2017-08-27 12:10:38 +02:00
|
|
|
import "RV32IBase.core_desc"
|
|
|
|
|
|
|
|
InsructionSet RV32F extends RV32IBase{
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, {imm}(x{rs1})";
|
2018-05-09 12:14:59 +02:00
|
|
|
val offs[XLEN] <= X[rs1]'s + imm;
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rs2}, {imm}(x{rs1})";
|
2018-05-09 12:14:59 +02:00
|
|
|
val offs[XLEN] <= X[rs1]'s + imm;
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
|
|
|
|
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
|
|
|
|
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
|
|
|
|
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
|
|
|
|
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
// F[rd]f <= F[rs1]f + F[rs2]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fadd_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fadd_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
// F[rd]f <= F[rs1]f - F[rs2]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fsub_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fsub_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
// F[rd]f <= F[rs1]f * F[rs2]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fmul_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fmul_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
// F[rd]f <= F[rs1]f / F[rs2]f;
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fdiv_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fdiv_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<=sqrt(F[rs1]f);
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fsqrt_s(F[rs1], choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val res[32] <= fdispatch_fsqrt_s(frs1, choose(rm<7, rm{8}, FCSR{8}));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= (F[rs1] & 0x7fffffff) | (F[rs2] & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= (frs1 & 0x7fffffff) | (frs2 & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= (F[rs1] & 0x7fffffff) | (~F[rs2] & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= (frs1 & 0x7fffffff) | (~frs2 & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= F[rs1] ^ (F[rs2] & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= frs1 ^ (frs2 & 0x80000000);
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fsel_s(F[rs1], F[rs2], zext(0, 32));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fsel_s(frs1, frs2, zext(0, 32));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2018-11-24 20:29:24 +01:00
|
|
|
args_disass:"f{rd}, f{rs1}, f{rs2}";
|
2018-04-30 19:22:00 +02:00
|
|
|
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
|
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fsel_s(F[rs1], F[rs2], zext(1, 32));
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
val res[32] <= fdispatch_fsel_s(frs1, frs2, zext(1, 32));
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}";
|
|
|
|
if(FLEN==32)
|
|
|
|
X[rd] <= sext(fdispatch_fcvt_s(F[rs1], zext(0, 32), rm{8}), XLEN);
|
|
|
|
else { // NaN boxing
|
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(0, 32), rm{8}), XLEN);
|
|
|
|
}
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}";
|
|
|
|
//FIXME: according to the spec it should be zero-extended not sign extended
|
|
|
|
if(FLEN==32)
|
|
|
|
X[rd]<= sext(fdispatch_fcvt_s(F[rs1], zext(1, 32), rm{8}), XLEN);
|
|
|
|
else { // NaN boxing
|
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(1, 32), rm{8}), XLEN);
|
|
|
|
}
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
|
|
|
|
if(FLEN==32)
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(0, 32)));
|
|
|
|
else {
|
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(0, 32)));
|
|
|
|
}
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
|
|
|
|
if(FLEN==32)
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(2, 32)));
|
|
|
|
else {
|
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(2, 32)));
|
|
|
|
}
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
|
|
|
|
if(FLEN==32)
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(1, 32)));
|
|
|
|
else {
|
|
|
|
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
|
|
|
|
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
|
|
|
|
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(1, 32)));
|
|
|
|
}
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}";
|
|
|
|
X[rd]<=fdispatch_fclass_s(fdispatch_unbox_s(F[rs1]));
|
2018-04-30 19:22:00 +02:00
|
|
|
}
|
|
|
|
FCVT.S.W {
|
|
|
|
encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"f{rd}, {name(rs1)}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
|
2018-04-30 19:22:00 +02:00
|
|
|
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;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"f{rd}, {name(rs1)}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
2019-01-10 11:35:20 +01:00
|
|
|
val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
|
|
|
|
val upper[FLEN] <= -1;
|
2018-04-30 19:22:00 +02:00
|
|
|
F[rd] <= (upper<<32) | zext(res, FLEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FMV.X.W {
|
|
|
|
encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"{name(rd)}, f{rs1}";
|
2018-04-30 19:22:00 +02:00
|
|
|
X[rd]<=sext(F[rs1]{32});
|
|
|
|
}
|
|
|
|
FMV.W.X {
|
|
|
|
encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
2019-01-10 11:35:20 +01:00
|
|
|
args_disass:"f{rd}, {name(rs1)}";
|
2018-04-30 19:22:00 +02:00
|
|
|
if(FLEN==32)
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= X[rs1]{32};
|
2018-04-30 19:22:00 +02:00
|
|
|
else { // NaN boxing
|
|
|
|
val upper[FLEN] <= -1;
|
2019-01-10 11:35:20 +01:00
|
|
|
F[rd] <= (upper<<32) | zext(X[rs1]{32}, FLEN);
|
2018-04-30 19:22:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 11:35:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
InsructionSet RV64F extends RV32F{
|
|
|
|
constants {
|
|
|
|
FLEN, FFLAG_MASK := 0x1f
|
|
|
|
}
|
|
|
|
registers {
|
|
|
|
[31:0] F[FLEN], FCSR[32]
|
|
|
|
}
|
|
|
|
instructions{
|
|
|
|
FCVT.L.S { // fp to 64bit signed integer
|
|
|
|
encoding: b1100000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
|
|
|
args_disass:"x{rd}, f{rs1}";
|
|
|
|
val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(0, 32), rm{8});
|
|
|
|
X[rd]<= sext(res);
|
|
|
|
val flags[32] <= fdispatch_fget_flags();
|
|
|
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
|
|
|
}
|
|
|
|
FCVT.LU.S { // fp to 64bit unsigned integer
|
|
|
|
encoding: b1100000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
|
|
|
args_disass:"x{rd}, f{rs1}";
|
|
|
|
val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(1, 32), rm{8});
|
|
|
|
X[rd]<= zext(res);
|
|
|
|
val flags[32] <= fdispatch_fget_flags();
|
|
|
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
|
|
|
}
|
|
|
|
FCVT.S.L { // 64bit signed int to to fp
|
|
|
|
encoding: b1101000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
|
|
|
args_disass:"f{rd}, x{rs1}";
|
|
|
|
val res[32] <= fdispatch_fcvt_64_32(X[rs1], zext(2, 32));
|
|
|
|
if(FLEN==32)
|
|
|
|
F[rd] <= res;
|
|
|
|
else { // NaN boxing
|
|
|
|
val upper[FLEN] <= -1;
|
|
|
|
F[rd] <= (upper<<32) | zext(res, FLEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FCVT.S.LU { // 64bit unsigned int to to fp
|
|
|
|
encoding: b1101000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
|
|
|
args_disass:"f{rd}, x{rs1}";
|
|
|
|
val res[32] <=fdispatch_fcvt_64_32(X[rs1], zext(3,32));
|
|
|
|
if(FLEN==32)
|
|
|
|
F[rd] <= res;
|
|
|
|
else { // NaN boxing
|
|
|
|
val upper[FLEN] <= -1;
|
|
|
|
F[rd] <= (upper<<32) | zext(res, FLEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|