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