mem.isa (12110:c24ee249b8ba) mem.isa (12234:78ece221f9f5)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010, 2012, 2014, 2016 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43
44def template PanicExecute {{
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010, 2012, 2014, 2016 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43
44def template PanicExecute {{
45 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
45 Fault %(class_name)s::execute(ExecContext *xc,
46 Trace::InstRecord *traceData) const
47 {
48 panic("Execute function executed when it shouldn't be!\n");
49 return NoFault;
50 }
51}};
52
53def template PanicInitiateAcc {{
46 Trace::InstRecord *traceData) const
47 {
48 panic("Execute function executed when it shouldn't be!\n");
49 return NoFault;
50 }
51}};
52
53def template PanicInitiateAcc {{
54 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
54 Fault %(class_name)s::initiateAcc(ExecContext *xc,
55 Trace::InstRecord *traceData) const
56 {
57 panic("InitiateAcc function executed when it shouldn't be!\n");
58 return NoFault;
59 }
60}};
61
62def template PanicCompleteAcc {{
55 Trace::InstRecord *traceData) const
56 {
57 panic("InitiateAcc function executed when it shouldn't be!\n");
58 return NoFault;
59 }
60}};
61
62def template PanicCompleteAcc {{
63 Fault %(class_name)s::completeAcc(PacketPtr pkt,
64 CPU_EXEC_CONTEXT *xc,
63 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
65 Trace::InstRecord *traceData) const
66 {
67 panic("CompleteAcc function executed when it shouldn't be!\n");
68 return NoFault;
69 }
70}};
71
72
73def template SwapExecute {{
64 Trace::InstRecord *traceData) const
65 {
66 panic("CompleteAcc function executed when it shouldn't be!\n");
67 return NoFault;
68 }
69}};
70
71
72def template SwapExecute {{
74 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
73 Fault %(class_name)s::execute(ExecContext *xc,
75 Trace::InstRecord *traceData) const
76 {
77 Addr EA;
78 Fault fault = NoFault;
79
80 %(op_decl)s;
81 uint64_t memData = 0;
82 %(op_rd)s;
83 %(ea_code)s;
84
85 if (%(predicate_test)s)
86 {
87 %(preacc_code)s;
88
89 if (fault == NoFault) {
90 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
91 &memData);
92 }
93
94 if (fault == NoFault) {
95 %(postacc_code)s;
96 }
97
98 if (fault == NoFault) {
99 %(op_wb)s;
100 }
101 } else {
102 xc->setPredicate(false);
103 }
104
105 return fault;
106 }
107}};
108
109def template SwapInitiateAcc {{
74 Trace::InstRecord *traceData) const
75 {
76 Addr EA;
77 Fault fault = NoFault;
78
79 %(op_decl)s;
80 uint64_t memData = 0;
81 %(op_rd)s;
82 %(ea_code)s;
83
84 if (%(predicate_test)s)
85 {
86 %(preacc_code)s;
87
88 if (fault == NoFault) {
89 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
90 &memData);
91 }
92
93 if (fault == NoFault) {
94 %(postacc_code)s;
95 }
96
97 if (fault == NoFault) {
98 %(op_wb)s;
99 }
100 } else {
101 xc->setPredicate(false);
102 }
103
104 return fault;
105 }
106}};
107
108def template SwapInitiateAcc {{
110 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
109 Fault %(class_name)s::initiateAcc(ExecContext *xc,
111 Trace::InstRecord *traceData) const
112 {
113 Addr EA;
114 Fault fault = NoFault;
115
116 %(op_decl)s;
117 uint64_t memData = 0;
118 %(op_rd)s;
119 %(ea_code)s;
120
121 if (%(predicate_test)s)
122 {
123 %(preacc_code)s;
124
125 if (fault == NoFault) {
126 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
127 &memData);
128 }
129 } else {
130 xc->setPredicate(false);
131 }
132
133 return fault;
134 }
135}};
136
137def template SwapCompleteAcc {{
110 Trace::InstRecord *traceData) const
111 {
112 Addr EA;
113 Fault fault = NoFault;
114
115 %(op_decl)s;
116 uint64_t memData = 0;
117 %(op_rd)s;
118 %(ea_code)s;
119
120 if (%(predicate_test)s)
121 {
122 %(preacc_code)s;
123
124 if (fault == NoFault) {
125 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
126 &memData);
127 }
128 } else {
129 xc->setPredicate(false);
130 }
131
132 return fault;
133 }
134}};
135
136def template SwapCompleteAcc {{
138 Fault %(class_name)s::completeAcc(PacketPtr pkt,
139 CPU_EXEC_CONTEXT *xc,
137 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
140 Trace::InstRecord *traceData) const
141 {
142 Fault fault = NoFault;
143
144 %(op_decl)s;
145 %(op_rd)s;
146
147 if (%(predicate_test)s)
148 {
149 // ARM instructions will not have a pkt if the predicate is false
150 getMem(pkt, Mem, traceData);
151 uint64_t memData = Mem;
152
153 %(postacc_code)s;
154
155 if (fault == NoFault) {
156 %(op_wb)s;
157 }
158 }
159
160 return fault;
161 }
162}};
163
164def template LoadExecute {{
138 Trace::InstRecord *traceData) const
139 {
140 Fault fault = NoFault;
141
142 %(op_decl)s;
143 %(op_rd)s;
144
145 if (%(predicate_test)s)
146 {
147 // ARM instructions will not have a pkt if the predicate is false
148 getMem(pkt, Mem, traceData);
149 uint64_t memData = Mem;
150
151 %(postacc_code)s;
152
153 if (fault == NoFault) {
154 %(op_wb)s;
155 }
156 }
157
158 return fault;
159 }
160}};
161
162def template LoadExecute {{
165 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
163 Fault %(class_name)s::execute(ExecContext *xc,
166 Trace::InstRecord *traceData) const
167 {
168 Addr EA;
169 Fault fault = NoFault;
170
171 %(op_decl)s;
172 %(op_rd)s;
173 %(ea_code)s;
174
175 if (%(predicate_test)s)
176 {
177 if (fault == NoFault) {
178 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
179 %(memacc_code)s;
180 }
181
182 if (fault == NoFault) {
183 %(op_wb)s;
184 }
185 } else {
186 xc->setPredicate(false);
187 }
188
189 return fault;
190 }
191}};
192
193def template NeonLoadExecute {{
194 template <class Element>
195 Fault %(class_name)s<Element>::execute(
164 Trace::InstRecord *traceData) const
165 {
166 Addr EA;
167 Fault fault = NoFault;
168
169 %(op_decl)s;
170 %(op_rd)s;
171 %(ea_code)s;
172
173 if (%(predicate_test)s)
174 {
175 if (fault == NoFault) {
176 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
177 %(memacc_code)s;
178 }
179
180 if (fault == NoFault) {
181 %(op_wb)s;
182 }
183 } else {
184 xc->setPredicate(false);
185 }
186
187 return fault;
188 }
189}};
190
191def template NeonLoadExecute {{
192 template <class Element>
193 Fault %(class_name)s<Element>::execute(
196 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
194 ExecContext *xc, Trace::InstRecord *traceData) const
197 {
198 Addr EA;
199 Fault fault = NoFault;
200
201 %(op_decl)s;
202 %(mem_decl)s;
203 %(op_rd)s;
204 %(ea_code)s;
205
206 MemUnion memUnion;
207 uint8_t *dataPtr = memUnion.bytes;
208
209 if (%(predicate_test)s)
210 {
211 if (fault == NoFault) {
212 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
213 %(memacc_code)s;
214 }
215
216 if (fault == NoFault) {
217 %(op_wb)s;
218 }
219 } else {
220 xc->setPredicate(false);
221 }
222
223 return fault;
224 }
225}};
226
227def template StoreExecute {{
195 {
196 Addr EA;
197 Fault fault = NoFault;
198
199 %(op_decl)s;
200 %(mem_decl)s;
201 %(op_rd)s;
202 %(ea_code)s;
203
204 MemUnion memUnion;
205 uint8_t *dataPtr = memUnion.bytes;
206
207 if (%(predicate_test)s)
208 {
209 if (fault == NoFault) {
210 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
211 %(memacc_code)s;
212 }
213
214 if (fault == NoFault) {
215 %(op_wb)s;
216 }
217 } else {
218 xc->setPredicate(false);
219 }
220
221 return fault;
222 }
223}};
224
225def template StoreExecute {{
228 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
226 Fault %(class_name)s::execute(ExecContext *xc,
229 Trace::InstRecord *traceData) const
230 {
231 Addr EA;
232 Fault fault = NoFault;
233
234 %(op_decl)s;
235 %(op_rd)s;
236 %(ea_code)s;
237
238 if (%(predicate_test)s)
239 {
240 if (fault == NoFault) {
241 %(memacc_code)s;
242 }
243
244 if (fault == NoFault) {
245 fault = writeMemAtomic(xc, traceData, Mem, EA,
246 memAccessFlags, NULL);
247 }
248
249 if (fault == NoFault) {
250 %(op_wb)s;
251 }
252 } else {
253 xc->setPredicate(false);
254 }
255
256 return fault;
257 }
258}};
259
260def template NeonStoreExecute {{
261 template <class Element>
262 Fault %(class_name)s<Element>::execute(
227 Trace::InstRecord *traceData) const
228 {
229 Addr EA;
230 Fault fault = NoFault;
231
232 %(op_decl)s;
233 %(op_rd)s;
234 %(ea_code)s;
235
236 if (%(predicate_test)s)
237 {
238 if (fault == NoFault) {
239 %(memacc_code)s;
240 }
241
242 if (fault == NoFault) {
243 fault = writeMemAtomic(xc, traceData, Mem, EA,
244 memAccessFlags, NULL);
245 }
246
247 if (fault == NoFault) {
248 %(op_wb)s;
249 }
250 } else {
251 xc->setPredicate(false);
252 }
253
254 return fault;
255 }
256}};
257
258def template NeonStoreExecute {{
259 template <class Element>
260 Fault %(class_name)s<Element>::execute(
263 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
261 ExecContext *xc, Trace::InstRecord *traceData) const
264 {
265 Addr EA;
266 Fault fault = NoFault;
267
268 %(op_decl)s;
269 %(mem_decl)s;
270 %(op_rd)s;
271 %(ea_code)s;
272
273 MemUnion memUnion;
274 uint8_t *dataPtr = memUnion.bytes;
275
276 if (%(predicate_test)s)
277 {
278 if (fault == NoFault) {
279 %(memacc_code)s;
280 }
281
282 if (fault == NoFault) {
283 fault = xc->writeMem(dataPtr, %(size)d, EA,
284 memAccessFlags, NULL);
285 }
286
287 if (fault == NoFault) {
288 %(op_wb)s;
289 }
290 } else {
291 xc->setPredicate(false);
292 }
293
294 return fault;
295 }
296}};
297
298def template StoreExExecute {{
262 {
263 Addr EA;
264 Fault fault = NoFault;
265
266 %(op_decl)s;
267 %(mem_decl)s;
268 %(op_rd)s;
269 %(ea_code)s;
270
271 MemUnion memUnion;
272 uint8_t *dataPtr = memUnion.bytes;
273
274 if (%(predicate_test)s)
275 {
276 if (fault == NoFault) {
277 %(memacc_code)s;
278 }
279
280 if (fault == NoFault) {
281 fault = xc->writeMem(dataPtr, %(size)d, EA,
282 memAccessFlags, NULL);
283 }
284
285 if (fault == NoFault) {
286 %(op_wb)s;
287 }
288 } else {
289 xc->setPredicate(false);
290 }
291
292 return fault;
293 }
294}};
295
296def template StoreExExecute {{
299 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
297 Fault %(class_name)s::execute(ExecContext *xc,
300 Trace::InstRecord *traceData) const
301 {
302 Addr EA;
303 Fault fault = NoFault;
304
305 %(op_decl)s;
306 %(op_rd)s;
307 %(ea_code)s;
308
309 if (%(predicate_test)s)
310 {
311 if (fault == NoFault) {
312 %(memacc_code)s;
313 }
314
315 uint64_t writeResult;
316
317 if (fault == NoFault) {
318 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
319 &writeResult);
320 }
321
322 if (fault == NoFault) {
323 %(postacc_code)s;
324 }
325
326 if (fault == NoFault) {
327 %(op_wb)s;
328 }
329 } else {
330 xc->setPredicate(false);
331 }
332
333 return fault;
334 }
335}};
336
337def template StoreExInitiateAcc {{
298 Trace::InstRecord *traceData) const
299 {
300 Addr EA;
301 Fault fault = NoFault;
302
303 %(op_decl)s;
304 %(op_rd)s;
305 %(ea_code)s;
306
307 if (%(predicate_test)s)
308 {
309 if (fault == NoFault) {
310 %(memacc_code)s;
311 }
312
313 uint64_t writeResult;
314
315 if (fault == NoFault) {
316 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
317 &writeResult);
318 }
319
320 if (fault == NoFault) {
321 %(postacc_code)s;
322 }
323
324 if (fault == NoFault) {
325 %(op_wb)s;
326 }
327 } else {
328 xc->setPredicate(false);
329 }
330
331 return fault;
332 }
333}};
334
335def template StoreExInitiateAcc {{
338 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
336 Fault %(class_name)s::initiateAcc(ExecContext *xc,
339 Trace::InstRecord *traceData) const
340 {
341 Addr EA;
342 Fault fault = NoFault;
343
344 %(op_decl)s;
345 %(op_rd)s;
346 %(ea_code)s;
347
348 if (%(predicate_test)s)
349 {
350 if (fault == NoFault) {
351 %(memacc_code)s;
352 }
353
354 if (fault == NoFault) {
355 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
356 NULL);
357 }
358 } else {
359 xc->setPredicate(false);
360 }
361
362 return fault;
363 }
364}};
365
366def template StoreInitiateAcc {{
337 Trace::InstRecord *traceData) const
338 {
339 Addr EA;
340 Fault fault = NoFault;
341
342 %(op_decl)s;
343 %(op_rd)s;
344 %(ea_code)s;
345
346 if (%(predicate_test)s)
347 {
348 if (fault == NoFault) {
349 %(memacc_code)s;
350 }
351
352 if (fault == NoFault) {
353 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
354 NULL);
355 }
356 } else {
357 xc->setPredicate(false);
358 }
359
360 return fault;
361 }
362}};
363
364def template StoreInitiateAcc {{
367 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
365 Fault %(class_name)s::initiateAcc(ExecContext *xc,
368 Trace::InstRecord *traceData) const
369 {
370 Addr EA;
371 Fault fault = NoFault;
372
373 %(op_decl)s;
374 %(op_rd)s;
375 %(ea_code)s;
376
377 if (%(predicate_test)s)
378 {
379 if (fault == NoFault) {
380 %(memacc_code)s;
381 }
382
383 if (fault == NoFault) {
384 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
385 NULL);
386 }
387 } else {
388 xc->setPredicate(false);
389 }
390
391 return fault;
392 }
393}};
394
395def template NeonStoreInitiateAcc {{
396 template <class Element>
397 Fault %(class_name)s<Element>::initiateAcc(
366 Trace::InstRecord *traceData) const
367 {
368 Addr EA;
369 Fault fault = NoFault;
370
371 %(op_decl)s;
372 %(op_rd)s;
373 %(ea_code)s;
374
375 if (%(predicate_test)s)
376 {
377 if (fault == NoFault) {
378 %(memacc_code)s;
379 }
380
381 if (fault == NoFault) {
382 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
383 NULL);
384 }
385 } else {
386 xc->setPredicate(false);
387 }
388
389 return fault;
390 }
391}};
392
393def template NeonStoreInitiateAcc {{
394 template <class Element>
395 Fault %(class_name)s<Element>::initiateAcc(
398 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
396 ExecContext *xc, Trace::InstRecord *traceData) const
399 {
400 Addr EA;
401 Fault fault = NoFault;
402
403 %(op_decl)s;
404 %(mem_decl)s;
405 %(op_rd)s;
406 %(ea_code)s;
407
408 if (%(predicate_test)s)
409 {
410 MemUnion memUnion;
411 if (fault == NoFault) {
412 %(memacc_code)s;
413 }
414
415 if (fault == NoFault) {
416 fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
417 memAccessFlags, NULL);
418 }
419 } else {
420 xc->setPredicate(false);
421 }
422
423 return fault;
424 }
425}};
426
427def template LoadInitiateAcc {{
397 {
398 Addr EA;
399 Fault fault = NoFault;
400
401 %(op_decl)s;
402 %(mem_decl)s;
403 %(op_rd)s;
404 %(ea_code)s;
405
406 if (%(predicate_test)s)
407 {
408 MemUnion memUnion;
409 if (fault == NoFault) {
410 %(memacc_code)s;
411 }
412
413 if (fault == NoFault) {
414 fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
415 memAccessFlags, NULL);
416 }
417 } else {
418 xc->setPredicate(false);
419 }
420
421 return fault;
422 }
423}};
424
425def template LoadInitiateAcc {{
428 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
426 Fault %(class_name)s::initiateAcc(ExecContext *xc,
429 Trace::InstRecord *traceData) const
430 {
431 Addr EA;
432 Fault fault = NoFault;
433
434 %(op_src_decl)s;
435 %(op_rd)s;
436 %(ea_code)s;
437
438 if (%(predicate_test)s)
439 {
440 if (fault == NoFault) {
441 fault = initiateMemRead(xc, traceData, EA, Mem,
442 memAccessFlags);
443 }
444 } else {
445 xc->setPredicate(false);
446 }
447
448 return fault;
449 }
450}};
451
452def template NeonLoadInitiateAcc {{
453 template <class Element>
454 Fault %(class_name)s<Element>::initiateAcc(
427 Trace::InstRecord *traceData) const
428 {
429 Addr EA;
430 Fault fault = NoFault;
431
432 %(op_src_decl)s;
433 %(op_rd)s;
434 %(ea_code)s;
435
436 if (%(predicate_test)s)
437 {
438 if (fault == NoFault) {
439 fault = initiateMemRead(xc, traceData, EA, Mem,
440 memAccessFlags);
441 }
442 } else {
443 xc->setPredicate(false);
444 }
445
446 return fault;
447 }
448}};
449
450def template NeonLoadInitiateAcc {{
451 template <class Element>
452 Fault %(class_name)s<Element>::initiateAcc(
455 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
453 ExecContext *xc, Trace::InstRecord *traceData) const
456 {
457 Addr EA;
458 Fault fault = NoFault;
459
460 %(op_decl)s;
461 %(mem_decl)s;
462 %(op_rd)s;
463 %(ea_code)s;
464
465 if (%(predicate_test)s)
466 {
467 if (fault == NoFault) {
468 fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
469 }
470 } else {
471 xc->setPredicate(false);
472 }
473
474 return fault;
475 }
476}};
477
478def template LoadCompleteAcc {{
454 {
455 Addr EA;
456 Fault fault = NoFault;
457
458 %(op_decl)s;
459 %(mem_decl)s;
460 %(op_rd)s;
461 %(ea_code)s;
462
463 if (%(predicate_test)s)
464 {
465 if (fault == NoFault) {
466 fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
467 }
468 } else {
469 xc->setPredicate(false);
470 }
471
472 return fault;
473 }
474}};
475
476def template LoadCompleteAcc {{
479 Fault %(class_name)s::completeAcc(PacketPtr pkt,
480 CPU_EXEC_CONTEXT *xc,
477 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
481 Trace::InstRecord *traceData) const
482 {
483 Fault fault = NoFault;
484
485 %(op_decl)s;
486 %(op_rd)s;
487
488 if (%(predicate_test)s)
489 {
490 // ARM instructions will not have a pkt if the predicate is false
491 getMem(pkt, Mem, traceData);
492
493 if (fault == NoFault) {
494 %(memacc_code)s;
495 }
496
497 if (fault == NoFault) {
498 %(op_wb)s;
499 }
500 }
501
502 return fault;
503 }
504}};
505
506def template NeonLoadCompleteAcc {{
507 template <class Element>
508 Fault %(class_name)s<Element>::completeAcc(
478 Trace::InstRecord *traceData) const
479 {
480 Fault fault = NoFault;
481
482 %(op_decl)s;
483 %(op_rd)s;
484
485 if (%(predicate_test)s)
486 {
487 // ARM instructions will not have a pkt if the predicate is false
488 getMem(pkt, Mem, traceData);
489
490 if (fault == NoFault) {
491 %(memacc_code)s;
492 }
493
494 if (fault == NoFault) {
495 %(op_wb)s;
496 }
497 }
498
499 return fault;
500 }
501}};
502
503def template NeonLoadCompleteAcc {{
504 template <class Element>
505 Fault %(class_name)s<Element>::completeAcc(
509 PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
506 PacketPtr pkt, ExecContext *xc,
510 Trace::InstRecord *traceData) const
511 {
512 Fault fault = NoFault;
513
514 %(mem_decl)s;
515 %(op_decl)s;
516 %(op_rd)s;
517
518 if (%(predicate_test)s)
519 {
520 // ARM instructions will not have a pkt if the predicate is false
521 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
522
523 if (fault == NoFault) {
524 %(memacc_code)s;
525 }
526
527 if (fault == NoFault) {
528 %(op_wb)s;
529 }
530 }
531
532 return fault;
533 }
534}};
535
536def template StoreCompleteAcc {{
507 Trace::InstRecord *traceData) const
508 {
509 Fault fault = NoFault;
510
511 %(mem_decl)s;
512 %(op_decl)s;
513 %(op_rd)s;
514
515 if (%(predicate_test)s)
516 {
517 // ARM instructions will not have a pkt if the predicate is false
518 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
519
520 if (fault == NoFault) {
521 %(memacc_code)s;
522 }
523
524 if (fault == NoFault) {
525 %(op_wb)s;
526 }
527 }
528
529 return fault;
530 }
531}};
532
533def template StoreCompleteAcc {{
537 Fault %(class_name)s::completeAcc(PacketPtr pkt,
538 CPU_EXEC_CONTEXT *xc,
534 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
539 Trace::InstRecord *traceData) const
540 {
541 return NoFault;
542 }
543}};
544
545def template NeonStoreCompleteAcc {{
546 template <class Element>
547 Fault %(class_name)s<Element>::completeAcc(
535 Trace::InstRecord *traceData) const
536 {
537 return NoFault;
538 }
539}};
540
541def template NeonStoreCompleteAcc {{
542 template <class Element>
543 Fault %(class_name)s<Element>::completeAcc(
548 PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
549 Trace::InstRecord *traceData) const
544 PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
550 {
551 return NoFault;
552 }
553}};
554
555def template StoreExCompleteAcc {{
545 {
546 return NoFault;
547 }
548}};
549
550def template StoreExCompleteAcc {{
556 Fault %(class_name)s::completeAcc(PacketPtr pkt,
557 CPU_EXEC_CONTEXT *xc,
551 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
558 Trace::InstRecord *traceData) const
559 {
560 Fault fault = NoFault;
561
562 %(op_decl)s;
563 %(op_rd)s;
564
565 if (%(predicate_test)s)
566 {
567 uint64_t writeResult = pkt->req->getExtraData();
568 %(postacc_code)s;
569
570 if (fault == NoFault) {
571 %(op_wb)s;
572 }
573 }
574
575 return fault;
576 }
577}};
578
579def template RfeDeclare {{
580 /**
581 * Static instruction class for "%(mnemonic)s".
582 */
583 class %(class_name)s : public %(base_class)s
584 {
585 public:
586
587 /// Constructor.
588 %(class_name)s(ExtMachInst machInst,
589 uint32_t _base, int _mode, bool _wb);
590
591 %(BasicExecDeclare)s
592
593 %(InitiateAccDeclare)s
594
595 %(CompleteAccDeclare)s
596 };
597}};
598
599def template SrsDeclare {{
600 /**
601 * Static instruction class for "%(mnemonic)s".
602 */
603 class %(class_name)s : public %(base_class)s
604 {
605 public:
606
607 /// Constructor.
608 %(class_name)s(ExtMachInst machInst,
609 uint32_t _regMode, int _mode, bool _wb);
610
611 %(BasicExecDeclare)s
612
613 %(InitiateAccDeclare)s
614
615 %(CompleteAccDeclare)s
616 };
617}};
618
619def template SwapDeclare {{
620 /**
621 * Static instruction class for "%(mnemonic)s".
622 */
623 class %(class_name)s : public %(base_class)s
624 {
625 public:
626
627 /// Constructor.
628 %(class_name)s(ExtMachInst machInst,
629 uint32_t _dest, uint32_t _op1, uint32_t _base);
630
631 %(BasicExecDeclare)s
632
633 %(InitiateAccDeclare)s
634
635 %(CompleteAccDeclare)s
636 };
637}};
638
639def template LoadStoreDImmDeclare {{
640 /**
641 * Static instruction class for "%(mnemonic)s".
642 */
643 class %(class_name)s : public %(base_class)s
644 {
645 public:
646
647 /// Constructor.
648 %(class_name)s(ExtMachInst machInst,
649 uint32_t _dest, uint32_t _dest2,
650 uint32_t _base, bool _add, int32_t _imm);
651
652 %(BasicExecDeclare)s
653
654 %(InitiateAccDeclare)s
655
656 %(CompleteAccDeclare)s
657 };
658}};
659
660def template StoreExDImmDeclare {{
661 /**
662 * Static instruction class for "%(mnemonic)s".
663 */
664 class %(class_name)s : public %(base_class)s
665 {
666 public:
667
668 /// Constructor.
669 %(class_name)s(ExtMachInst machInst,
670 uint32_t _result, uint32_t _dest, uint32_t _dest2,
671 uint32_t _base, bool _add, int32_t _imm);
672
673 %(BasicExecDeclare)s
674
675 %(InitiateAccDeclare)s
676
677 %(CompleteAccDeclare)s
678 };
679}};
680
681def template LoadStoreImmDeclare {{
682 /**
683 * Static instruction class for "%(mnemonic)s".
684 */
685 class %(class_name)s : public %(base_class)s
686 {
687 public:
688
689 /// Constructor.
690 %(class_name)s(ExtMachInst machInst,
691 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
692
693 %(BasicExecDeclare)s
694
695 %(InitiateAccDeclare)s
696
697 %(CompleteAccDeclare)s
698
699 virtual void
700 annotateFault(ArmFault *fault) {
701 %(fa_code)s
702 }
703 };
704}};
705
706def template StoreExImmDeclare {{
707 /**
708 * Static instruction class for "%(mnemonic)s".
709 */
710 class %(class_name)s : public %(base_class)s
711 {
712 public:
713
714 /// Constructor.
715 %(class_name)s(ExtMachInst machInst,
716 uint32_t _result, uint32_t _dest, uint32_t _base,
717 bool _add, int32_t _imm);
718
719 %(BasicExecDeclare)s
720
721 %(InitiateAccDeclare)s
722
723 %(CompleteAccDeclare)s
724 };
725}};
726
727def template StoreDRegDeclare {{
728 /**
729 * Static instruction class for "%(mnemonic)s".
730 */
731 class %(class_name)s : public %(base_class)s
732 {
733 public:
734
735 /// Constructor.
736 %(class_name)s(ExtMachInst machInst,
737 uint32_t _dest, uint32_t _dest2,
738 uint32_t _base, bool _add,
739 int32_t _shiftAmt, uint32_t _shiftType,
740 uint32_t _index);
741
742 %(BasicExecDeclare)s
743
744 %(InitiateAccDeclare)s
745
746 %(CompleteAccDeclare)s
747 };
748}};
749
750def template StoreRegDeclare {{
751 /**
752 * Static instruction class for "%(mnemonic)s".
753 */
754 class %(class_name)s : public %(base_class)s
755 {
756 public:
757
758 /// Constructor.
759 %(class_name)s(ExtMachInst machInst,
760 uint32_t _dest, uint32_t _base, bool _add,
761 int32_t _shiftAmt, uint32_t _shiftType,
762 uint32_t _index);
763
764 %(BasicExecDeclare)s
765
766 %(InitiateAccDeclare)s
767
768 %(CompleteAccDeclare)s
769
770 virtual void
771 annotateFault(ArmFault *fault) {
772 %(fa_code)s
773 }
774 };
775}};
776
777def template LoadDRegDeclare {{
778 /**
779 * Static instruction class for "%(mnemonic)s".
780 */
781 class %(class_name)s : public %(base_class)s
782 {
783 public:
784
785 /// Constructor.
786 %(class_name)s(ExtMachInst machInst,
787 uint32_t _dest, uint32_t _dest2,
788 uint32_t _base, bool _add,
789 int32_t _shiftAmt, uint32_t _shiftType,
790 uint32_t _index);
791
792 %(BasicExecDeclare)s
793
794 %(InitiateAccDeclare)s
795
796 %(CompleteAccDeclare)s
797 };
798}};
799
800def template LoadRegDeclare {{
801 /**
802 * Static instruction class for "%(mnemonic)s".
803 */
804 class %(class_name)s : public %(base_class)s
805 {
806 public:
807
808 /// Constructor.
809 %(class_name)s(ExtMachInst machInst,
810 uint32_t _dest, uint32_t _base, bool _add,
811 int32_t _shiftAmt, uint32_t _shiftType,
812 uint32_t _index);
813
814 %(BasicExecDeclare)s
815
816 %(InitiateAccDeclare)s
817
818 %(CompleteAccDeclare)s
819
820 virtual void
821 annotateFault(ArmFault *fault) {
822 %(fa_code)s
823 }
824 };
825}};
826
827def template LoadImmDeclare {{
828 /**
829 * Static instruction class for "%(mnemonic)s".
830 */
831 class %(class_name)s : public %(base_class)s
832 {
833 public:
834
835 /// Constructor.
836 %(class_name)s(ExtMachInst machInst,
837 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
838
839 %(BasicExecDeclare)s
840
841 %(InitiateAccDeclare)s
842
843 %(CompleteAccDeclare)s
844
845 virtual void
846 annotateFault(ArmFault *fault) {
847 %(fa_code)s
848 }
849 };
850}};
851
852def template InitiateAccDeclare {{
552 Trace::InstRecord *traceData) const
553 {
554 Fault fault = NoFault;
555
556 %(op_decl)s;
557 %(op_rd)s;
558
559 if (%(predicate_test)s)
560 {
561 uint64_t writeResult = pkt->req->getExtraData();
562 %(postacc_code)s;
563
564 if (fault == NoFault) {
565 %(op_wb)s;
566 }
567 }
568
569 return fault;
570 }
571}};
572
573def template RfeDeclare {{
574 /**
575 * Static instruction class for "%(mnemonic)s".
576 */
577 class %(class_name)s : public %(base_class)s
578 {
579 public:
580
581 /// Constructor.
582 %(class_name)s(ExtMachInst machInst,
583 uint32_t _base, int _mode, bool _wb);
584
585 %(BasicExecDeclare)s
586
587 %(InitiateAccDeclare)s
588
589 %(CompleteAccDeclare)s
590 };
591}};
592
593def template SrsDeclare {{
594 /**
595 * Static instruction class for "%(mnemonic)s".
596 */
597 class %(class_name)s : public %(base_class)s
598 {
599 public:
600
601 /// Constructor.
602 %(class_name)s(ExtMachInst machInst,
603 uint32_t _regMode, int _mode, bool _wb);
604
605 %(BasicExecDeclare)s
606
607 %(InitiateAccDeclare)s
608
609 %(CompleteAccDeclare)s
610 };
611}};
612
613def template SwapDeclare {{
614 /**
615 * Static instruction class for "%(mnemonic)s".
616 */
617 class %(class_name)s : public %(base_class)s
618 {
619 public:
620
621 /// Constructor.
622 %(class_name)s(ExtMachInst machInst,
623 uint32_t _dest, uint32_t _op1, uint32_t _base);
624
625 %(BasicExecDeclare)s
626
627 %(InitiateAccDeclare)s
628
629 %(CompleteAccDeclare)s
630 };
631}};
632
633def template LoadStoreDImmDeclare {{
634 /**
635 * Static instruction class for "%(mnemonic)s".
636 */
637 class %(class_name)s : public %(base_class)s
638 {
639 public:
640
641 /// Constructor.
642 %(class_name)s(ExtMachInst machInst,
643 uint32_t _dest, uint32_t _dest2,
644 uint32_t _base, bool _add, int32_t _imm);
645
646 %(BasicExecDeclare)s
647
648 %(InitiateAccDeclare)s
649
650 %(CompleteAccDeclare)s
651 };
652}};
653
654def template StoreExDImmDeclare {{
655 /**
656 * Static instruction class for "%(mnemonic)s".
657 */
658 class %(class_name)s : public %(base_class)s
659 {
660 public:
661
662 /// Constructor.
663 %(class_name)s(ExtMachInst machInst,
664 uint32_t _result, uint32_t _dest, uint32_t _dest2,
665 uint32_t _base, bool _add, int32_t _imm);
666
667 %(BasicExecDeclare)s
668
669 %(InitiateAccDeclare)s
670
671 %(CompleteAccDeclare)s
672 };
673}};
674
675def template LoadStoreImmDeclare {{
676 /**
677 * Static instruction class for "%(mnemonic)s".
678 */
679 class %(class_name)s : public %(base_class)s
680 {
681 public:
682
683 /// Constructor.
684 %(class_name)s(ExtMachInst machInst,
685 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
686
687 %(BasicExecDeclare)s
688
689 %(InitiateAccDeclare)s
690
691 %(CompleteAccDeclare)s
692
693 virtual void
694 annotateFault(ArmFault *fault) {
695 %(fa_code)s
696 }
697 };
698}};
699
700def template StoreExImmDeclare {{
701 /**
702 * Static instruction class for "%(mnemonic)s".
703 */
704 class %(class_name)s : public %(base_class)s
705 {
706 public:
707
708 /// Constructor.
709 %(class_name)s(ExtMachInst machInst,
710 uint32_t _result, uint32_t _dest, uint32_t _base,
711 bool _add, int32_t _imm);
712
713 %(BasicExecDeclare)s
714
715 %(InitiateAccDeclare)s
716
717 %(CompleteAccDeclare)s
718 };
719}};
720
721def template StoreDRegDeclare {{
722 /**
723 * Static instruction class for "%(mnemonic)s".
724 */
725 class %(class_name)s : public %(base_class)s
726 {
727 public:
728
729 /// Constructor.
730 %(class_name)s(ExtMachInst machInst,
731 uint32_t _dest, uint32_t _dest2,
732 uint32_t _base, bool _add,
733 int32_t _shiftAmt, uint32_t _shiftType,
734 uint32_t _index);
735
736 %(BasicExecDeclare)s
737
738 %(InitiateAccDeclare)s
739
740 %(CompleteAccDeclare)s
741 };
742}};
743
744def template StoreRegDeclare {{
745 /**
746 * Static instruction class for "%(mnemonic)s".
747 */
748 class %(class_name)s : public %(base_class)s
749 {
750 public:
751
752 /// Constructor.
753 %(class_name)s(ExtMachInst machInst,
754 uint32_t _dest, uint32_t _base, bool _add,
755 int32_t _shiftAmt, uint32_t _shiftType,
756 uint32_t _index);
757
758 %(BasicExecDeclare)s
759
760 %(InitiateAccDeclare)s
761
762 %(CompleteAccDeclare)s
763
764 virtual void
765 annotateFault(ArmFault *fault) {
766 %(fa_code)s
767 }
768 };
769}};
770
771def template LoadDRegDeclare {{
772 /**
773 * Static instruction class for "%(mnemonic)s".
774 */
775 class %(class_name)s : public %(base_class)s
776 {
777 public:
778
779 /// Constructor.
780 %(class_name)s(ExtMachInst machInst,
781 uint32_t _dest, uint32_t _dest2,
782 uint32_t _base, bool _add,
783 int32_t _shiftAmt, uint32_t _shiftType,
784 uint32_t _index);
785
786 %(BasicExecDeclare)s
787
788 %(InitiateAccDeclare)s
789
790 %(CompleteAccDeclare)s
791 };
792}};
793
794def template LoadRegDeclare {{
795 /**
796 * Static instruction class for "%(mnemonic)s".
797 */
798 class %(class_name)s : public %(base_class)s
799 {
800 public:
801
802 /// Constructor.
803 %(class_name)s(ExtMachInst machInst,
804 uint32_t _dest, uint32_t _base, bool _add,
805 int32_t _shiftAmt, uint32_t _shiftType,
806 uint32_t _index);
807
808 %(BasicExecDeclare)s
809
810 %(InitiateAccDeclare)s
811
812 %(CompleteAccDeclare)s
813
814 virtual void
815 annotateFault(ArmFault *fault) {
816 %(fa_code)s
817 }
818 };
819}};
820
821def template LoadImmDeclare {{
822 /**
823 * Static instruction class for "%(mnemonic)s".
824 */
825 class %(class_name)s : public %(base_class)s
826 {
827 public:
828
829 /// Constructor.
830 %(class_name)s(ExtMachInst machInst,
831 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
832
833 %(BasicExecDeclare)s
834
835 %(InitiateAccDeclare)s
836
837 %(CompleteAccDeclare)s
838
839 virtual void
840 annotateFault(ArmFault *fault) {
841 %(fa_code)s
842 }
843 };
844}};
845
846def template InitiateAccDeclare {{
853 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
847 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
854}};
855
856def template CompleteAccDeclare {{
848}};
849
850def template CompleteAccDeclare {{
857 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
851 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
858}};
859
860def template RfeConstructor {{
861 %(class_name)s::%(class_name)s(ExtMachInst machInst,
862 uint32_t _base, int _mode, bool _wb)
863 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
864 (IntRegIndex)_base, (AddrMode)_mode, _wb)
865 {
866 %(constructor)s;
867 if (!(condCode == COND_AL || condCode == COND_UC)) {
868 for (int x = 0; x < _numDestRegs; x++) {
869 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
870 }
871 }
872#if %(use_uops)d
873 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
874 int uopIdx = 0;
875 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
876 uops[uopIdx]->setDelayedCommit();
877#if %(use_wb)d
878 uops[++uopIdx] = new %(wb_decl)s;
879 uops[uopIdx]->setDelayedCommit();
880#endif
881#if %(use_pc)d
882 uops[++uopIdx] = new %(pc_decl)s;
883#endif
884 uops[0]->setFirstMicroop();
885 uops[uopIdx]->setLastMicroop();
886#endif
887 }
888}};
889
890def template SrsConstructor {{
891 %(class_name)s::%(class_name)s(ExtMachInst machInst,
892 uint32_t _regMode, int _mode, bool _wb)
893 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
894 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
895 {
896 %(constructor)s;
897 if (!(condCode == COND_AL || condCode == COND_UC)) {
898 for (int x = 0; x < _numDestRegs; x++) {
899 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
900 }
901 }
902#if %(use_uops)d
903 assert(numMicroops >= 2);
904 uops = new StaticInstPtr[numMicroops];
905 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
906 uops[0]->setDelayedCommit();
907 uops[0]->setFirstMicroop();
908 uops[1] = new %(wb_decl)s;
909 uops[1]->setLastMicroop();
910#endif
911 }
912}};
913
914def template SwapConstructor {{
915 %(class_name)s::%(class_name)s(ExtMachInst machInst,
916 uint32_t _dest, uint32_t _op1, uint32_t _base)
917 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
918 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
919 {
920 %(constructor)s;
921 if (!(condCode == COND_AL || condCode == COND_UC)) {
922 for (int x = 0; x < _numDestRegs; x++) {
923 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
924 }
925 }
926 }
927}};
928
929def template LoadStoreDImmConstructor {{
930 %(class_name)s::%(class_name)s(ExtMachInst machInst,
931 uint32_t _dest, uint32_t _dest2,
932 uint32_t _base, bool _add, int32_t _imm)
933 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
934 (IntRegIndex)_dest, (IntRegIndex)_dest2,
935 (IntRegIndex)_base, _add, _imm)
936 {
937 %(constructor)s;
938 if (!(condCode == COND_AL || condCode == COND_UC)) {
939 for (int x = 0; x < _numDestRegs; x++) {
940 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
941 }
942 }
943#if %(use_uops)d
944 assert(numMicroops >= 2);
945 uops = new StaticInstPtr[numMicroops];
946 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
947 uops[0]->setFirstMicroop();
948 uops[0]->setDelayedCommit();
949 uops[1] = new %(wb_decl)s;
950 uops[1]->setLastMicroop();
951#endif
952 }
953}};
954
955def template StoreExDImmConstructor {{
956 %(class_name)s::%(class_name)s(ExtMachInst machInst,
957 uint32_t _result, uint32_t _dest, uint32_t _dest2,
958 uint32_t _base, bool _add, int32_t _imm)
959 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
960 (IntRegIndex)_result,
961 (IntRegIndex)_dest, (IntRegIndex)_dest2,
962 (IntRegIndex)_base, _add, _imm)
963 {
964 %(constructor)s;
965 if (!(condCode == COND_AL || condCode == COND_UC)) {
966 for (int x = 0; x < _numDestRegs; x++) {
967 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
968 }
969 }
970#if %(use_uops)d
971 assert(numMicroops >= 2);
972 uops = new StaticInstPtr[numMicroops];
973 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
974 _base, _add, _imm);
975 uops[0]->setDelayedCommit();
976 uops[0]->setFirstMicroop();
977 uops[1] = new %(wb_decl)s;
978 uops[1]->setLastMicroop();
979#endif
980 }
981}};
982
983def template LoadStoreImmConstructor {{
984 %(class_name)s::%(class_name)s(ExtMachInst machInst,
985 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
986 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
987 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
988 {
989 %(constructor)s;
990 if (!(condCode == COND_AL || condCode == COND_UC)) {
991 for (int x = 0; x < _numDestRegs; x++) {
992 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
993 }
994 }
995#if %(use_uops)d
996 assert(numMicroops >= 2);
997 uops = new StaticInstPtr[numMicroops];
998 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
999 uops[0]->setDelayedCommit();
1000 uops[0]->setFirstMicroop();
1001 uops[1] = new %(wb_decl)s;
1002 uops[1]->setLastMicroop();
1003#endif
1004 }
1005}};
1006
1007def template StoreExImmConstructor {{
1008 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1009 uint32_t _result, uint32_t _dest, uint32_t _base,
1010 bool _add, int32_t _imm)
1011 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1012 (IntRegIndex)_result, (IntRegIndex)_dest,
1013 (IntRegIndex)_base, _add, _imm)
1014 {
1015 %(constructor)s;
1016 if (!(condCode == COND_AL || condCode == COND_UC)) {
1017 for (int x = 0; x < _numDestRegs; x++) {
1018 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1019 }
1020 }
1021#if %(use_uops)d
1022 assert(numMicroops >= 2);
1023 uops = new StaticInstPtr[numMicroops];
1024 uops[0] = new %(acc_name)s(machInst, _result, _dest,
1025 _base, _add, _imm);
1026 uops[0]->setDelayedCommit();
1027 uops[0]->setFirstMicroop();
1028 uops[1] = new %(wb_decl)s;
1029 uops[1]->setLastMicroop();
1030#endif
1031 }
1032}};
1033
1034def template StoreDRegConstructor {{
1035 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1036 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1037 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1038 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1039 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1040 (IntRegIndex)_base, _add,
1041 _shiftAmt, (ArmShiftType)_shiftType,
1042 (IntRegIndex)_index)
1043 {
1044 %(constructor)s;
1045 if (!(condCode == COND_AL || condCode == COND_UC)) {
1046 for (int x = 0; x < _numDestRegs; x++) {
1047 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1048 }
1049 }
1050#if %(use_uops)d
1051 assert(numMicroops >= 2);
1052 uops = new StaticInstPtr[numMicroops];
1053 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1054 _shiftAmt, _shiftType, _index);
1055 uops[0]->setDelayedCommit();
1056 uops[0]->setFirstMicroop();
1057 uops[1] = new %(wb_decl)s;
1058 uops[1]->setLastMicroop();
1059#endif
1060 }
1061}};
1062
1063def template StoreRegConstructor {{
1064 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1065 uint32_t _dest, uint32_t _base, bool _add,
1066 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1067 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1068 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1069 _shiftAmt, (ArmShiftType)_shiftType,
1070 (IntRegIndex)_index)
1071 {
1072 %(constructor)s;
1073 if (!(condCode == COND_AL || condCode == COND_UC)) {
1074 for (int x = 0; x < _numDestRegs; x++) {
1075 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1076 }
1077 }
1078#if %(use_uops)d
1079 assert(numMicroops >= 2);
1080 uops = new StaticInstPtr[numMicroops];
1081 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1082 _shiftAmt, _shiftType, _index);
1083 uops[0]->setDelayedCommit();
1084 uops[0]->setFirstMicroop();
1085 uops[1] = new %(wb_decl)s;
1086 uops[1]->setLastMicroop();
1087#endif
1088 }
1089}};
1090
1091def template LoadDRegConstructor {{
1092 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1093 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1094 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1095 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1096 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1097 (IntRegIndex)_base, _add,
1098 _shiftAmt, (ArmShiftType)_shiftType,
1099 (IntRegIndex)_index)
1100 {
1101 %(constructor)s;
1102 if (!(condCode == COND_AL || condCode == COND_UC)) {
1103 for (int x = 0; x < _numDestRegs; x++) {
1104 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1105 }
1106 }
1107#if %(use_uops)d
1108 assert(numMicroops >= 2);
1109 uops = new StaticInstPtr[numMicroops];
1110 if ((_dest == _index) || (_dest2 == _index)) {
1111 IntRegIndex wbIndexReg = INTREG_UREG0;
1112 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1113 uops[0]->setDelayedCommit();
1114 uops[0]->setFirstMicroop();
1115 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1116 _shiftAmt, _shiftType, _index);
1117 uops[1]->setDelayedCommit();
1118 uops[2] = new %(wb_decl)s;
1119 uops[2]->setLastMicroop();
1120 } else {
1121 IntRegIndex wbIndexReg = index;
1122 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1123 _shiftAmt, _shiftType, _index);
1124 uops[0]->setDelayedCommit();
1125 uops[0]->setFirstMicroop();
1126 uops[1] = new %(wb_decl)s;
1127 uops[1]->setLastMicroop();
1128 }
1129#endif
1130 }
1131}};
1132
1133def template LoadRegConstructor {{
1134 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1135 uint32_t _dest, uint32_t _base, bool _add,
1136 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1137 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1138 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1139 _shiftAmt, (ArmShiftType)_shiftType,
1140 (IntRegIndex)_index)
1141 {
1142 %(constructor)s;
1143 bool conditional M5_VAR_USED = false;
1144 if (!(condCode == COND_AL || condCode == COND_UC)) {
1145 conditional = true;
1146 for (int x = 0; x < _numDestRegs; x++) {
1147 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1148 }
1149 }
1150#if %(use_uops)d
1151 assert(numMicroops >= 2);
1152 uops = new StaticInstPtr[numMicroops];
1153 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1154 IntRegIndex wbIndexReg = index;
1155 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1156 _shiftAmt, _shiftType, _index);
1157 uops[0]->setDelayedCommit();
1158 uops[0]->setFirstMicroop();
1159 uops[1] = new %(wb_decl)s;
1160 uops[1]->setDelayedCommit();
1161 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1162 uops[2]->setFlag(StaticInst::IsControl);
1163 uops[2]->setFlag(StaticInst::IsIndirectControl);
1164 if (conditional)
1165 uops[2]->setFlag(StaticInst::IsCondControl);
1166 else
1167 uops[2]->setFlag(StaticInst::IsUncondControl);
1168 uops[2]->setLastMicroop();
1169 } else if(_dest == _index) {
1170 IntRegIndex wbIndexReg = INTREG_UREG0;
1171 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1172 uops[0]->setDelayedCommit();
1173 uops[0]->setFirstMicroop();
1174 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1175 _shiftAmt, _shiftType, _index);
1176 uops[1]->setDelayedCommit();
1177 uops[2] = new %(wb_decl)s;
1178 uops[2]->setLastMicroop();
1179 } else {
1180 IntRegIndex wbIndexReg = index;
1181 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1182 _shiftAmt, _shiftType, _index);
1183 uops[0]->setDelayedCommit();
1184 uops[0]->setFirstMicroop();
1185 uops[1] = new %(wb_decl)s;
1186 uops[1]->setLastMicroop();
1187
1188 }
1189#else
1190 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1191 flags[IsControl] = true;
1192 flags[IsIndirectControl] = true;
1193 if (conditional)
1194 flags[IsCondControl] = true;
1195 else
1196 flags[IsUncondControl] = true;
1197 }
1198#endif
1199 }
1200}};
1201
1202def template LoadImmConstructor {{
1203 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1204 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1205 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1206 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1207 {
1208 %(constructor)s;
1209 bool conditional M5_VAR_USED = false;
1210 if (!(condCode == COND_AL || condCode == COND_UC)) {
1211 conditional = true;
1212 for (int x = 0; x < _numDestRegs; x++) {
1213 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1214 }
1215 }
1216#if %(use_uops)d
1217 assert(numMicroops >= 2);
1218 uops = new StaticInstPtr[numMicroops];
1219 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1220 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1221 _imm);
1222 uops[0]->setDelayedCommit();
1223 uops[0]->setFirstMicroop();
1224 uops[1] = new %(wb_decl)s;
1225 uops[1]->setDelayedCommit();
1226 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1227 uops[2]->setFlag(StaticInst::IsControl);
1228 uops[2]->setFlag(StaticInst::IsIndirectControl);
1229 /* Also set flags on the macroop so that pre-microop decomposition
1230 branch prediction can work */
1231 setFlag(StaticInst::IsControl);
1232 setFlag(StaticInst::IsIndirectControl);
1233 if (conditional) {
1234 uops[2]->setFlag(StaticInst::IsCondControl);
1235 setFlag(StaticInst::IsCondControl);
1236 } else {
1237 uops[2]->setFlag(StaticInst::IsUncondControl);
1238 setFlag(StaticInst::IsUncondControl);
1239 }
1240 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) {
1241 uops[2]->setFlag(StaticInst::IsReturn);
1242 setFlag(StaticInst::IsReturn);
1243 }
1244 uops[2]->setLastMicroop();
1245 } else {
1246 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1247 uops[0]->setDelayedCommit();
1248 uops[0]->setFirstMicroop();
1249 uops[1] = new %(wb_decl)s;
1250 uops[1]->setLastMicroop();
1251 }
1252#else
1253 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1254 flags[IsControl] = true;
1255 flags[IsIndirectControl] = true;
1256 if (conditional)
1257 flags[IsCondControl] = true;
1258 else
1259 flags[IsUncondControl] = true;
1260 }
1261#endif
1262 }
1263}};
1264
852}};
853
854def template RfeConstructor {{
855 %(class_name)s::%(class_name)s(ExtMachInst machInst,
856 uint32_t _base, int _mode, bool _wb)
857 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
858 (IntRegIndex)_base, (AddrMode)_mode, _wb)
859 {
860 %(constructor)s;
861 if (!(condCode == COND_AL || condCode == COND_UC)) {
862 for (int x = 0; x < _numDestRegs; x++) {
863 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
864 }
865 }
866#if %(use_uops)d
867 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
868 int uopIdx = 0;
869 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
870 uops[uopIdx]->setDelayedCommit();
871#if %(use_wb)d
872 uops[++uopIdx] = new %(wb_decl)s;
873 uops[uopIdx]->setDelayedCommit();
874#endif
875#if %(use_pc)d
876 uops[++uopIdx] = new %(pc_decl)s;
877#endif
878 uops[0]->setFirstMicroop();
879 uops[uopIdx]->setLastMicroop();
880#endif
881 }
882}};
883
884def template SrsConstructor {{
885 %(class_name)s::%(class_name)s(ExtMachInst machInst,
886 uint32_t _regMode, int _mode, bool _wb)
887 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
888 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
889 {
890 %(constructor)s;
891 if (!(condCode == COND_AL || condCode == COND_UC)) {
892 for (int x = 0; x < _numDestRegs; x++) {
893 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
894 }
895 }
896#if %(use_uops)d
897 assert(numMicroops >= 2);
898 uops = new StaticInstPtr[numMicroops];
899 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
900 uops[0]->setDelayedCommit();
901 uops[0]->setFirstMicroop();
902 uops[1] = new %(wb_decl)s;
903 uops[1]->setLastMicroop();
904#endif
905 }
906}};
907
908def template SwapConstructor {{
909 %(class_name)s::%(class_name)s(ExtMachInst machInst,
910 uint32_t _dest, uint32_t _op1, uint32_t _base)
911 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
912 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
913 {
914 %(constructor)s;
915 if (!(condCode == COND_AL || condCode == COND_UC)) {
916 for (int x = 0; x < _numDestRegs; x++) {
917 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
918 }
919 }
920 }
921}};
922
923def template LoadStoreDImmConstructor {{
924 %(class_name)s::%(class_name)s(ExtMachInst machInst,
925 uint32_t _dest, uint32_t _dest2,
926 uint32_t _base, bool _add, int32_t _imm)
927 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
928 (IntRegIndex)_dest, (IntRegIndex)_dest2,
929 (IntRegIndex)_base, _add, _imm)
930 {
931 %(constructor)s;
932 if (!(condCode == COND_AL || condCode == COND_UC)) {
933 for (int x = 0; x < _numDestRegs; x++) {
934 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
935 }
936 }
937#if %(use_uops)d
938 assert(numMicroops >= 2);
939 uops = new StaticInstPtr[numMicroops];
940 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
941 uops[0]->setFirstMicroop();
942 uops[0]->setDelayedCommit();
943 uops[1] = new %(wb_decl)s;
944 uops[1]->setLastMicroop();
945#endif
946 }
947}};
948
949def template StoreExDImmConstructor {{
950 %(class_name)s::%(class_name)s(ExtMachInst machInst,
951 uint32_t _result, uint32_t _dest, uint32_t _dest2,
952 uint32_t _base, bool _add, int32_t _imm)
953 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
954 (IntRegIndex)_result,
955 (IntRegIndex)_dest, (IntRegIndex)_dest2,
956 (IntRegIndex)_base, _add, _imm)
957 {
958 %(constructor)s;
959 if (!(condCode == COND_AL || condCode == COND_UC)) {
960 for (int x = 0; x < _numDestRegs; x++) {
961 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
962 }
963 }
964#if %(use_uops)d
965 assert(numMicroops >= 2);
966 uops = new StaticInstPtr[numMicroops];
967 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
968 _base, _add, _imm);
969 uops[0]->setDelayedCommit();
970 uops[0]->setFirstMicroop();
971 uops[1] = new %(wb_decl)s;
972 uops[1]->setLastMicroop();
973#endif
974 }
975}};
976
977def template LoadStoreImmConstructor {{
978 %(class_name)s::%(class_name)s(ExtMachInst machInst,
979 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
980 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
981 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
982 {
983 %(constructor)s;
984 if (!(condCode == COND_AL || condCode == COND_UC)) {
985 for (int x = 0; x < _numDestRegs; x++) {
986 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
987 }
988 }
989#if %(use_uops)d
990 assert(numMicroops >= 2);
991 uops = new StaticInstPtr[numMicroops];
992 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
993 uops[0]->setDelayedCommit();
994 uops[0]->setFirstMicroop();
995 uops[1] = new %(wb_decl)s;
996 uops[1]->setLastMicroop();
997#endif
998 }
999}};
1000
1001def template StoreExImmConstructor {{
1002 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1003 uint32_t _result, uint32_t _dest, uint32_t _base,
1004 bool _add, int32_t _imm)
1005 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1006 (IntRegIndex)_result, (IntRegIndex)_dest,
1007 (IntRegIndex)_base, _add, _imm)
1008 {
1009 %(constructor)s;
1010 if (!(condCode == COND_AL || condCode == COND_UC)) {
1011 for (int x = 0; x < _numDestRegs; x++) {
1012 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1013 }
1014 }
1015#if %(use_uops)d
1016 assert(numMicroops >= 2);
1017 uops = new StaticInstPtr[numMicroops];
1018 uops[0] = new %(acc_name)s(machInst, _result, _dest,
1019 _base, _add, _imm);
1020 uops[0]->setDelayedCommit();
1021 uops[0]->setFirstMicroop();
1022 uops[1] = new %(wb_decl)s;
1023 uops[1]->setLastMicroop();
1024#endif
1025 }
1026}};
1027
1028def template StoreDRegConstructor {{
1029 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1030 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1031 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1032 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1033 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1034 (IntRegIndex)_base, _add,
1035 _shiftAmt, (ArmShiftType)_shiftType,
1036 (IntRegIndex)_index)
1037 {
1038 %(constructor)s;
1039 if (!(condCode == COND_AL || condCode == COND_UC)) {
1040 for (int x = 0; x < _numDestRegs; x++) {
1041 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1042 }
1043 }
1044#if %(use_uops)d
1045 assert(numMicroops >= 2);
1046 uops = new StaticInstPtr[numMicroops];
1047 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1048 _shiftAmt, _shiftType, _index);
1049 uops[0]->setDelayedCommit();
1050 uops[0]->setFirstMicroop();
1051 uops[1] = new %(wb_decl)s;
1052 uops[1]->setLastMicroop();
1053#endif
1054 }
1055}};
1056
1057def template StoreRegConstructor {{
1058 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1059 uint32_t _dest, uint32_t _base, bool _add,
1060 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1061 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1062 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1063 _shiftAmt, (ArmShiftType)_shiftType,
1064 (IntRegIndex)_index)
1065 {
1066 %(constructor)s;
1067 if (!(condCode == COND_AL || condCode == COND_UC)) {
1068 for (int x = 0; x < _numDestRegs; x++) {
1069 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1070 }
1071 }
1072#if %(use_uops)d
1073 assert(numMicroops >= 2);
1074 uops = new StaticInstPtr[numMicroops];
1075 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1076 _shiftAmt, _shiftType, _index);
1077 uops[0]->setDelayedCommit();
1078 uops[0]->setFirstMicroop();
1079 uops[1] = new %(wb_decl)s;
1080 uops[1]->setLastMicroop();
1081#endif
1082 }
1083}};
1084
1085def template LoadDRegConstructor {{
1086 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1087 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1088 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1089 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1090 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1091 (IntRegIndex)_base, _add,
1092 _shiftAmt, (ArmShiftType)_shiftType,
1093 (IntRegIndex)_index)
1094 {
1095 %(constructor)s;
1096 if (!(condCode == COND_AL || condCode == COND_UC)) {
1097 for (int x = 0; x < _numDestRegs; x++) {
1098 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1099 }
1100 }
1101#if %(use_uops)d
1102 assert(numMicroops >= 2);
1103 uops = new StaticInstPtr[numMicroops];
1104 if ((_dest == _index) || (_dest2 == _index)) {
1105 IntRegIndex wbIndexReg = INTREG_UREG0;
1106 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1107 uops[0]->setDelayedCommit();
1108 uops[0]->setFirstMicroop();
1109 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1110 _shiftAmt, _shiftType, _index);
1111 uops[1]->setDelayedCommit();
1112 uops[2] = new %(wb_decl)s;
1113 uops[2]->setLastMicroop();
1114 } else {
1115 IntRegIndex wbIndexReg = index;
1116 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1117 _shiftAmt, _shiftType, _index);
1118 uops[0]->setDelayedCommit();
1119 uops[0]->setFirstMicroop();
1120 uops[1] = new %(wb_decl)s;
1121 uops[1]->setLastMicroop();
1122 }
1123#endif
1124 }
1125}};
1126
1127def template LoadRegConstructor {{
1128 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1129 uint32_t _dest, uint32_t _base, bool _add,
1130 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1131 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1132 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1133 _shiftAmt, (ArmShiftType)_shiftType,
1134 (IntRegIndex)_index)
1135 {
1136 %(constructor)s;
1137 bool conditional M5_VAR_USED = false;
1138 if (!(condCode == COND_AL || condCode == COND_UC)) {
1139 conditional = true;
1140 for (int x = 0; x < _numDestRegs; x++) {
1141 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1142 }
1143 }
1144#if %(use_uops)d
1145 assert(numMicroops >= 2);
1146 uops = new StaticInstPtr[numMicroops];
1147 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1148 IntRegIndex wbIndexReg = index;
1149 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1150 _shiftAmt, _shiftType, _index);
1151 uops[0]->setDelayedCommit();
1152 uops[0]->setFirstMicroop();
1153 uops[1] = new %(wb_decl)s;
1154 uops[1]->setDelayedCommit();
1155 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1156 uops[2]->setFlag(StaticInst::IsControl);
1157 uops[2]->setFlag(StaticInst::IsIndirectControl);
1158 if (conditional)
1159 uops[2]->setFlag(StaticInst::IsCondControl);
1160 else
1161 uops[2]->setFlag(StaticInst::IsUncondControl);
1162 uops[2]->setLastMicroop();
1163 } else if(_dest == _index) {
1164 IntRegIndex wbIndexReg = INTREG_UREG0;
1165 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1166 uops[0]->setDelayedCommit();
1167 uops[0]->setFirstMicroop();
1168 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1169 _shiftAmt, _shiftType, _index);
1170 uops[1]->setDelayedCommit();
1171 uops[2] = new %(wb_decl)s;
1172 uops[2]->setLastMicroop();
1173 } else {
1174 IntRegIndex wbIndexReg = index;
1175 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1176 _shiftAmt, _shiftType, _index);
1177 uops[0]->setDelayedCommit();
1178 uops[0]->setFirstMicroop();
1179 uops[1] = new %(wb_decl)s;
1180 uops[1]->setLastMicroop();
1181
1182 }
1183#else
1184 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1185 flags[IsControl] = true;
1186 flags[IsIndirectControl] = true;
1187 if (conditional)
1188 flags[IsCondControl] = true;
1189 else
1190 flags[IsUncondControl] = true;
1191 }
1192#endif
1193 }
1194}};
1195
1196def template LoadImmConstructor {{
1197 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1198 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1199 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1200 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1201 {
1202 %(constructor)s;
1203 bool conditional M5_VAR_USED = false;
1204 if (!(condCode == COND_AL || condCode == COND_UC)) {
1205 conditional = true;
1206 for (int x = 0; x < _numDestRegs; x++) {
1207 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1208 }
1209 }
1210#if %(use_uops)d
1211 assert(numMicroops >= 2);
1212 uops = new StaticInstPtr[numMicroops];
1213 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1214 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1215 _imm);
1216 uops[0]->setDelayedCommit();
1217 uops[0]->setFirstMicroop();
1218 uops[1] = new %(wb_decl)s;
1219 uops[1]->setDelayedCommit();
1220 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1221 uops[2]->setFlag(StaticInst::IsControl);
1222 uops[2]->setFlag(StaticInst::IsIndirectControl);
1223 /* Also set flags on the macroop so that pre-microop decomposition
1224 branch prediction can work */
1225 setFlag(StaticInst::IsControl);
1226 setFlag(StaticInst::IsIndirectControl);
1227 if (conditional) {
1228 uops[2]->setFlag(StaticInst::IsCondControl);
1229 setFlag(StaticInst::IsCondControl);
1230 } else {
1231 uops[2]->setFlag(StaticInst::IsUncondControl);
1232 setFlag(StaticInst::IsUncondControl);
1233 }
1234 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) {
1235 uops[2]->setFlag(StaticInst::IsReturn);
1236 setFlag(StaticInst::IsReturn);
1237 }
1238 uops[2]->setLastMicroop();
1239 } else {
1240 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1241 uops[0]->setDelayedCommit();
1242 uops[0]->setFirstMicroop();
1243 uops[1] = new %(wb_decl)s;
1244 uops[1]->setLastMicroop();
1245 }
1246#else
1247 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1248 flags[IsControl] = true;
1249 flags[IsIndirectControl] = true;
1250 if (conditional)
1251 flags[IsCondControl] = true;
1252 else
1253 flags[IsUncondControl] = true;
1254 }
1255#endif
1256 }
1257}};
1258