@ -1 +1 @@ | |||
Subproject commit 393c374cac4950e629036dda1615abedf866961f | |||
Subproject commit 23dbab0b768d122c492110d1db34408e9ae787f3 |
@ -1,108 +1,108 @@ | |||
import "RV32IBase.core_desc" | |||
InsructionSet RV32A extends RV32IBase{ | |||
address_spaces { | |||
RES[8] | |||
} | |||
instructions{ | |||
LR.W { | |||
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d"; | |||
if(rd!=0){ | |||
val offs[XLEN] <= X[rs1]; | |||
X[rd]<= sext(MEM[offs]{32}, XLEN); | |||
RES[offs]{32}<=sext(-1, 32); | |||
} | |||
} | |||
SC.W { | |||
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | |||
val offs[XLEN] <= X[rs1]; | |||
val res1[32] <= RES[offs]{32}; | |||
if(res1!=0) | |||
MEM[offs]{32} <= X[rs2]; | |||
if(rd!=0) X[rd]<= choose(res1!=0, 0, 1); | |||
} | |||
AMOSWAP.W{ | |||
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | |||
MEM[offs]{32}<=X[rs2]; | |||
} | |||
AMOADD.W{ | |||
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 + X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOXOR.W{ | |||
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 ^ X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOAND.W{ | |||
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN] <=res1 & X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOOR.W { | |||
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 | X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMIN.W{ | |||
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMAX.W{ | |||
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMINU.W{ | |||
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= zext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMAXU.W{ | |||
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= zext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
} | |||
address_spaces { | |||
RES[8] | |||
} | |||
instructions{ | |||
LR.W { | |||
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d"; | |||
if(rd!=0){ | |||
val offs[XLEN] <= X[rs1]; | |||
X[rd]<= sext(MEM[offs]{32}, XLEN); | |||
RES[offs]{32}<=sext(-1, 32); | |||
} | |||
} | |||
SC.W { | |||
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; | |||
val offs[XLEN] <= X[rs1]; | |||
val res1[32] <= RES[offs]{32}; | |||
if(res1!=0) | |||
MEM[offs]{32} <= X[rs2]; | |||
if(rd!=0) X[rd]<= choose(res1!=0, 0, 1); | |||
} | |||
AMOSWAP.W{ | |||
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
if(rd!=0) X[rd]<=sext(MEM[offs]{32}); | |||
MEM[offs]{32}<=X[rs2]; | |||
} | |||
AMOADD.W{ | |||
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 + X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOXOR.W{ | |||
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 ^ X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOAND.W{ | |||
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN] <=res1 & X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOOR.W { | |||
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<=res1 | X[rs2]; | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMIN.W{ | |||
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMAX.W{ | |||
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= sext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMINU.W{ | |||
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= zext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
AMOMAXU.W{ | |||
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; | |||
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; | |||
val offs[XLEN]<=X[rs1]; | |||
val res1[XLEN] <= zext(MEM[offs]{32}); | |||
if(rd!=0) X[rd]<=res1; | |||
val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1); | |||
MEM[offs]{32}<=res2; | |||
} | |||
} | |||
} |
@ -1,298 +1,298 @@ | |||
import "RV32IBase.core_desc" | |||
InsructionSet RV32D extends RV32IBase{ | |||
constants { | |||
FLEN, FFLAG_MASK := 0x1f | |||
} | |||
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]f<F[rs2]f, F[rs1]f, F[rs2]f); | |||
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 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}; | |||
} | |||
FMAX.D { | |||
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
//F[rd]f<= choose(F[rs1]f>F[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; | |||
} | |||
} | |||
} | |||
constants { | |||
FLEN, FFLAG_MASK := 0x1f | |||
} | |||
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]f<F[rs2]f, F[rs1]f, F[rs2]f); | |||
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 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}; | |||
} | |||
FMAX.D { | |||
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
//F[rd]f<= choose(F[rs1]f>F[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; | |||
} | |||
} | |||
} | |||
} |
@ -1,294 +1,294 @@ | |||
import "RV32IBase.core_desc" | |||
InsructionSet RV32F extends RV32IBase{ | |||
constants { | |||
FLEN, FFLAG_MASK := 0x1f | |||
} | |||
registers { | |||
[31:0] F[FLEN], FCSR[32] | |||
} | |||
instructions{ | |||
FLW { | |||
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111; | |||
args_disass:"f%rd$d, %imm%(x%rs1$d)"; | |||
val offs[XLEN] <= X[rs1]+imm; | |||
val res[32] <= MEM[offs]{32}; | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FSW { | |||
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111; | |||
args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | |||
val offs[XLEN] <= X[rs1]+imm; | |||
MEM[offs]{32}<=F[rs2]{32}; | |||
} | |||
FMADD.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FMSUB.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FNMADD.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FNMSUB.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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:"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 { // 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:"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 { // 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:"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 { // 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:"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 { // 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:"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 { // 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}; | |||
} | |||
FSGNJ.S { | |||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000); | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FSGNJN.S { | |||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000); | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FSGNJX.S { | |||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000); | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FMIN.S { | |||
encoding: b0010100 | 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]f<F[rs2]f, F[rs1]f, F[rs2]f); | |||
val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | |||
if(FLEN==32) | |||
F[rd] <= 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}; | |||
} | |||
FMAX.S { | |||
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; | |||
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f); | |||
val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | |||
if(FLEN==32) | |||
F[rd] <= 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}; | |||
} | |||
FCVT.W.S { | |||
encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | |||
args_disass:"x%rd$d, f%rs1$d"; | |||
X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN); | |||
val flags[32] <= fdispatch_fget_flags(); | |||
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | |||
} | |||
FCVT.WU.S { | |||
encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | |||
args_disass:"x%rd$d, f%rs1$d"; | |||
X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN); | |||
val flags[32] <= fdispatch_fget_flags(); | |||
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | |||
} | |||
FEQ.S { | |||
encoding: b1010000 | 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_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); | |||
val flags[32] <= fdispatch_fget_flags(); | |||
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | |||
} | |||
FLT.S { | |||
encoding: b1010000 | 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_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32)); | |||
val flags[32] <= fdispatch_fget_flags(); | |||
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | |||
} | |||
FLE.S { | |||
encoding: b1010000 | 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_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); | |||
val flags[32] <= fdispatch_fget_flags(); | |||
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; | |||
} | |||
FCLASS.S { | |||
encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; | |||
args_disass:"x%rd$d, f%rs1$d"; | |||
X[rd]<=fdispatch_fclass_s(F[rs1]{32}); | |||
} | |||
FCVT.S.W { | |||
encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, x%rs1$d"; | |||
val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FCVT.S.WU { | |||
encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, x%rs1$d"; | |||
val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FMV.X.W { | |||
encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | |||
args_disass:"x%rd$d, f%rs1$d"; | |||
X[rd]<=sext(F[rs1]{32}); | |||
} | |||
FMV.W.X { | |||
encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; | |||
args_disass:"f%rd$d, x%rs1$d"; | |||
if(FLEN==32) | |||
F[rd] <= X[rs1]; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(X[rs1], FLEN); | |||
} | |||
} | |||
} | |||
constants { | |||
FLEN, FFLAG_MASK := 0x1f | |||
} | |||
registers { | |||
[31:0] F[FLEN], FCSR[32] | |||
} | |||
instructions{ | |||
FLW { | |||
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111; | |||
args_disass:"f%rd$d, %imm%(x%rs1$d)"; | |||
val offs[XLEN] <= X[rs1]+imm; | |||
val res[32] <= MEM[offs]{32}; | |||
if(FLEN==32) | |||
F[rd] <= res; | |||
else { // NaN boxing | |||
val upper[FLEN] <= -1; | |||
F[rd] <= (upper<<32) | zext(res, FLEN); | |||
} | |||
} | |||
FSW { | |||
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111; | |||
args_disass:"f%rs2$d, %imm%(x%rs1$d)"; | |||
val offs[XLEN] <= X[rs1]+imm; | |||
MEM[offs]{32}<=F[rs2]{32}; | |||
} | |||
FMADD.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FMSUB.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FNMADD.S { | |||
encoding: rs3[4:0] | b00 | 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[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 { // 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}; | |||
} | |||
FNMSUB.S { | |||
encoding: rs3[4:0] | b00 | 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[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) | |||