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",
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);
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;
228 int64_t offset = CJUMPIMM<3:1> << 1 |
235 if (CJUMPIMM<10:10> > 0)
236 offset |= ~((int64_t)0x7FF);
238 }}, IsIndirectControl, IsUncondControl, IsCall);
245 }}, IsDirectControl, IsCondControl);
251 }}, IsDirectControl, IsCondControl);
254 0x2: decode COPCODE {
256 imm = CIMM5 | (CIMM1 << 5);
259 fault = make_shared<IllegalInstFault>("immediate = 0",
263 fault = make_shared<IllegalInstFault>("source reg x0",
268 format CompressedLoad {
270 offset = CIMM5<4:3> << 3 |
279 offset = CIMM5<4:2> << 2 |
284 fault = make_shared<IllegalInstFault>("source reg x0",
292 offset = CIMM5<4:3> << 3 |
297 fault = make_shared<IllegalInstFault>("source reg x0",
305 0x4: decode CFUNCT1 {
309 fault = make_shared<IllegalInstFault>("source reg x0",
313 }}, IsIndirectControl, IsUncondControl, IsCall);
314 default: CROp::c_mv({{
316 fault = make_shared<IllegalInstFault>("source reg x0",
323 0x0: SystemOp::c_ebreak({{
325 fault = make_shared<IllegalInstFault>("source reg x1",
328 fault = make_shared<BreakpointFault>(xc->pcState());
329 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
330 default: decode RC2 {
333 fault = make_shared<IllegalInstFault>
339 }}, IsIndirectControl, IsUncondControl, IsCall);
340 default: ROp::c_add({{
341 Rc1_sd = Rc1_sd + Rc2_sd;
346 format CompressedStore {
348 offset = CIMM6<5:3> << 3 |
356 offset = CIMM6<5:2> << 2 |
364 offset = CIMM6<5:3> << 3 |
374 0x00: decode FUNCT3 {
400 0x01: decode FUNCT3 {
403 Fd_bits = (uint64_t)Mem_uw;
404 }}, inst_flags=FloatMemReadOp);
407 }}, inst_flags=FloatMemReadOp);
411 0x03: decode FUNCT3 {
414 }}, uint64_t, IsMemBarrier, No_OpClass);
416 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
420 0x04: decode FUNCT3 {
423 Rd_sd = Rs1_sd + imm;
429 Rd = (Rs1_sd < imm) ? 1 : 0;
432 Rd = (Rs1 < imm) ? 1 : 0;
442 Rd_sd = Rs1_sd >> SHAMT6;
458 0x06: decode FUNCT3 {
461 Rd_sd = Rs1_sw + imm;
464 Rd_sd = Rs1_sw << SHAMT5;
468 Rd_sd = (int32_t)(Rs1_uw >> SHAMT5);
471 Rd_sd = Rs1_sw >> SHAMT5;
477 0x08: decode FUNCT3 {
494 0x09: decode FUNCT3 {
497 Mem_uw = (uint32_t)Fs2_bits;
498 }}, inst_flags=FloatMemWriteOp);
501 }}, inst_flags=FloatMemWriteOp);
505 0x0b: decode FUNCT3 {
506 0x2: decode AMOFUNCT {
507 0x2: LoadReserved::lr_w({{
510 0x3: StoreCond::sc_w({{
514 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
515 0x0: AtomicMemOp::amoadd_w({{
518 TypedAtomicOpFunctor<int32_t> *amo_op =
519 new AtomicGenericOp<int32_t>(Rs2_sw,
520 [](int32_t* b, int32_t a){ *b += a; });
521 }}, mem_flags=ATOMIC_RETURN_OP);
522 0x1: AtomicMemOp::amoswap_w({{
525 TypedAtomicOpFunctor<uint32_t> *amo_op =
526 new AtomicGenericOp<uint32_t>(Rs2_uw,
527 [](uint32_t* b, uint32_t a){ *b = a; });
528 }}, mem_flags=ATOMIC_RETURN_OP);
529 0x4: AtomicMemOp::amoxor_w({{
532 TypedAtomicOpFunctor<uint32_t> *amo_op =
533 new AtomicGenericOp<uint32_t>(Rs2_uw,
534 [](uint32_t* b, uint32_t a){ *b ^= a; });
535 }}, mem_flags=ATOMIC_RETURN_OP);
536 0x8: AtomicMemOp::amoor_w({{
539 TypedAtomicOpFunctor<uint32_t> *amo_op =
540 new AtomicGenericOp<uint32_t>(Rs2_uw,
541 [](uint32_t* b, uint32_t a){ *b |= a; });
542 }}, mem_flags=ATOMIC_RETURN_OP);
543 0xc: AtomicMemOp::amoand_w({{
546 TypedAtomicOpFunctor<uint32_t> *amo_op =
547 new AtomicGenericOp<uint32_t>(Rs2_uw,
548 [](uint32_t* b, uint32_t a){ *b &= a; });
549 }}, mem_flags=ATOMIC_RETURN_OP);
550 0x10: AtomicMemOp::amomin_w({{
553 TypedAtomicOpFunctor<int32_t> *amo_op =
554 new AtomicGenericOp<int32_t>(Rs2_sw,
555 [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
556 }}, mem_flags=ATOMIC_RETURN_OP);
557 0x14: AtomicMemOp::amomax_w({{
560 TypedAtomicOpFunctor<int32_t> *amo_op =
561 new AtomicGenericOp<int32_t>(Rs2_sw,
562 [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
563 }}, mem_flags=ATOMIC_RETURN_OP);
564 0x18: AtomicMemOp::amominu_w({{
567 TypedAtomicOpFunctor<uint32_t> *amo_op =
568 new AtomicGenericOp<uint32_t>(Rs2_uw,
569 [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
570 }}, mem_flags=ATOMIC_RETURN_OP);
571 0x1c: AtomicMemOp::amomaxu_w({{
574 TypedAtomicOpFunctor<uint32_t> *amo_op =
575 new AtomicGenericOp<uint32_t>(Rs2_uw,
576 [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
577 }}, mem_flags=ATOMIC_RETURN_OP);
579 0x3: decode AMOFUNCT {
580 0x2: LoadReserved::lr_d({{
583 0x3: StoreCond::sc_d({{
587 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
588 0x0: AtomicMemOp::amoadd_d({{
591 TypedAtomicOpFunctor<int64_t> *amo_op =
592 new AtomicGenericOp<int64_t>(Rs2_sd,
593 [](int64_t* b, int64_t a){ *b += a; });
594 }}, mem_flags=ATOMIC_RETURN_OP);
595 0x1: AtomicMemOp::amoswap_d({{
598 TypedAtomicOpFunctor<uint64_t> *amo_op =
599 new AtomicGenericOp<uint64_t>(Rs2_ud,
600 [](uint64_t* b, uint64_t a){ *b = a; });
601 }}, mem_flags=ATOMIC_RETURN_OP);
602 0x4: AtomicMemOp::amoxor_d({{
605 TypedAtomicOpFunctor<uint64_t> *amo_op =
606 new AtomicGenericOp<uint64_t>(Rs2_ud,
607 [](uint64_t* b, uint64_t a){ *b ^= a; });
608 }}, mem_flags=ATOMIC_RETURN_OP);
609 0x8: AtomicMemOp::amoor_d({{
612 TypedAtomicOpFunctor<uint64_t> *amo_op =
613 new AtomicGenericOp<uint64_t>(Rs2_ud,
614 [](uint64_t* b, uint64_t a){ *b |= a; });
615 }}, mem_flags=ATOMIC_RETURN_OP);
616 0xc: AtomicMemOp::amoand_d({{
619 TypedAtomicOpFunctor<uint64_t> *amo_op =
620 new AtomicGenericOp<uint64_t>(Rs2_ud,
621 [](uint64_t* b, uint64_t a){ *b &= a; });
622 }}, mem_flags=ATOMIC_RETURN_OP);
623 0x10: AtomicMemOp::amomin_d({{
626 TypedAtomicOpFunctor<int64_t> *amo_op =
627 new AtomicGenericOp<int64_t>(Rs2_sd,
628 [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
629 }}, mem_flags=ATOMIC_RETURN_OP);
630 0x14: AtomicMemOp::amomax_d({{
633 TypedAtomicOpFunctor<int64_t> *amo_op =
634 new AtomicGenericOp<int64_t>(Rs2_sd,
635 [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
636 }}, mem_flags=ATOMIC_RETURN_OP);
637 0x18: AtomicMemOp::amominu_d({{
640 TypedAtomicOpFunctor<uint64_t> *amo_op =
641 new AtomicGenericOp<uint64_t>(Rs2_ud,
642 [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
643 }}, mem_flags=ATOMIC_RETURN_OP);
644 0x1c: AtomicMemOp::amomaxu_d({{
647 TypedAtomicOpFunctor<uint64_t> *amo_op =
648 new AtomicGenericOp<uint64_t>(Rs2_ud,
649 [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
650 }}, mem_flags=ATOMIC_RETURN_OP);
653 0x0c: decode FUNCT3 {
657 Rd = Rs1_sd + Rs2_sd;
663 Rd = Rs1_sd - Rs2_sd;
668 Rd = Rs1 << Rs2<5:0>;
671 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
673 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
674 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
675 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
676 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
678 uint64_t hi = Rs1_hi*Rs2_hi;
679 uint64_t mid1 = Rs1_hi*Rs2_lo;
680 uint64_t mid2 = Rs1_lo*Rs2_hi;
681 uint64_t lo = Rs2_lo*Rs1_lo;
682 uint64_t carry = ((uint64_t)(uint32_t)mid1
683 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
689 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
695 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
698 bool negate = Rs1_sd < 0;
699 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
700 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
701 uint64_t Rs2_lo = (uint32_t)Rs2;
702 uint64_t Rs2_hi = Rs2 >> 32;
704 uint64_t hi = Rs1_hi*Rs2_hi;
705 uint64_t mid1 = Rs1_hi*Rs2_lo;
706 uint64_t mid2 = Rs1_lo*Rs2_hi;
707 uint64_t lo = Rs1_lo*Rs2_lo;
708 uint64_t carry = ((uint64_t)(uint32_t)mid1
709 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
715 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
720 Rd = (Rs1 < Rs2) ? 1 : 0;
723 uint64_t Rs1_lo = (uint32_t)Rs1;
724 uint64_t Rs1_hi = Rs1 >> 32;
725 uint64_t Rs2_lo = (uint32_t)Rs2;
726 uint64_t Rs2_hi = Rs2 >> 32;
728 uint64_t hi = Rs1_hi*Rs2_hi;
729 uint64_t mid1 = Rs1_hi*Rs2_lo;
730 uint64_t mid2 = Rs1_lo*Rs2_hi;
731 uint64_t lo = Rs1_lo*Rs2_lo;
732 uint64_t carry = ((uint64_t)(uint32_t)mid1
733 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
735 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
745 } else if (Rs1_sd == numeric_limits<int64_t>::min()
747 Rd_sd = numeric_limits<int64_t>::min();
749 Rd_sd = Rs1_sd/Rs2_sd;
755 Rd = Rs1 >> Rs2<5:0>;
759 Rd = numeric_limits<uint64_t>::max();
765 Rd_sd = Rs1_sd >> Rs2<5:0>;
775 } else if (Rs1_sd == numeric_limits<int64_t>::min()
802 0x0e: decode FUNCT3 {
806 Rd_sd = Rs1_sw + Rs2_sw;
809 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
812 Rd_sd = Rs1_sw - Rs2_sw;
816 Rd_sd = Rs1_sw << Rs2<4:0>;
821 } else if (Rs1_sw == numeric_limits<int32_t>::min()
823 Rd_sd = numeric_limits<int32_t>::min();
825 Rd_sd = Rs1_sw/Rs2_sw;
830 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
834 Rd_sd = numeric_limits<uint64_t>::max();
836 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
840 Rd_sd = Rs1_sw >> Rs2<4:0>;
846 } else if (Rs1_sw == numeric_limits<int32_t>::min()
850 Rd_sd = Rs1_sw%Rs2_sw;
855 Rd_sd = (int32_t)Rs1_uw;
857 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
864 0x10: decode FUNCT2 {
867 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
868 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
869 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
872 if (std::isnan(fs1) || std::isnan(fs2) ||
874 if (issignalingnan(fs1) || issignalingnan(fs2)
875 || issignalingnan(fs3)) {
876 FFLAGS |= FloatInvalid;
878 fd = numeric_limits<float>::quiet_NaN();
879 } else if (std::isinf(fs1) || std::isinf(fs2) ||
881 if (signbit(fs1) == signbit(fs2)
882 && !std::isinf(fs3)) {
883 fd = numeric_limits<float>::infinity();
884 } else if (signbit(fs1) != signbit(fs2)
885 && !std::isinf(fs3)) {
886 fd = -numeric_limits<float>::infinity();
887 } else { // Fs3_sf is infinity
893 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
896 if (std::isnan(Fs1) || std::isnan(Fs2) ||
898 if (issignalingnan(Fs1) || issignalingnan(Fs2)
899 || issignalingnan(Fs3)) {
900 FFLAGS |= FloatInvalid;
902 Fd = numeric_limits<double>::quiet_NaN();
903 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
905 if (signbit(Fs1) == signbit(Fs2)
906 && !std::isinf(Fs3)) {
907 Fd = numeric_limits<double>::infinity();
908 } else if (signbit(Fs1) != signbit(Fs2)
909 && !std::isinf(Fs3)) {
910 Fd = -numeric_limits<double>::infinity();
919 0x11: decode FUNCT2 {
922 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
923 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
924 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
927 if (std::isnan(fs1) || std::isnan(fs2) ||
929 if (issignalingnan(fs1) || issignalingnan(fs2)
930 || issignalingnan(fs3)) {
931 FFLAGS |= FloatInvalid;
933 fd = numeric_limits<float>::quiet_NaN();
934 } else if (std::isinf(fs1) || std::isinf(fs2) ||
936 if (signbit(fs1) == signbit(fs2)
937 && !std::isinf(fs3)) {
938 fd = numeric_limits<float>::infinity();
939 } else if (signbit(fs1) != signbit(fs2)
940 && !std::isinf(fs3)) {
941 fd = -numeric_limits<float>::infinity();
942 } else { // Fs3_sf is infinity
948 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
951 if (std::isnan(Fs1) || std::isnan(Fs2) ||
953 if (issignalingnan(Fs1) || issignalingnan(Fs2)
954 || issignalingnan(Fs3)) {
955 FFLAGS |= FloatInvalid;
957 Fd = numeric_limits<double>::quiet_NaN();
958 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
960 if (signbit(Fs1) == signbit(Fs2)
961 && !std::isinf(Fs3)) {
962 Fd = numeric_limits<double>::infinity();
963 } else if (signbit(Fs1) != signbit(Fs2)
964 && !std::isinf(Fs3)) {
965 Fd = -numeric_limits<double>::infinity();
974 0x12: decode FUNCT2 {
977 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
978 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
979 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
982 if (std::isnan(fs1) || std::isnan(fs2) ||
984 if (issignalingnan(fs1) || issignalingnan(fs2)
985 || issignalingnan(fs3)) {
986 FFLAGS |= FloatInvalid;
988 fd = numeric_limits<float>::quiet_NaN();
989 } else if (std::isinf(fs1) || std::isinf(fs2) ||
991 if (signbit(fs1) == signbit(fs2)
992 && !std::isinf(fs3)) {
993 fd = -numeric_limits<float>::infinity();
994 } else if (signbit(fs1) != signbit(fs2)
995 && !std::isinf(fs3)) {
996 fd = numeric_limits<float>::infinity();
997 } else { // Fs3_sf is infinity
1001 fd = -(fs1*fs2 - fs3);
1003 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1004 }}, FloatMultAccOp);
1006 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1008 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1009 || issignalingnan(Fs3)) {
1010 FFLAGS |= FloatInvalid;
1012 Fd = numeric_limits<double>::quiet_NaN();
1013 } else if (std::isinf(Fs1) || std::isinf(Fs2)
1014 || std::isinf(Fs3)) {
1015 if (signbit(Fs1) == signbit(Fs2)
1016 && !std::isinf(Fs3)) {
1017 Fd = -numeric_limits<double>::infinity();
1018 } else if (signbit(Fs1) != signbit(Fs2)
1019 && !std::isinf(Fs3)) {
1020 Fd = numeric_limits<double>::infinity();
1025 Fd = -(Fs1*Fs2 - Fs3);
1027 }}, FloatMultAccOp);
1029 0x13: decode FUNCT2 {
1032 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1033 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1034 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1037 if (std::isnan(fs1) || std::isnan(fs2) ||
1039 if (issignalingnan(fs1) || issignalingnan(fs2)
1040 || issignalingnan(fs3)) {
1041 FFLAGS |= FloatInvalid;
1043 fd = numeric_limits<float>::quiet_NaN();
1044 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1046 if (signbit(fs1) == signbit(fs2)
1047 && !std::isinf(fs3)) {
1048 fd = -numeric_limits<float>::infinity();
1049 } else if (signbit(fs1) != signbit(fs2)
1050 && !std::isinf(fs3)) {
1051 fd = numeric_limits<float>::infinity();
1052 } else { // Fs3_sf is infinity
1056 fd = -(fs1*fs2 + fs3);
1058 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1059 }}, FloatMultAccOp);
1061 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1063 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1064 || issignalingnan(Fs3)) {
1065 FFLAGS |= FloatInvalid;
1067 Fd = numeric_limits<double>::quiet_NaN();
1068 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1070 if (signbit(Fs1) == signbit(Fs2)
1071 && !std::isinf(Fs3)) {
1072 Fd = -numeric_limits<double>::infinity();
1073 } else if (signbit(Fs1) != signbit(Fs2)
1074 && !std::isinf(Fs3)) {
1075 Fd = numeric_limits<double>::infinity();
1080 Fd = -(Fs1*Fs2 + Fs3);
1082 }}, FloatMultAccOp);
1084 0x14: decode FUNCT7 {
1087 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1088 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1091 if (std::isnan(fs1) || std::isnan(fs2)) {
1092 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1093 FFLAGS |= FloatInvalid;
1095 fd = numeric_limits<float>::quiet_NaN();
1099 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1102 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1103 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1104 FFLAGS |= FloatInvalid;
1106 Fd = numeric_limits<double>::quiet_NaN();
1113 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1114 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1117 if (std::isnan(fs1) || std::isnan(fs2)) {
1118 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1119 FFLAGS |= FloatInvalid;
1121 fd = numeric_limits<float>::quiet_NaN();
1125 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1128 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1129 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1130 FFLAGS |= FloatInvalid;
1132 Fd = numeric_limits<double>::quiet_NaN();
1139 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1140 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1143 if (std::isnan(fs1) || std::isnan(fs2)) {
1144 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1145 FFLAGS |= FloatInvalid;
1147 fd = numeric_limits<float>::quiet_NaN();
1151 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1154 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1155 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1156 FFLAGS |= FloatInvalid;
1158 Fd = numeric_limits<double>::quiet_NaN();
1165 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1166 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1169 if (std::isnan(fs1) || std::isnan(fs2)) {
1170 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1171 FFLAGS |= FloatInvalid;
1173 fd = numeric_limits<float>::quiet_NaN();
1177 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1180 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1181 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1182 FFLAGS |= FloatInvalid;
1184 Fd = numeric_limits<double>::quiet_NaN();
1189 0x10: decode ROUND_MODE {
1192 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1193 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1196 if (issignalingnan(fs1)) {
1197 fd = numeric_limits<float>::signaling_NaN();
1198 feclearexcept(FE_INVALID);
1200 fd = copysign(fs1, fs2);
1202 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1206 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1207 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1210 if (issignalingnan(fs1)) {
1211 fd = numeric_limits<float>::signaling_NaN();
1212 feclearexcept(FE_INVALID);
1214 fd = copysign(fs1, -fs2);
1216 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1220 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1221 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1224 if (issignalingnan(fs1)) {
1225 fd = numeric_limits<float>::signaling_NaN();
1226 feclearexcept(FE_INVALID);
1228 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1230 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1233 0x11: decode ROUND_MODE {
1235 if (issignalingnan(Fs1)) {
1236 Fd = numeric_limits<double>::signaling_NaN();
1237 feclearexcept(FE_INVALID);
1239 Fd = copysign(Fs1, Fs2);
1243 if (issignalingnan(Fs1)) {
1244 Fd = numeric_limits<double>::signaling_NaN();
1245 feclearexcept(FE_INVALID);
1247 Fd = copysign(Fs1, -Fs2);
1251 if (issignalingnan(Fs1)) {
1252 Fd = numeric_limits<double>::signaling_NaN();
1253 feclearexcept(FE_INVALID);
1255 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1259 0x14: decode ROUND_MODE {
1262 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1263 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1266 if (issignalingnan(fs2)) {
1268 FFLAGS |= FloatInvalid;
1269 } else if (issignalingnan(fs1)) {
1271 FFLAGS |= FloatInvalid;
1273 fd = fmin(fs1, fs2);
1275 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1279 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1280 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1283 if (issignalingnan(fs2)) {
1285 FFLAGS |= FloatInvalid;
1286 } else if (issignalingnan(fs1)) {
1288 FFLAGS |= FloatInvalid;
1290 fd = fmax(fs1, fs2);
1292 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1295 0x15: decode ROUND_MODE {
1297 if (issignalingnan(Fs2)) {
1299 FFLAGS |= FloatInvalid;
1300 } else if (issignalingnan(Fs1)) {
1302 FFLAGS |= FloatInvalid;
1304 Fd = fmin(Fs1, Fs2);
1308 if (issignalingnan(Fs2)) {
1310 FFLAGS |= FloatInvalid;
1311 } else if (issignalingnan(Fs1)) {
1313 FFLAGS |= FloatInvalid;
1315 Fd = fmax(Fs1, Fs2);
1320 if (CONV_SGN != 1) {
1321 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1325 if (issignalingnan(Fs1)) {
1326 fd = numeric_limits<float>::quiet_NaN();
1327 FFLAGS |= FloatInvalid;
1331 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1334 if (CONV_SGN != 0) {
1335 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1339 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1341 if (issignalingnan(fs1)) {
1342 Fd = numeric_limits<double>::quiet_NaN();
1343 FFLAGS |= FloatInvalid;
1350 fault = make_shared<IllegalInstFault>("source reg x1",
1354 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1357 if (issignalingnan(Fs1_sf)) {
1358 FFLAGS |= FloatInvalid;
1361 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1365 fault = make_shared<IllegalInstFault>("source reg x1",
1370 0x50: decode ROUND_MODE {
1373 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1374 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1376 if (std::isnan(fs1) || std::isnan(fs2)) {
1377 FFLAGS |= FloatInvalid;
1380 Rd = fs1 <= fs2 ? 1 : 0;
1385 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1386 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1388 if (std::isnan(fs1) || std::isnan(fs2)) {
1389 FFLAGS |= FloatInvalid;
1392 Rd = fs1 < fs2 ? 1 : 0;
1397 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1398 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1400 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1401 FFLAGS |= FloatInvalid;
1403 Rd = fs1 == fs2 ? 1 : 0;
1406 0x51: decode ROUND_MODE {
1408 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1409 FFLAGS |= FloatInvalid;
1412 Rd = Fs1 <= Fs2 ? 1 : 0;
1416 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1417 FFLAGS |= FloatInvalid;
1420 Rd = Fs1 < Fs2 ? 1 : 0;
1424 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1425 FFLAGS |= FloatInvalid;
1427 Rd = Fs1 == Fs2 ? 1 : 0;
1430 0x60: decode CONV_SGN {
1433 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1435 if (std::isnan(fs1)) {
1436 Rd_sd = numeric_limits<int32_t>::max();
1437 FFLAGS |= FloatInvalid;
1438 } else if (fs1 >= numeric_limits<int32_t>::max()) {
1439 Rd_sd = numeric_limits<int32_t>::max();
1440 FFLAGS |= FloatInvalid;
1441 } else if (fs1 <= numeric_limits<int32_t>::min()) {
1442 Rd_sd = numeric_limits<int32_t>::min();
1443 FFLAGS |= FloatInvalid;
1445 Rd_sd = (int32_t)fs1;
1450 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1452 if (std::isnan(fs1)) {
1453 Rd = numeric_limits<uint64_t>::max();
1454 FFLAGS |= FloatInvalid;
1455 } else if (fs1 < 0.0) {
1457 FFLAGS |= FloatInvalid;
1458 } else if (fs1 > numeric_limits<uint32_t>::max()) {
1459 Rd = numeric_limits<uint64_t>::max();
1460 FFLAGS |= FloatInvalid;
1467 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1469 if (std::isnan(fs1)) {
1470 Rd_sd = numeric_limits<int64_t>::max();
1471 FFLAGS |= FloatInvalid;
1472 } else if (fs1 > numeric_limits<int64_t>::max()) {
1473 Rd_sd = numeric_limits<int64_t>::max();
1474 FFLAGS |= FloatInvalid;
1475 } else if (fs1 < numeric_limits<int64_t>::min()) {
1476 Rd_sd = numeric_limits<int64_t>::min();
1477 FFLAGS |= FloatInvalid;
1479 Rd_sd = (int64_t)fs1;
1484 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1486 if (std::isnan(fs1)) {
1487 Rd = numeric_limits<uint64_t>::max();
1488 FFLAGS |= FloatInvalid;
1489 } else if (fs1 < 0.0) {
1491 FFLAGS |= FloatInvalid;
1492 } else if (fs1 > numeric_limits<uint64_t>::max()) {
1493 Rd = numeric_limits<uint64_t>::max();
1494 FFLAGS |= FloatInvalid;
1500 0x61: decode CONV_SGN {
1502 if (std::isnan(Fs1)) {
1503 Rd_sd = numeric_limits<int32_t>::max();
1504 FFLAGS |= FloatInvalid;
1505 } else if (Fs1 > numeric_limits<int32_t>::max()) {
1506 Rd_sd = numeric_limits<int32_t>::max();
1507 FFLAGS |= FloatInvalid;
1508 } else if (Fs1 < numeric_limits<int32_t>::min()) {
1509 Rd_sd = numeric_limits<int32_t>::min();
1510 FFLAGS |= FloatInvalid;
1512 Rd_sd = (int32_t)Fs1;
1516 if (std::isnan(Fs1)) {
1517 Rd = numeric_limits<uint64_t>::max();
1518 FFLAGS |= FloatInvalid;
1519 } else if (Fs1 < 0) {
1521 FFLAGS |= FloatInvalid;
1522 } else if (Fs1 > 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;
1533 } else if (Fs1 > numeric_limits<int64_t>::max()) {
1534 Rd_sd = numeric_limits<int64_t>::max();
1535 FFLAGS |= FloatInvalid;
1536 } else if (Fs1 < 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;
1550 } else if (Fs1 > numeric_limits<uint64_t>::max()) {
1551 Rd = numeric_limits<uint64_t>::max();
1552 FFLAGS |= FloatInvalid;
1558 0x68: decode CONV_SGN {
1560 float temp = (float)Rs1_sw;
1561 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1564 float temp = (float)Rs1_uw;
1565 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1568 float temp = (float)Rs1_sd;
1569 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1572 float temp = (float)Rs1;
1573 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1576 0x69: decode CONV_SGN {
1578 Fd = (double)Rs1_sw;
1581 Fd = (double)Rs1_uw;
1584 Fd = (double)Rs1_sd;
1590 0x70: decode ROUND_MODE {
1592 Rd = (uint32_t)Fs1_bits;
1593 if ((Rd&0x80000000) != 0) {
1594 Rd |= (0xFFFFFFFFULL << 32);
1599 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1600 switch (fpclassify(fs1)) {
1609 if (issignalingnan(fs1)) {
1637 panic("Unknown classification for operand.");
1642 0x71: decode ROUND_MODE {
1647 switch (fpclassify(Fs1)) {
1656 if (issignalingnan(Fs1)) {
1684 panic("Unknown classification for operand.");
1690 Fd_bits = (uint64_t)Rs1_uw;
1698 0x18: decode FUNCT3 {
1706 }}, IsDirectControl, IsCondControl);
1713 }}, IsDirectControl, IsCondControl);
1715 if (Rs1_sd < Rs2_sd) {
1720 }}, IsDirectControl, IsCondControl);
1722 if (Rs1_sd >= Rs2_sd) {
1727 }}, IsDirectControl, IsCondControl);
1734 }}, IsDirectControl, IsCondControl);
1741 }}, IsDirectControl, IsCondControl);
1745 0x19: decode FUNCT3 {
1748 NPC = (imm + Rs1) & (~0x1);
1749 }}, IsIndirectControl, IsUncondControl, IsCall);
1755 }}, IsDirectControl, IsUncondControl, IsCall);
1757 0x1c: decode FUNCT3 {
1759 0x0: decode FUNCT12 {
1761 fault = make_shared<SyscallFault>(
1762 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1763 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1766 fault = make_shared<BreakpointFault>(xc->pcState());
1767 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1769 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1770 status.uie = status.upie;
1772 xc->setMiscReg(MISCREG_STATUS, status);
1773 NPC = xc->readMiscReg(MISCREG_UEPC);
1776 if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1777 fault = make_shared<IllegalInstFault>(
1778 "sret in user mode", machInst);
1781 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1782 xc->setMiscReg(MISCREG_PRV, status.spp);
1783 status.sie = status.spie;
1786 xc->setMiscReg(MISCREG_STATUS, status);
1787 NPC = xc->readMiscReg(MISCREG_SEPC);
1791 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1792 fault = make_shared<IllegalInstFault>(
1793 "mret at lower privilege", machInst);
1796 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1797 xc->setMiscReg(MISCREG_PRV, status.mpp);
1798 status.mie = status.mpie;
1801 xc->setMiscReg(MISCREG_STATUS, status);
1802 NPC = xc->readMiscReg(MISCREG_MEPC);
1811 }}, IsNonSpeculative, No_OpClass);
1815 }}, IsNonSpeculative, No_OpClass);
1819 }}, IsNonSpeculative, No_OpClass);
1823 }}, IsNonSpeculative, No_OpClass);
1827 }}, IsNonSpeculative, No_OpClass);
1831 }}, IsNonSpeculative, No_OpClass);