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