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 // Authors: Alec Roelke
32 ////////////////////////////////////////////////////////////////////
34 // The RISC-V ISA decoder
37 decode QUADRANT default Unknown::unknown() {
39 0x0: CIAddi4spnOp::c_addi4spn({{
40 imm = CIMM8<1:1> << 2 |
46 fault = make_shared<IllegalInstFault>("zero instruction",
50 format CompressedLoad {
52 offset = CIMM3 << 3 | CIMM2 << 6;
59 offset = CIMM2<1:1> << 2 |
68 offset = CIMM3 << 3 | CIMM2 << 6;
75 format CompressedStore {
77 offset = CIMM3 << 3 | CIMM2 << 6;
84 offset = CIMM2<1:1> << 2 |
93 offset = CIMM3 << 3 | CIMM2 << 6;
101 0x1: decode COPCODE {
106 imm |= ~((uint64_t)0x1F);
108 if ((RC1 == 0) != (imm == 0)) {
110 fault = make_shared<IllegalInstFault>("source reg x0",
113 fault = make_shared<IllegalInstFault>("immediate = 0",
116 Rc1_sd = Rc1_sd + imm;
121 imm |= ~((uint64_t)0x1F);
124 fault = make_shared<IllegalInstFault>("source reg x0",
127 Rc1_sd = (int32_t)Rc1_sd + imm;
132 imm |= ~((uint64_t)0x1F);
135 fault = make_shared<IllegalInstFault>("source reg x0",
142 imm = CIMM5<4:4> << 4 |
147 imm |= ~((int64_t)0x1FF);
150 fault = make_shared<IllegalInstFault>("immediate = 0",
158 imm |= ~((uint64_t)0x1FFFF);
160 if (RC1 == 0 || RC1 == 2) {
161 fault = make_shared<IllegalInstFault>("source reg x0",
165 fault = make_shared<IllegalInstFault>("immediate = 0",
172 0x4: decode CFUNCT2HIGH {
175 imm = CIMM5 | (CIMM1 << 5);
178 fault = make_shared<IllegalInstFault>("immediate = 0",
184 imm = CIMM5 | (CIMM1 << 5);
187 fault = make_shared<IllegalInstFault>("immediate = 0",
190 Rp1_sd = Rp1_sd >> imm;
195 imm |= ~((uint64_t)0x1F);
200 format CompressedROp {
201 0x3: decode CFUNCT1 {
202 0x0: decode CFUNCT2LOW {
216 0x1: decode CFUNCT2LOW {
218 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
221 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
229 }}, IsDirectControl, IsUncondControl);
236 }}, IsDirectControl, IsCondControl);
242 }}, IsDirectControl, IsCondControl);
245 0x2: decode COPCODE {
247 imm = CIMM5 | (CIMM1 << 5);
250 fault = make_shared<IllegalInstFault>("immediate = 0",
254 fault = make_shared<IllegalInstFault>("source reg x0",
259 format CompressedLoad {
261 offset = CIMM5<4:3> << 3 |
270 offset = CIMM5<4:2> << 2 |
275 fault = make_shared<IllegalInstFault>("source reg x0",
283 offset = CIMM5<4:3> << 3 |
288 fault = make_shared<IllegalInstFault>("source reg x0",
296 0x4: decode CFUNCT1 {
300 fault = make_shared<IllegalInstFault>("source reg x0",
304 }}, IsIndirectControl, IsUncondControl, IsCall);
305 default: CROp::c_mv({{
307 fault = make_shared<IllegalInstFault>("source reg x0",
314 0x0: SystemOp::c_ebreak({{
316 fault = make_shared<IllegalInstFault>("source reg x1",
319 fault = make_shared<BreakpointFault>(xc->pcState());
320 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
321 default: decode RC2 {
324 fault = make_shared<IllegalInstFault>
330 }}, IsIndirectControl, IsUncondControl, IsCall);
331 default: CompressedROp::c_add({{
332 Rc1_sd = Rc1_sd + Rc2_sd;
337 format CompressedStore {
339 offset = CIMM6<5:3> << 3 |
347 offset = CIMM6<5:2> << 2 |
355 offset = CIMM6<5:3> << 3 |
365 0x00: decode FUNCT3 {
391 0x01: decode FUNCT3 {
394 Fd_bits = (uint64_t)Mem_uw;
395 }}, inst_flags=FloatMemReadOp);
398 }}, inst_flags=FloatMemReadOp);
402 0x03: decode FUNCT3 {
405 }}, uint64_t, IsMemBarrier, No_OpClass);
407 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
411 0x04: decode FUNCT3 {
414 Rd_sd = Rs1_sd + imm;
418 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
420 Rd = (Rs1_sd < imm) ? 1 : 0;
423 Rd = (Rs1 < imm) ? 1 : 0;
431 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
433 Rd_sd = Rs1_sd >> imm;
434 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
446 Rd = PC + (sext<20>(imm) << 12);
449 0x06: decode FUNCT3 {
452 Rd_sd = Rs1_sw + imm;
455 Rd_sd = Rs1_sw << imm;
456 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
459 Rd_sd = (int32_t)(Rs1_uw >> imm);
460 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
462 Rd_sd = Rs1_sw >> imm;
463 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
468 0x08: decode FUNCT3 {
485 0x09: decode FUNCT3 {
488 Mem_uw = (uint32_t)Fs2_bits;
489 }}, inst_flags=FloatMemWriteOp);
492 }}, inst_flags=FloatMemWriteOp);
496 0x0b: decode FUNCT3 {
497 0x2: decode AMOFUNCT {
498 0x2: LoadReserved::lr_w({{
501 0x3: StoreCond::sc_w({{
505 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
506 0x0: AtomicMemOp::amoadd_w({{
509 TypedAtomicOpFunctor<int32_t> *amo_op =
510 new AtomicGenericOp<int32_t>(Rs2_sw,
511 [](int32_t* b, int32_t a){ *b += a; });
512 }}, mem_flags=ATOMIC_RETURN_OP);
513 0x1: AtomicMemOp::amoswap_w({{
516 TypedAtomicOpFunctor<uint32_t> *amo_op =
517 new AtomicGenericOp<uint32_t>(Rs2_uw,
518 [](uint32_t* b, uint32_t a){ *b = a; });
519 }}, mem_flags=ATOMIC_RETURN_OP);
520 0x4: AtomicMemOp::amoxor_w({{
523 TypedAtomicOpFunctor<uint32_t> *amo_op =
524 new AtomicGenericOp<uint32_t>(Rs2_uw,
525 [](uint32_t* b, uint32_t a){ *b ^= a; });
526 }}, mem_flags=ATOMIC_RETURN_OP);
527 0x8: AtomicMemOp::amoor_w({{
530 TypedAtomicOpFunctor<uint32_t> *amo_op =
531 new AtomicGenericOp<uint32_t>(Rs2_uw,
532 [](uint32_t* b, uint32_t a){ *b |= a; });
533 }}, mem_flags=ATOMIC_RETURN_OP);
534 0xc: AtomicMemOp::amoand_w({{
537 TypedAtomicOpFunctor<uint32_t> *amo_op =
538 new AtomicGenericOp<uint32_t>(Rs2_uw,
539 [](uint32_t* b, uint32_t a){ *b &= a; });
540 }}, mem_flags=ATOMIC_RETURN_OP);
541 0x10: AtomicMemOp::amomin_w({{
544 TypedAtomicOpFunctor<int32_t> *amo_op =
545 new AtomicGenericOp<int32_t>(Rs2_sw,
546 [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
547 }}, mem_flags=ATOMIC_RETURN_OP);
548 0x14: AtomicMemOp::amomax_w({{
551 TypedAtomicOpFunctor<int32_t> *amo_op =
552 new AtomicGenericOp<int32_t>(Rs2_sw,
553 [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
554 }}, mem_flags=ATOMIC_RETURN_OP);
555 0x18: AtomicMemOp::amominu_w({{
558 TypedAtomicOpFunctor<uint32_t> *amo_op =
559 new AtomicGenericOp<uint32_t>(Rs2_uw,
560 [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
561 }}, mem_flags=ATOMIC_RETURN_OP);
562 0x1c: AtomicMemOp::amomaxu_w({{
565 TypedAtomicOpFunctor<uint32_t> *amo_op =
566 new AtomicGenericOp<uint32_t>(Rs2_uw,
567 [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
568 }}, mem_flags=ATOMIC_RETURN_OP);
570 0x3: decode AMOFUNCT {
571 0x2: LoadReserved::lr_d({{
574 0x3: StoreCond::sc_d({{
578 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
579 0x0: AtomicMemOp::amoadd_d({{
582 TypedAtomicOpFunctor<int64_t> *amo_op =
583 new AtomicGenericOp<int64_t>(Rs2_sd,
584 [](int64_t* b, int64_t a){ *b += a; });
585 }}, mem_flags=ATOMIC_RETURN_OP);
586 0x1: AtomicMemOp::amoswap_d({{
589 TypedAtomicOpFunctor<uint64_t> *amo_op =
590 new AtomicGenericOp<uint64_t>(Rs2_ud,
591 [](uint64_t* b, uint64_t a){ *b = a; });
592 }}, mem_flags=ATOMIC_RETURN_OP);
593 0x4: AtomicMemOp::amoxor_d({{
596 TypedAtomicOpFunctor<uint64_t> *amo_op =
597 new AtomicGenericOp<uint64_t>(Rs2_ud,
598 [](uint64_t* b, uint64_t a){ *b ^= a; });
599 }}, mem_flags=ATOMIC_RETURN_OP);
600 0x8: AtomicMemOp::amoor_d({{
603 TypedAtomicOpFunctor<uint64_t> *amo_op =
604 new AtomicGenericOp<uint64_t>(Rs2_ud,
605 [](uint64_t* b, uint64_t a){ *b |= a; });
606 }}, mem_flags=ATOMIC_RETURN_OP);
607 0xc: AtomicMemOp::amoand_d({{
610 TypedAtomicOpFunctor<uint64_t> *amo_op =
611 new AtomicGenericOp<uint64_t>(Rs2_ud,
612 [](uint64_t* b, uint64_t a){ *b &= a; });
613 }}, mem_flags=ATOMIC_RETURN_OP);
614 0x10: AtomicMemOp::amomin_d({{
617 TypedAtomicOpFunctor<int64_t> *amo_op =
618 new AtomicGenericOp<int64_t>(Rs2_sd,
619 [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
620 }}, mem_flags=ATOMIC_RETURN_OP);
621 0x14: AtomicMemOp::amomax_d({{
624 TypedAtomicOpFunctor<int64_t> *amo_op =
625 new AtomicGenericOp<int64_t>(Rs2_sd,
626 [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
627 }}, mem_flags=ATOMIC_RETURN_OP);
628 0x18: AtomicMemOp::amominu_d({{
631 TypedAtomicOpFunctor<uint64_t> *amo_op =
632 new AtomicGenericOp<uint64_t>(Rs2_ud,
633 [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
634 }}, mem_flags=ATOMIC_RETURN_OP);
635 0x1c: AtomicMemOp::amomaxu_d({{
638 TypedAtomicOpFunctor<uint64_t> *amo_op =
639 new AtomicGenericOp<uint64_t>(Rs2_ud,
640 [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
641 }}, mem_flags=ATOMIC_RETURN_OP);
644 0x0c: decode FUNCT3 {
648 Rd = Rs1_sd + Rs2_sd;
654 Rd = Rs1_sd - Rs2_sd;
659 Rd = Rs1 << Rs2<5:0>;
662 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
664 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
665 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
666 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
667 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
669 uint64_t hi = Rs1_hi*Rs2_hi;
670 uint64_t mid1 = Rs1_hi*Rs2_lo;
671 uint64_t mid2 = Rs1_lo*Rs2_hi;
672 uint64_t lo = Rs2_lo*Rs1_lo;
673 uint64_t carry = ((uint64_t)(uint32_t)mid1
674 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
680 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
686 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
689 bool negate = Rs1_sd < 0;
690 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
691 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
692 uint64_t Rs2_lo = (uint32_t)Rs2;
693 uint64_t Rs2_hi = Rs2 >> 32;
695 uint64_t hi = Rs1_hi*Rs2_hi;
696 uint64_t mid1 = Rs1_hi*Rs2_lo;
697 uint64_t mid2 = Rs1_lo*Rs2_hi;
698 uint64_t lo = Rs1_lo*Rs2_lo;
699 uint64_t carry = ((uint64_t)(uint32_t)mid1
700 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
706 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
711 Rd = (Rs1 < Rs2) ? 1 : 0;
714 uint64_t Rs1_lo = (uint32_t)Rs1;
715 uint64_t Rs1_hi = Rs1 >> 32;
716 uint64_t Rs2_lo = (uint32_t)Rs2;
717 uint64_t Rs2_hi = Rs2 >> 32;
719 uint64_t hi = Rs1_hi*Rs2_hi;
720 uint64_t mid1 = Rs1_hi*Rs2_lo;
721 uint64_t mid2 = Rs1_lo*Rs2_hi;
722 uint64_t lo = Rs1_lo*Rs2_lo;
723 uint64_t carry = ((uint64_t)(uint32_t)mid1
724 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
726 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
736 } else if (Rs1_sd == numeric_limits<int64_t>::min()
738 Rd_sd = numeric_limits<int64_t>::min();
740 Rd_sd = Rs1_sd/Rs2_sd;
746 Rd = Rs1 >> Rs2<5:0>;
750 Rd = numeric_limits<uint64_t>::max();
756 Rd_sd = Rs1_sd >> Rs2<5:0>;
766 } else if (Rs1_sd == numeric_limits<int64_t>::min()
790 Rd = (uint64_t)(sext<20>(imm) << 12);
793 0x0e: decode FUNCT3 {
797 Rd_sd = Rs1_sw + Rs2_sw;
800 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
803 Rd_sd = Rs1_sw - Rs2_sw;
807 Rd_sd = Rs1_sw << Rs2<4:0>;
812 } else if (Rs1_sw == numeric_limits<int32_t>::min()
814 Rd_sd = numeric_limits<int32_t>::min();
816 Rd_sd = Rs1_sw/Rs2_sw;
821 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
825 Rd_sd = numeric_limits<uint64_t>::max();
827 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
831 Rd_sd = Rs1_sw >> Rs2<4:0>;
837 } else if (Rs1_sw == numeric_limits<int32_t>::min()
841 Rd_sd = Rs1_sw%Rs2_sw;
846 Rd_sd = (int32_t)Rs1_uw;
848 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
855 0x10: decode FUNCT2 {
858 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
859 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
860 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
863 if (std::isnan(fs1) || std::isnan(fs2) ||
865 if (issignalingnan(fs1) || issignalingnan(fs2)
866 || issignalingnan(fs3)) {
867 FFLAGS |= FloatInvalid;
869 fd = numeric_limits<float>::quiet_NaN();
870 } else if (std::isinf(fs1) || std::isinf(fs2) ||
872 if (signbit(fs1) == signbit(fs2)
873 && !std::isinf(fs3)) {
874 fd = numeric_limits<float>::infinity();
875 } else if (signbit(fs1) != signbit(fs2)
876 && !std::isinf(fs3)) {
877 fd = -numeric_limits<float>::infinity();
878 } else { // Fs3_sf is infinity
884 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
887 if (std::isnan(Fs1) || std::isnan(Fs2) ||
889 if (issignalingnan(Fs1) || issignalingnan(Fs2)
890 || issignalingnan(Fs3)) {
891 FFLAGS |= FloatInvalid;
893 Fd = numeric_limits<double>::quiet_NaN();
894 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
896 if (signbit(Fs1) == signbit(Fs2)
897 && !std::isinf(Fs3)) {
898 Fd = numeric_limits<double>::infinity();
899 } else if (signbit(Fs1) != signbit(Fs2)
900 && !std::isinf(Fs3)) {
901 Fd = -numeric_limits<double>::infinity();
910 0x11: decode FUNCT2 {
913 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
914 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
915 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
918 if (std::isnan(fs1) || std::isnan(fs2) ||
920 if (issignalingnan(fs1) || issignalingnan(fs2)
921 || issignalingnan(fs3)) {
922 FFLAGS |= FloatInvalid;
924 fd = numeric_limits<float>::quiet_NaN();
925 } else if (std::isinf(fs1) || std::isinf(fs2) ||
927 if (signbit(fs1) == signbit(fs2)
928 && !std::isinf(fs3)) {
929 fd = numeric_limits<float>::infinity();
930 } else if (signbit(fs1) != signbit(fs2)
931 && !std::isinf(fs3)) {
932 fd = -numeric_limits<float>::infinity();
933 } else { // Fs3_sf is infinity
939 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
942 if (std::isnan(Fs1) || std::isnan(Fs2) ||
944 if (issignalingnan(Fs1) || issignalingnan(Fs2)
945 || issignalingnan(Fs3)) {
946 FFLAGS |= FloatInvalid;
948 Fd = numeric_limits<double>::quiet_NaN();
949 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
951 if (signbit(Fs1) == signbit(Fs2)
952 && !std::isinf(Fs3)) {
953 Fd = numeric_limits<double>::infinity();
954 } else if (signbit(Fs1) != signbit(Fs2)
955 && !std::isinf(Fs3)) {
956 Fd = -numeric_limits<double>::infinity();
965 0x12: decode FUNCT2 {
968 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
969 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
970 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
973 if (std::isnan(fs1) || std::isnan(fs2) ||
975 if (issignalingnan(fs1) || issignalingnan(fs2)
976 || issignalingnan(fs3)) {
977 FFLAGS |= FloatInvalid;
979 fd = numeric_limits<float>::quiet_NaN();
980 } else if (std::isinf(fs1) || std::isinf(fs2) ||
982 if (signbit(fs1) == signbit(fs2)
983 && !std::isinf(fs3)) {
984 fd = -numeric_limits<float>::infinity();
985 } else if (signbit(fs1) != signbit(fs2)
986 && !std::isinf(fs3)) {
987 fd = numeric_limits<float>::infinity();
988 } else { // Fs3_sf is infinity
992 fd = -(fs1*fs2 - fs3);
994 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
997 if (std::isnan(Fs1) || std::isnan(Fs2) ||
999 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1000 || issignalingnan(Fs3)) {
1001 FFLAGS |= FloatInvalid;
1003 Fd = numeric_limits<double>::quiet_NaN();
1004 } else if (std::isinf(Fs1) || std::isinf(Fs2)
1005 || std::isinf(Fs3)) {
1006 if (signbit(Fs1) == signbit(Fs2)
1007 && !std::isinf(Fs3)) {
1008 Fd = -numeric_limits<double>::infinity();
1009 } else if (signbit(Fs1) != signbit(Fs2)
1010 && !std::isinf(Fs3)) {
1011 Fd = numeric_limits<double>::infinity();
1016 Fd = -(Fs1*Fs2 - Fs3);
1018 }}, FloatMultAccOp);
1020 0x13: decode FUNCT2 {
1023 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1024 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1025 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1028 if (std::isnan(fs1) || std::isnan(fs2) ||
1030 if (issignalingnan(fs1) || issignalingnan(fs2)
1031 || issignalingnan(fs3)) {
1032 FFLAGS |= FloatInvalid;
1034 fd = numeric_limits<float>::quiet_NaN();
1035 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1037 if (signbit(fs1) == signbit(fs2)
1038 && !std::isinf(fs3)) {
1039 fd = -numeric_limits<float>::infinity();
1040 } else if (signbit(fs1) != signbit(fs2)
1041 && !std::isinf(fs3)) {
1042 fd = numeric_limits<float>::infinity();
1043 } else { // Fs3_sf is infinity
1047 fd = -(fs1*fs2 + fs3);
1049 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1050 }}, FloatMultAccOp);
1052 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1054 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1055 || issignalingnan(Fs3)) {
1056 FFLAGS |= FloatInvalid;
1058 Fd = numeric_limits<double>::quiet_NaN();
1059 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1061 if (signbit(Fs1) == signbit(Fs2)
1062 && !std::isinf(Fs3)) {
1063 Fd = -numeric_limits<double>::infinity();
1064 } else if (signbit(Fs1) != signbit(Fs2)
1065 && !std::isinf(Fs3)) {
1066 Fd = numeric_limits<double>::infinity();
1071 Fd = -(Fs1*Fs2 + Fs3);
1073 }}, FloatMultAccOp);
1075 0x14: decode FUNCT7 {
1078 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1079 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1082 if (std::isnan(fs1) || std::isnan(fs2)) {
1083 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1084 FFLAGS |= FloatInvalid;
1086 fd = numeric_limits<float>::quiet_NaN();
1090 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1093 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1094 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1095 FFLAGS |= FloatInvalid;
1097 Fd = numeric_limits<double>::quiet_NaN();
1104 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1105 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1108 if (std::isnan(fs1) || std::isnan(fs2)) {
1109 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1110 FFLAGS |= FloatInvalid;
1112 fd = numeric_limits<float>::quiet_NaN();
1116 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1119 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1120 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1121 FFLAGS |= FloatInvalid;
1123 Fd = numeric_limits<double>::quiet_NaN();
1130 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1131 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1134 if (std::isnan(fs1) || std::isnan(fs2)) {
1135 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1136 FFLAGS |= FloatInvalid;
1138 fd = numeric_limits<float>::quiet_NaN();
1142 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1145 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1146 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1147 FFLAGS |= FloatInvalid;
1149 Fd = numeric_limits<double>::quiet_NaN();
1156 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1157 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1160 if (std::isnan(fs1) || std::isnan(fs2)) {
1161 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1162 FFLAGS |= FloatInvalid;
1164 fd = numeric_limits<float>::quiet_NaN();
1168 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1171 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1172 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1173 FFLAGS |= FloatInvalid;
1175 Fd = numeric_limits<double>::quiet_NaN();
1180 0x10: decode ROUND_MODE {
1183 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1184 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1187 if (issignalingnan(fs1)) {
1188 fd = numeric_limits<float>::signaling_NaN();
1189 feclearexcept(FE_INVALID);
1191 fd = copysign(fs1, fs2);
1193 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1197 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1198 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1201 if (issignalingnan(fs1)) {
1202 fd = numeric_limits<float>::signaling_NaN();
1203 feclearexcept(FE_INVALID);
1205 fd = copysign(fs1, -fs2);
1207 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1211 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1212 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1215 if (issignalingnan(fs1)) {
1216 fd = numeric_limits<float>::signaling_NaN();
1217 feclearexcept(FE_INVALID);
1219 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1221 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1224 0x11: decode ROUND_MODE {
1226 if (issignalingnan(Fs1)) {
1227 Fd = numeric_limits<double>::signaling_NaN();
1228 feclearexcept(FE_INVALID);
1230 Fd = copysign(Fs1, Fs2);
1234 if (issignalingnan(Fs1)) {
1235 Fd = numeric_limits<double>::signaling_NaN();
1236 feclearexcept(FE_INVALID);
1238 Fd = copysign(Fs1, -Fs2);
1242 if (issignalingnan(Fs1)) {
1243 Fd = numeric_limits<double>::signaling_NaN();
1244 feclearexcept(FE_INVALID);
1246 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1250 0x14: decode ROUND_MODE {
1253 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1254 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1257 if (issignalingnan(fs2)) {
1259 FFLAGS |= FloatInvalid;
1260 } else if (issignalingnan(fs1)) {
1262 FFLAGS |= FloatInvalid;
1264 fd = fmin(fs1, fs2);
1266 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1270 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1271 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1274 if (issignalingnan(fs2)) {
1276 FFLAGS |= FloatInvalid;
1277 } else if (issignalingnan(fs1)) {
1279 FFLAGS |= FloatInvalid;
1281 fd = fmax(fs1, fs2);
1283 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1286 0x15: decode ROUND_MODE {
1288 if (issignalingnan(Fs2)) {
1290 FFLAGS |= FloatInvalid;
1291 } else if (issignalingnan(Fs1)) {
1293 FFLAGS |= FloatInvalid;
1295 Fd = fmin(Fs1, Fs2);
1299 if (issignalingnan(Fs2)) {
1301 FFLAGS |= FloatInvalid;
1302 } else if (issignalingnan(Fs1)) {
1304 FFLAGS |= FloatInvalid;
1306 Fd = fmax(Fs1, Fs2);
1311 if (CONV_SGN != 1) {
1312 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1316 if (issignalingnan(Fs1)) {
1317 fd = numeric_limits<float>::quiet_NaN();
1318 FFLAGS |= FloatInvalid;
1322 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1325 if (CONV_SGN != 0) {
1326 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1330 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1332 if (issignalingnan(fs1)) {
1333 Fd = numeric_limits<double>::quiet_NaN();
1334 FFLAGS |= FloatInvalid;
1341 fault = make_shared<IllegalInstFault>("source reg x1",
1345 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1348 if (issignalingnan(Fs1_sf)) {
1349 FFLAGS |= FloatInvalid;
1352 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1356 fault = make_shared<IllegalInstFault>("source reg x1",
1361 0x50: decode ROUND_MODE {
1364 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1365 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1367 if (std::isnan(fs1) || std::isnan(fs2)) {
1368 FFLAGS |= FloatInvalid;
1371 Rd = fs1 <= fs2 ? 1 : 0;
1376 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1377 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1379 if (std::isnan(fs1) || std::isnan(fs2)) {
1380 FFLAGS |= FloatInvalid;
1383 Rd = fs1 < fs2 ? 1 : 0;
1388 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1389 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1391 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1392 FFLAGS |= FloatInvalid;
1394 Rd = fs1 == fs2 ? 1 : 0;
1397 0x51: decode ROUND_MODE {
1399 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1400 FFLAGS |= FloatInvalid;
1403 Rd = Fs1 <= Fs2 ? 1 : 0;
1407 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1408 FFLAGS |= FloatInvalid;
1411 Rd = Fs1 < Fs2 ? 1 : 0;
1415 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1416 FFLAGS |= FloatInvalid;
1418 Rd = Fs1 == Fs2 ? 1 : 0;
1421 0x60: decode CONV_SGN {
1424 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1426 if (std::isnan(fs1)) {
1427 Rd_sd = numeric_limits<int32_t>::max();
1428 FFLAGS |= FloatInvalid;
1430 float(numeric_limits<int32_t>::max())) {
1431 Rd_sd = numeric_limits<int32_t>::max();
1432 FFLAGS |= FloatInvalid;
1434 float(numeric_limits<int32_t>::min())) {
1435 Rd_sd = numeric_limits<int32_t>::min();
1436 FFLAGS |= FloatInvalid;
1438 Rd_sd = (int32_t)fs1;
1443 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1445 if (std::isnan(fs1)) {
1446 Rd = numeric_limits<uint64_t>::max();
1447 FFLAGS |= FloatInvalid;
1448 } else if (fs1 < 0.0) {
1450 FFLAGS |= FloatInvalid;
1452 float(numeric_limits<uint32_t>::max())) {
1453 Rd = numeric_limits<uint64_t>::max();
1454 FFLAGS |= FloatInvalid;
1461 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1463 if (std::isnan(fs1)) {
1464 Rd_sd = numeric_limits<int64_t>::max();
1465 FFLAGS |= FloatInvalid;
1467 float(numeric_limits<int64_t>::max())) {
1468 Rd_sd = numeric_limits<int64_t>::max();
1469 FFLAGS |= FloatInvalid;
1471 float(numeric_limits<int64_t>::min())) {
1472 Rd_sd = numeric_limits<int64_t>::min();
1473 FFLAGS |= FloatInvalid;
1475 Rd_sd = (int64_t)fs1;
1480 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1482 if (std::isnan(fs1)) {
1483 Rd = numeric_limits<uint64_t>::max();
1484 FFLAGS |= FloatInvalid;
1485 } else if (fs1 < 0.0) {
1487 FFLAGS |= FloatInvalid;
1489 float(numeric_limits<uint64_t>::max())) {
1490 Rd = numeric_limits<uint64_t>::max();
1491 FFLAGS |= FloatInvalid;
1497 0x61: decode CONV_SGN {
1499 if (std::isnan(Fs1)) {
1500 Rd_sd = numeric_limits<int32_t>::max();
1501 FFLAGS |= FloatInvalid;
1503 float(numeric_limits<int32_t>::max())) {
1504 Rd_sd = numeric_limits<int32_t>::max();
1505 FFLAGS |= FloatInvalid;
1507 float(numeric_limits<int32_t>::min())) {
1508 Rd_sd = numeric_limits<int32_t>::min();
1509 FFLAGS |= FloatInvalid;
1511 Rd_sd = (int32_t)Fs1;
1515 if (std::isnan(Fs1)) {
1516 Rd = numeric_limits<uint64_t>::max();
1517 FFLAGS |= FloatInvalid;
1518 } else if (Fs1 < 0) {
1520 FFLAGS |= FloatInvalid;
1522 float(numeric_limits<uint32_t>::max())) {
1523 Rd = numeric_limits<uint64_t>::max();
1524 FFLAGS |= FloatInvalid;
1530 if (std::isnan(Fs1)) {
1531 Rd_sd = numeric_limits<int64_t>::max();
1532 FFLAGS |= FloatInvalid;
1534 float(numeric_limits<int64_t>::max())) {
1535 Rd_sd = numeric_limits<int64_t>::max();
1536 FFLAGS |= FloatInvalid;
1538 float(numeric_limits<int64_t>::min())) {
1539 Rd_sd = numeric_limits<int64_t>::min();
1540 FFLAGS |= FloatInvalid;
1546 if (std::isnan(Fs1)) {
1547 Rd = numeric_limits<uint64_t>::max();
1548 FFLAGS |= FloatInvalid;
1549 } else if (Fs1 < 0) {
1551 FFLAGS |= FloatInvalid;
1553 float(numeric_limits<uint64_t>::max())) {
1554 Rd = numeric_limits<uint64_t>::max();
1555 FFLAGS |= FloatInvalid;
1561 0x68: decode CONV_SGN {
1563 float temp = (float)Rs1_sw;
1564 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1567 float temp = (float)Rs1_uw;
1568 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1571 float temp = (float)Rs1_sd;
1572 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1575 float temp = (float)Rs1;
1576 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1579 0x69: decode CONV_SGN {
1581 Fd = (double)Rs1_sw;
1584 Fd = (double)Rs1_uw;
1587 Fd = (double)Rs1_sd;
1593 0x70: decode ROUND_MODE {
1595 Rd = (uint32_t)Fs1_bits;
1596 if ((Rd&0x80000000) != 0) {
1597 Rd |= (0xFFFFFFFFULL << 32);
1602 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1603 switch (fpclassify(fs1)) {
1612 if (issignalingnan(fs1)) {
1640 panic("Unknown classification for operand.");
1645 0x71: decode ROUND_MODE {
1650 switch (fpclassify(Fs1)) {
1659 if (issignalingnan(Fs1)) {
1687 panic("Unknown classification for operand.");
1693 Fd_bits = (uint64_t)Rs1_uw;
1701 0x18: decode FUNCT3 {
1709 }}, IsDirectControl, IsCondControl);
1716 }}, IsDirectControl, IsCondControl);
1718 if (Rs1_sd < Rs2_sd) {
1723 }}, IsDirectControl, IsCondControl);
1725 if (Rs1_sd >= Rs2_sd) {
1730 }}, IsDirectControl, IsCondControl);
1737 }}, IsDirectControl, IsCondControl);
1744 }}, IsDirectControl, IsCondControl);
1748 0x19: decode FUNCT3 {
1751 NPC = (imm + Rs1) & (~0x1);
1752 }}, IsIndirectControl, IsUncondControl, IsCall);
1758 }}, IsDirectControl, IsUncondControl, IsCall);
1760 0x1c: decode FUNCT3 {
1762 0x0: decode FUNCT12 {
1764 fault = make_shared<SyscallFault>(
1765 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1766 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1769 fault = make_shared<BreakpointFault>(xc->pcState());
1770 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1772 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1773 status.uie = status.upie;
1775 xc->setMiscReg(MISCREG_STATUS, status);
1776 NPC = xc->readMiscReg(MISCREG_UEPC);
1779 if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1780 fault = make_shared<IllegalInstFault>(
1781 "sret in user mode", machInst);
1784 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1785 xc->setMiscReg(MISCREG_PRV, status.spp);
1786 status.sie = status.spie;
1789 xc->setMiscReg(MISCREG_STATUS, status);
1790 NPC = xc->readMiscReg(MISCREG_SEPC);
1794 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1795 fault = make_shared<IllegalInstFault>(
1796 "mret at lower privilege", machInst);
1799 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1800 xc->setMiscReg(MISCREG_PRV, status.mpp);
1801 status.mie = status.mpie;
1804 xc->setMiscReg(MISCREG_STATUS, status);
1805 NPC = xc->readMiscReg(MISCREG_MEPC);
1814 }}, IsNonSpeculative, No_OpClass);
1818 }}, IsNonSpeculative, No_OpClass);
1822 }}, IsNonSpeculative, No_OpClass);
1826 }}, IsNonSpeculative, No_OpClass);
1830 }}, IsNonSpeculative, No_OpClass);
1834 }}, IsNonSpeculative, No_OpClass);