misc: Merge branch hotfix v20.1.0.2 branch into develop
[gem5.git] / src / arch / riscv / isa / decoder.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2017 The University of Virginia
5 // Copyright (c) 2020 Barkhausen Institut
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met: redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer;
12 // redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution;
15 // neither the name of the copyright holders nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 ////////////////////////////////////////////////////////////////////
32 //
33 // The RISC-V ISA decoder
34 //
35
36 decode QUADRANT default Unknown::unknown() {
37 0x0: decode COPCODE {
38 0x0: CIAddi4spnOp::c_addi4spn({{
39 imm = CIMM8<1:1> << 2 |
40 CIMM8<0:0> << 3 |
41 CIMM8<7:6> << 4 |
42 CIMM8<5:2> << 6;
43 }}, {{
44 if (machInst == 0)
45 fault = make_shared<IllegalInstFault>("zero instruction",
46 machInst);
47 Rp2 = sp + imm;
48 }}, uint64_t);
49 format CompressedLoad {
50 0x1: c_fld({{
51 offset = CIMM3 << 3 | CIMM2 << 6;
52 }}, {{
53 STATUS status = xc->readMiscReg(MISCREG_STATUS);
54 if (status.fs == FPUStatus::OFF)
55 fault = make_shared<IllegalInstFault>("FPU is off",
56 machInst);
57
58 Fp2_bits = Mem;
59 }}, {{
60 EA = Rp1 + offset;
61 }});
62 0x2: c_lw({{
63 offset = CIMM2<1:1> << 2 |
64 CIMM3 << 3 |
65 CIMM2<0:0> << 6;
66 }}, {{
67 Rp2_sd = Mem_sw;
68 }}, {{
69 EA = Rp1 + offset;
70 }});
71 0x3: c_ld({{
72 offset = CIMM3 << 3 | CIMM2 << 6;
73 }}, {{
74 Rp2_sd = Mem_sd;
75 }}, {{
76 EA = Rp1 + offset;
77 }});
78 }
79 format CompressedStore {
80 0x5: c_fsd({{
81 offset = CIMM3 << 3 | CIMM2 << 6;
82 }}, {{
83 STATUS status = xc->readMiscReg(MISCREG_STATUS);
84 if (status.fs == FPUStatus::OFF)
85 fault = make_shared<IllegalInstFault>("FPU is off",
86 machInst);
87
88 Mem = Fp2_bits;
89 }}, {{
90 EA = Rp1 + offset;
91 }});
92 0x6: c_sw({{
93 offset = CIMM2<1:1> << 2 |
94 CIMM3 << 3 |
95 CIMM2<0:0> << 6;
96 }}, {{
97 Mem_uw = Rp2_uw;
98 }}, ea_code={{
99 EA = Rp1 + offset;
100 }});
101 0x7: c_sd({{
102 offset = CIMM3 << 3 | CIMM2 << 6;
103 }}, {{
104 Mem_ud = Rp2_ud;
105 }}, {{
106 EA = Rp1 + offset;
107 }});
108 }
109 }
110 0x1: decode COPCODE {
111 format CIOp {
112 0x0: c_addi({{
113 imm = CIMM5;
114 if (CIMM1 > 0)
115 imm |= ~((uint64_t)0x1F);
116 }}, {{
117 if ((RC1 == 0) != (imm == 0)) {
118 if (RC1 == 0) {
119 fault = make_shared<IllegalInstFault>("source reg x0",
120 machInst);
121 } else // imm == 0
122 fault = make_shared<IllegalInstFault>("immediate = 0",
123 machInst);
124 }
125 Rc1_sd = Rc1_sd + imm;
126 }});
127 0x1: c_addiw({{
128 imm = CIMM5;
129 if (CIMM1 > 0)
130 imm |= ~((uint64_t)0x1F);
131 }}, {{
132 if (RC1 == 0) {
133 fault = make_shared<IllegalInstFault>("source reg x0",
134 machInst);
135 }
136 Rc1_sd = (int32_t)Rc1_sd + imm;
137 }});
138 0x2: c_li({{
139 imm = CIMM5;
140 if (CIMM1 > 0)
141 imm |= ~((uint64_t)0x1F);
142 }}, {{
143 if (RC1 == 0) {
144 fault = make_shared<IllegalInstFault>("source reg x0",
145 machInst);
146 }
147 Rc1_sd = imm;
148 }});
149 0x3: decode RC1 {
150 0x2: c_addi16sp({{
151 imm = CIMM5<4:4> << 4 |
152 CIMM5<0:0> << 5 |
153 CIMM5<3:3> << 6 |
154 CIMM5<2:1> << 7;
155 if (CIMM1 > 0)
156 imm |= ~((int64_t)0x1FF);
157 }}, {{
158 if (imm == 0) {
159 fault = make_shared<IllegalInstFault>("immediate = 0",
160 machInst);
161 }
162 sp_sd = sp_sd + imm;
163 }});
164 default: c_lui({{
165 imm = CIMM5 << 12;
166 if (CIMM1 > 0)
167 imm |= ~((uint64_t)0x1FFFF);
168 }}, {{
169 if (RC1 == 0 || RC1 == 2) {
170 fault = make_shared<IllegalInstFault>("source reg x0",
171 machInst);
172 }
173 if (imm == 0) {
174 fault = make_shared<IllegalInstFault>("immediate = 0",
175 machInst);
176 }
177 Rc1_sd = imm;
178 }});
179 }
180 }
181 0x4: decode CFUNCT2HIGH {
182 format CIOp {
183 0x0: c_srli({{
184 imm = CIMM5 | (CIMM1 << 5);
185 }}, {{
186 if (imm == 0) {
187 fault = make_shared<IllegalInstFault>("immediate = 0",
188 machInst);
189 }
190 Rp1 = Rp1 >> imm;
191 }}, uint64_t);
192 0x1: c_srai({{
193 imm = CIMM5 | (CIMM1 << 5);
194 }}, {{
195 if (imm == 0) {
196 fault = make_shared<IllegalInstFault>("immediate = 0",
197 machInst);
198 }
199 Rp1_sd = Rp1_sd >> imm;
200 }}, uint64_t);
201 0x2: c_andi({{
202 imm = CIMM5;
203 if (CIMM1 > 0)
204 imm |= ~((uint64_t)0x1F);
205 }}, {{
206 Rp1 = Rp1 & imm;
207 }}, uint64_t);
208 }
209 format CompressedROp {
210 0x3: decode CFUNCT1 {
211 0x0: decode CFUNCT2LOW {
212 0x0: c_sub({{
213 Rp1 = Rp1 - Rp2;
214 }});
215 0x1: c_xor({{
216 Rp1 = Rp1 ^ Rp2;
217 }});
218 0x2: c_or({{
219 Rp1 = Rp1 | Rp2;
220 }});
221 0x3: c_and({{
222 Rp1 = Rp1 & Rp2;
223 }});
224 }
225 0x1: decode CFUNCT2LOW {
226 0x0: c_subw({{
227 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
228 }});
229 0x1: c_addw({{
230 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
231 }});
232 }
233 }
234 }
235 }
236 0x5: CJOp::c_j({{
237 NPC = PC + imm;
238 }}, IsDirectControl, IsUncondControl);
239 format CBOp {
240 0x6: c_beqz({{
241 if (Rp1 == 0)
242 NPC = PC + imm;
243 else
244 NPC = NPC;
245 }}, IsDirectControl, IsCondControl);
246 0x7: c_bnez({{
247 if (Rp1 != 0)
248 NPC = PC + imm;
249 else
250 NPC = NPC;
251 }}, IsDirectControl, IsCondControl);
252 }
253 }
254 0x2: decode COPCODE {
255 0x0: CIOp::c_slli({{
256 imm = CIMM5 | (CIMM1 << 5);
257 }}, {{
258 if (imm == 0) {
259 fault = make_shared<IllegalInstFault>("immediate = 0",
260 machInst);
261 }
262 if (RC1 == 0) {
263 fault = make_shared<IllegalInstFault>("source reg x0",
264 machInst);
265 }
266 Rc1 = Rc1 << imm;
267 }}, uint64_t);
268 format CompressedLoad {
269 0x1: c_fldsp({{
270 offset = CIMM5<4:3> << 3 |
271 CIMM1 << 5 |
272 CIMM5<2:0> << 6;
273 }}, {{
274 Fc1_bits = Mem;
275 }}, {{
276 EA = sp + offset;
277 }});
278 0x2: c_lwsp({{
279 offset = CIMM5<4:2> << 2 |
280 CIMM1 << 5 |
281 CIMM5<1:0> << 6;
282 }}, {{
283 if (RC1 == 0) {
284 fault = make_shared<IllegalInstFault>("source reg x0",
285 machInst);
286 }
287 Rc1_sd = Mem_sw;
288 }}, {{
289 EA = sp + offset;
290 }});
291 0x3: c_ldsp({{
292 offset = CIMM5<4:3> << 3 |
293 CIMM1 << 5 |
294 CIMM5<2:0> << 6;
295 }}, {{
296 if (RC1 == 0) {
297 fault = make_shared<IllegalInstFault>("source reg x0",
298 machInst);
299 }
300 Rc1_sd = Mem_sd;
301 }}, {{
302 EA = sp + offset;
303 }});
304 }
305 0x4: decode CFUNCT1 {
306 0x0: decode RC2 {
307 0x0: Jump::c_jr({{
308 if (RC1 == 0) {
309 fault = make_shared<IllegalInstFault>("source reg x0",
310 machInst);
311 }
312 NPC = Rc1;
313 }}, IsIndirectControl, IsUncondControl, IsCall);
314 default: CROp::c_mv({{
315 if (RC1 == 0) {
316 fault = make_shared<IllegalInstFault>("source reg x0",
317 machInst);
318 }
319 Rc1 = Rc2;
320 }});
321 }
322 0x1: decode RC1 {
323 0x0: SystemOp::c_ebreak({{
324 if (RC2 != 0) {
325 fault = make_shared<IllegalInstFault>("source reg x1",
326 machInst);
327 }
328 fault = make_shared<BreakpointFault>(xc->pcState());
329 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
330 default: decode RC2 {
331 0x0: Jump::c_jalr({{
332 if (RC1 == 0) {
333 fault = make_shared<IllegalInstFault>
334 ("source reg x0",
335 machInst);
336 }
337 ra = NPC;
338 NPC = Rc1;
339 }}, IsIndirectControl, IsUncondControl, IsCall);
340 default: CompressedROp::c_add({{
341 Rc1_sd = Rc1_sd + Rc2_sd;
342 }});
343 }
344 }
345 }
346 format CompressedStore {
347 0x5: c_fsdsp({{
348 offset = CIMM6<5:3> << 3 |
349 CIMM6<2:0> << 6;
350 }}, {{
351 Mem_ud = Fc2_bits;
352 }}, {{
353 EA = sp + offset;
354 }});
355 0x6: c_swsp({{
356 offset = CIMM6<5:2> << 2 |
357 CIMM6<1:0> << 6;
358 }}, {{
359 Mem_uw = Rc2_uw;
360 }}, {{
361 EA = sp + offset;
362 }});
363 0x7: c_sdsp({{
364 offset = CIMM6<5:3> << 3 |
365 CIMM6<2:0> << 6;
366 }}, {{
367 Mem = Rc2;
368 }}, {{
369 EA = sp + offset;
370 }});
371 }
372 }
373 0x3: decode OPCODE {
374 0x00: decode FUNCT3 {
375 format Load {
376 0x0: lb({{
377 Rd_sd = Mem_sb;
378 }});
379 0x1: lh({{
380 Rd_sd = Mem_sh;
381 }});
382 0x2: lw({{
383 Rd_sd = Mem_sw;
384 }});
385 0x3: ld({{
386 Rd_sd = Mem_sd;
387 }});
388 0x4: lbu({{
389 Rd = Mem_ub;
390 }});
391 0x5: lhu({{
392 Rd = Mem_uh;
393 }});
394 0x6: lwu({{
395 Rd = Mem_uw;
396 }});
397 }
398 }
399
400 0x01: decode FUNCT3 {
401 format Load {
402 0x2: flw({{
403 STATUS status = xc->readMiscReg(MISCREG_STATUS);
404 if (status.fs == FPUStatus::OFF)
405 fault = make_shared<IllegalInstFault>("FPU is off",
406 machInst);
407
408 Fd_bits = (uint64_t)Mem_uw;
409 }}, inst_flags=FloatMemReadOp);
410 0x3: fld({{
411 STATUS status = xc->readMiscReg(MISCREG_STATUS);
412 if (status.fs == FPUStatus::OFF)
413 fault = make_shared<IllegalInstFault>("FPU is off",
414 machInst);
415
416 Fd_bits = Mem;
417 }}, inst_flags=FloatMemReadOp);
418 }
419 }
420
421 0x03: decode FUNCT3 {
422 format FenceOp {
423 0x0: fence({{
424 }}, uint64_t, IsReadBarrier, IsWriteBarrier, No_OpClass);
425 0x1: fence_i({{
426 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
427 }
428 }
429
430 0x04: decode FUNCT3 {
431 format IOp {
432 0x0: addi({{
433 Rd_sd = Rs1_sd + imm;
434 }});
435 0x1: slli({{
436 Rd = Rs1 << imm;
437 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
438 0x2: slti({{
439 Rd = (Rs1_sd < imm) ? 1 : 0;
440 }});
441 0x3: sltiu({{
442 Rd = (Rs1 < imm) ? 1 : 0;
443 }}, uint64_t);
444 0x4: xori({{
445 Rd = Rs1 ^ imm;
446 }}, uint64_t);
447 0x5: decode SRTYPE {
448 0x0: srli({{
449 Rd = Rs1 >> imm;
450 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
451 0x1: srai({{
452 Rd_sd = Rs1_sd >> imm;
453 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
454 }
455 0x6: ori({{
456 Rd = Rs1 | imm;
457 }}, uint64_t);
458 0x7: andi({{
459 Rd = Rs1 & imm;
460 }}, uint64_t);
461 }
462 }
463
464 0x05: UOp::auipc({{
465 Rd = PC + (sext<20>(imm) << 12);
466 }});
467
468 0x06: decode FUNCT3 {
469 format IOp {
470 0x0: addiw({{
471 Rd_sd = Rs1_sw + imm;
472 }}, int32_t);
473 0x1: slliw({{
474 Rd_sd = Rs1_sw << imm;
475 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
476 0x5: decode SRTYPE {
477 0x0: srliw({{
478 Rd_sd = (int32_t)(Rs1_uw >> imm);
479 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
480 0x1: sraiw({{
481 Rd_sd = Rs1_sw >> imm;
482 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
483 }
484 }
485 }
486
487 0x08: decode FUNCT3 {
488 format Store {
489 0x0: sb({{
490 Mem_ub = Rs2_ub;
491 }});
492 0x1: sh({{
493 Mem_uh = Rs2_uh;
494 }});
495 0x2: sw({{
496 Mem_uw = Rs2_uw;
497 }});
498 0x3: sd({{
499 Mem_ud = Rs2_ud;
500 }});
501 }
502 }
503
504 0x09: decode FUNCT3 {
505 format Store {
506 0x2: fsw({{
507 STATUS status = xc->readMiscReg(MISCREG_STATUS);
508 if (status.fs == FPUStatus::OFF)
509 fault = make_shared<IllegalInstFault>("FPU is off",
510 machInst);
511
512 Mem_uw = (uint32_t)Fs2_bits;
513 }}, inst_flags=FloatMemWriteOp);
514 0x3: fsd({{
515 STATUS status = xc->readMiscReg(MISCREG_STATUS);
516 if (status.fs == FPUStatus::OFF)
517 fault = make_shared<IllegalInstFault>("FPU is off",
518 machInst);
519
520 Mem_ud = Fs2_bits;
521 }}, inst_flags=FloatMemWriteOp);
522 }
523 }
524
525 0x0b: decode FUNCT3 {
526 0x2: decode AMOFUNCT {
527 0x2: LoadReserved::lr_w({{
528 Rd_sd = Mem_sw;
529 }}, mem_flags=LLSC);
530 0x3: StoreCond::sc_w({{
531 Mem_uw = Rs2_uw;
532 }}, {{
533 Rd = result;
534 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
535 0x0: AtomicMemOp::amoadd_w({{
536 Rd_sd = Mem_sw;
537 }}, {{
538 TypedAtomicOpFunctor<int32_t> *amo_op =
539 new AtomicGenericOp<int32_t>(Rs2_sw,
540 [](int32_t* b, int32_t a){ *b += a; });
541 }}, mem_flags=ATOMIC_RETURN_OP);
542 0x1: AtomicMemOp::amoswap_w({{
543 Rd_sd = Mem_sw;
544 }}, {{
545 TypedAtomicOpFunctor<uint32_t> *amo_op =
546 new AtomicGenericOp<uint32_t>(Rs2_uw,
547 [](uint32_t* b, uint32_t a){ *b = a; });
548 }}, mem_flags=ATOMIC_RETURN_OP);
549 0x4: AtomicMemOp::amoxor_w({{
550 Rd_sd = Mem_sw;
551 }}, {{
552 TypedAtomicOpFunctor<uint32_t> *amo_op =
553 new AtomicGenericOp<uint32_t>(Rs2_uw,
554 [](uint32_t* b, uint32_t a){ *b ^= a; });
555 }}, mem_flags=ATOMIC_RETURN_OP);
556 0x8: AtomicMemOp::amoor_w({{
557 Rd_sd = Mem_sw;
558 }}, {{
559 TypedAtomicOpFunctor<uint32_t> *amo_op =
560 new AtomicGenericOp<uint32_t>(Rs2_uw,
561 [](uint32_t* b, uint32_t a){ *b |= a; });
562 }}, mem_flags=ATOMIC_RETURN_OP);
563 0xc: AtomicMemOp::amoand_w({{
564 Rd_sd = Mem_sw;
565 }}, {{
566 TypedAtomicOpFunctor<uint32_t> *amo_op =
567 new AtomicGenericOp<uint32_t>(Rs2_uw,
568 [](uint32_t* b, uint32_t a){ *b &= a; });
569 }}, mem_flags=ATOMIC_RETURN_OP);
570 0x10: AtomicMemOp::amomin_w({{
571 Rd_sd = Mem_sw;
572 }}, {{
573 TypedAtomicOpFunctor<int32_t> *amo_op =
574 new AtomicGenericOp<int32_t>(Rs2_sw,
575 [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
576 }}, mem_flags=ATOMIC_RETURN_OP);
577 0x14: AtomicMemOp::amomax_w({{
578 Rd_sd = Mem_sw;
579 }}, {{
580 TypedAtomicOpFunctor<int32_t> *amo_op =
581 new AtomicGenericOp<int32_t>(Rs2_sw,
582 [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
583 }}, mem_flags=ATOMIC_RETURN_OP);
584 0x18: AtomicMemOp::amominu_w({{
585 Rd_sd = Mem_sw;
586 }}, {{
587 TypedAtomicOpFunctor<uint32_t> *amo_op =
588 new AtomicGenericOp<uint32_t>(Rs2_uw,
589 [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
590 }}, mem_flags=ATOMIC_RETURN_OP);
591 0x1c: AtomicMemOp::amomaxu_w({{
592 Rd_sd = Mem_sw;
593 }}, {{
594 TypedAtomicOpFunctor<uint32_t> *amo_op =
595 new AtomicGenericOp<uint32_t>(Rs2_uw,
596 [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
597 }}, mem_flags=ATOMIC_RETURN_OP);
598 }
599 0x3: decode AMOFUNCT {
600 0x2: LoadReserved::lr_d({{
601 Rd_sd = Mem_sd;
602 }}, mem_flags=LLSC);
603 0x3: StoreCond::sc_d({{
604 Mem = Rs2;
605 }}, {{
606 Rd = result;
607 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
608 0x0: AtomicMemOp::amoadd_d({{
609 Rd_sd = Mem_sd;
610 }}, {{
611 TypedAtomicOpFunctor<int64_t> *amo_op =
612 new AtomicGenericOp<int64_t>(Rs2_sd,
613 [](int64_t* b, int64_t a){ *b += a; });
614 }}, mem_flags=ATOMIC_RETURN_OP);
615 0x1: AtomicMemOp::amoswap_d({{
616 Rd_sd = Mem_sd;
617 }}, {{
618 TypedAtomicOpFunctor<uint64_t> *amo_op =
619 new AtomicGenericOp<uint64_t>(Rs2_ud,
620 [](uint64_t* b, uint64_t a){ *b = a; });
621 }}, mem_flags=ATOMIC_RETURN_OP);
622 0x4: AtomicMemOp::amoxor_d({{
623 Rd_sd = Mem_sd;
624 }}, {{
625 TypedAtomicOpFunctor<uint64_t> *amo_op =
626 new AtomicGenericOp<uint64_t>(Rs2_ud,
627 [](uint64_t* b, uint64_t a){ *b ^= a; });
628 }}, mem_flags=ATOMIC_RETURN_OP);
629 0x8: AtomicMemOp::amoor_d({{
630 Rd_sd = Mem_sd;
631 }}, {{
632 TypedAtomicOpFunctor<uint64_t> *amo_op =
633 new AtomicGenericOp<uint64_t>(Rs2_ud,
634 [](uint64_t* b, uint64_t a){ *b |= a; });
635 }}, mem_flags=ATOMIC_RETURN_OP);
636 0xc: AtomicMemOp::amoand_d({{
637 Rd_sd = Mem_sd;
638 }}, {{
639 TypedAtomicOpFunctor<uint64_t> *amo_op =
640 new AtomicGenericOp<uint64_t>(Rs2_ud,
641 [](uint64_t* b, uint64_t a){ *b &= a; });
642 }}, mem_flags=ATOMIC_RETURN_OP);
643 0x10: AtomicMemOp::amomin_d({{
644 Rd_sd = Mem_sd;
645 }}, {{
646 TypedAtomicOpFunctor<int64_t> *amo_op =
647 new AtomicGenericOp<int64_t>(Rs2_sd,
648 [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
649 }}, mem_flags=ATOMIC_RETURN_OP);
650 0x14: AtomicMemOp::amomax_d({{
651 Rd_sd = Mem_sd;
652 }}, {{
653 TypedAtomicOpFunctor<int64_t> *amo_op =
654 new AtomicGenericOp<int64_t>(Rs2_sd,
655 [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
656 }}, mem_flags=ATOMIC_RETURN_OP);
657 0x18: AtomicMemOp::amominu_d({{
658 Rd_sd = Mem_sd;
659 }}, {{
660 TypedAtomicOpFunctor<uint64_t> *amo_op =
661 new AtomicGenericOp<uint64_t>(Rs2_ud,
662 [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
663 }}, mem_flags=ATOMIC_RETURN_OP);
664 0x1c: AtomicMemOp::amomaxu_d({{
665 Rd_sd = Mem_sd;
666 }}, {{
667 TypedAtomicOpFunctor<uint64_t> *amo_op =
668 new AtomicGenericOp<uint64_t>(Rs2_ud,
669 [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
670 }}, mem_flags=ATOMIC_RETURN_OP);
671 }
672 }
673 0x0c: decode FUNCT3 {
674 format ROp {
675 0x0: decode FUNCT7 {
676 0x0: add({{
677 Rd = Rs1_sd + Rs2_sd;
678 }});
679 0x1: mul({{
680 Rd = Rs1_sd*Rs2_sd;
681 }}, IntMultOp);
682 0x20: sub({{
683 Rd = Rs1_sd - Rs2_sd;
684 }});
685 }
686 0x1: decode FUNCT7 {
687 0x0: sll({{
688 Rd = Rs1 << Rs2<5:0>;
689 }});
690 0x1: mulh({{
691 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
692
693 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
694 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
695 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
696 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
697
698 uint64_t hi = Rs1_hi*Rs2_hi;
699 uint64_t mid1 = Rs1_hi*Rs2_lo;
700 uint64_t mid2 = Rs1_lo*Rs2_hi;
701 uint64_t lo = Rs2_lo*Rs1_lo;
702 uint64_t carry = ((uint64_t)(uint32_t)mid1
703 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
704
705 uint64_t res = hi +
706 (mid1 >> 32) +
707 (mid2 >> 32) +
708 carry;
709 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
710 : res;
711 }}, IntMultOp);
712 }
713 0x2: decode FUNCT7 {
714 0x0: slt({{
715 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
716 }});
717 0x1: mulhsu({{
718 bool negate = Rs1_sd < 0;
719 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
720 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
721 uint64_t Rs2_lo = (uint32_t)Rs2;
722 uint64_t Rs2_hi = Rs2 >> 32;
723
724 uint64_t hi = Rs1_hi*Rs2_hi;
725 uint64_t mid1 = Rs1_hi*Rs2_lo;
726 uint64_t mid2 = Rs1_lo*Rs2_hi;
727 uint64_t lo = Rs1_lo*Rs2_lo;
728 uint64_t carry = ((uint64_t)(uint32_t)mid1
729 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
730
731 uint64_t res = hi +
732 (mid1 >> 32) +
733 (mid2 >> 32) +
734 carry;
735 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
736 }}, IntMultOp);
737 }
738 0x3: decode FUNCT7 {
739 0x0: sltu({{
740 Rd = (Rs1 < Rs2) ? 1 : 0;
741 }});
742 0x1: mulhu({{
743 uint64_t Rs1_lo = (uint32_t)Rs1;
744 uint64_t Rs1_hi = Rs1 >> 32;
745 uint64_t Rs2_lo = (uint32_t)Rs2;
746 uint64_t Rs2_hi = Rs2 >> 32;
747
748 uint64_t hi = Rs1_hi*Rs2_hi;
749 uint64_t mid1 = Rs1_hi*Rs2_lo;
750 uint64_t mid2 = Rs1_lo*Rs2_hi;
751 uint64_t lo = Rs1_lo*Rs2_lo;
752 uint64_t carry = ((uint64_t)(uint32_t)mid1
753 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
754
755 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
756 }}, IntMultOp);
757 }
758 0x4: decode FUNCT7 {
759 0x0: xor({{
760 Rd = Rs1 ^ Rs2;
761 }});
762 0x1: div({{
763 if (Rs2_sd == 0) {
764 Rd_sd = -1;
765 } else if (Rs1_sd == numeric_limits<int64_t>::min()
766 && Rs2_sd == -1) {
767 Rd_sd = numeric_limits<int64_t>::min();
768 } else {
769 Rd_sd = Rs1_sd/Rs2_sd;
770 }
771 }}, IntDivOp);
772 }
773 0x5: decode FUNCT7 {
774 0x0: srl({{
775 Rd = Rs1 >> Rs2<5:0>;
776 }});
777 0x1: divu({{
778 if (Rs2 == 0) {
779 Rd = numeric_limits<uint64_t>::max();
780 } else {
781 Rd = Rs1/Rs2;
782 }
783 }}, IntDivOp);
784 0x20: sra({{
785 Rd_sd = Rs1_sd >> Rs2<5:0>;
786 }});
787 }
788 0x6: decode FUNCT7 {
789 0x0: or({{
790 Rd = Rs1 | Rs2;
791 }});
792 0x1: rem({{
793 if (Rs2_sd == 0) {
794 Rd = Rs1_sd;
795 } else if (Rs1_sd == numeric_limits<int64_t>::min()
796 && Rs2_sd == -1) {
797 Rd = 0;
798 } else {
799 Rd = Rs1_sd%Rs2_sd;
800 }
801 }}, IntDivOp);
802 }
803 0x7: decode FUNCT7 {
804 0x0: and({{
805 Rd = Rs1 & Rs2;
806 }});
807 0x1: remu({{
808 if (Rs2 == 0) {
809 Rd = Rs1;
810 } else {
811 Rd = Rs1%Rs2;
812 }
813 }}, IntDivOp);
814 }
815 }
816 }
817
818 0x0d: UOp::lui({{
819 Rd = (uint64_t)(sext<20>(imm) << 12);
820 }});
821
822 0x0e: decode FUNCT3 {
823 format ROp {
824 0x0: decode FUNCT7 {
825 0x0: addw({{
826 Rd_sd = Rs1_sw + Rs2_sw;
827 }});
828 0x1: mulw({{
829 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
830 }}, IntMultOp);
831 0x20: subw({{
832 Rd_sd = Rs1_sw - Rs2_sw;
833 }});
834 }
835 0x1: sllw({{
836 Rd_sd = Rs1_sw << Rs2<4:0>;
837 }});
838 0x4: divw({{
839 if (Rs2_sw == 0) {
840 Rd_sd = -1;
841 } else if (Rs1_sw == numeric_limits<int32_t>::min()
842 && Rs2_sw == -1) {
843 Rd_sd = numeric_limits<int32_t>::min();
844 } else {
845 Rd_sd = Rs1_sw/Rs2_sw;
846 }
847 }}, IntDivOp);
848 0x5: decode FUNCT7 {
849 0x0: srlw({{
850 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
851 }});
852 0x1: divuw({{
853 if (Rs2_uw == 0) {
854 Rd_sd = numeric_limits<uint64_t>::max();
855 } else {
856 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
857 }
858 }}, IntDivOp);
859 0x20: sraw({{
860 Rd_sd = Rs1_sw >> Rs2<4:0>;
861 }});
862 }
863 0x6: remw({{
864 if (Rs2_sw == 0) {
865 Rd_sd = Rs1_sw;
866 } else if (Rs1_sw == numeric_limits<int32_t>::min()
867 && Rs2_sw == -1) {
868 Rd_sd = 0;
869 } else {
870 Rd_sd = Rs1_sw%Rs2_sw;
871 }
872 }}, IntDivOp);
873 0x7: remuw({{
874 if (Rs2_uw == 0) {
875 Rd_sd = (int32_t)Rs1_uw;
876 } else {
877 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
878 }
879 }}, IntDivOp);
880 }
881 }
882
883 format FPROp {
884 0x10: decode FUNCT2 {
885 0x0: fmadd_s({{
886 uint32_t temp;
887 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
888 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
889 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
890 float fd;
891
892 if (std::isnan(fs1) || std::isnan(fs2) ||
893 std::isnan(fs3)) {
894 if (issignalingnan(fs1) || issignalingnan(fs2)
895 || issignalingnan(fs3)) {
896 FFLAGS |= FloatInvalid;
897 }
898 fd = numeric_limits<float>::quiet_NaN();
899 } else if (std::isinf(fs1) || std::isinf(fs2) ||
900 std::isinf(fs3)) {
901 if (signbit(fs1) == signbit(fs2)
902 && !std::isinf(fs3)) {
903 fd = numeric_limits<float>::infinity();
904 } else if (signbit(fs1) != signbit(fs2)
905 && !std::isinf(fs3)) {
906 fd = -numeric_limits<float>::infinity();
907 } else { // Fs3_sf is infinity
908 fd = fs3;
909 }
910 } else {
911 fd = fs1*fs2 + fs3;
912 }
913 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
914 }}, FloatMultAccOp);
915 0x1: fmadd_d({{
916 if (std::isnan(Fs1) || std::isnan(Fs2) ||
917 std::isnan(Fs3)) {
918 if (issignalingnan(Fs1) || issignalingnan(Fs2)
919 || issignalingnan(Fs3)) {
920 FFLAGS |= FloatInvalid;
921 }
922 Fd = numeric_limits<double>::quiet_NaN();
923 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
924 std::isinf(Fs3)) {
925 if (signbit(Fs1) == signbit(Fs2)
926 && !std::isinf(Fs3)) {
927 Fd = numeric_limits<double>::infinity();
928 } else if (signbit(Fs1) != signbit(Fs2)
929 && !std::isinf(Fs3)) {
930 Fd = -numeric_limits<double>::infinity();
931 } else {
932 Fd = Fs3;
933 }
934 } else {
935 Fd = Fs1*Fs2 + Fs3;
936 }
937 }}, FloatMultAccOp);
938 }
939 0x11: decode FUNCT2 {
940 0x0: fmsub_s({{
941 uint32_t temp;
942 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
943 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
944 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
945 float fd;
946
947 if (std::isnan(fs1) || std::isnan(fs2) ||
948 std::isnan(fs3)) {
949 if (issignalingnan(fs1) || issignalingnan(fs2)
950 || issignalingnan(fs3)) {
951 FFLAGS |= FloatInvalid;
952 }
953 fd = numeric_limits<float>::quiet_NaN();
954 } else if (std::isinf(fs1) || std::isinf(fs2) ||
955 std::isinf(fs3)) {
956 if (signbit(fs1) == signbit(fs2)
957 && !std::isinf(fs3)) {
958 fd = numeric_limits<float>::infinity();
959 } else if (signbit(fs1) != signbit(fs2)
960 && !std::isinf(fs3)) {
961 fd = -numeric_limits<float>::infinity();
962 } else { // Fs3_sf is infinity
963 fd = -fs3;
964 }
965 } else {
966 fd = fs1*fs2 - fs3;
967 }
968 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
969 }}, FloatMultAccOp);
970 0x1: fmsub_d({{
971 if (std::isnan(Fs1) || std::isnan(Fs2) ||
972 std::isnan(Fs3)) {
973 if (issignalingnan(Fs1) || issignalingnan(Fs2)
974 || issignalingnan(Fs3)) {
975 FFLAGS |= FloatInvalid;
976 }
977 Fd = numeric_limits<double>::quiet_NaN();
978 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
979 std::isinf(Fs3)) {
980 if (signbit(Fs1) == signbit(Fs2)
981 && !std::isinf(Fs3)) {
982 Fd = numeric_limits<double>::infinity();
983 } else if (signbit(Fs1) != signbit(Fs2)
984 && !std::isinf(Fs3)) {
985 Fd = -numeric_limits<double>::infinity();
986 } else {
987 Fd = -Fs3;
988 }
989 } else {
990 Fd = Fs1*Fs2 - Fs3;
991 }
992 }}, FloatMultAccOp);
993 }
994 0x12: decode FUNCT2 {
995 0x0: fnmsub_s({{
996 uint32_t temp;
997 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
998 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
999 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1000 float fd;
1001
1002 if (std::isnan(fs1) || std::isnan(fs2) ||
1003 std::isnan(fs3)) {
1004 if (issignalingnan(fs1) || issignalingnan(fs2)
1005 || issignalingnan(fs3)) {
1006 FFLAGS |= FloatInvalid;
1007 }
1008 fd = numeric_limits<float>::quiet_NaN();
1009 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1010 std::isinf(fs3)) {
1011 if (signbit(fs1) == signbit(fs2)
1012 && !std::isinf(fs3)) {
1013 fd = -numeric_limits<float>::infinity();
1014 } else if (signbit(fs1) != signbit(fs2)
1015 && !std::isinf(fs3)) {
1016 fd = numeric_limits<float>::infinity();
1017 } else { // Fs3_sf is infinity
1018 fd = fs3;
1019 }
1020 } else {
1021 fd = -(fs1*fs2 - fs3);
1022 }
1023 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1024 }}, FloatMultAccOp);
1025 0x1: fnmsub_d({{
1026 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1027 std::isnan(Fs3)) {
1028 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1029 || issignalingnan(Fs3)) {
1030 FFLAGS |= FloatInvalid;
1031 }
1032 Fd = numeric_limits<double>::quiet_NaN();
1033 } else if (std::isinf(Fs1) || std::isinf(Fs2)
1034 || std::isinf(Fs3)) {
1035 if (signbit(Fs1) == signbit(Fs2)
1036 && !std::isinf(Fs3)) {
1037 Fd = -numeric_limits<double>::infinity();
1038 } else if (signbit(Fs1) != signbit(Fs2)
1039 && !std::isinf(Fs3)) {
1040 Fd = numeric_limits<double>::infinity();
1041 } else {
1042 Fd = Fs3;
1043 }
1044 } else {
1045 Fd = -(Fs1*Fs2 - Fs3);
1046 }
1047 }}, FloatMultAccOp);
1048 }
1049 0x13: decode FUNCT2 {
1050 0x0: fnmadd_s({{
1051 uint32_t temp;
1052 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1053 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1054 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1055 float fd;
1056
1057 if (std::isnan(fs1) || std::isnan(fs2) ||
1058 std::isnan(fs3)) {
1059 if (issignalingnan(fs1) || issignalingnan(fs2)
1060 || issignalingnan(fs3)) {
1061 FFLAGS |= FloatInvalid;
1062 }
1063 fd = numeric_limits<float>::quiet_NaN();
1064 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1065 std::isinf(fs3)) {
1066 if (signbit(fs1) == signbit(fs2)
1067 && !std::isinf(fs3)) {
1068 fd = -numeric_limits<float>::infinity();
1069 } else if (signbit(fs1) != signbit(fs2)
1070 && !std::isinf(fs3)) {
1071 fd = numeric_limits<float>::infinity();
1072 } else { // Fs3_sf is infinity
1073 fd = -fs3;
1074 }
1075 } else {
1076 fd = -(fs1*fs2 + fs3);
1077 }
1078 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1079 }}, FloatMultAccOp);
1080 0x1: fnmadd_d({{
1081 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1082 std::isnan(Fs3)) {
1083 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1084 || issignalingnan(Fs3)) {
1085 FFLAGS |= FloatInvalid;
1086 }
1087 Fd = numeric_limits<double>::quiet_NaN();
1088 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1089 std::isinf(Fs3)) {
1090 if (signbit(Fs1) == signbit(Fs2)
1091 && !std::isinf(Fs3)) {
1092 Fd = -numeric_limits<double>::infinity();
1093 } else if (signbit(Fs1) != signbit(Fs2)
1094 && !std::isinf(Fs3)) {
1095 Fd = numeric_limits<double>::infinity();
1096 } else {
1097 Fd = -Fs3;
1098 }
1099 } else {
1100 Fd = -(Fs1*Fs2 + Fs3);
1101 }
1102 }}, FloatMultAccOp);
1103 }
1104 0x14: decode FUNCT7 {
1105 0x0: fadd_s({{
1106 uint32_t temp;
1107 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1108 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1109 float fd;
1110
1111 if (std::isnan(fs1) || std::isnan(fs2)) {
1112 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1113 FFLAGS |= FloatInvalid;
1114 }
1115 fd = numeric_limits<float>::quiet_NaN();
1116 } else {
1117 fd = fs1 + fs2;
1118 }
1119 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1120 }}, FloatAddOp);
1121 0x1: fadd_d({{
1122 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1123 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1124 FFLAGS |= FloatInvalid;
1125 }
1126 Fd = numeric_limits<double>::quiet_NaN();
1127 } else {
1128 Fd = Fs1 + Fs2;
1129 }
1130 }}, FloatAddOp);
1131 0x4: fsub_s({{
1132 uint32_t temp;
1133 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1134 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1135 float fd;
1136
1137 if (std::isnan(fs1) || std::isnan(fs2)) {
1138 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1139 FFLAGS |= FloatInvalid;
1140 }
1141 fd = numeric_limits<float>::quiet_NaN();
1142 } else {
1143 fd = fs1 - fs2;
1144 }
1145 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1146 }}, FloatAddOp);
1147 0x5: fsub_d({{
1148 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1149 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1150 FFLAGS |= FloatInvalid;
1151 }
1152 Fd = numeric_limits<double>::quiet_NaN();
1153 } else {
1154 Fd = Fs1 - Fs2;
1155 }
1156 }}, FloatAddOp);
1157 0x8: fmul_s({{
1158 uint32_t temp;
1159 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1160 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1161 float fd;
1162
1163 if (std::isnan(fs1) || std::isnan(fs2)) {
1164 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1165 FFLAGS |= FloatInvalid;
1166 }
1167 fd = numeric_limits<float>::quiet_NaN();
1168 } else {
1169 fd = fs1*fs2;
1170 }
1171 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1172 }}, FloatMultOp);
1173 0x9: fmul_d({{
1174 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1175 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1176 FFLAGS |= FloatInvalid;
1177 }
1178 Fd = numeric_limits<double>::quiet_NaN();
1179 } else {
1180 Fd = Fs1*Fs2;
1181 }
1182 }}, FloatMultOp);
1183 0xc: fdiv_s({{
1184 uint32_t temp;
1185 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1186 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1187 float fd;
1188
1189 if (std::isnan(fs1) || std::isnan(fs2)) {
1190 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1191 FFLAGS |= FloatInvalid;
1192 }
1193 fd = numeric_limits<float>::quiet_NaN();
1194 } else {
1195 fd = fs1/fs2;
1196 }
1197 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1198 }}, FloatDivOp);
1199 0xd: fdiv_d({{
1200 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1201 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1202 FFLAGS |= FloatInvalid;
1203 }
1204 Fd = numeric_limits<double>::quiet_NaN();
1205 } else {
1206 Fd = Fs1/Fs2;
1207 }
1208 }}, FloatDivOp);
1209 0x10: decode ROUND_MODE {
1210 0x0: fsgnj_s({{
1211 uint32_t temp;
1212 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1213 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1214 float fd;
1215
1216 if (issignalingnan(fs1)) {
1217 fd = numeric_limits<float>::signaling_NaN();
1218 feclearexcept(FE_INVALID);
1219 } else {
1220 fd = copysign(fs1, fs2);
1221 }
1222 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1223 }}, FloatMiscOp);
1224 0x1: fsgnjn_s({{
1225 uint32_t temp;
1226 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1227 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1228 float fd;
1229
1230 if (issignalingnan(fs1)) {
1231 fd = numeric_limits<float>::signaling_NaN();
1232 feclearexcept(FE_INVALID);
1233 } else {
1234 fd = copysign(fs1, -fs2);
1235 }
1236 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1237 }}, FloatMiscOp);
1238 0x2: fsgnjx_s({{
1239 uint32_t temp;
1240 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1241 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1242 float fd;
1243
1244 if (issignalingnan(fs1)) {
1245 fd = numeric_limits<float>::signaling_NaN();
1246 feclearexcept(FE_INVALID);
1247 } else {
1248 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1249 }
1250 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1251 }}, FloatMiscOp);
1252 }
1253 0x11: decode ROUND_MODE {
1254 0x0: fsgnj_d({{
1255 if (issignalingnan(Fs1)) {
1256 Fd = numeric_limits<double>::signaling_NaN();
1257 feclearexcept(FE_INVALID);
1258 } else {
1259 Fd = copysign(Fs1, Fs2);
1260 }
1261 }}, FloatMiscOp);
1262 0x1: fsgnjn_d({{
1263 if (issignalingnan(Fs1)) {
1264 Fd = numeric_limits<double>::signaling_NaN();
1265 feclearexcept(FE_INVALID);
1266 } else {
1267 Fd = copysign(Fs1, -Fs2);
1268 }
1269 }}, FloatMiscOp);
1270 0x2: fsgnjx_d({{
1271 if (issignalingnan(Fs1)) {
1272 Fd = numeric_limits<double>::signaling_NaN();
1273 feclearexcept(FE_INVALID);
1274 } else {
1275 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1276 }
1277 }}, FloatMiscOp);
1278 }
1279 0x14: decode ROUND_MODE {
1280 0x0: fmin_s({{
1281 uint32_t temp;
1282 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1283 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1284 float fd;
1285
1286 if (issignalingnan(fs2)) {
1287 fd = fs1;
1288 FFLAGS |= FloatInvalid;
1289 } else if (issignalingnan(fs1)) {
1290 fd = fs2;
1291 FFLAGS |= FloatInvalid;
1292 } else {
1293 fd = fmin(fs1, fs2);
1294 }
1295 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1296 }}, FloatCmpOp);
1297 0x1: fmax_s({{
1298 uint32_t temp;
1299 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1300 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1301 float fd;
1302
1303 if (issignalingnan(fs2)) {
1304 fd = fs1;
1305 FFLAGS |= FloatInvalid;
1306 } else if (issignalingnan(fs1)) {
1307 fd = fs2;
1308 FFLAGS |= FloatInvalid;
1309 } else {
1310 fd = fmax(fs1, fs2);
1311 }
1312 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1313 }}, FloatCmpOp);
1314 }
1315 0x15: decode ROUND_MODE {
1316 0x0: fmin_d({{
1317 if (issignalingnan(Fs2)) {
1318 Fd = Fs1;
1319 FFLAGS |= FloatInvalid;
1320 } else if (issignalingnan(Fs1)) {
1321 Fd = Fs2;
1322 FFLAGS |= FloatInvalid;
1323 } else {
1324 Fd = fmin(Fs1, Fs2);
1325 }
1326 }}, FloatCmpOp);
1327 0x1: fmax_d({{
1328 if (issignalingnan(Fs2)) {
1329 Fd = Fs1;
1330 FFLAGS |= FloatInvalid;
1331 } else if (issignalingnan(Fs1)) {
1332 Fd = Fs2;
1333 FFLAGS |= FloatInvalid;
1334 } else {
1335 Fd = fmax(Fs1, Fs2);
1336 }
1337 }}, FloatCmpOp);
1338 }
1339 0x20: fcvt_s_d({{
1340 if (CONV_SGN != 1) {
1341 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1342 machInst);
1343 }
1344 float fd;
1345 if (issignalingnan(Fs1)) {
1346 fd = numeric_limits<float>::quiet_NaN();
1347 FFLAGS |= FloatInvalid;
1348 } else {
1349 fd = (float)Fs1;
1350 }
1351 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1352 }}, FloatCvtOp);
1353 0x21: fcvt_d_s({{
1354 if (CONV_SGN != 0) {
1355 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1356 machInst);
1357 }
1358 uint32_t temp;
1359 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1360
1361 if (issignalingnan(fs1)) {
1362 Fd = numeric_limits<double>::quiet_NaN();
1363 FFLAGS |= FloatInvalid;
1364 } else {
1365 Fd = (double)fs1;
1366 }
1367 }}, FloatCvtOp);
1368 0x2c: fsqrt_s({{
1369 if (RS2 != 0) {
1370 fault = make_shared<IllegalInstFault>("source reg x1",
1371 machInst);
1372 }
1373 uint32_t temp;
1374 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1375 float fd;
1376
1377 if (issignalingnan(Fs1_sf)) {
1378 FFLAGS |= FloatInvalid;
1379 }
1380 fd = sqrt(fs1);
1381 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1382 }}, FloatSqrtOp);
1383 0x2d: fsqrt_d({{
1384 if (RS2 != 0) {
1385 fault = make_shared<IllegalInstFault>("source reg x1",
1386 machInst);
1387 }
1388 Fd = sqrt(Fs1);
1389 }}, FloatSqrtOp);
1390 0x50: decode ROUND_MODE {
1391 0x0: fle_s({{
1392 uint32_t temp;
1393 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1394 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1395
1396 if (std::isnan(fs1) || std::isnan(fs2)) {
1397 FFLAGS |= FloatInvalid;
1398 Rd = 0;
1399 } else {
1400 Rd = fs1 <= fs2 ? 1 : 0;
1401 }
1402 }}, FloatCmpOp);
1403 0x1: flt_s({{
1404 uint32_t temp;
1405 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1406 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1407
1408 if (std::isnan(fs1) || std::isnan(fs2)) {
1409 FFLAGS |= FloatInvalid;
1410 Rd = 0;
1411 } else {
1412 Rd = fs1 < fs2 ? 1 : 0;
1413 }
1414 }}, FloatCmpOp);
1415 0x2: feq_s({{
1416 uint32_t temp;
1417 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1418 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1419
1420 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1421 FFLAGS |= FloatInvalid;
1422 }
1423 Rd = fs1 == fs2 ? 1 : 0;
1424 }}, FloatCmpOp);
1425 }
1426 0x51: decode ROUND_MODE {
1427 0x0: fle_d({{
1428 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1429 FFLAGS |= FloatInvalid;
1430 Rd = 0;
1431 } else {
1432 Rd = Fs1 <= Fs2 ? 1 : 0;
1433 }
1434 }}, FloatCmpOp);
1435 0x1: flt_d({{
1436 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1437 FFLAGS |= FloatInvalid;
1438 Rd = 0;
1439 } else {
1440 Rd = Fs1 < Fs2 ? 1 : 0;
1441 }
1442 }}, FloatCmpOp);
1443 0x2: feq_d({{
1444 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1445 FFLAGS |= FloatInvalid;
1446 }
1447 Rd = Fs1 == Fs2 ? 1 : 0;
1448 }}, FloatCmpOp);
1449 }
1450 0x60: decode CONV_SGN {
1451 0x0: fcvt_w_s({{
1452 uint32_t temp;
1453 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1454
1455 if (std::isnan(fs1)) {
1456 Rd_sd = numeric_limits<int32_t>::max();
1457 FFLAGS |= FloatInvalid;
1458 } else if (fs1 >=
1459 float(numeric_limits<int32_t>::max())) {
1460 Rd_sd = numeric_limits<int32_t>::max();
1461 FFLAGS |= FloatInvalid;
1462 } else if (fs1 <=
1463 float(numeric_limits<int32_t>::min())) {
1464 Rd_sd = numeric_limits<int32_t>::min();
1465 FFLAGS |= FloatInvalid;
1466 } else {
1467 Rd_sd = (int32_t)fs1;
1468 }
1469 }}, FloatCvtOp);
1470 0x1: fcvt_wu_s({{
1471 uint32_t temp;
1472 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1473
1474 if (std::isnan(fs1)) {
1475 Rd = numeric_limits<uint64_t>::max();
1476 FFLAGS |= FloatInvalid;
1477 } else if (fs1 < 0.0) {
1478 Rd = 0;
1479 FFLAGS |= FloatInvalid;
1480 } else if (fs1 >
1481 float(numeric_limits<uint32_t>::max())) {
1482 Rd = numeric_limits<uint64_t>::max();
1483 FFLAGS |= FloatInvalid;
1484 } else {
1485 Rd = (uint32_t)fs1;
1486 }
1487 }}, FloatCvtOp);
1488 0x2: fcvt_l_s({{
1489 uint32_t temp;
1490 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1491
1492 if (std::isnan(fs1)) {
1493 Rd_sd = numeric_limits<int64_t>::max();
1494 FFLAGS |= FloatInvalid;
1495 } else if (fs1 >
1496 float(numeric_limits<int64_t>::max())) {
1497 Rd_sd = numeric_limits<int64_t>::max();
1498 FFLAGS |= FloatInvalid;
1499 } else if (fs1 <
1500 float(numeric_limits<int64_t>::min())) {
1501 Rd_sd = numeric_limits<int64_t>::min();
1502 FFLAGS |= FloatInvalid;
1503 } else {
1504 Rd_sd = (int64_t)fs1;
1505 }
1506 }}, FloatCvtOp);
1507 0x3: fcvt_lu_s({{
1508 uint32_t temp;
1509 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1510
1511 if (std::isnan(fs1)) {
1512 Rd = numeric_limits<uint64_t>::max();
1513 FFLAGS |= FloatInvalid;
1514 } else if (fs1 < 0.0) {
1515 Rd = 0;
1516 FFLAGS |= FloatInvalid;
1517 } else if (fs1 >
1518 float(numeric_limits<uint64_t>::max())) {
1519 Rd = numeric_limits<uint64_t>::max();
1520 FFLAGS |= FloatInvalid;
1521 } else {
1522 Rd = (uint64_t)fs1;
1523 }
1524 }}, FloatCvtOp);
1525 }
1526 0x61: decode CONV_SGN {
1527 0x0: fcvt_w_d({{
1528 if (std::isnan(Fs1)) {
1529 Rd_sd = numeric_limits<int32_t>::max();
1530 FFLAGS |= FloatInvalid;
1531 } else if (Fs1 >
1532 float(numeric_limits<int32_t>::max())) {
1533 Rd_sd = numeric_limits<int32_t>::max();
1534 FFLAGS |= FloatInvalid;
1535 } else if (Fs1 <
1536 float(numeric_limits<int32_t>::min())) {
1537 Rd_sd = numeric_limits<int32_t>::min();
1538 FFLAGS |= FloatInvalid;
1539 } else {
1540 Rd_sd = (int32_t)Fs1;
1541 }
1542 }}, FloatCvtOp);
1543 0x1: fcvt_wu_d({{
1544 if (std::isnan(Fs1)) {
1545 Rd = numeric_limits<uint64_t>::max();
1546 FFLAGS |= FloatInvalid;
1547 } else if (Fs1 < 0) {
1548 Rd = 0;
1549 FFLAGS |= FloatInvalid;
1550 } else if (Fs1 >
1551 float(numeric_limits<uint32_t>::max())) {
1552 Rd = numeric_limits<uint64_t>::max();
1553 FFLAGS |= FloatInvalid;
1554 } else {
1555 Rd = (uint32_t)Fs1;
1556 }
1557 }}, FloatCvtOp);
1558 0x2: fcvt_l_d({{
1559 if (std::isnan(Fs1)) {
1560 Rd_sd = numeric_limits<int64_t>::max();
1561 FFLAGS |= FloatInvalid;
1562 } else if (Fs1 >
1563 float(numeric_limits<int64_t>::max())) {
1564 Rd_sd = numeric_limits<int64_t>::max();
1565 FFLAGS |= FloatInvalid;
1566 } else if (Fs1 <
1567 float(numeric_limits<int64_t>::min())) {
1568 Rd_sd = numeric_limits<int64_t>::min();
1569 FFLAGS |= FloatInvalid;
1570 } else {
1571 Rd_sd = Fs1;
1572 }
1573 }}, FloatCvtOp);
1574 0x3: fcvt_lu_d({{
1575 if (std::isnan(Fs1)) {
1576 Rd = numeric_limits<uint64_t>::max();
1577 FFLAGS |= FloatInvalid;
1578 } else if (Fs1 < 0) {
1579 Rd = 0;
1580 FFLAGS |= FloatInvalid;
1581 } else if (Fs1 >
1582 float(numeric_limits<uint64_t>::max())) {
1583 Rd = numeric_limits<uint64_t>::max();
1584 FFLAGS |= FloatInvalid;
1585 } else {
1586 Rd = Fs1;
1587 }
1588 }}, FloatCvtOp);
1589 }
1590 0x68: decode CONV_SGN {
1591 0x0: fcvt_s_w({{
1592 float temp = (float)Rs1_sw;
1593 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1594 }}, FloatCvtOp);
1595 0x1: fcvt_s_wu({{
1596 float temp = (float)Rs1_uw;
1597 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1598 }}, FloatCvtOp);
1599 0x2: fcvt_s_l({{
1600 float temp = (float)Rs1_sd;
1601 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1602 }}, FloatCvtOp);
1603 0x3: fcvt_s_lu({{
1604 float temp = (float)Rs1;
1605 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1606 }}, FloatCvtOp);
1607 }
1608 0x69: decode CONV_SGN {
1609 0x0: fcvt_d_w({{
1610 Fd = (double)Rs1_sw;
1611 }}, FloatCvtOp);
1612 0x1: fcvt_d_wu({{
1613 Fd = (double)Rs1_uw;
1614 }}, FloatCvtOp);
1615 0x2: fcvt_d_l({{
1616 Fd = (double)Rs1_sd;
1617 }}, FloatCvtOp);
1618 0x3: fcvt_d_lu({{
1619 Fd = (double)Rs1;
1620 }}, FloatCvtOp);
1621 }
1622 0x70: decode ROUND_MODE {
1623 0x0: fmv_x_s({{
1624 Rd = (uint32_t)Fs1_bits;
1625 if ((Rd&0x80000000) != 0) {
1626 Rd |= (0xFFFFFFFFULL << 32);
1627 }
1628 }}, FloatCvtOp);
1629 0x1: fclass_s({{
1630 uint32_t temp;
1631 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1632 switch (fpclassify(fs1)) {
1633 case FP_INFINITE:
1634 if (signbit(fs1)) {
1635 Rd = 1 << 0;
1636 } else {
1637 Rd = 1 << 7;
1638 }
1639 break;
1640 case FP_NAN:
1641 if (issignalingnan(fs1)) {
1642 Rd = 1 << 8;
1643 } else {
1644 Rd = 1 << 9;
1645 }
1646 break;
1647 case FP_ZERO:
1648 if (signbit(fs1)) {
1649 Rd = 1 << 3;
1650 } else {
1651 Rd = 1 << 4;
1652 }
1653 break;
1654 case FP_SUBNORMAL:
1655 if (signbit(fs1)) {
1656 Rd = 1 << 2;
1657 } else {
1658 Rd = 1 << 5;
1659 }
1660 break;
1661 case FP_NORMAL:
1662 if (signbit(fs1)) {
1663 Rd = 1 << 1;
1664 } else {
1665 Rd = 1 << 6;
1666 }
1667 break;
1668 default:
1669 panic("Unknown classification for operand.");
1670 break;
1671 }
1672 }}, FloatMiscOp);
1673 }
1674 0x71: decode ROUND_MODE {
1675 0x0: fmv_x_d({{
1676 Rd = Fs1_bits;
1677 }}, FloatCvtOp);
1678 0x1: fclass_d({{
1679 switch (fpclassify(Fs1)) {
1680 case FP_INFINITE:
1681 if (signbit(Fs1)) {
1682 Rd = 1 << 0;
1683 } else {
1684 Rd = 1 << 7;
1685 }
1686 break;
1687 case FP_NAN:
1688 if (issignalingnan(Fs1)) {
1689 Rd = 1 << 8;
1690 } else {
1691 Rd = 1 << 9;
1692 }
1693 break;
1694 case FP_ZERO:
1695 if (signbit(Fs1)) {
1696 Rd = 1 << 3;
1697 } else {
1698 Rd = 1 << 4;
1699 }
1700 break;
1701 case FP_SUBNORMAL:
1702 if (signbit(Fs1)) {
1703 Rd = 1 << 2;
1704 } else {
1705 Rd = 1 << 5;
1706 }
1707 break;
1708 case FP_NORMAL:
1709 if (signbit(Fs1)) {
1710 Rd = 1 << 1;
1711 } else {
1712 Rd = 1 << 6;
1713 }
1714 break;
1715 default:
1716 panic("Unknown classification for operand.");
1717 break;
1718 }
1719 }}, FloatMiscOp);
1720 }
1721 0x78: fmv_s_x({{
1722 Fd_bits = (uint64_t)Rs1_uw;
1723 }}, FloatCvtOp);
1724 0x79: fmv_d_x({{
1725 Fd_bits = Rs1;
1726 }}, FloatCvtOp);
1727 }
1728 }
1729
1730 0x18: decode FUNCT3 {
1731 format BOp {
1732 0x0: beq({{
1733 if (Rs1 == Rs2) {
1734 NPC = PC + imm;
1735 } else {
1736 NPC = NPC;
1737 }
1738 }}, IsDirectControl, IsCondControl);
1739 0x1: bne({{
1740 if (Rs1 != Rs2) {
1741 NPC = PC + imm;
1742 } else {
1743 NPC = NPC;
1744 }
1745 }}, IsDirectControl, IsCondControl);
1746 0x4: blt({{
1747 if (Rs1_sd < Rs2_sd) {
1748 NPC = PC + imm;
1749 } else {
1750 NPC = NPC;
1751 }
1752 }}, IsDirectControl, IsCondControl);
1753 0x5: bge({{
1754 if (Rs1_sd >= Rs2_sd) {
1755 NPC = PC + imm;
1756 } else {
1757 NPC = NPC;
1758 }
1759 }}, IsDirectControl, IsCondControl);
1760 0x6: bltu({{
1761 if (Rs1 < Rs2) {
1762 NPC = PC + imm;
1763 } else {
1764 NPC = NPC;
1765 }
1766 }}, IsDirectControl, IsCondControl);
1767 0x7: bgeu({{
1768 if (Rs1 >= Rs2) {
1769 NPC = PC + imm;
1770 } else {
1771 NPC = NPC;
1772 }
1773 }}, IsDirectControl, IsCondControl);
1774 }
1775 }
1776
1777 0x19: decode FUNCT3 {
1778 0x0: Jump::jalr({{
1779 Rd = NPC;
1780 NPC = (imm + Rs1) & (~0x1);
1781 }}, IsIndirectControl, IsUncondControl, IsCall);
1782 }
1783
1784 0x1b: JOp::jal({{
1785 Rd = NPC;
1786 NPC = PC + imm;
1787 }}, IsDirectControl, IsUncondControl, IsCall);
1788
1789 0x1c: decode FUNCT3 {
1790 format SystemOp {
1791 0x0: decode FUNCT7 {
1792 0x0: decode RS2 {
1793 0x0: ecall({{
1794 fault = make_shared<SyscallFault>(
1795 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1796 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1797 No_OpClass);
1798 0x1: ebreak({{
1799 fault = make_shared<BreakpointFault>(
1800 xc->pcState());
1801 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1802 0x2: uret({{
1803 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1804 status.uie = status.upie;
1805 status.upie = 1;
1806 xc->setMiscReg(MISCREG_STATUS, status);
1807 NPC = xc->readMiscReg(MISCREG_UEPC);
1808 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1809 }
1810 0x8: decode RS2 {
1811 0x2: sret({{
1812 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1813 auto pm = (PrivilegeMode)xc->readMiscReg(
1814 MISCREG_PRV);
1815 if (pm == PRV_U ||
1816 (pm == PRV_S && status.tsr == 1)) {
1817 fault = make_shared<IllegalInstFault>(
1818 "sret in user mode or TSR enabled",
1819 machInst);
1820 NPC = NPC;
1821 } else {
1822 xc->setMiscReg(MISCREG_PRV, status.spp);
1823 status.sie = status.spie;
1824 status.spie = 1;
1825 status.spp = PRV_U;
1826 xc->setMiscReg(MISCREG_STATUS, status);
1827 NPC = xc->readMiscReg(MISCREG_SEPC);
1828 }
1829 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1830 0x5: wfi({{
1831 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1832 auto pm = (PrivilegeMode)xc->readMiscReg(
1833 MISCREG_PRV);
1834 if (pm == PRV_U ||
1835 (pm == PRV_S && status.tw == 1)) {
1836 fault = make_shared<IllegalInstFault>(
1837 "wfi in user mode or TW enabled",
1838 machInst);
1839 }
1840 // don't do anything for now
1841 }}, No_OpClass);
1842 }
1843 0x9: sfence_vma({{
1844 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1845 auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
1846 if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
1847 fault = make_shared<IllegalInstFault>(
1848 "sfence in user mode or TVM enabled",
1849 machInst);
1850 }
1851 xc->tcBase()->getMMUPtr()->demapPage(Rs1, Rs2);
1852 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
1853 0x18: mret({{
1854 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1855 fault = make_shared<IllegalInstFault>(
1856 "mret at lower privilege", machInst);
1857 NPC = NPC;
1858 } else {
1859 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1860 xc->setMiscReg(MISCREG_PRV, status.mpp);
1861 status.mie = status.mpie;
1862 status.mpie = 1;
1863 status.mpp = PRV_U;
1864 xc->setMiscReg(MISCREG_STATUS, status);
1865 NPC = xc->readMiscReg(MISCREG_MEPC);
1866 }
1867 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1868 }
1869 }
1870 format CSROp {
1871 0x1: csrrw({{
1872 Rd = data;
1873 data = Rs1;
1874 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1875 0x2: csrrs({{
1876 Rd = data;
1877 data |= Rs1;
1878 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1879 0x3: csrrc({{
1880 Rd = data;
1881 data &= ~Rs1;
1882 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1883 0x5: csrrwi({{
1884 Rd = data;
1885 data = uimm;
1886 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1887 0x6: csrrsi({{
1888 Rd = data;
1889 data |= uimm;
1890 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1891 0x7: csrrci({{
1892 Rd = data;
1893 data &= ~uimm;
1894 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1895 }
1896 }
1897
1898 0x1e: M5Op::M5Op();
1899 }
1900 }