3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2017 The University of Virginia
5 // Copyright (c) 2020 Barkhausen Institut
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met: redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer;
12 // redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution;
15 // neither the name of the copyright holders nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ////////////////////////////////////////////////////////////////////
33 // The RISC-V ISA decoder
36 decode QUADRANT default Unknown::unknown() {
38 0x0: CIAddi4spnOp::c_addi4spn({{
39 imm = CIMM8<1:1> << 2 |
45 fault = make_shared<IllegalInstFault>("zero instruction",
49 format CompressedLoad {
51 offset = CIMM3 << 3 | CIMM2 << 6;
53 STATUS status = xc->readMiscReg(MISCREG_STATUS);
54 if (status.fs == FPUStatus::OFF)
55 fault = make_shared<IllegalInstFault>("FPU is off",
63 offset = CIMM2<1:1> << 2 |
72 offset = CIMM3 << 3 | CIMM2 << 6;
79 format CompressedStore {
81 offset = CIMM3 << 3 | CIMM2 << 6;
83 STATUS status = xc->readMiscReg(MISCREG_STATUS);
84 if (status.fs == FPUStatus::OFF)
85 fault = make_shared<IllegalInstFault>("FPU is off",
93 offset = CIMM2<1:1> << 2 |
102 offset = CIMM3 << 3 | CIMM2 << 6;
110 0x1: decode COPCODE {
115 imm |= ~((uint64_t)0x1F);
117 if ((RC1 == 0) != (imm == 0)) {
119 fault = make_shared<IllegalInstFault>("source reg x0",
122 fault = make_shared<IllegalInstFault>("immediate = 0",
125 Rc1_sd = Rc1_sd + imm;
130 imm |= ~((uint64_t)0x1F);
133 fault = make_shared<IllegalInstFault>("source reg x0",
136 Rc1_sd = (int32_t)Rc1_sd + imm;
141 imm |= ~((uint64_t)0x1F);
144 fault = make_shared<IllegalInstFault>("source reg x0",
151 imm = CIMM5<4:4> << 4 |
156 imm |= ~((int64_t)0x1FF);
159 fault = make_shared<IllegalInstFault>("immediate = 0",
167 imm |= ~((uint64_t)0x1FFFF);
169 if (RC1 == 0 || RC1 == 2) {
170 fault = make_shared<IllegalInstFault>("source reg x0",
174 fault = make_shared<IllegalInstFault>("immediate = 0",
181 0x4: decode CFUNCT2HIGH {
184 imm = CIMM5 | (CIMM1 << 5);
187 fault = make_shared<IllegalInstFault>("immediate = 0",
193 imm = CIMM5 | (CIMM1 << 5);
196 fault = make_shared<IllegalInstFault>("immediate = 0",
199 Rp1_sd = Rp1_sd >> imm;
204 imm |= ~((uint64_t)0x1F);
209 format CompressedROp {
210 0x3: decode CFUNCT1 {
211 0x0: decode CFUNCT2LOW {
225 0x1: decode CFUNCT2LOW {
227 Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
230 Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
238 }}, IsDirectControl, IsUncondControl);
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: CompressedROp::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 STATUS status = xc->readMiscReg(MISCREG_STATUS);
404 if (status.fs == FPUStatus::OFF)
405 fault = make_shared<IllegalInstFault>("FPU is off",
408 Fd_bits = (uint64_t)Mem_uw;
409 }}, inst_flags=FloatMemReadOp);
411 STATUS status = xc->readMiscReg(MISCREG_STATUS);
412 if (status.fs == FPUStatus::OFF)
413 fault = make_shared<IllegalInstFault>("FPU is off",
417 }}, inst_flags=FloatMemReadOp);
421 0x03: decode FUNCT3 {
424 }}, uint64_t, IsReadBarrier, IsWriteBarrier, No_OpClass);
426 }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
430 0x04: decode FUNCT3 {
433 Rd_sd = Rs1_sd + imm;
437 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
439 Rd = (Rs1_sd < imm) ? 1 : 0;
442 Rd = (Rs1 < imm) ? 1 : 0;
450 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
452 Rd_sd = Rs1_sd >> imm;
453 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
465 Rd = PC + (sext<20>(imm) << 12);
468 0x06: decode FUNCT3 {
471 Rd_sd = Rs1_sw + imm;
474 Rd_sd = Rs1_sw << imm;
475 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
478 Rd_sd = (int32_t)(Rs1_uw >> imm);
479 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
481 Rd_sd = Rs1_sw >> imm;
482 }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
487 0x08: decode FUNCT3 {
504 0x09: decode FUNCT3 {
507 STATUS status = xc->readMiscReg(MISCREG_STATUS);
508 if (status.fs == FPUStatus::OFF)
509 fault = make_shared<IllegalInstFault>("FPU is off",
512 Mem_uw = (uint32_t)Fs2_bits;
513 }}, inst_flags=FloatMemWriteOp);
515 STATUS status = xc->readMiscReg(MISCREG_STATUS);
516 if (status.fs == FPUStatus::OFF)
517 fault = make_shared<IllegalInstFault>("FPU is off",
521 }}, inst_flags=FloatMemWriteOp);
525 0x0b: decode FUNCT3 {
526 0x2: decode AMOFUNCT {
527 0x2: LoadReserved::lr_w({{
530 0x3: StoreCond::sc_w({{
534 }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
535 0x0: AtomicMemOp::amoadd_w({{
538 TypedAtomicOpFunctor<int32_t> *amo_op =
539 new AtomicGenericOp<int32_t>(Rs2_sw,
540 [](int32_t* b, int32_t a){ *b += a; });
541 }}, mem_flags=ATOMIC_RETURN_OP);
542 0x1: AtomicMemOp::amoswap_w({{
545 TypedAtomicOpFunctor<uint32_t> *amo_op =
546 new AtomicGenericOp<uint32_t>(Rs2_uw,
547 [](uint32_t* b, uint32_t a){ *b = a; });
548 }}, mem_flags=ATOMIC_RETURN_OP);
549 0x4: AtomicMemOp::amoxor_w({{
552 TypedAtomicOpFunctor<uint32_t> *amo_op =
553 new AtomicGenericOp<uint32_t>(Rs2_uw,
554 [](uint32_t* b, uint32_t a){ *b ^= a; });
555 }}, mem_flags=ATOMIC_RETURN_OP);
556 0x8: AtomicMemOp::amoor_w({{
559 TypedAtomicOpFunctor<uint32_t> *amo_op =
560 new AtomicGenericOp<uint32_t>(Rs2_uw,
561 [](uint32_t* b, uint32_t a){ *b |= a; });
562 }}, mem_flags=ATOMIC_RETURN_OP);
563 0xc: AtomicMemOp::amoand_w({{
566 TypedAtomicOpFunctor<uint32_t> *amo_op =
567 new AtomicGenericOp<uint32_t>(Rs2_uw,
568 [](uint32_t* b, uint32_t a){ *b &= a; });
569 }}, mem_flags=ATOMIC_RETURN_OP);
570 0x10: AtomicMemOp::amomin_w({{
573 TypedAtomicOpFunctor<int32_t> *amo_op =
574 new AtomicGenericOp<int32_t>(Rs2_sw,
575 [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
576 }}, mem_flags=ATOMIC_RETURN_OP);
577 0x14: AtomicMemOp::amomax_w({{
580 TypedAtomicOpFunctor<int32_t> *amo_op =
581 new AtomicGenericOp<int32_t>(Rs2_sw,
582 [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
583 }}, mem_flags=ATOMIC_RETURN_OP);
584 0x18: AtomicMemOp::amominu_w({{
587 TypedAtomicOpFunctor<uint32_t> *amo_op =
588 new AtomicGenericOp<uint32_t>(Rs2_uw,
589 [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
590 }}, mem_flags=ATOMIC_RETURN_OP);
591 0x1c: AtomicMemOp::amomaxu_w({{
594 TypedAtomicOpFunctor<uint32_t> *amo_op =
595 new AtomicGenericOp<uint32_t>(Rs2_uw,
596 [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
597 }}, mem_flags=ATOMIC_RETURN_OP);
599 0x3: decode AMOFUNCT {
600 0x2: LoadReserved::lr_d({{
603 0x3: StoreCond::sc_d({{
607 }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
608 0x0: AtomicMemOp::amoadd_d({{
611 TypedAtomicOpFunctor<int64_t> *amo_op =
612 new AtomicGenericOp<int64_t>(Rs2_sd,
613 [](int64_t* b, int64_t a){ *b += a; });
614 }}, mem_flags=ATOMIC_RETURN_OP);
615 0x1: AtomicMemOp::amoswap_d({{
618 TypedAtomicOpFunctor<uint64_t> *amo_op =
619 new AtomicGenericOp<uint64_t>(Rs2_ud,
620 [](uint64_t* b, uint64_t a){ *b = a; });
621 }}, mem_flags=ATOMIC_RETURN_OP);
622 0x4: AtomicMemOp::amoxor_d({{
625 TypedAtomicOpFunctor<uint64_t> *amo_op =
626 new AtomicGenericOp<uint64_t>(Rs2_ud,
627 [](uint64_t* b, uint64_t a){ *b ^= a; });
628 }}, mem_flags=ATOMIC_RETURN_OP);
629 0x8: AtomicMemOp::amoor_d({{
632 TypedAtomicOpFunctor<uint64_t> *amo_op =
633 new AtomicGenericOp<uint64_t>(Rs2_ud,
634 [](uint64_t* b, uint64_t a){ *b |= a; });
635 }}, mem_flags=ATOMIC_RETURN_OP);
636 0xc: AtomicMemOp::amoand_d({{
639 TypedAtomicOpFunctor<uint64_t> *amo_op =
640 new AtomicGenericOp<uint64_t>(Rs2_ud,
641 [](uint64_t* b, uint64_t a){ *b &= a; });
642 }}, mem_flags=ATOMIC_RETURN_OP);
643 0x10: AtomicMemOp::amomin_d({{
646 TypedAtomicOpFunctor<int64_t> *amo_op =
647 new AtomicGenericOp<int64_t>(Rs2_sd,
648 [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
649 }}, mem_flags=ATOMIC_RETURN_OP);
650 0x14: AtomicMemOp::amomax_d({{
653 TypedAtomicOpFunctor<int64_t> *amo_op =
654 new AtomicGenericOp<int64_t>(Rs2_sd,
655 [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
656 }}, mem_flags=ATOMIC_RETURN_OP);
657 0x18: AtomicMemOp::amominu_d({{
660 TypedAtomicOpFunctor<uint64_t> *amo_op =
661 new AtomicGenericOp<uint64_t>(Rs2_ud,
662 [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
663 }}, mem_flags=ATOMIC_RETURN_OP);
664 0x1c: AtomicMemOp::amomaxu_d({{
667 TypedAtomicOpFunctor<uint64_t> *amo_op =
668 new AtomicGenericOp<uint64_t>(Rs2_ud,
669 [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
670 }}, mem_flags=ATOMIC_RETURN_OP);
673 0x0c: decode FUNCT3 {
677 Rd = Rs1_sd + Rs2_sd;
683 Rd = Rs1_sd - Rs2_sd;
688 Rd = Rs1 << Rs2<5:0>;
691 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
693 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
694 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
695 uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
696 uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
698 uint64_t hi = Rs1_hi*Rs2_hi;
699 uint64_t mid1 = Rs1_hi*Rs2_lo;
700 uint64_t mid2 = Rs1_lo*Rs2_hi;
701 uint64_t lo = Rs2_lo*Rs1_lo;
702 uint64_t carry = ((uint64_t)(uint32_t)mid1
703 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
709 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
715 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
718 bool negate = Rs1_sd < 0;
719 uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
720 uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
721 uint64_t Rs2_lo = (uint32_t)Rs2;
722 uint64_t Rs2_hi = Rs2 >> 32;
724 uint64_t hi = Rs1_hi*Rs2_hi;
725 uint64_t mid1 = Rs1_hi*Rs2_lo;
726 uint64_t mid2 = Rs1_lo*Rs2_hi;
727 uint64_t lo = Rs1_lo*Rs2_lo;
728 uint64_t carry = ((uint64_t)(uint32_t)mid1
729 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
735 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
740 Rd = (Rs1 < Rs2) ? 1 : 0;
743 uint64_t Rs1_lo = (uint32_t)Rs1;
744 uint64_t Rs1_hi = Rs1 >> 32;
745 uint64_t Rs2_lo = (uint32_t)Rs2;
746 uint64_t Rs2_hi = Rs2 >> 32;
748 uint64_t hi = Rs1_hi*Rs2_hi;
749 uint64_t mid1 = Rs1_hi*Rs2_lo;
750 uint64_t mid2 = Rs1_lo*Rs2_hi;
751 uint64_t lo = Rs1_lo*Rs2_lo;
752 uint64_t carry = ((uint64_t)(uint32_t)mid1
753 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
755 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
765 } else if (Rs1_sd == numeric_limits<int64_t>::min()
767 Rd_sd = numeric_limits<int64_t>::min();
769 Rd_sd = Rs1_sd/Rs2_sd;
775 Rd = Rs1 >> Rs2<5:0>;
779 Rd = numeric_limits<uint64_t>::max();
785 Rd_sd = Rs1_sd >> Rs2<5:0>;
795 } else if (Rs1_sd == numeric_limits<int64_t>::min()
819 Rd = (uint64_t)(sext<20>(imm) << 12);
822 0x0e: decode FUNCT3 {
826 Rd_sd = Rs1_sw + Rs2_sw;
829 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
832 Rd_sd = Rs1_sw - Rs2_sw;
836 Rd_sd = Rs1_sw << Rs2<4:0>;
841 } else if (Rs1_sw == numeric_limits<int32_t>::min()
843 Rd_sd = numeric_limits<int32_t>::min();
845 Rd_sd = Rs1_sw/Rs2_sw;
850 Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
854 Rd_sd = numeric_limits<uint64_t>::max();
856 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
860 Rd_sd = Rs1_sw >> Rs2<4:0>;
866 } else if (Rs1_sw == numeric_limits<int32_t>::min()
870 Rd_sd = Rs1_sw%Rs2_sw;
875 Rd_sd = (int32_t)Rs1_uw;
877 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
884 0x10: decode FUNCT2 {
887 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
888 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
889 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
892 if (std::isnan(fs1) || std::isnan(fs2) ||
894 if (issignalingnan(fs1) || issignalingnan(fs2)
895 || issignalingnan(fs3)) {
896 FFLAGS |= FloatInvalid;
898 fd = numeric_limits<float>::quiet_NaN();
899 } else if (std::isinf(fs1) || std::isinf(fs2) ||
901 if (signbit(fs1) == signbit(fs2)
902 && !std::isinf(fs3)) {
903 fd = numeric_limits<float>::infinity();
904 } else if (signbit(fs1) != signbit(fs2)
905 && !std::isinf(fs3)) {
906 fd = -numeric_limits<float>::infinity();
907 } else { // Fs3_sf is infinity
913 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
916 if (std::isnan(Fs1) || std::isnan(Fs2) ||
918 if (issignalingnan(Fs1) || issignalingnan(Fs2)
919 || issignalingnan(Fs3)) {
920 FFLAGS |= FloatInvalid;
922 Fd = numeric_limits<double>::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<double>::infinity();
928 } else if (signbit(Fs1) != signbit(Fs2)
929 && !std::isinf(Fs3)) {
930 Fd = -numeric_limits<double>::infinity();
939 0x11: decode FUNCT2 {
942 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
943 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
944 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
947 if (std::isnan(fs1) || std::isnan(fs2) ||
949 if (issignalingnan(fs1) || issignalingnan(fs2)
950 || issignalingnan(fs3)) {
951 FFLAGS |= FloatInvalid;
953 fd = numeric_limits<float>::quiet_NaN();
954 } else if (std::isinf(fs1) || std::isinf(fs2) ||
956 if (signbit(fs1) == signbit(fs2)
957 && !std::isinf(fs3)) {
958 fd = numeric_limits<float>::infinity();
959 } else if (signbit(fs1) != signbit(fs2)
960 && !std::isinf(fs3)) {
961 fd = -numeric_limits<float>::infinity();
962 } else { // Fs3_sf is infinity
968 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
971 if (std::isnan(Fs1) || std::isnan(Fs2) ||
973 if (issignalingnan(Fs1) || issignalingnan(Fs2)
974 || issignalingnan(Fs3)) {
975 FFLAGS |= FloatInvalid;
977 Fd = numeric_limits<double>::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<double>::infinity();
983 } else if (signbit(Fs1) != signbit(Fs2)
984 && !std::isinf(Fs3)) {
985 Fd = -numeric_limits<double>::infinity();
994 0x12: decode FUNCT2 {
997 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
998 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
999 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1002 if (std::isnan(fs1) || std::isnan(fs2) ||
1004 if (issignalingnan(fs1) || issignalingnan(fs2)
1005 || issignalingnan(fs3)) {
1006 FFLAGS |= FloatInvalid;
1008 fd = numeric_limits<float>::quiet_NaN();
1009 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1011 if (signbit(fs1) == signbit(fs2)
1012 && !std::isinf(fs3)) {
1013 fd = -numeric_limits<float>::infinity();
1014 } else if (signbit(fs1) != signbit(fs2)
1015 && !std::isinf(fs3)) {
1016 fd = numeric_limits<float>::infinity();
1017 } else { // Fs3_sf is infinity
1021 fd = -(fs1*fs2 - fs3);
1023 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1024 }}, FloatMultAccOp);
1026 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1028 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1029 || issignalingnan(Fs3)) {
1030 FFLAGS |= FloatInvalid;
1032 Fd = numeric_limits<double>::quiet_NaN();
1033 } else if (std::isinf(Fs1) || std::isinf(Fs2)
1034 || std::isinf(Fs3)) {
1035 if (signbit(Fs1) == signbit(Fs2)
1036 && !std::isinf(Fs3)) {
1037 Fd = -numeric_limits<double>::infinity();
1038 } else if (signbit(Fs1) != signbit(Fs2)
1039 && !std::isinf(Fs3)) {
1040 Fd = numeric_limits<double>::infinity();
1045 Fd = -(Fs1*Fs2 - Fs3);
1047 }}, FloatMultAccOp);
1049 0x13: decode FUNCT2 {
1052 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1053 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1054 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1057 if (std::isnan(fs1) || std::isnan(fs2) ||
1059 if (issignalingnan(fs1) || issignalingnan(fs2)
1060 || issignalingnan(fs3)) {
1061 FFLAGS |= FloatInvalid;
1063 fd = numeric_limits<float>::quiet_NaN();
1064 } else if (std::isinf(fs1) || std::isinf(fs2) ||
1066 if (signbit(fs1) == signbit(fs2)
1067 && !std::isinf(fs3)) {
1068 fd = -numeric_limits<float>::infinity();
1069 } else if (signbit(fs1) != signbit(fs2)
1070 && !std::isinf(fs3)) {
1071 fd = numeric_limits<float>::infinity();
1072 } else { // Fs3_sf is infinity
1076 fd = -(fs1*fs2 + fs3);
1078 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1079 }}, FloatMultAccOp);
1081 if (std::isnan(Fs1) || std::isnan(Fs2) ||
1083 if (issignalingnan(Fs1) || issignalingnan(Fs2)
1084 || issignalingnan(Fs3)) {
1085 FFLAGS |= FloatInvalid;
1087 Fd = numeric_limits<double>::quiet_NaN();
1088 } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1090 if (signbit(Fs1) == signbit(Fs2)
1091 && !std::isinf(Fs3)) {
1092 Fd = -numeric_limits<double>::infinity();
1093 } else if (signbit(Fs1) != signbit(Fs2)
1094 && !std::isinf(Fs3)) {
1095 Fd = numeric_limits<double>::infinity();
1100 Fd = -(Fs1*Fs2 + Fs3);
1102 }}, FloatMultAccOp);
1104 0x14: decode FUNCT7 {
1107 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1108 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1111 if (std::isnan(fs1) || std::isnan(fs2)) {
1112 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1113 FFLAGS |= FloatInvalid;
1115 fd = numeric_limits<float>::quiet_NaN();
1119 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1122 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1123 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1124 FFLAGS |= FloatInvalid;
1126 Fd = numeric_limits<double>::quiet_NaN();
1133 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1134 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1137 if (std::isnan(fs1) || std::isnan(fs2)) {
1138 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1139 FFLAGS |= FloatInvalid;
1141 fd = numeric_limits<float>::quiet_NaN();
1145 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1148 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1149 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1150 FFLAGS |= FloatInvalid;
1152 Fd = numeric_limits<double>::quiet_NaN();
1159 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1160 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1163 if (std::isnan(fs1) || std::isnan(fs2)) {
1164 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1165 FFLAGS |= FloatInvalid;
1167 fd = numeric_limits<float>::quiet_NaN();
1171 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1174 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1175 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1176 FFLAGS |= FloatInvalid;
1178 Fd = numeric_limits<double>::quiet_NaN();
1185 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1186 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1189 if (std::isnan(fs1) || std::isnan(fs2)) {
1190 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1191 FFLAGS |= FloatInvalid;
1193 fd = numeric_limits<float>::quiet_NaN();
1197 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1200 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1201 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1202 FFLAGS |= FloatInvalid;
1204 Fd = numeric_limits<double>::quiet_NaN();
1209 0x10: decode ROUND_MODE {
1212 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1213 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1216 if (issignalingnan(fs1)) {
1217 fd = numeric_limits<float>::signaling_NaN();
1218 feclearexcept(FE_INVALID);
1220 fd = copysign(fs1, fs2);
1222 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1226 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1227 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1230 if (issignalingnan(fs1)) {
1231 fd = numeric_limits<float>::signaling_NaN();
1232 feclearexcept(FE_INVALID);
1234 fd = copysign(fs1, -fs2);
1236 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1240 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1241 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1244 if (issignalingnan(fs1)) {
1245 fd = numeric_limits<float>::signaling_NaN();
1246 feclearexcept(FE_INVALID);
1248 fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1250 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1253 0x11: decode ROUND_MODE {
1255 if (issignalingnan(Fs1)) {
1256 Fd = numeric_limits<double>::signaling_NaN();
1257 feclearexcept(FE_INVALID);
1259 Fd = copysign(Fs1, Fs2);
1263 if (issignalingnan(Fs1)) {
1264 Fd = numeric_limits<double>::signaling_NaN();
1265 feclearexcept(FE_INVALID);
1267 Fd = copysign(Fs1, -Fs2);
1271 if (issignalingnan(Fs1)) {
1272 Fd = numeric_limits<double>::signaling_NaN();
1273 feclearexcept(FE_INVALID);
1275 Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1279 0x14: decode ROUND_MODE {
1282 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1283 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1286 if (issignalingnan(fs2)) {
1288 FFLAGS |= FloatInvalid;
1289 } else if (issignalingnan(fs1)) {
1291 FFLAGS |= FloatInvalid;
1293 fd = fmin(fs1, fs2);
1295 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1299 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1300 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1303 if (issignalingnan(fs2)) {
1305 FFLAGS |= FloatInvalid;
1306 } else if (issignalingnan(fs1)) {
1308 FFLAGS |= FloatInvalid;
1310 fd = fmax(fs1, fs2);
1312 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1315 0x15: decode ROUND_MODE {
1317 if (issignalingnan(Fs2)) {
1319 FFLAGS |= FloatInvalid;
1320 } else if (issignalingnan(Fs1)) {
1322 FFLAGS |= FloatInvalid;
1324 Fd = fmin(Fs1, Fs2);
1328 if (issignalingnan(Fs2)) {
1330 FFLAGS |= FloatInvalid;
1331 } else if (issignalingnan(Fs1)) {
1333 FFLAGS |= FloatInvalid;
1335 Fd = fmax(Fs1, Fs2);
1340 if (CONV_SGN != 1) {
1341 fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1345 if (issignalingnan(Fs1)) {
1346 fd = numeric_limits<float>::quiet_NaN();
1347 FFLAGS |= FloatInvalid;
1351 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1354 if (CONV_SGN != 0) {
1355 fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1359 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1361 if (issignalingnan(fs1)) {
1362 Fd = numeric_limits<double>::quiet_NaN();
1363 FFLAGS |= FloatInvalid;
1370 fault = make_shared<IllegalInstFault>("source reg x1",
1374 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1377 if (issignalingnan(Fs1_sf)) {
1378 FFLAGS |= FloatInvalid;
1381 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1385 fault = make_shared<IllegalInstFault>("source reg x1",
1390 0x50: decode ROUND_MODE {
1393 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1394 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1396 if (std::isnan(fs1) || std::isnan(fs2)) {
1397 FFLAGS |= FloatInvalid;
1400 Rd = fs1 <= fs2 ? 1 : 0;
1405 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1406 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1408 if (std::isnan(fs1) || std::isnan(fs2)) {
1409 FFLAGS |= FloatInvalid;
1412 Rd = fs1 < fs2 ? 1 : 0;
1417 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1418 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1420 if (issignalingnan(fs1) || issignalingnan(fs2)) {
1421 FFLAGS |= FloatInvalid;
1423 Rd = fs1 == fs2 ? 1 : 0;
1426 0x51: decode ROUND_MODE {
1428 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1429 FFLAGS |= FloatInvalid;
1432 Rd = Fs1 <= Fs2 ? 1 : 0;
1436 if (std::isnan(Fs1) || std::isnan(Fs2)) {
1437 FFLAGS |= FloatInvalid;
1440 Rd = Fs1 < Fs2 ? 1 : 0;
1444 if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1445 FFLAGS |= FloatInvalid;
1447 Rd = Fs1 == Fs2 ? 1 : 0;
1450 0x60: decode CONV_SGN {
1453 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1455 if (std::isnan(fs1)) {
1456 Rd_sd = numeric_limits<int32_t>::max();
1457 FFLAGS |= FloatInvalid;
1459 float(numeric_limits<int32_t>::max())) {
1460 Rd_sd = numeric_limits<int32_t>::max();
1461 FFLAGS |= FloatInvalid;
1463 float(numeric_limits<int32_t>::min())) {
1464 Rd_sd = numeric_limits<int32_t>::min();
1465 FFLAGS |= FloatInvalid;
1467 Rd_sd = (int32_t)fs1;
1472 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1474 if (std::isnan(fs1)) {
1475 Rd = numeric_limits<uint64_t>::max();
1476 FFLAGS |= FloatInvalid;
1477 } else if (fs1 < 0.0) {
1479 FFLAGS |= FloatInvalid;
1481 float(numeric_limits<uint32_t>::max())) {
1482 Rd = numeric_limits<uint64_t>::max();
1483 FFLAGS |= FloatInvalid;
1490 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1492 if (std::isnan(fs1)) {
1493 Rd_sd = numeric_limits<int64_t>::max();
1494 FFLAGS |= FloatInvalid;
1496 float(numeric_limits<int64_t>::max())) {
1497 Rd_sd = numeric_limits<int64_t>::max();
1498 FFLAGS |= FloatInvalid;
1500 float(numeric_limits<int64_t>::min())) {
1501 Rd_sd = numeric_limits<int64_t>::min();
1502 FFLAGS |= FloatInvalid;
1504 Rd_sd = (int64_t)fs1;
1509 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1511 if (std::isnan(fs1)) {
1512 Rd = numeric_limits<uint64_t>::max();
1513 FFLAGS |= FloatInvalid;
1514 } else if (fs1 < 0.0) {
1516 FFLAGS |= FloatInvalid;
1518 float(numeric_limits<uint64_t>::max())) {
1519 Rd = numeric_limits<uint64_t>::max();
1520 FFLAGS |= FloatInvalid;
1526 0x61: decode CONV_SGN {
1528 if (std::isnan(Fs1)) {
1529 Rd_sd = numeric_limits<int32_t>::max();
1530 FFLAGS |= FloatInvalid;
1532 float(numeric_limits<int32_t>::max())) {
1533 Rd_sd = numeric_limits<int32_t>::max();
1534 FFLAGS |= FloatInvalid;
1536 float(numeric_limits<int32_t>::min())) {
1537 Rd_sd = numeric_limits<int32_t>::min();
1538 FFLAGS |= FloatInvalid;
1540 Rd_sd = (int32_t)Fs1;
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<uint32_t>::max())) {
1552 Rd = numeric_limits<uint64_t>::max();
1553 FFLAGS |= FloatInvalid;
1559 if (std::isnan(Fs1)) {
1560 Rd_sd = numeric_limits<int64_t>::max();
1561 FFLAGS |= FloatInvalid;
1563 float(numeric_limits<int64_t>::max())) {
1564 Rd_sd = numeric_limits<int64_t>::max();
1565 FFLAGS |= FloatInvalid;
1567 float(numeric_limits<int64_t>::min())) {
1568 Rd_sd = numeric_limits<int64_t>::min();
1569 FFLAGS |= FloatInvalid;
1575 if (std::isnan(Fs1)) {
1576 Rd = numeric_limits<uint64_t>::max();
1577 FFLAGS |= FloatInvalid;
1578 } else if (Fs1 < 0) {
1580 FFLAGS |= FloatInvalid;
1582 float(numeric_limits<uint64_t>::max())) {
1583 Rd = numeric_limits<uint64_t>::max();
1584 FFLAGS |= FloatInvalid;
1590 0x68: decode CONV_SGN {
1592 float temp = (float)Rs1_sw;
1593 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1596 float temp = (float)Rs1_uw;
1597 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1600 float temp = (float)Rs1_sd;
1601 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1604 float temp = (float)Rs1;
1605 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1608 0x69: decode CONV_SGN {
1610 Fd = (double)Rs1_sw;
1613 Fd = (double)Rs1_uw;
1616 Fd = (double)Rs1_sd;
1622 0x70: decode ROUND_MODE {
1624 Rd = (uint32_t)Fs1_bits;
1625 if ((Rd&0x80000000) != 0) {
1626 Rd |= (0xFFFFFFFFULL << 32);
1631 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1632 switch (fpclassify(fs1)) {
1641 if (issignalingnan(fs1)) {
1669 panic("Unknown classification for operand.");
1674 0x71: decode ROUND_MODE {
1679 switch (fpclassify(Fs1)) {
1688 if (issignalingnan(Fs1)) {
1716 panic("Unknown classification for operand.");
1722 Fd_bits = (uint64_t)Rs1_uw;
1730 0x18: decode FUNCT3 {
1738 }}, IsDirectControl, IsCondControl);
1745 }}, IsDirectControl, IsCondControl);
1747 if (Rs1_sd < Rs2_sd) {
1752 }}, IsDirectControl, IsCondControl);
1754 if (Rs1_sd >= Rs2_sd) {
1759 }}, IsDirectControl, IsCondControl);
1766 }}, IsDirectControl, IsCondControl);
1773 }}, IsDirectControl, IsCondControl);
1777 0x19: decode FUNCT3 {
1780 NPC = (imm + Rs1) & (~0x1);
1781 }}, IsIndirectControl, IsUncondControl, IsCall);
1787 }}, IsDirectControl, IsUncondControl, IsCall);
1789 0x1c: decode FUNCT3 {
1791 0x0: decode FUNCT7 {
1794 fault = make_shared<SyscallFault>(
1795 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1796 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1799 fault = make_shared<BreakpointFault>(
1801 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1803 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1804 status.uie = status.upie;
1806 xc->setMiscReg(MISCREG_STATUS, status);
1807 NPC = xc->readMiscReg(MISCREG_UEPC);
1808 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1812 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1813 auto pm = (PrivilegeMode)xc->readMiscReg(
1816 (pm == PRV_S && status.tsr == 1)) {
1817 fault = make_shared<IllegalInstFault>(
1818 "sret in user mode or TSR enabled",
1822 xc->setMiscReg(MISCREG_PRV, status.spp);
1823 status.sie = status.spie;
1826 xc->setMiscReg(MISCREG_STATUS, status);
1827 NPC = xc->readMiscReg(MISCREG_SEPC);
1829 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1831 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1832 auto pm = (PrivilegeMode)xc->readMiscReg(
1835 (pm == PRV_S && status.tw == 1)) {
1836 fault = make_shared<IllegalInstFault>(
1837 "wfi in user mode or TW enabled",
1840 // don't do anything for now
1844 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1845 auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
1846 if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
1847 fault = make_shared<IllegalInstFault>(
1848 "sfence in user mode or TVM enabled",
1851 xc->tcBase()->getMMUPtr()->demapPage(Rs1, Rs2);
1852 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
1854 if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1855 fault = make_shared<IllegalInstFault>(
1856 "mret at lower privilege", machInst);
1859 STATUS status = xc->readMiscReg(MISCREG_STATUS);
1860 xc->setMiscReg(MISCREG_PRV, status.mpp);
1861 status.mie = status.mpie;
1864 xc->setMiscReg(MISCREG_STATUS, status);
1865 NPC = xc->readMiscReg(MISCREG_MEPC);
1867 }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
1874 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1878 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1882 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1886 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1890 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1894 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);