macromem.isa (6308:46fcf4dc4c30) macromem.isa (6309:7f10d636910b)
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// Gabe Black
31
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// Gabe Black
31
32////////////////////////////////////////////////////////////////////
33//
34// Common microop templates
35//
32
36
37def template MicroConstructor {{
38 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
39 RegIndex _ura,
40 RegIndex _urb,
41 uint8_t _imm)
42 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
43 _ura, _urb, _imm)
44 {
45 %(constructor)s;
46 }
47}};
48
33////////////////////////////////////////////////////////////////////
34//
49////////////////////////////////////////////////////////////////////
50//
35// Integer = Integer op Immediate microops
51// Load/store microops
36//
37
52//
53
38def template MicroIntDeclare {{
54def template MicroMemDeclare {{
39 class %(class_name)s : public %(base_class)s
40 {
41 public:
42 %(class_name)s(ExtMachInst machInst,
43 RegIndex _ura, RegIndex _urb,
44 uint8_t _imm);
45 %(BasicExecDeclare)s
55 class %(class_name)s : public %(base_class)s
56 {
57 public:
58 %(class_name)s(ExtMachInst machInst,
59 RegIndex _ura, RegIndex _urb,
60 uint8_t _imm);
61 %(BasicExecDeclare)s
62 %(InitiateAccDeclare)s
63 %(CompleteAccDeclare)s
46 };
47}};
48
64 };
65}};
66
49def template MicroIntConstructor {{
50 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
51 RegIndex _ura,
52 RegIndex _urb,
53 uint8_t _imm)
54 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
55 _ura, _urb, _imm)
67let {{
68 microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
69 'MicroMemOp',
70 {'memacc_code': 'Ra = Mem;',
71 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
72 'predicate_test': predicateTest},
73 ['IsMicroop'])
74
75 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
76 'MicroMemOp',
77 {'memacc_code': 'Mem = Ra;',
78 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
79 'predicate_test': predicateTest},
80 ['IsMicroop'])
81
82 header_output = MicroMemDeclare.subst(microLdrUopIop) + \
83 MicroMemDeclare.subst(microStrUopIop)
84 decoder_output = MicroConstructor.subst(microLdrUopIop) + \
85 MicroConstructor.subst(microStrUopIop)
86 exec_output = LoadExecute.subst(microLdrUopIop) + \
87 StoreExecute.subst(microStrUopIop) + \
88 LoadInitiateAcc.subst(microLdrUopIop) + \
89 StoreInitiateAcc.subst(microStrUopIop) + \
90 LoadCompleteAcc.subst(microLdrUopIop) + \
91 StoreCompleteAcc.subst(microStrUopIop)
92}};
93
94////////////////////////////////////////////////////////////////////
95//
96// Integer = Integer op Immediate microops
97//
98
99def template MicroIntDeclare {{
100 class %(class_name)s : public %(base_class)s
56 {
101 {
57 %(constructor)s;
58 }
102 public:
103 %(class_name)s(ExtMachInst machInst,
104 RegIndex _ura, RegIndex _urb,
105 uint8_t _imm);
106 %(BasicExecDeclare)s
107 };
59}};
60
61let {{
62 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
63 'MicroIntOp',
64 {'code': 'Ra = Rb + imm;',
65 'predicate_test': predicateTest},
66 ['IsMicroop'])
67
68 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
69 'MicroIntOp',
70 {'code': 'Ra = Rb - imm;',
71 'predicate_test': predicateTest},
72 ['IsMicroop'])
73
74 header_output = MicroIntDeclare.subst(microAddiUopIop) + \
75 MicroIntDeclare.subst(microSubiUopIop)
108}};
109
110let {{
111 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
112 'MicroIntOp',
113 {'code': 'Ra = Rb + imm;',
114 'predicate_test': predicateTest},
115 ['IsMicroop'])
116
117 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
118 'MicroIntOp',
119 {'code': 'Ra = Rb - imm;',
120 'predicate_test': predicateTest},
121 ['IsMicroop'])
122
123 header_output = MicroIntDeclare.subst(microAddiUopIop) + \
124 MicroIntDeclare.subst(microSubiUopIop)
76 decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
77 MicroIntConstructor.subst(microSubiUopIop)
125 decoder_output = MicroConstructor.subst(microAddiUopIop) + \
126 MicroConstructor.subst(microSubiUopIop)
78 exec_output = PredOpExecute.subst(microAddiUopIop) + \
79 PredOpExecute.subst(microSubiUopIop)
80}};
81
82////////////////////////////////////////////////////////////////////
83//
84// Macro Memory-format instructions
85//
86
87def template MacroStoreDeclare {{
88/**
89 * Static instructions class for a store multiple instruction
90 */
91class %(class_name)s : public %(base_class)s
92{
93 public:
94 // Constructor
95 %(class_name)s(ExtMachInst machInst);
96 %(BasicExecDeclare)s
97};
98}};
99
100def template MacroStoreConstructor {{
101inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
102 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
103{
104 %(constructor)s;
105 uint32_t regs_to_handle = reglist;
106 uint32_t start_addr = 0;
107
108 switch (puswl)
109 {
110 case 0x00: // stmda
111 case 0x01: // L ldmda_l
112 case 0x02: // W stmda_w
113 case 0x03: // WL ldmda_wl
114 start_addr = (ones << 2) - 4;
115 break;
116 case 0x08: // U stmia_u
117 case 0x09: // U L ldmia_ul
118 case 0x0a: // U W stmia
119 case 0x0b: // U WL ldmia
120 start_addr = 0;
121 break;
122 case 0x10: // P stmdb
123 case 0x11: // P L ldmdb
124 case 0x12: // P W stmdb
125 case 0x13: // P WL ldmdb
126 start_addr = (ones << 2); // U-bit is already 0 for subtract
127 break;
128 case 0x18: // PU stmib
129 case 0x19: // PU L ldmib
130 case 0x1a: // PU W stmib
131 case 0x1b: // PU WL ldmib
132 start_addr = 4;
133 break;
134 default:
135 panic("Unhandled Load/Store Multiple Instruction, "
136 "puswl = 0x%x", (unsigned) puswl);
137 break;
138 }
139
140 // Add 0 to Rn and stick it in Raddr (register 17).
141 // This is equivalent to a move.
142 microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
143
144 unsigned j = 0;
145 for (int i = 1; i < ones+1; i++) {
146 // Get next available bit for transfer
147 while (! ( regs_to_handle & (1<<j)))
148 j++;
149 regs_to_handle &= ~(1<<j);
150
127 exec_output = PredOpExecute.subst(microAddiUopIop) + \
128 PredOpExecute.subst(microSubiUopIop)
129}};
130
131////////////////////////////////////////////////////////////////////
132//
133// Macro Memory-format instructions
134//
135
136def template MacroStoreDeclare {{
137/**
138 * Static instructions class for a store multiple instruction
139 */
140class %(class_name)s : public %(base_class)s
141{
142 public:
143 // Constructor
144 %(class_name)s(ExtMachInst machInst);
145 %(BasicExecDeclare)s
146};
147}};
148
149def template MacroStoreConstructor {{
150inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
151 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
152{
153 %(constructor)s;
154 uint32_t regs_to_handle = reglist;
155 uint32_t start_addr = 0;
156
157 switch (puswl)
158 {
159 case 0x00: // stmda
160 case 0x01: // L ldmda_l
161 case 0x02: // W stmda_w
162 case 0x03: // WL ldmda_wl
163 start_addr = (ones << 2) - 4;
164 break;
165 case 0x08: // U stmia_u
166 case 0x09: // U L ldmia_ul
167 case 0x0a: // U W stmia
168 case 0x0b: // U WL ldmia
169 start_addr = 0;
170 break;
171 case 0x10: // P stmdb
172 case 0x11: // P L ldmdb
173 case 0x12: // P W stmdb
174 case 0x13: // P WL ldmdb
175 start_addr = (ones << 2); // U-bit is already 0 for subtract
176 break;
177 case 0x18: // PU stmib
178 case 0x19: // PU L ldmib
179 case 0x1a: // PU W stmib
180 case 0x1b: // PU WL ldmib
181 start_addr = 4;
182 break;
183 default:
184 panic("Unhandled Load/Store Multiple Instruction, "
185 "puswl = 0x%x", (unsigned) puswl);
186 break;
187 }
188
189 // Add 0 to Rn and stick it in Raddr (register 17).
190 // This is equivalent to a move.
191 microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
192
193 unsigned j = 0;
194 for (int i = 1; i < ones+1; i++) {
195 // Get next available bit for transfer
196 while (! ( regs_to_handle & (1<<j)))
197 j++;
198 regs_to_handle &= ~(1<<j);
199
151 microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
200 if (loadop)
201 microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
202 else
203 microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
152
153 if (up)
154 start_addr += 4;
155 else
156 start_addr -= 4;
157 }
158
159 if (writeback) {
160 if (up) {
161 microOps[numMicroops-1] =
162 new MicroAddiUop(machInst, RN, RN, ones * 4);
163 } else {
164 microOps[numMicroops-1] =
165 new MicroSubiUop(machInst, RN, RN, ones * 4);
166 }
167 }
168 microOps[numMicroops-1]->setLastMicroop();
169}
170
171}};
172
173def template MacroStoreExecute {{
174Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
175{
176 Fault fault = NoFault;
177
178 %(fp_enable_check)s;
179 %(op_decl)s;
180 %(op_rd)s;
181 %(code)s;
182 if (fault == NoFault)
183 {
184 %(op_wb)s;
185 }
186
187 return fault;
188}
189}};
190
191def template MacroFPAConstructor {{
192inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
193 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
194{
195 %(constructor)s;
196
197 uint32_t start_addr = 0;
198
199 if (prepost)
200 start_addr = disp8;
201 else
202 start_addr = 0;
203
204 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
205
206 if (writeback)
207 {
208 if (up) {
209 microOps[numMicroops-1] =
210 new MicroAddiUop(machInst, RN, RN, disp8);
211 } else {
212 microOps[numMicroops-1] =
213 new MicroSubiUop(machInst, RN, RN, disp8);
214 }
215 }
216 microOps[numMicroops-1]->setLastMicroop();
217}
218
219}};
220
221
222def template MacroFMConstructor {{
223inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
224 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
225{
226 %(constructor)s;
227
228 uint32_t start_addr = 0;
229
230 if (prepost)
231 start_addr = disp8;
232 else
233 start_addr = 0;
234
235 for (int i = 0; i < count; i++)
236 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
237
238 if (writeback) {
239 if (up) {
240 microOps[numMicroops-1] =
241 new MicroAddiUop(machInst, RN, RN, disp8);
242 } else {
243 microOps[numMicroops-1] =
244 new MicroSubiUop(machInst, RN, RN, disp8);
245 }
246 }
247 microOps[numMicroops-1]->setLastMicroop();
248}
249}};
250
251
252def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
253 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
254 header_output = MacroStoreDeclare.subst(iop)
255 decoder_output = MacroStoreConstructor.subst(iop)
256 decode_block = BasicDecode.subst(iop)
257 exec_output = MacroStoreExecute.subst(iop)
258}};
259
260def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
261 iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
262 {"code": code,
263 "predicate_test": predicateTest},
264 opt_flags)
265 header_output = BasicDeclare.subst(iop)
266 decoder_output = MacroFPAConstructor.subst(iop)
267 decode_block = BasicDecode.subst(iop)
268 exec_output = PredOpExecute.subst(iop)
269}};
270
271def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
272 iop = InstObjParams(name, Name, 'ArmMacroFMOp',
273 {"code": code,
274 "predicate_test": predicateTest},
275 opt_flags)
276 header_output = BasicDeclare.subst(iop)
277 decoder_output = MacroFMConstructor.subst(iop)
278 decode_block = BasicDecode.subst(iop)
279 exec_output = PredOpExecute.subst(iop)
280}};
204
205 if (up)
206 start_addr += 4;
207 else
208 start_addr -= 4;
209 }
210
211 if (writeback) {
212 if (up) {
213 microOps[numMicroops-1] =
214 new MicroAddiUop(machInst, RN, RN, ones * 4);
215 } else {
216 microOps[numMicroops-1] =
217 new MicroSubiUop(machInst, RN, RN, ones * 4);
218 }
219 }
220 microOps[numMicroops-1]->setLastMicroop();
221}
222
223}};
224
225def template MacroStoreExecute {{
226Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
227{
228 Fault fault = NoFault;
229
230 %(fp_enable_check)s;
231 %(op_decl)s;
232 %(op_rd)s;
233 %(code)s;
234 if (fault == NoFault)
235 {
236 %(op_wb)s;
237 }
238
239 return fault;
240}
241}};
242
243def template MacroFPAConstructor {{
244inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
245 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
246{
247 %(constructor)s;
248
249 uint32_t start_addr = 0;
250
251 if (prepost)
252 start_addr = disp8;
253 else
254 start_addr = 0;
255
256 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
257
258 if (writeback)
259 {
260 if (up) {
261 microOps[numMicroops-1] =
262 new MicroAddiUop(machInst, RN, RN, disp8);
263 } else {
264 microOps[numMicroops-1] =
265 new MicroSubiUop(machInst, RN, RN, disp8);
266 }
267 }
268 microOps[numMicroops-1]->setLastMicroop();
269}
270
271}};
272
273
274def template MacroFMConstructor {{
275inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
276 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
277{
278 %(constructor)s;
279
280 uint32_t start_addr = 0;
281
282 if (prepost)
283 start_addr = disp8;
284 else
285 start_addr = 0;
286
287 for (int i = 0; i < count; i++)
288 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
289
290 if (writeback) {
291 if (up) {
292 microOps[numMicroops-1] =
293 new MicroAddiUop(machInst, RN, RN, disp8);
294 } else {
295 microOps[numMicroops-1] =
296 new MicroSubiUop(machInst, RN, RN, disp8);
297 }
298 }
299 microOps[numMicroops-1]->setLastMicroop();
300}
301}};
302
303
304def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
305 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
306 header_output = MacroStoreDeclare.subst(iop)
307 decoder_output = MacroStoreConstructor.subst(iop)
308 decode_block = BasicDecode.subst(iop)
309 exec_output = MacroStoreExecute.subst(iop)
310}};
311
312def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
313 iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
314 {"code": code,
315 "predicate_test": predicateTest},
316 opt_flags)
317 header_output = BasicDeclare.subst(iop)
318 decoder_output = MacroFPAConstructor.subst(iop)
319 decode_block = BasicDecode.subst(iop)
320 exec_output = PredOpExecute.subst(iop)
321}};
322
323def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
324 iop = InstObjParams(name, Name, 'ArmMacroFMOp',
325 {"code": code,
326 "predicate_test": predicateTest},
327 opt_flags)
328 header_output = BasicDeclare.subst(iop)
329 decoder_output = MacroFMConstructor.subst(iop)
330 decode_block = BasicDecode.subst(iop)
331 exec_output = PredOpExecute.subst(iop)
332}};