arch-power: Update copyrights
[gem5.git] / src / arch / power / isa / formats / integer.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2009 The University of Edinburgh
4 // Copyright (c) 2021 IBM Corporation
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met: redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer;
11 // redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution;
14 // neither the name of the copyright holders nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 ////////////////////////////////////////////////////////////////////
31 //
32 // Integer ALU instructions
33 //
34
35
36 // Instruction class constructor template when Rc is set.
37 def template IntRcConstructor {{
38 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
39 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
40 {
41 %(set_reg_idx_arr)s;
42 %(constructor)s;
43 rcSet = true;
44 }
45 }};
46
47
48 // Instruction class constructor template when OE is set.
49 def template IntOeConstructor {{
50 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
51 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
52 {
53 %(set_reg_idx_arr)s;
54 %(constructor)s;
55 oeSet = true;
56 }
57 }};
58
59
60 // Instruction class constructor template when both Rc and OE are set.
61 def template IntRcOeConstructor {{
62 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
63 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
64 {
65 %(set_reg_idx_arr)s;
66 %(constructor)s;
67 rcSet = true;
68 oeSet = true;
69 }
70 }};
71
72
73 let {{
74
75 readXERCode = 'M5_VAR_USED Xer xer = XER;'
76
77 setXERCode = 'XER = xer;'
78
79 computeCR0Code = '''
80 {
81 Cr cr = CR;
82 Msr msr = MSR;
83 cr.cr0 = msr.sf ?
84 makeCRField((int64_t)%(result)s, (int64_t)0, xer.so) :
85 makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
86 CR = cr;
87 }
88 '''
89
90 computeCACode = '''
91 {
92 Msr msr = MSR;
93 if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
94 xer.ca = 1;
95 xer.ca32 = 1;
96 } else {
97 xer.ca = 0;
98 xer.ca32 = 0;
99 }
100
101 if (msr.sf) {
102 if (findCarry(64, %(result)s, %(inputa)s, %(inputb)s)) {
103 xer.ca = 1;
104 } else {
105 xer.ca = 0;
106 }
107 }
108 }
109 '''
110
111 computeOVCode = '''
112 {
113 Msr msr = MSR;
114 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
115 xer.ov = 1;
116 xer.ov32 = 1;
117 } else {
118 xer.ov = 0;
119 xer.ov32 = 0;
120 }
121
122 if (msr.sf) {
123 if (findOverflow(64, %(result)s, %(inputa)s, %(inputb)s)) {
124 xer.ov = 1;
125 } else {
126 xer.ov = 0;
127 }
128 }
129
130 if (xer.ov) {
131 xer.so = 1;
132 }
133 }
134 '''
135
136 setCACode = '''
137 if (setCA) {
138 xer.ca = 1;
139 xer.ca32 = 1;
140 } else {
141 xer.ca = 0;
142 xer.ca32 = 0;
143 }
144 '''
145
146 setOVCode = '''
147 if (setOV) {
148 xer.ov = 1;
149 xer.ov32 = 1;
150 xer.so = 1;
151 } else {
152 xer.ov = 0;
153 xer.ov32 = 0;
154 }
155 '''
156
157 }};
158
159
160 // A basic integer instruction.
161 def format IntOp(code, inst_flags = []) {{
162 (header_output, decoder_output, decode_block, exec_output) = \
163 GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
164 BasicConstructor)
165 }};
166
167
168 // Integer instructions with immediate (signed or unsigned).
169 def format IntImmOp(code, inst_flags = []) {{
170 (header_output, decoder_output, decode_block, exec_output) = \
171 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
172 BasicConstructor)
173 }};
174
175
176 // Integer instructions with immediate that perform arithmetic.
177 // These instructions all write to Rt and use an altered form of the
178 // value in source register Ra, hence the use of src to hold the actual
179 // value. The control flags include the use of code to compute the
180 // carry bit or the CR0 code.
181 def format IntImmArithOp(code, computeCA = 0, computeCR0 = 0,
182 inst_flags = []) {{
183
184 # Set up the dictionary
185 dict = {'result':'Rt', 'inputa':'src', 'inputb':'simm'}
186
187 # Deal with computing CR0 and carry
188 if computeCA or computeCR0:
189 code += readXERCode
190 if computeCA:
191 code += computeCACode % dict + setXERCode
192 if computeCR0:
193 code += computeCR0Code % dict
194
195 # Generate the class
196 (header_output, decoder_output, decode_block, exec_output) = \
197 GenAluOp(name, Name, 'IntImmArithOp', code, inst_flags, BasicDecode,
198 BasicConstructor)
199 }};
200
201
202 // Integer instructions with immediate that perform arithmetic but use
203 // the value 0 when Ra == 0. We generate two versions of each instruction
204 // corresponding to these two different scenarios. The correct version is
205 // determined at decode (see the CheckRaDecode template).
206 def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
207
208 # First the version where Ra is non-zero
209 (header_output, decoder_output, decode_block, exec_output) = \
210 GenAluOp(name, Name, 'IntImmArithOp', code, inst_flags,
211 CheckRaDecode, BasicConstructor)
212
213 # Now another version where Ra == 0
214 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
215 GenAluOp(name, Name + 'RaZero', 'IntImmArithOp', code_ra0, inst_flags,
216 CheckRaDecode, BasicConstructor)
217
218 # Finally, add to the other outputs
219 header_output += header_output_ra0
220 decoder_output += decoder_output_ra0
221 exec_output += exec_output_ra0
222 }};
223
224
225 // Integer instructions with immediate that perform logic operations.
226 // All instructions write to Ra and use Rs as a source register. Some
227 // also compute the CR0 code too.
228 def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
229
230 # Set up the dictionary and deal with computing CR0
231 dict = {'result':'Ra'}
232
233 # Code when Rc is set
234 if computeCR0:
235 code += readXERCode + computeCR0Code % dict
236
237 # Generate the class
238 (header_output, decoder_output, decode_block, exec_output) = \
239 GenAluOp(name, Name, 'IntImmLogicOp', code, inst_flags, BasicDecode,
240 BasicConstructor)
241 }};
242
243
244 // Integer instructions with displacement that perform arithmetic.
245 // There are no control flags to set.
246 def format IntDispArithOp(code, inst_flags = []) {{
247
248 # Generate the class
249 (header_output, decoder_output, decode_block, exec_output) = \
250 GenAluOp(name, Name, 'IntDispArithOp', code, inst_flags, BasicDecode,
251 BasicConstructor)
252 }};
253
254
255 // Integer compare instructions.
256 def format IntCompOp(code, inst_flags = []) {{
257
258 # Add code to setup variables
259 code = 'M5_VAR_USED uint32_t cr = 0;\n' + code
260 code += 'CR = insertCRField(CR, field, cr);\n'
261
262 # Add code to access XER
263 code = readXERCode + code
264
265 # Generate the class
266 (header_output, decoder_output, decode_block, exec_output) = \
267 GenAluOp(name, Name, 'IntCompOp', code, inst_flags, BasicDecode,
268 BasicConstructor)
269 }};
270
271
272 // Integer immediate compare instructions.
273 def format IntImmCompOp(code, inst_flags = []) {{
274
275 # Add code to setup variables
276 code = 'M5_VAR_USED uint32_t cr = 0;\n' + code
277 code += 'CR = insertCRField(CR, field, cr);\n'
278
279 # Add code to access XER
280 code = readXERCode + code
281
282 # Generate the class
283 (header_output, decoder_output, decode_block, exec_output) = \
284 GenAluOp(name, Name, 'IntImmCompOp', code, inst_flags, BasicDecode,
285 BasicConstructor)
286 }};
287
288
289 // Integer immediate compare logical instructions.
290 def format IntImmCompLogicOp(code, inst_flags = []) {{
291
292 # Add code to setup variables
293 code = 'M5_VAR_USED uint32_t cr = 0;\n' + code
294 code += 'CR = insertCRField(CR, field, cr);\n'
295
296 # Add code to access XER
297 code = readXERCode + code
298
299 # Generate the class
300 (header_output, decoder_output, decode_block, exec_output) = \
301 GenAluOp(name, Name, 'IntImmCompLogicOp', code, inst_flags,
302 BasicDecode, BasicConstructor)
303 }};
304
305
306 // Integer instructions that perform logic operations. The result is
307 // always written into Ra. Some instructions have 2 versions depending on
308 // whether the Rc bit is set to compute the CR0 code. This is determined
309 // at decode as before.
310 def format IntLogicOp(code, computeCR0 = 0, inst_flags = []) {{
311 dict = {'result':'Ra'}
312
313 # Deal with computing CR0
314 if computeCR0:
315 # Setup the 2 code versions and add code to access XER if necessary
316 code_rc1 = code + readXERCode + computeCR0Code % dict
317
318 # Generate the first class
319 (header_output, decoder_output, decode_block, exec_output) = \
320 GenAluOp(name, Name, 'IntLogicOp', code, inst_flags,
321 CheckRcDecode, BasicConstructor)
322
323 # Generate the second class
324 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
325 GenAluOp(name, Name + 'RcSet', 'IntLogicOp', code_rc1, inst_flags,
326 CheckRcDecode, IntRcConstructor)
327
328 # Finally, add to the other outputs
329 header_output += header_output_rc1
330 decoder_output += decoder_output_rc1
331 exec_output += exec_output_rc1
332
333 else:
334 # Generate the class
335 (header_output, decoder_output, decode_block, exec_output) = \
336 GenAluOp(name, Name, 'IntLogicOp', code, inst_flags,
337 BasicDecode, BasicConstructor)
338 }};
339
340
341 // Integer instructions that perform shift operations. All of these
342 // instructions write to Ra and use Rs as a source register. The shift
343 // value is obtained from an register or an instruction field. If it
344 // from a register, Rb is also used as a source register. In certain
345 // situations, the carry bits have to be set and this is dealt with
346 // using the 'setCA' boolean in decoder.isa. We need two versions for
347 // each instruction to deal with the Rc bit.
348 def format IntShiftOp(code, computeCA = 0, inst_flags = []) {{
349 dict = {'result':'Ra'}
350
351 # Add code to setup variables and access XER if necessary
352 code = 'M5_VAR_USED bool setCA = false;\n' + code
353
354 # Code when Rc is set
355 code_rc1 = readXERCode + code + computeCR0Code % dict
356
357 # Add code for calculating the carry, if needed
358 if computeCA:
359 code = readXERCode + code + setCACode + setXERCode
360 code_rc1 += setCACode + setXERCode
361
362 # Generate the first class
363 (header_output, decoder_output, decode_block, exec_output) = \
364 GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
365 CheckRcDecode, BasicConstructor)
366
367 # Generate the second class
368 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
369 GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
370 CheckRcDecode, IntRcConstructor)
371
372 # Finally, add to the other outputs
373 header_output += header_output_rc1
374 decoder_output += decoder_output_rc1
375 exec_output += exec_output_rc1
376 }};
377
378
379 // Instructions in this format are all reduced to the form Rt = src1 + src2,
380 // therefore we just give src1 and src2 definitions. In working out the
381 // template we first put in the definitions of the variables and then
382 // the code for the addition. We also deal with computing the carry flag
383 // if required.
384 //
385 // We generate 4 versions of each instruction. This correspond to the
386 // different combinations of having the OE bit set or unset (which controls
387 // whether the overflow flag is computed) and the Rc bit set or unset too
388 // (which controls whether the CR0 code is computed).
389 def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
390 inst_flags = []) {{
391
392 # The result is always in Rt, but the source values vary
393 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
394
395 # Add code to set up variables and do the sum
396 code = 'uint64_t src1 = ' + src1 + ';\n'
397 code += 'uint64_t src2 = ' + src2 + ';\n'
398 code += 'uint64_t ca = ' + ca + ';\n'
399 code += 'Rt = src1 + src2 + ca;\n'
400
401 # Add code for calculating the carry, if needed
402 if computeCA:
403 code += computeCACode % dict + setXERCode
404
405 # Setup the 4 code versions and add code to access XER if necessary
406 code_rc1 = readXERCode + code
407 code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
408 code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
409 if (computeCA or ca == 'xer.ca'):
410 code = readXERCode + code
411 code_rc1 += computeCR0Code % dict
412 code_rc1_oe1 += computeCR0Code % dict
413
414 # Generate the classes
415 (header_output, decoder_output, decode_block, exec_output) = \
416 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
417 CheckRcOeDecode, BasicConstructor)
418 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
419 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
420 CheckRcOeDecode, IntRcConstructor)
421 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
422 GenAluOp(name, Name + 'OeSet', 'IntArithOp', code_oe1, inst_flags,
423 CheckRcOeDecode, IntOeConstructor)
424 (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
425 GenAluOp(name, Name + 'RcSetOeSet', 'IntArithOp', code_rc1_oe1,
426 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
427
428 # Finally, add to the other outputs
429 header_output += \
430 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
431 decoder_output += \
432 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
433 exec_output += \
434 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
435
436 }};
437
438 // Instructions that use source registers Ra and Rb, with the result
439 // placed into Rt but do not check for carry, overflow or the Rc bit.
440 def format IntArithOp(code, inst_flags = []) {{
441
442 # Generate the class
443 (header_output, decoder_output, decode_block, exec_output) = \
444 GenAluOp(name, Name, 'IntArithOp', code, inst_flags, BasicDecode,
445 BasicConstructor)
446 }};
447
448
449 // Instructions that use source registers Ra and Rb, with the result
450 // placed into Rt. Basically multiply and divide instructions. The
451 // carry bit is never set, but overflow can be calculated. In certain
452 // situations, the overflow bits have to be set and this is dealt with
453 // using the 'setOV' boolean in decoder.isa.
454 //
455 // In case overflow is to be calculated, we generate four versions of
456 // each instruction to deal with different combinations of having the
457 // OE bit set or unset and the Rc bit set or unset too. Otherwise, we
458 // generate two versions of each instruction to deal with the Rc bit.
459 def format IntArithCheckRcOp(code, computeOV = 0, inst_flags = []) {{
460
461 # The result is always in Rt, but the source values vary
462 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
463
464 # Deal with setting the overflow flag
465 if computeOV:
466 # Setup the 4 code versions and add code to access XER if necessary
467 code = 'M5_VAR_USED bool setOV = false;\n' + code
468 code_rc1 = readXERCode + code + computeCR0Code % dict
469 code_oe1 = readXERCode + code + setOVCode + setXERCode
470 code_rc1_oe1 = readXERCode + code + setOVCode + setXERCode
471 code_rc1_oe1 += computeCR0Code % dict
472
473 # Generate the classes
474 (header_output, decoder_output, decode_block, exec_output) = \
475 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
476 CheckRcOeDecode, BasicConstructor)
477 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
478 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
479 CheckRcOeDecode, IntRcConstructor)
480 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
481 GenAluOp(name, Name + 'OeSet', 'IntArithOp', code_oe1, inst_flags,
482 CheckRcOeDecode, IntOeConstructor)
483 (header_output_rc1_oe1, decoder_output_rc1_oe1, _,
484 exec_output_rc1_oe1) = \
485 GenAluOp(name, Name + 'RcSetOeSet', 'IntArithOp', code_rc1_oe1,
486 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
487
488 # Finally, add to the other outputs
489 header_output += \
490 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
491 decoder_output += \
492 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
493 exec_output += \
494 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
495
496 else:
497 # Setup the 2 code versions and add code to access XER if necessary
498 code_rc1 = readXERCode + code + computeCR0Code % dict
499
500 # Generate the first class
501 (header_output, decoder_output, decode_block, exec_output) = \
502 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
503 CheckRcDecode, BasicConstructor)
504
505 # Generate the second class
506 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
507 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
508 CheckRcDecode, IntRcConstructor)
509
510 # Finally, add to the other outputs
511 header_output += header_output_rc1
512 decoder_output += decoder_output_rc1
513 exec_output += exec_output_rc1
514 }};
515
516
517 // Integer instructions that also perform shift operations. Everything
518 // is same as above except if the shift value is not obtained from a
519 // register, two immediates need to be concatenated to get the final
520 // shift value.
521 def format IntConcatShiftOp(code, computeCA = 0, inst_flags = []) {{
522 dict = {'result':'Ra'}
523
524 # Add code to setup variables and access XER if necessary
525 code = 'M5_VAR_USED bool setCA = false;\n' + code
526
527 # Code when Rc is set
528 code_rc1 = readXERCode + code + computeCR0Code % dict
529
530 # Add code for calculating the carry, if needed
531 if computeCA:
532 code = readXERCode + code + setCACode + setXERCode
533 code_rc1 += setCACode + setXERCode
534
535 # Generate the first class
536 (header_output, decoder_output, decode_block, exec_output) = \
537 GenAluOp(name, Name, 'IntConcatShiftOp', code, inst_flags,
538 CheckRcDecode, BasicConstructor)
539
540 # Generate the second class
541 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
542 GenAluOp(name, Name + 'RcSet', 'IntConcatShiftOp', code_rc1,
543 inst_flags, CheckRcDecode, IntRcConstructor)
544
545 # Finally, add to the other outputs
546 header_output += header_output_rc1
547 decoder_output += decoder_output_rc1
548 exec_output += exec_output_rc1
549 }};
550
551
552 // Integer instructions with or without immediate that perform rotate
553 // operations. All instructions write to Ra and use Rs as a source
554 // register. If immediate is not used, Rb is also used as a source
555 // register. We need two versions for each instruction to deal with
556 // the Rc bit.
557 def format IntRotateOp(code, inst_flags = []) {{
558
559 # The result is always in Ra
560 dict = {'result':'Ra'}
561
562 # Code when Rc is set
563 code_rc1 = readXERCode + code + computeCR0Code % dict
564
565 # Generate the first class
566 (header_output, decoder_output, decode_block, exec_output) = \
567 GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
568 CheckRcDecode, BasicConstructor)
569
570 # Generate the second class
571 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
572 GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
573 CheckRcDecode, IntRcConstructor)
574
575 # Finally, add to the other outputs
576 header_output += header_output_rc1
577 decoder_output += decoder_output_rc1
578 exec_output += exec_output_rc1
579 }};
580
581
582 // Everything is same as above except that the immediates may need to be
583 // concatenated to get the final values for the mask bounds or the shift
584 // value. We need two versions for each instruction to deal with the Rc
585 // bit.
586 def format IntConcatRotateOp(code, inst_flags = []) {{
587
588 # The result is always in Ra
589 dict = {'result':'Ra'}
590
591 # Code when Rc is set
592 code_rc1 = readXERCode + code + computeCR0Code % dict
593
594 # Generate the first class
595 (header_output, decoder_output, decode_block, exec_output) = \
596 GenAluOp(name, Name, 'IntConcatRotateOp', code, inst_flags,
597 CheckRcDecode, BasicConstructor)
598
599 # Generate the second class
600 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
601 GenAluOp(name, Name + 'RcSet', 'IntConcatRotateOp', code_rc1,
602 inst_flags, CheckRcDecode, IntRcConstructor)
603
604 # Finally, add to the other outputs
605 header_output += header_output_rc1
606 decoder_output += decoder_output_rc1
607 exec_output += exec_output_rc1
608 }};
609
610
611 def format IntTrapOp(src1, src2, inst_flags = []) {{
612
613 # Add code to set up variables and check for a trap
614 code = 'int64_t src1 = ' + src1 + ';\n'
615 code += 'int64_t src2 = ' + src2 + ';\n'
616 code += 'if (checkTrap(src1, src2)) {\n'
617 code += ' panic("trap generated at %#x", xc->pcState().pc());\n'
618 code += ' return std::make_shared<TrapFault>();\n'
619 code += '}\n'
620
621 (header_output, decoder_output, decode_block, exec_output) = \
622 GenAluOp(name, Name, 'IntTrapOp', code, inst_flags, BasicDecode,
623 BasicConstructor)
624 }};
625
626
627 def format IntImmTrapOp(src, inst_flags = []) {{
628
629 # Add code to set up variables and check for a trap
630 code = 'int64_t src = ' + src + ';\n'
631 code += 'if (checkTrap(src, this->simm)) {\n'
632 code += ' panic("trap generated at %#x", xc->pcState().pc());\n'
633 code += ' return std::make_shared<TrapFault>();\n'
634 code += '}\n'
635
636 (header_output, decoder_output, decode_block, exec_output) = \
637 GenAluOp(name, Name, 'IntImmTrapOp', code, inst_flags, BasicDecode,
638 BasicConstructor)
639 }};