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: CIOp::c_addi4spn({{
40 imm = CIMM8<1:1> << 2 |
46 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");
111 fault = make_shared<IllegalInstFault>("immediate = 0");
113 Rc1_sd = Rc1_sd + imm;
118 imm |= ~((uint64_t)0x1F);
121 Rc1_sd = (int32_t)Rc1_sd + imm;
126 imm |= ~((uint64_t)0x1F);
133 imm = CIMM5<4:4> << 4 |
138 imm |= ~((int64_t)0x1FF);
146 imm |= ~((uint64_t)0x1FFFF);
148 assert(RC1 != 0 && RC1 != 2);
154 0x4: decode CFUNCT2HIGH {
157 imm = CIMM5 | (CIMM1 << 5);
163 imm = CIMM5 | (CIMM1 << 5);
166 Rp1_sd = Rp1_sd >> imm;
171 imm |= ~((uint64_t)0x1F);
177 0x3: decode CFUNCT1 {
178 0x0: decode CFUNCT2LOW {
192 0x1: decode CFUNCT2LOW {
194 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
197 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
204 int64_t offset = CJUMPIMM<3:1> << 1 |
211 if (CJUMPIMM<10:10> > 0)
212 offset |= ~((int64_t)0x7FF);
214 }}, IsIndirectControl, IsUncondControl, IsCall);
221 }}, IsDirectControl, IsCondControl);
227 }}, IsDirectControl, IsCondControl);
230 0x2: decode COPCODE {
232 imm = CIMM5 | (CIMM1 << 5);
238 format CompressedLoad {
240 offset = CIMM5<4:3> << 3 |
249 offset = CIMM5<4:2> << 2 |
259 offset = CIMM5<4:3> << 3 |
269 0x4: decode CFUNCT1 {
274 }}, IsIndirectControl, IsUncondControl, IsCall);
275 default: CROp::c_mv({{
281 0x0: SystemOp::c_ebreak({{
283 fault = make_shared<BreakpointFault>();
284 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
285 default: decode RC2 {
290 }}, IsIndirectControl, IsUncondControl, IsCall);
291 default: ROp::c_add({{
292 Rc1_sd = Rc1_sd + Rc2_sd;
297 format CompressedStore {
299 offset = CIMM6<5:3> << 3 |
307 offset = CIMM6<5:2> << 2 |
315 offset = CIMM6<5:3> << 3 |
325 0x00: decode FUNCT3 {
351 0x01: decode FUNCT3 {
354 Fd_bits = (uint64_t)Mem_uw;
355 }}, inst_flags=FloatMemReadOp);
358 }}, inst_flags=FloatMemReadOp);
362 0x03: decode FUNCT3 {
365 }}, uint64_t, IsNonSpeculative, IsMemBarrier, No_OpClass);
367 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
371 0x04: decode FUNCT3 {
374 Rd_sd = Rs1_sd + imm;
380 Rd = (Rs1_sd < imm) ? 1 : 0;
383 Rd = (Rs1 < imm) ? 1 : 0;
393 Rd_sd = Rs1_sd >> SHAMT6;
409 0x06: decode FUNCT3 {
412 Rd_sd = Rs1_sw + imm;
415 Rd_sd = Rs1_sw << SHAMT5;
419 Rd = Rs1_uw >> SHAMT5;
422 Rd_sd = Rs1_sw >> SHAMT5;
428 0x08: decode FUNCT3 {
445 0x09: decode FUNCT3 {
448 Mem_uw = (uint32_t)Fs2_bits;
449 }}, inst_flags=FloatMemWriteOp);
452 }}, inst_flags=FloatMemWriteOp);
456 0x0b: decode FUNCT3 {
457 0x2: decode AMOFUNCT {
458 0x2: LoadReserved::lr_w({{
461 0x3: StoreCond::sc_w({{
465 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
467 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
468 Mem_sw = Rs2_sw + Rt_sd;
471 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
475 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
476 Mem_sw = Rs2_uw^Rt_sd;
479 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
480 Mem_sw = Rs2_uw | Rt_sd;
483 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
484 Mem_sw = Rs2_uw&Rt_sd;
487 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
488 Mem_sw = min<int32_t>(Rs2_sw, Rt_sd);
491 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
492 Mem_sw = max<int32_t>(Rs2_sw, Rt_sd);
495 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
496 Mem_sw = min<uint32_t>(Rs2_uw, Rt_sd);
499 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
500 Mem_sw = max<uint32_t>(Rs2_uw, Rt_sd);
505 0x3: decode AMOFUNCT {
506 0x2: LoadReserved::lr_d({{
509 0x3: StoreCond::sc_d({{
513 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
515 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
516 Mem_sd = Rs2_sd + Rt_sd;
519 0x1: amoswap_d({{Rt = Mem;}}, {{
523 0x4: amoxor_d({{Rt = Mem;}}, {{
527 0x8: amoor_d({{Rt = Mem;}}, {{
531 0xc: amoand_d({{Rt = Mem;}}, {{
535 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
536 Mem_sd = min(Rs2_sd, Rt_sd);
539 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
540 Mem_sd = max(Rs2_sd, Rt_sd);
543 0x18: amominu_d({{Rt = Mem;}}, {{
547 0x1c: amomaxu_d({{Rt = Mem;}}, {{
554 0x0c: decode FUNCT3 {
558 Rd = Rs1_sd + Rs2_sd;
564 Rd = Rs1_sd - Rs2_sd;
569 Rd = Rs1 << Rs2<5:0>;
572 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
574 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
575 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
576 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
577 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
579 uint64_t hi = Rs1_hi*Rs2_hi;
580 uint64_t mid1 = Rs1_hi*Rs2_lo;
581 uint64_t mid2 = Rs1_lo*Rs2_hi;
582 uint64_t lo = Rs2_lo*Rs1_lo;
583 uint64_t carry = ((uint64_t)(uint32_t)mid1
584 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
590 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
596 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
599 bool negate = Rs1_sd < 0;
600 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
601 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
602 uint64_t Rs2_lo = (uint32_t)Rs2;
603 uint64_t Rs2_hi = Rs2 >> 32;
605 uint64_t hi = Rs1_hi*Rs2_hi;
606 uint64_t mid1 = Rs1_hi*Rs2_lo;
607 uint64_t mid2 = Rs1_lo*Rs2_hi;
608 uint64_t lo = Rs1_lo*Rs2_lo;
609 uint64_t carry = ((uint64_t)(uint32_t)mid1
610 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
616 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
621 Rd = (Rs1 < Rs2) ? 1 : 0;
624 uint64_t Rs1_lo = (uint32_t)Rs1;
625 uint64_t Rs1_hi = Rs1 >> 32;
626 uint64_t Rs2_lo = (uint32_t)Rs2;
627 uint64_t Rs2_hi = Rs2 >> 32;
629 uint64_t hi = Rs1_hi*Rs2_hi;
630 uint64_t mid1 = Rs1_hi*Rs2_lo;
631 uint64_t mid2 = Rs1_lo*Rs2_hi;
632 uint64_t lo = Rs1_lo*Rs2_lo;
633 uint64_t carry = ((uint64_t)(uint32_t)mid1
634 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
636 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
646 } else if (Rs1_sd == numeric_limits<int64_t>::min()
648 Rd_sd = numeric_limits<int64_t>::min();
650 Rd_sd = Rs1_sd/Rs2_sd;
656 Rd = Rs1 >> Rs2<5:0>;
660 Rd = numeric_limits<uint64_t>::max();
666 Rd_sd = Rs1_sd >> Rs2<5:0>;
676 } else if (Rs1_sd == numeric_limits<int64_t>::min()
703 0x0e: decode FUNCT3 {
707 Rd_sd = Rs1_sw + Rs2_sw;
710 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
713 Rd_sd = Rs1_sw - Rs2_sw;
717 Rd_sd = Rs1_sw << Rs2<4:0>;
722 } else if (Rs1_sw == numeric_limits<int32_t>::min()
724 Rd_sd = numeric_limits<int32_t>::min();
726 Rd_sd = Rs1_sw/Rs2_sw;
731 Rd_uw = Rs1_uw >> Rs2<4:0>;
735 Rd_sd = numeric_limits<IntReg>::max();
737 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
741 Rd_sd = Rs1_sw >> Rs2<4:0>;
747 } else if (Rs1_sw == numeric_limits<int32_t>::min()
751 Rd_sd = Rs1_sw%Rs2_sw;
756 Rd_sd = (int32_t)Rs1_uw;
758 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
765 0x10: decode FUNCT2 {
768 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
769 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
770 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
773 if (std::isnan(fs1) || std::isnan(fs2) ||
775 if (issignalingnan(fs1) || issignalingnan(fs2)
776 || issignalingnan(fs3)) {
777 FFLAGS |= FloatInvalid;
779 fd = numeric_limits<float>::quiet_NaN();
780 } else if (std::isinf(fs1) || std::isinf(fs2) ||
782 if (signbit(fs1) == signbit(fs2)
783 && !std::isinf(fs3)) {
784 fd = numeric_limits<float>::infinity();
785 } else if (signbit(fs1) != signbit(fs2)
786 && !std::isinf(fs3)) {
787 fd = -numeric_limits<float>::infinity();
788 } else { // Fs3_sf is infinity
794 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
797 if (std::isnan(Fs1) || std::isnan(Fs2) ||
799 if (issignalingnan(Fs1) || issignalingnan(Fs2)
800 || issignalingnan(Fs3)) {
801 FFLAGS |= FloatInvalid;
803 Fd = numeric_limits<double>::quiet_NaN();
804 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
806 if (signbit(Fs1) == signbit(Fs2)
807 && !std::isinf(Fs3)) {
808 Fd = numeric_limits<double>::infinity();
809 } else if (signbit(Fs1) != signbit(Fs2)
810 && !std::isinf(Fs3)) {
811 Fd = -numeric_limits<double>::infinity();
820 0x11: decode FUNCT2 {
823 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
824 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
825 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
828 if (std::isnan(fs1) || std::isnan(fs2) ||
830 if (issignalingnan(fs1) || issignalingnan(fs2)
831 || issignalingnan(fs3)) {
832 FFLAGS |= FloatInvalid;
834 fd = numeric_limits<float>::quiet_NaN();
835 } else if (std::isinf(fs1) || std::isinf(fs2) ||
837 if (signbit(fs1) == signbit(fs2)
838 && !std::isinf(fs3)) {
839 fd = numeric_limits<float>::infinity();
840 } else if (signbit(fs1) != signbit(fs2)
841 && !std::isinf(fs3)) {
842 fd = -numeric_limits<float>::infinity();
843 } else { // Fs3_sf is infinity
849 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
852 if (std::isnan(Fs1) || std::isnan(Fs2) ||
854 if (issignalingnan(Fs1) || issignalingnan(Fs2)
855 || issignalingnan(Fs3)) {
856 FFLAGS |= FloatInvalid;
858 Fd = numeric_limits<double>::quiet_NaN();
859 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
861 if (signbit(Fs1) == signbit(Fs2)
862 && !std::isinf(Fs3)) {
863 Fd = numeric_limits<double>::infinity();
864 } else if (signbit(Fs1) != signbit(Fs2)
865 && !std::isinf(Fs3)) {
866 Fd = -numeric_limits<double>::infinity();
875 0x12: decode FUNCT2 {
878 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
879 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
880 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
883 if (std::isnan(fs1) || std::isnan(fs2) ||
885 if (issignalingnan(fs1) || issignalingnan(fs2)
886 || issignalingnan(fs3)) {
887 FFLAGS |= FloatInvalid;
889 fd = numeric_limits<float>::quiet_NaN();
890 } else if (std::isinf(fs1) || std::isinf(fs2) ||
892 if (signbit(fs1) == signbit(fs2)
893 && !std::isinf(fs3)) {
894 fd = -numeric_limits<float>::infinity();
895 } else if (signbit(fs1) != signbit(fs2)
896 && !std::isinf(fs3)) {
897 fd = numeric_limits<float>::infinity();
898 } else { // Fs3_sf is infinity
902 fd = -(fs1*fs2 - fs3);
904 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
907 if (std::isnan(Fs1) || std::isnan(Fs2) ||
909 if (issignalingnan(Fs1) || issignalingnan(Fs2)
910 || issignalingnan(Fs3)) {
911 FFLAGS |= FloatInvalid;
913 Fd = numeric_limits<double>::quiet_NaN();
914 } else if (std::isinf(Fs1) || std::isinf(Fs2)
915 || std::isinf(Fs3)) {
916 if (signbit(Fs1) == signbit(Fs2)
917 && !std::isinf(Fs3)) {
918 Fd = -numeric_limits<double>::infinity();
919 } else if (signbit(Fs1) != signbit(Fs2)
920 && !std::isinf(Fs3)) {
921 Fd = numeric_limits<double>::infinity();
926 Fd = -(Fs1*Fs2 - Fs3);
930 0x13: decode FUNCT2 {
933 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
934 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
935 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
938 if (std::isnan(fs1) || std::isnan(fs2) ||
940 if (issignalingnan(fs1) || issignalingnan(fs2)
941 || issignalingnan(fs3)) {
942 FFLAGS |= FloatInvalid;
944 fd = numeric_limits<float>::quiet_NaN();
945 } else if (std::isinf(fs1) || std::isinf(fs2) ||
947 if (signbit(fs1) == signbit(fs2)
948 && !std::isinf(fs3)) {
949 fd = -numeric_limits<float>::infinity();
950 } else if (signbit(fs1) != signbit(fs2)
951 && !std::isinf(fs3)) {
952 fd = numeric_limits<float>::infinity();
953 } else { // Fs3_sf is infinity
957 fd = -(fs1*fs2 + fs3);
959 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
962 if (std::isnan(Fs1) || std::isnan(Fs2) ||
964 if (issignalingnan(Fs1) || issignalingnan(Fs2)
965 || issignalingnan(Fs3)) {
966 FFLAGS |= FloatInvalid;
968 Fd = numeric_limits<double>::quiet_NaN();
969 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
971 if (signbit(Fs1) == signbit(Fs2)
972 && !std::isinf(Fs3)) {
973 Fd = -numeric_limits<double>::infinity();
974 } else if (signbit(Fs1) != signbit(Fs2)
975 && !std::isinf(Fs3)) {
976 Fd = numeric_limits<double>::infinity();
981 Fd = -(Fs1*Fs2 + Fs3);
985 0x14: decode FUNCT7 {
988 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
989 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
992 if (std::isnan(fs1) || std::isnan(fs2)) {
993 if (issignalingnan(fs1) || issignalingnan(fs2)) {
994 FFLAGS |= FloatInvalid;
996 fd = numeric_limits<float>::quiet_NaN();
1000 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1003 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1004 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1005 FFLAGS |= FloatInvalid;
1007 Fd = numeric_limits<double>::quiet_NaN();
1014 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1015 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1018 if (std::isnan(fs1) || std::isnan(fs2)) {
1019 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1020 FFLAGS |= FloatInvalid;
1022 fd = numeric_limits<float>::quiet_NaN();
1026 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1029 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1030 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1031 FFLAGS |= FloatInvalid;
1033 Fd = numeric_limits<double>::quiet_NaN();
1040 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1041 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1044 if (std::isnan(fs1) || std::isnan(fs2)) {
1045 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1046 FFLAGS |= FloatInvalid;
1048 fd = numeric_limits<float>::quiet_NaN();
1052 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1055 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1056 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1057 FFLAGS |= FloatInvalid;
1059 Fd = numeric_limits<double>::quiet_NaN();
1066 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1067 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1070 if (std::isnan(fs1) || std::isnan(fs2)) {
1071 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1072 FFLAGS |= FloatInvalid;
1074 fd = numeric_limits<float>::quiet_NaN();
1078 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1081 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1082 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1083 FFLAGS |= FloatInvalid;
1085 Fd = numeric_limits<double>::quiet_NaN();
1090 0x10: decode ROUND_MODE {
1093 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1094 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1097 if (issignalingnan(fs1)) {
1098 fd = numeric_limits<float>::signaling_NaN();
1099 feclearexcept(FE_INVALID);
1101 fd = copysign(fs1, fs2);
1103 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1107 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1108 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1111 if (issignalingnan(fs1)) {
1112 fd = numeric_limits<float>::signaling_NaN();
1113 feclearexcept(FE_INVALID);
1115 fd = copysign(fs1, -fs2);
1117 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1121 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1122 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1125 if (issignalingnan(fs1)) {
1126 fd = numeric_limits<float>::signaling_NaN();
1127 feclearexcept(FE_INVALID);
1129 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1131 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1134 0x11: decode ROUND_MODE {
1136 if (issignalingnan(Fs1)) {
1137 Fd = numeric_limits<double>::signaling_NaN();
1138 feclearexcept(FE_INVALID);
1140 Fd = copysign(Fs1, Fs2);
1144 if (issignalingnan(Fs1)) {
1145 Fd = numeric_limits<double>::signaling_NaN();
1146 feclearexcept(FE_INVALID);
1148 Fd = copysign(Fs1, -Fs2);
1152 if (issignalingnan(Fs1)) {
1153 Fd = numeric_limits<double>::signaling_NaN();
1154 feclearexcept(FE_INVALID);
1156 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1160 0x14: decode ROUND_MODE {
1163 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1164 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1167 if (issignalingnan(fs2)) {
1169 FFLAGS |= FloatInvalid;
1170 } else if (issignalingnan(fs1)) {
1172 FFLAGS |= FloatInvalid;
1174 fd = fmin(fs1, fs2);
1176 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1180 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1181 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1184 if (issignalingnan(fs2)) {
1186 FFLAGS |= FloatInvalid;
1187 } else if (issignalingnan(fs1)) {
1189 FFLAGS |= FloatInvalid;
1191 fd = fmax(fs1, fs2);
1193 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1196 0x15: decode ROUND_MODE {
1198 if (issignalingnan(Fs2)) {
1200 FFLAGS |= FloatInvalid;
1201 } else if (issignalingnan(Fs1)) {
1203 FFLAGS |= FloatInvalid;
1205 Fd = fmin(Fs1, Fs2);
1209 if (issignalingnan(Fs2)) {
1211 FFLAGS |= FloatInvalid;
1212 } else if (issignalingnan(Fs1)) {
1214 FFLAGS |= FloatInvalid;
1216 Fd = fmax(Fs1, Fs2);
1221 assert(CONV_SGN == 1);
1223 if (issignalingnan(Fs1)) {
1224 fd = numeric_limits<float>::quiet_NaN();
1225 FFLAGS |= FloatInvalid;
1229 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1232 assert(CONV_SGN == 0);
1234 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1236 if (issignalingnan(fs1)) {
1237 Fd = numeric_limits<double>::quiet_NaN();
1238 FFLAGS |= FloatInvalid;
1246 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1249 if (issignalingnan(Fs1_sf)) {
1250 FFLAGS |= FloatInvalid;
1253 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1259 0x50: decode ROUND_MODE {
1262 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1263 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1265 if (std::isnan(fs1) || std::isnan(fs2)) {
1266 FFLAGS |= FloatInvalid;
1269 Rd = fs1 <= fs2 ? 1 : 0;
1274 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1275 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1277 if (std::isnan(fs1) || std::isnan(fs2)) {
1278 FFLAGS |= FloatInvalid;
1281 Rd = fs1 < fs2 ? 1 : 0;
1286 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1287 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1289 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1290 FFLAGS |= FloatInvalid;
1292 Rd = fs1 == fs2 ? 1 : 0;
1295 0x51: decode ROUND_MODE {
1297 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1298 FFLAGS |= FloatInvalid;
1301 Rd = Fs1 <= Fs2 ? 1 : 0;
1305 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1306 FFLAGS |= FloatInvalid;
1309 Rd = Fs1 < Fs2 ? 1 : 0;
1313 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1314 FFLAGS |= FloatInvalid;
1316 Rd = Fs1 == Fs2 ? 1 : 0;
1319 0x60: decode CONV_SGN {
1322 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1324 if (std::isnan(fs1)) {
1325 Rd_sd = numeric_limits<int32_t>::max();
1326 FFLAGS |= FloatInvalid;
1327 } else if (fs1 >= numeric_limits<int32_t>::max()) {
1328 Rd_sd = numeric_limits<int32_t>::max();
1329 FFLAGS |= FloatInvalid;
1330 } else if (fs1 <= numeric_limits<int32_t>::min()) {
1331 Rd_sd = numeric_limits<int32_t>::min();
1332 FFLAGS |= FloatInvalid;
1334 Rd_sd = (int32_t)fs1;
1339 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1341 if (std::isnan(fs1)) {
1342 Rd = numeric_limits<uint64_t>::max();
1343 FFLAGS |= FloatInvalid;
1344 } else if (fs1 < 0.0) {
1346 FFLAGS |= FloatInvalid;
1347 } else if (fs1 > numeric_limits<uint32_t>::max()) {
1348 Rd = numeric_limits<uint64_t>::max();
1349 FFLAGS |= FloatInvalid;
1356 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1358 if (std::isnan(fs1)) {
1359 Rd_sd = numeric_limits<int64_t>::max();
1360 FFLAGS |= FloatInvalid;
1361 } else if (fs1 > numeric_limits<int64_t>::max()) {
1362 Rd_sd = numeric_limits<int64_t>::max();
1363 FFLAGS |= FloatInvalid;
1364 } else if (fs1 < numeric_limits<int64_t>::min()) {
1365 Rd_sd = numeric_limits<int64_t>::min();
1366 FFLAGS |= FloatInvalid;
1368 Rd_sd = (int64_t)fs1;
1373 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1375 if (std::isnan(fs1)) {
1376 Rd = numeric_limits<uint64_t>::max();
1377 FFLAGS |= FloatInvalid;
1378 } else if (fs1 < 0.0) {
1380 FFLAGS |= FloatInvalid;
1381 } else if (fs1 > numeric_limits<uint64_t>::max()) {
1382 Rd = numeric_limits<uint64_t>::max();
1383 FFLAGS |= FloatInvalid;
1389 0x61: decode CONV_SGN {
1391 if (std::isnan(Fs1)) {
1392 Rd_sd = numeric_limits<int32_t>::max();
1393 FFLAGS |= FloatInvalid;
1394 } else if (Fs1 > numeric_limits<int32_t>::max()) {
1395 Rd_sd = numeric_limits<int32_t>::max();
1396 FFLAGS |= FloatInvalid;
1397 } else if (Fs1 < numeric_limits<int32_t>::min()) {
1398 Rd_sd = numeric_limits<int32_t>::min();
1399 FFLAGS |= FloatInvalid;
1401 Rd_sd = (int32_t)Fs1;
1405 if (std::isnan(Fs1)) {
1406 Rd = numeric_limits<uint64_t>::max();
1407 FFLAGS |= FloatInvalid;
1408 } else if (Fs1 < 0) {
1410 FFLAGS |= FloatInvalid;
1411 } else if (Fs1 > numeric_limits<uint32_t>::max()) {
1412 Rd = numeric_limits<uint64_t>::max();
1413 FFLAGS |= FloatInvalid;
1419 if (std::isnan(Fs1)) {
1420 Rd_sd = numeric_limits<int64_t>::max();
1421 FFLAGS |= FloatInvalid;
1422 } else if (Fs1 > numeric_limits<int64_t>::max()) {
1423 Rd_sd = numeric_limits<int64_t>::max();
1424 FFLAGS |= FloatInvalid;
1425 } else if (Fs1 < numeric_limits<int64_t>::min()) {
1426 Rd_sd = numeric_limits<int64_t>::min();
1427 FFLAGS |= FloatInvalid;
1433 if (std::isnan(Fs1)) {
1434 Rd = numeric_limits<uint64_t>::max();
1435 FFLAGS |= FloatInvalid;
1436 } else if (Fs1 < 0) {
1438 FFLAGS |= FloatInvalid;
1439 } else if (Fs1 > numeric_limits<uint64_t>::max()) {
1440 Rd = numeric_limits<uint64_t>::max();
1441 FFLAGS |= FloatInvalid;
1447 0x68: decode CONV_SGN {
1449 float temp = (float)Rs1_sw;
1450 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1453 float temp = (float)Rs1_uw;
1454 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1457 float temp = (float)Rs1_sd;
1458 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1461 float temp = (float)Rs1;
1462 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1465 0x69: decode CONV_SGN {
1467 Fd = (double)Rs1_sw;
1470 Fd = (double)Rs1_uw;
1473 Fd = (double)Rs1_sd;
1479 0x70: decode ROUND_MODE {
1481 Rd = (uint32_t)Fs1_bits;
1482 if ((Rd&0x80000000) != 0) {
1483 Rd |= (0xFFFFFFFFULL << 32);
1488 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1489 switch (fpclassify(fs1)) {
1498 if (issignalingnan(fs1)) {
1526 panic("Unknown classification for operand.");
1531 0x71: decode ROUND_MODE {
1536 switch (fpclassify(Fs1)) {
1545 if (issignalingnan(Fs1)) {
1573 panic("Unknown classification for operand.");
1579 Fd_bits = (uint64_t)Rs1_uw;
1587 0x18: decode FUNCT3 {
1595 }}, IsDirectControl, IsCondControl);
1602 }}, IsDirectControl, IsCondControl);
1604 if (Rs1_sd < Rs2_sd) {
1609 }}, IsDirectControl, IsCondControl);
1611 if (Rs1_sd >= Rs2_sd) {
1616 }}, IsDirectControl, IsCondControl);
1623 }}, IsDirectControl, IsCondControl);
1630 }}, IsDirectControl, IsCondControl);
1634 0x19: decode FUNCT3 {
1637 NPC = (imm + Rs1) & (~0x1);
1638 }}, IsIndirectControl, IsUncondControl, IsCall);
1644 }}, IsDirectControl, IsUncondControl, IsCall);
1646 0x1c: decode FUNCT3 {
1648 0x0: decode FUNCT12 {
1650 fault = make_shared<SyscallFault>();
1651 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1654 fault = make_shared<BreakpointFault>();
1655 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1657 fault = make_shared<UnimplementedFault>("eret");
1663 Rd = xc->readMiscReg(csr);
1664 xc->setMiscReg(csr, Rs1);
1665 }}, IsNonSpeculative, No_OpClass);
1667 Rd = xc->readMiscReg(csr);
1669 xc->setMiscReg(csr, Rd | Rs1);
1671 }}, IsNonSpeculative, No_OpClass);
1673 Rd = xc->readMiscReg(csr);
1675 xc->setMiscReg(csr, Rd & ~Rs1);
1677 }}, IsNonSpeculative, No_OpClass);
1679 Rd = xc->readMiscReg(csr);
1680 xc->setMiscReg(csr, uimm);
1681 }}, IsNonSpeculative, No_OpClass);
1683 Rd = xc->readMiscReg(csr);
1685 xc->setMiscReg(csr, Rd | uimm);
1687 }}, IsNonSpeculative, No_OpClass);
1689 Rd = xc->readMiscReg(csr);
1691 xc->setMiscReg(csr, Rd & ~uimm);
1693 }}, IsNonSpeculative, No_OpClass);