From ce98e2ad31693208da998da063c836bb93d4426b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 24 Apr 2018 15:33:21 +0200 Subject: [PATCH] Added RV32D extension --- riscv/gen_input/RV32D.core_desc | 298 +++ riscv/gen_input/RV32F.core_desc | 118 +- riscv/gen_input/minres_rv.core_desc | 5 +- riscv/gen_input/templates/incl-CORENAME.h.gtl | 5 +- .../templates/vm-vm_CORENAME.cpp.gtl | 4 +- riscv/incl/iss/arch/rv32gc.h | 75 +- riscv/incl/iss/arch/rv32imac.h | 5 +- riscv/incl/iss/arch/rv64ia.h | 5 +- riscv/src/internal/fp_functions.cpp | 198 +- riscv/src/internal/vm_rv32gc.cpp | 1983 +++++++++++++++-- riscv/src/internal/vm_rv32imac.cpp | 4 +- riscv/src/internal/vm_rv64ia.cpp | 4 +- softfloat/source/RISCV/specialize.h | 24 +- 13 files changed, 2452 insertions(+), 276 deletions(-) create mode 100644 riscv/gen_input/RV32D.core_desc diff --git a/riscv/gen_input/RV32D.core_desc b/riscv/gen_input/RV32D.core_desc new file mode 100644 index 0000000..faf2b7b --- /dev/null +++ b/riscv/gen_input/RV32D.core_desc @@ -0,0 +1,298 @@ +import "RV32IBase.core_desc" + +InsructionSet RV32D extends RV32IBase{ + constants { + FLEN, FFLAG_MASK + } + registers { + [31:0] F[FLEN], FCSR[32] + } + instructions{ + FLD { + encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111; + args_disass:"f%rd$d, %imm%(x%rs1$d)"; + val offs[XLEN] <= X[rs1]+imm; + val res[64] <= MEM[offs]{64}; + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FSD { + encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111; + args_disass:"f%rs2$d, %imm%(x%rs1$d)"; + val offs[XLEN] <= X[rs1]+imm; + MEM[offs]{64}<=F[rs2]{64}; + } + FMADD.D { + encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + //F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; + val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FMSUB.D { + encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + //F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; + val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FNMADD.D { + encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + //F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; + val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FNMSUB.D { + encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + //F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; + val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FADD.D { + encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + // F[rd]f <= F[rs1]f + F[rs2]f; + val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FSUB.D { + encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + // F[rd]f <= F[rs1]f - F[rs2]f; + val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FMUL.D { + encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + // F[rd]f <= F[rs1]f * F[rs2]f; + val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FDIV.D { + encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + // F[rd]f <= F[rs1]f / F[rs2]f; + val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FSQRT.D { + encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d"; + //F[rd]f<=sqrt(F[rs1]f); + val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8})); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FSGNJ.D { + encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FSGNJN.D { + encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FSGNJX.D { + encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FMIN.D { + encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + //F[rd]f<= choose(F[rs1]fF[rs2]f, F[rs1]f, F[rs2]f); + val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCVT.S.D { + encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d"; + val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8}); + // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= upper<<32 | zext(res, FLEN); + } + FCVT.D.S { + encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"f%rd$d, f%rs1$d"; + val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8}); + if(FLEN==64){ + F[rd] <= res; + } else { + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FEQ.D { + encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FLT.D { + encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32)); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FLE.D { + encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCLASS.D { + encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d"; + X[rd]<=fdispatch_fclass_d(F[rs1]{64}); + } + FCVT.W.D { + encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d"; + X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCVT.WU.D { + encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x%rd$d, f%rs1$d"; + X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCVT.D.W { + encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"f%rd$d, x%rs1$d"; + val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8}); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + FCVT.D.WU { + encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"f%rd$d, x%rs1$d"; + val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8}); + if(FLEN==64) + F[rd] <= res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<64) | res; + } + } + } +} \ No newline at end of file diff --git a/riscv/gen_input/RV32F.core_desc b/riscv/gen_input/RV32F.core_desc index ea5711e..3a41db7 100644 --- a/riscv/gen_input/RV32F.core_desc +++ b/riscv/gen_input/RV32F.core_desc @@ -15,9 +15,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= MEM[offs]{32}; if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FSW { @@ -33,9 +33,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -47,9 +47,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -61,9 +61,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -75,79 +75,79 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FADD.S { encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; // F[rd]f <= F[rs1]f + F[rs2]f; val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= (-1<<31); - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FSUB.S { encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; // F[rd]f <= F[rs1]f - F[rs2]f; val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FMUL.S { encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; // F[rd]f <= F[rs1]f * F[rs2]f; val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FDIV.S { encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; // F[rd]f <= F[rs1]f / F[rs2]f; val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FSQRT.S { encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"f%rd$d, f%rs1$d"; //F[rd]f<=sqrt(F[rs1]f); val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -158,9 +158,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FSGNJN.S { @@ -169,9 +169,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FSGNJX.S { @@ -180,9 +180,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FMIN.S { @@ -192,9 +192,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -206,9 +206,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; @@ -259,9 +259,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FCVT.S.WU { @@ -270,9 +270,9 @@ InsructionSet RV32F extends RV32IBase{ val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); if(FLEN==32) F[rd] <= res; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | res; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); } } FMV.X.W { @@ -285,9 +285,9 @@ InsructionSet RV32F extends RV32IBase{ args_disass:"f%rd$d, x%rs1$d"; if(FLEN==32) F[rd] <= X[rs1]; - else { - val upper[FLEN] <= -1<<31; - F[rd] <= upper*2 | X[rs1]; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(X[rs1], FLEN); } } } diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index 3b8ee93..5b5485f 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -3,6 +3,7 @@ import "RV32M.core_desc" import "RV32A.core_desc" import "RV32C.core_desc" import "RV32F.core_desc" +import "RV32D.core_desc" import "RV64IBase.core_desc" //import "RV64M.core_desc" import "RV64A.core_desc" @@ -26,10 +27,10 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { } } -Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC { +Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D { constants { XLEN:=32; - FLEN:=32; + FLEN:=64; XLEN2:=64; XLEN_BIT_MASK:=0x1f; PCLEN:=32; diff --git a/riscv/gen_input/templates/incl-CORENAME.h.gtl b/riscv/gen_input/templates/incl-CORENAME.h.gtl index 4b0c2d3..0b5ecb0 100644 --- a/riscv/gen_input/templates/incl-CORENAME.h.gtl +++ b/riscv/gen_input/templates/incl-CORENAME.h.gtl @@ -56,6 +56,8 @@ struct traits<${coreDef.name.toLowerCase()}> { enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}}; + constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0}; + enum reg_e {<% allRegs.each { reg -> if( reg instanceof RegisterFile) { @@ -99,9 +101,6 @@ struct traits<${coreDef.name.toLowerCase()}> { enum sreg_flag_e {FLAGS}; enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}}; - - constexpr static bool has_fp_regs = ${allRegs.find {it.name=='FCSR'}!= null ?'true':'false'}; - }; struct ${coreDef.name.toLowerCase()}: public arch_if { diff --git a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl index 0b78375..acb1dea 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -50,7 +50,7 @@ namespace iss { namespace vm { namespace fp_impl{ -void add_fp_functions_2_module(llvm::Module *mod); +void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -89,7 +89,7 @@ protected: void setup_module(llvm::Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, diff --git a/riscv/incl/iss/arch/rv32gc.h b/riscv/incl/iss/arch/rv32gc.h index 106c70c..297aaaa 100644 --- a/riscv/incl/iss/arch/rv32gc.h +++ b/riscv/incl/iss/arch/rv32gc.h @@ -48,7 +48,9 @@ struct traits { constexpr static char const* const core_type = "RV32GC"; - enum constants {XLEN=32, FLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31}; + enum constants {XLEN=32, FLEN=64, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31}; + + constexpr static unsigned FP_REGS_SIZE = 64; enum reg_e { X0, @@ -136,12 +138,12 @@ struct traits { using phys_addr_t = iss::typed_addr_t; constexpr static unsigned reg_bit_width(unsigned r) { - constexpr std::array RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; + constexpr std::array RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,64}}; return RV32GC_reg_size[r]; } constexpr static unsigned reg_byte_offset(unsigned r) { - constexpr std::array RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,288}}; + constexpr std::array RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,416,424}}; return RV32GC_reg_byte_offset[r]; } @@ -150,9 +152,6 @@ struct traits { enum sreg_flag_e {FLAGS}; enum mem_type_e {MEM, CSR, FENCE, RES}; - - constexpr static bool has_fp_regs = true; - }; struct rv32gc: public arch_if { @@ -227,38 +226,38 @@ protected: uint32_t X30 = 0; uint32_t X31 = 0; uint32_t PC = 0; - uint32_t F0 = 0; - uint32_t F1 = 0; - uint32_t F2 = 0; - uint32_t F3 = 0; - uint32_t F4 = 0; - uint32_t F5 = 0; - uint32_t F6 = 0; - uint32_t F7 = 0; - uint32_t F8 = 0; - uint32_t F9 = 0; - uint32_t F10 = 0; - uint32_t F11 = 0; - uint32_t F12 = 0; - uint32_t F13 = 0; - uint32_t F14 = 0; - uint32_t F15 = 0; - uint32_t F16 = 0; - uint32_t F17 = 0; - uint32_t F18 = 0; - uint32_t F19 = 0; - uint32_t F20 = 0; - uint32_t F21 = 0; - uint32_t F22 = 0; - uint32_t F23 = 0; - uint32_t F24 = 0; - uint32_t F25 = 0; - uint32_t F26 = 0; - uint32_t F27 = 0; - uint32_t F28 = 0; - uint32_t F29 = 0; - uint32_t F30 = 0; - uint32_t F31 = 0; + uint64_t F0 = 0; + uint64_t F1 = 0; + uint64_t F2 = 0; + uint64_t F3 = 0; + uint64_t F4 = 0; + uint64_t F5 = 0; + uint64_t F6 = 0; + uint64_t F7 = 0; + uint64_t F8 = 0; + uint64_t F9 = 0; + uint64_t F10 = 0; + uint64_t F11 = 0; + uint64_t F12 = 0; + uint64_t F13 = 0; + uint64_t F14 = 0; + uint64_t F15 = 0; + uint64_t F16 = 0; + uint64_t F17 = 0; + uint64_t F18 = 0; + uint64_t F19 = 0; + uint64_t F20 = 0; + uint64_t F21 = 0; + uint64_t F22 = 0; + uint64_t F23 = 0; + uint64_t F24 = 0; + uint64_t F25 = 0; + uint64_t F26 = 0; + uint64_t F27 = 0; + uint64_t F28 = 0; + uint64_t F29 = 0; + uint64_t F30 = 0; + uint64_t F31 = 0; uint32_t FCSR = 0; uint32_t NEXT_PC = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index 2f8ce5c..5e8924b 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -50,6 +50,8 @@ struct traits { enum constants {XLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095}; + constexpr static unsigned FP_REGS_SIZE = 0; + enum reg_e { X0, X1, @@ -117,9 +119,6 @@ struct traits { enum sreg_flag_e {FLAGS}; enum mem_type_e {MEM, CSR, FENCE, RES}; - - constexpr static bool has_fp_regs = false; - }; struct rv32imac: public arch_if { diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index d97023f..1c2b12d 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64ia.h @@ -50,6 +50,8 @@ struct traits { enum constants {XLEN=64, XLEN2=128, XLEN_BIT_MASK=63, PCLEN=64, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=2147746049, PGSIZE=4096, PGMASK=4095}; + constexpr static unsigned FP_REGS_SIZE = 0; + enum reg_e { X0, X1, @@ -117,9 +119,6 @@ struct traits { enum sreg_flag_e {FLAGS}; enum mem_type_e {MEM, CSR, FENCE, RES}; - - constexpr static bool has_fp_regs = false; - }; struct rv64ia: public arch_if { diff --git a/riscv/src/internal/fp_functions.cpp b/riscv/src/internal/fp_functions.cpp index c01492b..34c1bac 100644 --- a/riscv/src/internal/fp_functions.cpp +++ b/riscv/src/internal/fp_functions.cpp @@ -41,6 +41,8 @@ extern "C" { #include "specialize.h" } +#include + namespace iss { namespace vm { namespace fp_impl { @@ -68,18 +70,34 @@ using namespace std; using namespace llvm; -void add_fp_functions_2_module(Module *mod) { - FDECL(fget_flags, INT_TYPE(32)); - FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fsub_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fmul_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fdiv_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fsqrt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fcmp_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); - FDECL(fcvt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); - FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); - FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32)); +void add_fp_functions_2_module(Module *mod, uint32_t flen) { + if(flen){ + FDECL(fget_flags, INT_TYPE(32)); + FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fsub_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fmul_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fdiv_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fsqrt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fcmp_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); + FDECL(fcvt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); + FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32)); + if(flen>32){ + FDECL(fconv_d2f, INT_TYPE(32), INT_TYPE(64), INT_TYPE(8)); + FDECL(fconv_f2d, INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); + FDECL(fadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); + FDECL(fsub_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); + FDECL(fmul_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); + FDECL(fdiv_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); + FDECL(fsqrt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); + FDECL(fcmp_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32)); + FDECL(fcvt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); + FDECL(fmadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); + FDECL(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32)); + FDECL(fclass_d, INT_TYPE(64), INT_TYPE(64)); + } + } } } @@ -202,14 +220,14 @@ uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mod softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_exceptionFlags=0; float32_t res = softfloat_mulAddF32(v1, v2, v3, op&0x1); - if(op>1) res.v ^= 0x80000000UL; + if(op>1) res.v ^= 1ULL<<31; return res.v; } uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op) { softfloat_exceptionFlags = 0; - bool v1_nan = (v1 & defaultNaNF32UI) == quiet_nan32; - bool v2_nan = (v2 & defaultNaNF32UI) == quiet_nan32; + bool v1_nan = (v1 & defaultNaNF32UI) == defaultNaNF32UI; + bool v2_nan = (v2 & defaultNaNF32UI) == defaultNaNF32UI; bool v1_snan = softfloat_isSigNaNF32UI(v1); bool v2_snan = softfloat_isSigNaNF32UI(v2); if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid); @@ -257,6 +275,156 @@ uint32_t fclass_s( uint32_t v1 ){ ( isNaN && !isSNaN ) << 9; } +uint32_t fconv_d2f(uint64_t v1, uint8_t mode){ + softfloat_roundingMode=rmm_map[mode&0x7]; + bool nan = (v1 & defaultNaNF64UI)==defaultNaNF64UI; + if(nan){ + return defaultNaNF32UI; + } else { + float32_t res = f64_to_f32(float64_t{v1}); + return res.v; + } +} + +uint64_t fconv_f2d(uint32_t v1, uint8_t mode){ + bool nan = (v1 & defaultNaNF32UI)==defaultNaNF32UI; + if(nan){ + return defaultNaNF64UI; + } else { + softfloat_roundingMode=rmm_map[mode&0x7]; + float64_t res = f32_to_f64(float32_t{v1}); + return res.v; + } +} + +uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode) { + bool nan = (v1&defaultNaNF32UI)==quiet_nan32; + bool snan = softfloat_isSigNaNF32UI(v1); + float64_t v1f{v1},v2f{v2}; + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t r =f64_add(v1f, v2f); + return r.v; +} + +uint64_t fsub_d(uint64_t v1, uint64_t v2, uint8_t mode) { + float64_t v1f{v1},v2f{v2}; + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t r=f64_sub(v1f, v2f); + return r.v; +} + +uint64_t fmul_d(uint64_t v1, uint64_t v2, uint8_t mode) { + float64_t v1f{v1},v2f{v2}; + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t r=f64_mul(v1f, v2f); + return r.v; +} + +uint64_t fdiv_d(uint64_t v1, uint64_t v2, uint8_t mode) { + float64_t v1f{v1},v2f{v2}; + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t r=f64_div(v1f, v2f); + return r.v; +} + +uint64_t fsqrt_d(uint64_t v1, uint8_t mode) { + float64_t v1f{v1}; + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t r=f64_sqrt(v1f); + return r.v; +} + +uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) { + float64_t v1f{v1},v2f{v2}; + softfloat_exceptionFlags=0; + bool nan = (v1&defaultNaNF64UI)==quiet_nan32 || (v2&defaultNaNF64UI)==quiet_nan32; + bool snan = softfloat_isSigNaNF64UI(v1) || softfloat_isSigNaNF64UI(v2); + switch(op){ + case 0: + if(nan | snan){ + if(snan) softfloat_raiseFlags(softfloat_flag_invalid); + return 0; + } else + return f64_eq(v1f,v2f )?1:0; + case 1: + if(nan | snan){ + softfloat_raiseFlags(softfloat_flag_invalid); + return 0; + } else + return f64_le(v1f,v2f )?1:0; + case 2: + if(nan | snan){ + softfloat_raiseFlags(softfloat_flag_invalid); + return 0; + } else + return f64_lt(v1f,v2f )?1:0; + default: + break; + } + return -1; +} + +uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) { + float64_t v1f{v1}; + softfloat_exceptionFlags=0; + float64_t r; + int32_t res; + switch(op){ + case 0: //w->s, fp to int32 + res = f64_to_i64(v1f,rmm_map[mode&0x7],true); + return (uint64_t)res; + case 1: //wu->s + return f64_to_ui64(v1f,rmm_map[mode&0x7],true); + case 2: //s->w + r=i64_to_f64(v1); + return r.v; + case 3: //s->wu + r=ui64_to_f64(v1); + return r.v; + } + return 0; +} + +uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode) { + // op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)} + softfloat_roundingMode=rmm_map[mode&0x7]; + softfloat_exceptionFlags=0; + float64_t res = softfloat_mulAddF64(v1, v2, v3, op&0x1); + if(op>1) res.v ^= 1ULL<<63; + return res.v; +} + +uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op) { + softfloat_exceptionFlags = 0; + bool v1_nan = (v1 & defaultNaNF64UI) == defaultNaNF64UI; + bool v2_nan = (v2 & defaultNaNF64UI) == defaultNaNF64UI; + bool v1_snan = softfloat_isSigNaNF64UI(v1); + bool v2_snan = softfloat_isSigNaNF64UI(v2); + if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid); + if (v1_nan || v1_snan) + return (v2_nan || v2_snan) ? defaultNaNF64UI : v2; + else + if (v2_nan || v2_snan) + return v1; + else { + if ((v1 & std::numeric_limits::max()) == 0 && (v2 & std::numeric_limits::max()) == 0) { + return op == 0 ? + ((v1 & std::numeric_limits::min()) ? v1 : v2) : + ((v1 & std::numeric_limits::min()) ? v2 : v1); + } else { + float64_t v1f{ v1 }, v2f{ v2 }; + return op == 0 ? + (f64_lt(v1f, v2f) ? v1 : v2) : + (f64_lt(v1f, v2f) ? v2 : v1); + } + } +} + uint64_t fclass_d(uint64_t v1 ){ float64_t a{v1}; diff --git a/riscv/src/internal/vm_rv32gc.cpp b/riscv/src/internal/vm_rv32gc.cpp index 2f8c0bf..1bab6fe 100644 --- a/riscv/src/internal/vm_rv32gc.cpp +++ b/riscv/src/internal/vm_rv32gc.cpp @@ -50,7 +50,7 @@ namespace iss { namespace vm { namespace fp_impl{ -void add_fp_functions_2_module(llvm::Module *mod); +void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -89,7 +89,7 @@ protected: void setup_module(llvm::Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, @@ -194,7 +194,7 @@ private: compile_func op; }; - const std::array instr_descr = {{ + const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, @@ -454,6 +454,58 @@ private: {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, /* instruction C.FSWSP */ {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, + /* instruction FLD */ + {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, + /* instruction FSD */ + {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, + /* instruction FMADD.D */ + {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, + /* instruction FMSUB.D */ + {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, + /* instruction FNMADD.D */ + {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, + /* instruction FNMSUB.D */ + {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, + /* instruction FADD.D */ + {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, + /* instruction FSUB.D */ + {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, + /* instruction FMUL.D */ + {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, + /* instruction FDIV.D */ + {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, + /* instruction FSQRT.D */ + {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, + /* instruction FSGNJ.D */ + {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, + /* instruction FSGNJN.D */ + {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, + /* instruction FSGNJX.D */ + {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, + /* instruction FMIN.D */ + {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, + /* instruction FMAX.D */ + {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, + /* instruction FCVT.S.D */ + {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, + /* instruction FCVT.D.S */ + {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, + /* instruction FEQ.D */ + {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, + /* instruction FLT.D */ + {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, + /* instruction FLE.D */ + {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, + /* instruction FCLASS.D */ + {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, + /* instruction FCVT.W.D */ + {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, + /* instruction FCVT.WU.D */ + {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, + /* instruction FCVT.D.W */ + {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, + /* instruction FCVT.D.WU */ + {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, }}; /* instruction definitions */ @@ -589,19 +641,43 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); - } - Value* ret_val = this->builder.CreateAdd( + Value* new_pc_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val + traits::X0, 0), this->gen_const(32U, fld_imm_val)); - Value* PC_val = this->builder.CreateAnd( - ret_val, - this->builder.CreateNot(this->gen_const(32U, 1))); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* align_val = this->builder.CreateAnd( + new_pc_val, + this->gen_const(32U, 2)); + llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( + ICmpInst::ICMP_NE, + align_val, + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + this->gen_raise_trap(0, 0); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + } + Value* PC_val = this->builder.CreateAnd( + new_pc_val, + this->builder.CreateNot(this->gen_const(32U, 1))); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); this->gen_sync(iss::POST_SYNC, 3); this->gen_trap_check(this->leave_blk); return std::make_tuple(iss::vm::BRANCH, nullptr); @@ -4664,16 +4740,19 @@ private: this->gen_reg_load(fld_rs1_val + traits::X0, 0), this->gen_const(32U, fld_imm_val)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -4780,16 +4859,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -4862,16 +4944,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -4944,16 +5029,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5026,16 +5114,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5065,7 +5156,7 @@ private: uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FADD.S x%1$d, f%2$d, f%3$d"); + boost::format ins_fmter("FADD.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; std::vector args { this->core_ptr, @@ -5099,16 +5190,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5138,7 +5232,7 @@ private: uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSUB.S x%1$d, f%2$d, f%3$d"); + boost::format ins_fmter("FSUB.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; std::vector args { this->core_ptr, @@ -5172,16 +5266,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5211,7 +5308,7 @@ private: uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMUL.S x%1$d, f%2$d, f%3$d"); + boost::format ins_fmter("FMUL.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; std::vector args { this->core_ptr, @@ -5245,16 +5342,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5284,7 +5384,7 @@ private: uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FDIV.S x%1$d, f%2$d, f%3$d"); + boost::format ins_fmter("FDIV.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; std::vector args { this->core_ptr, @@ -5318,16 +5418,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5356,7 +5459,7 @@ private: uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSQRT.S x%1$d, f%2$d"); + boost::format ins_fmter("FSQRT.S f%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; std::vector args { this->core_ptr, @@ -5386,16 +5489,19 @@ private: ), 8) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5450,16 +5556,19 @@ private: this-> get_type(32) ), this->gen_const(32U, 2147483648))); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -5506,16 +5615,19 @@ private: this-> get_type(32) )), this->gen_const(32U, 2147483648))); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -5560,16 +5672,19 @@ private: this-> get_type(32) ), this->gen_const(32U, 2147483648))); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -5617,16 +5732,19 @@ private: 32, false) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -5682,16 +5800,19 @@ private: 32, false) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ @@ -6051,16 +6172,19 @@ private: false), this->gen_const(8U, fld_rm_val) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -6105,16 +6229,19 @@ private: false), this->gen_const(8U, fld_rm_val) }); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - res_val); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -6185,16 +6312,19 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1); Value* F_rd_val = this->builder.CreateOr( - this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), - this->gen_reg_load(fld_rs1_val + traits::X0, 0)); + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + this->gen_reg_load(fld_rs1_val + traits::X0, 0), + 64, + false)); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -6234,15 +6364,15 @@ private: this->gen_reg_load(rs1_idx_val + traits::X0, 0), this->gen_const(32U, fld_uimm_val)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(32 == 32){ + if(64 == 32){ Value* F_rd_idx_val = res_val; this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1) << 31; Value* F_rd_idx_val = this->builder.CreateOr( this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), + this->gen_const(64U, upper_val), + this->gen_const(64U, 2)), res_val); this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits::F0), false); } @@ -6325,15 +6455,15 @@ private: this->gen_reg_load(x2_idx_val + traits::X0, 0), this->gen_const(32U, fld_uimm_val)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(32 == 32){ + if(64 == 32){ Value* F_rd_val = res_val; this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } else { - uint32_t upper_val = (-1) << 31; + uint64_t upper_val = (-1) << 31; Value* F_rd_val = this->builder.CreateOr( this->builder.CreateMul( - this->gen_const(32U, upper_val), - this->gen_const(32U, 2)), + this->gen_const(64U, upper_val), + this->gen_const(64U, 2)), res_val); this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); } @@ -6383,6 +6513,1589 @@ private: return std::make_tuple(vm::CONT, bb); } + /* instruction 129: FLD */ + std::tuple __fld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FLD"); + + this->gen_sync(iss::PRE_SYNC, 129); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FLD f%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_const(32U, fld_imm_val)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 129); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 130: FSD */ + std::tuple __fsd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSD"); + + this->gen_sync(iss::PRE_SYNC, 130); + + int16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSD f%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_const(32U, fld_imm_val)); + Value* MEM_offs_val = this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 130); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 131: FMADD.D */ + std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FMADD.D"); + + this->gen_sync(iss::PRE_SYNC, 131); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rs3_val = 0 | (bit_sub<27,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 64, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 131); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 132: FMSUB.D */ + std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FMSUB.D"); + + this->gen_sync(iss::PRE_SYNC, 132); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rs3_val = 0 | (bit_sub<27,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 132); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 133: FNMADD.D */ + std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FNMADD.D"); + + this->gen_sync(iss::PRE_SYNC, 133); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rs3_val = 0 | (bit_sub<27,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FNMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 133); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 134: FNMSUB.D */ + std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FNMSUB.D"); + + this->gen_sync(iss::PRE_SYNC, 134); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rs3_val = 0 | (bit_sub<27,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FNMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 134); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 135: FADD.D */ + std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FADD.D"); + + this->gen_sync(iss::PRE_SYNC, 135); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FADD.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 135); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 136: FSUB.D */ + std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSUB.D"); + + this->gen_sync(iss::PRE_SYNC, 136); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSUB.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 136); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 137: FMUL.D */ + std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FMUL.D"); + + this->gen_sync(iss::PRE_SYNC, 137); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FMUL.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 137); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 138: FDIV.D */ + std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FDIV.D"); + + this->gen_sync(iss::PRE_SYNC, 138); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FDIV.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 138); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 139: FSQRT.D */ + std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSQRT.D"); + + this->gen_sync(iss::PRE_SYNC, 139); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSQRT.D x%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(3U, fld_rm_val), + this->gen_const(3U, 7)), + this->gen_const(8U, fld_rm_val), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 139); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 140: FSGNJ.D */ + std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSGNJ.D"); + + this->gen_sync(iss::PRE_SYNC, 140); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSGNJ.D f%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, 2147483647)), + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, 2147483648))); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 140); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 141: FSGNJN.D */ + std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSGNJN.D"); + + this->gen_sync(iss::PRE_SYNC, 141); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSGNJN.D f%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, 2147483647)), + this->builder.CreateAnd( + this->builder.CreateNot(this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + )), + this->gen_const(64U, 2147483648))); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 141); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 142: FSGNJX.D */ + std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FSGNJX.D"); + + this->gen_sync(iss::PRE_SYNC, 142); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FSGNJX.D f%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateXor( + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, 2147483648))); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 142); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 143: FMIN.D */ + std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FMIN.D"); + + this->gen_sync(iss::PRE_SYNC, 143); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FMIN.D f%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 143); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 144: FMAX.D */ + std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FMAX.D"); + + this->gen_sync(iss::PRE_SYNC, 144); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FMAX.D f%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 144); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 145: FCVT.S.D */ + std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.S.D"); + + this->gen_sync(iss::PRE_SYNC, 145); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.S.D f%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector{ + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_const(8U, fld_rm_val) + }); + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 145); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 146: FCVT.D.S */ + std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.D.S"); + + this->gen_sync(iss::PRE_SYNC, 146); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.D.S f%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(32) + ), + this->gen_const(8U, fld_rm_val) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 146); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 147: FEQ.D */ + std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FEQ.D"); + + this->gen_sync(iss::PRE_SYNC, 147); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FEQ.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 147); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 148: FLT.D */ + std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FLT.D"); + + this->gen_sync(iss::PRE_SYNC, 148); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FLT.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 148); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 149: FLE.D */ + std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FLE.D"); + + this->gen_sync(iss::PRE_SYNC, 149); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FLE.D x%1$d, f%2$d, f%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 149); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 150: FCLASS.D */ + std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCLASS.D"); + + this->gen_sync(iss::PRE_SYNC, 150); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCLASS.D x%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ) + }); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 150); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 151: FCVT.W.D */ + std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.W.D"); + + this->gen_sync(iss::PRE_SYNC, 151); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.W.D x%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, fld_rm_val) + }), + 32, + true); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 151); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 152: FCVT.WU.D */ + std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.WU.D"); + + this->gen_sync(iss::PRE_SYNC, 152); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.WU.D x%1$d, f%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* X_rd_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, fld_rm_val) + }), + 32, + false); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 31))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 152); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 153: FCVT.D.W */ + std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.D.W"); + + this->gen_sync(iss::PRE_SYNC, 153); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.D.W f%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->gen_ext( + this->gen_reg_load(fld_rs1_val + traits::X0, 0), + 64, + true), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, fld_rm_val) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 153); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + /* instruction 154: FCVT.D.WU */ + std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("FCVT.D.WU"); + + this->gen_sync(iss::PRE_SYNC, 154); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rm_val = 0 | (bit_sub<12,3>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("FCVT.D.WU f%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->gen_ext( + this->gen_reg_load(fld_rs1_val + traits::X0, 0), + 64, + false), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, fld_rm_val) + }); + if(64 == 64){ + Value* F_rd_val = res_val; + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } else { + uint64_t upper_val = (-1); + Value* F_rd_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 154); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + /**************************************************************************** * end opcode definitions ****************************************************************************/ diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index 6ba14bd..daa48da 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -50,7 +50,7 @@ namespace iss { namespace vm { namespace fp_impl{ -void add_fp_functions_2_module(llvm::Module *mod); +void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -89,7 +89,7 @@ protected: void setup_module(llvm::Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index 9aa7777..cfdfe57 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -50,7 +50,7 @@ namespace iss { namespace vm { namespace fp_impl{ -void add_fp_functions_2_module(llvm::Module *mod); +void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -89,7 +89,7 @@ protected: void setup_module(llvm::Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, diff --git a/softfloat/source/RISCV/specialize.h b/softfloat/source/RISCV/specialize.h index ec54615..1cb9854 100644 --- a/softfloat/source/RISCV/specialize.h +++ b/softfloat/source/RISCV/specialize.h @@ -51,23 +51,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | The values to return on conversions to 32-bit integer formats that raise an | invalid exception. *----------------------------------------------------------------------------*/ -#define ui32_fromPosOverflow 0xFFFFFFFF -#define ui32_fromNegOverflow 0x0 -#define ui32_fromNaN 0xFFFFFFFF -#define i32_fromPosOverflow (0x7FFFFFFF) -#define i32_fromNegOverflow (-0x7FFFFFFF - 1) -#define i32_fromNaN (0x7FFFFFFF) +#define ui32_fromPosOverflow UINT32_C(0xFFFFFFFF) +#define ui32_fromNegOverflow UINT32_C(0x0) +#define ui32_fromNaN UINT32_C(0xFFFFFFFF) +#define i32_fromPosOverflow INT64_C(0x7FFFFFFF) +#define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF)-1) +#define i32_fromNaN INT64_C(0x7FFFFFFF) /*---------------------------------------------------------------------------- | The values to return on conversions to 64-bit integer formats that raise an | invalid exception. *----------------------------------------------------------------------------*/ #define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) +#define ui64_fromNegOverflow UINT64_C( 0x0 ) +#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF) +#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF) +#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF)-1) +#define i64_fromNaN INT64_C( 0x7FFFFFFFFFFFFFFF) /*---------------------------------------------------------------------------- | "Common NaN" structure, used to transfer NaN representations from one format @@ -155,7 +155,7 @@ uint_fast32_t /*---------------------------------------------------------------------------- | The bit pattern for a default generated 64-bit floating-point NaN. *----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 ) +#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) /*---------------------------------------------------------------------------- | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a