From bcbc1f76a7f00d91c9dfcdec68667f1b9a6fe31f Mon Sep 17 00:00:00 2001 From: gregoral Date: Fri, 26 Jan 2024 18:44:37 +0100 Subject: [PATCH] RISC-V: Instructions from H and Q extensions Add missing instructions from H and Q exension. Fix bugs with decoders for existing instructions. Updated 193.instructions test assembly and elf binary. --- src/Arch/RiscV/InstructionSet.cs | 165 +- src/Arch/RiscV/Mnemonic.cs | 107 +- src/Arch/RiscV/RiscVRewriter.Alu.cs | 26 + src/Arch/RiscV/RiscVRewriter.Fpu.cs | 7 +- src/Arch/RiscV/RiscVRewriter.cs | 172 +- .../Arch/RiscV/RiscVDisassemblerTests.cs | 103 +- .../Arch/RiscV/RiscVRewriterTests.cs | 2756 +++++++++++------ .../193.instructions/193.instructions.asm | 260 +- .../193.instructions/193.instructions.elf | Bin 8720 -> 9160 bytes 9 files changed, 2408 insertions(+), 1188 deletions(-) diff --git a/src/Arch/RiscV/InstructionSet.cs b/src/Arch/RiscV/InstructionSet.cs index 28f8230891..9eee1182eb 100644 --- a/src/Arch/RiscV/InstructionSet.cs +++ b/src/Arch/RiscV/InstructionSet.cs @@ -35,6 +35,7 @@ public class InstructionSet { private static readonly Decoder invalid = Instr(Mnemonic.invalid, InstrClass.Invalid); + private Func[], Decoder> float16Support; private Func[], Decoder> float32Support; private Func[], Decoder> float64Support; private Func[], Decoder> float128Support; @@ -59,21 +60,31 @@ private InstructionSet(Dictionary options) float128Support = Instr; float64Support = Instr; float32Support = Instr; + float16Support = Instr; break; case 64: float128Support = MakeInvalid; float64Support = Instr; float32Support = Instr; + float16Support = Instr; break; case 32: float128Support = MakeInvalid; float64Support = MakeInvalid; float32Support = Instr; + float16Support = Instr; + break; + case 16: + float128Support = MakeInvalid; + float64Support = MakeInvalid; + float32Support = MakeInvalid; + float16Support = Instr; break; default: float128Support = MakeInvalid; float64Support = MakeInvalid; float32Support = MakeInvalid; + float16Support = MakeInvalid; break; } } @@ -82,6 +93,7 @@ private InstructionSet(Dictionary options) float128Support = MakeInvalid; float64Support = MakeInvalid; float32Support = MakeInvalid; + float16Support = MakeInvalid; } if (!options.TryGetValue("Zfa", out var oZfa) || @@ -106,6 +118,11 @@ private static Decoder Instr(Mnemonic mnemonic, params Mutator(InstrClass.Linear, mnemonic, mutators); } + private Decoder FpInstr16(Mnemonic mnemonic, params Mutator[] mutators) + { + return float16Support(mnemonic, mutators); + } + private Decoder FpInstr32(Mnemonic mnemonic, params Mutator[] mutators) { return float32Support(mnemonic, mutators); @@ -151,24 +168,23 @@ public Decoder[] CreateRootDecoders() var loads = new Decoder[] // 0b00000 { - Instr(Mnemonic.lb, Rd,Ls), - Instr(Mnemonic.lh, Rd,Ls), - Instr(Mnemonic.lw, Rd,Ls), - Instr(Mnemonic.ld, Rd,Ls), // 64I - - Instr(Mnemonic.lbu, Rd,Ls), - Instr(Mnemonic.lhu, Rd,Ls), - Instr(Mnemonic.lwu, Rd,Ls), // 64I + Instr(Mnemonic.lb, rd,Ls), + Instr(Mnemonic.lh, rd,Ls), + Instr(Mnemonic.lw, rd,Ls), + Instr(Mnemonic.ld, rd,Ls), // 64I + + Instr(Mnemonic.lbu, rd,Ls), + Instr(Mnemonic.lhu, rd,Ls), + Instr(Mnemonic.lwu, rd,Ls), // 64I Nyi(""), }; var fploads = new Decoder[8] // 0b00001 { invalid, - invalid, + FpInstr16(Mnemonic.flh, Fd,Mem(PrimitiveType.Real16, 15, (20, 12))), FpInstr32(Mnemonic.flw, Fd,Mem(PrimitiveType.Real32, 15, (20, 12))), FpInstr64(Mnemonic.fld, Fd,Mem(PrimitiveType.Real64, 15, (20, 12))), - FpInstr128(Mnemonic.flq, Fd,Mem(PrimitiveType.Real64, 15, (20, 12))), invalid, invalid, @@ -191,11 +207,10 @@ public Decoder[] CreateRootDecoders() var fpstores = new Decoder[8] // 0b01001 { invalid, - invalid, + FpInstr16(Mnemonic.fsh, F2,Mem(PrimitiveType.Real16, 15, (25,7),(7,5))), FpInstr32(Mnemonic.fsw, F2,Mem(PrimitiveType.Real32, 15, (25,7),(7,5))), FpInstr64(Mnemonic.fsd, F2,Mem(PrimitiveType.Real64, 15, (25,7),(7,5))), - - invalid, + FpInstr128(Mnemonic.fsq, F2,Mem(PrimitiveType.Real128, 15, (25,7),(7,5))), invalid, invalid, invalid, @@ -307,18 +322,22 @@ public Decoder[] CreateRootDecoders() { ( 0x00, FpInstr32(Mnemonic.fadd_s, Fd,F1,F2, rm12) ), ( 0x01, FpInstr64(Mnemonic.fadd_d, Fd,F1,F2, rm12) ), + ( 0x02, FpInstr16(Mnemonic.fadd_h, Fd,F1,F2, rm12) ), ( 0x03, FpInstr128(Mnemonic.fadd_q, Fd,F1,F2, rm12) ), ( 0x04, FpInstr32(Mnemonic.fsub_s, Fd,F1,F2, rm12) ), ( 0x05, FpInstr64(Mnemonic.fsub_d, Fd,F1,F2, rm12) ), + ( 0x06, FpInstr16(Mnemonic.fsub_h, Fd,F1,F2, rm12) ), ( 0x07, FpInstr128(Mnemonic.fsub_q, Fd,F1,F2, rm12) ), ( 0x08, FpInstr32(Mnemonic.fmul_s, Fd,F1,F2, rm12) ), ( 0x09, FpInstr64(Mnemonic.fmul_d, Fd,F1,F2, rm12) ), + ( 0x0A, FpInstr16(Mnemonic.fmul_h, Fd,F1,F2, rm12) ), ( 0x0B, FpInstr128(Mnemonic.fmul_q, Fd,F1,F2, rm12) ), ( 0x0C, FpInstr32(Mnemonic.fdiv_s, Fd,F1,F2, rm12) ), ( 0x0D, FpInstr64(Mnemonic.fdiv_d, Fd,F1,F2, rm12) ), + ( 0x0E, FpInstr16(Mnemonic.fdiv_h, Fd,F1,F2, rm12) ), ( 0x0F, FpInstr128(Mnemonic.fdiv_q, Fd,F1,F2, rm12) ), ( 0x10, Sparse(12, 3, "fsgn.s", invalid, @@ -341,6 +360,16 @@ public Decoder[] CreateRootDecoders() (0x2, Select(R1EqR2, FpInstr64(Mnemonic.fabs_d, Fd,F1), FpInstr64(Mnemonic.fsgnjx_d, Fd,F1, F2))))), + ( 0x12, Sparse(12, 3, "fsgn.h", invalid, + (0x0, Select(R1EqR2, + FpInstr64(Mnemonic.fmv_h, Fd,F1), + FpInstr64(Mnemonic.fsgnj_h, Fd,F1, F2))), + (0x1, Select(R1EqR2, + FpInstr64(Mnemonic.fneg_h, Fd,F1), + FpInstr64(Mnemonic.fsgnjn_h, Fd,F1, F2))), + (0x2, Select(R1EqR2, + FpInstr64(Mnemonic.fabs_h, Fd,F1), + FpInstr64(Mnemonic.fsgnjx_h, Fd,F1, F2))))), ( 0x13, Sparse(12, 3, "fsgn.q", invalid, (0x0, Select(R1EqR2, FpInstr128(Mnemonic.fmv_q, Fd,F1, F2), @@ -374,29 +403,35 @@ public Decoder[] CreateRootDecoders() (0x3, FpInstr128(Mnemonic.fmaxm_q, Fd,F1, F2)))), ( 0x20, Sparse(20, 5, "fcvt.s", invalid, - (0x1, FpInstr64(Mnemonic.fcvt_s_d, Fd,F1) ), - (0x3, FpInstr128(Mnemonic.fcvt_s_q, Fd,F1) ), - (0x4, FpInstr32(Mnemonic.fround_s, Rd,F1) ), - (0x5, FpInstr32(Mnemonic.froundnx_s, Rd,F1) ))), + (0x1, FpInstr32(Mnemonic.fcvt_s_d, Fd,F1, rm12) ), + (0x2, FpInstr32(Mnemonic.fcvt_s_h, Fd,F1) ), + (0x3, FpInstr32(Mnemonic.fcvt_s_q, Fd,F1, rm12) ), + (0x4, FpInstr32(Mnemonic.fround_s, Fd,F1, rm12) ), + (0x5, FpInstr32(Mnemonic.froundnx_s, Fd,F1, rm12) ))), ( 0x21, Sparse(20, 5, "fcvt.d", invalid, (0x0, FpInstr64(Mnemonic.fcvt_d_s, Fd,F1) ), - (0x3, FpInstr128(Mnemonic.fcvt_d_q, Fd,F1) ), - (0x4, FpInstr32(Mnemonic.fround_d, Rd,F1) ), - (0x5, FpInstr32(Mnemonic.froundnx_d, Rd,F1) ))), + (0x2, FpInstr64(Mnemonic.fcvt_d_h, Fd,F1) ), + (0x3, FpInstr64(Mnemonic.fcvt_d_q, Fd,F1, rm12) ), + (0x4, FpInstr64(Mnemonic.fround_d, Fd,F1, rm12) ), + (0x5, FpInstr64(Mnemonic.froundnx_d, Fd,F1, rm12) ))), ( 0x22, Sparse(20, 5, "fcvt.h", invalid, - (0x0, FpInstr32(Mnemonic.fcvt_h_s, Fd,F1) ), - (0x4, FpInstr32(Mnemonic.fround_h, Rd,F1) ), - (0x5, FpInstr32(Mnemonic.froundnx_h, Rd,F1) ))), + (0x0, FpInstr16(Mnemonic.fcvt_h_s, Fd,F1, rm12)), + (0x1, FpInstr16(Mnemonic.fcvt_h_d, Fd,F1, rm12)), + (0x3, FpInstr16(Mnemonic.fcvt_h_q, Fd,F1, rm12)), + (0x4, FpInstr16(Mnemonic.fround_h, Fd,F1, rm12) ), + (0x5, FpInstr16(Mnemonic.froundnx_h, Fd,F1, rm12) ))), ( 0x23, Sparse(20, 5, "fcvt.q", invalid, (0x0, FpInstr128(Mnemonic.fcvt_q_s, Fd,F1) ), (0x1, FpInstr128(Mnemonic.fcvt_q_d, Fd,F1) ), - (0x4, FpInstr32(Mnemonic.fround_q, Rd,F1) ), - (0x5, FpInstr32(Mnemonic.froundnx_q, Rd,F1) ))), + (0x2, FpInstr128(Mnemonic.fcvt_q_h, Fd,F1) ), + (0x4, FpInstr128(Mnemonic.fround_q, Fd,F1, rm12) ), + (0x5, FpInstr128(Mnemonic.froundnx_q, Fd,F1, rm12) ))), - ( 0x2C, Select((20, 5), Ne0, invalid, FpInstr32(Mnemonic.fsqrt_s, Fd,F1)) ), - ( 0x2D, Select((20, 5), Ne0, invalid, FpInstr64(Mnemonic.fsqrt_d, Fd,F1)) ), - ( 0x2F, Select((20, 5), Ne0, invalid, FpInstr128(Mnemonic.fsqrt_q, Fd,F1)) ), + ( 0x2C, Select((20, 5), Ne0, invalid, FpInstr32(Mnemonic.fsqrt_s, Fd,F1, rm12)) ), + ( 0x2D, Select((20, 5), Ne0, invalid, FpInstr64(Mnemonic.fsqrt_d, Fd,F1, rm12)) ), + ( 0x2E, Select((20, 5), Ne0, invalid, FpInstr16(Mnemonic.fsqrt_h, Fd,F1, rm12)) ), + ( 0x2F, Select((20, 5), Ne0, invalid, FpInstr128(Mnemonic.fsqrt_q, Fd,F1, rm12)) ), ( 0x50, Sparse(12, 3, "fcmp.s", invalid, ( 0, FpInstr32(Mnemonic.fle_s, rd,F1,F2)), @@ -406,6 +441,10 @@ public Decoder[] CreateRootDecoders() ( 0, FpInstr64(Mnemonic.fle_d, rd,F1,F2)), ( 1, FpInstr64(Mnemonic.flt_d, rd,F1,F2)), ( 2, FpInstr64(Mnemonic.feq_d, rd,F1,F2)))), + ( 0x52, Sparse(12, 3, "fcmp.h", invalid, + ( 0, FpInstr16(Mnemonic.fle_h, rd,F1,F2)), + ( 1, FpInstr16(Mnemonic.flt_h, rd,F1,F2)), + ( 2, FpInstr16(Mnemonic.feq_h, rd,F1,F2)))), ( 0x53, Sparse(12, 3, "fcmp.q", invalid, ( 0, FpInstr128(Mnemonic.fle_q, rd,F1,F2)), ( 1, FpInstr128(Mnemonic.flt_q, rd,F1,F2)), @@ -421,6 +460,11 @@ public Decoder[] CreateRootDecoders() ( 1, FpInstr64(Mnemonic.fcvt_wu_d, Rd,F1,rm12)), ( 2, FpInstr64(Mnemonic.fcvt_l_d, Rd,F1,rm12)), ( 3, FpInstr64(Mnemonic.fcvt_lu_d, Rd,F1,rm12)))), + ( 0x62, Sparse(20, 5, "fcvt.w.h", invalid, + ( 0, FpInstr16(Mnemonic.fcvt_w_h, Rd,F1,rm12)), + ( 1, FpInstr16(Mnemonic.fcvt_wu_h, Rd,F1,rm12)), + ( 2, FpInstr16(Mnemonic.fcvt_l_h, Rd,F1,rm12)), + ( 3, FpInstr16(Mnemonic.fcvt_lu_h, Rd,F1,rm12)))), ( 0x63, Sparse(20, 5, "fcvt_w_q", invalid, ( 0, FpInstr128(Mnemonic.fcvt_w_q, Rd,F1,rm12)), ( 1, FpInstr128(Mnemonic.fcvt_wu_q, Rd,F1,rm12)), @@ -428,40 +472,48 @@ public Decoder[] CreateRootDecoders() ( 3, FpInstr128(Mnemonic.fcvt_lu_q, Rd,F1,rm12)))), ( 0x68, Sparse(20, 5, "fcvt.to.s", invalid, - ( 0, FpInstr32(Mnemonic.fcvt_s_w, Fd,R1)), - ( 1, FpInstr32(Mnemonic.fcvt_s_wu, Fd,R1)), - ( 2, FpInstr32(Mnemonic.fcvt_s_l, Fd,R1)), - ( 3, FpInstr32(Mnemonic.fcvt_s_lu, Fd,R1)))), + ( 0, FpInstr32(Mnemonic.fcvt_s_w, Fd,R1,rm12)), + ( 1, FpInstr32(Mnemonic.fcvt_s_wu, Fd,R1,rm12)), + ( 2, FpInstr32(Mnemonic.fcvt_s_l, Fd,R1,rm12)), + ( 3, FpInstr32(Mnemonic.fcvt_s_lu, Fd,R1,rm12)))), ( 0x69, Sparse(20, 5, "fcvt.to.d", invalid, ( 0, FpInstr64(Mnemonic.fcvt_d_w, Fd,R1)), ( 1, FpInstr64(Mnemonic.fcvt_d_wu, Fd,R1)), - ( 2, FpInstr64(Mnemonic.fcvt_d_l, Fd,R1)), - ( 3, FpInstr64(Mnemonic.fcvt_d_lu, Fd,R1)))), + ( 2, FpInstr64(Mnemonic.fcvt_d_l, Fd,R1,rm12)), + ( 3, FpInstr64(Mnemonic.fcvt_d_lu, Fd,R1,rm12)))), + ( 0x6A, Sparse(20, 5, "fcvt.to.h", invalid, + ( 0, FpInstr16(Mnemonic.fcvt_h_w, Fd,R1,rm12)), + ( 1, FpInstr16(Mnemonic.fcvt_h_wu, Fd,R1,rm12)), + ( 2, FpInstr16(Mnemonic.fcvt_h_l, Fd,R1,rm12)), + ( 3, FpInstr16(Mnemonic.fcvt_h_lu, Fd,R1,rm12)))), ( 0x6B, Sparse(20, 5, "fcvt.to.q", invalid, ( 0, FpInstr128(Mnemonic.fcvt_q_w, Fd,R1)), ( 1, FpInstr128(Mnemonic.fcvt_q_wu, Fd,R1)), - ( 2, FpInstr128(Mnemonic.fcvt_q_l, Fd,R1)), - ( 3, FpInstr128(Mnemonic.fcvt_q_lu, Fd,R1)))), - + ( 2, FpInstr128(Mnemonic.fcvt_q_l, Fd,R1,rm12)), + ( 3, FpInstr128(Mnemonic.fcvt_q_lu, Fd,R1,rm12)))), ( 0x70, Sparse(12, 3, " 0x70", invalid, (0, FpInstr32(Mnemonic.fmv_x_w, Rd,F1) ), (1, FpInstr32(Mnemonic.fclass_s, Rd,F1) ))), ( 0x71, Sparse(12, 3, " 0x71", invalid, (0, FpInstr64(Mnemonic.fmv_x_d, Rd,F1) ), (1, FpInstr64(Mnemonic.fclass_d, Rd,F1) ))), - ( 0x73, Sparse(20, 5, "fclass.q", invalid, - ( 0, FpInstr128(Mnemonic.fclass_q, Rd,F1)))), - - ( 0x78, Sparse(20, 5, "fmv.w.x", invalid, + ( 0x72, Sparse(12, 3, "0x72", invalid, + (0, FpInstr16(Mnemonic.fmv_x_h, Rd,F1) ), + (1, FpInstr16(Mnemonic.fclass_h, Rd,F1) ))), + ( 0x73, Sparse(12, 3, "fclass.q", invalid, + // (0, FpInstr128(Mnemonic.fmv_x_q, Rd,F1) ), //$TODO: this will be part of RV128 + ( 1, FpInstr128(Mnemonic.fclass_q, Rd,F1)))), + ( 0x78, Sparse(20, 5, "0x78", invalid, (0, FpInstr32(Mnemonic.fmv_w_x, Fd,r1) ), (1, Zfa(FpInstr32(Mnemonic.fli_s, Fd, fpImm_s))))), - ( 0x79, Sparse(20, 5, "fmv.d.x", invalid, + ( 0x79, Sparse(20, 5, "0x79", invalid, (0, FpInstr64(Mnemonic.fmv_d_x, Fd,r1) ), (1, Zfa(FpInstr64(Mnemonic.fli_d, Fd, fpImm_d))))), - ( 0x7A, Sparse(20, 5, "fli.h", invalid, - (1, Zfa(Nyi("fli.h"))))), - ( 0x7B, Sparse(20, 5, "fli.q", invalid, - (1, Zfa(Nyi("fli.q"))))) + ( 0x7A, Sparse(20, 5, "0x7A", invalid, + (0, FpInstr16(Mnemonic.fmv_h_x, Fd,r1) ), + (1, Zfa(FpInstr16(Mnemonic.fli_h, Fd, fpImm_d))))), + ( 0x7B, Sparse(20, 5, "0x7B", invalid, + (1, Zfa(FpInstr128(Mnemonic.fli_q, Fd, fpImm_d))))), }; var branches = new Decoder[] // 0b11000 @@ -520,16 +572,17 @@ public Decoder[] CreateRootDecoders() (2, Instr(Mnemonic.uret, InstrClass.Transfer | InstrClass.Return)))), (0x08, Sparse(20, 5, " system 0x08", Nyi("system 0x08"), (2, Instr(Mnemonic.sret, InstrClass.Privileged | InstrClass.Transfer | InstrClass.Return)), + (4, Instr(Mnemonic.sfence_vm, InstrClass.Privileged | InstrClass.Linear, r1)), (5, Instr(Mnemonic.wfi, InstrClass.Privileged | InstrClass.Linear)))), - (0x09, Instr(Mnemonic.sfence_vma, InstrClass.Privileged | InstrClass.Linear, R1, R2)), - (0x0B, Instr(Mnemonic.sfence_inval, InstrClass.Privileged | InstrClass.Linear, R1, R2)), + (0x09, Instr(Mnemonic.sfence_vma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), + (0x0B, Instr(Mnemonic.sinval_vma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), (0x0C, Sparse(20, 5, " system 0x0C", Nyi("system 0x0C"), (0, Instr(Mnemonic.sfence_w_inval, InstrClass.Privileged | InstrClass.Linear)), (1, Instr(Mnemonic.sfence_inval_ir, InstrClass.Privileged | InstrClass.Linear)))), - (0x11, Instr(Mnemonic.hfence_vvma, InstrClass.Privileged | InstrClass.Linear, R1, R2)), - (0x13, Instr(Mnemonic.hinval_vvma, InstrClass.Privileged | InstrClass.Linear, R1, R2)), - (0x31, Instr(Mnemonic.hfence_gvma, InstrClass.Privileged | InstrClass.Linear, R1, R2)), - (0x33, Instr(Mnemonic.hinval_gvma, InstrClass.Privileged | InstrClass.Linear, R1, R2)), + (0x11, Instr(Mnemonic.hfence_vvma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), + (0x13, Instr(Mnemonic.hinval_vvma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), + (0x31, Instr(Mnemonic.hfence_gvma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), + (0x33, Instr(Mnemonic.hinval_gvma, InstrClass.Privileged | InstrClass.Linear, r1, r2)), (0x18, Sparse(20, 5, " system 11000", Nyi("system 11000"), (2, Instr(Mnemonic.mret, InstrClass.Privileged | InstrClass.Transfer | InstrClass.Return))))), @@ -552,10 +605,10 @@ public Decoder[] CreateRootDecoders() (3, Instr(Mnemonic.hlvx_wu, InstrClass.Privileged | InstrClass.Linear, Rd, Mem(PrimitiveType.UInt32, 15))))), (0x36, Sparse(20, 5, " system 0x36", Nyi("system 0x36"), (0, Instr(Mnemonic.hlv_d, InstrClass.Privileged | InstrClass.Linear, Rd, Mem(PrimitiveType.UInt64, 15))))), - (0x31, Instr(Mnemonic.hsv_b, InstrClass.Privileged | InstrClass.Linear, Mem(PrimitiveType.Byte, 15), R2)), - (0x33, Instr(Mnemonic.hsv_h, InstrClass.Privileged | InstrClass.Linear, Mem(PrimitiveType.Word16, 15), R2)), - (0x35, Instr(Mnemonic.hsv_w, InstrClass.Privileged | InstrClass.Linear, Mem(PrimitiveType.Word32, 15), R2)), - (0x37, Instr(Mnemonic.hsv_d, InstrClass.Privileged | InstrClass.Linear, Mem(PrimitiveType.Word64, 15), R2))), + (0x31, Instr(Mnemonic.hsv_b, InstrClass.Privileged | InstrClass.Linear, r2, Mem(PrimitiveType.Byte, 15))), + (0x33, Instr(Mnemonic.hsv_h, InstrClass.Privileged | InstrClass.Linear, r2, Mem(PrimitiveType.Word16, 15))), + (0x35, Instr(Mnemonic.hsv_w, InstrClass.Privileged | InstrClass.Linear, r2, Mem(PrimitiveType.Word32, 15))), + (0x37, Instr(Mnemonic.hsv_d, InstrClass.Privileged | InstrClass.Linear, r2, Mem(PrimitiveType.Word64, 15)))), Instr(Mnemonic.csrrwi, rd, Csr20, Imm(15, 5)), Instr(Mnemonic.csrrsi, rd, Csr20, Imm(15, 5)), Instr(Mnemonic.csrrci, rd, Csr20, Imm(15, 5))); diff --git a/src/Arch/RiscV/Mnemonic.cs b/src/Arch/RiscV/Mnemonic.cs index 34f1389cae..1cb81c2b81 100644 --- a/src/Arch/RiscV/Mnemonic.cs +++ b/src/Arch/RiscV/Mnemonic.cs @@ -110,63 +110,85 @@ public enum Mnemonic ebreak, ecall, fabs_d, + fabs_h, fabs_q, fabs_s, fadd_d, + fadd_h, fadd_q, fadd_s, fclass_d, + fclass_h, fclass_q, fclass_s, + fcvt_d_h, fcvt_d_l, fcvt_d_lu, fcvt_d_q, fcvt_d_s, fcvt_d_w, fcvt_d_wu, + fcvt_h_d, + fcvt_h_l, + fcvt_h_lu, + fcvt_h_q, + fcvt_h_s, + fcvt_h_w, + fcvt_h_wu, fcvt_l_d, + fcvt_l_h, fcvt_l_q, fcvt_l_s, fcvt_lu_d, + fcvt_lu_h, fcvt_lu_q, fcvt_lu_s, fcvt_q_d, + fcvt_q_h, fcvt_q_l, fcvt_q_lu, fcvt_q_s, fcvt_q_w, fcvt_q_wu, fcvt_s_d, + fcvt_s_h, fcvt_s_l, fcvt_s_lu, fcvt_s_q, fcvt_s_w, fcvt_s_wu, fcvt_w_d, + fcvt_w_h, fcvt_w_q, fcvt_w_s, fcvt_wu_d, + fcvt_wu_h, fcvt_wu_q, fcvt_wu_s, fdiv_d, + fdiv_h, fdiv_q, fdiv_s, fence, fence_i, fence_tso, feq_d, + feq_h, feq_q, feq_s, fld, fle_d, + fle_h, fle_q, fle_s, + flh, fli_d, fli_h, fli_q, fli_s, flq, flt_d, + flt_h, flt_q, flt_s, flw, @@ -195,17 +217,23 @@ public enum Mnemonic fmsub_q, fmsub_s, fmul_d, + fmul_h, fmul_q, fmul_s, fmv_d, fmv_d_x, + fmv_h, + fmv_h_x, fmv_q, + // fmv_q_x, //$TODO: this will be part of RV128 fmv_s, - fmv_s_x, fmv_w_x, fmv_x_d, + fmv_x_h, + // fmv_x_q, //$TODO: this will be part of RV128 fmv_x_w, fneg_d, + fneg_h, fneg_q, fneg_s, fnmadd_d, @@ -216,23 +244,60 @@ public enum Mnemonic fnmsub_h, fnmsub_q, fnmsub_s, + fround_d, + fround_h, + fround_q, + fround_s, + froundnx_d, + froundnx_h, + froundnx_q, + froundnx_s, fsd, fsgnj_d, + fsgnj_h, fsgnj_q, fsgnj_s, fsgnjn_d, + fsgnjn_h, fsgnjn_q, fsgnjn_s, fsgnjx_d, + fsgnjx_h, fsgnjx_q, fsgnjx_s, + fsh, + fsq, fsqrt_d, + fsqrt_h, fsqrt_q, fsqrt_s, fsub_d, + fsub_h, fsub_q, fsub_s, fsw, + hfence_gvma, + hfence_vvma, + hinval_gvma, + hinval_vvma, + hlv_b, + hlv_bu, + hlv_d, + hlv_w, + hlv_wu, + hlv_du, + hlv_h, + hlv_hu, + hlvx_h, + hlvx_hu, + hlvx_wu, + hsv_b, + hsv_bu, + hsv_d, + hsv_du, + hsv_h, + hsv_hu, + hsv_w, jal, jalr, lb, @@ -241,6 +306,8 @@ public enum Mnemonic lh, lhu, lr_d, + lr_h, + lr_q, lr_w, lui, lw, @@ -260,9 +327,16 @@ public enum Mnemonic remw, sb, sc_d, + sc_h, sc_w, sd, + sfence_inval, + sfence_inval_ir, + sfence_vm, + sfence_vma, + sfence_w_inval, sh, + sinval_vma, sll, slli, slliw, @@ -287,36 +361,5 @@ public enum Mnemonic wfi, xor, xori, - sfence_vma, - sfence_inval, - sfence_w_inval, - sfence_inval_ir, - hfence_vvma, - hinval_vvma, - hfence_gvma, - hinval_gvma, - - hlv_b, - hlv_bu, - hlv_h, - hlv_hu, - hlvx_hu, - hlv_w, - hlvx_wu, - hsv_b, - hsv_h, - hsv_w, - hsv_d, - hlv_wu, - hlv_d, - fround_s, - froundnx_s, - fround_d, - froundnx_d, - fcvt_h_s, - fround_h, - froundnx_h, - froundnx_q, - fround_q, } } \ No newline at end of file diff --git a/src/Arch/RiscV/RiscVRewriter.Alu.cs b/src/Arch/RiscV/RiscVRewriter.Alu.cs index 89549ba6d5..ff1c93718c 100644 --- a/src/Arch/RiscV/RiscVRewriter.Alu.cs +++ b/src/Arch/RiscV/RiscVRewriter.Alu.cs @@ -139,6 +139,32 @@ private void RewriteCompressedBinOp(Func op, P MaybeSliceSignExtend(dst, val, dtDst); } + private Expression RewriteEffectiveAddress() + { + Expression ea; + if (instr.Operands[1] is MemoryOperand mem) + { + var baseReg = binder.EnsureRegister(mem.Base); + ea = baseReg; + if (mem.Offset != 0) + { + ea = m.IAddS(ea, mem.Offset); + } + } + else + { + var baseReg = RewriteOp(1); + var offset = ((ImmediateOperand) instr.Operands[2]).Value; + ea = baseReg; + if (!offset.IsZero) + { + ea = m.IAdd(ea, offset); + } + } + + return ea; + } + private void RewriteLi() { var src = RewriteOp(1); diff --git a/src/Arch/RiscV/RiscVRewriter.Fpu.cs b/src/Arch/RiscV/RiscVRewriter.Fpu.cs index b0fe20a1da..1b3b5303a0 100644 --- a/src/Arch/RiscV/RiscVRewriter.Fpu.cs +++ b/src/Arch/RiscV/RiscVRewriter.Fpu.cs @@ -156,6 +156,12 @@ private void RewriteFGenericBinaryIntrinsic(PrimitiveType dt, IntrinsicProcedure m.Assign(dst, MaybeNanBox(m.Fn(fn.MakeInstance(dt), src1, src2), dst.DataType)); } + private void RewriteFGenericUnaryIntrinsic(PrimitiveType dt, IntrinsicProcedure fn) + { + var src1 = MaybeSlice(RewriteOp(1), dt); + var dst = RewriteOp(0); + m.Assign(dst, MaybeNanBox(m.Fn(fn.MakeInstance(dt), src1), dst.DataType)); + } private void RewriteFUnaryIntrinsic(PrimitiveType dt, IntrinsicProcedure fn) { @@ -164,7 +170,6 @@ private void RewriteFUnaryIntrinsic(PrimitiveType dt, IntrinsicProcedure fn) m.Assign(dst, MaybeNanBox(m.Fn(fn, src), dst.DataType)); } - // Move bits between integer and FP regs without interpretation. private void RewriteFMove(PrimitiveType dtFrom, PrimitiveType dtTo) { diff --git a/src/Arch/RiscV/RiscVRewriter.cs b/src/Arch/RiscV/RiscVRewriter.cs index 3839f42729..87047e34f6 100644 --- a/src/Arch/RiscV/RiscVRewriter.cs +++ b/src/Arch/RiscV/RiscVRewriter.cs @@ -167,69 +167,122 @@ public IEnumerator GetEnumerator() case Mnemonic.ecall: RewriteEcall(); break; case Mnemonic.fabs_d: RewriteFUnaryIntrinsic(PrimitiveType.Real64, FpOps.fabs); break; case Mnemonic.fadd_d: RewriteFBinOp(PrimitiveType.Real64, Operator.FAdd); break; + case Mnemonic.fadd_h: RewriteFBinOp(PrimitiveType.Real16, Operator.FAdd); break; + case Mnemonic.fadd_q: RewriteFBinOp(PrimitiveType.Real128, Operator.FAdd); break; case Mnemonic.fadd_s: RewriteFBinOp(PrimitiveType.Real32, Operator.FAdd); break; case Mnemonic.fclass_d: RewriteFUnaryIntrinsic(PrimitiveType.Real64, fclass_intrinsic.MakeInstance(PrimitiveType.Real64, arch.WordWidth)); break; + case Mnemonic.fclass_h: RewriteFUnaryIntrinsic(PrimitiveType.Real16, fclass_intrinsic.MakeInstance(PrimitiveType.Real64, arch.WordWidth)); break; + case Mnemonic.fclass_q: RewriteFUnaryIntrinsic(PrimitiveType.Real128, fclass_intrinsic.MakeInstance(PrimitiveType.Real64, arch.WordWidth)); break; case Mnemonic.fclass_s: RewriteFUnaryIntrinsic(PrimitiveType.Real32, fclass_intrinsic.MakeInstance(PrimitiveType.Real32, arch.WordWidth)); break; + case Mnemonic.fcvt_d_h: RewriteFcvt(PrimitiveType.Int16, PrimitiveType.Real64); break; case Mnemonic.fcvt_d_l: RewriteFcvt(PrimitiveType.Int64, PrimitiveType.Real64); break; + case Mnemonic.fcvt_d_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.Real64); break; case Mnemonic.fcvt_d_w: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real64); break; case Mnemonic.fcvt_d_lu: RewriteFcvt(PrimitiveType.UInt64, PrimitiveType.Real64); break; case Mnemonic.fcvt_d_wu: RewriteFcvt(PrimitiveType.UInt32, PrimitiveType.Real64); break; case Mnemonic.fcvt_d_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.Real64); break; + case Mnemonic.fcvt_h_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_l: RewriteFcvt(PrimitiveType.Int64, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_lu: RewriteFcvt(PrimitiveType.UInt64, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_w: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_wu: RewriteFcvt(PrimitiveType.UInt32, PrimitiveType.Real16); break; + case Mnemonic.fcvt_h_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.Real16); break; case Mnemonic.fcvt_l_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.Int64); break; + case Mnemonic.fcvt_l_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.Int64); break; + case Mnemonic.fcvt_l_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.Int64); break; case Mnemonic.fcvt_l_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.Int64); break; case Mnemonic.fcvt_lu_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.UInt64); break; + case Mnemonic.fcvt_lu_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.UInt64); break; + case Mnemonic.fcvt_lu_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.UInt64); break; case Mnemonic.fcvt_lu_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.UInt64); break; + case Mnemonic.fcvt_q_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_l: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_lu: RewriteFcvt(PrimitiveType.UInt32, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_s: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_w: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real128); break; + case Mnemonic.fcvt_q_wu: RewriteFcvt(PrimitiveType.UInt32, PrimitiveType.Real128); break; case Mnemonic.fcvt_s_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.Real32); break; + case Mnemonic.fcvt_s_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.Real32); break; + case Mnemonic.fcvt_s_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.Real32); break; case Mnemonic.fcvt_s_l: RewriteFcvt(PrimitiveType.Int64, PrimitiveType.Real32); break; case Mnemonic.fcvt_s_w: RewriteFcvt(PrimitiveType.Int32, PrimitiveType.Real32); break; case Mnemonic.fcvt_s_lu: RewriteFcvt(PrimitiveType.UInt64, PrimitiveType.Real32); break; case Mnemonic.fcvt_s_wu: RewriteFcvt(PrimitiveType.UInt32, PrimitiveType.Real32); break; case Mnemonic.fcvt_w_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.Int32); break; + case Mnemonic.fcvt_w_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.Int32); break; + case Mnemonic.fcvt_w_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.Int32); break; case Mnemonic.fcvt_w_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.Int32); break; case Mnemonic.fcvt_wu_d: RewriteFcvt(PrimitiveType.Real64, PrimitiveType.UInt32); break; + case Mnemonic.fcvt_wu_h: RewriteFcvt(PrimitiveType.Real16, PrimitiveType.UInt32); break; + case Mnemonic.fcvt_wu_q: RewriteFcvt(PrimitiveType.Real128, PrimitiveType.UInt32); break; case Mnemonic.fcvt_wu_s: RewriteFcvt(PrimitiveType.Real32, PrimitiveType.UInt32); break; case Mnemonic.fdiv_d: RewriteFBinOp(PrimitiveType.Real64, Operator.FDiv); break; + case Mnemonic.fdiv_h: RewriteFBinOp(PrimitiveType.Real16, Operator.FDiv); break; + case Mnemonic.fdiv_q: RewriteFBinOp(PrimitiveType.Real128, Operator.FDiv); break; case Mnemonic.fdiv_s: RewriteFBinOp(PrimitiveType.Real32, Operator.FDiv); break; - case Mnemonic.fence: RewriteFence(); break; + case Mnemonic.fence: RewriteFence(fence_intrinsic); break; case Mnemonic.fence_i: RewriteFenceI(); break; case Mnemonic.fence_tso: RewriteFenceTso(); break; case Mnemonic.feq_d: RewriteFcmp(PrimitiveType.Real64, Operator.Feq); break; + case Mnemonic.feq_h: RewriteFcmp(PrimitiveType.Real16, Operator.Feq); break; + case Mnemonic.feq_q: RewriteFcmp(PrimitiveType.Real128, Operator.Feq); break; case Mnemonic.feq_s: RewriteFcmp(PrimitiveType.Real32, Operator.Feq); break; case Mnemonic.fle_d: RewriteFcmp(PrimitiveType.Real64, Operator.Fle); break; + case Mnemonic.fle_h: RewriteFcmp(PrimitiveType.Real16, Operator.Fle); break; + case Mnemonic.fle_q: RewriteFcmp(PrimitiveType.Real128, Operator.Fle); break; case Mnemonic.fle_s: RewriteFcmp(PrimitiveType.Real32, Operator.Fle); break; case Mnemonic.fld: RewriteFload(PrimitiveType.Real64); break; + case Mnemonic.flh: RewriteFload(PrimitiveType.Real16); break; case Mnemonic.fli_d: RewriteMove(); break; + case Mnemonic.fli_h: RewriteMove(); break; + case Mnemonic.fli_q: RewriteMove(); break; case Mnemonic.fli_s: RewriteMove(); break; case Mnemonic.flq: RewriteFload(PrimitiveType.Real128); break; - case Mnemonic.flw: RewriteFload(PrimitiveType.Real32); break; case Mnemonic.flt_d: RewriteFcmp(PrimitiveType.Real64, Operator.Flt); break; + case Mnemonic.flt_h: RewriteFcmp(PrimitiveType.Real16, Operator.Flt); break; case Mnemonic.flt_q: RewriteFcmp(PrimitiveType.Real128, Operator.Flt); break; case Mnemonic.flt_s: RewriteFcmp(PrimitiveType.Real32, Operator.Flt); break; + case Mnemonic.flw: RewriteFload(PrimitiveType.Real32); break; case Mnemonic.fmadd_d: RewriteFmadd(PrimitiveType.Real64, Operator.FAdd, false); break; case Mnemonic.fmadd_h: RewriteFmadd(PrimitiveType.Real16, Operator.FAdd, false); break; case Mnemonic.fmadd_q: RewriteFmadd(PrimitiveType.Real128, Operator.FAdd, false); break; case Mnemonic.fmadd_s: RewriteFmadd(PrimitiveType.Real32, Operator.FAdd, false); break; - case Mnemonic.fmax_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, FpOps.fmax); break; - case Mnemonic.fmax_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, FpOps.fmaxf); break; + case Mnemonic.fmax_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, fmax_intrinsic.MakeInstance(PrimitiveType.Real64)); break; + case Mnemonic.fmax_h: RewriteFBinaryIntrinsic(PrimitiveType.Real16, fmax_intrinsic.MakeInstance(PrimitiveType.Real16)); break; + case Mnemonic.fmax_q: RewriteFBinaryIntrinsic(PrimitiveType.Real128, fmax_intrinsic.MakeInstance(PrimitiveType.Real128)); break; + case Mnemonic.fmax_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, fmax_intrinsic.MakeInstance(PrimitiveType.Real32)); break; case Mnemonic.fmaxm_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, fmaxm_intrinsic.MakeInstance(PrimitiveType.Real64)); break; + case Mnemonic.fmaxm_h: RewriteFBinaryIntrinsic(PrimitiveType.Real16, fmaxm_intrinsic.MakeInstance(PrimitiveType.Real16)); break; + case Mnemonic.fmaxm_q: RewriteFBinaryIntrinsic(PrimitiveType.Real128, fmaxm_intrinsic.MakeInstance(PrimitiveType.Real128)); break; case Mnemonic.fmaxm_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, fmaxm_intrinsic.MakeInstance(PrimitiveType.Real32)); break; - case Mnemonic.fmin_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, FpOps.fmin); break; - case Mnemonic.fmin_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, FpOps.fminf); break; + case Mnemonic.fmin_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, fmin_intrinsic.MakeInstance(PrimitiveType.Real64)); break; + case Mnemonic.fmin_h: RewriteFBinaryIntrinsic(PrimitiveType.Real16, fmin_intrinsic.MakeInstance(PrimitiveType.Real16)); break; + case Mnemonic.fmin_q: RewriteFBinaryIntrinsic(PrimitiveType.Real128, fmin_intrinsic.MakeInstance(PrimitiveType.Real128)); break; + case Mnemonic.fmin_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, fmin_intrinsic.MakeInstance(PrimitiveType.Real32)); break; case Mnemonic.fminm_d: RewriteFBinaryIntrinsic(PrimitiveType.Real64, fminm_intrinsic.MakeInstance(PrimitiveType.Real64)); break; + case Mnemonic.fminm_h: RewriteFBinaryIntrinsic(PrimitiveType.Real16, fminm_intrinsic.MakeInstance(PrimitiveType.Real16)); break; + case Mnemonic.fminm_q: RewriteFBinaryIntrinsic(PrimitiveType.Real128, fminm_intrinsic.MakeInstance(PrimitiveType.Real128)); break; case Mnemonic.fminm_s: RewriteFBinaryIntrinsic(PrimitiveType.Real32, fminm_intrinsic.MakeInstance(PrimitiveType.Real32)); break; case Mnemonic.fmsub_d: RewriteFmadd(PrimitiveType.Real64, Operator.FSub, false); break; case Mnemonic.fmsub_h: RewriteFmadd(PrimitiveType.Real16, Operator.FSub, false); break; case Mnemonic.fmsub_q: RewriteFmadd(PrimitiveType.Real128, Operator.FSub, false); break; case Mnemonic.fmsub_s: RewriteFmadd(PrimitiveType.Real32, Operator.FSub, false); break; case Mnemonic.fmul_d: RewriteFBinOp(PrimitiveType.Real64, Operator.FMul); break; + case Mnemonic.fmul_h: RewriteFBinOp(PrimitiveType.Real16, Operator.FMul); break; case Mnemonic.fmul_q: RewriteFBinOp(PrimitiveType.Real128, Operator.FMul); break; case Mnemonic.fmul_s: RewriteFBinOp(PrimitiveType.Real32, Operator.FMul); break; case Mnemonic.fmv_d_x: RewriteFMove(PrimitiveType.Int64, PrimitiveType.Real64); break; case Mnemonic.fmv_d: RewriteMove(); break; + case Mnemonic.fmv_h_x: RewriteFMove(PrimitiveType.Int16, PrimitiveType.Real32); break; + // case Mnemonic.fmv_q_x: RewriteFMove(PrimitiveType.Int32, PrimitiveType.Real128); break; //$TODO: this will be part of RV128 case Mnemonic.fmv_s: RewriteMove(); break; - case Mnemonic.fmv_w_x: RewriteFMove(PrimitiveType.Real32, PrimitiveType.Real32); break; - case Mnemonic.fmv_x_w: RewriteFMove(PrimitiveType.Real32, PrimitiveType.Real32); break; - case Mnemonic.fmv_x_d: RewriteFMove(PrimitiveType.Real64, PrimitiveType.Real64); break; + case Mnemonic.fmv_w_x: RewriteFMove(PrimitiveType.Int32, PrimitiveType.Real32); break; + case Mnemonic.fmv_x_d: RewriteFMove(PrimitiveType.Real64, PrimitiveType.Int32); break; + case Mnemonic.fmv_x_h: RewriteFMove(PrimitiveType.Real16, PrimitiveType.Int32); break; + // case Mnemonic.fmv_x_q: RewriteFMove(PrimitiveType.Real128, PrimitiveType.Int32); break; //$TODO: this will be part of RV128 + case Mnemonic.fmv_x_w: RewriteFMove(PrimitiveType.Real32, PrimitiveType.Int32); break; case Mnemonic.fneg_d: RewriteFneg(PrimitiveType.Real64); break; case Mnemonic.fneg_s: RewriteFneg(PrimitiveType.Real32); break; case Mnemonic.fnmadd_d: RewriteFmadd(PrimitiveType.Real64, Operator.FSub /* sic! */, true); break; @@ -240,22 +293,42 @@ public IEnumerator GetEnumerator() case Mnemonic.fnmsub_h: RewriteFmadd(PrimitiveType.Real16, Operator.FAdd /* sic! */, true); break; case Mnemonic.fnmsub_q: RewriteFmadd(PrimitiveType.Real128, Operator.FAdd /* sic! */, true); break; case Mnemonic.fnmsub_s: RewriteFmadd(PrimitiveType.Real32, Operator.FAdd /* sic! */, true); break; + case Mnemonic.fround_d: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real64, fround_intrinsic); break; + case Mnemonic.froundnx_d: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real64, froundnx_intrinsic); break; + case Mnemonic.fround_h: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real16, fround_intrinsic); break; + case Mnemonic.froundnx_h: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real16, froundnx_intrinsic); break; + case Mnemonic.fround_s: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real32, fround_intrinsic); break; + case Mnemonic.froundnx_s: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real32, froundnx_intrinsic); break; + case Mnemonic.fround_q: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real128, fround_intrinsic); break; + case Mnemonic.froundnx_q: RewriteFGenericUnaryIntrinsic(PrimitiveType.Real128, froundnx_intrinsic); break; case Mnemonic.fsd: RewriteStore(PrimitiveType.Real64); break; + case Mnemonic.fsh: RewriteStore(PrimitiveType.Real16); break; case Mnemonic.fsgnj_d: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real64, fsgnj_intrinsic); break; + case Mnemonic.fsgnj_h: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real16, fsgnj_intrinsic); break; + case Mnemonic.fsgnj_q: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real128, fsgnj_intrinsic); break; case Mnemonic.fsgnj_s: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real32, fsgnj_intrinsic); break; case Mnemonic.fsgnjn_d: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real64, fsgnjn_intrinsic); break; + case Mnemonic.fsgnjn_h: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real16, fsgnjn_intrinsic); break; + case Mnemonic.fsgnjn_q: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real128, fsgnjn_intrinsic); break; case Mnemonic.fsgnjn_s: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real32, fsgnjn_intrinsic); break; case Mnemonic.fsgnjx_d: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real64, fsgnjx_intrinsic); break; + case Mnemonic.fsgnjx_h: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real16, fsgnjx_intrinsic); break; + case Mnemonic.fsgnjx_q: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real128, fsgnjx_intrinsic); break; case Mnemonic.fsgnjx_s: RewriteFGenericBinaryIntrinsic(PrimitiveType.Real32, fsgnjx_intrinsic); break; - case Mnemonic.fsub_d: RewriteFBinOp(PrimitiveType.Real64, Operator.FSub); break; + case Mnemonic.fsq: RewriteStore(PrimitiveType.Real128); break; case Mnemonic.fsqrt_d: RewriteFUnaryIntrinsic(PrimitiveType.Real64, FpOps.sqrt); break; + case Mnemonic.fsqrt_h: RewriteFUnaryIntrinsic(PrimitiveType.Real16, FpOps.sqrt); break; + case Mnemonic.fsqrt_q: RewriteFUnaryIntrinsic(PrimitiveType.Real128, FpOps.sqrt); break; case Mnemonic.fsqrt_s: RewriteFUnaryIntrinsic(PrimitiveType.Real32, FpOps.sqrtf); break; + case Mnemonic.fsub_d: RewriteFBinOp(PrimitiveType.Real64, Operator.FSub); break; + case Mnemonic.fsub_h: RewriteFBinOp(PrimitiveType.Real16, Operator.FSub); break; + case Mnemonic.fsub_q: RewriteFBinOp(PrimitiveType.Real128, Operator.FSub); break; case Mnemonic.fsub_s: RewriteFBinOp(PrimitiveType.Real32, Operator.FSub); break; case Mnemonic.fsw: RewriteStore(PrimitiveType.Real32); break; case Mnemonic.hfence_gvma: RewriteFence(hfence_gvma_intrinsic); break; case Mnemonic.hfence_vvma: RewriteFence(hfence_vvma_intrinsic); break; - case Mnemonic.hinval_gvma: RewriteFence(hfence_gvma_intrinsic); break; - case Mnemonic.hinval_vvma: RewriteFence(hfence_vvma_intrinsic); break; + case Mnemonic.hinval_gvma: RewriteFence(hinval_gvma_intrinsic); break; + case Mnemonic.hinval_vvma: RewriteFence(hinval_vvma_intrinsic); break; case Mnemonic.hlv_b: RewriteHlv(PrimitiveType.Int8, hlv_intrinsic); break; case Mnemonic.hlv_bu: RewriteHlv(PrimitiveType.Byte, hlv_intrinsic); break; case Mnemonic.hlv_d: RewriteHlv(PrimitiveType.Word64, hlv_intrinsic); break; @@ -300,11 +373,11 @@ public IEnumerator GetEnumerator() case Mnemonic.sd: RewriteStore(PrimitiveType.Word64); break; case Mnemonic.sfence_inval: RewriteFence(sfence_inval_intrinsic); break; case Mnemonic.sfence_inval_ir: RewriteFence(sfence_inval_ir_intrinsic); break; + case Mnemonic.sfence_vm: RewriteFence(sfence_vm_intrinsic); break; case Mnemonic.sfence_vma: RewriteFence(sfence_vma_intrinsic); break; case Mnemonic.sfence_w_inval: RewriteFence(sfence_w_inval_intrinsic); break; + case Mnemonic.sinval_vma: RewriteFence(sinval_vma_intrinsic); break; case Mnemonic.sh: RewriteStore(PrimitiveType.Word16); break; - case Mnemonic.sret: RewriteRet(sret_intrinsic); break; - case Mnemonic.sw: RewriteStore(PrimitiveType.Word32); break; case Mnemonic.sll: RewriteBinOp(Operator.Shl); break; case Mnemonic.slli: RewriteShift(Operator.Shl); break; case Mnemonic.slliw: RewriteShiftw(m.Shl); break; @@ -317,6 +390,8 @@ public IEnumerator GetEnumerator() case Mnemonic.sraw: RewriteShiftw(m.Sar); break; case Mnemonic.srai: RewriteShift(Operator.Sar); break; case Mnemonic.sraiw: RewriteShiftw(m.Sar); break; + case Mnemonic.sret: RewriteRet(sret_intrinsic); break; + case Mnemonic.sw: RewriteStore(PrimitiveType.Word32); break; case Mnemonic.srl: RewriteBinOp(Operator.Shr); break; case Mnemonic.srli: RewriteShift(Operator.Shr); break; case Mnemonic.srliw: RewriteShiftw(SrlI); break; @@ -471,32 +546,48 @@ private static IntrinsicProcedure AmoIntrinsic(string intrinsicName) static readonly IntrinsicProcedure fsgnjx_intrinsic = IntrinsicBuilder.GenericBinary("__fsgnjx"); static readonly IntrinsicProcedure hfence_gvma_intrinsic = new IntrinsicBuilder("__hfence_gvma", true) - .GenericTypes("T","U") - .Param("T") - .Param("U") - .Void(); - static readonly IntrinsicProcedure hfence_vvma_intrinsic = new IntrinsicBuilder("__hfence_vvma", true) - .GenericTypes("T","U") - .Param("T") - .Param("U") - .Void(); - + .GenericTypes("T","U") + .Param("T") + .Param("U") + .Void(); + static readonly IntrinsicProcedure hfence_vvma_intrinsic = new IntrinsicBuilder("__hfence_vvma", true) + .GenericTypes("T","U") + .Param("T") + .Param("U") + .Void(); + static readonly IntrinsicProcedure hinval_gvma_intrinsic = new IntrinsicBuilder("__hinval_gvma", true) + .GenericTypes("T","U") + .Param("T") + .Param("U") + .Void(); + static readonly IntrinsicProcedure hinval_vvma_intrinsic = new IntrinsicBuilder("__hinval_vvma", true) + .GenericTypes("T","U") + .Param("T") + .Param("U") + .Void(); static readonly IntrinsicProcedure sfence_inval_intrinsic = new IntrinsicBuilder("__sfence_inval", true) - .GenericTypes("T", "U") - .Param("T") - .Param("U") - .Void(); - static readonly IntrinsicProcedure sfence_inval_ir_intrinsic= new IntrinsicBuilder("__sfence_inval_ir", true) - .Void(); - static readonly IntrinsicProcedure sfence_vma_intrinsic = new IntrinsicBuilder("__sfence_vma", true) - .GenericTypes("T", "U") - .Param("T") - .Param("U") - .Void(); + .GenericTypes("T", "U") + .Param("T") + .Param("U") + .Void(); + static readonly IntrinsicProcedure sfence_inval_ir_intrinsic = new IntrinsicBuilder("__sfence_inval_ir", true) + .Void(); + static readonly IntrinsicProcedure sfence_vm_intrinsic = new IntrinsicBuilder("__sfence_vm", true) + .GenericTypes("T") + .Param("T") + .Void(); + static readonly IntrinsicProcedure sfence_vma_intrinsic = new IntrinsicBuilder("__sfence_vma", true) + .GenericTypes("T", "U") + .Param("T") + .Param("U") + .Void(); static readonly IntrinsicProcedure sfence_w_inval_intrinsic = new IntrinsicBuilder("__sfence_w_inval", true) - .Void(); - - + .Void(); + static readonly IntrinsicProcedure sinval_vma_intrinsic = new IntrinsicBuilder("__sinval_vma", true) + .GenericTypes("T","U") + .Param("T") + .Param("U") + .Void(); static readonly IntrinsicProcedure hlv_intrinsic = new IntrinsicBuilder("__hypervisor_load_from_VM", true) .GenericTypes("T") .PtrParam("T") @@ -511,6 +602,10 @@ private static IntrinsicProcedure AmoIntrinsic(string intrinsicName) .Param("T") .Void(); + static readonly IntrinsicProcedure fround_intrinsic = IntrinsicBuilder.GenericUnary("__fround"); + static readonly IntrinsicProcedure froundnx_intrinsic = IntrinsicBuilder.GenericUnary("__froundnx"); + static readonly IntrinsicProcedure fmax_intrinsic = IntrinsicBuilder.GenericBinary("__fmax"); + static readonly IntrinsicProcedure fmin_intrinsic = IntrinsicBuilder.GenericBinary("__fmin"); static readonly IntrinsicProcedure lr_intrinsic = new IntrinsicBuilder("__load_reserved", true) .GenericTypes("T") @@ -530,7 +625,6 @@ private static IntrinsicProcedure AmoIntrinsic(string intrinsicName) .Returns("T"); static readonly IntrinsicProcedure sret_intrinsic = new IntrinsicBuilder("__sret", true) .Void(); - static readonly IntrinsicProcedure uret_intrinsic = new IntrinsicBuilder("__uret", true) .Void(); static readonly IntrinsicProcedure wait_for_interrupt_intrinsic = new IntrinsicBuilder("__wait_for_interrupt", true) diff --git a/src/UnitTests/Arch/RiscV/RiscVDisassemblerTests.cs b/src/UnitTests/Arch/RiscV/RiscVDisassemblerTests.cs index 87b31e5361..029acff529 100644 --- a/src/UnitTests/Arch/RiscV/RiscVDisassemblerTests.cs +++ b/src/UnitTests/Arch/RiscV/RiscVDisassemblerTests.cs @@ -188,7 +188,6 @@ public void RiscV_dasm_and() AssertCode("and\ta5,s0,a5", 0x00F477B3u); } - [Test] public void RiscV_dasm_c_and() { @@ -424,9 +423,9 @@ public void RiscV_dasm_fmadd_s() } [Test] - public void RiscV_dasm_round_s() + public void RiscV_dasm_fround_s() { - AssertCode("fround.s\ta4,fa4", 0x40470753u); + AssertCode("fround.s\tfa4,fa4,rne", 0x40470753u); } [Test] @@ -743,7 +742,6 @@ public void RiscV_dasm_divuw() AssertCode("divuw\ta5,a6,a2", 0x02C857BB); } - [Test] public void RiscV_dasm_c_fsd() { @@ -776,41 +774,16 @@ public void RiscV_dasm_sllw() } [Test] - public void RiscV_dasm_regressions1() + public void RiscV_dasm_sret() { - AssertCode("fence.i", "0f100000"); // invalid - AssertCode("csrrw\ts2,0x315,t0", "73995231"); // invalid - AssertCode("csrrs\ta1,sstatus,a5", "f3a50710"); // csrrs a1,sstatus,a5 - AssertCode("csrrc\ttp,0x5F0,s0", "7332045f"); // invalid - AssertCode("csrrc\ttp,0x5F0,zero", "7332005f"); // invalid - AssertCode("csrrsi\ts2,0x6E6,0x1E", "73696f6e"); // invalid - AssertCode("csrrci\ts0,0x6A5,0x1A", "73745d6a"); // invalid - AssertCode("mul\ta0,s5,s7", "33857a03"); // add a0,s5,s7 - AssertCode("mulh\tt5,a7,s1", "339f9802"); // sll t5,a7,s1 - AssertCode("mulhsu\tt3,sp,a6", "332e0103"); // slt t3,sp,a6 - AssertCode("mulhu\tt3,sp,a6", "333e0103"); // sltu t3,sp,a6 - AssertCode("mulhsu\tt3,sp,a6", "332e0103"); // slt t3,sp,a6 - AssertCode("divu\tt4,t3,t2", "b35e7e02"); // srl t4,t3,t2 - AssertCode("rem\ta4,a1,a2", "33e7c502"); // or a4,a1,a2 - AssertCode("remu\ta6,a1,t2", "33f87502"); // and a6,a1,t2 - AssertCode("fsw\tfs1,0x48(a1)", "27a49504"); // fsw fs1,288(a1) - AssertCode("fmadd.s\tfs10,ft10,ft5,fa0,rmm", "434d5f50"); // fmadd.s fs10,ft10,ft5,fa0 - AssertCode("fmsub.s\tft8,ft10,fs11,ft7,rdn", "472ebf39"); // fmsub.s ft8,ft10,fs11,ft7 - AssertCode("fnmsub.s\tfs7,fa4,fs3,fs0,rne", "cb0b3741"); // fnmsub.s fs7,fa4,fs3,fs0 - AssertCode("fnmadd.s\tfa4,ft4,fs5,fs0,rmm", "4f475241"); // fnmadd.s fa4,ft4,fs5,fs0 - AssertCode("fclass.s\ta3,fa2", "d31606e0"); // fmv.x.w a3,fa2 - AssertCode("fsd\tfs4,0x138(sp)", "273c4113"); // fsd fs4,2496(a0) - AssertCode("fmsub.d\tft0,ft0,fs0,fa6,rne", "47008082"); // fmsub.s ft0,ft0,fs0,fa6 - AssertCode("fnmsub.d\tfs0,ft4,ft2,fa5,rdn", "4b24227a"); // fnmsub.s fs0,ft4,ft2,fa5 - AssertCode("fnmadd.d\tfa2,ft10,ft5,fa0,rmm", "4f465f52"); // fnmadd.s fa2,ft10,ft5,fa0 - AssertCode("fcvt.l.d\tra,ft1,rtz", "d39020c2"); // fcvt.l.d ra,ft1 - AssertCode("fcvt.lu.d\ta0,fa3,rtz", "539536c2"); // fcvt.lu.d a0,fa3 + AssertCode("sret", 0b0001000_00010_00000_000_00000_1110011); } [Test] - public void RiscV_dasm_sret() + public void RiscV_dasm_sfence_vm() { - AssertCode("sret", 0b0001000_00010_00000_000_00000_1110011); + AssertCode("sfence.vm\ta3", 0b0001000_00100_01101_000_00000_1110011); + } [Test] @@ -831,12 +804,6 @@ public void RiscV_dasm_sfence_inval_ir() AssertCode("sfence.inval.ir", 0b0001100_00001_00000_000_00000_1110011); } - [Test] - public void RiscV_dasm_hfence_vvma() - { - AssertCode("hfence.vvma\ta7,s5", 0b0010001_10101_10001_000_00000_1110011); - } - [Test] public void RiscV_dasm_hfence_gvma() { @@ -844,9 +811,9 @@ public void RiscV_dasm_hfence_gvma() } [Test] - public void RiscV_dasm_hinval_vvma() + public void RiscV_dasm_hfence_vvma() { - AssertCode("hinval.vvma\ta7,s5", 0b0010011_10101_10001_000_00000_1110011); + AssertCode("hfence.vvma\ta7,s5", 0b0010001_10101_10001_000_00000_1110011); } [Test] @@ -855,6 +822,12 @@ public void RiscV_dasm_hinval_gvma() AssertCode("hinval.gvma\ta7,s5", 0b0110011_10101_10001_000_00000_1110011); } + [Test] + public void RiscV_dasm_hinval_vvma() + { + AssertCode("hinval.vvma\ta7,s5", 0b0010011_10101_10001_000_00000_1110011); + } + [Test] public void RiscV_dasm_hlv_b() { @@ -900,19 +873,25 @@ public void RiscV_dasm_hlvx_wu() [Test] public void RiscV_dasm_hsv_b() { - AssertCode("hsv.b\t(a7),s5", 0b0110001_10101_10001_100_00000_1110011); + AssertCode("hsv.b\ts5,(a7)", 0b0110001_10101_10001_100_00000_1110011); + } + + [Test] + public void RiscV_dasm_hsv_d() + { + AssertCode("hsv.d\ts5,(a7)", 0b0110111_10101_10001_100_00000_1110011); } [Test] public void RiscV_dasm_hsv_h() { - AssertCode("hsv.h\t(a7),s5", 0b0110011_10101_10001_100_00000_1110011); + AssertCode("hsv.h\ts5,(a7)", 0b0110011_10101_10001_100_00000_1110011); } [Test] public void RiscV_dasm_hsv_w() { - AssertCode("hsv.w\t(a7),s5", 0b0110101_10101_10001_100_00000_1110011); + AssertCode("hsv.w\ts5,(a7)", 0b0110101_10101_10001_100_00000_1110011); } [Test] @@ -926,11 +905,37 @@ public void RiscV_dasm_hlv_d() { AssertCode("hlv.d\ts11,(a7)", 0b0110110_00000_10001_100_11011_1110011); } - + [Test] - public void RiscV_dasm_hsv_d() + public void RiscV_dasm_regressions1() { - AssertCode("hsv.d\t(a7),s5", 0b0110111_10101_10001_100_00000_1110011); + AssertCode("fence.i", "0f100000"); // invalid + AssertCode("csrrw\ts2,0x315,t0", "73995231"); // invalid + AssertCode("csrrs\ta1,sstatus,a5", "f3a50710"); // csrrs a1,sstatus,a5 + AssertCode("csrrc\ttp,0x5F0,s0", "7332045f"); // invalid + AssertCode("csrrc\ttp,0x5F0,zero", "7332005f"); // invalid + AssertCode("csrrsi\ts2,0x6E6,0x1E", "73696f6e"); // invalid + AssertCode("csrrci\ts0,0x6A5,0x1A", "73745d6a"); // invalid + AssertCode("mul\ta0,s5,s7", "33857a03"); // add a0,s5,s7 + AssertCode("mulh\tt5,a7,s1", "339f9802"); // sll t5,a7,s1 + AssertCode("mulhsu\tt3,sp,a6", "332e0103"); // slt t3,sp,a6 + AssertCode("mulhu\tt3,sp,a6", "333e0103"); // sltu t3,sp,a6 + AssertCode("mulhsu\tt3,sp,a6", "332e0103"); // slt t3,sp,a6 + AssertCode("divu\tt4,t3,t2", "b35e7e02"); // srl t4,t3,t2 + AssertCode("rem\ta4,a1,a2", "33e7c502"); // or a4,a1,a2 + AssertCode("remu\ta6,a1,t2", "33f87502"); // and a6,a1,t2 + AssertCode("fsw\tfs1,0x48(a1)", "27a49504"); // fsw fs1,288(a1) + AssertCode("fmadd.s\tfs10,ft10,ft5,fa0,rmm", "434d5f50"); // fmadd.s fs10,ft10,ft5,fa0 + AssertCode("fmsub.s\tft8,ft10,fs11,ft7,rdn", "472ebf39"); // fmsub.s ft8,ft10,fs11,ft7 + AssertCode("fnmsub.s\tfs7,fa4,fs3,fs0,rne", "cb0b3741"); // fnmsub.s fs7,fa4,fs3,fs0 + AssertCode("fnmadd.s\tfa4,ft4,fs5,fs0,rmm", "4f475241"); // fnmadd.s fa4,ft4,fs5,fs0 + AssertCode("fclass.s\ta3,fa2", "d31606e0"); // fmv.x.w a3,fa2 + AssertCode("fsd\tfs4,0x138(sp)", "273c4113"); // fsd fs4,2496(a0) + AssertCode("fmsub.d\tft0,ft0,fs0,fa6,rne", "47008082"); // fmsub.s ft0,ft0,fs0,fa6 + AssertCode("fnmsub.d\tfs0,ft4,ft2,fa5,rdn", "4b24227a"); // fnmsub.s fs0,ft4,ft2,fa5 + AssertCode("fnmadd.d\tfa2,ft10,ft5,fa0,rmm", "4f465f52"); // fnmadd.s fa2,ft10,ft5,fa0 + AssertCode("fcvt.l.d\tra,ft1,rtz", "d39020c2"); // fcvt.l.d ra,ft1 + AssertCode("fcvt.lu.d\ta0,fa3,rtz", "539536c2"); // fcvt.lu.d a0,fa3 } - } + } } \ No newline at end of file diff --git a/src/UnitTests/Arch/RiscV/RiscVRewriterTests.cs b/src/UnitTests/Arch/RiscV/RiscVRewriterTests.cs index 157d349e35..92ae42b4ea 100644 --- a/src/UnitTests/Arch/RiscV/RiscVRewriterTests.cs +++ b/src/UnitTests/Arch/RiscV/RiscVRewriterTests.cs @@ -118,6 +118,16 @@ public void RiscV_rw_amoadd_d() "1|L--|t2 = __amo_add(s6, &Mem0[t2:word64])"); } + [Test] + public void RiscV_rw_amoadd_w() + { + Given_HexString("AF21AF03"); + AssertCode( // amoadd.w.rl gp,s10,(t5) + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v6 = __amo_add(s10, &Mem0[t5:word32])", + "2|L--|gp = CONVERT(v6, word32, int64)"); + } + [Test] public void RiscV_rw_amoadd_w_rl() { @@ -148,6 +158,15 @@ public void RiscV_rw_amoand_w() "2|L--|s0 = CONVERT(v6, word32, int64)"); } + [Test] + public void RiscV_rw_amomax_d() + { + Given_HexString("2FB3C7A1"); + AssertCode( // amomax.d t1,t3,(a5) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t1 = __amo_max(t3, &Mem0[a5:int64])"); + } + [Test] public void RiscV_rw_amomax_w() { @@ -168,6 +187,15 @@ public void RiscV_rw_amomax_d_aq_rl() "1|L--|gp = __amo_max(s9, &Mem0[a5:int64])"); } + [Test] + public void RiscV_rw_amomaxu_d() + { + Given_HexString("AFB670E0"); + AssertCode( // amomaxu.d a3,t2,(ra) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = __amo_max(t2, &Mem0[ra:uint64])"); + } + [Test] public void RiscV_rw_amomaxu_d_aq() { @@ -197,6 +225,16 @@ public void RiscV_rw_amomin_d() "1|L--|a5 = __amo_min(s11, &Mem0[t2:int64])"); } + [Test] + public void RiscV_rw_amomin_w() + { + Given_HexString("AF276680"); + AssertCode( // amomin.w a5,t1,(a2) + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v6 = __amo_min(t1, &Mem0[a2:int32])", + "2|L--|a5 = CONVERT(v6, int32, int64)"); + } + [Test] public void RiscV_rw_amomin_w_aq() { @@ -207,6 +245,14 @@ public void RiscV_rw_amomin_w_aq() "2|L--|t5 = CONVERT(v6, int32, int64)"); } + [Test] + public void RiscV_rw_amominu_d() + { + Given_HexString("AF35DEC1"); + AssertCode( // amominu.d a1,t4,(t3) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a1 = __amo_min(t4, &Mem0[t3:uint64])"); + } [Test] public void RiscV_rw_amominu_d_aq_rl() @@ -294,1316 +340,2167 @@ public void RiscV_rw_auipc() } [Test] - public void RiscV_rw_jal_zero() + public void RiscV_rw_add() { - Given_RiscVInstructions(0x9F4FF06Fu); + Given_RiscVInstructions(0x00E787B3u); // add\ta5,a5,a4 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|goto 000000000000F1F4"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = a5 + a4"); } [Test] - public void RiscV_rw_lb() + public void RiscV_rw_addi_zero() { - Given_RiscVInstructions(0x87010183u); + Given_RiscVInstructions(0xFFF00413); // addi s0,zero,-00000001 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|gp = CONVERT(Mem0[sp + -1936:int8], int8, int64)"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s0 = -1"); } [Test] - public void RiscV_rw_jal_not_zero() + public void RiscV_rw_addiw() { - Given_RiscVInstructions(0x9F4FF0EFu); + Given_RiscVInstructions(0x0087879Bu); // addiw\ta5,a5,+00000008 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|call 000000000000F1F4 (0)"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = CONVERT(CONVERT(a5, word64, word32) + 8, word32, int64)"); } [Test] - public void RiscV_rw_jalr_zero() + public void RiscV_rw_addiw_sign_extend() { - Given_RiscVInstructions(0x00078067); // jalr zero, a5, 0 + Given_RiscVInstructions(0x00002301); // c.addiw\tt1,00000000 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|goto a5"); + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|t1 = CONVERT(SLICE(t1, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_jalr_zero_ra() + public void RiscV_rw_addw() { - Given_RiscVInstructions(0x00008067); // jalr zero,ra,0 - AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|R--|return (0,0)"); + Given_HexString("3B8F2000"); + AssertCode( // addw t5,ra,sp + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t5 = CONVERT(CONVERT(ra, word64, word32) + sp, word32, int64)"); } [Test] - public void RiscV_rw_jalr_ra() + public void RiscV_rw_and() { - Given_RiscVInstructions(0x003780E7); // jalr ra,a5,0 + Given_RiscVInstructions(0x00F477B3u); // and\ta5,s0,a5 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|call a5 + 3 (0)"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = s0 & a5"); } [Test] - public void RiscV_rw_sc_d() + public void RiscV_rw_beqz_backward() { - Given_HexString("AFBA3C1B"); - AssertCode( // sc.d.rl s5,s9,s3 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s5 = __store_conditional(s3, &Mem0[s9:word64])"); + Given_RiscVInstructions(0xD399); // c.beqz\ta5,00000000000FFF06 + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|if (a5 == 0<64>) branch 000000000000FF06"); } [Test] - public void RiscV_rw_sc_w() + public void RiscV_rw_beq() { - Given_HexString("AFADE31C"); - AssertCode( // sc.w.aq s11,t2,a4 - "0|L--|0000000000010000(4): 2 instructions", - "1|L--|v6 = __store_conditional(a4, &Mem0[t2:word32])", - "2|L--|s11 = CONVERT(v6, word32, int64)"); + Given_RiscVInstructions(0x00F58063u); // beq\ta1,a5,0000000000010000 + AssertCode( + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|if (a1 == a5) branch 0000000000010000"); } [Test] - public void RiscV_rw_sd() + public void RiscV_rw_beq_2() { - Given_RiscVInstructions(0x19513423u); // sd\ts5,sp,392 + Given_RiscVInstructions(0x12E50463u); // beq\ta0,a4,0000000000100128 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|Mem0[sp + 392:word64] = s5"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|if (a0 == a4) branch 0000000000010128"); } [Test] - public void RiscV_rw_lui() + public void RiscV_rw_beqz() { - Given_RiscVInstructions(0x000114B7u); // lui s1,0x00000011<32> + Given_RiscVInstructions(0xC3F1); // c.beqz\ta5,00000000001000C4 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s1 = 0x11000<64>"); + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|if (a5 == 0<64>) branch 00000000000100C4"); } [Test] - public void RiscV_rw_lh() + public void RiscV_rw_c_addiw() { - Given_RiscVInstructions(0x03131083u); // lh + Given_RiscVInstructions(0x00002405); // c.addiw\ts0,00000001 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ra = CONVERT(Mem0[t1 + 49:int16], int16, int64)"); + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s0 = CONVERT(SLICE(s0 + 1, word32, 0), word32, int64)"); } [Test] - public void RiscV_dasm_fence_i() + public void RiscV_rw_c_addiw_negative() { - Given_HexString("0F10 0000"); - AssertCode( // fence.i - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__fence_i()"); + Given_RiscVInstructions(0x0000347D); // c.addiw\ts0,FFFFFFFFFFFFFFFF + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s0 = CONVERT(SLICE(s0 + -1, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_fence() + public void RiscV_rw_c_addi16sp() { - Given_HexString("0F00F00F"); - AssertCode( // fence iorw,iorw - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__fence(iorw, iorw)"); + Given_RiscVInstructions(0x6169); // c.addi16sp\t000000D0 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|sp = sp + 208"); } [Test] - public void RiscV_rw_fmadd_d() + public void RiscV_rw_c_and() { - Given_HexString("43F16303"); - AssertCode( // fmadd.d ft2,ft7,fs6,ft0,dyn - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft2 = ft7 * fs6 + ft0"); + Given_RiscVInstructions(0x8FF5); // c.and\ta5,a3 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a5 = a5 & a3"); } [Test] - public void RiscV_rw_fmadd_s() + public void RiscV_rw_c_addi4spn() { - Given_32bitFloat(); - Given_RiscVInstructions(0x8093FD43); + Given_RiscVInstructions(0x0000101C); // c.addi4spn\ta5,00000020 AssertCode( - "0|L--|00010000(4): 1 instructions", - "1|L--|fs10 = ft7 * fs1 + fa6"); + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a5 = sp + 32"); } [Test] - public void RiscV_rw_fmadd_h() + public void RiscV_rw_c_addi() { - Given_HexString("C3250264"); - AssertCode( // fmadd.h fa1,ft4,ft0,fa2,rdn - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa1 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(ft4, real16, 0) * SLICE(ft0, real16, 0) + SLICE(fa2, real16, 0))"); + Given_RiscVInstructions(0x00000785); // c.addi\ta5,00000001 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a5 = a5 + 1"); } [Test] - public void RiscV_rw_fmadd_q() + public void RiscV_rw_c_addw() { - Given_HexString("432A8146"); - AssertCode( // fmadd.q fs4,ft2,fs0,fs0,rdn - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fs4 = ft2 * fs0 + fs0"); + Given_RiscVInstructions(0x00009FB5); // c.addw\ta5,a3 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a5 = CONVERT(SLICE(a5 + a3, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_fmax_d() + public void RiscV_rw_c_andi() { - Given_HexString("5311402A"); - AssertCode( // fmax.d ft2,ft0,ft4 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft2 = fmax(ft0, ft4)"); + Given_RiscVInstructions(0x00008A61); // c.andi\ta2,00000018 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a2 = a2 & 24"); } [Test] - public void RiscV_rw_fmax_s() + public void RiscV_rw_c_beqz() { - Given_HexString("D3122228"); - AssertCode( // fmax.s ft5,ft4,ft2 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft5 = SEQ(0xFFFFFFFF<32>, fmaxf(SLICE(ft4, real32, 0), SLICE(ft2, real32, 0)))"); + Given_RiscVInstructions(0x0000C121); // c.beqz\ta0,0000000000100040 + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|if (a0 == 0<64>) branch 0000000000010040"); } [Test] - public void RiscV_rw_fmaxm_d() + public void RiscV_rw_c_bnez() { - Given_HexString("5331402A"); // fmaxm.d\tft2,ft0,ft4" + Given_RiscVInstructions(0x0000EF09); // c.bnez\ta4,000000000010001A AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft2 = __fmaxm(ft0, ft4)"); + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|if (a4 != 0<64>) branch 000000000001001A"); } [Test] - public void RiscV_rw_fmin_d() + public void RiscV_rw_c_bnez_backward() { - Given_HexString("D301102A"); - AssertCode( // fmin.d ft3,ft0,ft1 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft3 = fmin(ft0, ft1)"); + Given_RiscVInstructions(0xFB05); // c.bnez\ta4,00000000000FFF30 + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|if (a4 != 0<64>) branch 000000000000FF30"); } [Test] - public void RiscV_rw_fminm_s() + public void RiscV_rw_c_fsdsp() { - Given_HexString("53231028"); // fminm.s\tft6,ft0,ft1 + Given_RiscVInstructions(0xA7E6); // c.fsdsp\tfs9,000001C8 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft6 = SEQ(0xFFFFFFFF<32>, __fminm(SLICE(ft0, real32, 0), SLICE(ft1, real32, 0)))"); + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|Mem0[sp + 456:real64] = fs9"); } [Test] - public void RiscV_rw_fmin_s() + public void RiscV_rw_c_fsd() { - Given_HexString("53031028"); - AssertCode( // fmin.s ft6,ft0,ft1 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft6 = SEQ(0xFFFFFFFF<32>, fminf(SLICE(ft0, real32, 0), SLICE(ft1, real32, 0)))"); + Given_RiscVInstructions(0x0000A604); // c.fsd\tfs1,8(a2) + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|Mem0[a2 + 8:real64] = fs1"); } [Test] - public void RiscV_rw_fmsub_d() + public void RiscV_rw_c_fsw() { - Given_HexString("47B29C63"); - AssertCode( // fmsub.d ft4,fs9,fs9,fa2,rup - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft4 = fs9 * fs9 - fa2"); + Given_32bitFloat(); + Given_HexString("00FC"); + AssertCode( // c.fsw s0,56(s0) + "0|L--|00010000(2): 1 instructions", + "1|L--|Mem0[s0 + 56:real32] = s0"); } [Test] - public void RiscV_rw_fmsub_h() + public void RiscV_rw_c_flw_32() { - Given_HexString("C7003355"); - AssertCode( // fmsub.h ft1,ft6,fs3,fa0,rne - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft1 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(ft6, real16, 0) * SLICE(fs3, real16, 0) - SLICE(fa0, real16, 0))"); + Given_32bitFloat(); + Given_HexString("C462"); + AssertCode( // c.flw fs1,4(a3) + "0|L--|00010000(2): 1 instructions", + "1|L--|fs1 = Mem0[a3 + 4:real32]"); } [Test] - public void RiscV_rw_fmsub_q() + public void RiscV_rw_c_fldsp() { - Given_128bitFloat(); - Given_HexString("C706FD56"); - AssertCode( // fmsub.q fa3,fs10,fa5,fa0,rne - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa3 = fs10 * fa5 - fa0"); + Given_RiscVInstructions(0x00003436); // c.fldsp\tfa3,00000228 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|fa3 = Mem0[sp + 552:real64]"); } [Test] - public void RiscV_rw_fmul_d() + public void RiscV_rw_c_fld() + { + Given_RiscVInstructions(0x00002E64); // c.fld\tfs1,216(a2) + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|fs1 = Mem0[a2 + 216:real64]"); + } + + [Test] + public void RiscV_rw_c_jal() + { + Given_32bitFloat(); + Given_HexString("912C"); + AssertCode( // c.jal 00000000230822D4 + "0|T--|00010000(2): 1 instructions", + "1|T--|call 00010254 (0)"); + } + + [Test] + public void RiscV_rw_c_nop() + { + Given_HexString("0100"); + AssertCode( // c.nop + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|nop"); + } + + [Test] + public void RiscV_rw_c_ld_64() + { + Given_HexString("C462"); + AssertCode( // c.ld s1,4(a3) + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s1 = Mem0[a3 + 128:word64]"); + } + + [Test] + public void RiscV_rw_c_sw() + { + Given_RiscVInstructions(0xC29C); // c.sw\ta3,0(a5) + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|Mem0[a3:word32] = SLICE(a5, word32, 0)"); + } + + [Test] + public void RiscV_rw_c_sdsp() + { + Given_RiscVInstructions(0xE4CE); // c.sdsp\ts3,00000048 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|Mem0[sp + 72:word64] = s3"); + } + + [Test] + public void RiscV_rw_c_lui() + { + Given_RiscVInstructions(0x00006585); // c.lui\ta1,00001000 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a1 = 0x1000000<64>"); + } + + [Test] + public void RiscV_rw_c_ld() + { + Given_RiscVInstructions(0x00006568); // c.ld\ta0,200(a0) + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a0 = Mem0[a0 + 200:word64]"); + } + + [Test] + public void RiscV_rw_c_li() + { + Given_RiscVInstructions(0x00004521); // c.li\ta0,00000008 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a0 = 8"); + } + + [Test] + public void RiscV_rw_c_li_minus3() + { + Given_RiscVInstructions(0x00005775); // c.li\ta4,FFFFFFFFFFFFFFFD + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a4 = -3"); + } + + [Test] + public void RiscV_rw_c_swsp() + { + Given_RiscVInstructions(0xC22A); // c.swsp\ta0,00000080 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|Mem0[sp + 4:word32] = SLICE(a0, word32, 0)"); + } + + [Test] + public void RiscV_rw_c_lwsp() + { + Given_RiscVInstructions(0x00004512); // c.lwsp\ta0,00000004 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a0 = CONVERT(Mem0[sp + 4:word32], word32, int64)"); + } + + [Test] + public void RiscV_rw_c_mv() + { + Given_RiscVInstructions(0x844E); // c.mv\ts0,s3 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s0 = s3"); + } + + [Test] + public void RiscV_rw_c_lw() + { + Given_RiscVInstructions(0x000043F4); // c.lw\ta3,68(a5) + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a3 = CONVERT(Mem0[a5 + 68:word32], word32, int64)"); + } + [Test] + public void RiscV_rw_c_or() + { + Given_RiscVInstructions(0x8E55); // c.or\ta2,a3 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a2 = a2 | a3"); + } + + [Test] + public void RiscV_rw_c_j() + { + Given_RiscVInstructions(0x0000B7D5); // c.j\t00000000001003FC + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|goto 000000000000FFE4"); + } + + [Test] + public void RiscV_rw_c_sub() + { + Given_RiscVInstructions(0x8D89); // c.sub\ta1,a0 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a1 = a1 - a0"); + } + + [Test] + public void RiscV_rw_c_j_backward() + { + Given_RiscVInstructions(0x0000BF1D); // c.j\t000000000000FF36 + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|goto 000000000000FF36"); + } + + [Test] + public void RiscV_rw_c_jr() + { + Given_RiscVInstructions(0x00008782); // c.jr\ta5 + AssertCode( + "0|T--|0000000000010000(2): 1 instructions", + "1|T--|goto a5"); + } + + [Test] + public void RiscV_rw_c_subw() + { + Given_RiscVInstructions(0x00009D1D); // c.subw\ta0,a5 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a0 = CONVERT(SLICE(a0 - a5, word32, 0), word32, int64)"); + } + + [Test] + public void RiscV_rw_c_slli() + { + Given_RiscVInstructions(0x0000040E); // c.slli\ts0,03 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s0 = s0 << 3"); + } + + [Test] + public void RiscV_rw_c_srli() + { + Given_RiscVInstructions(0x000083A9); // c.srli\ta5,0000000A + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a5 = a5 >>u 10"); + } + + [Test] + public void RiscV_rw_c_srai() + { + Given_RiscVInstructions(0x0000977D); // c.srai\ta4,0000003F + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|a4 = a4 >> 63"); + } + + [Test] + public void RiscV_rw_c_ldsp() + { + Given_RiscVInstructions(0x00006BA2); // c.ldsp\ts7,00000008 + AssertCode( + "0|L--|0000000000010000(2): 1 instructions", + "1|L--|s7 = Mem0[sp + 8:word64]"); + } + + [Test] + public void RiscV_rw_csrrc() + { + Given_HexString("73B00230"); + AssertCode( // csrrc zero,mstatus,t0 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__csrrc(mstatus, t0)"); + } + + [Test] + public void RiscV_rw_csrrci() + { + Given_HexString("F3770430"); + AssertCode( // csrrci a5,mstatus,00000008 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = __csrrc(mstatus, 8<64>)"); + } + + [Test] + public void RiscV_rw_csrrs() + { + Given_HexString("73292000"); + AssertCode( // csrrs s2,frm,zero + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s2 = __csrrs(frm, 0<64>)"); + } + + [Test] + public void RiscV_rw_csrrsi() + { + Given_HexString("73600430"); + AssertCode( // csrrsi zero,mstatus,00000008 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__csrrs(mstatus, 8<64>)"); + } + + [Test] + public void RiscV_rw_csrrw() + { + Given_HexString("73900930"); + AssertCode( // csrrw zero,mstatus,x19 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__csrrw(mstatus, s3)"); + } + + [Test] + public void RiscV_rw_csrw_unknown() + { + Given_HexString("7310C5BF"); + AssertCode( // csrw\t0xbfc,a0 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__csrrw(0xBFC, a0)"); + } + + [Test] + public void RiscV_rw_csrrwi() + { + Given_HexString("73D02334"); + AssertCode( // csrrwi zero,mcause,00000007 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__csrrw(mcause, 7<64>)"); + } + + [Test] + public void RiscV_rw_div() + { + Given_HexString("B3C5E502"); + AssertCode( // div a1,a1,a4 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a1 = a1 / a4"); + } + + [Test] + public void RiscV_rw_divu() + { + Given_RiscVInstructions(0x02B6D6B3); // divu a3,a3,a1 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = a3 /u a1"); + } + + [Test] + public void RiscV_rw_divuw() + { + Given_RiscVInstructions(0x02C857BB); // divuw\ta5,a6,a2 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = CONVERT(SLICE(a6 /u a2, word32, 0), word32, int64)"); + } + + [Test] + public void RiscV_rw_divw() + { + Given_RiscVInstructions(0x02B4443B); // divw\ts0,s0,a1 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s0 = CONVERT(SLICE(s0 / a1, word32, 0), word32, int64)"); + } + + [Test] + public void RiscV_rw_ebreak() + { + Given_HexString("73001000"); + AssertCode( // ebreak + "0|H--|0000000000010000(4): 1 instructions", + "1|L--|__ebreak()"); + } + + [Test] + public void RiscV_rw_ecall() + { + Given_HexString("73000000"); + AssertCode( // ecall + "0|T--|0000000000010000(4): 1 instructions", + "1|L--|__syscall()"); + } + + [Test] + public void RiscV_rw_fadd_d() + { + Given_HexString("D3383102"); + AssertCode( // fadd.d fa7,ft2,ft3,rup + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa7 = ft2 + ft3"); + } + + [Test] + public void RiscV_rw_fadd_h() + { + Given_HexString("53C60605"); + AssertCode( // fadd.h fa2,fa3,fa6,rmm + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa2 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(fa3, real16, 0) + SLICE(fa6, real16, 0))"); + } + + [Test] + public void RiscV_rw_fadd_q() + { + Given_128bitFloat(); + Given_HexString("D3832607"); + AssertCode( // fadd.q ft7,fa3,fs2,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft7 = fa3 + fs2"); + } + + [Test] + public void RiscV_rw_fadd_s() + { + Given_HexString("53495800"); + AssertCode( // fadd.s fs2,fa6,ft5,rmm + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs2 = SEQ(0xFFFFFFFF<32>, SLICE(fa6, real32, 0) + SLICE(ft5, real32, 0))"); + } + + [Test] + public void RiscV_rw_fabs_d() + { + Given_HexString("D3278422"); + AssertCode( // fabs.d fa5,fs0 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa5 = fabs(fs0)"); + } + + [Test] + public void RiscV_rw_fclass_d() + { + Given_HexString("539506E2"); + AssertCode( // fclass.d a0,fa3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = __fclass(fa3)"); + } + + [Test] + public void RiscV_rw_fclass_h() + { + Given_HexString("531607E4"); + AssertCode( // fclass.h a2,fa4 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a2 = __fclass(SLICE(fa4, real16, 0))"); + } + + [Test] + public void RiscV_rw_fclass_q() + { + Given_128bitFloat(); + Given_HexString("D31603E6"); + AssertCode( // fclass.q a3,ft6 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = __fclass(ft6)"); + } + + [Test] + public void RiscV_rw_fclass_s() + { + Given_HexString("D31606E0"); + AssertCode( // fclass.s a3,fa2 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = __fclass(SLICE(fa2, real32, 0))"); + } + + [Test] + public void RiscV_rw_fcvt_d_h() + { + Given_HexString("53872842"); + AssertCode( // fcvt.d.h fa4,fa7,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = CONVERT(SLICE(fa7, int16, 0), int16, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_d_l() + { + Given_HexString("D3F026D2"); + AssertCode( // fcvt.d.l ft1,a3,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft1 = CONVERT(a3, int64, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_d_lu() { - Given_HexString("5377D712"); - AssertCode( // fmul.d fa4,fa4,fa3 + Given_HexString("53F739D2"); + AssertCode( // fcvt.d.lu fa4,s3 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = fa4 * fa3"); + "1|L--|fa4 = CONVERT(s3, uint64, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_d_q() + { + Given_128bitFloat(); + Given_HexString("D37B3B42"); + AssertCode( // fcvt.d.q fs7,fs6 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs7 = SEQ(0xFFFFFFFFFFFFFFFF<64>, CONVERT(fs6, real128, real64))"); + } + + [Test] + public void RiscV_rw_fcvt_d_s() + { + Given_RiscVInstructions(0x42070753u); // fcvt.d.s\tfa4,fa4 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = CONVERT(SLICE(fa4, real32, 0), real32, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_d_w() + { + Given_HexString("538706D2"); + AssertCode( // fcvt.d.w fa4,a3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = CONVERT(SLICE(a3, int32, 0), int32, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_d_wu() + { + Given_HexString("538416D2"); + AssertCode( // fcvt.d.wu fs0,a3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs0 = CONVERT(SLICE(a3, uint32, 0), uint32, real64)"); + } + + [Test] + public void RiscV_rw_fcvt_h_d() + { + Given_HexString("D3261744"); + AssertCode( // fcvt.h.d fa3,a4,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(fa4, real64, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_l() + { + Given_HexString("D32628D4"); + AssertCode( // fcvt.h.l fa3,a6,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(a6, int64, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_lu() + { + Given_HexString("53C638D4"); + AssertCode( // fcvt.h.lu fa2,a7,rmm + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa2 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(a7, uint64, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_q() + { + Given_128bitFloat(); + Given_HexString("D3283644"); + AssertCode( // fcvt.h.q fa7,a2,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa7 = SEQ(0x0FFFFFFFFFFFFFFFF<112>, CONVERT(fa2, real128, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_s() + { + Given_HexString("D3750744"); + AssertCode( // fcvt.h.s fa1,a4,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa1 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(SLICE(fa4, real32, 0), real32, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_w() + { + Given_HexString("D37607D4"); + AssertCode( // fcvt.h.w fa3,a4,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(SLICE(a4, int32, 0), int32, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_h_wu() + { + Given_HexString("53F815D4"); + AssertCode( // fcvt.h.wu fa6,a1,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa6 = SEQ(0xFFFFFFFFFFFF<48>, CONVERT(SLICE(a1, uint32, 0), uint32, real16))"); + } + + [Test] + public void RiscV_rw_fcvt_l_d() + { + Given_HexString("D39020C2"); + AssertCode( // fcvt.l.d ra,ft1,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ra = CONVERT(ft1, real64, int64)"); + } + + [Test] + public void RiscV_rw_fcvt_l_h() + { + Given_HexString("D31827C4"); + AssertCode( // fcvt.l.h a7,fa4,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a7 = CONVERT(SLICE(fa4, real16, 0), real16, int64)"); + } + + [Test] + public void RiscV_rw_fcvt_l_q() + { + Given_128bitFloat(); + Given_HexString("D32121C6"); + AssertCode( // fcvt.l.q gp,ft2,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|gp = CONVERT(ft2, real128, int64)"); + } + + [Test] + public void RiscV_rw_fcvt_l_s() + { + Given_HexString("53952FC0"); + AssertCode( // fcvt.l.s a0,ft11,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = CONVERT(SLICE(ft11, real32, 0), real32, int64)"); + } + + [Test] + public void RiscV_rw_fcvt_lu_d() + { + Given_HexString("531534C2"); + AssertCode( // fcvt.lu.d a0,fs0 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = CONVERT(fs0, real64, uint64)"); + } + + [Test] + public void RiscV_rw_fcvt_lu_h() + { + Given_HexString("D38537C4"); + AssertCode( // fcvt.lu.h a1,fa5,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a1 = CONVERT(SLICE(fa5, real16, 0), real16, uint64)"); + } + + [Test] + public void RiscV_rw_fcvt_lu_s() + { + Given_HexString("D39437C0"); + AssertCode( // fcvt.lu.s s1,fa5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s1 = CONVERT(SLICE(fa5, real32, 0), real32, uint64)"); + } + + [Test] + public void RiscV_rw_fcvt_q_d() + { + Given_128bitFloat(); + Given_HexString("D3891A46"); + AssertCode( // fcvt.q.d fs3,fs5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs3 = CONVERT(SLICE(fs5, real64, 0), real64, real128)"); + } + + [Test] + public void RiscV_rw_fcvt_q_h() + { + Given_128bitFloat(); + Given_HexString("D3082846"); + AssertCode( // fcvt.q.h fa7,fa6,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa7 = CONVERT(SLICE(fa6, real16, 0), real16, real128)"); + } + + [Test] + public void RiscV_rw_fcvt_q_s() + { + Given_128bitFloat(); + Given_HexString("D30D0A46"); + AssertCode( // fcvt.q.s fs11,fs4 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs11 = CONVERT(SLICE(fs4, int32, 0), int32, real128)"); + } + + [Test] + public void RiscV_rw_fcvt_q_w() + { + Given_128bitFloat(); + Given_HexString("D30303D6"); + AssertCode( // fcvt.q.w ft7,t1,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft7 = CONVERT(SLICE(t1, int32, 0), int32, real128)"); + } + + [Test] + public void RiscV_rw_fcvt_q_wu() + { + Given_128bitFloat(); + Given_HexString("D30212D6"); + AssertCode( // fcvt.q.wu ft5,tp,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft5 = CONVERT(SLICE(tp, uint32, 0), uint32, real128)"); + } + + [Test] + public void RiscV_rw_fcvt_s_d() + { + Given_HexString("D3261C40"); + AssertCode( // fcvt.s.d fa3,fs8 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFF<32>, CONVERT(fs8, real64, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_s_h() + { + Given_HexString("53862740"); + AssertCode( // fcvt.s.h fa2,fa5,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa2 = SEQ(0xFFFFFFFF<32>, CONVERT(SLICE(fa5, real16, 0), real16, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_s_l() + { + Given_HexString("D3F328D0"); + AssertCode( // fcvt.s.l ft7,a7 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft7 = SEQ(0xFFFFFFFF<32>, CONVERT(a7, int64, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_s_lu() + { + Given_HexString("D3F734D0"); + AssertCode( // fcvt.s.lu fa5,s1 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa5 = SEQ(0xFFFFFFFF<32>, CONVERT(s1, uint64, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_s_q() + { + Given_128bitFloat(); + Given_HexString("53FD3C40"); + AssertCode( // fcvt.s.q fs10,fs9 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs10 = SEQ(0x0FFFFFFFFFFFFFFFF<96>, CONVERT(fs9, real128, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_s_w() + { + Given_32bitFloat(); + Given_HexString("537404D0"); + AssertCode( // fcvt.s.w s0,fs0 + "0|L--|00010000(4): 1 instructions", + "1|L--|fs0 = CONVERT(s0, int32, real32)"); + } + + [Test] + public void RiscV_rw_fcvt_s_wu() + { + Given_HexString("53F719D0"); + AssertCode( // fcvt.s.wu fs4,a3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = SEQ(0xFFFFFFFF<32>, CONVERT(SLICE(s3, uint32, 0), uint32, real32))"); + } + + [Test] + public void RiscV_rw_fcvt_w_d() + { + Given_HexString("D31801C2"); + AssertCode( // fcvt.w.d a7,ft2,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a7 = SEQ(0xFFFFFFFF<32>, CONVERT(ft2, real64, int32))"); + } + + [Test] + public void RiscV_rw_fcvt_w_h() + { + Given_HexString("D3F805C4"); + AssertCode( // fcvt.w.h a7,fa1,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a7 = SEQ(0xFFFFFFFF<32>, CONVERT(SLICE(fa1, real16, 0), real16, int32))"); + } + + [Test] + public void RiscV_rw_fcvt_w_q() + { + Given_128bitFloat(); + Given_HexString("530001C6"); + AssertCode( // fcvt.w.q zero,ft2,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|0<64> = SEQ(0xFFFFFFFF<32>, CONVERT(ft2, real128, int32))"); + } + + [Test] + public void RiscV_rw_fcvt_w_s() + { + Given_32bitFloat(); + Given_HexString("D31704C0"); + AssertCode( // fcvt.w.s a5,fs0 + "0|L--|00010000(4): 1 instructions", + "1|L--|a5 = CONVERT(fs0, real32, int32)"); + } + + [Test] + public void RiscV_rw_fcvt_wu_d() + { + Given_HexString("D39719C2"); + AssertCode( // fcvt.wu.d a5,fs3,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = SEQ(0xFFFFFFFF<32>, CONVERT(fs3, real64, uint32))"); + } + + [Test] + public void RiscV_rw_fcvt_wu_h() + { + Given_HexString("53F716C4"); + AssertCode( // fcvt.wu.h a4,fa3,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a4 = SEQ(0xFFFFFFFF<32>, CONVERT(SLICE(fa3, real16, 0), real16, uint32))"); + } + + [Test] + public void RiscV_rw_fcvt_wu_q() + { + Given_128bitFloat(); + Given_HexString("D31013C6"); + AssertCode( // fcvt.wu.q ra,ft6,rtz + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ra = SEQ(0xFFFFFFFF<32>, CONVERT(ft6, real128, uint32))"); + } + + [Test] + public void RiscV_rw_fcvt_wu_s() + { + Given_32bitFloat(); + Given_HexString("539517C0"); + AssertCode( // fcvt.wu.s a0,fa5 + "0|L--|00010000(4): 1 instructions", + "1|L--|a0 = CONVERT(fa5, real32, uint32)"); } [Test] - public void RiscV_rw_fnmadd_d() + public void RiscV_rw_fdiv_d() { - Given_HexString("4FFF7D5A"); - AssertCode( // fnmadd.d ft10,fs11,ft7,fa1,dyn + Given_HexString("D377F71A"); + AssertCode( // fdiv.d fa5,fa4,fa5 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft10 = -(fs11 * ft7) - fa1"); + "1|L--|fa5 = fa4 / fa5"); } [Test] - public void RiscV_rw_fnmadd_h() + public void RiscV_rw_fdiv_h() { - Given_HexString("4F81A285"); - AssertCode( // fnmadd.h ft2,ft5,fs10,fa6,rne + Given_HexString("5307181D"); + AssertCode( // fdiv.h fa4,fa6,fa7,rne "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft2 = SEQ(0xFFFFFFFFFFFF<48>, -(SLICE(ft5, real16, 0) * SLICE(fs10, real16, 0)) - SLICE(fa6, real16, 0))"); + "1|L--|fa4 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(fa6, real16, 0) / SLICE(fa7, real16, 0))"); } + [Test] + public void RiscV_rw_fdiv_s() + { + Given_32bitFloat(); + Given_HexString("5374F418"); + AssertCode( // fdiv.s fs0,fs0,fa5 + "0|L--|00010000(4): 1 instructions", + "1|L--|fs0 = fs0 / fa5"); + } [Test] - public void RiscV_rw_fnmadd_q() + public void RiscV_rw_fdiv_q() { Given_128bitFloat(); - Given_HexString("4FF39707"); - AssertCode( // fnmadd.q ft6,fa5,fs9,ft0,dyn + Given_HexString("53CDBC1F"); + AssertCode( // fdiv.q fs10,fs9,fs11,rmm + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs10 = fs9 / fs11"); + } + + [Test] + public void RiscV_rw_fence() + { + Given_HexString("0F00F00F"); + AssertCode( // fence iorw,iorw "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft6 = -(fa5 * fs9) - ft0"); + "1|L--|__fence(iorw, iorw)"); } [Test] - public void RiscV_rw_fnmadd_s() + public void RiscV_rw_fence_i() { - Given_32bitFloat(); - Given_RiscVInstructions(0x00B3FDCF); // fnmadd.s\tfs11,ft7,fa1,ft0 - AssertCode( - "0|L--|00010000(4): 1 instructions", - "1|L--|fs11 = -(ft7 * fa1) - ft0"); + Given_HexString("0F100000"); + AssertCode( // fence.i + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|__fence_i()"); } [Test] - public void RiscV_rw_fnmsub_d() + public void RiscV_rw_fence_tso() { - Given_HexString("4BA9AA8A"); - AssertCode( // fnmsub.d fs2,fs5,fa0,fa7,rdn + Given_HexString("0F003083"); + AssertCode( // fence.tso "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fs2 = -(fs5 * fa0) + fa7"); + "1|L--|__fence_tso()"); } [Test] - public void RiscV_rw_fnmsub_h() + public void RiscV_rw_feq_d() { - Given_HexString("4B00BE9D"); - AssertCode( // fnmsub.h ft0,ft8,fs11,fs3,rne + Given_HexString("D327D7A2"); + AssertCode( // feq.d a5,fa4,fa3 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft0 = SEQ(0xFFFFFFFFFFFF<48>, -(SLICE(ft8, real16, 0) * SLICE(fs11, real16, 0)) + SLICE(fs3, real16, 0))"); + "1|L--|a5 = CONVERT(fa4 == fa3, bool, word64)"); } + [Test] + public void RiscV_rw_feq_h() + { + Given_HexString("D3A7F5A4"); + AssertCode( // feq.h a5,fa1,fa5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = CONVERT(SLICE(fa1, real16, 0) == SLICE(fa5, real16, 0), bool, word64)"); + } [Test] - public void RiscV_rw_fnmsub_q() + public void RiscV_rw_feq_q() { Given_128bitFloat(); - Given_HexString("4B008947"); - AssertCode( // fnmsub.q ft0,fs2,fs8,fs0,rne - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft0 = -(fs2 * fs8) + fs0"); + Given_HexString("D3A321A6"); + AssertCode( // feq.q t2,ft3,ft2 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t2 = CONVERT(ft3 == ft2, bool, word64)"); } [Test] - public void RiscV_rw_fsgnj_d() + public void RiscV_rw_feq_s() { - Given_HexString("53822523"); - AssertCode( // fsgnj.d ft4,fa1,fs2 + // 1010000 011110111001001111 10100 11 + Given_RiscVInstructions(0xA0F727D3u); // feq.s\ta5,fa4,fa5 + AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft4 = __fsgnj(fa1, fs2)"); + "1|L--|a5 = CONVERT(SLICE(fa4, real32, 0) == SLICE(fa5, real32, 0), bool, word64)"); } [Test] - public void RiscV_rw_fsgnj_s() + public void RiscV_rw_fld() { - Given_HexString("53802020"); - AssertCode( // fsgnj.s ft0,ft1,ft2 + Given_HexString("07B6870F"); + AssertCode( // fld fa2,0xF8(a5) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft0 = SEQ(0xFFFFFFFF<32>, __fsgnj(SLICE(ft1, real32, 0), SLICE(ft2, real32, 0)))"); + "1|L--|fa2 = Mem0[a5 + 248:real64]"); } [Test] - public void RiscV_rw_fsgnjn_d() + public void RiscV_rw_fle_d() { - Given_HexString("D391C422"); - AssertCode( // fsgnjn.d ft3,fs1,fa2 + Given_HexString("D387E7A2"); + AssertCode( // fle.d a5,fa5,fa4 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft3 = __fsgnjn(fs1, fa2)"); + "1|L--|a5 = CONVERT(fa5 <= fa4, bool, word64)"); } [Test] - public void RiscV_rw_fsgnjn_s() + public void RiscV_rw_fle_h() { - Given_HexString("D3914320"); - AssertCode( // fsgnjn.s ft3,ft7,ft4 + Given_HexString("D308E6A4"); + AssertCode( // fle.h a7,fa2,fa4 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft3 = SEQ(0xFFFFFFFF<32>, __fsgnjn(SLICE(ft7, real32, 0), SLICE(ft4, real32, 0)))"); + "1|L--|a7 = CONVERT(SLICE(fa2, real16, 0) <= SLICE(fa4, real16, 0), bool, word64)"); } [Test] - public void RiscV_rw_fsgnjx_d() + public void RiscV_rw_fle_q() { - Given_HexString("53A41123"); - AssertCode( // fsgnjx.d fs0,ft3,fa7 + Given_128bitFloat(); + Given_HexString("530470A6"); + AssertCode( // fle.q s0,ft0,ft7 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s0 = CONVERT(ft0 <= ft7, bool, word64)"); + } + + [Test] + public void RiscV_rw_fle_s() + { + Given_HexString("D307F7A0"); + AssertCode( // fle.s a5,fa4,fa5 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fs0 = __fsgnjx(ft3, fa7)"); + "1|L--|a5 = CONVERT(SLICE(fa4, real32, 0) <= SLICE(fa5, real32, 0), bool, word64)"); } [Test] - public void RiscV_rw_fsgnjx_s() + public void RiscV_rw_flh() { - Given_HexString("532E5120"); - AssertCode( // fsgnjx.s ft8,ft2,ft5 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft8 = SEQ(0xFFFFFFFF<32>, __fsgnjx(SLICE(ft2, real32, 0), SLICE(ft5, real32, 0)))"); + Given_HexString("0797C800"); + AssertCode( // flh fa4,0xC(a7) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = SEQ(0xFFFFFFFFFFFF<48>, Mem0[a7 + 12:real16])"); } + [Test] - public void RiscV_rw_fsqrt_d() + public void RiscV_rw_fli_d() { - Given_HexString("5377065A"); - AssertCode( // fsqrt.d fa4,fa2 + Given_RiscVInstructions(0xF21007D3u); // fli.d\tfa5,-1.0 + AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = sqrt(fa2)"); + "1|L--|fa5 = -1.0F"); } [Test] - public void RiscV_rw_fsqrt_s() + public void RiscV_rw_fli_h() { - Given_HexString("D3710058"); - AssertCode( // fsqrt.s ft3,ft0 + Given_HexString("D30F1CF4"); + AssertCode( // fli.h ft11,8.0 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft3 = SEQ(0xFFFFFFFF<32>, sqrtf(SLICE(ft0, real32, 0)))"); + "1|L--|ft11 = 8.0F"); } [Test] - public void RiscV_rw_fsub_s() + public void RiscV_rw_fli_q() { - Given_32bitFloat(); - Given_HexString("5375A708"); - AssertCode( // fsub.s fa0,fa4,fa0 - "0|L--|00010000(4): 1 instructions", - "1|L--|fa0 = fa4 - fa0"); + Given_128bitFloat(); + Given_HexString("D30214F6"); + AssertCode( // fli.q ft5,0.25 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft5 = 0.25F"); } [Test] - public void RiscV_rw_jal() + public void RiscV_rw_fli_s() { - Given_RiscVInstructions(0x9F4FF06F); // jal\tzero,00000000000FF1F4 + Given_RiscVInstructions(0xF01587D3u); // fli.s\tfa5,0.3125 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|goto 000000000000F1F4"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa5 = 0.4375F"); } [Test] - public void RiscV_rw_addi_zero() + public void RiscV_rw_flq() { - Given_RiscVInstructions(0xFFF00413); // addi s0,zero,-00000001 - AssertCode( + Given_128bitFloat(); + Given_HexString("0740E391"); + AssertCode( // flq ft0,2334(t1) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s0 = -1"); + "1|L--|ft0 = Mem0[t1 + 2334:real128]"); } [Test] - public void RiscV_rw_addiw() + public void RiscV_rw_flt_d() { - Given_RiscVInstructions(0x0087879Bu); // addiw\ta5,a5,+00000008 - AssertCode( + Given_HexString("D317C7A2"); + AssertCode( // flt.d a5,fa4,fa2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(CONVERT(a5, word64, word32) + 8, word32, int64)"); + "1|L--|a5 = CONVERT(fa4 < fa2, bool, word64)"); } [Test] - public void RiscV_rw_addiw_sign_extend() + public void RiscV_rw_flt_h() { - Given_RiscVInstructions(0x00002301); // c.addiw\tt1,00000000 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|t1 = CONVERT(SLICE(t1, word32, 0), word32, int64)"); + Given_HexString("D39606A5"); + AssertCode( // flt.h a3,fa3,fa6 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = CONVERT(SLICE(fa3, real16, 0) < SLICE(fa6, real16, 0), bool, word64)"); } [Test] - public void RiscV_rw_c_addiw() + public void RiscV_rw_flt_s() { - Given_RiscVInstructions(0x00002405); // c.addiw\ts0,00000001 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s0 = CONVERT(SLICE(s0 + 1, word32, 0), word32, int64)"); + Given_32bitFloat(); + Given_HexString("D397E7A0"); + AssertCode( // flt.s a5,fa5,fa4 + "0|L--|00010000(4): 1 instructions", + "1|L--|a5 = CONVERT(fa5 < fa4, bool, word32)"); } [Test] - public void RiscV_rw_c_addiw_negative() + public void RiscV_rw_flw() { - Given_RiscVInstructions(0x0000347D); // c.addiw\ts0,FFFFFFFFFFFFFFFF + Given_RiscVInstructions(0x03492707u); // flw\tfa4,s2,+00000034 AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s0 = CONVERT(SLICE(s0 + -1, word32, 0), word32, int64)"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = SEQ(0xFFFFFFFF<32>, Mem0[s2 + 52:real32])"); } [Test] - public void RiscV_rw_c_fsdsp() + public void RiscV_rw_fmadd_d() { - Given_RiscVInstructions(0xA7E6); // c.fsdsp\tfs9,000001C8 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|Mem0[sp + 456:real64] = fs9"); + Given_HexString("43F16303"); + AssertCode( // fmadd.d ft2,ft7,fs6,ft0,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft2 = ft7 * fs6 + ft0"); } [Test] - public void RiscV_rw_c_fsd() + public void RiscV_rw_fmadd_s() { - Given_RiscVInstructions(0x0000A604); // c.fsd\tfs1,8(a2) + Given_32bitFloat(); + Given_RiscVInstructions(0x8093FD43); AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|Mem0[a2 + 8:real64] = fs1"); + "0|L--|00010000(4): 1 instructions", + "1|L--|fs10 = ft7 * fs1 + fa6"); } [Test] - public void RiscV_rw_c_fsw() + public void RiscV_rw_fmadd_h() { - Given_32bitFloat(); - Given_HexString("00FC"); - AssertCode( // c.fsw s0,56(s0) - "0|L--|00010000(2): 1 instructions", - "1|L--|Mem0[s0 + 56:real32] = s0"); + Given_HexString("C3250264"); + AssertCode( // fmadd.h fa1,ft4,ft0,fa2,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa1 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(ft4, real16, 0) * SLICE(ft0, real16, 0) + SLICE(fa2, real16, 0))"); } [Test] - public void RiscV_rw_c_jal() + public void RiscV_rw_fmadd_q() { - Given_32bitFloat(); - Given_HexString("912C"); - AssertCode( // c.jal 00000000230822D4 - "0|T--|00010000(2): 1 instructions", - "1|T--|call 00010254 (0)"); + Given_128bitFloat(); + Given_HexString("432A8146"); + AssertCode( // fmadd.q fs4,ft2,fs0,fs0,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs4 = ft2 * fs0 + fs0"); } [Test] - public void RiscV_rw_c_nop() + public void RiscV_rw_fmax_d() { - Given_HexString("0100"); - AssertCode( // c.nop - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|nop"); + Given_HexString("5311402A"); + AssertCode( // fmax.d ft2,ft0,ft4 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft2 = __fmax(ft0, ft4)"); } [Test] - public void RiscV_rw_fclass_d() + public void RiscV_rw_fmax_h() { - Given_HexString("539506E2"); - AssertCode( // fclass.d a0,fa3 + Given_HexString("D395C82C"); + AssertCode( // fmax.h fa1,fa7,fa2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a0 = __fclass(fa3)"); + "1|L--|fa1 = SEQ(0xFFFFFFFFFFFF<48>, __fmax(SLICE(fa7, real16, 0), SLICE(fa2, real16, 0)))"); } [Test] - public void RiscV_rw_fclass_s() + public void RiscV_rw_fmax_s() { - Given_HexString("D31606E0"); - AssertCode( // fclass.s a3,fa2 + Given_HexString("D3122228"); + AssertCode( // fmax.s ft5,ft4,ft2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a3 = __fclass(SLICE(fa2, real32, 0))"); + "1|L--|ft5 = SEQ(0xFFFFFFFF<32>, __fmax(SLICE(ft4, real32, 0), SLICE(ft2, real32, 0)))"); } [Test] - public void RiscV_rw_fcvt_d_lu() + public void RiscV_rw_fmaxm_d() { - Given_HexString("53F739D2"); - AssertCode( // fcvt.d.lu fa4,s3 + Given_HexString("5331402A"); // fmaxm.d\tft2,ft0,ft4" + AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = CONVERT(s3, uint64, real64)"); + "1|L--|ft2 = __fmaxm(ft0, ft4)"); } [Test] - public void RiscV_rw_fcvt_d_w() + public void RiscV_rw_fmaxm_h() { - Given_HexString("538706D2"); - AssertCode( // fcvt.d.w fa4,a3 + Given_HexString("D3B5C82C"); + AssertCode( // fmaxm.h fa1,fa7,fa2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = CONVERT(SLICE(a3, int32, 0), int32, real64)"); + "1|L--|fa1 = SEQ(0xFFFFFFFFFFFF<48>, __fmaxm(SLICE(fa7, real16, 0), SLICE(fa2, real16, 0)))"); } [Test] - public void RiscV_rw_fcvt_d_wu() + public void RiscV_rw_fmaxm_s() { - Given_HexString("538416D2"); - AssertCode( // fcvt.d.wu fs0,a3 + Given_HexString("D3322228"); + AssertCode( // fmaxm.s ft5,ft4,ft2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fs0 = CONVERT(SLICE(a3, uint32, 0), uint32, real64)"); + "1|L--|ft5 = SEQ(0xFFFFFFFF<32>, __fmaxm(SLICE(ft4, real32, 0), SLICE(ft2, real32, 0)))"); } [Test] - public void RiscV_rw_fcvt_lu_d() + public void RiscV_rw_fmin_d() { - Given_HexString("531534C2"); - AssertCode( // fcvt.lu.d a0,fs0 + Given_HexString("D301102A"); + AssertCode( // fmin.d ft3,ft0,ft1 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a0 = CONVERT(fs0, real64, uint64)"); + "1|L--|ft3 = __fmin(ft0, ft1)"); } [Test] - public void RiscV_rw_fcvt_lu_s() + public void RiscV_rw_fmin_h() { - Given_HexString("D39437C0"); - AssertCode( // fcvt.lu.s s1,fa5 + Given_HexString("5387F62C"); + AssertCode( // fmin.h fa4,fa3,fa5 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s1 = CONVERT(SLICE(fa5, real32, 0), real32, uint64)"); + "1|L--|fa4 = SEQ(0xFFFFFFFFFFFF<48>, __fmin(SLICE(fa3, real16, 0), SLICE(fa5, real16, 0)))"); } [Test] - public void RiscV_rw_fcvt_s_d() + public void RiscV_rw_fmin_s() { - Given_HexString("D3261C40"); - AssertCode( // fcvt.s.d fa3,fs8 + Given_HexString("53031028"); + AssertCode( // fmin.s ft6,ft0,ft1 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa3 = SEQ(0xFFFFFFFF<32>, CONVERT(fs8, real64, real32))"); + "1|L--|ft6 = SEQ(0xFFFFFFFF<32>, __fmin(SLICE(ft0, real32, 0), SLICE(ft1, real32, 0)))"); } [Test] - public void RiscV_rw_fcvt_s_l() + public void RiscV_rw_fminm_d() { - Given_HexString("D3F328D0"); - AssertCode( // fcvt.s.l ft7,a7 + Given_HexString("D321102A"); + AssertCode( // fminm.d ft3,ft0,ft1 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft7 = SEQ(0xFFFFFFFF<32>, CONVERT(a7, int64, real32))"); + "1|L--|ft3 = __fminm(ft0, ft1)"); } [Test] - public void RiscV_rw_fcvt_s_lu() + public void RiscV_rw_fminm_h() { - Given_HexString("D3F734D0"); - AssertCode( // fcvt.s.lu fa5,s1 + Given_HexString("53A7F62C"); + AssertCode( // fminm.h fa4,fa3,fa5 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = SEQ(0xFFFFFFFF<32>, CONVERT(s1, uint64, real32))"); + "1|L--|fa4 = SEQ(0xFFFFFFFFFFFF<48>, __fminm(SLICE(fa3, real16, 0), SLICE(fa5, real16, 0)))"); } [Test] - public void RiscV_rw_fcvt_s_w() + public void RiscV_rw_fminm_s() { - Given_32bitFloat(); - Given_HexString("537404D0"); - AssertCode( // fcvt.s.w s0,fs0 - "0|L--|00010000(4): 1 instructions", - "1|L--|fs0 = CONVERT(s0, int32, real32)"); + Given_HexString("53231028"); // fminm.s\tft6,ft0,ft1 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft6 = SEQ(0xFFFFFFFF<32>, __fminm(SLICE(ft0, real32, 0), SLICE(ft1, real32, 0)))"); } [Test] - public void RiscV_rw_fcvt_s_wu() + public void RiscV_rw_fmsub_d() { - Given_HexString("53F719D0"); - AssertCode( // fcvt.s.wu fs4,a3 + Given_HexString("47B29C63"); + AssertCode( // fmsub.d ft4,fs9,fs9,fa2,rup "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = SEQ(0xFFFFFFFF<32>, CONVERT(SLICE(s3, uint32, 0), uint32, real32))"); + "1|L--|ft4 = fs9 * fs9 - fa2"); } [Test] - public void RiscV_rw_fcvt_w_s() + public void RiscV_rw_fmsub_h() { - Given_32bitFloat(); - Given_HexString("D31704C0"); - AssertCode( // fcvt.w.s a5,fs0 - "0|L--|00010000(4): 1 instructions", - "1|L--|a5 = CONVERT(fs0, real32, int32)"); + Given_HexString("C7003355"); + AssertCode( // fmsub.h ft1,ft6,fs3,fa0,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft1 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(ft6, real16, 0) * SLICE(fs3, real16, 0) - SLICE(fa0, real16, 0))"); } [Test] - public void RiscV_rw_fcvt_wu_s() + public void RiscV_rw_fmsub_q() { - Given_32bitFloat(); - Given_HexString("539517C0"); - AssertCode( // fcvt.wu.s a0,fa5 - "0|L--|00010000(4): 1 instructions", - "1|L--|a0 = CONVERT(fa5, real32, uint32)"); + Given_128bitFloat(); + Given_HexString("C706FD56"); + AssertCode( // fmsub.q fa3,fs10,fa5,fa0,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = fs10 * fa5 - fa0"); } [Test] - public void RiscV_rw_fdiv_s() + public void RiscV_rw_fmul_d() { - Given_32bitFloat(); - Given_HexString("5374F418"); - AssertCode( // fdiv.s fs0,fs0,fa5 - "0|L--|00010000(4): 1 instructions", - "1|L--|fs0 = fs0 / fa5"); + Given_HexString("5377D712"); + AssertCode( // fmul.d fa4,fa4,fa3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = fa4 * fa3"); } [Test] - public void RiscV_rw_feq_d() + public void RiscV_rw_fmul_h() { - Given_HexString("D327D7A2"); - AssertCode( // feq.d a5,fa4,fa3 + Given_HexString("53A6E714"); + AssertCode( // fmul.h fa2,fa5,fa4,rdn "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(fa4 == fa3, bool, word64)"); + "1|L--|fa2 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(fa5, real16, 0) * SLICE(fa4, real16, 0))"); } [Test] - public void RiscV_rw_c_flw_32() + public void RiscV_rw_fmul_q() { - Given_32bitFloat(); - Given_HexString("C462"); - AssertCode( // c.flw fs1,4(a3) - "0|L--|00010000(2): 1 instructions", - "1|L--|fs1 = Mem0[a3 + 4:real32]"); + Given_128bitFloat(); + Given_HexString("533e1417"); + AssertCode( // fmul.q ft8,fs0,fa7,rup + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft8 = fs0 * fa7"); } [Test] - public void RiscV_rw_c_ld_64() + public void RiscV_rw_fmul_s() { - Given_HexString("C462"); - AssertCode( // c.ld s1,4(a3) - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s1 = Mem0[a3 + 128:word64]"); + Given_32bitFloat(); + Given_HexString("53749510"); + AssertCode( // fmul.s fs0,fa0,fs1 + "0|L--|00010000(4): 1 instructions", + "1|L--|fs0 = fa0 * fs1"); } [Test] - public void RiscV_rw_x1() + public void RiscV_rw_fmv_d_x() { - Given_RiscVInstructions(0x12E50463u); // beq\ta0,a4,0000000000100128 + Given_RiscVInstructions(0xF2070753u); // fmv.d.x\tfa4,a4 AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|if (a0 == a4) branch 0000000000010128"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = a4"); } [Test] - public void RiscV_rw_jalr() + public void RiscV_rw_fmv_h_x() { - Given_RiscVInstructions(0x00078067u); // jalr\tzero,a5,+00000000 - AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|goto a5"); + Given_HexString("530608F4"); + AssertCode( // fmv.h.x fa2,a6 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v5 = SLICE(a6, int16, 0)", + "2|L--|fa2 = SEQ(0xFFFFFFFFFFFF<48>, v5)"); } [Test] - public void RiscV_rw_or() + public void RiscV_rw_fmv_x_d() { - Given_RiscVInstructions(0x01846433u); // or\ts0,s0,s8 + Given_RiscVInstructions(0xE2070753u); // fmv.d.x\tfa4,a4 AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s0 = s0 | s8"); + "1|L--|a4 = fa4"); } [Test] - public void RiscV_rw_add() + public void RiscV_rw_fmv_x_h() { - Given_RiscVInstructions(0x00E787B3u); // add\ta5,a5,a4 - AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = a5 + a4"); + Given_HexString("D38705E4"); + AssertCode( // fmv.x.h a5,fa1 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v5 = SLICE(fa1, real16, 0)", + "2|L--|a5 = SEQ(0xFFFFFFFFFFFF<48>, v5)"); } [Test] - public void RiscV_rw_and() + public void RiscV_rw_fmv_s() { - Given_RiscVInstructions(0x00F477B3u); // and\ta5,s0,a5 - AssertCode( + Given_HexString("53058420"); + AssertCode( // fmv.s fa0,fs0 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = s0 & a5"); + "1|L--|fa0 = fs0"); } [Test] - public void RiscV_rw_subw() + public void RiscV_rw_fmv_w_x() { - Given_RiscVInstructions(0x40F686BBu); // subw\ta3,a3,a5 + Given_RiscVInstructions(0xF00007D3u); // fmv.w.x\tfa5,zero AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a3 = CONVERT(SLICE(a3 - a5, word32, 0), word32, int64)"); + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v4 = SLICE(0<64>, int32, 0)", + "2|L--|fa5 = SEQ(0xFFFFFFFF<32>, v4)"); } [Test] - public void RiscV_rw_srliw() + public void RiscV_rw_fmv_x_w() { - Given_RiscVInstructions(0x0017D71Bu); // srliw\ta4,a5,00000001 - AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = CONVERT(SLICE(a5, word32, 0) >>u 1, word32, int64)"); + Given_32bitFloat(); + Given_HexString("538507E0"); + AssertCode( // fmv.x.w a0,fa5 + "0|L--|00010000(4): 1 instructions", + "1|L--|a0 = fa5"); } [Test] - public void RiscV_rw_lbu() + public void RiscV_rw_fmsub_s() { - Given_RiscVInstructions(0x00094703u); // lbu\ta4,s2,+00000000 + Given_32bitFloat(); + Given_RiscVInstructions(0x6118B5C7); // fmsub.s\tfa1,fa7,fa7,fa2 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = CONVERT(Mem0[s2:byte], byte, word64)"); + "0|L--|00010000(4): 1 instructions", + "1|L--|fa1 = fa7 * fa7 - fa2"); } [Test] - public void RiscV_rw_beq() + public void RiscV_rw_fnmadd_d() { - Given_RiscVInstructions(0x00F58063u); // beq\ta1,a5,0000000000010000 - AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|if (a1 == a5) branch 0000000000010000"); + Given_HexString("4FFF7D5A"); + AssertCode( // fnmadd.d ft10,fs11,ft7,fa1,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft10 = -(fs11 * ft7) - fa1"); } [Test] - public void RiscV_rw_fcvt_d_s() + public void RiscV_rw_fnmadd_h() { - Given_RiscVInstructions(0x42070753u); // fcvt.d.s\tfa4,fa4 - AssertCode( + Given_HexString("4F81A285"); + AssertCode( // fnmadd.h ft2,ft5,fs10,fa6,rne "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = CONVERT(SLICE(fa4, real32, 0), real32, real64)"); + "1|L--|ft2 = SEQ(0xFFFFFFFFFFFF<48>, -(SLICE(ft5, real16, 0) * SLICE(fs10, real16, 0)) - SLICE(fa6, real16, 0))"); } [Test] - public void RiscV_rw_fdiv_d() + public void RiscV_rw_fnmadd_q() { - Given_HexString("D377F71A"); - AssertCode( // fdiv.d fa5,fa4,fa5 + Given_128bitFloat(); + Given_128bitFloat(); + Given_HexString("4FF39707"); + AssertCode( // fnmadd.q ft6,fa5,fs9,ft0,dyn "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = fa4 / fa5"); + "1|L--|ft6 = -(fa5 * fs9) - ft0"); } [Test] - public void RiscV_rw_feq_s() + public void RiscV_rw_fnmadd_s() { - // 1010000 011110111001001111 10100 11 - Given_RiscVInstructions(0xA0F727D3u); // feq.s\ta5,fa4,fa5 + Given_32bitFloat(); + Given_RiscVInstructions(0x00B3FDCF); // fnmadd.s\tfs11,ft7,fa1,ft0 AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(SLICE(fa4, real32, 0) == SLICE(fa5, real32, 0), bool, word64)"); + "0|L--|00010000(4): 1 instructions", + "1|L--|fs11 = -(ft7 * fa1) - ft0"); } [Test] - public void RiscV_rw_fle_d() + public void RiscV_rw_fnmsub_d() { - Given_HexString("D387E7A2"); - AssertCode( // fle.d a5,fa5,fa4 + Given_HexString("4BA9AA8A"); + AssertCode( // fnmsub.d fs2,fs5,fa0,fa7,rdn "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(fa5 <= fa4, bool, word64)"); + "1|L--|fs2 = -(fs5 * fa0) + fa7"); } [Test] - public void RiscV_rw_fle_s() + public void RiscV_rw_fnmsub_h() { - Given_HexString("D307F7A0"); - AssertCode( // fle.s a5,fa4,fa5 + Given_HexString("4B00BE9D"); + AssertCode( // fnmsub.h ft0,ft8,fs11,fs3,rne "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(SLICE(fa4, real32, 0) <= SLICE(fa5, real32, 0), bool, word64)"); + "1|L--|ft0 = SEQ(0xFFFFFFFFFFFF<48>, -(SLICE(ft8, real16, 0) * SLICE(fs11, real16, 0)) + SLICE(fs3, real16, 0))"); } [Test] - public void RiscV_rw_fli_d() + public void RiscV_rw_fnmsub_q() { - Given_RiscVInstructions(0xF21007D3u); // fli.d\tfa5,-1.0 - AssertCode( + Given_128bitFloat(); + Given_128bitFloat(); + Given_HexString("4B008947"); + AssertCode( // fnmsub.q ft0,fs2,fs8,fs0,rne "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = -1.0F"); + "1|L--|ft0 = -(fs2 * fs8) + fs0"); } [Test] - public void RiscV_rw_fli_s() + public void RiscV_rw_fneg_d() { - Given_RiscVInstructions(0xF01587D3u); // fli.s\tfa5,0.3125 - AssertCode( + Given_HexString("5317E722"); + AssertCode( // fneg.d fa4,fa4,fa4 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = 0.4375F"); + "1|L--|fa4 = -fa4"); } [Test] - public void RiscV_rw_flq() + public void RiscV_rw_fneg_s_64bit() { - Given_128bitFloat(); - Given_HexString("0740E391"); - AssertCode( // flq ft0,2334(t1) + Given_HexString("D397F720"); + AssertCode( // fsgnjn.s fa5,fa5,fa5 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|ft0 = Mem0[t1 + 2334:real128]"); + "1|L--|fa5 = SEQ(0xFFFFFFFF<32>, -SLICE(fa5, real32, 0))"); } [Test] - public void RiscV_rw_flt_d() + public void RiscV_rw_fneg_s() { - Given_HexString("D317C7A2"); - AssertCode( // flt.d a5,fa4,fa2 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(fa4 < fa2, bool, word64)"); + Given_32bitFloat(); + Given_HexString("D397F720"); + AssertCode( // fsgnjn.s fa5,fa5,fa5 + "0|L--|00010000(4): 1 instructions", + "1|L--|fa5 = -fa5"); } [Test] - public void RiscV_rw_flt_s() + public void RiscV_rw_fnmsub_s() { Given_32bitFloat(); - Given_HexString("D397E7A0"); - AssertCode( // flt.s a5,fa5,fa4 + Given_RiscVInstructions(0x4189004B); // fnmsub.s\tft0,fs2,fs8,fs0 + AssertCode( "0|L--|00010000(4): 1 instructions", - "1|L--|a5 = CONVERT(fa5 < fa4, bool, word32)"); + "1|L--|ft0 = -(fs2 * fs8) + fs0"); } [Test] - public void RiscV_rw_flw() + public void RiscV_rw_fround_d() { - Given_RiscVInstructions(0x03492707u); // flw\tfa4,s2,+00000034 - AssertCode( + Given_HexString("D3014042"); + AssertCode( // fround.d ft3,ft0,rne "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = SEQ(0xFFFFFFFF<32>, Mem0[s2 + 52:real32])"); + "1|L--|ft3 = __fround(ft0)"); } [Test] - public void RiscV_rw_fmv_d_x() + public void RiscV_rw_fround_h() { - Given_RiscVInstructions(0xF2070753u); // fmv.d.x\tfa4,a4 - AssertCode( + Given_HexString("53434044"); + AssertCode( // fround.h ft6,ft0,rmm "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = a4"); + "1|L--|ft6 = SEQ(0xFFFFFFFFFFFF<48>, __fround(SLICE(ft0, real16, 0)))"); } [Test] - public void RiscV_rw_fmv_x_d() + public void RiscV_rw_fround_q() { - Given_RiscVInstructions(0xE2070753u); // fmv.d.x\tfa4,a4 - AssertCode( + Given_128bitFloat(); + Given_HexString("D3A34046"); + AssertCode( // fround.q ft7,ft1,rdn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft7 = __fround(ft1)"); + } + + [Test] + public void RiscV_rw_fround_s() + { + Given_HexString("D3924140"); + AssertCode( // fround.s ft5,ft3,rtz "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = fa4"); + "1|L--|ft5 = SEQ(0xFFFFFFFF<32>, __fround(SLICE(ft3, real32, 0)))"); } [Test] - public void RiscV_rw_fmv_s() + public void RiscV_rw_froundnx_d() { - Given_HexString("53058420"); - AssertCode( // fmv.s fa0,fs0 + Given_HexString("D3115042"); + AssertCode( // froundnx.d ft3,ft0,rtz "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa0 = fs0"); + "1|L--|ft3 = __froundnx(ft0)"); } [Test] - public void RiscV_rw_fmv_w_x() + public void RiscV_rw_froundnx_h() { - Given_RiscVInstructions(0xF00007D3u); // fmv.w.x\tfa5,zero - AssertCode( - "0|L--|0000000000010000(4): 2 instructions", - "1|L--|v4 = SLICE(0<64>, real32, 0)", - "2|L--|fa5 = SEQ(0xFFFFFFFF<32>, v4)"); + Given_HexString("53735044"); + AssertCode( // froundnx.h ft6,ft0,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft6 = SEQ(0xFFFFFFFFFFFF<48>, __froundnx(SLICE(ft0, real16, 0)))"); } [Test] - public void RiscV_rw_fmv_x_w() + public void RiscV_rw_froundnx_q() { - Given_32bitFloat(); - Given_HexString("538507E0"); - AssertCode( // fmv.x.w a0,fa5 - "0|L--|00010000(4): 1 instructions", - "1|L--|a0 = fa5"); + Given_128bitFloat(); + Given_HexString("D3C35046"); + AssertCode( // froundnx.q ft7,ft1,rmm + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft7 = __froundnx(ft1)"); } [Test] - public void RiscV_rw_fneg_d() + public void RiscV_rw_froundnx_s() { - Given_HexString("5317E722"); - AssertCode( // fneg.d fa4,fa4,fa4 + Given_HexString("D3B25140"); + AssertCode( // froundnx.s ft5,ft3,rup "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa4 = -fa4"); + "1|L--|ft5 = SEQ(0xFFFFFFFF<32>, __froundnx(SLICE(ft3, real32, 0)))"); } [Test] - public void RiscV_rw_fneg_s_64bit() + public void RiscV_rw_fsgnj_d() { - Given_HexString("D397F720"); - AssertCode( // fsgnjn.s fa5,fa5,fa5 + Given_HexString("53822523"); + AssertCode( // fsgnj.d ft4,fa1,fs2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = SEQ(0xFFFFFFFF<32>, -SLICE(fa5, real32, 0))"); + "1|L--|ft4 = __fsgnj(fa1, fs2)"); } [Test] - public void RiscV_rw_fneg_s() + public void RiscV_rw_fsgnj_h() { - Given_32bitFloat(); - Given_HexString("D397F720"); - AssertCode( // fsgnjn.s fa5,fa5,fa5 - "0|L--|00010000(4): 1 instructions", - "1|L--|fa5 = -fa5"); + Given_HexString("D307B624"); + AssertCode( // fsgnj.h fa5,fa2,fa1 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa5 = SEQ(0xFFFFFFFFFFFF<48>, __fsgnj(SLICE(fa2, real16, 0), SLICE(fa1, real16, 0)))"); } [Test] - public void RiscV_rw_lr_d() + public void RiscV_rw_fsgnj_s() { - Given_HexString("2FB10114"); - AssertCode( // lr.d.aq sp,gp + Given_HexString("53802020"); + AssertCode( // fsgnj.s ft0,ft1,ft2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|sp = __load_reserved(&Mem0[gp:word64])"); + "1|L--|ft0 = SEQ(0xFFFFFFFF<32>, __fsgnj(SLICE(ft1, real32, 0), SLICE(ft2, real32, 0)))"); } [Test] - public void RiscV_rw_lr_w() + public void RiscV_rw_fsgnjn_d() { - Given_HexString("AFAB1715"); - AssertCode( // lr.w.aq s7,a5 + Given_HexString("D391C422"); + AssertCode( // fsgnjn.d ft3,fs1,fa2 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s7 = __load_reserved(&Mem0[a5:word32])"); + "1|L--|ft3 = __fsgnjn(fs1, fa2)"); } [Test] - public void RiscV_rw_lwu() + public void RiscV_rw_fsgnjn_h() { - Given_RiscVInstructions(0x00446703u); // lwu\ta4,s0,+00000004 - AssertCode( + Given_HexString("53971725"); + AssertCode( // fsgnjn.h fa4,fa5,fa7 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = CONVERT(Mem0[s0 + 4:uint32], uint32, word64)"); + "1|L--|fa4 = SEQ(0xFFFFFFFFFFFF<48>, __fsgnjn(SLICE(fa5, real16, 0), SLICE(fa7, real16, 0)))"); } [Test] - public void RiscV_rw_mul() + public void RiscV_rw_fsgnjn_s() { - Given_HexString("B387D702"); - AssertCode( // mul a5,a5,a3 + Given_HexString("D3914320"); + AssertCode( // fsgnjn.s ft3,ft7,ft4 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = a5 * a3"); + "1|L--|ft3 = SEQ(0xFFFFFFFF<32>, __fsgnjn(SLICE(ft7, real32, 0), SLICE(ft4, real32, 0)))"); } [Test] - public void RiscV_rw_mulh() + public void RiscV_rw_fsgnjx_d() { - Given_HexString("B397E702"); - AssertCode( // mulh a5,a5,a4 - "0|L--|0000000000010000(4): 2 instructions", - "1|L--|v5 = a5 *s128 a4", - "2|L--|a5 = SLICE(v5, word64, 64)"); + Given_HexString("53A41123"); + AssertCode( // fsgnjx.d fs0,ft3,fa7 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs0 = __fsgnjx(ft3, fa7)"); } [Test] - public void RiscV_rw_mulhsu() + public void RiscV_rw_fsgnjx_h() { - Given_HexString("332E0103"); - AssertCode( // mulhsu t3,sp,a6 - "0|L--|0000000000010000(4): 2 instructions", - "1|L--|v6 = sp *s128 a6", - "2|L--|t3 = SLICE(v6, word64, 64)"); + Given_HexString("D326C724"); + AssertCode( // fsgnjx.h fa3,fa4,fa2 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFFFFFF<48>, __fsgnjx(SLICE(fa4, real16, 0), SLICE(fa2, real16, 0)))"); } [Test] - public void RiscV_rw_mulhu() + public void RiscV_rw_fsgnjx_s() { - Given_HexString("33B7C502"); - AssertCode( // mulhu a4,a1,a2 - "0|L--|0000000000010000(4): 2 instructions", - "1|L--|v6 = a1 *u128 a2", - "2|L--|a4 = SLICE(v6, word64, 64)"); + Given_HexString("532E5120"); + AssertCode( // fsgnjx.s ft8,ft2,ft5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft8 = SEQ(0xFFFFFFFF<32>, __fsgnjx(SLICE(ft2, real32, 0), SLICE(ft5, real32, 0)))"); } [Test] - public void RiscV_rw_mret() + public void RiscV_rw_fsq() { - Given_HexString("73002030"); - AssertCode( // mret - "0|R--|0000000000010000(4): 2 instructions", - "1|L--|__mret()", - "2|R--|return (0,0)"); + Given_128bitFloat(); + Given_HexString("A7CF7955"); + AssertCode( // fsq fs7,0x55F(s3) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|Mem0[s3 + 1375:real128] = fs7"); } [Test] - public void RiscV_rw_c_sw() + public void RiscV_rw_fsqrt_d() { - Given_RiscVInstructions(0xC29C); // c.sw\ta3,0(a5) - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|Mem0[a3:word32] = SLICE(a5, word32, 0)"); + Given_HexString("5377065A"); + AssertCode( // fsqrt.d fa4,fa2 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa4 = sqrt(fa2)"); } [Test] - public void RiscV_rw_c_sdsp() + public void RiscV_rw_fsqrt_h() { - Given_RiscVInstructions(0xE4CE); // c.sdsp\ts3,00000048 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|Mem0[sp + 72:word64] = s3"); + Given_HexString("D306085C"); + AssertCode( // fsqrt.h fa3,fa6,rne + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = sqrt(SLICE(fa6, real16, 0))"); } [Test] - public void RiscV_rw_c_beqz() + public void RiscV_rw_fsqrt_q() { - Given_RiscVInstructions(0x0000C121); // c.beqz\ta0,0000000000100040 - AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|if (a0 == 0<64>) branch 0000000000010040"); + Given_128bitFloat(); + Given_HexString("53FD0D5E"); + AssertCode( // fsqrt.q fs10,fs11 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fs10 = SEQ(0xFFFFFFFFFFFFFFFF<64>, sqrt(fs11))"); } [Test] - public void RiscV_rw_c_lui() + public void RiscV_rw_fsqrt_s() { - Given_RiscVInstructions(0x00006585); // c.lui\ta1,00001000 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a1 = 0x1000000<64>"); + Given_HexString("D3710058"); + AssertCode( // fsqrt.s ft3,ft0 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft3 = SEQ(0xFFFFFFFF<32>, sqrtf(SLICE(ft0, real32, 0)))"); } [Test] - public void RiscV_rw_c_ld() + public void RiscV_rw_fsub_d() { - Given_RiscVInstructions(0x00006568); // c.ld\ta0,200(a0) - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a0 = Mem0[a0 + 200:word64]"); + Given_HexString("D371100A"); + AssertCode( // fsub.d ft3,ft0,ft1,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ft3 = ft0 - ft1"); } [Test] - public void RiscV_rw_c_bnez() + public void RiscV_rw_fsub_h() { - Given_RiscVInstructions(0x0000EF09); // c.bnez\ta4,000000000010001A - AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|if (a4 != 0<64>) branch 000000000001001A"); + Given_HexString("D376070D"); + AssertCode( // fsub.h fa3,fa4,fa6,dyn + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|fa3 = SEQ(0xFFFFFFFFFFFF<48>, SLICE(fa4, real16, 0) - SLICE(fa6, real16, 0))"); } [Test] - public void RiscV_rw_pause() + public void RiscV_rw_fsub_q() { - Given_HexString("0F000001"); - AssertCode( // pause + Given_128bitFloat(); + Given_HexString("531EEC0F"); + AssertCode( // fsub.q ft8,fs8,ft10,rtz "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__pause()"); + "1|L--|ft8 = fs8 - ft10"); } [Test] - public void RiscV_rw_rem() + public void RiscV_rw_fsub_s() { - Given_HexString("33E7E402"); - AssertCode( // rem a4,s1,a4 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = s1 %s a4"); + Given_32bitFloat(); + Given_HexString("5375A708"); + AssertCode( // fsub.s fa0,fa4,fa0 + "0|L--|00010000(4): 1 instructions", + "1|L--|fa0 = fa4 - fa0"); } [Test] - public void RiscV_rw_remu() + public void RiscV_rw_fsh() { - Given_HexString("3377C702"); - AssertCode( // remu a4,a4,a2 + Given_HexString("A79AD700"); + AssertCode( // fsh fa3,0x15(a5) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a4 = a4 %u a2"); + "1|L--|Mem0[a5 + 21:real16] = SLICE(fa3, real16, 0)"); } [Test] - public void RiscV_rw_remuw() + public void RiscV_rw_fsw() { - Given_RiscVInstructions(0x02C8783B); // remuw\ta6,a6,a2 + Given_RiscVInstructions(0x8963A3A7); // fsw fs6,8732(a5) AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a6 = CONVERT(SLICE(a6 %u a2, word32, 0), word32, int64)"); + "1|L--|Mem0[t2 + 2183:real32] = SLICE(fs6, real32, 0)"); } [Test] - public void RiscV_rw_c_li() + public void RiscV_rw_fsd() { - Given_RiscVInstructions(0x00004521); // c.li\ta0,00000008 + Given_RiscVInstructions(0x639435A7); // fsd fs9,12632(s0) AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a0 = 8"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|Mem0[s0 + 1579:real64] = fs9"); } - [Test] - public void RiscV_rw_c_li_minus3() + public void RiscV_rw_hfence_vvma() { - Given_RiscVInstructions(0x00005775); // c.li\ta4,FFFFFFFFFFFFFFFD - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a4 = -3"); + Given_HexString("73000022"); + AssertCode( // hfence.vvma zero,(zero) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hfence_vvma(0<64>, 0<64>)"); } [Test] - public void RiscV_rw_c_swsp() + public void RiscV_rw_hfence_gvma() { - Given_RiscVInstructions(0xC22A); // c.swsp\ta0,00000080 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|Mem0[sp + 4:word32] = SLICE(a0, word32, 0)"); + Given_HexString("73000062"); + AssertCode( // hfence.gvma zero,(zero) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hfence_gvma(0<64>, 0<64>)"); } [Test] - public void RiscV_rw_c_lwsp() + public void RiscV_rw_hinval_vvma() { - Given_RiscVInstructions(0x00004512); // c.lwsp\ta0,00000004 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a0 = CONVERT(Mem0[sp + 4:word32], word32, int64)"); + Given_HexString("7380C626"); + AssertCode( // hinval.vvma a2,(a3) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hinval_vvma(a3, a2)"); } [Test] - public void RiscV_rw_c_mv() + public void RiscV_rw_hinval_gvma() { - Given_RiscVInstructions(0x844E); // c.mv\ts0,s3 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s0 = s3"); + Given_HexString("7380B866"); + AssertCode( // hinval.gvma a7,a1 + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hinval_gvma(a7, a1)"); } [Test] - public void RiscV_rw_c_lw() + public void RiscV_rw_hlv_b() { - Given_RiscVInstructions(0x000043F4); // c.lw\ta3,68(a5) - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a3 = CONVERT(Mem0[a5 + 68:word32], word32, int64)"); + Given_HexString("F3C80760"); + AssertCode( // hlv.b a7,(a5) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a7 = __hypervisor_load_from_VM(&Mem0[a5:int8])"); } [Test] - public void RiscV_rw_csrrc() + public void RiscV_rw_hlv_bu() { - Given_HexString("73B00230"); - AssertCode( // csrrc zero,mstatus,t0 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__csrrc(mstatus, t0)"); + Given_HexString("73481660"); + AssertCode( // hlv.bu a6,(a2) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a6 = __hypervisor_load_from_VM(&Mem0[a2:uint8])"); } [Test] - public void RiscV_rw_csrrci() + public void RiscV_rw_hlv_d() { - Given_HexString("F3770430"); - AssertCode( // csrrci a5,mstatus,00000008 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = __csrrc(mstatus, 8<64>)"); + Given_HexString("F3C8036C"); + AssertCode( // hlv.d a7,(t2) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a7 = __hypervisor_load_from_VM(&Mem0[t2:uint64])"); + } + + [Test] + public void RiscV_rw_hlv_h() + { + Given_HexString("F3C60664"); + AssertCode( // hlv.h a3,(a3) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a3 = __hypervisor_load_from_VM(&Mem0[a3:int16])"); } [Test] - public void RiscV_rw_csrrs() + public void RiscV_rw_hlv_hu() { - Given_HexString("73292000"); - AssertCode( // csrrs s2,frm,zero - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s2 = __csrrs(frm, 0<64>)"); + Given_HexString("73411764"); + AssertCode( // hlv.hu sp,(a4) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|sp = __hypervisor_load_from_VM(&Mem0[a4:uint16])"); } [Test] - public void RiscV_rw_csrrsi() + public void RiscV_rw_hlv_w() { - Given_HexString("73600430"); - AssertCode( // csrrsi zero,mstatus,00000008 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__csrrs(mstatus, 8<64>)"); + Given_HexString("73C80468"); + AssertCode( // hlv.w a6,(s1) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a6 = __hypervisor_load_from_VM(&Mem0[s1:int32])"); } [Test] - public void RiscV_rw_csrrw() + public void RiscV_rw_hlv_wu() { - Given_HexString("73900930"); - AssertCode( // csrrw zero,mstatus,x19 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__csrrw(mstatus, s3)"); + Given_HexString("73CE1868"); + AssertCode( // hlv.wu t3,(a7) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|t3 = __hypervisor_load_from_VM(&Mem0[a7:uint32])"); } [Test] - public void RiscV_rw_csrw_unknown() + public void RiscV_rw_hlvx_hu() { - Given_HexString("7310C5BF"); - AssertCode( // csrw\t0xbfc,a0 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__csrrw(0xBFC, a0)"); + Given_HexString("F3483164"); + AssertCode( // hlvx.hu a7,(sp) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|a7 = __hypervisor_load_exe_from_VM(&Mem0[sp:uint16])"); } [Test] - public void RiscV_rw_csrrwi() + public void RiscV_rw_hlvx_wu() { - Given_HexString("73D02334"); - AssertCode( // csrrwi zero,mcause,00000007 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|__csrrw(mcause, 7<64>)"); + Given_HexString("F3C13E68"); + AssertCode( // hlvx.wu gp,(t4) + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|gp = __hypervisor_load_exe_from_VM(&Mem0[t4:uint32])"); } [Test] - public void RiscV_rw_div() + public void RiscV_rw_hsv_b() { - Given_HexString("B3C5E502"); - AssertCode( // div a1,a1,a4 - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a1 = a1 / a4"); + Given_HexString("7340C663"); + AssertCode( // hsv.b (a2),t3 + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hypervisor_store_in_VM(&t3, Mem0[a2:byte])"); } [Test] - public void RiscV_rw_divu() + public void RiscV_rw_hsv_d() { - Given_RiscVInstructions(0x02B6D6B3); // divu a3,a3,a1 - AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a3 = a3 /u a1"); + Given_HexString("73C0416E"); + AssertCode( // hsv.d (gp),tp + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hypervisor_store_in_VM(&tp, Mem0[gp:word64])"); } [Test] - public void RiscV_rw_divuw() + public void RiscV_rw_hsv_h() { - Given_RiscVInstructions(0x02C857BB); // divuw\ta5,a6,a2 - AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(SLICE(a6 /u a2, word32, 0), word32, int64)"); + Given_HexString("73C0CF66"); + AssertCode( // hsv.h (t6),a2 + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hypervisor_store_in_VM(&a2, Mem0[t6:word16])"); } [Test] - public void RiscV_rw_divw() + public void RiscV_rw_hsv_w() { - Given_RiscVInstructions(0x02B4443B); // divw\ts0,s0,a1 - AssertCode( - "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s0 = CONVERT(SLICE(s0 / a1, word32, 0), word32, int64)"); + Given_HexString("7340DE6B"); + AssertCode( // hsv.w (t3),t4 + "0|S--|0000000000010000(4): 1 instructions", + "1|L--|__hypervisor_store_in_VM(&t4, Mem0[t3:word32])"); } [Test] - public void RiscV_rw_ecall() + public void RiscV_rw_invalid() { - Given_HexString("73000000"); - AssertCode( // ecall - "0|T--|0000000000010000(4): 1 instructions", - "1|L--|__syscall()"); + Given_RiscVInstructions(0x00000000); // invalid + AssertCode( + "0|---|0000000000010000(2): 1 instructions", + "1|---|"); } [Test] - public void RiscV_rw_c_addi16sp() + public void RiscV_rw_jal_zero() { - Given_RiscVInstructions(0x6169); // c.addi16sp\t000000D0 + Given_RiscVInstructions(0x9F4FF06Fu); AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|sp = sp + 208"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|goto 000000000000F1F4"); } [Test] - public void RiscV_rw_li() + public void RiscV_rw_jal_not_zero() { - Given_RiscVInstructions(0x00004385); // c.li\tt2,00000001 + Given_RiscVInstructions(0x9F4FF0EFu); AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|t2 = 1"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|call 000000000000F1F4 (0)"); } [Test] - public void RiscV_rw_beqz() + public void RiscV_rw_jalr_zero() { - Given_RiscVInstructions(0xC3F1); // c.beqz\ta5,00000000001000C4 + Given_RiscVInstructions(0x00078067); // jalr zero, a5, 0 AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|if (a5 == 0<64>) branch 00000000000100C4"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|goto a5"); } [Test] - public void RiscV_rw_beqz_backward() + public void RiscV_rw_jalr_zero_ra() { - Given_RiscVInstructions(0xD399); // c.beqz\ta5,00000000000FFF06 + Given_RiscVInstructions(0x00008067); // jalr zero,ra,0 AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|if (a5 == 0<64>) branch 000000000000FF06"); + "0|T--|0000000000010000(4): 1 instructions", + "1|R--|return (0,0)"); } [Test] - public void RiscV_rw_c_bnez_backward() + public void RiscV_rw_jalr_ra() { - Given_RiscVInstructions(0xFB05); // c.bnez\ta4,00000000000FFF30 + Given_RiscVInstructions(0x003780E7); // jalr ra,a5,0 AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|if (a4 != 0<64>) branch 000000000000FF30"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|call a5 + 3 (0)"); } [Test] - public void RiscV_rw_c_fldsp() + public void RiscV_rw_jal() { - Given_RiscVInstructions(0x00003436); // c.fldsp\tfa3,00000228 + Given_RiscVInstructions(0x9F4FF06F); // jal\tzero,00000000000FF1F4 AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|fa3 = Mem0[sp + 552:real64]"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|goto 000000000000F1F4"); } [Test] - public void RiscV_rw_invalid() + public void RiscV_rw_jalr() { - Given_RiscVInstructions(0x00000000); // invalid + Given_RiscVInstructions(0x00078067u); // jalr\tzero,a5,+00000000 AssertCode( - "0|---|0000000000010000(2): 1 instructions", - "1|---|"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|goto a5"); } [Test] @@ -1616,511 +2513,540 @@ public void RiscV_rw_jr_ra() } [Test] - public void RiscV_rw_c_or() + public void RiscV_rw_jal_ra() { - Given_RiscVInstructions(0x8E55); // c.or\ta2,a3 + Given_RiscVInstructions(0x02C000EF); // jal ra,0000B6A4 AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a2 = a2 | a3"); + "0|T--|0000000000010000(4): 1 instructions", + "1|T--|call 000000000001002C (0)"); } [Test] - public void RiscV_rw_c_and() + public void RiscV_rw_lb() { - Given_RiscVInstructions(0x8FF5); // c.and\ta5,a3 + Given_RiscVInstructions(0x87010183u); AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a5 = a5 & a3"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|gp = CONVERT(Mem0[sp + -1936:int8], int8, int64)"); } [Test] - public void RiscV_rw_c_j() + public void RiscV_rw_ld() { - Given_RiscVInstructions(0x0000B7D5); // c.j\t00000000001003FC - AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|goto 000000000000FFE4"); + Given_HexString("833F850F"); + AssertCode( // ld t6,0xF8(a0) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t6 = Mem0[a0 + 248:word64]"); } [Test] - public void RiscV_rw_c_sub() + public void RiscV_rw_lui() { - Given_RiscVInstructions(0x8D89); // c.sub\ta1,a0 + Given_RiscVInstructions(0x000114B7u); // lui s1,0x00000011<32> AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a1 = a1 - a0"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s1 = 0x11000<64>"); } [Test] - public void RiscV_rw_c_j_backward() + public void RiscV_rw_lh() { - Given_RiscVInstructions(0x0000BF1D); // c.j\t000000000000FF36 + Given_RiscVInstructions(0x03131083u); // lh AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|goto 000000000000FF36"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|ra = CONVERT(Mem0[t1 + 49:int16], int16, int64)"); } [Test] - public void RiscV_rw_c_addi4spn() + public void RiscV_rw_lhu() { - Given_RiscVInstructions(0x0000101C); // c.addi4spn\ta5,00000020 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a5 = sp + 32"); + Given_HexString("835D4162"); + AssertCode( // lhu s11,0x624(sp) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s11 = CONVERT(Mem0[sp + 1572:uint16], uint16, word64)"); } [Test] - public void RiscV_rw_c_jr() + public void RiscV_rw_lbu() { - Given_RiscVInstructions(0x00008782); // c.jr\ta5 + Given_RiscVInstructions(0x00094703u); // lbu\ta4,s2,+00000000 AssertCode( - "0|T--|0000000000010000(2): 1 instructions", - "1|T--|goto a5"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a4 = CONVERT(Mem0[s2:byte], byte, word64)"); } [Test] - public void RiscV_rw_c_subw() + public void RiscV_rw_lr_d() { - Given_RiscVInstructions(0x00009D1D); // c.subw\ta0,a5 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a0 = CONVERT(SLICE(a0 - a5, word32, 0), word32, int64)"); + Given_HexString("2FB10114"); + AssertCode( // lr.d.aq sp,gp + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|sp = __load_reserved(&Mem0[gp:word64])"); } [Test] - public void RiscV_rw_c_addi() + public void RiscV_rw_lr_w() { - Given_RiscVInstructions(0x00000785); // c.addi\ta5,00000001 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a5 = a5 + 1"); + Given_HexString("AFAB1715"); + AssertCode( // lr.w.aq s7,a5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s7 = __load_reserved(&Mem0[a5:word32])"); } [Test] - public void RiscV_rw_c_addw() + public void RiscV_rw_lw() { - Given_RiscVInstructions(0x00009FB5); // c.addw\ta5,a3 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a5 = CONVERT(SLICE(a5 + a3, word32, 0), word32, int64)"); + Given_HexString("03AA897E"); + AssertCode( // lw s4,0x7E8(s3) + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s4 = CONVERT(Mem0[s3 + 2024:int32], int32, int64)"); } [Test] - public void RiscV_rw_c_slli() + public void RiscV_rw_lwu() { - Given_RiscVInstructions(0x0000040E); // c.slli\ts0,03 + Given_RiscVInstructions(0x00446703u); // lwu\ta4,s0,+00000004 AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s0 = s0 << 3"); + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a4 = CONVERT(Mem0[s0 + 4:uint32], uint32, word64)"); } [Test] - public void RiscV_rw_c_srli() + public void RiscV_rw_li() { - Given_RiscVInstructions(0x000083A9); // c.srli\ta5,0000000A + Given_RiscVInstructions(0x00004385); // c.li\tt2,00000001 AssertCode( "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a5 = a5 >>u 10"); + "1|L--|t2 = 1"); } [Test] - public void RiscV_rw_c_srai() + public void RiscV_rw_mul() { - Given_RiscVInstructions(0x0000977D); // c.srai\ta4,0000003F - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a4 = a4 >> 63"); + Given_HexString("B387D702"); + AssertCode( // mul a5,a5,a3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = a5 * a3"); } [Test] - public void RiscV_rw_c_andi() + public void RiscV_rw_mulh() { - Given_RiscVInstructions(0x00008A61); // c.andi\ta2,00000018 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|a2 = a2 & 24"); + Given_HexString("B397E702"); + AssertCode( // mulh a5,a5,a4 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v5 = a5 *s128 a4", + "2|L--|a5 = SLICE(v5, word64, 64)"); + } + + [Test] + public void RiscV_rw_mulhsu() + { + Given_HexString("332E0103"); + AssertCode( // mulhsu t3,sp,a6 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v6 = sp *s128 a6", + "2|L--|t3 = SLICE(v6, word64, 64)"); } [Test] - public void RiscV_rw_c_ldsp() + public void RiscV_rw_mulhu() { - Given_RiscVInstructions(0x00006BA2); // c.ldsp\ts7,00000008 - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|s7 = Mem0[sp + 8:word64]"); + Given_HexString("33B7C502"); + AssertCode( // mulhu a4,a1,a2 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v6 = a1 *u128 a2", + "2|L--|a4 = SLICE(v6, word64, 64)"); } [Test] - public void RiscV_rw_c_fld() + public void RiscV_rw_mulw() { - Given_RiscVInstructions(0x00002E64); // c.fld\tfs1,216(a2) - AssertCode( - "0|L--|0000000000010000(2): 1 instructions", - "1|L--|fs1 = Mem0[a2 + 216:real64]"); + Given_HexString("BB8E2802"); + AssertCode( // mulw t4,a7,sp + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t4 = CONVERT(SLICE(a7 * sp, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_jal_ra() + public void RiscV_rw_mret() { - Given_RiscVInstructions(0x02C000EF); // jal ra,0000B6A4 - AssertCode( - "0|T--|0000000000010000(4): 1 instructions", - "1|T--|call 000000000001002C (0)"); + Given_HexString("73002030"); + AssertCode( // mret + "0|R--|0000000000010000(4): 2 instructions", + "1|L--|__mret()", + "2|R--|return (0,0)"); } [Test] - public void RiscV_rw_sltiu() + public void RiscV_rw_or() { - Given_RiscVInstructions(0x0014B493); // sltiu s1,s1,+00000001 + Given_RiscVInstructions(0x01846433u); // or\ts0,s0,s8 AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s1 = CONVERT(s1 , bool, word64)"); + "1|L--|s0 = s0 | s8"); } [Test] - public void RiscV_rw_fabs_d() + public void RiscV_rw_ori() { - Given_HexString("D3278422"); - AssertCode( // fabs.d fa5,fs0 + Given_HexString("13670B40"); + AssertCode( // ori a4,s6,0x400 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fa5 = fabs(fs0)"); + "1|L--|a4 = s6 | 1024"); } [Test] - public void RiscV_rw_fsw() + public void RiscV_rw_pause() { - Given_RiscVInstructions(0x8963A3A7); // fsw fs6,8732(a5) - AssertCode( + Given_HexString("0F000001"); + AssertCode( // pause "0|L--|0000000000010000(4): 1 instructions", - "1|L--|Mem0[t2 + 2183:real32] = SLICE(fs6, real32, 0)"); + "1|L--|__pause()"); } [Test] - public void RiscV_rw_slti() + public void RiscV_rw_rem() { - Given_HexString("93A72700"); - AssertCode( // slti a5,a5,+00000002 + Given_HexString("33E7E402"); + AssertCode( // rem a4,s1,a4 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a5 = CONVERT(a5 < 2, bool, word64)"); + "1|L--|a4 = s1 %s a4"); } [Test] - public void RiscV_rw_sret() + public void RiscV_rw_remu() { - Given_UInt32s(0b0001000_00010_00000_000_00000_1110011); - AssertCode( // sret - "0|R--|0000000000010000(4): 2 instructions", - "1|L--|__sret()", - "2|R--|return (0,0)"); + Given_HexString("3377C702"); + AssertCode( // remu a4,a4,a2 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a4 = a4 %u a2"); } [Test] - public void RiscV_rw_srl() + public void RiscV_rw_remuw() { - Given_RiscVInstructions(0x00B6D6B3); // srl a3,a3,a1 + Given_RiscVInstructions(0x02C8783B); // remuw\ta6,a6,a2 AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a3 = a3 >>u a1"); + "1|L--|a6 = CONVERT(SLICE(a6 %u a2, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_srlw() + public void RiscV_rw_remw() { - Given_HexString("3BD6F600"); - AssertCode( // srlw a2,a3,a5 + Given_RiscVInstructions(0x02D7E6BB); // remw\ta3,a5,a3 + AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a2 = CONVERT(SLICE(a3, word32, 0) >>u a5, word32, int64)"); + "1|L--|a3 = CONVERT(SLICE(a5 %s a3, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_fsd() + public void RiscV_rw_sb() { - Given_RiscVInstructions(0x639435A7); // fsd fs9,12632(s0) - AssertCode( + Given_HexString("A30AF7D2"); + AssertCode( // sb a5,-0x2CB(a4) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|Mem0[s0 + 1579:real64] = fs9"); + "1|L--|Mem0[a4 + -715:byte] = SLICE(a5, byte, 0)"); } [Test] - public void RiscV_rw_sltu() + public void RiscV_rw_sc_d() { - Given_RiscVInstructions(0x00A03533); // sltu\ta0,zero,a0 - AssertCode( + Given_HexString("AFBA3C1B"); + AssertCode( // sc.d.rl s5,s9,s3 "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a0 = CONVERT(a0 != 0<64>, bool, word64)"); + "1|L--|s5 = __store_conditional(s3, &Mem0[s9:word64])"); } [Test] - public void RiscV_rw_slt() + public void RiscV_rw_sc_w() { - Given_RiscVInstructions(0x00A7A533); // slt\ta0,a5,a0 + Given_HexString("AFADE31C"); + AssertCode( // sc.w.aq s11,t2,a4 + "0|L--|0000000000010000(4): 2 instructions", + "1|L--|v6 = __store_conditional(a4, &Mem0[t2:word32])", + "2|L--|s11 = CONVERT(v6, word32, int64)"); + } + + [Test] + public void RiscV_rw_sd() + { + Given_RiscVInstructions(0x19513423u); // sd\ts5,sp,392 AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a0 = CONVERT(a5 < a0, bool, word64)"); + "1|L--|Mem0[sp + 392:word64] = s5"); } [Test] - public void RiscV_rw_sra() + public void RiscV_rw_sh() { - Given_HexString("3355B540"); - AssertCode( // sra a0,a0,a1 + Given_HexString("2396A47E"); + AssertCode( // sh a0,0x7EC(s1) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a0 = a0 >> a1"); + "1|L--|Mem0[s1 + 2028:word16] = SLICE(a0, word16, 0)"); } [Test] - public void RiscV_rw_sraw() + public void RiscV_rw_sw() { - Given_HexString("BB 5B D5 41"); - AssertCode( // sraw\ts7,a0,t4 + Given_HexString("2320217F"); + AssertCode( // sw s2,0x7E0(sp) "0|L--|0000000000010000(4): 1 instructions", - "1|L--|s7 = CONVERT(SLICE(a0, word32, 0) >> t4, word32, int64)"); + "1|L--|Mem0[sp + 2016:word32] = SLICE(s2, word32, 0)"); } [Test] - public void RiscV_rw_fmsub_s() + public void RiscV_rw_sub() { - Given_32bitFloat(); - Given_RiscVInstructions(0x6118B5C7); // fmsub.s\tfa1,fa7,fa7,fa2 - AssertCode( - "0|L--|00010000(4): 1 instructions", - "1|L--|fa1 = fa7 * fa7 - fa2"); + Given_HexString("B38D6B40"); + AssertCode( // sub s11,s7,t1 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s11 = s7 - t1"); } [Test] - public void RiscV_rw_fmul_q() + public void RiscV_rw_subw() { - Given_128bitFloat(); - Given_HexString("53046316"); - AssertCode( // fmul.q fs0,ft6,ft6 + Given_RiscVInstructions(0x40F686BBu); // subw\ta3,a3,a5 + AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|fs0 = ft6 * ft6"); + "1|L--|a3 = CONVERT(SLICE(a3 - a5, word32, 0), word32, int64)"); } [Test] - public void RiscV_rw_fmul_s() + public void RiscV_rw_srai() { - Given_32bitFloat(); - Given_HexString("53749510"); - AssertCode( // fmul.s fs0,fa0,fs1 - "0|L--|00010000(4): 1 instructions", - "1|L--|fs0 = fa0 * fs1"); + Given_HexString("13DCFD41"); + AssertCode( // srai s8,s11,0x1F + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s8 = s11 >> 0x1F"); } [Test] - public void RiscV_rw_fnmsub_s() + public void RiscV_rw_srli() { - Given_32bitFloat(); - Given_RiscVInstructions(0x4189004B); // fnmsub.s\tft0,fs2,fs8,fs0 - AssertCode( - "0|L--|00010000(4): 1 instructions", - "1|L--|ft0 = -(fs2 * fs8) + fs0"); + Given_HexString("13DC7C01"); + AssertCode( // srli s8,s9,0x17 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s8 = s9 >>u 0x17"); } [Test] - public void RiscV_rw_remw() + public void RiscV_rw_srliw() { - Given_RiscVInstructions(0x02D7E6BB); // remw\ta3,a5,a3 + Given_RiscVInstructions(0x0017D71Bu); // srliw\ta4,a5,00000001 AssertCode( "0|L--|0000000000010000(4): 1 instructions", - "1|L--|a3 = CONVERT(SLICE(a5 %s a3, word32, 0), word32, int64)"); + "1|L--|a4 = CONVERT(SLICE(a5, word32, 0) >>u 1, word32, int64)"); } [Test] - public void RiscV_rw_wfi() + public void RiscV_rw_sinval_vma() { - Given_HexString("73005010"); - AssertCode( // wfi + Given_HexString("73800717"); + AssertCode( // sinval.vma a5,a6 "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__wait_for_interrupt()"); + "1|L--|__sinval_vma(a5, a6)"); } - // This file contains unit tests automatically generated by Reko decompiler. - // Please copy the contents of this file and report it on GitHub, using the - // following URL: https://github.com/uxmal/reko/issues - - + [Test] + public void RiscV_rw_sll() + { + Given_HexString("B39D6B00"); + AssertCode( // sll s11,s7,t1 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s11 = s7 << t1"); + } [Test] - public void RiscV_rw_sfence_vma() + public void RiscV_rw_slli() { - Given_UInt32s(0b0001001_10101_11011_000_00000_1110011); - AssertCode( - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__sfence_vma(s11, s5)"); + Given_HexString("13150B01"); + AssertCode( // slli a0,s6,0x10 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = s6 << 0x10"); } [Test] - public void RiscV_rw_sfence_w_inval() + public void RiscV_rw_slliw() { - Given_UInt32s(0b0001100_00000_00000_000_00000_1110011); - AssertCode( // sfence.w.inval - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__sfence_w_inval()"); + Given_HexString("1B9FF001"); + AssertCode( // slliw t5,ra,0x1F + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t5 = CONVERT(SLICE(ra, word32, 0) << 0x1F<64>, word32, int64)"); } [Test] - public void RiscV_rw_sfence_inval_ir() + public void RiscV_rw_sllw() { - Given_UInt32s(0b0001100_00001_00000_000_00000_1110011); - AssertCode( // sfence.inval.ir - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__sfence_inval_ir()"); + Given_HexString("3B9F2000"); + AssertCode( // sllw t5,ra,sp + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t5 = CONVERT(SLICE(ra, word32, 0) << sp, word32, int64)"); } [Test] - public void RiscV_rw_hfence_vvma() + public void RiscV_rw_sltiu() { - Given_UInt32s(0b0010001_10101_10001_000_00000_1110011); - AssertCode( // hfence.vvma - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hfence_vvma(a7, s5)"); + Given_RiscVInstructions(0x0014B493); // sltiu s1,s1,+00000001 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s1 = CONVERT(s1 , bool, word64)"); } [Test] - public void RiscV_rw_hfence_gvma() + public void RiscV_rw_slti() { - Given_UInt32s(0b0110001_10101_10001_000_00000_1110011); - AssertCode( // hfence.gvma - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hfence_gvma(a7, s5)"); + Given_HexString("93A72700"); + AssertCode( // slti a5,a5,+00000002 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a5 = CONVERT(a5 < 2, bool, word64)"); } [Test] - public void RiscV_rw_hinval_vvma() + public void RiscV_rw_srl() { - Given_UInt32s(0b0010011_10101_10001_000_00000_1110011); - AssertCode( // hinval.vvma - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hfence_vvma(a7, s5)"); + Given_RiscVInstructions(0x00B6D6B3); // srl a3,a3,a1 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a3 = a3 >>u a1"); } [Test] - public void RiscV_rw_hinval_gvma() + public void RiscV_rw_srlw() { - Given_UInt32s(0b0110011_10101_10001_000_00000_1110011); - AssertCode( // hinval.gvma - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hfence_gvma(a7, s5)"); + Given_HexString("3BD6F600"); + AssertCode( // srlw a2,a3,a5 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a2 = CONVERT(SLICE(a3, word32, 0) >>u a5, word32, int64)"); } [Test] - public void RiscV_rw_hlv_b() + public void RiscV_rw_sltu() { - Given_UInt32s(0b0110000_00000_10001_100_11011_1110011); - AssertCode( // hlv.b s11,(a7) - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:int8])"); + Given_RiscVInstructions(0x00A03533); // sltu\ta0,zero,a0 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = CONVERT(a0 != 0<64>, bool, word64)"); } [Test] - public void RiscV_rw_hlv_bu() + public void RiscV_rw_slt() { - Given_UInt32s(0b0110000_00001_10001_100_11011_1110011); - AssertCode( // hlv.bu s11,(a7) - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:uint8])"); + Given_RiscVInstructions(0x00A7A533); // slt\ta0,a5,a0 + AssertCode( + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = CONVERT(a5 < a0, bool, word64)"); } [Test] - public void RiscV_rw_hlv_h() + public void RiscV_rw_sra() { - Given_UInt32s(0b0110010_00000_10001_100_11011_1110011); - AssertCode( // hlv.h - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:int16])"); + Given_HexString("3355B540"); + AssertCode( // sra a0,a0,a1 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|a0 = a0 >> a1"); } [Test] - public void RiscV_rw_hlv_hu() + public void RiscV_rw_sraiw() { - Given_UInt32s(0b0110010_00001_10001_100_11011_1110011); - AssertCode( // hlv.hu - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:uint16])"); + Given_HexString("1BD0C041"); + AssertCode( // sraiw zero,ra,0x1C + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|0<64> = CONVERT(SLICE(ra, word32, 0) >> 0x1C, word32, int64)"); } + [Test] + public void RiscV_rw_sraw() + { + Given_HexString("BB 5B D5 41"); + AssertCode( // sraw\ts7,a0,t4 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s7 = CONVERT(SLICE(a0, word32, 0) >> t4, word32, int64)"); + } [Test] - public void RiscV_rw_hlv_w() + public void RiscV_rw_sfence_vm_zero() { - Given_UInt32s(0b0110100_00000_10001_100_11011_1110011); - AssertCode( // hlv.w + Given_HexString("73004010"); + AssertCode( // sfence.vm zero "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:int32])"); + "1|L--|__sfence_vm(0<64>)"); } - [Test] - public void RiscV_rw_hlvx_hu() + public void RiscV_rw_sfence_vm() { - Given_UInt32s(0b0110010_00011_10001_100_11011_1110011); - AssertCode( // hlvx.hu + Given_HexString("73804610"); + AssertCode( // sfence.vm a3 "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_exe_from_VM(&Mem0[a7:uint16])"); + "1|L--|__sfence_vm(a3)"); } [Test] - public void RiscV_rw_hlvx_wu() + public void RiscV_rw_sfence_vma() { - Given_UInt32s(0b0110100_00011_10001_100_11011_1110011); - AssertCode( // hlvx.wu + Given_HexString("73000012"); + AssertCode( // sfence.vma zero,(zero) "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_exe_from_VM(&Mem0[a7:uint32])"); + "1|L--|__sfence_vma(0<64>, 0<64>)"); } [Test] - public void RiscV_rw_hsv_b() + public void RiscV_rw_sfence_w_inval() { - Given_UInt32s(0b0110001_10101_10001_100_00000_1110011); - AssertCode( // hsv.b + Given_HexString("73000018"); + AssertCode( // sfence.w.inval "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hypervisor_store_in_VM(&Mem0[a7:byte], s5)"); + "1|L--|__sfence_w_inval()"); } [Test] - public void RiscV_rw_hsv_h() + public void RiscV_rw_sfence_inval_ir() { - Given_UInt32s(0b0110011_10101_10001_100_00000_1110011); - AssertCode( // hsv.h + Given_HexString("73001018"); + AssertCode( // sfence.inval.ir "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hypervisor_store_in_VM(&Mem0[a7:word16], s5)"); + "1|L--|__sfence_inval_ir()"); } [Test] - public void RiscV_rw_hsv_w() + public void RiscV_rw_sret() { - Given_UInt32s(0b0110101_10101_10001_100_00000_1110011); - AssertCode( // hsv.w - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hypervisor_store_in_VM(&Mem0[a7:word32], s5)"); + Given_HexString("73002010"); + AssertCode( // sret + "0|R--|0000000000010000(4): 2 instructions", + "1|L--|__sret()", + "2|R--|return (0,0)"); } [Test] - public void RiscV_rw_hlv_wu() + public void RiscV_rw_wfi() { - Given_UInt32s(0b0110100_00001_10001_100_11011_1110011); - AssertCode( // hlv.wu + Given_HexString("73005010"); + AssertCode( // wfi "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:uint32])"); + "1|L--|__wait_for_interrupt()"); } [Test] - public void RiscV_rw_hlv_d() + public void RiscV_rw_xor() { - Given_UInt32s(0b0110110_00000_10001_100_11011_1110011); - AssertCode( // hlv.d - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|s11 = __hypervisor_load_from_VM(&Mem0[a7:uint64])"); + Given_HexString("33CFCF01"); + AssertCode( // xor t5,t6,t3 + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|t5 = t6 ^ t3"); } [Test] - public void RiscV_rw_hsv_d() + public void RiscV_rw_xori() { - Given_UInt32s(0b0110111_10101_10001_100_00000_1110011); - AssertCode( // hsv.d - "0|S--|0000000000010000(4): 1 instructions", - "1|L--|__hypervisor_store_in_VM(&Mem0[a7:word64], s5)"); + Given_HexString("1344D33F"); + AssertCode( // xori s0,t1,0x3FD + "0|L--|0000000000010000(4): 1 instructions", + "1|L--|s0 = t1 ^ 1021"); } - } -} \ No newline at end of file + } +} diff --git a/subjects/Elf/RiscV/193.instructions/193.instructions.asm b/subjects/Elf/RiscV/193.instructions/193.instructions.asm index 77522e6692..0844850946 100644 --- a/subjects/Elf/RiscV/193.instructions/193.instructions.asm +++ b/subjects/Elf/RiscV/193.instructions/193.instructions.asm @@ -22,12 +22,13 @@ .section .init .global _start .align 2 # align code on 2^n => ( 4 bytes ) +.attribute 5, "rv64gaimdfqh_zicsr_zfh_zihintpause_svinval_zmmul_zfa" _start: #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV32I Base Instruction Set #════════════════════════════════════════════════════════════════════════════════════════════════════ -lui x0,0x80000 # LUI U // imm[31:12] rd 0110111 +lui zero,0x80000 # LUI U // imm[31:12] rd 0110111 auipc s3,0xfffb # AUIPC U // imm[31:12] rd 0010111 #---------------------------------------------------------------------------------------------------- #jal ra,0x800000e6 # JAL J // imm[20|10:1|11|19:12] rd 1101111 @@ -73,15 +74,15 @@ or a1,a2,t5 # OR and s5,s7,t4 # AND R // 0000000 rs2 rs1 111 rd 0110011 #---------------------------------------------------------------------------------------------------- fence w,i # FENCE I // fm pred succ rs1 000 rd 0001111 -#fence.tso # FENCE.TSO I // 1000 0011 0011 00000 000 00000 0001111 -#pause # PAUSE I // 0000 0001 0000 00000 000 00000 0001111 +fence.tso # FENCE.TSO I // 1000 0011 0011 00000 000 00000 0001111 +pause # PAUSE I // 0000 0001 0000 00000 000 00000 0001111 ecall # ECALL I // 000000000000 00000 000 00000 1110011 ebreak # EBREAK I // 000000000001 00000 000 00000 1110011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV32 3.3 Machine-Mode Privileged Instructions #════════════════════════════════════════════════════════════════════════════════════════════════════ - + # Trap-Return Instructions #uret # URET I // 0000000 00010 00000 000 00000 1110011 #sret # SRET I // 0001000 00010 00000 000 00000 1110011 @@ -92,34 +93,34 @@ ebreak # EBREAK wfi # WFI I // 0001000 00101 00000 000 00000 1110011 # Supervisor Memory-Management Instructions -sfence.vm # SFENCE.VM I // 0001000 00100 rs1 000 00000 1110011 -sfence.vma # SFENCE.VMA I // 0001001 rs2 rs1 000 00000 1110011 -#sinval.vma # SINVAL.VMA I // 0001011 rs2 rs1 000 00000 1110011 -#sfence.w.inval # SFENCE.W.INVAL I // 0001100 00000 00000 000 00000 1110011 -#sfence.inval.ir # SFENCE.INVAL.IR I // 0001100 00001 00000 000 00000 1110011 +sfence.vm a3 # SFENCE.VM I // 0001000 00100 rs1 000 00000 1110011 +sfence.vma a7,a4 # SFENCE.VMA R // 0001001 rs2 rs1 000 00000 1110011 +sinval.vma a5,a6 # SINVAL.VMA R // 0001011 rs2 rs1 000 00000 1110011 +sfence.w.inval # SFENCE.W.INVAL I // 0001100 00000 00000 000 00000 1110011 +sfence.inval.ir # SFENCE.INVAL.IR I // 0001100 00001 00000 000 00000 1110011 # Hypervisor Memory-Management Instructions -#hfence.vvma # HFENCE.VVMA I // 0010001 rs2 rs1 000 00000 1110011 -#hfence.gvma # HFENCE.GVMA I // 0110001 rs2 rs1 000 00000 1110011 -#hinval.vvma # HINVAL.VVMA I // 0010011 rs2 rs1 000 00000 1110011 -#hinval.gvma # HINVAL.GVMA I // 0110011 rs2 rs1 000 00000 1110011 +hfence.vvma a1,a3 # HFENCE.VVMA R // 0010001 rs2 rs1 000 00000 1110011 +hfence.gvma a4,a5 # HFENCE.GVMA R // 0110001 rs2 rs1 000 00000 1110011 +hinval.vvma a3,a2 # HINVAL.VVMA R // 0010011 rs2 rs1 000 00000 1110011 +hinval.gvma a7,a1 # HINVAL.GVMA R // 0110011 rs2 rs1 000 00000 1110011 # Hypervisor Virtual-Machine Load and Store Instructions -#hlv.b # HLV.B I // 0110000 00000 rs1 100 rd 1110011 -#hlv.bu # HLV.BU I // 0110000 00001 rs1 100 rd 1110011 -#hlv.h # HLV.H I // 0110010 00000 rs1 100 rd 1110011 -#hlv.hu # HLV.HU I // 0110010 00001 rs1 100 rd 1110011 -#hlvx.hu # HLVX.HU I // 0110010 00011 rs1 100 rd 1110011 -#hlv.w # HLV.W I // 0110100 00000 rs1 100 rd 1110011 -#hlvx.wu # HLVX.WU I // 0110100 00011 rs1 100 rd 1110011 -#hsv.b # HSV.B I // 0110001 rs2 rs1 100 00000 1110011 -#hsv.h # HSV.H I // 0110011 rs2 rs1 100 00000 1110011 -#hsv.w # HSV.W I // 0110101 rs2 rs1 100 00000 1110011 +hlv.b a7,(a5) # HLV.B I // 0110000 00000 rs1 100 rd 1110011 +hlv.bu a6,(a2) # HLV.BU I // 0110000 00001 rs1 100 rd 1110011 +hlv.h a4,(a3) # HLV.H I // 0110010 00000 rs1 100 rd 1110011 +hlv.hu sp,(a4) # HLV.HU I // 0110010 00001 rs1 100 rd 1110011 +hlvx.hu a7,(sp) # HLVX.HU I // 0110010 00011 rs1 100 rd 1110011 +hlv.w a6,(s1) # HLV.W I // 0110100 00000 rs1 100 rd 1110011 +hlvx.wu gp,(t4) # HLVX.WU I // 0110100 00011 rs1 100 rd 1110011 +hsv.b t3,(a2) # HSV.B R // 0110001 rs2 rs1 100 00000 1110011 +hsv.h a2,(t6) # HSV.H R // 0110011 rs2 rs1 100 00000 1110011 +hsv.w t4,(t3) # HSV.W R // 0110101 rs2 rs1 100 00000 1110011 # Hypervisor Virtual-Machine Load and Store Instructions, RV64 only -#hlv.wu # HLV.WU I // 0110100 00001 rs1 100 rd 1110011 -#hlv.d # HLV.D I // 0110110 00000 rs1 100 rd 1110011 -#hsv.d # HSV.D I // 0110111 rs2 rs1 100 00000 1110011 +hlv.wu t3,(a7) # HLV.WU I // 0110100 00001 rs1 100 rd 1110011 +hlv.d a7,(t2) # HLV.D I // 0110110 00000 rs1 100 rd 1110011 +hsv.d tp,(gp) # HSV.D R // 0110111 rs2 rs1 100 00000 1110011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV64I Base Instruction Set (in addition to RV32I) @@ -142,7 +143,7 @@ addw t5,ra,sp # ADDW subw a0,a5,a4 # SUBW R // 0100000 rs2 rs1 000 rd 0111011 sllw t5,ra,sp # SLLW R // 0000000 rs2 rs1 001 rd 0111011 srlw t4,a3,sp # SRLW R // 0000000 rs2 rs1 101 rd 0111011 -#sraw t5,ra,sp # SRAW R // 0100000 rs2 rs1 101 rd 0111011 //$ TODO warning: Risc-V instruction 'sraw' not supported yet. +sraw t5,ra,sp # SRAW R // 0100000 rs2 rs1 101 rd 0111011 @@ -184,17 +185,17 @@ remu a6,a1,t2 # REMU #RV64M Standard Extension (in addition to RV32M) #════════════════════════════════════════════════════════════════════════════════════════════════════ mulw t4,a7,sp # MULW R // 0000001 rs2 rs1 000 rd 0111011 -divw t3,a6,x1 # DIVW R // 0000001 rs2 rs1 100 rd 0111011 -divuw t5,a4,x2 # DIVUW R // 0000001 rs2 rs1 101 rd 0111011 +divw t3,a6,ra # DIVW R // 0000001 rs2 rs1 100 rd 0111011 +divuw t5,a4,sp # DIVUW R // 0000001 rs2 rs1 101 rd 0111011 remw t2,a2,ra # REMW R // 0000001 rs2 rs1 110 rd 0111011 -remuw t1,a4,x3 # REMUW R // 0000001 rs2 rs1 111 rd 0111011 +remuw t1,a4,gp # REMUW R // 0000001 rs2 rs1 111 rd 0111011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV32A Standard Extension #════════════════════════════════════════════════════════════════════════════════════════════════════ -lr.w.aqrl a0,0(a0) # LR.W R // 00010 aq rl 00000 rs1 010 rd 0101111 +lr.w.aqrl a0,(a0) # LR.W R // 00010 aq rl 00000 rs1 010 rd 0101111 #---------------------------------------------------------------------------------------------------- sc.w a4,zero,(a0) # SC.W R // 00011 aq rl rs2 rs1 010 rd 0101111 amoswap.w a4,a1,(a3) # AMOSWAP.W R // 00001 aq rl rs2 rs1 010 rd 0101111 @@ -205,25 +206,25 @@ amoor.w a2,a3,(a1) # AMOOR.W amomin.w a5,t1,(a2) # AMOMIN.W R // 10000 aq rl rs2 rs1 010 rd 0101111 amomax.w t1,t3,(a5) # AMOMAX.W R // 10100 aq rl rs2 rs1 010 rd 0101111 amominu.w a1,t4,(t3) # AMOMINU.W R // 11000 aq rl rs2 rs1 010 rd 0101111 -amomaxu.w a3,t2,(x1) # AMOMAXU.W R // 11100 aq rl rs2 rs1 010 rd 0101111 +amomaxu.w a3,t2,(ra) # AMOMAXU.W R // 11100 aq rl rs2 rs1 010 rd 0101111 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV64A Standard Extension (in addition to RV32A) #════════════════════════════════════════════════════════════════════════════════════════════════════ -lr.d.aqrl a1,0(a4) # LR.D R // 00010 aq rl 00000 rs1 011 rd 0101111 +lr.d.aqrl a1,(a4) # LR.D R // 00010 aq rl 00000 rs1 011 rd 0101111 #---------------------------------------------------------------------------------------------------- -sc.d.aqrl a2,a3,0(a2) # SC.D R // 00011 aq rl rs2 rs1 011 rd 0101111 +sc.d.aqrl a2,a3,(a2) # SC.D R // 00011 aq rl rs2 rs1 011 rd 0101111 amoswap.d a4,a1,(a3) # AMOSWAP.D R // 00001 aq rl rs2 rs1 011 rd 0101111 -amoadd.d t4,a2,(x3) # AMOADD.D R // 00000 aq rl rs2 rs1 011 rd 0101111 +amoadd.d t4,a2,(gp) # AMOADD.D R // 00000 aq rl rs2 rs1 011 rd 0101111 amoxor.d a3,a2,(a5) # AMOXOR.D R // 00100 aq rl rs2 rs1 011 rd 0101111 amoand.d.aqrl t3,s2,(t5) # AMOAND.D R // 01100 aq rl rs2 rs1 011 rd 0101111 amoor.d a2,a3,(a1) # AMOOR.D R // 01000 aq rl rs2 rs1 011 rd 0101111 amomin.d a5,t1,(a2) # AMOMIN.D R // 10000 aq rl rs2 rs1 011 rd 0101111 amomax.d t1,t3,(a5) # AMOMAX.D R // 10100 aq rl rs2 rs1 011 rd 0101111 amominu.d a1,t4,(t3) # AMOMINU.D R // 11000 aq rl rs2 rs1 011 rd 0101111 -amomaxu.d a3,t2,(x1) # AMOMAXU.D R // 11100 aq rl rs2 rs1 011 rd 0101111 +amomaxu.d a3,t2,(ra) # AMOMAXU.D R // 11100 aq rl rs2 rs1 011 rd 0101111 @@ -243,32 +244,43 @@ fadd.s fs2,fa6,ft5,rmm # FADD.S fsub.s ft3,ft0,ft1 # FSUB.S R // 0000100 rs2 rs1 rm rd 1010011 fmul.s ft3,ft0,ft1 # FMUL.S R // 0001000 rs2 rs1 rm rd 1010011 fdiv.s fs4,fs6,fs3,rne # FDIV.S R // 0001100 rs2 rs1 rm rd 1010011 -fsqrt.s ft3,ft0 # FSQRT.S R // 0101100 00000 rs1 rm rd 1010011 +fsqrt.s ft3,ft0 # FSQRT.S I // 0101100 00000 rs1 rm rd 1010011 fsgnj.s ft0,ft1,ft2 # FSGNJ.S R // 0010000 rs2 rs1 000 rd 1010011 fsgnjn.s ft3,ft7,ft4 # FSGNJN.S R // 0010000 rs2 rs1 001 rd 1010011 fsgnjx.s ft8,ft2,ft5 # FSGNJX.S R // 0010000 rs2 rs1 010 rd 1010011 fmin.s ft6,ft0,ft1 # FMIN.S R // 0010100 rs2 rs1 000 rd 1010011 -fmax.s ft5,ft4,ft2 # FMAX.S R // 0010100 rs2 rs1 001 rd 1010011 -fcvt.w.s a1,fa5,rtz # FCVT.W.S R // 1100000 00000 rs1 rm rd 1010011 -fcvt.wu.s a0,ft0,rtz # FCVT.WU.S R // 1100000 00001 rs1 rm rd 1010011 -fmv.x.w a0,ft3 # FMV.X.W R // 1110000 00000 rs1 000 rd 1010011 +fmax.s ft5,ft3,ft2 # FMAX.S R // 0010100 rs2 rs1 001 rd 1010011 +fminm.s ft3,ft0,ft1 # FMINM.S R // 0010100 rs2 rs1 010 rd 1010011 +fmaxm.s ft7,ft1,ft2 # FMAXM.S R // 0010100 rs2 rs1 011 rd 1010011 +fcvt.w.s a1,fa5,rtz # FCVT.W.S I // 1100000 00000 rs1 rm rd 1010011 +fcvt.wu.s a0,ft0,rtz # FCVT.WU.S I // 1100000 00001 rs1 rm rd 1010011 +fmv.x.w a0,ft3 # FMV.X.W I // 1110000 00000 rs1 000 rd 1010011 feq.s a0,ft0,ft1 # FEQ.S R // 1010000 rs2 rs1 010 rd 1010011 flt.s a1,ft2,ft3 # FLT.S R // 1010000 rs2 rs1 001 rd 1010011 fle.s a2,ft5,ft4 # FLE.S R // 1010000 rs2 rs1 000 rd 1010011 -fclass.s a3,fa2 # FCLASS.S R // 1110000 00000 rs1 001 rd 1010011 -fcvt.s.w ft1,a5 # FCVT.S.W R // 1101000 00000 rs1 rm rd 1010011 -fcvt.s.wu fs0,a2 # FCVT.S.WU R // 1101000 00001 rs1 rm rd 1010011 -fmv.w.x ft11,a3 # FMV.W.X R // 1111000 00000 rs1 000 rd 1010011 - +fclass.s a3,fa2 # FCLASS.S I // 1110000 00000 rs1 001 rd 1010011 +fcvt.s.w ft1,a5,rmm # FCVT.S.W I // 1101000 00000 rs1 rm rd 1010011 +fcvt.s.wu fs0,a2,rdn # FCVT.S.WU I // 1101000 00001 rs1 rm rd 1010011 +fmv.w.x ft11,a3 # FMV.W.X I // 1111000 00000 rs1 000 rd 1010011 +fli.s ft3,0x1p-3 # FLI.S I // 1111000 00001 rs1 000 rd 1010011 + +fround.s ft5,ft3,rtz # FROUND.S I // 0100000 00100 rs1 rm rd 1010011 +froundnx.s ft5,ft3,rup # FROUNDNX.S I // 0100000 00101 rs1 rm rd 1010011 +fround.h ft6,ft0,rmm # FROUND.H I // 0100010 00100 rs1 rm rd 1010011 +froundnx.h ft6,ft0,dyn # FROUNDNX.H I // 0100010 00101 rs1 rm rd 1010011 +fround.d ft3,ft0,rne # FROUND.D I // 0100001 00100 rs1 rm rd 1010011 +froundnx.d ft3,ft0,rtz # FROUNDNX.D I // 0100001 00101 rs1 rm rd 1010011 +fround.q ft7,ft1,rdn # FROUND.Q I // 0100011 00100 rs1 rm rd 1010011 +froundnx.q ft7,ft1,rmm # FROUNDNX.Q I // 0100011 00101 rs1 rm rd 1010011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV64F Standard Extension (in addition to RV32F) #════════════════════════════════════════════════════════════════════════════════════════════════════ -fcvt.l.s a0,ft11,rtz # FCVT.L.S R // 1100000 00010 rs1 rm rd 1010011 -fcvt.lu.s a0,ft9,rtz # FCVT.LU.S R // 1100000 00011 rs1 rm rd 1010011 -fcvt.s.l ft7,a7 # FCVT.S.L R // 1101000 00010 rs1 rm rd 1010011 -fcvt.s.lu ft4,a3 # FCVT.S.LU R // 1101000 00011 rs1 rm rd 1010011 +fcvt.l.s a0,ft11,rdn # FCVT.L.S I // 1100000 00010 rs1 rm rd 1010011 +fcvt.lu.s a0,ft9,rup # FCVT.LU.S I // 1100000 00011 rs1 rm rd 1010011 +fcvt.s.l ft7,a7,rmm # FCVT.S.L I // 1101000 00010 rs1 rm rd 1010011 +fcvt.s.lu ft4,a3,rdn # FCVT.S.LU I // 1101000 00011 rs1 rm rd 1010011 @@ -288,79 +300,135 @@ fadd.d fa7,ft2,ft3,rup # FADD.D fsub.d ft3,ft0,ft1 # FSUB.D R // 0000101 rs2 rs1 rm rd 1010011 fmul.d ft5,ft4,fa6,rne # FMUL.D R // 0001001 rs2 rs1 rm rd 1010011 fdiv.d fa1,fa5,fa7 # FDIV.D R // 0001101 rs2 rs1 rm rd 1010011 -fsqrt.d fa4,fa2 # FSQRT.D R // 0101101 00000 rs1 rm rd 1010011 +fsqrt.d fa4,fa2 # FSQRT.D I // 0101101 00000 rs1 rm rd 1010011 fsgnj.d ft4,fa1,fs2 # FSGNJ.D R // 0010001 rs2 rs1 000 rd 1010011 fsgnjn.d ft3,fs1,fa2 # FSGNJN.D R // 0010001 rs2 rs1 001 rd 1010011 fsgnjx.d fs0,ft3,fa7 # FSGNJX.D R // 0010001 rs2 rs1 010 rd 1010011 fmin.d ft3,ft0,ft1 # FMIN.D R // 0010101 rs2 rs1 000 rd 1010011 fmax.d ft2,ft0,ft4 # FMAX.D R // 0010101 rs2 rs1 001 rd 1010011 -fcvt.s.d fa5,fa2 # FCVT.S.D R // 0100000 00001 rs1 rm rd 1010011 -fcvt.d.s fa3,fa4 # FCVT.D.S R // 0100001 00000 rs1 rm rd 1010011 +fminm.d ft3,ft0,ft1 # FMINM.D R // 0010101 rs2 rs1 010 rd 1010011 +fmaxm.d ft2,ft0,ft4 # FMAXM.D R // 0010101 rs2 rs1 011 rd 1010011 +fcvt.s.d fa5,fa2,rne # FCVT.S.D I // 0100000 00001 rs1 rm rd 1010011 +fcvt.d.s fa3,fa4 # FCVT.D.S I // 0100001 00000 rs1 rm rd 1010011 feq.d a3,fa4,fa2 # FEQ.D R // 1010001 rs2 rs1 010 rd 1010011 flt.d a5,fa5,fa4 # FLT.D R // 1010001 rs2 rs1 001 rd 1010011 fle.d a0,fa2,ft1 # FLE.D R // 1010001 rs2 rs1 000 rd 1010011 -fclass.d a0,fa3 # FCLASS.D R // 1110001 00000 rs1 001 rd 1010011 -fcvt.w.d a7,ft2,rtz # FCVT.W.D R // 1100001 00000 rs1 rm rd 1010011 -fcvt.wu.d a5,fs3,rtz # FCVT.WU.D R // 1100001 00001 rs1 rm rd 1010011 -fcvt.d.w fa5,zero # FCVT.D.W R // 1101001 00000 rs1 rm rd 1010011 -fcvt.d.wu fa4,a3 # FCVT.D.WU R // 1101001 00001 rs1 rm rd 1010011 +fclass.d a0,fa3 # FCLASS.D I // 1110001 00000 rs1 001 rd 1010011 +fcvt.w.d a7,ft2,rmm # FCVT.W.D I // 1100001 00000 rs1 rm rd 1010011 +fcvt.wu.d a5,fs3,rup # FCVT.WU.D I // 1100001 00001 rs1 rm rd 1010011 +fcvt.d.w fa5,zero # FCVT.D.W I // 1101001 00000 rs1 rm rd 1010011 +fcvt.d.wu fa4,a3 # FCVT.D.WU I // 1101001 00001 rs1 rm rd 1010011 +fli.d ft7,0.25 # FLI.D I // 1111001 00001 rs1 000 rd 1010011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV64D Standard Extension (in addition to RV32D) #════════════════════════════════════════════════════════════════════════════════════════════════════ -fcvt.l.d ra,ft1,rtz # FCVT.L.D R // 1100001 00010 rs1 rm rd 1010011 -fcvt.lu.d a0,fa3,rtz # FCVT.LU.D R // 1100001 00011 rs1 rm rd 1010011 -fmv.x.d a2,ft3 # FMV.X.D R // 1110001 00000 rs1 000 rd 1010011 -fcvt.d.l ft1,a3 # FCVT.D.L R // 1101001 00010 rs1 rm rd 1010011 -fcvt.d.lu ft0,a2 # FCVT.D.LU R // 1101001 00011 rs1 rm rd 1010011 -fmv.d.x ft2,a5 # FMV.D.X R // 1111001 00000 rs1 000 rd 1010011 +fcvt.l.d ra,ft1,rdn # FCVT.L.D I // 1100001 00010 rs1 rm rd 1010011 +fcvt.lu.d a0,fa3,rtz # FCVT.LU.D I // 1100001 00011 rs1 rm rd 1010011 +fmv.x.d a2,ft3 # FMV.X.D I // 1110001 00000 rs1 000 rd 1010011 +fcvt.d.l ft1,a3,rmm # FCVT.D.L I // 1101001 00010 rs1 rm rd 1010011 +fcvt.d.lu ft0,a2,rdn # FCVT.D.LU I // 1101001 00011 rs1 rm rd 1010011 +fmv.d.x ft2,a5 # FMV.D.X I // 1111001 00000 rs1 000 rd 1010011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV32Q Standard Extension #════════════════════════════════════════════════════════════════════════════════════════════════════ -## flq fs6,-1168(tp) # FLQ I // imm[11:0] rs1 100 rd 0000111 +flq fs6,-1168(tp) # FLQ I // imm[11:0] rs1 100 rd 0000111 #---------------------------------------------------------------------------------------------------- -## fsq fs7,1375(s3) # FSQ S // imm[11:5] rs2 rs1 100 imm[4:0] 0100111 +fsq fs7,1375(s3) # FSQ S // imm[11:5] rs2 rs1 100 imm[4:0] 0100111 #---------------------------------------------------------------------------------------------------- -## fmadd.q fa0,fs6,fs0,fs6,rup # FMADD.Q R4 // rs3 11 rs2 rs1 rm rd 1000011 -## fmsub.q ft7,ft4,fa1,fs9,rne # FMSUB.Q R4 // rs3 11 rs2 rs1 rm rd 1000111 -## fnmsub.q fs0,ft4,fs2,fa5,rdn # FNMSUB.Q R4 // rs3 11 rs2 rs1 rm rd 1001011 -## fnmadd.q ft10,fa4,fa1,fs3,rtz # FNMADD.Q R4 // rs3 11 rs2 rs1 rm rd 1001111 +fmadd.q fa0,fs6,fs0,fs6,rup # FMADD.Q R4 // rs3 11 rs2 rs1 rm rd 1000011 +fmsub.q ft7,ft4,fa1,fs9,rne # FMSUB.Q R4 // rs3 11 rs2 rs1 rm rd 1000111 +fnmsub.q fs0,ft4,fs2,fa5,rdn # FNMSUB.Q R4 // rs3 11 rs2 rs1 rm rd 1001011 +fnmadd.q ft10,fa4,fa1,fs3,rtz # FNMADD.Q R4 // rs3 11 rs2 rs1 rm rd 1001111 #---------------------------------------------------------------------------------------------------- -## fadd.q ft7,fa3,fs2,rne # FADD.Q R // 0000011 rs2 rs1 rm rd 1010011 -## fsub.q ft8,fs8,ft10,rtz # FSUB.Q R // 0000111 rs2 rs1 rm rd 1010011 -## fmul.q ft8,fs0,fa7,rup # FMUL.Q R // 0001011 rs2 rs1 rm rd 1010011 -## fdiv.q fs10,fs9,fs11,rmm # FDIV.Q R // 0001111 rs2 rs1 rm rd 1010011 -## fsqrt.q fs10,fs11 # FSQRT.Q R // 0101111 00000 rs1 rm rd 1010011 -## fsgnj.q ft7,fa3,fs2,rne # FSGNJ.Q R // 0010011 rs2 rs1 000 rd 1010011 -## fsgnjn.q ft8,fs8,ft10,rtz # FSGNJN.Q R // 0010011 rs2 rs1 001 rd 1010011 -## fsgnjx.q ft8,fs0,fa7,rup # FSGNJX.Q R // 0010011 rs2 rs1 010 rd 1010011 -## fmin.q fs10,fs9,fs11,rmm # FMIN.Q R // 0010111 rs2 rs1 000 rd 1010011 -## fmax.q fs0,ft4,fs2,fa5,rdn # FMAX.Q R // 0010111 rs2 rs1 001 rd 1010011 -## fcvt.s.q fs10,fs9 # FCVT.S.Q R // 0100000 00011 rs1 rm rd 1010011 -## fcvt.q.s fs11,fs4 # FCVT.Q.S R // 0100011 00000 rs1 rm rd 1010011 -## fcvt.d.q fs7,fs6 # FCVT.D.Q R // 0100001 00011 rs1 rm rd 1010011 -## fcvt.q.d fs3,fs5 # FCVT.Q.D R // 0100011 00001 rs1 rm rd 1010011 -## feq.q ft7,fa3,fs2,rne # FEQ.Q R // 1010011 rs2 rs1 010 rd 1010011 -## flt.q ft8,fs8,ft10,rtz # FLT.Q R // 1010011 rs2 rs1 001 rd 1010011 -## fle.q ft8,fs0,fa7,rup # FLE.Q R // 1010011 rs2 rs1 000 rd 1010011 -## fclass.q fs13,fs6 # FCLASS.Q R // 1110011 00000 rs1 001 rd 1010011 -## fcvt.w.q a0,a2,rne # FCVT.W.Q R // 1100011 00000 rs1 rm rd 1010011 -## fcvt.wu.q x4,x6,rtz # FCVT.WU.Q R // 1100011 00001 rs1 rm rd 1010011 -## fcvt.q.w x6,x4 # FCVT.Q.W R // 1101011 00000 rs1 rm rd 1010011 -## fcvt.q.wu x5,x4 # FCVT.Q.WU R // 1101011 00001 rs1 rm rd 1010011 +fadd.q ft7,fa3,fs2,rne # FADD.Q R // 0000011 rs2 rs1 rm rd 1010011 +fsub.q ft8,fs8,ft10,rtz # FSUB.Q R // 0000111 rs2 rs1 rm rd 1010011 +fmul.q ft8,fs0,fa7,rup # FMUL.Q R // 0001011 rs2 rs1 rm rd 1010011 +fdiv.q fs10,fs9,fs11,rmm # FDIV.Q R // 0001111 rs2 rs1 rm rd 1010011 +fsqrt.q fs10,fs11 # FSQRT.Q I // 0101111 00000 rs1 rm rd 1010011 +fsgnj.q ft7,ft3,ft2 # FSGNJ.Q R // 0010011 rs2 rs1 000 rd 1010011 +fsgnjn.q fs0,ft1,fa2 # FSGNJN.Q R // 0010011 rs2 rs1 001 rd 1010011 +fsgnjx.q fs2,fa3,ft3 # FSGNJX.Q R // 0010011 rs2 rs1 010 rd 1010011 +fmin.q fa0,ft3,fs7 # FMIN.Q R // 0010111 rs2 rs1 000 rd 1010011 +fmax.q ft0,fs4,fa2 # FMAX.Q R // 0010111 rs2 rs1 001 rd 1010011 +fminm.q fs1,ft3,fa7 # FMINM.Q R // 0010111 rs2 rs1 010 rd 1010011 +fmaxm.q ft3,fa4,ft5 # FMAXM.Q R // 0010111 rs2 rs1 011 rd 1010011 +fcvt.s.q fs10,fs9,rdn # FCVT.S.Q I // 0100000 00011 rs1 rm rd 1010011 +fcvt.q.s fs11,fs4 # FCVT.Q.S I // 0100011 00000 rs1 rm rd 1010011 +fcvt.d.q fs7,fs6,rup # FCVT.D.Q I // 0100001 00011 rs1 rm rd 1010011 +fcvt.q.d fs3,fs5 # FCVT.Q.D I // 0100011 00001 rs1 rm rd 1010011 +feq.q t2,fs3,ft2 # FEQ.Q R // 1010011 rs2 rs1 010 rd 1010011 +flt.q s0,ft7,fs10 # FLT.Q R // 1010011 rs2 rs1 001 rd 1010011 +fle.q s2,fa0,ft7 # FLE.Q R // 1010011 rs2 rs1 000 rd 1010011 +fclass.q a3,fa6 # FCLASS.Q I // 1110011 00000 rs1 001 rd 1010011 +fcvt.w.q zero,ft3,rne # FCVT.W.Q I // 1100011 00000 rs1 rm rd 1010011 +fcvt.wu.q ra,fs4,rtz # FCVT.WU.Q I // 1100011 00001 rs1 rm rd 1010011 +fcvt.q.w fa7,t1 # FCVT.Q.W I // 1101011 00000 rs1 rm rd 1010011 +fcvt.q.wu ft5,tp # FCVT.Q.WU I // 1101011 00001 rs1 rm rd 1010011 +fli.q ft5,0.25 # FLI.Q I // 1111011 00001 rs1 000 rd 1010011 #════════════════════════════════════════════════════════════════════════════════════════════════════ #RV64Q Standard Extension (in addition to RV32Q) #════════════════════════════════════════════════════════════════════════════════════════════════════ -## fcvt.l.q a3,a2,rdn # FCVT.L.Q R // 1100011 00010 rs1 rm rd 1010011 -## fcvt.lu.q t1,a2,rne # FCVT.LU.Q R // 1100011 00011 rs1 rm rd 1010011 -## fcvt.q.l x7,t3 # FCVT.Q.L R // 1101011 00010 rs1 rm rd 1010011 -## fcvt.q.lu t3,x2 # FCVT.Q.LU R // 1101011 00011 rs1 rm rd 1010011 +fcvt.l.q gp,fa2,rdn # FCVT.L.Q R // 1100011 00010 rs1 rm rd 1010011 +fcvt.lu.q ra,ft3,rne # FCVT.LU.Q R // 1100011 00011 rs1 rm rd 1010011 +fcvt.q.l fs3,t3,rtz # FCVT.Q.L R // 1101011 00010 rs1 rm rd 1010011 +fcvt.q.lu fa5,sp,rmm # FCVT.Q.LU R // 1101011 00011 rs1 rm rd 1010011 + + +#════════════════════════════════════════════════════════════════════════════════════════════════════ +#RV32Zfh Standard Extension +#════════════════════════════════════════════════════════════════════════════════════════════════════ +flh fa4,12(a7) # FLH I // imm[11:0] rs1 001 rd 0000111 +fsh fa3,21(a5) # FSH S // imm[11:5] rs2 rs1 001 imm[4:0] 0100111 +fmadd.h fa4,fa2,fa1,fa7,rne # FMADD.H R4 // rs3 10 rs2 rs1 rm rd 1000011 +fmsub.h fa3,fa1,fa6,fa2,rdn # FMSUB.H R4 // rs3 10 rs2 rs1 rm rd 1000111 +fnmsub.h fa4,fa3,fa5,fa6,rtz # FNMSUB.H R4 // rs3 10 rs2 rs1 rm rd 1001011 +fnmadd.h fa1,fa7,fa4,fa2,rup # FNMADD.H R4 // rs3 10 rs2 rs1 rm rd 1001111 +fadd.h fa2,fa3,fa6,rmm # FADD.H R // 0000010 rs2 rs1 rm rd 1010011 +fsub.h fa3,fa4,fa6 # FSUB.H R // 0000110 rs2 rs1 rm rd 1010011 +fmul.h fa2,fa5,fa4,rdn # FMUL.H R // 0001010 rs2 rs1 rm rd 1010011 +fdiv.h fa4,fa6,fa7,rne # FDIV.H R // 0001110 rs2 rs1 rm rd 1010011 +fsqrt.h fa3,fa6,rne # FSQRT.H I // 0101110 00000 rs1 rm rd 1010011 +fsgnj.h fa5,fa2,fa1 # FSGNJ.H R // 0010010 rs2 rs1 000 rd 1010011 +fsgnjn.h fa4,fa5,fa7 # FSGNJN.H R // 0010010 rs2 rs1 001 rd 1010011 +fsgnjx.h fa3,fa4,fa2 # FSGNJX.H R // 0010010 rs2 rs1 010 rd 1010011 +fmin.h fa4,fa3,fa5 # FMIN.H R // 0010110 rs2 rs1 000 rd 1010011 +fmax.h fa1,fa7,fa2 # FMAX.H R // 0010110 rs2 rs1 001 rd 1010011 +fminm.h fa4,fa3,fa5 # FMINM.H R // 0010110 rs2 rs1 010 rd 1010011 +fmaxm.h fa1,fa7,fa2 # FMAXM.H R // 0010110 rs2 rs1 011 rd 1010011 +fcvt.s.h fa2,fa5 # FCVT.S.H I // 0100000 00010 rs1 rm rd 1010011 +fcvt.h.s fa1,fa4 # FCVT.H.S I // 0100010 00000 rs1 rm rd 1010011 +fcvt.d.h fa4,fa7 # FCVT.D.H I // 0100001 00010 rs1 rm rd 1010011 +fcvt.h.d fa3,fa4,rdn # FCVT.H.D I // 0100010 00001 rs1 rm rd 1010011 +fcvt.q.h fa7,fa6 # FCVT.Q.H I // 0100011 00010 rs1 rm rd 1010011 +fcvt.h.q fa7,fa2,rdn # FCVT.H.Q I // 0100010 00011 rs1 rm rd 1010011 +feq.h a5,fa1,fa5 # FEQ.H R // 1010010 rs2 rs1 010 rd 1010011 +flt.h a3,fa3,fa6 # FLT.H R // 1010010 rs2 rs1 001 rd 1010011 +fle.h a7,fa2,fa4 # FLE.H R // 1010010 rs2 rs1 000 rd 1010011 +fclass.h a2,fa4 # FCLASS.H I // 1110010 00000 rs1 001 rd 1010011 +fcvt.w.h a7,fa1 # FCVT.W.H I // 1100010 00000 rs1 rm rd 1010011 +fcvt.wu.h a4,fa3 # FCVT.WU.H I // 1100010 00001 rs1 rm rd 1010011 +fmv.x.h a5,fa1 # FMV.X.H I // 1110010 00000 rs1 000 rd 1010011 +fcvt.h.w fa3,a4 # FCVT.H.W I // 1101010 00000 rs1 rm rd 1010011 +fcvt.h.wu fa6,a1 # FCVT.H.WU I // 1101010 00001 rs1 rm rd 1010011 +fmv.h.x fa2,a6 # FMV.H.X I // 1111010 00000 rs1 000 rd 1010011 +fli.h ft11,8.0 # FLI.H I // 1111010 00001 rs1 000 rd 1010011 + + + +#════════════════════════════════════════════════════════════════════════════════════════════════════ +#RV64Zfh Standard Extension (in addition to RV32Zfh) +#════════════════════════════════════════════════════════════════════════════════════════════════════ +fcvt.l.h a7,fa4,rtz # FCVT.L.H I // 1100010 00010 rs1 rm rd 1010011 +fcvt.lu.h a1,fa5,rne # FCVT.LU.H I // 1100010 00011 rs1 rm rd 1010011 +fcvt.h.l fa3,a6,rdn # FCVT.H.L I // 1101010 00010 rs1 rm rd 1010011 +fcvt.h.lu fa2,a7,rmm # FCVT.H.LU I // 1101010 00011 rs1 rm rd 1010011 diff --git a/subjects/Elf/RiscV/193.instructions/193.instructions.elf b/subjects/Elf/RiscV/193.instructions/193.instructions.elf index cca4b7ebc3028af7a378e2bcbd90766df843ec48..f2c23f6ab85e632bfcdd73b880b8d762a4ae3cbe 100644 GIT binary patch delta 1333 zcmb_cQA}H96#g%5?=28)JG!Rbv%Wh^LOpy^0>u;h<1Q6qFMO&dqo^>3R= zVp@WXn9WGJAc+rZfKiR{ff>LD9|~(qV{{M>;+r}$#~w@^Fxe7g=6_qRnQuP$C+B?U z|IRu8z30F8oH1wq?3k@qTZ;;drCLNSNKG||SfoNItd>1|YT3kGmF5L=O5|VT3mjz+ z5$Oxrh@l`K!5fQv>QBm+g1?j(c?BQOE5tFW-TL`kJ5P-3FC}!Saae~CL#T()NP^sY zl5|nIdxRu8GvzImw~*uywFEslN0K=!Nq+6$&vSjG%hX3!Ss!UP`}VsWK9W}l_LtiN zM9g_fX3bB;pWY%jErI>K>O9G`hg83dkA`0w(LL32OIJC?GL^5Zq)+rG)U7}BqLkJD zS~f1&K+xOZD_;7-aQwv#w~p&f>+k`44~8o5!Fam}*Ly_VDLOH6JAn~9z~JtH8PNqd z+%9~rA%hp%GH}DTj;Ez zOCQ6qmBYt>)8RIw8Grvx4gRa*O&Auecp_s>;Ln?_c;sRO)_-e zI0cjWQ#eg=f#T(Q5n`MZkJ{+%n4O@txxm)!g!CV?@F9B*w0CB)iMtICHCgodv6H6X#ksi+`W2=l|R)Pqbg5RwPKgal{N!Qxl0d zKNoBYJ9-D2!i~Ki+447qn|gh+x+trFgE|I-UJ{Wb27~_okhhp1~6a&k`4?O49q~1je&Jyxnfib6GRF|GYCNVj6jMFh*N~%@(mys zP#u__!wcduFu-VJeP9WN$%>5Xni2tH*JQku*!Bq#ZS{X%ew*oDjeY#)NB>K_Q6YIorBXN?QNpC)GsIop?uIb3FA zce<>0e9`6U&ld%=iY*GB%J%581mmI0(X9Nx*Vl*}eSP~zZCfNBN>D)VGhWo^y`1&9#G#6Y4giqi BTRQ*%