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.
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.
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.
31 ////////////////////////////////////////////////////////////////////
33 // The RISC-V ISA decoder
36 decode QUADRANT default Unknown::unknown() {
38 0x0: CIAddi4spnOp::c_addi4spn({{
39 imm = CIMM8<1:1> << 2 |
45 fault = make_shared<IllegalInstFault>("zero instruction",
49 format CompressedLoad {
51 offset = CIMM3 << 3 | CIMM2 << 6;
58 offset = CIMM2<1:1> << 2 |
67 offset = CIMM3 << 3 | CIMM2 << 6;
74 format CompressedStore {
76 offset = CIMM3 << 3 | CIMM2 << 6;
83 offset = CIMM2<1:1> << 2 |
92 offset = CIMM3 << 3 | CIMM2 << 6;
100 0x1: decode COPCODE {
105 imm |= ~((uint64_t)0x1F);
107 if ((RC1 == 0) != (imm == 0)) {
109 fault = make_shared<IllegalInstFault>("source reg x0",
112 fault = make_shared<IllegalInstFault>("immediate = 0",
115 Rc1_sd = Rc1_sd + imm;
120 imm |= ~((uint64_t)0x1F);
123 fault = make_shared<IllegalInstFault>("source reg x0",
126 Rc1_sd = (int32_t)Rc1_sd + imm;
131 imm |= ~((uint64_t)0x1F);
134 fault = make_shared<IllegalInstFault>("source reg x0",
141 imm = CIMM5<4:4> << 4 |
146 imm |= ~((int64_t)0x1FF);
149 fault = make_shared<IllegalInstFault>("immediate = 0",
157 imm |= ~((uint64_t)0x1FFFF);
159 if (RC1 == 0 || RC1 == 2) {
160 fault = make_shared<IllegalInstFault>("source reg x0",
164 fault = make_shared<IllegalInstFault>("immediate = 0",
171 0x4: decode CFUNCT2HIGH {
174 imm = CIMM5 | (CIMM1 << 5);
177 fault = make_shared<IllegalInstFault>("immediate = 0",
183 imm = CIMM5 | (CIMM1 << 5);
186 fault = make_shared<IllegalInstFault>("immediate = 0",
189 Rp1_sd = Rp1_sd >> imm;
194 imm |= ~((uint64_t)0x1F);
199 format CompressedROp {
200 0x3: decode CFUNCT1 {
201 0x0: decode CFUNCT2LOW {
215 0x1: decode CFUNCT2LOW {
217 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
220 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
228 }}, IsDirectControl, IsUncondControl);
235 }}, IsDirectControl, IsCondControl);
241 }}, IsDirectControl, IsCondControl);
244 0x2: decode COPCODE {
246 imm = CIMM5 | (CIMM1 << 5);
249 fault = make_shared<IllegalInstFault>("immediate = 0",
253 fault = make_shared<IllegalInstFault>("source reg x0",
258 format CompressedLoad {
260 offset = CIMM5<4:3> << 3 |
269 offset = CIMM5<4:2> << 2 |
274 fault = make_shared<IllegalInstFault>("source reg x0",
282 offset = CIMM5<4:3> << 3 |
287 fault = make_shared<IllegalInstFault>("source reg x0",
295 0x4: decode CFUNCT1 {
299 fault = make_shared<IllegalInstFault>("source reg x0",
303 }}, IsIndirectControl, IsUncondControl, IsCall);
304 default: CROp::c_mv({{
306 fault = make_shared<IllegalInstFault>("source reg x0",
313 0x0: SystemOp::c_ebreak({{
315 fault = make_shared<IllegalInstFault>("source reg x1",
318 fault = make_shared<BreakpointFault>(xc->pcState());
319 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
320 default: decode RC2 {
323 fault = make_shared<IllegalInstFault>
329 }}, IsIndirectControl, IsUncondControl, IsCall);
330 default: CompressedROp::c_add({{
331 Rc1_sd = Rc1_sd + Rc2_sd;
336 format CompressedStore {
338 offset = CIMM6<5:3> << 3 |
346 offset = CIMM6<5:2> << 2 |
354 offset = CIMM6<5:3> << 3 |
364 0x00: decode FUNCT3 {
390 0x01: decode FUNCT3 {
393 Fd_bits = (uint64_t)Mem_uw;
394 }}, inst_flags=FloatMemReadOp);
397 }}, inst_flags=FloatMemReadOp);
401 0x03: decode FUNCT3 {
404 }}, uint64_t, IsMemBarrier, No_OpClass);
406 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
410 0x04: decode FUNCT3 {
413 Rd_sd = Rs1_sd + imm;
417 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
419 Rd = (Rs1_sd < imm) ? 1 : 0;
422 Rd = (Rs1 < imm) ? 1 : 0;
430 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
432 Rd_sd = Rs1_sd >> imm;
433 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
445 Rd = PC + (sext<20>(imm) << 12);
448 0x06: decode FUNCT3 {
451 Rd_sd = Rs1_sw + imm;
454 Rd_sd = Rs1_sw << imm;
455 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
458 Rd_sd = (int32_t)(Rs1_uw >> imm);
459 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
461 Rd_sd = Rs1_sw >> imm;
462 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
467 0x08: decode FUNCT3 {
484 0x09: decode FUNCT3 {
487 Mem_uw = (uint32_t)Fs2_bits;
488 }}, inst_flags=FloatMemWriteOp);
491 }}, inst_flags=FloatMemWriteOp);
495 0x0b: decode FUNCT3 {
496 0x2: decode AMOFUNCT {
497 0x2: LoadReserved::lr_w({{
500 0x3: StoreCond::sc_w({{
504 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
505 0x0: AtomicMemOp::amoadd_w({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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);
569 0x3: decode AMOFUNCT {
570 0x2: LoadReserved::lr_d({{
573 0x3: StoreCond::sc_d({{
577 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
578 0x0: AtomicMemOp::amoadd_d({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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);
643 0x0c: decode FUNCT3 {
647 Rd = Rs1_sd + Rs2_sd;
653 Rd = Rs1_sd - Rs2_sd;
658 Rd = Rs1 << Rs2<5:0>;
661 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
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;
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;
679 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
685 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
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;
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;
705 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
710 Rd = (Rs1 < Rs2) ? 1 : 0;
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;
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;
725 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
735 } else if (Rs1_sd == numeric_limits<int64_t>::min()
737 Rd_sd = numeric_limits<int64_t>::min();
739 Rd_sd = Rs1_sd/Rs2_sd;
745 Rd = Rs1 >> Rs2<5:0>;
749 Rd = numeric_limits<uint64_t>::max();
755 Rd_sd = Rs1_sd >> Rs2<5:0>;
765 } else if (Rs1_sd == numeric_limits<int64_t>::min()
789 Rd = (uint64_t)(sext<20>(imm) << 12);
792 0x0e: decode FUNCT3 {
796 Rd_sd = Rs1_sw + Rs2_sw;
799 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
802 Rd_sd = Rs1_sw - Rs2_sw;
806 Rd_sd = Rs1_sw << Rs2<4:0>;
811 } else if (Rs1_sw == numeric_limits<int32_t>::min()
813 Rd_sd = numeric_limits<int32_t>::min();
815 Rd_sd = Rs1_sw/Rs2_sw;
820 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
824 Rd_sd = numeric_limits<uint64_t>::max();
826 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
830 Rd_sd = Rs1_sw >> Rs2<4:0>;
836 } else if (Rs1_sw == numeric_limits<int32_t>::min()
840 Rd_sd = Rs1_sw%Rs2_sw;
845 Rd_sd = (int32_t)Rs1_uw;
847 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
854 0x10: decode FUNCT2 {
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);
862 if (std::isnan(fs1) || std::isnan(fs2) ||
864 if (issignalingnan(fs1) || issignalingnan(fs2)
865 || issignalingnan(fs3)) {
866 FFLAGS |= FloatInvalid;
868 fd = numeric_limits<float>::quiet_NaN();
869 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
883 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
886 if (std::isnan(Fs1) || std::isnan(Fs2) ||
888 if (issignalingnan(Fs1) || issignalingnan(Fs2)
889 || issignalingnan(Fs3)) {
890 FFLAGS |= FloatInvalid;
892 Fd = numeric_limits<double>::quiet_NaN();
893 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
909 0x11: decode FUNCT2 {
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);
917 if (std::isnan(fs1) || std::isnan(fs2) ||
919 if (issignalingnan(fs1) || issignalingnan(fs2)
920 || issignalingnan(fs3)) {
921 FFLAGS |= FloatInvalid;
923 fd = numeric_limits<float>::quiet_NaN();
924 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
938 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
941 if (std::isnan(Fs1) || std::isnan(Fs2) ||
943 if (issignalingnan(Fs1) || issignalingnan(Fs2)
944 || issignalingnan(Fs3)) {
945 FFLAGS |= FloatInvalid;
947 Fd = numeric_limits<double>::quiet_NaN();
948 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
964 0x12: decode FUNCT2 {
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);
972 if (std::isnan(fs1) || std::isnan(fs2) ||
974 if (issignalingnan(fs1) || issignalingnan(fs2)
975 || issignalingnan(fs3)) {
976 FFLAGS |= FloatInvalid;
978 fd = numeric_limits<float>::quiet_NaN();
979 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
991 fd = -(fs1*fs2 - fs3);
993 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
996 if (std::isnan(Fs1) || std::isnan(Fs2) ||
998 if (issignalingnan(Fs1) || issignalingnan(Fs2)
999 || issignalingnan(Fs3)) {
1000 FFLAGS |= FloatInvalid;
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();
1015 Fd = -(Fs1*Fs2 - Fs3);
1017 }}, FloatMultAccOp);
1019 0x13: decode FUNCT2 {
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);
1027 if (std::isnan(fs1) || std::isnan(fs2) ||
1029 if (issignalingnan(fs1) || issignalingnan(fs2)
1030 || issignalingnan(fs3)) {
1031 FFLAGS |= FloatInvalid;
1033 fd = numeric_limits<float>::quiet_NaN();
1034 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
1046 fd = -(fs1*fs2 + fs3);
1048 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1049 }}, FloatMultAccOp);
1051 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1053 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1054 || issignalingnan(Fs3)) {
1055 FFLAGS |= FloatInvalid;
1057 Fd = numeric_limits<double>::quiet_NaN();
1058 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
1070 Fd = -(Fs1*Fs2 + Fs3);
1072 }}, FloatMultAccOp);
1074 0x14: decode FUNCT7 {
1077 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1078 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1081 if (std::isnan(fs1) || std::isnan(fs2)) {
1082 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1083 FFLAGS |= FloatInvalid;
1085 fd = numeric_limits<float>::quiet_NaN();
1089 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1092 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1093 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1094 FFLAGS |= FloatInvalid;
1096 Fd = numeric_limits<double>::quiet_NaN();
1103 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1104 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1107 if (std::isnan(fs1) || std::isnan(fs2)) {
1108 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1109 FFLAGS |= FloatInvalid;
1111 fd = numeric_limits<float>::quiet_NaN();
1115 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1118 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1119 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1120 FFLAGS |= FloatInvalid;
1122 Fd = numeric_limits<double>::quiet_NaN();
1129 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1130 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1133 if (std::isnan(fs1) || std::isnan(fs2)) {
1134 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1135 FFLAGS |= FloatInvalid;
1137 fd = numeric_limits<float>::quiet_NaN();
1141 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1144 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1145 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1146 FFLAGS |= FloatInvalid;
1148 Fd = numeric_limits<double>::quiet_NaN();
1155 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1156 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1159 if (std::isnan(fs1) || std::isnan(fs2)) {
1160 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1161 FFLAGS |= FloatInvalid;
1163 fd = numeric_limits<float>::quiet_NaN();
1167 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1170 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1171 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1172 FFLAGS |= FloatInvalid;
1174 Fd = numeric_limits<double>::quiet_NaN();
1179 0x10: decode ROUND_MODE {
1182 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1183 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1186 if (issignalingnan(fs1)) {
1187 fd = numeric_limits<float>::signaling_NaN();
1188 feclearexcept(FE_INVALID);
1190 fd = copysign(fs1, fs2);
1192 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1196 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1197 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1200 if (issignalingnan(fs1)) {
1201 fd = numeric_limits<float>::signaling_NaN();
1202 feclearexcept(FE_INVALID);
1204 fd = copysign(fs1, -fs2);
1206 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1210 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1211 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1214 if (issignalingnan(fs1)) {
1215 fd = numeric_limits<float>::signaling_NaN();
1216 feclearexcept(FE_INVALID);
1218 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1220 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1223 0x11: decode ROUND_MODE {
1225 if (issignalingnan(Fs1)) {
1226 Fd = numeric_limits<double>::signaling_NaN();
1227 feclearexcept(FE_INVALID);
1229 Fd = copysign(Fs1, Fs2);
1233 if (issignalingnan(Fs1)) {
1234 Fd = numeric_limits<double>::signaling_NaN();
1235 feclearexcept(FE_INVALID);
1237 Fd = copysign(Fs1, -Fs2);
1241 if (issignalingnan(Fs1)) {
1242 Fd = numeric_limits<double>::signaling_NaN();
1243 feclearexcept(FE_INVALID);
1245 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1249 0x14: decode ROUND_MODE {
1252 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1253 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1256 if (issignalingnan(fs2)) {
1258 FFLAGS |= FloatInvalid;
1259 } else if (issignalingnan(fs1)) {
1261 FFLAGS |= FloatInvalid;
1263 fd = fmin(fs1, fs2);
1265 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1269 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1270 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1273 if (issignalingnan(fs2)) {
1275 FFLAGS |= FloatInvalid;
1276 } else if (issignalingnan(fs1)) {
1278 FFLAGS |= FloatInvalid;
1280 fd = fmax(fs1, fs2);
1282 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1285 0x15: decode ROUND_MODE {
1287 if (issignalingnan(Fs2)) {
1289 FFLAGS |= FloatInvalid;
1290 } else if (issignalingnan(Fs1)) {
1292 FFLAGS |= FloatInvalid;
1294 Fd = fmin(Fs1, Fs2);
1298 if (issignalingnan(Fs2)) {
1300 FFLAGS |= FloatInvalid;
1301 } else if (issignalingnan(Fs1)) {
1303 FFLAGS |= FloatInvalid;
1305 Fd = fmax(Fs1, Fs2);
1310 if (CONV_SGN != 1) {
1311 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1315 if (issignalingnan(Fs1)) {
1316 fd = numeric_limits<float>::quiet_NaN();
1317 FFLAGS |= FloatInvalid;
1321 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1324 if (CONV_SGN != 0) {
1325 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1329 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1331 if (issignalingnan(fs1)) {
1332 Fd = numeric_limits<double>::quiet_NaN();
1333 FFLAGS |= FloatInvalid;
1340 fault = make_shared<IllegalInstFault>("source reg x1",
1344 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1347 if (issignalingnan(Fs1_sf)) {
1348 FFLAGS |= FloatInvalid;
1351 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1355 fault = make_shared<IllegalInstFault>("source reg x1",
1360 0x50: decode ROUND_MODE {
1363 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1364 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1366 if (std::isnan(fs1) || std::isnan(fs2)) {
1367 FFLAGS |= FloatInvalid;
1370 Rd = fs1 <= fs2 ? 1 : 0;
1375 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1376 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1378 if (std::isnan(fs1) || std::isnan(fs2)) {
1379 FFLAGS |= FloatInvalid;
1382 Rd = fs1 < fs2 ? 1 : 0;
1387 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1388 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1390 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1391 FFLAGS |= FloatInvalid;
1393 Rd = fs1 == fs2 ? 1 : 0;
1396 0x51: decode ROUND_MODE {
1398 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1399 FFLAGS |= FloatInvalid;
1402 Rd = Fs1 <= Fs2 ? 1 : 0;
1406 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1407 FFLAGS |= FloatInvalid;
1410 Rd = Fs1 < Fs2 ? 1 : 0;
1414 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1415 FFLAGS |= FloatInvalid;
1417 Rd = Fs1 == Fs2 ? 1 : 0;
1420 0x60: decode CONV_SGN {
1423 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1425 if (std::isnan(fs1)) {
1426 Rd_sd = numeric_limits<int32_t>::max();
1427 FFLAGS |= FloatInvalid;
1429 float(numeric_limits<int32_t>::max())) {
1430 Rd_sd = numeric_limits<int32_t>::max();
1431 FFLAGS |= FloatInvalid;
1433 float(numeric_limits<int32_t>::min())) {
1434 Rd_sd = numeric_limits<int32_t>::min();
1435 FFLAGS |= FloatInvalid;
1437 Rd_sd = (int32_t)fs1;
1442 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1444 if (std::isnan(fs1)) {
1445 Rd = numeric_limits<uint64_t>::max();
1446 FFLAGS |= FloatInvalid;
1447 } else if (fs1 < 0.0) {
1449 FFLAGS |= FloatInvalid;
1451 float(numeric_limits<uint32_t>::max())) {
1452 Rd = numeric_limits<uint64_t>::max();
1453 FFLAGS |= FloatInvalid;
1460 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1462 if (std::isnan(fs1)) {
1463 Rd_sd = numeric_limits<int64_t>::max();
1464 FFLAGS |= FloatInvalid;
1466 float(numeric_limits<int64_t>::max())) {
1467 Rd_sd = numeric_limits<int64_t>::max();
1468 FFLAGS |= FloatInvalid;
1470 float(numeric_limits<int64_t>::min())) {
1471 Rd_sd = numeric_limits<int64_t>::min();
1472 FFLAGS |= FloatInvalid;
1474 Rd_sd = (int64_t)fs1;
1479 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1481 if (std::isnan(fs1)) {
1482 Rd = numeric_limits<uint64_t>::max();
1483 FFLAGS |= FloatInvalid;
1484 } else if (fs1 < 0.0) {
1486 FFLAGS |= FloatInvalid;
1488 float(numeric_limits<uint64_t>::max())) {
1489 Rd = numeric_limits<uint64_t>::max();
1490 FFLAGS |= FloatInvalid;
1496 0x61: decode CONV_SGN {
1498 if (std::isnan(Fs1)) {
1499 Rd_sd = numeric_limits<int32_t>::max();
1500 FFLAGS |= FloatInvalid;
1502 float(numeric_limits<int32_t>::max())) {
1503 Rd_sd = numeric_limits<int32_t>::max();
1504 FFLAGS |= FloatInvalid;
1506 float(numeric_limits<int32_t>::min())) {
1507 Rd_sd = numeric_limits<int32_t>::min();
1508 FFLAGS |= FloatInvalid;
1510 Rd_sd = (int32_t)Fs1;
1514 if (std::isnan(Fs1)) {
1515 Rd = numeric_limits<uint64_t>::max();
1516 FFLAGS |= FloatInvalid;
1517 } else if (Fs1 < 0) {
1519 FFLAGS |= FloatInvalid;
1521 float(numeric_limits<uint32_t>::max())) {
1522 Rd = numeric_limits<uint64_t>::max();
1523 FFLAGS |= FloatInvalid;
1529 if (std::isnan(Fs1)) {
1530 Rd_sd = numeric_limits<int64_t>::max();
1531 FFLAGS |= FloatInvalid;
1533 float(numeric_limits<int64_t>::max())) {
1534 Rd_sd = numeric_limits<int64_t>::max();
1535 FFLAGS |= FloatInvalid;
1537 float(numeric_limits<int64_t>::min())) {
1538 Rd_sd = numeric_limits<int64_t>::min();
1539 FFLAGS |= FloatInvalid;
1545 if (std::isnan(Fs1)) {
1546 Rd = numeric_limits<uint64_t>::max();
1547 FFLAGS |= FloatInvalid;
1548 } else if (Fs1 < 0) {
1550 FFLAGS |= FloatInvalid;
1552 float(numeric_limits<uint64_t>::max())) {
1553 Rd = numeric_limits<uint64_t>::max();
1554 FFLAGS |= FloatInvalid;
1560 0x68: decode CONV_SGN {
1562 float temp = (float)Rs1_sw;
1563 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1566 float temp = (float)Rs1_uw;
1567 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1570 float temp = (float)Rs1_sd;
1571 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1574 float temp = (float)Rs1;
1575 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1578 0x69: decode CONV_SGN {
1580 Fd = (double)Rs1_sw;
1583 Fd = (double)Rs1_uw;
1586 Fd = (double)Rs1_sd;
1592 0x70: decode ROUND_MODE {
1594 Rd = (uint32_t)Fs1_bits;
1595 if ((Rd&0x80000000) != 0) {
1596 Rd |= (0xFFFFFFFFULL << 32);
1601 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1602 switch (fpclassify(fs1)) {
1611 if (issignalingnan(fs1)) {
1639 panic("Unknown classification for operand.");
1644 0x71: decode ROUND_MODE {
1649 switch (fpclassify(Fs1)) {
1658 if (issignalingnan(Fs1)) {
1686 panic("Unknown classification for operand.");
1692 Fd_bits = (uint64_t)Rs1_uw;
1700 0x18: decode FUNCT3 {
1708 }}, IsDirectControl, IsCondControl);
1715 }}, IsDirectControl, IsCondControl);
1717 if (Rs1_sd < Rs2_sd) {
1722 }}, IsDirectControl, IsCondControl);
1724 if (Rs1_sd >= Rs2_sd) {
1729 }}, IsDirectControl, IsCondControl);
1736 }}, IsDirectControl, IsCondControl);
1743 }}, IsDirectControl, IsCondControl);
1747 0x19: decode FUNCT3 {
1750 NPC = (imm + Rs1) & (~0x1);
1751 }}, IsIndirectControl, IsUncondControl, IsCall);
1757 }}, IsDirectControl, IsUncondControl, IsCall);
1759 0x1c: decode FUNCT3 {
1761 0x0: decode FUNCT7 {
1764 fault = make_shared<SyscallFault>(
1765 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1766 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1769 fault = make_shared<BreakpointFault>(
1771 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1773 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1774 status.uie = status.upie;
1776 xc->setMiscReg(MISCREG_STATUS, status);
1777 NPC = xc->readMiscReg(MISCREG_UEPC);
1782 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1783 auto pm = (PrivilegeMode)xc->readMiscReg(
1786 (pm == PRV_S && status.tsr == 1)) {
1787 fault = make_shared<IllegalInstFault>(
1788 "sret in user mode or TSR enabled",
1792 xc->setMiscReg(MISCREG_PRV, status.spp);
1793 status.sie = status.spie;
1796 xc->setMiscReg(MISCREG_STATUS, status);
1797 NPC = xc->readMiscReg(MISCREG_SEPC);
1801 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1802 auto pm = (PrivilegeMode)xc->readMiscReg(
1805 (pm == PRV_S && status.tw == 1)) {
1806 fault = make_shared<IllegalInstFault>(
1807 "wfi in user mode or TW enabled",
1810 // don't do anything for now
1814 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1815 auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
1816 if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
1817 fault = make_shared<IllegalInstFault>(
1818 "sfence in user mode or TVM enabled",
1821 xc->tcBase()->getITBPtr()->demapPage(Rs1, Rs2);
1822 xc->tcBase()->getDTBPtr()->demapPage(Rs1, Rs2);
1823 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
1825 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1826 fault = make_shared<IllegalInstFault>(
1827 "mret at lower privilege", machInst);
1830 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1831 xc->setMiscReg(MISCREG_PRV, status.mpp);
1832 status.mie = status.mpie;
1835 xc->setMiscReg(MISCREG_STATUS, status);
1836 NPC = xc->readMiscReg(MISCREG_MEPC);
1845 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1849 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1853 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1857 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1861 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1865 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);