macromem.isa revision 6304:a2af27fbc06c
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// Macro Memory-format instructions
34//
35
36def template MacroStoreDeclare {{
37/**
38 * Static instructions class for a store multiple instruction
39 */
40class %(class_name)s : public %(base_class)s
41{
42    public:
43        // Constructor
44        %(class_name)s(ExtMachInst machInst);
45        %(BasicExecDeclare)s
46};
47}};
48
49def template MacroStoreConstructor {{
50inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
51    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
52{
53    %(constructor)s;
54    uint32_t regs_to_handle = reglist;
55    uint32_t start_addr = 0;
56
57    switch (puswl)
58    {
59        case 0x00: //       stmda
60        case 0x01: //     L ldmda_l
61        case 0x02: //    W  stmda_w
62        case 0x03: //    WL ldmda_wl
63            start_addr = (ones << 2) - 4;
64            break;
65        case 0x08: //  U    stmia_u
66        case 0x09: //  U  L ldmia_ul
67        case 0x0a: //  U W  stmia
68        case 0x0b: //  U WL ldmia
69            start_addr = 0;
70            break;
71        case 0x10: // P     stmdb
72        case 0x11: // P   L ldmdb
73        case 0x12: // P  W  stmdb
74        case 0x13: // P  WL ldmdb
75            start_addr = (ones << 2); // U-bit is already 0 for subtract
76            break;
77        case 0x18: // PU    stmib
78        case 0x19: // PU  L ldmib
79        case 0x1a: // PU W  stmib
80        case 0x1b: // PU WL ldmib
81            start_addr = 4;
82            break;
83        default:
84            panic("Unhandled Load/Store Multiple Instruction, "
85                "puswl = 0x%x", (unsigned) puswl);
86            break;
87    }
88
89    uint32_t newMachInst = 0;
90    newMachInst = machInst & 0xffff0000;
91    microOps[0] = new Addi_uop(newMachInst);
92
93    unsigned j = 0;
94    for (int i = 1; i < ones+1; i++)
95    {
96        // Get next available bit for transfer
97        while (! ( regs_to_handle & (1<<j)))
98            j++;
99        regs_to_handle &= ~(1<<j);
100
101        microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
102
103        if (up)
104            start_addr += 4;
105        else
106            start_addr -= 4;
107    }
108
109    if (writeback)
110    {
111        uint32_t newMachInst = machInst & 0xf0000000;
112        uint32_t rn = (machInst >> 16) & 0x0f;
113        // 3322 2222 2222 1111 1111 11
114        // 1098 7654 3210 9876 5432 1098 7654 3210
115        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
116        // sub rn, rn, imm
117        newMachInst |= 0x02400000;
118        newMachInst |= ((rn << 16) | (rn << 12));
119        newMachInst |= (ones << 2);
120        if (up)
121        {
122            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
123        }
124        else
125        {
126            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
127        }
128    }
129    microOps[numMicroops-1]->setLastMicroop();
130}
131
132}};
133
134def template MacroStoreExecute {{
135Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
136{
137    Fault fault = NoFault;
138
139    %(fp_enable_check)s;
140    %(op_decl)s;
141    %(op_rd)s;
142    %(code)s;
143    if (fault == NoFault)
144    {
145        %(op_wb)s;
146    }
147
148    return fault;
149}
150}};
151
152def template MacroFPAConstructor {{
153inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
154    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
155{
156    %(constructor)s;
157
158    uint32_t start_addr = 0;
159
160    if (prepost)
161        start_addr = disp8;
162    else
163        start_addr = 0;
164
165    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
166
167    if (writeback)
168    {
169        uint32_t newMachInst = machInst & 0xf0000000;
170        uint32_t rn = (machInst >> 16) & 0x0f;
171        // 3322 2222 2222 1111 1111 11
172        // 1098 7654 3210 9876 5432 1098 7654 3210
173        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
174        // sub rn, rn, imm
175        newMachInst |= 0x02400000;
176        newMachInst |= ((rn << 16) | (rn << 12));
177        if (up)
178        {
179            newMachInst |= disp8;
180            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
181        }
182        else
183        {
184            newMachInst |= disp8;
185            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
186        }
187    }
188    microOps[numMicroops-1]->setLastMicroop();
189}
190
191}};
192
193
194def template MacroFMConstructor {{
195inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
196    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
197{
198    %(constructor)s;
199
200    uint32_t start_addr = 0;
201
202    if (prepost)
203        start_addr = disp8;
204    else
205        start_addr = 0;
206
207    for (int i = 0; i < count; i++)
208    {
209        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
210    }
211
212    if (writeback)
213    {
214        uint32_t newMachInst = machInst & 0xf0000000;
215        uint32_t rn = (machInst >> 16) & 0x0f;
216        // 3322 2222 2222 1111 1111 11
217        // 1098 7654 3210 9876 5432 1098 7654 3210
218        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
219        // sub rn, rn, imm
220        newMachInst |= 0x02400000;
221        newMachInst |= ((rn << 16) | (rn << 12));
222        if (up)
223        {
224            newMachInst |= disp8;
225            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
226        }
227        else
228        {
229            newMachInst |= disp8;
230            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
231        }
232    }
233    microOps[numMicroops-1]->setLastMicroop();
234}
235}};
236
237
238def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
239    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
240    header_output = MacroStoreDeclare.subst(iop)
241    decoder_output = MacroStoreConstructor.subst(iop)
242    decode_block = BasicDecode.subst(iop)
243    exec_output = MacroStoreExecute.subst(iop)
244}};
245
246def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
247    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
248                        {"code": code,
249                         "predicate_test": predicateTest},
250                        opt_flags)
251    header_output = BasicDeclare.subst(iop)
252    decoder_output = MacroFPAConstructor.subst(iop)
253    decode_block = BasicDecode.subst(iop)
254    exec_output = PredOpExecute.subst(iop)
255}};
256
257def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
258    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
259                        {"code": code,
260                         "predicate_test": predicateTest},
261                        opt_flags)
262    header_output = BasicDeclare.subst(iop)
263    decoder_output = MacroFMConstructor.subst(iop)
264    decode_block = BasicDecode.subst(iop)
265    exec_output = PredOpExecute.subst(iop)
266}};
267