3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2017 The University of Virginia
5 // All rights reserved.
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.
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.
30 ////////////////////////////////////////////////////////////////////
32 // The RISC-V ISA decoder
35 decode QUADRANT default Unknown::unknown() {
37 0x0: CIAddi4spnOp::c_addi4spn({{
38 imm = CIMM8<1:1> << 2 |
44 fault = make_shared<IllegalInstFault>("zero instruction",
48 format CompressedLoad {
50 offset = CIMM3 << 3 | CIMM2 << 6;
57 offset = CIMM2<1:1> << 2 |
66 offset = CIMM3 << 3 | CIMM2 << 6;
73 format CompressedStore {
75 offset = CIMM3 << 3 | CIMM2 << 6;
82 offset = CIMM2<1:1> << 2 |
91 offset = CIMM3 << 3 | CIMM2 << 6;
104 imm |= ~((uint64_t)0x1F);
106 if ((RC1 == 0) != (imm == 0)) {
108 fault = make_shared<IllegalInstFault>("source reg x0",
111 fault = make_shared<IllegalInstFault>("immediate = 0",
114 Rc1_sd = Rc1_sd + imm;
119 imm |= ~((uint64_t)0x1F);
122 fault = make_shared<IllegalInstFault>("source reg x0",
125 Rc1_sd = (int32_t)Rc1_sd + imm;
130 imm |= ~((uint64_t)0x1F);
133 fault = make_shared<IllegalInstFault>("source reg x0",
140 imm = CIMM5<4:4> << 4 |
145 imm |= ~((int64_t)0x1FF);
148 fault = make_shared<IllegalInstFault>("immediate = 0",
156 imm |= ~((uint64_t)0x1FFFF);
158 if (RC1 == 0 || RC1 == 2) {
159 fault = make_shared<IllegalInstFault>("source reg x0",
163 fault = make_shared<IllegalInstFault>("immediate = 0",
170 0x4: decode CFUNCT2HIGH {
173 imm = CIMM5 | (CIMM1 << 5);
176 fault = make_shared<IllegalInstFault>("immediate = 0",
182 imm = CIMM5 | (CIMM1 << 5);
185 fault = make_shared<IllegalInstFault>("immediate = 0",
188 Rp1_sd = Rp1_sd >> imm;
193 imm |= ~((uint64_t)0x1F);
198 format CompressedROp {
199 0x3: decode CFUNCT1 {
200 0x0: decode CFUNCT2LOW {
214 0x1: decode CFUNCT2LOW {
216 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
219 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
227 }}, IsDirectControl, IsUncondControl);
234 }}, IsDirectControl, IsCondControl);
240 }}, IsDirectControl, IsCondControl);
243 0x2: decode COPCODE {
245 imm = CIMM5 | (CIMM1 << 5);
248 fault = make_shared<IllegalInstFault>("immediate = 0",
252 fault = make_shared<IllegalInstFault>("source reg x0",
257 format CompressedLoad {
259 offset = CIMM5<4:3> << 3 |
268 offset = CIMM5<4:2> << 2 |
273 fault = make_shared<IllegalInstFault>("source reg x0",
281 offset = CIMM5<4:3> << 3 |
286 fault = make_shared<IllegalInstFault>("source reg x0",
294 0x4: decode CFUNCT1 {
298 fault = make_shared<IllegalInstFault>("source reg x0",
302 }}, IsIndirectControl, IsUncondControl, IsCall);
303 default: CROp::c_mv({{
305 fault = make_shared<IllegalInstFault>("source reg x0",
312 0x0: SystemOp::c_ebreak({{
314 fault = make_shared<IllegalInstFault>("source reg x1",
317 fault = make_shared<BreakpointFault>(xc->pcState());
318 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
319 default: decode RC2 {
322 fault = make_shared<IllegalInstFault>
328 }}, IsIndirectControl, IsUncondControl, IsCall);
329 default: CompressedROp::c_add({{
330 Rc1_sd = Rc1_sd + Rc2_sd;
335 format CompressedStore {
337 offset = CIMM6<5:3> << 3 |
345 offset = CIMM6<5:2> << 2 |
353 offset = CIMM6<5:3> << 3 |
363 0x00: decode FUNCT3 {
389 0x01: decode FUNCT3 {
392 Fd_bits = (uint64_t)Mem_uw;
393 }}, inst_flags=FloatMemReadOp);
396 }}, inst_flags=FloatMemReadOp);
400 0x03: decode FUNCT3 {
403 }}, uint64_t, IsMemBarrier, No_OpClass);
405 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
409 0x04: decode FUNCT3 {
412 Rd_sd = Rs1_sd + imm;
416 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
418 Rd = (Rs1_sd < imm) ? 1 : 0;
421 Rd = (Rs1 < imm) ? 1 : 0;
429 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
431 Rd_sd = Rs1_sd >> imm;
432 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
444 Rd = PC + (sext<20>(imm) << 12);
447 0x06: decode FUNCT3 {
450 Rd_sd = Rs1_sw + imm;
453 Rd_sd = Rs1_sw << imm;
454 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
457 Rd_sd = (int32_t)(Rs1_uw >> imm);
458 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
460 Rd_sd = Rs1_sw >> imm;
461 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
466 0x08: decode FUNCT3 {
483 0x09: decode FUNCT3 {
486 Mem_uw = (uint32_t)Fs2_bits;
487 }}, inst_flags=FloatMemWriteOp);
490 }}, inst_flags=FloatMemWriteOp);
494 0x0b: decode FUNCT3 {
495 0x2: decode AMOFUNCT {
496 0x2: LoadReserved::lr_w({{
499 0x3: StoreCond::sc_w({{
503 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
504 0x0: AtomicMemOp::amoadd_w({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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);
568 0x3: decode AMOFUNCT {
569 0x2: LoadReserved::lr_d({{
572 0x3: StoreCond::sc_d({{
576 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
577 0x0: AtomicMemOp::amoadd_d({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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({{
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);
642 0x0c: decode FUNCT3 {
646 Rd = Rs1_sd + Rs2_sd;
652 Rd = Rs1_sd - Rs2_sd;
657 Rd = Rs1 << Rs2<5:0>;
660 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
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;
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;
678 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
684 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
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;
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;
704 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
709 Rd = (Rs1 < Rs2) ? 1 : 0;
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;
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;
724 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
734 } else if (Rs1_sd == numeric_limits<int64_t>::min()
736 Rd_sd = numeric_limits<int64_t>::min();
738 Rd_sd = Rs1_sd/Rs2_sd;
744 Rd = Rs1 >> Rs2<5:0>;
748 Rd = numeric_limits<uint64_t>::max();
754 Rd_sd = Rs1_sd >> Rs2<5:0>;
764 } else if (Rs1_sd == numeric_limits<int64_t>::min()
788 Rd = (uint64_t)(sext<20>(imm) << 12);
791 0x0e: decode FUNCT3 {
795 Rd_sd = Rs1_sw + Rs2_sw;
798 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
801 Rd_sd = Rs1_sw - Rs2_sw;
805 Rd_sd = Rs1_sw << Rs2<4:0>;
810 } else if (Rs1_sw == numeric_limits<int32_t>::min()
812 Rd_sd = numeric_limits<int32_t>::min();
814 Rd_sd = Rs1_sw/Rs2_sw;
819 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
823 Rd_sd = numeric_limits<uint64_t>::max();
825 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
829 Rd_sd = Rs1_sw >> Rs2<4:0>;
835 } else if (Rs1_sw == numeric_limits<int32_t>::min()
839 Rd_sd = Rs1_sw%Rs2_sw;
844 Rd_sd = (int32_t)Rs1_uw;
846 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
853 0x10: decode FUNCT2 {
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);
861 if (std::isnan(fs1) || std::isnan(fs2) ||
863 if (issignalingnan(fs1) || issignalingnan(fs2)
864 || issignalingnan(fs3)) {
865 FFLAGS |= FloatInvalid;
867 fd = numeric_limits<float>::quiet_NaN();
868 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
882 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
885 if (std::isnan(Fs1) || std::isnan(Fs2) ||
887 if (issignalingnan(Fs1) || issignalingnan(Fs2)
888 || issignalingnan(Fs3)) {
889 FFLAGS |= FloatInvalid;
891 Fd = numeric_limits<double>::quiet_NaN();
892 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
908 0x11: decode FUNCT2 {
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);
916 if (std::isnan(fs1) || std::isnan(fs2) ||
918 if (issignalingnan(fs1) || issignalingnan(fs2)
919 || issignalingnan(fs3)) {
920 FFLAGS |= FloatInvalid;
922 fd = numeric_limits<float>::quiet_NaN();
923 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
937 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
940 if (std::isnan(Fs1) || std::isnan(Fs2) ||
942 if (issignalingnan(Fs1) || issignalingnan(Fs2)
943 || issignalingnan(Fs3)) {
944 FFLAGS |= FloatInvalid;
946 Fd = numeric_limits<double>::quiet_NaN();
947 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
963 0x12: decode FUNCT2 {
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);
971 if (std::isnan(fs1) || std::isnan(fs2) ||
973 if (issignalingnan(fs1) || issignalingnan(fs2)
974 || issignalingnan(fs3)) {
975 FFLAGS |= FloatInvalid;
977 fd = numeric_limits<float>::quiet_NaN();
978 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
990 fd = -(fs1*fs2 - fs3);
992 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
995 if (std::isnan(Fs1) || std::isnan(Fs2) ||
997 if (issignalingnan(Fs1) || issignalingnan(Fs2)
998 || issignalingnan(Fs3)) {
999 FFLAGS |= FloatInvalid;
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();
1014 Fd = -(Fs1*Fs2 - Fs3);
1016 }}, FloatMultAccOp);
1018 0x13: decode FUNCT2 {
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);
1026 if (std::isnan(fs1) || std::isnan(fs2) ||
1028 if (issignalingnan(fs1) || issignalingnan(fs2)
1029 || issignalingnan(fs3)) {
1030 FFLAGS |= FloatInvalid;
1032 fd = numeric_limits<float>::quiet_NaN();
1033 } else if (std::isinf(fs1) || std::isinf(fs2) ||
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
1045 fd = -(fs1*fs2 + fs3);
1047 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1048 }}, FloatMultAccOp);
1050 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1052 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1053 || issignalingnan(Fs3)) {
1054 FFLAGS |= FloatInvalid;
1056 Fd = numeric_limits<double>::quiet_NaN();
1057 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
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();
1069 Fd = -(Fs1*Fs2 + Fs3);
1071 }}, FloatMultAccOp);
1073 0x14: decode FUNCT7 {
1076 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1077 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1080 if (std::isnan(fs1) || std::isnan(fs2)) {
1081 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1082 FFLAGS |= FloatInvalid;
1084 fd = numeric_limits<float>::quiet_NaN();
1088 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1091 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1092 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1093 FFLAGS |= FloatInvalid;
1095 Fd = numeric_limits<double>::quiet_NaN();
1102 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1103 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1106 if (std::isnan(fs1) || std::isnan(fs2)) {
1107 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1108 FFLAGS |= FloatInvalid;
1110 fd = numeric_limits<float>::quiet_NaN();
1114 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1117 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1118 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1119 FFLAGS |= FloatInvalid;
1121 Fd = numeric_limits<double>::quiet_NaN();
1128 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1129 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1132 if (std::isnan(fs1) || std::isnan(fs2)) {
1133 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1134 FFLAGS |= FloatInvalid;
1136 fd = numeric_limits<float>::quiet_NaN();
1140 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1143 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1144 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1145 FFLAGS |= FloatInvalid;
1147 Fd = numeric_limits<double>::quiet_NaN();
1154 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1155 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1158 if (std::isnan(fs1) || std::isnan(fs2)) {
1159 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1160 FFLAGS |= FloatInvalid;
1162 fd = numeric_limits<float>::quiet_NaN();
1166 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1169 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1170 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1171 FFLAGS |= FloatInvalid;
1173 Fd = numeric_limits<double>::quiet_NaN();
1178 0x10: decode ROUND_MODE {
1181 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1182 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1185 if (issignalingnan(fs1)) {
1186 fd = numeric_limits<float>::signaling_NaN();
1187 feclearexcept(FE_INVALID);
1189 fd = copysign(fs1, fs2);
1191 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1195 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1196 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1199 if (issignalingnan(fs1)) {
1200 fd = numeric_limits<float>::signaling_NaN();
1201 feclearexcept(FE_INVALID);
1203 fd = copysign(fs1, -fs2);
1205 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1209 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1210 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1213 if (issignalingnan(fs1)) {
1214 fd = numeric_limits<float>::signaling_NaN();
1215 feclearexcept(FE_INVALID);
1217 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1219 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1222 0x11: decode ROUND_MODE {
1224 if (issignalingnan(Fs1)) {
1225 Fd = numeric_limits<double>::signaling_NaN();
1226 feclearexcept(FE_INVALID);
1228 Fd = copysign(Fs1, Fs2);
1232 if (issignalingnan(Fs1)) {
1233 Fd = numeric_limits<double>::signaling_NaN();
1234 feclearexcept(FE_INVALID);
1236 Fd = copysign(Fs1, -Fs2);
1240 if (issignalingnan(Fs1)) {
1241 Fd = numeric_limits<double>::signaling_NaN();
1242 feclearexcept(FE_INVALID);
1244 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1248 0x14: decode ROUND_MODE {
1251 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1252 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1255 if (issignalingnan(fs2)) {
1257 FFLAGS |= FloatInvalid;
1258 } else if (issignalingnan(fs1)) {
1260 FFLAGS |= FloatInvalid;
1262 fd = fmin(fs1, fs2);
1264 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1268 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1269 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1272 if (issignalingnan(fs2)) {
1274 FFLAGS |= FloatInvalid;
1275 } else if (issignalingnan(fs1)) {
1277 FFLAGS |= FloatInvalid;
1279 fd = fmax(fs1, fs2);
1281 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1284 0x15: decode ROUND_MODE {
1286 if (issignalingnan(Fs2)) {
1288 FFLAGS |= FloatInvalid;
1289 } else if (issignalingnan(Fs1)) {
1291 FFLAGS |= FloatInvalid;
1293 Fd = fmin(Fs1, Fs2);
1297 if (issignalingnan(Fs2)) {
1299 FFLAGS |= FloatInvalid;
1300 } else if (issignalingnan(Fs1)) {
1302 FFLAGS |= FloatInvalid;
1304 Fd = fmax(Fs1, Fs2);
1309 if (CONV_SGN != 1) {
1310 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1314 if (issignalingnan(Fs1)) {
1315 fd = numeric_limits<float>::quiet_NaN();
1316 FFLAGS |= FloatInvalid;
1320 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1323 if (CONV_SGN != 0) {
1324 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1328 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1330 if (issignalingnan(fs1)) {
1331 Fd = numeric_limits<double>::quiet_NaN();
1332 FFLAGS |= FloatInvalid;
1339 fault = make_shared<IllegalInstFault>("source reg x1",
1343 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1346 if (issignalingnan(Fs1_sf)) {
1347 FFLAGS |= FloatInvalid;
1350 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1354 fault = make_shared<IllegalInstFault>("source reg x1",
1359 0x50: decode ROUND_MODE {
1362 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1363 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1365 if (std::isnan(fs1) || std::isnan(fs2)) {
1366 FFLAGS |= FloatInvalid;
1369 Rd = fs1 <= fs2 ? 1 : 0;
1374 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1375 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1377 if (std::isnan(fs1) || std::isnan(fs2)) {
1378 FFLAGS |= FloatInvalid;
1381 Rd = fs1 < fs2 ? 1 : 0;
1386 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1387 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1389 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1390 FFLAGS |= FloatInvalid;
1392 Rd = fs1 == fs2 ? 1 : 0;
1395 0x51: decode ROUND_MODE {
1397 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1398 FFLAGS |= FloatInvalid;
1401 Rd = Fs1 <= Fs2 ? 1 : 0;
1405 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1406 FFLAGS |= FloatInvalid;
1409 Rd = Fs1 < Fs2 ? 1 : 0;
1413 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1414 FFLAGS |= FloatInvalid;
1416 Rd = Fs1 == Fs2 ? 1 : 0;
1419 0x60: decode CONV_SGN {
1422 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1424 if (std::isnan(fs1)) {
1425 Rd_sd = numeric_limits<int32_t>::max();
1426 FFLAGS |= FloatInvalid;
1428 float(numeric_limits<int32_t>::max())) {
1429 Rd_sd = numeric_limits<int32_t>::max();
1430 FFLAGS |= FloatInvalid;
1432 float(numeric_limits<int32_t>::min())) {
1433 Rd_sd = numeric_limits<int32_t>::min();
1434 FFLAGS |= FloatInvalid;
1436 Rd_sd = (int32_t)fs1;
1441 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1443 if (std::isnan(fs1)) {
1444 Rd = numeric_limits<uint64_t>::max();
1445 FFLAGS |= FloatInvalid;
1446 } else if (fs1 < 0.0) {
1448 FFLAGS |= FloatInvalid;
1450 float(numeric_limits<uint32_t>::max())) {
1451 Rd = numeric_limits<uint64_t>::max();
1452 FFLAGS |= FloatInvalid;
1459 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1461 if (std::isnan(fs1)) {
1462 Rd_sd = numeric_limits<int64_t>::max();
1463 FFLAGS |= FloatInvalid;
1465 float(numeric_limits<int64_t>::max())) {
1466 Rd_sd = numeric_limits<int64_t>::max();
1467 FFLAGS |= FloatInvalid;
1469 float(numeric_limits<int64_t>::min())) {
1470 Rd_sd = numeric_limits<int64_t>::min();
1471 FFLAGS |= FloatInvalid;
1473 Rd_sd = (int64_t)fs1;
1478 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1480 if (std::isnan(fs1)) {
1481 Rd = numeric_limits<uint64_t>::max();
1482 FFLAGS |= FloatInvalid;
1483 } else if (fs1 < 0.0) {
1485 FFLAGS |= FloatInvalid;
1487 float(numeric_limits<uint64_t>::max())) {
1488 Rd = numeric_limits<uint64_t>::max();
1489 FFLAGS |= FloatInvalid;
1495 0x61: decode CONV_SGN {
1497 if (std::isnan(Fs1)) {
1498 Rd_sd = numeric_limits<int32_t>::max();
1499 FFLAGS |= FloatInvalid;
1501 float(numeric_limits<int32_t>::max())) {
1502 Rd_sd = numeric_limits<int32_t>::max();
1503 FFLAGS |= FloatInvalid;
1505 float(numeric_limits<int32_t>::min())) {
1506 Rd_sd = numeric_limits<int32_t>::min();
1507 FFLAGS |= FloatInvalid;
1509 Rd_sd = (int32_t)Fs1;
1513 if (std::isnan(Fs1)) {
1514 Rd = numeric_limits<uint64_t>::max();
1515 FFLAGS |= FloatInvalid;
1516 } else if (Fs1 < 0) {
1518 FFLAGS |= FloatInvalid;
1520 float(numeric_limits<uint32_t>::max())) {
1521 Rd = numeric_limits<uint64_t>::max();
1522 FFLAGS |= FloatInvalid;
1528 if (std::isnan(Fs1)) {
1529 Rd_sd = numeric_limits<int64_t>::max();
1530 FFLAGS |= FloatInvalid;
1532 float(numeric_limits<int64_t>::max())) {
1533 Rd_sd = numeric_limits<int64_t>::max();
1534 FFLAGS |= FloatInvalid;
1536 float(numeric_limits<int64_t>::min())) {
1537 Rd_sd = numeric_limits<int64_t>::min();
1538 FFLAGS |= FloatInvalid;
1544 if (std::isnan(Fs1)) {
1545 Rd = numeric_limits<uint64_t>::max();
1546 FFLAGS |= FloatInvalid;
1547 } else if (Fs1 < 0) {
1549 FFLAGS |= FloatInvalid;
1551 float(numeric_limits<uint64_t>::max())) {
1552 Rd = numeric_limits<uint64_t>::max();
1553 FFLAGS |= FloatInvalid;
1559 0x68: decode CONV_SGN {
1561 float temp = (float)Rs1_sw;
1562 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1565 float temp = (float)Rs1_uw;
1566 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1569 float temp = (float)Rs1_sd;
1570 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1573 float temp = (float)Rs1;
1574 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1577 0x69: decode CONV_SGN {
1579 Fd = (double)Rs1_sw;
1582 Fd = (double)Rs1_uw;
1585 Fd = (double)Rs1_sd;
1591 0x70: decode ROUND_MODE {
1593 Rd = (uint32_t)Fs1_bits;
1594 if ((Rd&0x80000000) != 0) {
1595 Rd |= (0xFFFFFFFFULL << 32);
1600 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1601 switch (fpclassify(fs1)) {
1610 if (issignalingnan(fs1)) {
1638 panic("Unknown classification for operand.");
1643 0x71: decode ROUND_MODE {
1648 switch (fpclassify(Fs1)) {
1657 if (issignalingnan(Fs1)) {
1685 panic("Unknown classification for operand.");
1691 Fd_bits = (uint64_t)Rs1_uw;
1699 0x18: decode FUNCT3 {
1707 }}, IsDirectControl, IsCondControl);
1714 }}, IsDirectControl, IsCondControl);
1716 if (Rs1_sd < Rs2_sd) {
1721 }}, IsDirectControl, IsCondControl);
1723 if (Rs1_sd >= Rs2_sd) {
1728 }}, IsDirectControl, IsCondControl);
1735 }}, IsDirectControl, IsCondControl);
1742 }}, IsDirectControl, IsCondControl);
1746 0x19: decode FUNCT3 {
1749 NPC = (imm + Rs1) & (~0x1);
1750 }}, IsIndirectControl, IsUncondControl, IsCall);
1756 }}, IsDirectControl, IsUncondControl, IsCall);
1758 0x1c: decode FUNCT3 {
1760 0x0: decode FUNCT12 {
1762 fault = make_shared<SyscallFault>(
1763 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1764 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1767 fault = make_shared<BreakpointFault>(xc->pcState());
1768 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1770 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1771 status.uie = status.upie;
1773 xc->setMiscReg(MISCREG_STATUS, status);
1774 NPC = xc->readMiscReg(MISCREG_UEPC);
1777 if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1778 fault = make_shared<IllegalInstFault>(
1779 "sret in user mode", machInst);
1782 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1783 xc->setMiscReg(MISCREG_PRV, status.spp);
1784 status.sie = status.spie;
1787 xc->setMiscReg(MISCREG_STATUS, status);
1788 NPC = xc->readMiscReg(MISCREG_SEPC);
1792 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1793 fault = make_shared<IllegalInstFault>(
1794 "mret at lower privilege", machInst);
1797 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1798 xc->setMiscReg(MISCREG_PRV, status.mpp);
1799 status.mie = status.mpie;
1802 xc->setMiscReg(MISCREG_STATUS, status);
1803 NPC = xc->readMiscReg(MISCREG_MEPC);
1812 }}, IsNonSpeculative, No_OpClass);
1816 }}, IsNonSpeculative, No_OpClass);
1820 }}, IsNonSpeculative, No_OpClass);
1824 }}, IsNonSpeculative, No_OpClass);
1828 }}, IsNonSpeculative, No_OpClass);
1832 }}, IsNonSpeculative, No_OpClass);