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