decoder.isa (12850:7036cad54910) decoder.isa (13612:12ae022f3a30)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2017 The University of Virginia
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// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// The RISC-V ISA decoder
35//
36
37decode QUADRANT default Unknown::unknown() {
38 0x0: decode COPCODE {
39 0x0: CIOp::c_addi4spn({{
40 imm = CIMM8<1:1> << 2 |
41 CIMM8<0:0> << 3 |
42 CIMM8<7:6> << 4 |
43 CIMM8<5:2> << 6;
44 }}, {{
45 if (machInst == 0)
46 fault = make_shared<IllegalInstFault>("zero instruction",
47 machInst);
48 Rp2 = sp + imm;
49 }}, uint64_t);
50 format CompressedLoad {
51 0x1: c_fld({{
52 offset = CIMM3 << 3 | CIMM2 << 6;
53 }}, {{
54 Fp2_bits = Mem;
55 }}, {{
56 EA = Rp1 + offset;
57 }});
58 0x2: c_lw({{
59 offset = CIMM2<1:1> << 2 |
60 CIMM3 << 3 |
61 CIMM2<0:0> << 6;
62 }}, {{
63 Rp2_sd = Mem_sw;
64 }}, {{
65 EA = Rp1 + offset;
66 }});
67 0x3: c_ld({{
68 offset = CIMM3 << 3 | CIMM2 << 6;
69 }}, {{
70 Rp2_sd = Mem_sd;
71 }}, {{
72 EA = Rp1 + offset;
73 }});
74 }
75 format CompressedStore {
76 0x5: c_fsd({{
77 offset = CIMM3 << 3 | CIMM2 << 6;
78 }}, {{
79 Mem = Fp2_bits;
80 }}, {{
81 EA = Rp1 + offset;
82 }});
83 0x6: c_sw({{
84 offset = CIMM2<1:1> << 2 |
85 CIMM3 << 3 |
86 CIMM2<0:0> << 6;
87 }}, {{
88 Mem_uw = Rp2_uw;
89 }}, ea_code={{
90 EA = Rp1 + offset;
91 }});
92 0x7: c_sd({{
93 offset = CIMM3 << 3 | CIMM2 << 6;
94 }}, {{
95 Mem_ud = Rp2_ud;
96 }}, {{
97 EA = Rp1 + offset;
98 }});
99 }
100 }
101 0x1: decode COPCODE {
102 format CIOp {
103 0x0: c_addi({{
104 imm = CIMM5;
105 if (CIMM1 > 0)
106 imm |= ~((uint64_t)0x1F);
107 }}, {{
108 if ((RC1 == 0) != (imm == 0)) {
109 if (RC1 == 0) {
110 fault = make_shared<IllegalInstFault>("source reg x0",
111 machInst);
112 } else // imm == 0
113 fault = make_shared<IllegalInstFault>("immediate = 0",
114 machInst);
115 }
116 Rc1_sd = Rc1_sd + imm;
117 }});
118 0x1: c_addiw({{
119 imm = CIMM5;
120 if (CIMM1 > 0)
121 imm |= ~((uint64_t)0x1F);
122 }}, {{
123 if (RC1 == 0) {
124 fault = make_shared<IllegalInstFault>("source reg x0",
125 machInst);
126 }
127 Rc1_sd = (int32_t)Rc1_sd + imm;
128 }});
129 0x2: c_li({{
130 imm = CIMM5;
131 if (CIMM1 > 0)
132 imm |= ~((uint64_t)0x1F);
133 }}, {{
134 if (RC1 == 0) {
135 fault = make_shared<IllegalInstFault>("source reg x0",
136 machInst);
137 }
138 Rc1_sd = imm;
139 }});
140 0x3: decode RC1 {
141 0x2: c_addi16sp({{
142 imm = CIMM5<4:4> << 4 |
143 CIMM5<0:0> << 5 |
144 CIMM5<3:3> << 6 |
145 CIMM5<2:1> << 7;
146 if (CIMM1 > 0)
147 imm |= ~((int64_t)0x1FF);
148 }}, {{
149 if (imm == 0) {
150 fault = make_shared<IllegalInstFault>("immediate = 0",
151 machInst);
152 }
153 sp_sd = sp_sd + imm;
154 }});
155 default: c_lui({{
156 imm = CIMM5 << 12;
157 if (CIMM1 > 0)
158 imm |= ~((uint64_t)0x1FFFF);
159 }}, {{
160 if (RC1 == 0 || RC1 == 2) {
161 fault = make_shared<IllegalInstFault>("source reg x0",
162 machInst);
163 }
164 if (imm == 0) {
165 fault = make_shared<IllegalInstFault>("immediate = 0",
166 machInst);
167 }
168 Rc1_sd = imm;
169 }});
170 }
171 }
172 0x4: decode CFUNCT2HIGH {
173 format CIOp {
174 0x0: c_srli({{
175 imm = CIMM5 | (CIMM1 << 5);
176 }}, {{
177 if (imm == 0) {
178 fault = make_shared<IllegalInstFault>("immediate = 0",
179 machInst);
180 }
181 Rp1 = Rp1 >> imm;
182 }}, uint64_t);
183 0x1: c_srai({{
184 imm = CIMM5 | (CIMM1 << 5);
185 }}, {{
186 if (imm == 0) {
187 fault = make_shared<IllegalInstFault>("immediate = 0",
188 machInst);
189 }
190 Rp1_sd = Rp1_sd >> imm;
191 }}, uint64_t);
192 0x2: c_andi({{
193 imm = CIMM5;
194 if (CIMM1 > 0)
195 imm |= ~((uint64_t)0x1F);
196 }}, {{
197 Rp1 = Rp1 & imm;
198 }}, uint64_t);
199 }
200 format ROp {
201 0x3: decode CFUNCT1 {
202 0x0: decode CFUNCT2LOW {
203 0x0: c_sub({{
204 Rp1 = Rp1 - Rp2;
205 }});
206 0x1: c_xor({{
207 Rp1 = Rp1 ^ Rp2;
208 }});
209 0x2: c_or({{
210 Rp1 = Rp1 | Rp2;
211 }});
212 0x3: c_and({{
213 Rp1 = Rp1 & Rp2;
214 }});
215 }
216 0x1: decode CFUNCT2LOW {
217 0x0: c_subw({{
218 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
219 }});
220 0x1: c_addw({{
221 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
222 }});
223 }
224 }
225 }
226 }
227 0x5: JOp::c_j({{
228 int64_t offset = CJUMPIMM<3:1> << 1 |
229 CJUMPIMM<9:9> << 4 |
230 CJUMPIMM<0:0> << 5 |
231 CJUMPIMM<5:5> << 6 |
232 CJUMPIMM<4:4> << 7 |
233 CJUMPIMM<8:7> << 8 |
234 CJUMPIMM<6:6> << 10;
235 if (CJUMPIMM<10:10> > 0)
236 offset |= ~((int64_t)0x7FF);
237 NPC = PC + offset;
238 }}, IsIndirectControl, IsUncondControl, IsCall);
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: ROp::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 Fd_bits = (uint64_t)Mem_uw;
404 }}, inst_flags=FloatMemReadOp);
405 0x3: fld({{
406 Fd_bits = Mem;
407 }}, inst_flags=FloatMemReadOp);
408 }
409 }
410
411 0x03: decode FUNCT3 {
412 format IOp {
413 0x0: fence({{
414 }}, uint64_t, IsNonSpeculative, IsMemBarrier, No_OpClass);
415 0x1: fence_i({{
416 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
417 }
418 }
419
420 0x04: decode FUNCT3 {
421 format IOp {
422 0x0: addi({{
423 Rd_sd = Rs1_sd + imm;
424 }});
425 0x1: slli({{
426 Rd = Rs1 << SHAMT6;
427 }});
428 0x2: slti({{
429 Rd = (Rs1_sd < imm) ? 1 : 0;
430 }});
431 0x3: sltiu({{
432 Rd = (Rs1 < imm) ? 1 : 0;
433 }}, uint64_t);
434 0x4: xori({{
435 Rd = Rs1 ^ imm;
436 }}, uint64_t);
437 0x5: decode SRTYPE {
438 0x0: srli({{
439 Rd = Rs1 >> SHAMT6;
440 }});
441 0x1: srai({{
442 Rd_sd = Rs1_sd >> SHAMT6;
443 }});
444 }
445 0x6: ori({{
446 Rd = Rs1 | imm;
447 }}, uint64_t);
448 0x7: andi({{
449 Rd = Rs1 & imm;
450 }}, uint64_t);
451 }
452 }
453
454 0x05: UOp::auipc({{
455 Rd = PC + imm;
456 }});
457
458 0x06: decode FUNCT3 {
459 format IOp {
460 0x0: addiw({{
461 Rd_sd = Rs1_sw + imm;
462 }}, int32_t);
463 0x1: slliw({{
464 Rd_sd = Rs1_sw << SHAMT5;
465 }});
466 0x5: decode SRTYPE {
467 0x0: srliw({{
468 Rd_sd = (int32_t)(Rs1_uw >> SHAMT5);
469 }});
470 0x1: sraiw({{
471 Rd_sd = Rs1_sw >> SHAMT5;
472 }});
473 }
474 }
475 }
476
477 0x08: decode FUNCT3 {
478 format Store {
479 0x0: sb({{
480 Mem_ub = Rs2_ub;
481 }});
482 0x1: sh({{
483 Mem_uh = Rs2_uh;
484 }});
485 0x2: sw({{
486 Mem_uw = Rs2_uw;
487 }});
488 0x3: sd({{
489 Mem_ud = Rs2_ud;
490 }});
491 }
492 }
493
494 0x09: decode FUNCT3 {
495 format Store {
496 0x2: fsw({{
497 Mem_uw = (uint32_t)Fs2_bits;
498 }}, inst_flags=FloatMemWriteOp);
499 0x3: fsd({{
500 Mem_ud = Fs2_bits;
501 }}, inst_flags=FloatMemWriteOp);
502 }
503 }
504
505 0x0b: decode FUNCT3 {
506 0x2: decode AMOFUNCT {
507 0x2: LoadReserved::lr_w({{
508 Rd_sd = Mem_sw;
509 }}, mem_flags=LLSC);
510 0x3: StoreCond::sc_w({{
511 Mem_uw = Rs2_uw;
512 }}, {{
513 Rd = result;
514 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
515 format AtomicMemOp {
516 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
517 Mem_sw = Rs2_sw + Rt_sd;
518 Rd_sd = Rt_sd;
519 }}, {{EA = Rs1;}});
520 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
521 Mem_sw = Rs2_uw;
522 Rd_sd = Rt_sd;
523 }}, {{EA = Rs1;}});
524 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
525 Mem_sw = Rs2_uw^Rt_sd;
526 Rd_sd = Rt_sd;
527 }}, {{EA = Rs1;}});
528 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
529 Mem_sw = Rs2_uw | Rt_sd;
530 Rd_sd = Rt_sd;
531 }}, {{EA = Rs1;}});
532 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
533 Mem_sw = Rs2_uw&Rt_sd;
534 Rd_sd = Rt_sd;
535 }}, {{EA = Rs1;}});
536 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
537 Mem_sw = min<int32_t>(Rs2_sw, Rt_sd);
538 Rd_sd = Rt_sd;
539 }}, {{EA = Rs1;}});
540 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
541 Mem_sw = max<int32_t>(Rs2_sw, Rt_sd);
542 Rd_sd = Rt_sd;
543 }}, {{EA = Rs1;}});
544 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
545 Mem_sw = min<uint32_t>(Rs2_uw, Rt_sd);
546 Rd_sd = Rt_sd;
547 }}, {{EA = Rs1;}});
548 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
549 Mem_sw = max<uint32_t>(Rs2_uw, Rt_sd);
550 Rd_sd = Rt_sd;
551 }}, {{EA = Rs1;}});
552 }
553 }
554 0x3: decode AMOFUNCT {
555 0x2: LoadReserved::lr_d({{
556 Rd_sd = Mem_sd;
557 }}, mem_flags=LLSC);
558 0x3: StoreCond::sc_d({{
559 Mem = Rs2;
560 }}, {{
561 Rd = result;
562 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
563 format AtomicMemOp {
564 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
565 Mem_sd = Rs2_sd + Rt_sd;
566 Rd_sd = Rt_sd;
567 }}, {{EA = Rs1;}});
568 0x1: amoswap_d({{Rt = Mem;}}, {{
569 Mem = Rs2;
570 Rd = Rt;
571 }}, {{EA = Rs1;}});
572 0x4: amoxor_d({{Rt = Mem;}}, {{
573 Mem = Rs2^Rt;
574 Rd = Rt;
575 }}, {{EA = Rs1;}});
576 0x8: amoor_d({{Rt = Mem;}}, {{
577 Mem = Rs2 | Rt;
578 Rd = Rt;
579 }}, {{EA = Rs1;}});
580 0xc: amoand_d({{Rt = Mem;}}, {{
581 Mem = Rs2&Rt;
582 Rd = Rt;
583 }}, {{EA = Rs1;}});
584 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
585 Mem_sd = min(Rs2_sd, Rt_sd);
586 Rd_sd = Rt_sd;
587 }}, {{EA = Rs1;}});
588 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
589 Mem_sd = max(Rs2_sd, Rt_sd);
590 Rd_sd = Rt_sd;
591 }}, {{EA = Rs1;}});
592 0x18: amominu_d({{Rt = Mem;}}, {{
593 Mem = min(Rs2, Rt);
594 Rd = Rt;
595 }}, {{EA = Rs1;}});
596 0x1c: amomaxu_d({{Rt = Mem;}}, {{
597 Mem = max(Rs2, Rt);
598 Rd = Rt;
599 }}, {{EA = Rs1;}});
600 }
601 }
602 }
603 0x0c: decode FUNCT3 {
604 format ROp {
605 0x0: decode FUNCT7 {
606 0x0: add({{
607 Rd = Rs1_sd + Rs2_sd;
608 }});
609 0x1: mul({{
610 Rd = Rs1_sd*Rs2_sd;
611 }}, IntMultOp);
612 0x20: sub({{
613 Rd = Rs1_sd - Rs2_sd;
614 }});
615 }
616 0x1: decode FUNCT7 {
617 0x0: sll({{
618 Rd = Rs1 << Rs2<5:0>;
619 }});
620 0x1: mulh({{
621 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
622
623 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
624 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
625 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
626 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
627
628 uint64_t hi = Rs1_hi*Rs2_hi;
629 uint64_t mid1 = Rs1_hi*Rs2_lo;
630 uint64_t mid2 = Rs1_lo*Rs2_hi;
631 uint64_t lo = Rs2_lo*Rs1_lo;
632 uint64_t carry = ((uint64_t)(uint32_t)mid1
633 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
634
635 uint64_t res = hi +
636 (mid1 >> 32) +
637 (mid2 >> 32) +
638 carry;
639 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
640 : res;
641 }}, IntMultOp);
642 }
643 0x2: decode FUNCT7 {
644 0x0: slt({{
645 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
646 }});
647 0x1: mulhsu({{
648 bool negate = Rs1_sd < 0;
649 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
650 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
651 uint64_t Rs2_lo = (uint32_t)Rs2;
652 uint64_t Rs2_hi = Rs2 >> 32;
653
654 uint64_t hi = Rs1_hi*Rs2_hi;
655 uint64_t mid1 = Rs1_hi*Rs2_lo;
656 uint64_t mid2 = Rs1_lo*Rs2_hi;
657 uint64_t lo = Rs1_lo*Rs2_lo;
658 uint64_t carry = ((uint64_t)(uint32_t)mid1
659 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
660
661 uint64_t res = hi +
662 (mid1 >> 32) +
663 (mid2 >> 32) +
664 carry;
665 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
666 }}, IntMultOp);
667 }
668 0x3: decode FUNCT7 {
669 0x0: sltu({{
670 Rd = (Rs1 < Rs2) ? 1 : 0;
671 }});
672 0x1: mulhu({{
673 uint64_t Rs1_lo = (uint32_t)Rs1;
674 uint64_t Rs1_hi = Rs1 >> 32;
675 uint64_t Rs2_lo = (uint32_t)Rs2;
676 uint64_t Rs2_hi = Rs2 >> 32;
677
678 uint64_t hi = Rs1_hi*Rs2_hi;
679 uint64_t mid1 = Rs1_hi*Rs2_lo;
680 uint64_t mid2 = Rs1_lo*Rs2_hi;
681 uint64_t lo = Rs1_lo*Rs2_lo;
682 uint64_t carry = ((uint64_t)(uint32_t)mid1
683 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
684
685 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
686 }}, IntMultOp);
687 }
688 0x4: decode FUNCT7 {
689 0x0: xor({{
690 Rd = Rs1 ^ Rs2;
691 }});
692 0x1: div({{
693 if (Rs2_sd == 0) {
694 Rd_sd = -1;
695 } else if (Rs1_sd == numeric_limits<int64_t>::min()
696 && Rs2_sd == -1) {
697 Rd_sd = numeric_limits<int64_t>::min();
698 } else {
699 Rd_sd = Rs1_sd/Rs2_sd;
700 }
701 }}, IntDivOp);
702 }
703 0x5: decode FUNCT7 {
704 0x0: srl({{
705 Rd = Rs1 >> Rs2<5:0>;
706 }});
707 0x1: divu({{
708 if (Rs2 == 0) {
709 Rd = numeric_limits<uint64_t>::max();
710 } else {
711 Rd = Rs1/Rs2;
712 }
713 }}, IntDivOp);
714 0x20: sra({{
715 Rd_sd = Rs1_sd >> Rs2<5:0>;
716 }});
717 }
718 0x6: decode FUNCT7 {
719 0x0: or({{
720 Rd = Rs1 | Rs2;
721 }});
722 0x1: rem({{
723 if (Rs2_sd == 0) {
724 Rd = Rs1_sd;
725 } else if (Rs1_sd == numeric_limits<int64_t>::min()
726 && Rs2_sd == -1) {
727 Rd = 0;
728 } else {
729 Rd = Rs1_sd%Rs2_sd;
730 }
731 }}, IntDivOp);
732 }
733 0x7: decode FUNCT7 {
734 0x0: and({{
735 Rd = Rs1 & Rs2;
736 }});
737 0x1: remu({{
738 if (Rs2 == 0) {
739 Rd = Rs1;
740 } else {
741 Rd = Rs1%Rs2;
742 }
743 }}, IntDivOp);
744 }
745 }
746 }
747
748 0x0d: UOp::lui({{
749 Rd = (uint64_t)imm;
750 }});
751
752 0x0e: decode FUNCT3 {
753 format ROp {
754 0x0: decode FUNCT7 {
755 0x0: addw({{
756 Rd_sd = Rs1_sw + Rs2_sw;
757 }});
758 0x1: mulw({{
759 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
760 }}, IntMultOp);
761 0x20: subw({{
762 Rd_sd = Rs1_sw - Rs2_sw;
763 }});
764 }
765 0x1: sllw({{
766 Rd_sd = Rs1_sw << Rs2<4:0>;
767 }});
768 0x4: divw({{
769 if (Rs2_sw == 0) {
770 Rd_sd = -1;
771 } else if (Rs1_sw == numeric_limits<int32_t>::min()
772 && Rs2_sw == -1) {
773 Rd_sd = numeric_limits<int32_t>::min();
774 } else {
775 Rd_sd = Rs1_sw/Rs2_sw;
776 }
777 }}, IntDivOp);
778 0x5: decode FUNCT7 {
779 0x0: srlw({{
780 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
781 }});
782 0x1: divuw({{
783 if (Rs2_uw == 0) {
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2017 The University of Virginia
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// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// The RISC-V ISA decoder
35//
36
37decode QUADRANT default Unknown::unknown() {
38 0x0: decode COPCODE {
39 0x0: CIOp::c_addi4spn({{
40 imm = CIMM8<1:1> << 2 |
41 CIMM8<0:0> << 3 |
42 CIMM8<7:6> << 4 |
43 CIMM8<5:2> << 6;
44 }}, {{
45 if (machInst == 0)
46 fault = make_shared<IllegalInstFault>("zero instruction",
47 machInst);
48 Rp2 = sp + imm;
49 }}, uint64_t);
50 format CompressedLoad {
51 0x1: c_fld({{
52 offset = CIMM3 << 3 | CIMM2 << 6;
53 }}, {{
54 Fp2_bits = Mem;
55 }}, {{
56 EA = Rp1 + offset;
57 }});
58 0x2: c_lw({{
59 offset = CIMM2<1:1> << 2 |
60 CIMM3 << 3 |
61 CIMM2<0:0> << 6;
62 }}, {{
63 Rp2_sd = Mem_sw;
64 }}, {{
65 EA = Rp1 + offset;
66 }});
67 0x3: c_ld({{
68 offset = CIMM3 << 3 | CIMM2 << 6;
69 }}, {{
70 Rp2_sd = Mem_sd;
71 }}, {{
72 EA = Rp1 + offset;
73 }});
74 }
75 format CompressedStore {
76 0x5: c_fsd({{
77 offset = CIMM3 << 3 | CIMM2 << 6;
78 }}, {{
79 Mem = Fp2_bits;
80 }}, {{
81 EA = Rp1 + offset;
82 }});
83 0x6: c_sw({{
84 offset = CIMM2<1:1> << 2 |
85 CIMM3 << 3 |
86 CIMM2<0:0> << 6;
87 }}, {{
88 Mem_uw = Rp2_uw;
89 }}, ea_code={{
90 EA = Rp1 + offset;
91 }});
92 0x7: c_sd({{
93 offset = CIMM3 << 3 | CIMM2 << 6;
94 }}, {{
95 Mem_ud = Rp2_ud;
96 }}, {{
97 EA = Rp1 + offset;
98 }});
99 }
100 }
101 0x1: decode COPCODE {
102 format CIOp {
103 0x0: c_addi({{
104 imm = CIMM5;
105 if (CIMM1 > 0)
106 imm |= ~((uint64_t)0x1F);
107 }}, {{
108 if ((RC1 == 0) != (imm == 0)) {
109 if (RC1 == 0) {
110 fault = make_shared<IllegalInstFault>("source reg x0",
111 machInst);
112 } else // imm == 0
113 fault = make_shared<IllegalInstFault>("immediate = 0",
114 machInst);
115 }
116 Rc1_sd = Rc1_sd + imm;
117 }});
118 0x1: c_addiw({{
119 imm = CIMM5;
120 if (CIMM1 > 0)
121 imm |= ~((uint64_t)0x1F);
122 }}, {{
123 if (RC1 == 0) {
124 fault = make_shared<IllegalInstFault>("source reg x0",
125 machInst);
126 }
127 Rc1_sd = (int32_t)Rc1_sd + imm;
128 }});
129 0x2: c_li({{
130 imm = CIMM5;
131 if (CIMM1 > 0)
132 imm |= ~((uint64_t)0x1F);
133 }}, {{
134 if (RC1 == 0) {
135 fault = make_shared<IllegalInstFault>("source reg x0",
136 machInst);
137 }
138 Rc1_sd = imm;
139 }});
140 0x3: decode RC1 {
141 0x2: c_addi16sp({{
142 imm = CIMM5<4:4> << 4 |
143 CIMM5<0:0> << 5 |
144 CIMM5<3:3> << 6 |
145 CIMM5<2:1> << 7;
146 if (CIMM1 > 0)
147 imm |= ~((int64_t)0x1FF);
148 }}, {{
149 if (imm == 0) {
150 fault = make_shared<IllegalInstFault>("immediate = 0",
151 machInst);
152 }
153 sp_sd = sp_sd + imm;
154 }});
155 default: c_lui({{
156 imm = CIMM5 << 12;
157 if (CIMM1 > 0)
158 imm |= ~((uint64_t)0x1FFFF);
159 }}, {{
160 if (RC1 == 0 || RC1 == 2) {
161 fault = make_shared<IllegalInstFault>("source reg x0",
162 machInst);
163 }
164 if (imm == 0) {
165 fault = make_shared<IllegalInstFault>("immediate = 0",
166 machInst);
167 }
168 Rc1_sd = imm;
169 }});
170 }
171 }
172 0x4: decode CFUNCT2HIGH {
173 format CIOp {
174 0x0: c_srli({{
175 imm = CIMM5 | (CIMM1 << 5);
176 }}, {{
177 if (imm == 0) {
178 fault = make_shared<IllegalInstFault>("immediate = 0",
179 machInst);
180 }
181 Rp1 = Rp1 >> imm;
182 }}, uint64_t);
183 0x1: c_srai({{
184 imm = CIMM5 | (CIMM1 << 5);
185 }}, {{
186 if (imm == 0) {
187 fault = make_shared<IllegalInstFault>("immediate = 0",
188 machInst);
189 }
190 Rp1_sd = Rp1_sd >> imm;
191 }}, uint64_t);
192 0x2: c_andi({{
193 imm = CIMM5;
194 if (CIMM1 > 0)
195 imm |= ~((uint64_t)0x1F);
196 }}, {{
197 Rp1 = Rp1 & imm;
198 }}, uint64_t);
199 }
200 format ROp {
201 0x3: decode CFUNCT1 {
202 0x0: decode CFUNCT2LOW {
203 0x0: c_sub({{
204 Rp1 = Rp1 - Rp2;
205 }});
206 0x1: c_xor({{
207 Rp1 = Rp1 ^ Rp2;
208 }});
209 0x2: c_or({{
210 Rp1 = Rp1 | Rp2;
211 }});
212 0x3: c_and({{
213 Rp1 = Rp1 & Rp2;
214 }});
215 }
216 0x1: decode CFUNCT2LOW {
217 0x0: c_subw({{
218 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
219 }});
220 0x1: c_addw({{
221 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
222 }});
223 }
224 }
225 }
226 }
227 0x5: JOp::c_j({{
228 int64_t offset = CJUMPIMM<3:1> << 1 |
229 CJUMPIMM<9:9> << 4 |
230 CJUMPIMM<0:0> << 5 |
231 CJUMPIMM<5:5> << 6 |
232 CJUMPIMM<4:4> << 7 |
233 CJUMPIMM<8:7> << 8 |
234 CJUMPIMM<6:6> << 10;
235 if (CJUMPIMM<10:10> > 0)
236 offset |= ~((int64_t)0x7FF);
237 NPC = PC + offset;
238 }}, IsIndirectControl, IsUncondControl, IsCall);
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: ROp::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 Fd_bits = (uint64_t)Mem_uw;
404 }}, inst_flags=FloatMemReadOp);
405 0x3: fld({{
406 Fd_bits = Mem;
407 }}, inst_flags=FloatMemReadOp);
408 }
409 }
410
411 0x03: decode FUNCT3 {
412 format IOp {
413 0x0: fence({{
414 }}, uint64_t, IsNonSpeculative, IsMemBarrier, No_OpClass);
415 0x1: fence_i({{
416 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
417 }
418 }
419
420 0x04: decode FUNCT3 {
421 format IOp {
422 0x0: addi({{
423 Rd_sd = Rs1_sd + imm;
424 }});
425 0x1: slli({{
426 Rd = Rs1 << SHAMT6;
427 }});
428 0x2: slti({{
429 Rd = (Rs1_sd < imm) ? 1 : 0;
430 }});
431 0x3: sltiu({{
432 Rd = (Rs1 < imm) ? 1 : 0;
433 }}, uint64_t);
434 0x4: xori({{
435 Rd = Rs1 ^ imm;
436 }}, uint64_t);
437 0x5: decode SRTYPE {
438 0x0: srli({{
439 Rd = Rs1 >> SHAMT6;
440 }});
441 0x1: srai({{
442 Rd_sd = Rs1_sd >> SHAMT6;
443 }});
444 }
445 0x6: ori({{
446 Rd = Rs1 | imm;
447 }}, uint64_t);
448 0x7: andi({{
449 Rd = Rs1 & imm;
450 }}, uint64_t);
451 }
452 }
453
454 0x05: UOp::auipc({{
455 Rd = PC + imm;
456 }});
457
458 0x06: decode FUNCT3 {
459 format IOp {
460 0x0: addiw({{
461 Rd_sd = Rs1_sw + imm;
462 }}, int32_t);
463 0x1: slliw({{
464 Rd_sd = Rs1_sw << SHAMT5;
465 }});
466 0x5: decode SRTYPE {
467 0x0: srliw({{
468 Rd_sd = (int32_t)(Rs1_uw >> SHAMT5);
469 }});
470 0x1: sraiw({{
471 Rd_sd = Rs1_sw >> SHAMT5;
472 }});
473 }
474 }
475 }
476
477 0x08: decode FUNCT3 {
478 format Store {
479 0x0: sb({{
480 Mem_ub = Rs2_ub;
481 }});
482 0x1: sh({{
483 Mem_uh = Rs2_uh;
484 }});
485 0x2: sw({{
486 Mem_uw = Rs2_uw;
487 }});
488 0x3: sd({{
489 Mem_ud = Rs2_ud;
490 }});
491 }
492 }
493
494 0x09: decode FUNCT3 {
495 format Store {
496 0x2: fsw({{
497 Mem_uw = (uint32_t)Fs2_bits;
498 }}, inst_flags=FloatMemWriteOp);
499 0x3: fsd({{
500 Mem_ud = Fs2_bits;
501 }}, inst_flags=FloatMemWriteOp);
502 }
503 }
504
505 0x0b: decode FUNCT3 {
506 0x2: decode AMOFUNCT {
507 0x2: LoadReserved::lr_w({{
508 Rd_sd = Mem_sw;
509 }}, mem_flags=LLSC);
510 0x3: StoreCond::sc_w({{
511 Mem_uw = Rs2_uw;
512 }}, {{
513 Rd = result;
514 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
515 format AtomicMemOp {
516 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
517 Mem_sw = Rs2_sw + Rt_sd;
518 Rd_sd = Rt_sd;
519 }}, {{EA = Rs1;}});
520 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
521 Mem_sw = Rs2_uw;
522 Rd_sd = Rt_sd;
523 }}, {{EA = Rs1;}});
524 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
525 Mem_sw = Rs2_uw^Rt_sd;
526 Rd_sd = Rt_sd;
527 }}, {{EA = Rs1;}});
528 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
529 Mem_sw = Rs2_uw | Rt_sd;
530 Rd_sd = Rt_sd;
531 }}, {{EA = Rs1;}});
532 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
533 Mem_sw = Rs2_uw&Rt_sd;
534 Rd_sd = Rt_sd;
535 }}, {{EA = Rs1;}});
536 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
537 Mem_sw = min<int32_t>(Rs2_sw, Rt_sd);
538 Rd_sd = Rt_sd;
539 }}, {{EA = Rs1;}});
540 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
541 Mem_sw = max<int32_t>(Rs2_sw, Rt_sd);
542 Rd_sd = Rt_sd;
543 }}, {{EA = Rs1;}});
544 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
545 Mem_sw = min<uint32_t>(Rs2_uw, Rt_sd);
546 Rd_sd = Rt_sd;
547 }}, {{EA = Rs1;}});
548 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
549 Mem_sw = max<uint32_t>(Rs2_uw, Rt_sd);
550 Rd_sd = Rt_sd;
551 }}, {{EA = Rs1;}});
552 }
553 }
554 0x3: decode AMOFUNCT {
555 0x2: LoadReserved::lr_d({{
556 Rd_sd = Mem_sd;
557 }}, mem_flags=LLSC);
558 0x3: StoreCond::sc_d({{
559 Mem = Rs2;
560 }}, {{
561 Rd = result;
562 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
563 format AtomicMemOp {
564 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
565 Mem_sd = Rs2_sd + Rt_sd;
566 Rd_sd = Rt_sd;
567 }}, {{EA = Rs1;}});
568 0x1: amoswap_d({{Rt = Mem;}}, {{
569 Mem = Rs2;
570 Rd = Rt;
571 }}, {{EA = Rs1;}});
572 0x4: amoxor_d({{Rt = Mem;}}, {{
573 Mem = Rs2^Rt;
574 Rd = Rt;
575 }}, {{EA = Rs1;}});
576 0x8: amoor_d({{Rt = Mem;}}, {{
577 Mem = Rs2 | Rt;
578 Rd = Rt;
579 }}, {{EA = Rs1;}});
580 0xc: amoand_d({{Rt = Mem;}}, {{
581 Mem = Rs2&Rt;
582 Rd = Rt;
583 }}, {{EA = Rs1;}});
584 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
585 Mem_sd = min(Rs2_sd, Rt_sd);
586 Rd_sd = Rt_sd;
587 }}, {{EA = Rs1;}});
588 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
589 Mem_sd = max(Rs2_sd, Rt_sd);
590 Rd_sd = Rt_sd;
591 }}, {{EA = Rs1;}});
592 0x18: amominu_d({{Rt = Mem;}}, {{
593 Mem = min(Rs2, Rt);
594 Rd = Rt;
595 }}, {{EA = Rs1;}});
596 0x1c: amomaxu_d({{Rt = Mem;}}, {{
597 Mem = max(Rs2, Rt);
598 Rd = Rt;
599 }}, {{EA = Rs1;}});
600 }
601 }
602 }
603 0x0c: decode FUNCT3 {
604 format ROp {
605 0x0: decode FUNCT7 {
606 0x0: add({{
607 Rd = Rs1_sd + Rs2_sd;
608 }});
609 0x1: mul({{
610 Rd = Rs1_sd*Rs2_sd;
611 }}, IntMultOp);
612 0x20: sub({{
613 Rd = Rs1_sd - Rs2_sd;
614 }});
615 }
616 0x1: decode FUNCT7 {
617 0x0: sll({{
618 Rd = Rs1 << Rs2<5:0>;
619 }});
620 0x1: mulh({{
621 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
622
623 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
624 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
625 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
626 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
627
628 uint64_t hi = Rs1_hi*Rs2_hi;
629 uint64_t mid1 = Rs1_hi*Rs2_lo;
630 uint64_t mid2 = Rs1_lo*Rs2_hi;
631 uint64_t lo = Rs2_lo*Rs1_lo;
632 uint64_t carry = ((uint64_t)(uint32_t)mid1
633 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
634
635 uint64_t res = hi +
636 (mid1 >> 32) +
637 (mid2 >> 32) +
638 carry;
639 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
640 : res;
641 }}, IntMultOp);
642 }
643 0x2: decode FUNCT7 {
644 0x0: slt({{
645 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
646 }});
647 0x1: mulhsu({{
648 bool negate = Rs1_sd < 0;
649 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
650 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
651 uint64_t Rs2_lo = (uint32_t)Rs2;
652 uint64_t Rs2_hi = Rs2 >> 32;
653
654 uint64_t hi = Rs1_hi*Rs2_hi;
655 uint64_t mid1 = Rs1_hi*Rs2_lo;
656 uint64_t mid2 = Rs1_lo*Rs2_hi;
657 uint64_t lo = Rs1_lo*Rs2_lo;
658 uint64_t carry = ((uint64_t)(uint32_t)mid1
659 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
660
661 uint64_t res = hi +
662 (mid1 >> 32) +
663 (mid2 >> 32) +
664 carry;
665 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
666 }}, IntMultOp);
667 }
668 0x3: decode FUNCT7 {
669 0x0: sltu({{
670 Rd = (Rs1 < Rs2) ? 1 : 0;
671 }});
672 0x1: mulhu({{
673 uint64_t Rs1_lo = (uint32_t)Rs1;
674 uint64_t Rs1_hi = Rs1 >> 32;
675 uint64_t Rs2_lo = (uint32_t)Rs2;
676 uint64_t Rs2_hi = Rs2 >> 32;
677
678 uint64_t hi = Rs1_hi*Rs2_hi;
679 uint64_t mid1 = Rs1_hi*Rs2_lo;
680 uint64_t mid2 = Rs1_lo*Rs2_hi;
681 uint64_t lo = Rs1_lo*Rs2_lo;
682 uint64_t carry = ((uint64_t)(uint32_t)mid1
683 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
684
685 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
686 }}, IntMultOp);
687 }
688 0x4: decode FUNCT7 {
689 0x0: xor({{
690 Rd = Rs1 ^ Rs2;
691 }});
692 0x1: div({{
693 if (Rs2_sd == 0) {
694 Rd_sd = -1;
695 } else if (Rs1_sd == numeric_limits<int64_t>::min()
696 && Rs2_sd == -1) {
697 Rd_sd = numeric_limits<int64_t>::min();
698 } else {
699 Rd_sd = Rs1_sd/Rs2_sd;
700 }
701 }}, IntDivOp);
702 }
703 0x5: decode FUNCT7 {
704 0x0: srl({{
705 Rd = Rs1 >> Rs2<5:0>;
706 }});
707 0x1: divu({{
708 if (Rs2 == 0) {
709 Rd = numeric_limits<uint64_t>::max();
710 } else {
711 Rd = Rs1/Rs2;
712 }
713 }}, IntDivOp);
714 0x20: sra({{
715 Rd_sd = Rs1_sd >> Rs2<5:0>;
716 }});
717 }
718 0x6: decode FUNCT7 {
719 0x0: or({{
720 Rd = Rs1 | Rs2;
721 }});
722 0x1: rem({{
723 if (Rs2_sd == 0) {
724 Rd = Rs1_sd;
725 } else if (Rs1_sd == numeric_limits<int64_t>::min()
726 && Rs2_sd == -1) {
727 Rd = 0;
728 } else {
729 Rd = Rs1_sd%Rs2_sd;
730 }
731 }}, IntDivOp);
732 }
733 0x7: decode FUNCT7 {
734 0x0: and({{
735 Rd = Rs1 & Rs2;
736 }});
737 0x1: remu({{
738 if (Rs2 == 0) {
739 Rd = Rs1;
740 } else {
741 Rd = Rs1%Rs2;
742 }
743 }}, IntDivOp);
744 }
745 }
746 }
747
748 0x0d: UOp::lui({{
749 Rd = (uint64_t)imm;
750 }});
751
752 0x0e: decode FUNCT3 {
753 format ROp {
754 0x0: decode FUNCT7 {
755 0x0: addw({{
756 Rd_sd = Rs1_sw + Rs2_sw;
757 }});
758 0x1: mulw({{
759 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
760 }}, IntMultOp);
761 0x20: subw({{
762 Rd_sd = Rs1_sw - Rs2_sw;
763 }});
764 }
765 0x1: sllw({{
766 Rd_sd = Rs1_sw << Rs2<4:0>;
767 }});
768 0x4: divw({{
769 if (Rs2_sw == 0) {
770 Rd_sd = -1;
771 } else if (Rs1_sw == numeric_limits<int32_t>::min()
772 && Rs2_sw == -1) {
773 Rd_sd = numeric_limits<int32_t>::min();
774 } else {
775 Rd_sd = Rs1_sw/Rs2_sw;
776 }
777 }}, IntDivOp);
778 0x5: decode FUNCT7 {
779 0x0: srlw({{
780 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
781 }});
782 0x1: divuw({{
783 if (Rs2_uw == 0) {
784 Rd_sd = numeric_limits<IntReg>::max();
784 Rd_sd = numeric_limits<uint64_t>::max();
785 } else {
786 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
787 }
788 }}, IntDivOp);
789 0x20: sraw({{
790 Rd_sd = Rs1_sw >> Rs2<4:0>;
791 }});
792 }
793 0x6: remw({{
794 if (Rs2_sw == 0) {
795 Rd_sd = Rs1_sw;
796 } else if (Rs1_sw == numeric_limits<int32_t>::min()
797 && Rs2_sw == -1) {
798 Rd_sd = 0;
799 } else {
800 Rd_sd = Rs1_sw%Rs2_sw;
801 }
802 }}, IntDivOp);
803 0x7: remuw({{
804 if (Rs2_uw == 0) {
805 Rd_sd = (int32_t)Rs1_uw;
806 } else {
807 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
808 }
809 }}, IntDivOp);
810 }
811 }
812
813 format FPROp {
814 0x10: decode FUNCT2 {
815 0x0: fmadd_s({{
816 uint32_t temp;
817 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
818 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
819 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
820 float fd;
821
822 if (std::isnan(fs1) || std::isnan(fs2) ||
823 std::isnan(fs3)) {
824 if (issignalingnan(fs1) || issignalingnan(fs2)
825 || issignalingnan(fs3)) {
826 FFLAGS |= FloatInvalid;
827 }
828 fd = numeric_limits<float>::quiet_NaN();
829 } else if (std::isinf(fs1) || std::isinf(fs2) ||
830 std::isinf(fs3)) {
831 if (signbit(fs1) == signbit(fs2)
832 && !std::isinf(fs3)) {
833 fd = numeric_limits<float>::infinity();
834 } else if (signbit(fs1) != signbit(fs2)
835 && !std::isinf(fs3)) {
836 fd = -numeric_limits<float>::infinity();
837 } else { // Fs3_sf is infinity
838 fd = fs3;
839 }
840 } else {
841 fd = fs1*fs2 + fs3;
842 }
843 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
844 }}, FloatMultAccOp);
845 0x1: fmadd_d({{
846 if (std::isnan(Fs1) || std::isnan(Fs2) ||
847 std::isnan(Fs3)) {
848 if (issignalingnan(Fs1) || issignalingnan(Fs2)
849 || issignalingnan(Fs3)) {
850 FFLAGS |= FloatInvalid;
851 }
852 Fd = numeric_limits<double>::quiet_NaN();
853 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
854 std::isinf(Fs3)) {
855 if (signbit(Fs1) == signbit(Fs2)
856 && !std::isinf(Fs3)) {
857 Fd = numeric_limits<double>::infinity();
858 } else if (signbit(Fs1) != signbit(Fs2)
859 && !std::isinf(Fs3)) {
860 Fd = -numeric_limits<double>::infinity();
861 } else {
862 Fd = Fs3;
863 }
864 } else {
865 Fd = Fs1*Fs2 + Fs3;
866 }
867 }}, FloatMultAccOp);
868 }
869 0x11: decode FUNCT2 {
870 0x0: fmsub_s({{
871 uint32_t temp;
872 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
873 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
874 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
875 float fd;
876
877 if (std::isnan(fs1) || std::isnan(fs2) ||
878 std::isnan(fs3)) {
879 if (issignalingnan(fs1) || issignalingnan(fs2)
880 || issignalingnan(fs3)) {
881 FFLAGS |= FloatInvalid;
882 }
883 fd = numeric_limits<float>::quiet_NaN();
884 } else if (std::isinf(fs1) || std::isinf(fs2) ||
885 std::isinf(fs3)) {
886 if (signbit(fs1) == signbit(fs2)
887 && !std::isinf(fs3)) {
888 fd = numeric_limits<float>::infinity();
889 } else if (signbit(fs1) != signbit(fs2)
890 && !std::isinf(fs3)) {
891 fd = -numeric_limits<float>::infinity();
892 } else { // Fs3_sf is infinity
893 fd = -fs3;
894 }
895 } else {
896 fd = fs1*fs2 - fs3;
897 }
898 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
899 }}, FloatMultAccOp);
900 0x1: fmsub_d({{
901 if (std::isnan(Fs1) || std::isnan(Fs2) ||
902 std::isnan(Fs3)) {
903 if (issignalingnan(Fs1) || issignalingnan(Fs2)
904 || issignalingnan(Fs3)) {
905 FFLAGS |= FloatInvalid;
906 }
907 Fd = numeric_limits<double>::quiet_NaN();
908 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
909 std::isinf(Fs3)) {
910 if (signbit(Fs1) == signbit(Fs2)
911 && !std::isinf(Fs3)) {
912 Fd = numeric_limits<double>::infinity();
913 } else if (signbit(Fs1) != signbit(Fs2)
914 && !std::isinf(Fs3)) {
915 Fd = -numeric_limits<double>::infinity();
916 } else {
917 Fd = -Fs3;
918 }
919 } else {
920 Fd = Fs1*Fs2 - Fs3;
921 }
922 }}, FloatMultAccOp);
923 }
924 0x12: decode FUNCT2 {
925 0x0: fnmsub_s({{
926 uint32_t temp;
927 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
928 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
929 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
930 float fd;
931
932 if (std::isnan(fs1) || std::isnan(fs2) ||
933 std::isnan(fs3)) {
934 if (issignalingnan(fs1) || issignalingnan(fs2)
935 || issignalingnan(fs3)) {
936 FFLAGS |= FloatInvalid;
937 }
938 fd = numeric_limits<float>::quiet_NaN();
939 } else if (std::isinf(fs1) || std::isinf(fs2) ||
940 std::isinf(fs3)) {
941 if (signbit(fs1) == signbit(fs2)
942 && !std::isinf(fs3)) {
943 fd = -numeric_limits<float>::infinity();
944 } else if (signbit(fs1) != signbit(fs2)
945 && !std::isinf(fs3)) {
946 fd = numeric_limits<float>::infinity();
947 } else { // Fs3_sf is infinity
948 fd = fs3;
949 }
950 } else {
951 fd = -(fs1*fs2 - fs3);
952 }
953 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
954 }}, FloatMultAccOp);
955 0x1: fnmsub_d({{
956 if (std::isnan(Fs1) || std::isnan(Fs2) ||
957 std::isnan(Fs3)) {
958 if (issignalingnan(Fs1) || issignalingnan(Fs2)
959 || issignalingnan(Fs3)) {
960 FFLAGS |= FloatInvalid;
961 }
962 Fd = numeric_limits<double>::quiet_NaN();
963 } else if (std::isinf(Fs1) || std::isinf(Fs2)
964 || std::isinf(Fs3)) {
965 if (signbit(Fs1) == signbit(Fs2)
966 && !std::isinf(Fs3)) {
967 Fd = -numeric_limits<double>::infinity();
968 } else if (signbit(Fs1) != signbit(Fs2)
969 && !std::isinf(Fs3)) {
970 Fd = numeric_limits<double>::infinity();
971 } else {
972 Fd = Fs3;
973 }
974 } else {
975 Fd = -(Fs1*Fs2 - Fs3);
976 }
977 }}, FloatMultAccOp);
978 }
979 0x13: decode FUNCT2 {
980 0x0: fnmadd_s({{
981 uint32_t temp;
982 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
983 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
984 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
985 float fd;
986
987 if (std::isnan(fs1) || std::isnan(fs2) ||
988 std::isnan(fs3)) {
989 if (issignalingnan(fs1) || issignalingnan(fs2)
990 || issignalingnan(fs3)) {
991 FFLAGS |= FloatInvalid;
992 }
993 fd = numeric_limits<float>::quiet_NaN();
994 } else if (std::isinf(fs1) || std::isinf(fs2) ||
995 std::isinf(fs3)) {
996 if (signbit(fs1) == signbit(fs2)
997 && !std::isinf(fs3)) {
998 fd = -numeric_limits<float>::infinity();
999 } else if (signbit(fs1) != signbit(fs2)
1000 && !std::isinf(fs3)) {
1001 fd = numeric_limits<float>::infinity();
1002 } else { // Fs3_sf is infinity
1003 fd = -fs3;
1004 }
1005 } else {
1006 fd = -(fs1*fs2 + fs3);
1007 }
1008 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1009 }}, FloatMultAccOp);
1010 0x1: fnmadd_d({{
1011 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1012 std::isnan(Fs3)) {
1013 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1014 || issignalingnan(Fs3)) {
1015 FFLAGS |= FloatInvalid;
1016 }
1017 Fd = numeric_limits<double>::quiet_NaN();
1018 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1019 std::isinf(Fs3)) {
1020 if (signbit(Fs1) == signbit(Fs2)
1021 && !std::isinf(Fs3)) {
1022 Fd = -numeric_limits<double>::infinity();
1023 } else if (signbit(Fs1) != signbit(Fs2)
1024 && !std::isinf(Fs3)) {
1025 Fd = numeric_limits<double>::infinity();
1026 } else {
1027 Fd = -Fs3;
1028 }
1029 } else {
1030 Fd = -(Fs1*Fs2 + Fs3);
1031 }
1032 }}, FloatMultAccOp);
1033 }
1034 0x14: decode FUNCT7 {
1035 0x0: fadd_s({{
1036 uint32_t temp;
1037 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1038 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1039 float fd;
1040
1041 if (std::isnan(fs1) || std::isnan(fs2)) {
1042 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1043 FFLAGS |= FloatInvalid;
1044 }
1045 fd = numeric_limits<float>::quiet_NaN();
1046 } else {
1047 fd = fs1 + fs2;
1048 }
1049 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1050 }}, FloatAddOp);
1051 0x1: fadd_d({{
1052 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1053 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1054 FFLAGS |= FloatInvalid;
1055 }
1056 Fd = numeric_limits<double>::quiet_NaN();
1057 } else {
1058 Fd = Fs1 + Fs2;
1059 }
1060 }}, FloatAddOp);
1061 0x4: fsub_s({{
1062 uint32_t temp;
1063 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1064 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1065 float fd;
1066
1067 if (std::isnan(fs1) || std::isnan(fs2)) {
1068 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1069 FFLAGS |= FloatInvalid;
1070 }
1071 fd = numeric_limits<float>::quiet_NaN();
1072 } else {
1073 fd = fs1 - fs2;
1074 }
1075 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1076 }}, FloatAddOp);
1077 0x5: fsub_d({{
1078 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1079 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1080 FFLAGS |= FloatInvalid;
1081 }
1082 Fd = numeric_limits<double>::quiet_NaN();
1083 } else {
1084 Fd = Fs1 - Fs2;
1085 }
1086 }}, FloatAddOp);
1087 0x8: fmul_s({{
1088 uint32_t temp;
1089 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1090 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1091 float fd;
1092
1093 if (std::isnan(fs1) || std::isnan(fs2)) {
1094 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1095 FFLAGS |= FloatInvalid;
1096 }
1097 fd = numeric_limits<float>::quiet_NaN();
1098 } else {
1099 fd = fs1*fs2;
1100 }
1101 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1102 }}, FloatMultOp);
1103 0x9: fmul_d({{
1104 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1105 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1106 FFLAGS |= FloatInvalid;
1107 }
1108 Fd = numeric_limits<double>::quiet_NaN();
1109 } else {
1110 Fd = Fs1*Fs2;
1111 }
1112 }}, FloatMultOp);
1113 0xc: fdiv_s({{
1114 uint32_t temp;
1115 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1116 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1117 float fd;
1118
1119 if (std::isnan(fs1) || std::isnan(fs2)) {
1120 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1121 FFLAGS |= FloatInvalid;
1122 }
1123 fd = numeric_limits<float>::quiet_NaN();
1124 } else {
1125 fd = fs1/fs2;
1126 }
1127 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1128 }}, FloatDivOp);
1129 0xd: fdiv_d({{
1130 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1131 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1132 FFLAGS |= FloatInvalid;
1133 }
1134 Fd = numeric_limits<double>::quiet_NaN();
1135 } else {
1136 Fd = Fs1/Fs2;
1137 }
1138 }}, FloatDivOp);
1139 0x10: decode ROUND_MODE {
1140 0x0: fsgnj_s({{
1141 uint32_t temp;
1142 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1143 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1144 float fd;
1145
1146 if (issignalingnan(fs1)) {
1147 fd = numeric_limits<float>::signaling_NaN();
1148 feclearexcept(FE_INVALID);
1149 } else {
1150 fd = copysign(fs1, fs2);
1151 }
1152 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1153 }}, FloatMiscOp);
1154 0x1: fsgnjn_s({{
1155 uint32_t temp;
1156 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1157 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1158 float fd;
1159
1160 if (issignalingnan(fs1)) {
1161 fd = numeric_limits<float>::signaling_NaN();
1162 feclearexcept(FE_INVALID);
1163 } else {
1164 fd = copysign(fs1, -fs2);
1165 }
1166 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1167 }}, FloatMiscOp);
1168 0x2: fsgnjx_s({{
1169 uint32_t temp;
1170 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1171 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1172 float fd;
1173
1174 if (issignalingnan(fs1)) {
1175 fd = numeric_limits<float>::signaling_NaN();
1176 feclearexcept(FE_INVALID);
1177 } else {
1178 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1179 }
1180 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1181 }}, FloatMiscOp);
1182 }
1183 0x11: decode ROUND_MODE {
1184 0x0: fsgnj_d({{
1185 if (issignalingnan(Fs1)) {
1186 Fd = numeric_limits<double>::signaling_NaN();
1187 feclearexcept(FE_INVALID);
1188 } else {
1189 Fd = copysign(Fs1, Fs2);
1190 }
1191 }}, FloatMiscOp);
1192 0x1: fsgnjn_d({{
1193 if (issignalingnan(Fs1)) {
1194 Fd = numeric_limits<double>::signaling_NaN();
1195 feclearexcept(FE_INVALID);
1196 } else {
1197 Fd = copysign(Fs1, -Fs2);
1198 }
1199 }}, FloatMiscOp);
1200 0x2: fsgnjx_d({{
1201 if (issignalingnan(Fs1)) {
1202 Fd = numeric_limits<double>::signaling_NaN();
1203 feclearexcept(FE_INVALID);
1204 } else {
1205 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1206 }
1207 }}, FloatMiscOp);
1208 }
1209 0x14: decode ROUND_MODE {
1210 0x0: fmin_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(fs2)) {
1217 fd = fs1;
1218 FFLAGS |= FloatInvalid;
1219 } else if (issignalingnan(fs1)) {
1220 fd = fs2;
1221 FFLAGS |= FloatInvalid;
1222 } else {
1223 fd = fmin(fs1, fs2);
1224 }
1225 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1226 }}, FloatCmpOp);
1227 0x1: fmax_s({{
1228 uint32_t temp;
1229 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1230 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1231 float fd;
1232
1233 if (issignalingnan(fs2)) {
1234 fd = fs1;
1235 FFLAGS |= FloatInvalid;
1236 } else if (issignalingnan(fs1)) {
1237 fd = fs2;
1238 FFLAGS |= FloatInvalid;
1239 } else {
1240 fd = fmax(fs1, fs2);
1241 }
1242 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1243 }}, FloatCmpOp);
1244 }
1245 0x15: decode ROUND_MODE {
1246 0x0: fmin_d({{
1247 if (issignalingnan(Fs2)) {
1248 Fd = Fs1;
1249 FFLAGS |= FloatInvalid;
1250 } else if (issignalingnan(Fs1)) {
1251 Fd = Fs2;
1252 FFLAGS |= FloatInvalid;
1253 } else {
1254 Fd = fmin(Fs1, Fs2);
1255 }
1256 }}, FloatCmpOp);
1257 0x1: fmax_d({{
1258 if (issignalingnan(Fs2)) {
1259 Fd = Fs1;
1260 FFLAGS |= FloatInvalid;
1261 } else if (issignalingnan(Fs1)) {
1262 Fd = Fs2;
1263 FFLAGS |= FloatInvalid;
1264 } else {
1265 Fd = fmax(Fs1, Fs2);
1266 }
1267 }}, FloatCmpOp);
1268 }
1269 0x20: fcvt_s_d({{
1270 if (CONV_SGN != 1) {
1271 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1272 machInst);
1273 }
1274 float fd;
1275 if (issignalingnan(Fs1)) {
1276 fd = numeric_limits<float>::quiet_NaN();
1277 FFLAGS |= FloatInvalid;
1278 } else {
1279 fd = (float)Fs1;
1280 }
1281 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1282 }}, FloatCvtOp);
1283 0x21: fcvt_d_s({{
1284 if (CONV_SGN != 0) {
1285 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1286 machInst);
1287 }
1288 uint32_t temp;
1289 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1290
1291 if (issignalingnan(fs1)) {
1292 Fd = numeric_limits<double>::quiet_NaN();
1293 FFLAGS |= FloatInvalid;
1294 } else {
1295 Fd = (double)fs1;
1296 }
1297 }}, FloatCvtOp);
1298 0x2c: fsqrt_s({{
1299 if (RS2 != 0) {
1300 fault = make_shared<IllegalInstFault>("source reg x1",
1301 machInst);
1302 }
1303 uint32_t temp;
1304 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1305 float fd;
1306
1307 if (issignalingnan(Fs1_sf)) {
1308 FFLAGS |= FloatInvalid;
1309 }
1310 fd = sqrt(fs1);
1311 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1312 }}, FloatSqrtOp);
1313 0x2d: fsqrt_d({{
1314 if (RS2 != 0) {
1315 fault = make_shared<IllegalInstFault>("source reg x1",
1316 machInst);
1317 }
1318 Fd = sqrt(Fs1);
1319 }}, FloatSqrtOp);
1320 0x50: decode ROUND_MODE {
1321 0x0: fle_s({{
1322 uint32_t temp;
1323 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1324 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1325
1326 if (std::isnan(fs1) || std::isnan(fs2)) {
1327 FFLAGS |= FloatInvalid;
1328 Rd = 0;
1329 } else {
1330 Rd = fs1 <= fs2 ? 1 : 0;
1331 }
1332 }}, FloatCmpOp);
1333 0x1: flt_s({{
1334 uint32_t temp;
1335 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1336 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1337
1338 if (std::isnan(fs1) || std::isnan(fs2)) {
1339 FFLAGS |= FloatInvalid;
1340 Rd = 0;
1341 } else {
1342 Rd = fs1 < fs2 ? 1 : 0;
1343 }
1344 }}, FloatCmpOp);
1345 0x2: feq_s({{
1346 uint32_t temp;
1347 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1348 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1349
1350 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1351 FFLAGS |= FloatInvalid;
1352 }
1353 Rd = fs1 == fs2 ? 1 : 0;
1354 }}, FloatCmpOp);
1355 }
1356 0x51: decode ROUND_MODE {
1357 0x0: fle_d({{
1358 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1359 FFLAGS |= FloatInvalid;
1360 Rd = 0;
1361 } else {
1362 Rd = Fs1 <= Fs2 ? 1 : 0;
1363 }
1364 }}, FloatCmpOp);
1365 0x1: flt_d({{
1366 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1367 FFLAGS |= FloatInvalid;
1368 Rd = 0;
1369 } else {
1370 Rd = Fs1 < Fs2 ? 1 : 0;
1371 }
1372 }}, FloatCmpOp);
1373 0x2: feq_d({{
1374 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1375 FFLAGS |= FloatInvalid;
1376 }
1377 Rd = Fs1 == Fs2 ? 1 : 0;
1378 }}, FloatCmpOp);
1379 }
1380 0x60: decode CONV_SGN {
1381 0x0: fcvt_w_s({{
1382 uint32_t temp;
1383 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1384
1385 if (std::isnan(fs1)) {
1386 Rd_sd = numeric_limits<int32_t>::max();
1387 FFLAGS |= FloatInvalid;
1388 } else if (fs1 >= numeric_limits<int32_t>::max()) {
1389 Rd_sd = numeric_limits<int32_t>::max();
1390 FFLAGS |= FloatInvalid;
1391 } else if (fs1 <= numeric_limits<int32_t>::min()) {
1392 Rd_sd = numeric_limits<int32_t>::min();
1393 FFLAGS |= FloatInvalid;
1394 } else {
1395 Rd_sd = (int32_t)fs1;
1396 }
1397 }}, FloatCvtOp);
1398 0x1: fcvt_wu_s({{
1399 uint32_t temp;
1400 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1401
1402 if (std::isnan(fs1)) {
1403 Rd = numeric_limits<uint64_t>::max();
1404 FFLAGS |= FloatInvalid;
1405 } else if (fs1 < 0.0) {
1406 Rd = 0;
1407 FFLAGS |= FloatInvalid;
1408 } else if (fs1 > numeric_limits<uint32_t>::max()) {
1409 Rd = numeric_limits<uint64_t>::max();
1410 FFLAGS |= FloatInvalid;
1411 } else {
1412 Rd = (uint32_t)fs1;
1413 }
1414 }}, FloatCvtOp);
1415 0x2: fcvt_l_s({{
1416 uint32_t temp;
1417 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1418
1419 if (std::isnan(fs1)) {
1420 Rd_sd = numeric_limits<int64_t>::max();
1421 FFLAGS |= FloatInvalid;
1422 } else if (fs1 > numeric_limits<int64_t>::max()) {
1423 Rd_sd = numeric_limits<int64_t>::max();
1424 FFLAGS |= FloatInvalid;
1425 } else if (fs1 < numeric_limits<int64_t>::min()) {
1426 Rd_sd = numeric_limits<int64_t>::min();
1427 FFLAGS |= FloatInvalid;
1428 } else {
1429 Rd_sd = (int64_t)fs1;
1430 }
1431 }}, FloatCvtOp);
1432 0x3: fcvt_lu_s({{
1433 uint32_t temp;
1434 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1435
1436 if (std::isnan(fs1)) {
1437 Rd = numeric_limits<uint64_t>::max();
1438 FFLAGS |= FloatInvalid;
1439 } else if (fs1 < 0.0) {
1440 Rd = 0;
1441 FFLAGS |= FloatInvalid;
1442 } else if (fs1 > numeric_limits<uint64_t>::max()) {
1443 Rd = numeric_limits<uint64_t>::max();
1444 FFLAGS |= FloatInvalid;
1445 } else {
1446 Rd = (uint64_t)fs1;
1447 }
1448 }}, FloatCvtOp);
1449 }
1450 0x61: decode CONV_SGN {
1451 0x0: fcvt_w_d({{
1452 if (std::isnan(Fs1)) {
1453 Rd_sd = numeric_limits<int32_t>::max();
1454 FFLAGS |= FloatInvalid;
1455 } else if (Fs1 > numeric_limits<int32_t>::max()) {
1456 Rd_sd = numeric_limits<int32_t>::max();
1457 FFLAGS |= FloatInvalid;
1458 } else if (Fs1 < numeric_limits<int32_t>::min()) {
1459 Rd_sd = numeric_limits<int32_t>::min();
1460 FFLAGS |= FloatInvalid;
1461 } else {
1462 Rd_sd = (int32_t)Fs1;
1463 }
1464 }}, FloatCvtOp);
1465 0x1: fcvt_wu_d({{
1466 if (std::isnan(Fs1)) {
1467 Rd = numeric_limits<uint64_t>::max();
1468 FFLAGS |= FloatInvalid;
1469 } else if (Fs1 < 0) {
1470 Rd = 0;
1471 FFLAGS |= FloatInvalid;
1472 } else if (Fs1 > numeric_limits<uint32_t>::max()) {
1473 Rd = numeric_limits<uint64_t>::max();
1474 FFLAGS |= FloatInvalid;
1475 } else {
1476 Rd = (uint32_t)Fs1;
1477 }
1478 }}, FloatCvtOp);
1479 0x2: fcvt_l_d({{
1480 if (std::isnan(Fs1)) {
1481 Rd_sd = numeric_limits<int64_t>::max();
1482 FFLAGS |= FloatInvalid;
1483 } else if (Fs1 > numeric_limits<int64_t>::max()) {
1484 Rd_sd = numeric_limits<int64_t>::max();
1485 FFLAGS |= FloatInvalid;
1486 } else if (Fs1 < numeric_limits<int64_t>::min()) {
1487 Rd_sd = numeric_limits<int64_t>::min();
1488 FFLAGS |= FloatInvalid;
1489 } else {
1490 Rd_sd = Fs1;
1491 }
1492 }}, FloatCvtOp);
1493 0x3: fcvt_lu_d({{
1494 if (std::isnan(Fs1)) {
1495 Rd = numeric_limits<uint64_t>::max();
1496 FFLAGS |= FloatInvalid;
1497 } else if (Fs1 < 0) {
1498 Rd = 0;
1499 FFLAGS |= FloatInvalid;
1500 } else if (Fs1 > numeric_limits<uint64_t>::max()) {
1501 Rd = numeric_limits<uint64_t>::max();
1502 FFLAGS |= FloatInvalid;
1503 } else {
1504 Rd = Fs1;
1505 }
1506 }}, FloatCvtOp);
1507 }
1508 0x68: decode CONV_SGN {
1509 0x0: fcvt_s_w({{
1510 float temp = (float)Rs1_sw;
1511 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1512 }}, FloatCvtOp);
1513 0x1: fcvt_s_wu({{
1514 float temp = (float)Rs1_uw;
1515 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1516 }}, FloatCvtOp);
1517 0x2: fcvt_s_l({{
1518 float temp = (float)Rs1_sd;
1519 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1520 }}, FloatCvtOp);
1521 0x3: fcvt_s_lu({{
1522 float temp = (float)Rs1;
1523 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1524 }}, FloatCvtOp);
1525 }
1526 0x69: decode CONV_SGN {
1527 0x0: fcvt_d_w({{
1528 Fd = (double)Rs1_sw;
1529 }}, FloatCvtOp);
1530 0x1: fcvt_d_wu({{
1531 Fd = (double)Rs1_uw;
1532 }}, FloatCvtOp);
1533 0x2: fcvt_d_l({{
1534 Fd = (double)Rs1_sd;
1535 }}, FloatCvtOp);
1536 0x3: fcvt_d_lu({{
1537 Fd = (double)Rs1;
1538 }}, FloatCvtOp);
1539 }
1540 0x70: decode ROUND_MODE {
1541 0x0: fmv_x_s({{
1542 Rd = (uint32_t)Fs1_bits;
1543 if ((Rd&0x80000000) != 0) {
1544 Rd |= (0xFFFFFFFFULL << 32);
1545 }
1546 }}, FloatCvtOp);
1547 0x1: fclass_s({{
1548 uint32_t temp;
1549 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1550 switch (fpclassify(fs1)) {
1551 case FP_INFINITE:
1552 if (signbit(fs1)) {
1553 Rd = 1 << 0;
1554 } else {
1555 Rd = 1 << 7;
1556 }
1557 break;
1558 case FP_NAN:
1559 if (issignalingnan(fs1)) {
1560 Rd = 1 << 8;
1561 } else {
1562 Rd = 1 << 9;
1563 }
1564 break;
1565 case FP_ZERO:
1566 if (signbit(fs1)) {
1567 Rd = 1 << 3;
1568 } else {
1569 Rd = 1 << 4;
1570 }
1571 break;
1572 case FP_SUBNORMAL:
1573 if (signbit(fs1)) {
1574 Rd = 1 << 2;
1575 } else {
1576 Rd = 1 << 5;
1577 }
1578 break;
1579 case FP_NORMAL:
1580 if (signbit(fs1)) {
1581 Rd = 1 << 1;
1582 } else {
1583 Rd = 1 << 6;
1584 }
1585 break;
1586 default:
1587 panic("Unknown classification for operand.");
1588 break;
1589 }
1590 }}, FloatMiscOp);
1591 }
1592 0x71: decode ROUND_MODE {
1593 0x0: fmv_x_d({{
1594 Rd = Fs1_bits;
1595 }}, FloatCvtOp);
1596 0x1: fclass_d({{
1597 switch (fpclassify(Fs1)) {
1598 case FP_INFINITE:
1599 if (signbit(Fs1)) {
1600 Rd = 1 << 0;
1601 } else {
1602 Rd = 1 << 7;
1603 }
1604 break;
1605 case FP_NAN:
1606 if (issignalingnan(Fs1)) {
1607 Rd = 1 << 8;
1608 } else {
1609 Rd = 1 << 9;
1610 }
1611 break;
1612 case FP_ZERO:
1613 if (signbit(Fs1)) {
1614 Rd = 1 << 3;
1615 } else {
1616 Rd = 1 << 4;
1617 }
1618 break;
1619 case FP_SUBNORMAL:
1620 if (signbit(Fs1)) {
1621 Rd = 1 << 2;
1622 } else {
1623 Rd = 1 << 5;
1624 }
1625 break;
1626 case FP_NORMAL:
1627 if (signbit(Fs1)) {
1628 Rd = 1 << 1;
1629 } else {
1630 Rd = 1 << 6;
1631 }
1632 break;
1633 default:
1634 panic("Unknown classification for operand.");
1635 break;
1636 }
1637 }}, FloatMiscOp);
1638 }
1639 0x78: fmv_s_x({{
1640 Fd_bits = (uint64_t)Rs1_uw;
1641 }}, FloatCvtOp);
1642 0x79: fmv_d_x({{
1643 Fd_bits = Rs1;
1644 }}, FloatCvtOp);
1645 }
1646 }
1647
1648 0x18: decode FUNCT3 {
1649 format BOp {
1650 0x0: beq({{
1651 if (Rs1 == Rs2) {
1652 NPC = PC + imm;
1653 } else {
1654 NPC = NPC;
1655 }
1656 }}, IsDirectControl, IsCondControl);
1657 0x1: bne({{
1658 if (Rs1 != Rs2) {
1659 NPC = PC + imm;
1660 } else {
1661 NPC = NPC;
1662 }
1663 }}, IsDirectControl, IsCondControl);
1664 0x4: blt({{
1665 if (Rs1_sd < Rs2_sd) {
1666 NPC = PC + imm;
1667 } else {
1668 NPC = NPC;
1669 }
1670 }}, IsDirectControl, IsCondControl);
1671 0x5: bge({{
1672 if (Rs1_sd >= Rs2_sd) {
1673 NPC = PC + imm;
1674 } else {
1675 NPC = NPC;
1676 }
1677 }}, IsDirectControl, IsCondControl);
1678 0x6: bltu({{
1679 if (Rs1 < Rs2) {
1680 NPC = PC + imm;
1681 } else {
1682 NPC = NPC;
1683 }
1684 }}, IsDirectControl, IsCondControl);
1685 0x7: bgeu({{
1686 if (Rs1 >= Rs2) {
1687 NPC = PC + imm;
1688 } else {
1689 NPC = NPC;
1690 }
1691 }}, IsDirectControl, IsCondControl);
1692 }
1693 }
1694
1695 0x19: decode FUNCT3 {
1696 0x0: Jump::jalr({{
1697 Rd = NPC;
1698 NPC = (imm + Rs1) & (~0x1);
1699 }}, IsIndirectControl, IsUncondControl, IsCall);
1700 }
1701
1702 0x1b: JOp::jal({{
1703 Rd = NPC;
1704 NPC = PC + imm;
1705 }}, IsDirectControl, IsUncondControl, IsCall);
1706
1707 0x1c: decode FUNCT3 {
1708 format SystemOp {
1709 0x0: decode FUNCT12 {
1710 0x0: ecall({{
1711 fault = make_shared<SyscallFault>(
1712 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1713 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1714 No_OpClass);
1715 0x1: ebreak({{
1716 fault = make_shared<BreakpointFault>(xc->pcState());
1717 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1718 0x2: uret({{
1719 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1720 status.uie = status.upie;
1721 status.upie = 1;
1722 xc->setMiscReg(MISCREG_STATUS, status);
1723 NPC = xc->readMiscReg(MISCREG_UEPC);
1724 }}, IsReturn);
1725 0x102: sret({{
1726 if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1727 fault = make_shared<IllegalInstFault>(
1728 "sret in user mode", machInst);
1729 NPC = NPC;
1730 } else {
1731 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1732 xc->setMiscReg(MISCREG_PRV, status.spp);
1733 status.sie = status.spie;
1734 status.spie = 1;
1735 status.spp = PRV_U;
1736 xc->setMiscReg(MISCREG_STATUS, status);
1737 NPC = xc->readMiscReg(MISCREG_SEPC);
1738 }
1739 }}, IsReturn);
1740 0x302: mret({{
1741 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1742 fault = make_shared<IllegalInstFault>(
1743 "mret at lower privilege", machInst);
1744 NPC = NPC;
1745 } else {
1746 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1747 xc->setMiscReg(MISCREG_PRV, status.mpp);
1748 status.mie = status.mpie;
1749 status.mpie = 1;
1750 status.mpp = PRV_U;
1751 xc->setMiscReg(MISCREG_STATUS, status);
1752 NPC = xc->readMiscReg(MISCREG_MEPC);
1753 }
1754 }}, IsReturn);
1755 }
1756 }
1757 format CSROp {
1758 0x1: csrrw({{
1759 Rd = data;
1760 data = Rs1;
1761 }}, IsNonSpeculative, No_OpClass);
1762 0x2: csrrs({{
1763 Rd = data;
1764 data |= Rs1;
1765 }}, IsNonSpeculative, No_OpClass);
1766 0x3: csrrc({{
1767 Rd = data;
1768 data &= ~Rs1;
1769 }}, IsNonSpeculative, No_OpClass);
1770 0x5: csrrwi({{
1771 Rd = data;
1772 data = uimm;
1773 }}, IsNonSpeculative, No_OpClass);
1774 0x6: csrrsi({{
1775 Rd = data;
1776 data |= uimm;
1777 }}, IsNonSpeculative, No_OpClass);
1778 0x7: csrrci({{
1779 Rd = data;
1780 data &= ~uimm;
1781 }}, IsNonSpeculative, No_OpClass);
1782 }
1783 }
1784 }
1785}
785 } else {
786 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
787 }
788 }}, IntDivOp);
789 0x20: sraw({{
790 Rd_sd = Rs1_sw >> Rs2<4:0>;
791 }});
792 }
793 0x6: remw({{
794 if (Rs2_sw == 0) {
795 Rd_sd = Rs1_sw;
796 } else if (Rs1_sw == numeric_limits<int32_t>::min()
797 && Rs2_sw == -1) {
798 Rd_sd = 0;
799 } else {
800 Rd_sd = Rs1_sw%Rs2_sw;
801 }
802 }}, IntDivOp);
803 0x7: remuw({{
804 if (Rs2_uw == 0) {
805 Rd_sd = (int32_t)Rs1_uw;
806 } else {
807 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
808 }
809 }}, IntDivOp);
810 }
811 }
812
813 format FPROp {
814 0x10: decode FUNCT2 {
815 0x0: fmadd_s({{
816 uint32_t temp;
817 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
818 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
819 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
820 float fd;
821
822 if (std::isnan(fs1) || std::isnan(fs2) ||
823 std::isnan(fs3)) {
824 if (issignalingnan(fs1) || issignalingnan(fs2)
825 || issignalingnan(fs3)) {
826 FFLAGS |= FloatInvalid;
827 }
828 fd = numeric_limits<float>::quiet_NaN();
829 } else if (std::isinf(fs1) || std::isinf(fs2) ||
830 std::isinf(fs3)) {
831 if (signbit(fs1) == signbit(fs2)
832 && !std::isinf(fs3)) {
833 fd = numeric_limits<float>::infinity();
834 } else if (signbit(fs1) != signbit(fs2)
835 && !std::isinf(fs3)) {
836 fd = -numeric_limits<float>::infinity();
837 } else { // Fs3_sf is infinity
838 fd = fs3;
839 }
840 } else {
841 fd = fs1*fs2 + fs3;
842 }
843 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
844 }}, FloatMultAccOp);
845 0x1: fmadd_d({{
846 if (std::isnan(Fs1) || std::isnan(Fs2) ||
847 std::isnan(Fs3)) {
848 if (issignalingnan(Fs1) || issignalingnan(Fs2)
849 || issignalingnan(Fs3)) {
850 FFLAGS |= FloatInvalid;
851 }
852 Fd = numeric_limits<double>::quiet_NaN();
853 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
854 std::isinf(Fs3)) {
855 if (signbit(Fs1) == signbit(Fs2)
856 && !std::isinf(Fs3)) {
857 Fd = numeric_limits<double>::infinity();
858 } else if (signbit(Fs1) != signbit(Fs2)
859 && !std::isinf(Fs3)) {
860 Fd = -numeric_limits<double>::infinity();
861 } else {
862 Fd = Fs3;
863 }
864 } else {
865 Fd = Fs1*Fs2 + Fs3;
866 }
867 }}, FloatMultAccOp);
868 }
869 0x11: decode FUNCT2 {
870 0x0: fmsub_s({{
871 uint32_t temp;
872 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
873 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
874 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
875 float fd;
876
877 if (std::isnan(fs1) || std::isnan(fs2) ||
878 std::isnan(fs3)) {
879 if (issignalingnan(fs1) || issignalingnan(fs2)
880 || issignalingnan(fs3)) {
881 FFLAGS |= FloatInvalid;
882 }
883 fd = numeric_limits<float>::quiet_NaN();
884 } else if (std::isinf(fs1) || std::isinf(fs2) ||
885 std::isinf(fs3)) {
886 if (signbit(fs1) == signbit(fs2)
887 && !std::isinf(fs3)) {
888 fd = numeric_limits<float>::infinity();
889 } else if (signbit(fs1) != signbit(fs2)
890 && !std::isinf(fs3)) {
891 fd = -numeric_limits<float>::infinity();
892 } else { // Fs3_sf is infinity
893 fd = -fs3;
894 }
895 } else {
896 fd = fs1*fs2 - fs3;
897 }
898 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
899 }}, FloatMultAccOp);
900 0x1: fmsub_d({{
901 if (std::isnan(Fs1) || std::isnan(Fs2) ||
902 std::isnan(Fs3)) {
903 if (issignalingnan(Fs1) || issignalingnan(Fs2)
904 || issignalingnan(Fs3)) {
905 FFLAGS |= FloatInvalid;
906 }
907 Fd = numeric_limits<double>::quiet_NaN();
908 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
909 std::isinf(Fs3)) {
910 if (signbit(Fs1) == signbit(Fs2)
911 && !std::isinf(Fs3)) {
912 Fd = numeric_limits<double>::infinity();
913 } else if (signbit(Fs1) != signbit(Fs2)
914 && !std::isinf(Fs3)) {
915 Fd = -numeric_limits<double>::infinity();
916 } else {
917 Fd = -Fs3;
918 }
919 } else {
920 Fd = Fs1*Fs2 - Fs3;
921 }
922 }}, FloatMultAccOp);
923 }
924 0x12: decode FUNCT2 {
925 0x0: fnmsub_s({{
926 uint32_t temp;
927 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
928 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
929 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
930 float fd;
931
932 if (std::isnan(fs1) || std::isnan(fs2) ||
933 std::isnan(fs3)) {
934 if (issignalingnan(fs1) || issignalingnan(fs2)
935 || issignalingnan(fs3)) {
936 FFLAGS |= FloatInvalid;
937 }
938 fd = numeric_limits<float>::quiet_NaN();
939 } else if (std::isinf(fs1) || std::isinf(fs2) ||
940 std::isinf(fs3)) {
941 if (signbit(fs1) == signbit(fs2)
942 && !std::isinf(fs3)) {
943 fd = -numeric_limits<float>::infinity();
944 } else if (signbit(fs1) != signbit(fs2)
945 && !std::isinf(fs3)) {
946 fd = numeric_limits<float>::infinity();
947 } else { // Fs3_sf is infinity
948 fd = fs3;
949 }
950 } else {
951 fd = -(fs1*fs2 - fs3);
952 }
953 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
954 }}, FloatMultAccOp);
955 0x1: fnmsub_d({{
956 if (std::isnan(Fs1) || std::isnan(Fs2) ||
957 std::isnan(Fs3)) {
958 if (issignalingnan(Fs1) || issignalingnan(Fs2)
959 || issignalingnan(Fs3)) {
960 FFLAGS |= FloatInvalid;
961 }
962 Fd = numeric_limits<double>::quiet_NaN();
963 } else if (std::isinf(Fs1) || std::isinf(Fs2)
964 || std::isinf(Fs3)) {
965 if (signbit(Fs1) == signbit(Fs2)
966 && !std::isinf(Fs3)) {
967 Fd = -numeric_limits<double>::infinity();
968 } else if (signbit(Fs1) != signbit(Fs2)
969 && !std::isinf(Fs3)) {
970 Fd = numeric_limits<double>::infinity();
971 } else {
972 Fd = Fs3;
973 }
974 } else {
975 Fd = -(Fs1*Fs2 - Fs3);
976 }
977 }}, FloatMultAccOp);
978 }
979 0x13: decode FUNCT2 {
980 0x0: fnmadd_s({{
981 uint32_t temp;
982 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
983 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
984 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
985 float fd;
986
987 if (std::isnan(fs1) || std::isnan(fs2) ||
988 std::isnan(fs3)) {
989 if (issignalingnan(fs1) || issignalingnan(fs2)
990 || issignalingnan(fs3)) {
991 FFLAGS |= FloatInvalid;
992 }
993 fd = numeric_limits<float>::quiet_NaN();
994 } else if (std::isinf(fs1) || std::isinf(fs2) ||
995 std::isinf(fs3)) {
996 if (signbit(fs1) == signbit(fs2)
997 && !std::isinf(fs3)) {
998 fd = -numeric_limits<float>::infinity();
999 } else if (signbit(fs1) != signbit(fs2)
1000 && !std::isinf(fs3)) {
1001 fd = numeric_limits<float>::infinity();
1002 } else { // Fs3_sf is infinity
1003 fd = -fs3;
1004 }
1005 } else {
1006 fd = -(fs1*fs2 + fs3);
1007 }
1008 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1009 }}, FloatMultAccOp);
1010 0x1: fnmadd_d({{
1011 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1012 std::isnan(Fs3)) {
1013 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1014 || issignalingnan(Fs3)) {
1015 FFLAGS |= FloatInvalid;
1016 }
1017 Fd = numeric_limits<double>::quiet_NaN();
1018 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1019 std::isinf(Fs3)) {
1020 if (signbit(Fs1) == signbit(Fs2)
1021 && !std::isinf(Fs3)) {
1022 Fd = -numeric_limits<double>::infinity();
1023 } else if (signbit(Fs1) != signbit(Fs2)
1024 && !std::isinf(Fs3)) {
1025 Fd = numeric_limits<double>::infinity();
1026 } else {
1027 Fd = -Fs3;
1028 }
1029 } else {
1030 Fd = -(Fs1*Fs2 + Fs3);
1031 }
1032 }}, FloatMultAccOp);
1033 }
1034 0x14: decode FUNCT7 {
1035 0x0: fadd_s({{
1036 uint32_t temp;
1037 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1038 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1039 float fd;
1040
1041 if (std::isnan(fs1) || std::isnan(fs2)) {
1042 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1043 FFLAGS |= FloatInvalid;
1044 }
1045 fd = numeric_limits<float>::quiet_NaN();
1046 } else {
1047 fd = fs1 + fs2;
1048 }
1049 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1050 }}, FloatAddOp);
1051 0x1: fadd_d({{
1052 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1053 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1054 FFLAGS |= FloatInvalid;
1055 }
1056 Fd = numeric_limits<double>::quiet_NaN();
1057 } else {
1058 Fd = Fs1 + Fs2;
1059 }
1060 }}, FloatAddOp);
1061 0x4: fsub_s({{
1062 uint32_t temp;
1063 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1064 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1065 float fd;
1066
1067 if (std::isnan(fs1) || std::isnan(fs2)) {
1068 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1069 FFLAGS |= FloatInvalid;
1070 }
1071 fd = numeric_limits<float>::quiet_NaN();
1072 } else {
1073 fd = fs1 - fs2;
1074 }
1075 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1076 }}, FloatAddOp);
1077 0x5: fsub_d({{
1078 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1079 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1080 FFLAGS |= FloatInvalid;
1081 }
1082 Fd = numeric_limits<double>::quiet_NaN();
1083 } else {
1084 Fd = Fs1 - Fs2;
1085 }
1086 }}, FloatAddOp);
1087 0x8: fmul_s({{
1088 uint32_t temp;
1089 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1090 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1091 float fd;
1092
1093 if (std::isnan(fs1) || std::isnan(fs2)) {
1094 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1095 FFLAGS |= FloatInvalid;
1096 }
1097 fd = numeric_limits<float>::quiet_NaN();
1098 } else {
1099 fd = fs1*fs2;
1100 }
1101 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1102 }}, FloatMultOp);
1103 0x9: fmul_d({{
1104 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1105 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1106 FFLAGS |= FloatInvalid;
1107 }
1108 Fd = numeric_limits<double>::quiet_NaN();
1109 } else {
1110 Fd = Fs1*Fs2;
1111 }
1112 }}, FloatMultOp);
1113 0xc: fdiv_s({{
1114 uint32_t temp;
1115 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1116 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1117 float fd;
1118
1119 if (std::isnan(fs1) || std::isnan(fs2)) {
1120 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1121 FFLAGS |= FloatInvalid;
1122 }
1123 fd = numeric_limits<float>::quiet_NaN();
1124 } else {
1125 fd = fs1/fs2;
1126 }
1127 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1128 }}, FloatDivOp);
1129 0xd: fdiv_d({{
1130 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1131 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1132 FFLAGS |= FloatInvalid;
1133 }
1134 Fd = numeric_limits<double>::quiet_NaN();
1135 } else {
1136 Fd = Fs1/Fs2;
1137 }
1138 }}, FloatDivOp);
1139 0x10: decode ROUND_MODE {
1140 0x0: fsgnj_s({{
1141 uint32_t temp;
1142 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1143 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1144 float fd;
1145
1146 if (issignalingnan(fs1)) {
1147 fd = numeric_limits<float>::signaling_NaN();
1148 feclearexcept(FE_INVALID);
1149 } else {
1150 fd = copysign(fs1, fs2);
1151 }
1152 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1153 }}, FloatMiscOp);
1154 0x1: fsgnjn_s({{
1155 uint32_t temp;
1156 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1157 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1158 float fd;
1159
1160 if (issignalingnan(fs1)) {
1161 fd = numeric_limits<float>::signaling_NaN();
1162 feclearexcept(FE_INVALID);
1163 } else {
1164 fd = copysign(fs1, -fs2);
1165 }
1166 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1167 }}, FloatMiscOp);
1168 0x2: fsgnjx_s({{
1169 uint32_t temp;
1170 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1171 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1172 float fd;
1173
1174 if (issignalingnan(fs1)) {
1175 fd = numeric_limits<float>::signaling_NaN();
1176 feclearexcept(FE_INVALID);
1177 } else {
1178 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1179 }
1180 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1181 }}, FloatMiscOp);
1182 }
1183 0x11: decode ROUND_MODE {
1184 0x0: fsgnj_d({{
1185 if (issignalingnan(Fs1)) {
1186 Fd = numeric_limits<double>::signaling_NaN();
1187 feclearexcept(FE_INVALID);
1188 } else {
1189 Fd = copysign(Fs1, Fs2);
1190 }
1191 }}, FloatMiscOp);
1192 0x1: fsgnjn_d({{
1193 if (issignalingnan(Fs1)) {
1194 Fd = numeric_limits<double>::signaling_NaN();
1195 feclearexcept(FE_INVALID);
1196 } else {
1197 Fd = copysign(Fs1, -Fs2);
1198 }
1199 }}, FloatMiscOp);
1200 0x2: fsgnjx_d({{
1201 if (issignalingnan(Fs1)) {
1202 Fd = numeric_limits<double>::signaling_NaN();
1203 feclearexcept(FE_INVALID);
1204 } else {
1205 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1206 }
1207 }}, FloatMiscOp);
1208 }
1209 0x14: decode ROUND_MODE {
1210 0x0: fmin_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(fs2)) {
1217 fd = fs1;
1218 FFLAGS |= FloatInvalid;
1219 } else if (issignalingnan(fs1)) {
1220 fd = fs2;
1221 FFLAGS |= FloatInvalid;
1222 } else {
1223 fd = fmin(fs1, fs2);
1224 }
1225 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1226 }}, FloatCmpOp);
1227 0x1: fmax_s({{
1228 uint32_t temp;
1229 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1230 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1231 float fd;
1232
1233 if (issignalingnan(fs2)) {
1234 fd = fs1;
1235 FFLAGS |= FloatInvalid;
1236 } else if (issignalingnan(fs1)) {
1237 fd = fs2;
1238 FFLAGS |= FloatInvalid;
1239 } else {
1240 fd = fmax(fs1, fs2);
1241 }
1242 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1243 }}, FloatCmpOp);
1244 }
1245 0x15: decode ROUND_MODE {
1246 0x0: fmin_d({{
1247 if (issignalingnan(Fs2)) {
1248 Fd = Fs1;
1249 FFLAGS |= FloatInvalid;
1250 } else if (issignalingnan(Fs1)) {
1251 Fd = Fs2;
1252 FFLAGS |= FloatInvalid;
1253 } else {
1254 Fd = fmin(Fs1, Fs2);
1255 }
1256 }}, FloatCmpOp);
1257 0x1: fmax_d({{
1258 if (issignalingnan(Fs2)) {
1259 Fd = Fs1;
1260 FFLAGS |= FloatInvalid;
1261 } else if (issignalingnan(Fs1)) {
1262 Fd = Fs2;
1263 FFLAGS |= FloatInvalid;
1264 } else {
1265 Fd = fmax(Fs1, Fs2);
1266 }
1267 }}, FloatCmpOp);
1268 }
1269 0x20: fcvt_s_d({{
1270 if (CONV_SGN != 1) {
1271 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1272 machInst);
1273 }
1274 float fd;
1275 if (issignalingnan(Fs1)) {
1276 fd = numeric_limits<float>::quiet_NaN();
1277 FFLAGS |= FloatInvalid;
1278 } else {
1279 fd = (float)Fs1;
1280 }
1281 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1282 }}, FloatCvtOp);
1283 0x21: fcvt_d_s({{
1284 if (CONV_SGN != 0) {
1285 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1286 machInst);
1287 }
1288 uint32_t temp;
1289 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1290
1291 if (issignalingnan(fs1)) {
1292 Fd = numeric_limits<double>::quiet_NaN();
1293 FFLAGS |= FloatInvalid;
1294 } else {
1295 Fd = (double)fs1;
1296 }
1297 }}, FloatCvtOp);
1298 0x2c: fsqrt_s({{
1299 if (RS2 != 0) {
1300 fault = make_shared<IllegalInstFault>("source reg x1",
1301 machInst);
1302 }
1303 uint32_t temp;
1304 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1305 float fd;
1306
1307 if (issignalingnan(Fs1_sf)) {
1308 FFLAGS |= FloatInvalid;
1309 }
1310 fd = sqrt(fs1);
1311 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1312 }}, FloatSqrtOp);
1313 0x2d: fsqrt_d({{
1314 if (RS2 != 0) {
1315 fault = make_shared<IllegalInstFault>("source reg x1",
1316 machInst);
1317 }
1318 Fd = sqrt(Fs1);
1319 }}, FloatSqrtOp);
1320 0x50: decode ROUND_MODE {
1321 0x0: fle_s({{
1322 uint32_t temp;
1323 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1324 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1325
1326 if (std::isnan(fs1) || std::isnan(fs2)) {
1327 FFLAGS |= FloatInvalid;
1328 Rd = 0;
1329 } else {
1330 Rd = fs1 <= fs2 ? 1 : 0;
1331 }
1332 }}, FloatCmpOp);
1333 0x1: flt_s({{
1334 uint32_t temp;
1335 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1336 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1337
1338 if (std::isnan(fs1) || std::isnan(fs2)) {
1339 FFLAGS |= FloatInvalid;
1340 Rd = 0;
1341 } else {
1342 Rd = fs1 < fs2 ? 1 : 0;
1343 }
1344 }}, FloatCmpOp);
1345 0x2: feq_s({{
1346 uint32_t temp;
1347 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1348 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1349
1350 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1351 FFLAGS |= FloatInvalid;
1352 }
1353 Rd = fs1 == fs2 ? 1 : 0;
1354 }}, FloatCmpOp);
1355 }
1356 0x51: decode ROUND_MODE {
1357 0x0: fle_d({{
1358 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1359 FFLAGS |= FloatInvalid;
1360 Rd = 0;
1361 } else {
1362 Rd = Fs1 <= Fs2 ? 1 : 0;
1363 }
1364 }}, FloatCmpOp);
1365 0x1: flt_d({{
1366 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1367 FFLAGS |= FloatInvalid;
1368 Rd = 0;
1369 } else {
1370 Rd = Fs1 < Fs2 ? 1 : 0;
1371 }
1372 }}, FloatCmpOp);
1373 0x2: feq_d({{
1374 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1375 FFLAGS |= FloatInvalid;
1376 }
1377 Rd = Fs1 == Fs2 ? 1 : 0;
1378 }}, FloatCmpOp);
1379 }
1380 0x60: decode CONV_SGN {
1381 0x0: fcvt_w_s({{
1382 uint32_t temp;
1383 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1384
1385 if (std::isnan(fs1)) {
1386 Rd_sd = numeric_limits<int32_t>::max();
1387 FFLAGS |= FloatInvalid;
1388 } else if (fs1 >= numeric_limits<int32_t>::max()) {
1389 Rd_sd = numeric_limits<int32_t>::max();
1390 FFLAGS |= FloatInvalid;
1391 } else if (fs1 <= numeric_limits<int32_t>::min()) {
1392 Rd_sd = numeric_limits<int32_t>::min();
1393 FFLAGS |= FloatInvalid;
1394 } else {
1395 Rd_sd = (int32_t)fs1;
1396 }
1397 }}, FloatCvtOp);
1398 0x1: fcvt_wu_s({{
1399 uint32_t temp;
1400 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1401
1402 if (std::isnan(fs1)) {
1403 Rd = numeric_limits<uint64_t>::max();
1404 FFLAGS |= FloatInvalid;
1405 } else if (fs1 < 0.0) {
1406 Rd = 0;
1407 FFLAGS |= FloatInvalid;
1408 } else if (fs1 > numeric_limits<uint32_t>::max()) {
1409 Rd = numeric_limits<uint64_t>::max();
1410 FFLAGS |= FloatInvalid;
1411 } else {
1412 Rd = (uint32_t)fs1;
1413 }
1414 }}, FloatCvtOp);
1415 0x2: fcvt_l_s({{
1416 uint32_t temp;
1417 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1418
1419 if (std::isnan(fs1)) {
1420 Rd_sd = numeric_limits<int64_t>::max();
1421 FFLAGS |= FloatInvalid;
1422 } else if (fs1 > numeric_limits<int64_t>::max()) {
1423 Rd_sd = numeric_limits<int64_t>::max();
1424 FFLAGS |= FloatInvalid;
1425 } else if (fs1 < numeric_limits<int64_t>::min()) {
1426 Rd_sd = numeric_limits<int64_t>::min();
1427 FFLAGS |= FloatInvalid;
1428 } else {
1429 Rd_sd = (int64_t)fs1;
1430 }
1431 }}, FloatCvtOp);
1432 0x3: fcvt_lu_s({{
1433 uint32_t temp;
1434 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1435
1436 if (std::isnan(fs1)) {
1437 Rd = numeric_limits<uint64_t>::max();
1438 FFLAGS |= FloatInvalid;
1439 } else if (fs1 < 0.0) {
1440 Rd = 0;
1441 FFLAGS |= FloatInvalid;
1442 } else if (fs1 > numeric_limits<uint64_t>::max()) {
1443 Rd = numeric_limits<uint64_t>::max();
1444 FFLAGS |= FloatInvalid;
1445 } else {
1446 Rd = (uint64_t)fs1;
1447 }
1448 }}, FloatCvtOp);
1449 }
1450 0x61: decode CONV_SGN {
1451 0x0: fcvt_w_d({{
1452 if (std::isnan(Fs1)) {
1453 Rd_sd = numeric_limits<int32_t>::max();
1454 FFLAGS |= FloatInvalid;
1455 } else if (Fs1 > numeric_limits<int32_t>::max()) {
1456 Rd_sd = numeric_limits<int32_t>::max();
1457 FFLAGS |= FloatInvalid;
1458 } else if (Fs1 < numeric_limits<int32_t>::min()) {
1459 Rd_sd = numeric_limits<int32_t>::min();
1460 FFLAGS |= FloatInvalid;
1461 } else {
1462 Rd_sd = (int32_t)Fs1;
1463 }
1464 }}, FloatCvtOp);
1465 0x1: fcvt_wu_d({{
1466 if (std::isnan(Fs1)) {
1467 Rd = numeric_limits<uint64_t>::max();
1468 FFLAGS |= FloatInvalid;
1469 } else if (Fs1 < 0) {
1470 Rd = 0;
1471 FFLAGS |= FloatInvalid;
1472 } else if (Fs1 > numeric_limits<uint32_t>::max()) {
1473 Rd = numeric_limits<uint64_t>::max();
1474 FFLAGS |= FloatInvalid;
1475 } else {
1476 Rd = (uint32_t)Fs1;
1477 }
1478 }}, FloatCvtOp);
1479 0x2: fcvt_l_d({{
1480 if (std::isnan(Fs1)) {
1481 Rd_sd = numeric_limits<int64_t>::max();
1482 FFLAGS |= FloatInvalid;
1483 } else if (Fs1 > numeric_limits<int64_t>::max()) {
1484 Rd_sd = numeric_limits<int64_t>::max();
1485 FFLAGS |= FloatInvalid;
1486 } else if (Fs1 < numeric_limits<int64_t>::min()) {
1487 Rd_sd = numeric_limits<int64_t>::min();
1488 FFLAGS |= FloatInvalid;
1489 } else {
1490 Rd_sd = Fs1;
1491 }
1492 }}, FloatCvtOp);
1493 0x3: fcvt_lu_d({{
1494 if (std::isnan(Fs1)) {
1495 Rd = numeric_limits<uint64_t>::max();
1496 FFLAGS |= FloatInvalid;
1497 } else if (Fs1 < 0) {
1498 Rd = 0;
1499 FFLAGS |= FloatInvalid;
1500 } else if (Fs1 > numeric_limits<uint64_t>::max()) {
1501 Rd = numeric_limits<uint64_t>::max();
1502 FFLAGS |= FloatInvalid;
1503 } else {
1504 Rd = Fs1;
1505 }
1506 }}, FloatCvtOp);
1507 }
1508 0x68: decode CONV_SGN {
1509 0x0: fcvt_s_w({{
1510 float temp = (float)Rs1_sw;
1511 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1512 }}, FloatCvtOp);
1513 0x1: fcvt_s_wu({{
1514 float temp = (float)Rs1_uw;
1515 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1516 }}, FloatCvtOp);
1517 0x2: fcvt_s_l({{
1518 float temp = (float)Rs1_sd;
1519 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1520 }}, FloatCvtOp);
1521 0x3: fcvt_s_lu({{
1522 float temp = (float)Rs1;
1523 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1524 }}, FloatCvtOp);
1525 }
1526 0x69: decode CONV_SGN {
1527 0x0: fcvt_d_w({{
1528 Fd = (double)Rs1_sw;
1529 }}, FloatCvtOp);
1530 0x1: fcvt_d_wu({{
1531 Fd = (double)Rs1_uw;
1532 }}, FloatCvtOp);
1533 0x2: fcvt_d_l({{
1534 Fd = (double)Rs1_sd;
1535 }}, FloatCvtOp);
1536 0x3: fcvt_d_lu({{
1537 Fd = (double)Rs1;
1538 }}, FloatCvtOp);
1539 }
1540 0x70: decode ROUND_MODE {
1541 0x0: fmv_x_s({{
1542 Rd = (uint32_t)Fs1_bits;
1543 if ((Rd&0x80000000) != 0) {
1544 Rd |= (0xFFFFFFFFULL << 32);
1545 }
1546 }}, FloatCvtOp);
1547 0x1: fclass_s({{
1548 uint32_t temp;
1549 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1550 switch (fpclassify(fs1)) {
1551 case FP_INFINITE:
1552 if (signbit(fs1)) {
1553 Rd = 1 << 0;
1554 } else {
1555 Rd = 1 << 7;
1556 }
1557 break;
1558 case FP_NAN:
1559 if (issignalingnan(fs1)) {
1560 Rd = 1 << 8;
1561 } else {
1562 Rd = 1 << 9;
1563 }
1564 break;
1565 case FP_ZERO:
1566 if (signbit(fs1)) {
1567 Rd = 1 << 3;
1568 } else {
1569 Rd = 1 << 4;
1570 }
1571 break;
1572 case FP_SUBNORMAL:
1573 if (signbit(fs1)) {
1574 Rd = 1 << 2;
1575 } else {
1576 Rd = 1 << 5;
1577 }
1578 break;
1579 case FP_NORMAL:
1580 if (signbit(fs1)) {
1581 Rd = 1 << 1;
1582 } else {
1583 Rd = 1 << 6;
1584 }
1585 break;
1586 default:
1587 panic("Unknown classification for operand.");
1588 break;
1589 }
1590 }}, FloatMiscOp);
1591 }
1592 0x71: decode ROUND_MODE {
1593 0x0: fmv_x_d({{
1594 Rd = Fs1_bits;
1595 }}, FloatCvtOp);
1596 0x1: fclass_d({{
1597 switch (fpclassify(Fs1)) {
1598 case FP_INFINITE:
1599 if (signbit(Fs1)) {
1600 Rd = 1 << 0;
1601 } else {
1602 Rd = 1 << 7;
1603 }
1604 break;
1605 case FP_NAN:
1606 if (issignalingnan(Fs1)) {
1607 Rd = 1 << 8;
1608 } else {
1609 Rd = 1 << 9;
1610 }
1611 break;
1612 case FP_ZERO:
1613 if (signbit(Fs1)) {
1614 Rd = 1 << 3;
1615 } else {
1616 Rd = 1 << 4;
1617 }
1618 break;
1619 case FP_SUBNORMAL:
1620 if (signbit(Fs1)) {
1621 Rd = 1 << 2;
1622 } else {
1623 Rd = 1 << 5;
1624 }
1625 break;
1626 case FP_NORMAL:
1627 if (signbit(Fs1)) {
1628 Rd = 1 << 1;
1629 } else {
1630 Rd = 1 << 6;
1631 }
1632 break;
1633 default:
1634 panic("Unknown classification for operand.");
1635 break;
1636 }
1637 }}, FloatMiscOp);
1638 }
1639 0x78: fmv_s_x({{
1640 Fd_bits = (uint64_t)Rs1_uw;
1641 }}, FloatCvtOp);
1642 0x79: fmv_d_x({{
1643 Fd_bits = Rs1;
1644 }}, FloatCvtOp);
1645 }
1646 }
1647
1648 0x18: decode FUNCT3 {
1649 format BOp {
1650 0x0: beq({{
1651 if (Rs1 == Rs2) {
1652 NPC = PC + imm;
1653 } else {
1654 NPC = NPC;
1655 }
1656 }}, IsDirectControl, IsCondControl);
1657 0x1: bne({{
1658 if (Rs1 != Rs2) {
1659 NPC = PC + imm;
1660 } else {
1661 NPC = NPC;
1662 }
1663 }}, IsDirectControl, IsCondControl);
1664 0x4: blt({{
1665 if (Rs1_sd < Rs2_sd) {
1666 NPC = PC + imm;
1667 } else {
1668 NPC = NPC;
1669 }
1670 }}, IsDirectControl, IsCondControl);
1671 0x5: bge({{
1672 if (Rs1_sd >= Rs2_sd) {
1673 NPC = PC + imm;
1674 } else {
1675 NPC = NPC;
1676 }
1677 }}, IsDirectControl, IsCondControl);
1678 0x6: bltu({{
1679 if (Rs1 < Rs2) {
1680 NPC = PC + imm;
1681 } else {
1682 NPC = NPC;
1683 }
1684 }}, IsDirectControl, IsCondControl);
1685 0x7: bgeu({{
1686 if (Rs1 >= Rs2) {
1687 NPC = PC + imm;
1688 } else {
1689 NPC = NPC;
1690 }
1691 }}, IsDirectControl, IsCondControl);
1692 }
1693 }
1694
1695 0x19: decode FUNCT3 {
1696 0x0: Jump::jalr({{
1697 Rd = NPC;
1698 NPC = (imm + Rs1) & (~0x1);
1699 }}, IsIndirectControl, IsUncondControl, IsCall);
1700 }
1701
1702 0x1b: JOp::jal({{
1703 Rd = NPC;
1704 NPC = PC + imm;
1705 }}, IsDirectControl, IsUncondControl, IsCall);
1706
1707 0x1c: decode FUNCT3 {
1708 format SystemOp {
1709 0x0: decode FUNCT12 {
1710 0x0: ecall({{
1711 fault = make_shared<SyscallFault>(
1712 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1713 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1714 No_OpClass);
1715 0x1: ebreak({{
1716 fault = make_shared<BreakpointFault>(xc->pcState());
1717 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1718 0x2: uret({{
1719 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1720 status.uie = status.upie;
1721 status.upie = 1;
1722 xc->setMiscReg(MISCREG_STATUS, status);
1723 NPC = xc->readMiscReg(MISCREG_UEPC);
1724 }}, IsReturn);
1725 0x102: sret({{
1726 if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1727 fault = make_shared<IllegalInstFault>(
1728 "sret in user mode", machInst);
1729 NPC = NPC;
1730 } else {
1731 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1732 xc->setMiscReg(MISCREG_PRV, status.spp);
1733 status.sie = status.spie;
1734 status.spie = 1;
1735 status.spp = PRV_U;
1736 xc->setMiscReg(MISCREG_STATUS, status);
1737 NPC = xc->readMiscReg(MISCREG_SEPC);
1738 }
1739 }}, IsReturn);
1740 0x302: mret({{
1741 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1742 fault = make_shared<IllegalInstFault>(
1743 "mret at lower privilege", machInst);
1744 NPC = NPC;
1745 } else {
1746 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1747 xc->setMiscReg(MISCREG_PRV, status.mpp);
1748 status.mie = status.mpie;
1749 status.mpie = 1;
1750 status.mpp = PRV_U;
1751 xc->setMiscReg(MISCREG_STATUS, status);
1752 NPC = xc->readMiscReg(MISCREG_MEPC);
1753 }
1754 }}, IsReturn);
1755 }
1756 }
1757 format CSROp {
1758 0x1: csrrw({{
1759 Rd = data;
1760 data = Rs1;
1761 }}, IsNonSpeculative, No_OpClass);
1762 0x2: csrrs({{
1763 Rd = data;
1764 data |= Rs1;
1765 }}, IsNonSpeculative, No_OpClass);
1766 0x3: csrrc({{
1767 Rd = data;
1768 data &= ~Rs1;
1769 }}, IsNonSpeculative, No_OpClass);
1770 0x5: csrrwi({{
1771 Rd = data;
1772 data = uimm;
1773 }}, IsNonSpeculative, No_OpClass);
1774 0x6: csrrsi({{
1775 Rd = data;
1776 data |= uimm;
1777 }}, IsNonSpeculative, No_OpClass);
1778 0x7: csrrci({{
1779 Rd = data;
1780 data &= ~uimm;
1781 }}, IsNonSpeculative, No_OpClass);
1782 }
1783 }
1784 }
1785}