macromem.isa (6258:dadfc8d8b6dd) macromem.isa (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;
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 j = 0,
56 start_addr = 0,
57 end_addr = 0;
55 uint32_t start_addr = 0;
58
59 switch (puswl)
60 {
61 case 0x00: // stmda
62 case 0x01: // L ldmda_l
63 case 0x02: // W stmda_w
64 case 0x03: // WL ldmda_wl
65 start_addr = (ones << 2) - 4;
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;
66 end_addr = 0;
67 break;
68 case 0x08: // U stmia_u
69 case 0x09: // U L ldmia_ul
70 case 0x0a: // U W stmia
71 case 0x0b: // U WL ldmia
72 start_addr = 0;
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;
73 end_addr = (ones << 2) - 4;
74 break;
75 case 0x10: // P stmdb
76 case 0x11: // P L ldmdb
77 case 0x12: // P W stmdb
78 case 0x13: // P WL ldmdb
79 start_addr = (ones << 2); // U-bit is already 0 for subtract
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
80 end_addr = 4; // negative 4
81 break;
82 case 0x18: // PU stmib
83 case 0x19: // PU L ldmib
84 case 0x1a: // PU W stmib
85 case 0x1b: // PU WL ldmib
86 start_addr = 4;
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;
87 end_addr = (ones << 2) + 4;
88 break;
89 default:
90 panic("Unhandled Load/Store Multiple Instruction, "
91 "puswl = 0x%x", (unsigned) puswl);
92 break;
93 }
94
82 break;
83 default:
84 panic("Unhandled Load/Store Multiple Instruction, "
85 "puswl = 0x%x", (unsigned) puswl);
86 break;
87 }
88
95 //TODO - Add addi_uop/subi_uop here to create starting addresses
96 //Just using addi with 0 offset makes a "copy" of Rn for our use
97 uint32_t newMachInst = 0;
98 newMachInst = machInst & 0xffff0000;
99 microOps[0] = new Addi_uop(newMachInst);
100
89 uint32_t newMachInst = 0;
90 newMachInst = machInst & 0xffff0000;
91 microOps[0] = new Addi_uop(newMachInst);
92
93 unsigned j = 0;
101 for (int i = 1; i < ones+1; i++)
102 {
103 // Get next available bit for transfer
104 while (! ( regs_to_handle & (1<<j)))
105 j++;
106 regs_to_handle &= ~(1<<j);
107
108 microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
109
110 if (up)
111 start_addr += 4;
112 else
113 start_addr -= 4;
114 }
115
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
116 /* TODO: Take a look at how these 2 values should meet together
117 if (start_addr != (end_addr - 4))
118 {
119 fprintf(stderr, "start_addr: %d\n", start_addr);
120 fprintf(stderr, "end_addr: %d\n", end_addr);
121 panic("start_addr does not meet end_addr");
122 }
123 */
124
125 if (writeback)
126 {
127 uint32_t newMachInst = machInst & 0xf0000000;
128 uint32_t rn = (machInst >> 16) & 0x0f;
129 // 3322 2222 2222 1111 1111 11
130 // 1098 7654 3210 9876 5432 1098 7654 3210
131 // COND 0010 0100 [RN] [RD] 0000 [ IMM ]
132 // sub rn, rn, imm
133 newMachInst |= 0x02400000;
134 newMachInst |= ((rn << 16) | (rn << 12));
135 newMachInst |= (ones << 2);
136 if (up)
137 {
138 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
139 }
140 else
141 {
142 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
143 }
144 }
145 microOps[numMicroops-1]->setLastMicroop();
146}
147
148}};
149
150def template MacroStoreExecute {{
151Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
152{
153 Fault fault = NoFault;
154
155 %(fp_enable_check)s;
156 %(op_decl)s;
157 %(op_rd)s;
158 %(code)s;
159 if (fault == NoFault)
160 {
161 %(op_wb)s;
162 }
163
164 return fault;
165}
166}};
167
168def template MacroFPAConstructor {{
169inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
170 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
171{
172 %(constructor)s;
173
174 uint32_t start_addr = 0;
175
176 if (prepost)
177 start_addr = disp8;
178 else
179 start_addr = 0;
180
181 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
182
183 if (writeback)
184 {
185 uint32_t newMachInst = machInst & 0xf0000000;
186 uint32_t rn = (machInst >> 16) & 0x0f;
187 // 3322 2222 2222 1111 1111 11
188 // 1098 7654 3210 9876 5432 1098 7654 3210
189 // COND 0010 0100 [RN] [RD] 0000 [ IMM ]
190 // sub rn, rn, imm
191 newMachInst |= 0x02400000;
192 newMachInst |= ((rn << 16) | (rn << 12));
193 if (up)
194 {
195 newMachInst |= disp8;
196 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
197 }
198 else
199 {
200 newMachInst |= disp8;
201 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
202 }
203 }
204 microOps[numMicroops-1]->setLastMicroop();
205}
206
207}};
208
209
210def template MacroFMConstructor {{
211inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
212 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
213{
214 %(constructor)s;
215
216 uint32_t start_addr = 0;
217
218 if (prepost)
219 start_addr = disp8;
220 else
221 start_addr = 0;
222
223 for (int i = 0; i < count; i++)
224 {
225 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
226 }
227
228 if (writeback)
229 {
230 uint32_t newMachInst = machInst & 0xf0000000;
231 uint32_t rn = (machInst >> 16) & 0x0f;
232 // 3322 2222 2222 1111 1111 11
233 // 1098 7654 3210 9876 5432 1098 7654 3210
234 // COND 0010 0100 [RN] [RD] 0000 [ IMM ]
235 // sub rn, rn, imm
236 newMachInst |= 0x02400000;
237 newMachInst |= ((rn << 16) | (rn << 12));
238 if (up)
239 {
240 newMachInst |= disp8;
241 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
242 }
243 else
244 {
245 newMachInst |= disp8;
246 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
247 }
248 }
249 microOps[numMicroops-1]->setLastMicroop();
250}
251}};
252
253
254def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
255 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
256 header_output = MacroStoreDeclare.subst(iop)
257 decoder_output = MacroStoreConstructor.subst(iop)
258 decode_block = BasicDecode.subst(iop)
259 exec_output = MacroStoreExecute.subst(iop)
260}};
261
262def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
263 iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
264 {"code": code,
265 "predicate_test": predicateTest},
266 opt_flags)
267 header_output = BasicDeclare.subst(iop)
268 decoder_output = MacroFPAConstructor.subst(iop)
269 decode_block = BasicDecode.subst(iop)
270 exec_output = PredOpExecute.subst(iop)
271}};
272
273def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
274 iop = InstObjParams(name, Name, 'ArmMacroFMOp',
275 {"code": code,
276 "predicate_test": predicateTest},
277 opt_flags)
278 header_output = BasicDeclare.subst(iop)
279 decoder_output = MacroFMConstructor.subst(iop)
280 decode_block = BasicDecode.subst(iop)
281 exec_output = PredOpExecute.subst(iop)
282}};
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}};