diff --git a/sim/common/rvfloats.cpp b/sim/common/rvfloats.cpp index 677e7605..fe455045 100644 --- a/sim/common/rvfloats.cpp +++ b/sim/common/rvfloats.cpp @@ -8,11 +8,19 @@ extern "C" { } #define F32_SIGN 0x80000000 +// simx64 +#define F64_SIGN 0x8000000000000000 inline float32_t to_float32_t(uint32_t x) { return float32_t{x}; } +// simx64 +inline float64_t to_float64_t(uint64_t x) { return float64_t{x}; } + inline uint32_t from_float32_t(float32_t x) { return uint32_t(x.v); } +// simx64 +inline uint64_t from_float64_t(float64_t x) { return uint64_t(x.v); } + inline uint32_t get_fflags() { uint32_t fflags = softfloat_exceptionFlags; if (fflags) { @@ -25,35 +33,67 @@ inline uint32_t get_fflags() { extern "C" { #endif -uint32_t rv_fadd(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { +uint64_t rv_fadd(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_add(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_fsub(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fadd_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_add(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fsub(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_sub(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_fmul(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fsub_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_sub(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fmul(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_mul(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_fmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fmul_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_mul(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_mulAdd(to_float32_t(a), to_float32_t(b), to_float32_t(c)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_fmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fmadd_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_mulAdd(to_float64_t(a), to_float64_t(b), to_float64_t(c)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; int c_neg = c ^ F32_SIGN; auto r = f32_mulAdd(to_float32_t(a), to_float32_t(b), to_float32_t(c_neg)); @@ -61,7 +101,16 @@ uint32_t rv_fmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* ff return from_float32_t(r); } -uint32_t rv_fnmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fmsub_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + long c_neg = c ^ F64_SIGN; + auto r = f64_mulAdd(to_float64_t(a), to_float64_t(b), to_float64_t(c_neg)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fnmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; int a_neg = a ^ F32_SIGN; int c_neg = c ^ F32_SIGN; @@ -70,7 +119,17 @@ uint32_t rv_fnmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* f return from_float32_t(r); } -uint32_t rv_fnmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fnmadd_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + long a_neg = a ^ F64_SIGN; + long c_neg = c ^ F64_SIGN; + auto r = f64_mulAdd(to_float64_t(a_neg), to_float64_t(b), to_float64_t(c_neg)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fnmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; int a_neg = a ^ F32_SIGN; auto r = f32_mulAdd(to_float32_t(a_neg), to_float32_t(b), to_float32_t(c)); @@ -78,34 +137,76 @@ uint32_t rv_fnmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* f return from_float32_t(r); } -uint32_t rv_fdiv(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fnmsub_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + long a_neg = a ^ F64_SIGN; + auto r = f64_mulAdd(to_float64_t(a_neg), to_float64_t(b), to_float64_t(c)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fdiv(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_div(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_fdiv_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_div(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_sqrt(to_float32_t(a)); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags) { +// simx64x +uint64_t rv_fsqrt_d(uint64_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_sqrt(to_float64_t(a)); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + + +uint64_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_to_i32(to_float32_t(a), frm, true); if (fflags) { *fflags = get_fflags(); } return r; } -uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_ftoi_d(uint64_t a, uint64_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_to_i32(to_float64_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_to_ui32(to_float32_t(a), frm, true); if (fflags) { *fflags = get_fflags(); } return r; } +// simx64 +uint64_t rv_ftou_d(uint64_t a, uint64_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_to_ui32(to_float64_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + // simx64 uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; @@ -114,6 +215,15 @@ uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags) { return r; } +// simx64 +uint64_t rv_ftol_d(uint64_t a, uint64_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_to_i64(to_float64_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +// simx64 uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = f32_to_ui64(to_float32_t(a), frm, true); @@ -121,14 +231,30 @@ uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags) { return r; } -uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_ftolu_d(uint64_t a, uint64_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = f64_to_ui64(to_float64_t(a), frm, true); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = i32_to_f32(a); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_itof_d(uint32_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = i32_to_f64(a); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = ui32_to_f32(a); if (fflags) { *fflags = get_fflags(); } @@ -136,40 +262,86 @@ uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags) { } // simx64 -uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags) { +uint64_t rv_utof_d(uint32_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = ui32_to_f64(a); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +// simx64 +uint64_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = i64_to_f32(a); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags) { +// simx64 +uint64_t rv_ltof_d(uint64_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = i64_to_f64(a); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +// simx64 +uint64_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags) { softfloat_roundingMode = frm; auto r = ui64_to_f32(a); if (fflags) { *fflags = get_fflags(); } return from_float32_t(r); } -uint32_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags) { +// simx64 +uint64_t rv_lutof_d(uint64_t a, uint32_t frm, uint32_t* fflags) { + softfloat_roundingMode = frm; + auto r = ui64_to_f64(a); + if (fflags) { *fflags = get_fflags(); } + return from_float64_t(r); +} + +uint64_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags) { auto r = f32_lt(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return r; } -uint32_t rv_fle(uint32_t a, uint32_t b, uint32_t* fflags) { +// simx64 +uint64_t rv_flt_d(uint64_t a, uint64_t b, uint32_t* fflags) { + auto r = f64_lt(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_fle(uint32_t a, uint32_t b, uint32_t* fflags) { auto r = f32_le(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return r; } -uint32_t rv_feq(uint32_t a, uint32_t b, uint32_t* fflags) { +// simx64 +uint64_t rv_fle_d(uint64_t a, uint64_t b, uint32_t* fflags) { + auto r = f64_le(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_feq(uint32_t a, uint32_t b, uint32_t* fflags) { auto r = f32_eq(to_float32_t(a), to_float32_t(b)); if (fflags) { *fflags = get_fflags(); } return r; } -uint32_t rv_fmin(uint32_t a, uint32_t b, uint32_t* fflags) { - int r; +// simx64 +uint64_t rv_feq_d(uint64_t a, uint64_t b, uint32_t* fflags) { + auto r = f64_eq(to_float64_t(a), to_float64_t(b)); + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_fmin(uint32_t a, uint32_t b, uint32_t* fflags) { + long r; if (isNaNF32UI(a) && isNaNF32UI(b)) { r = defaultNaNF32UI; } else { @@ -186,8 +358,27 @@ uint32_t rv_fmin(uint32_t a, uint32_t b, uint32_t* fflags) { return r; } -uint32_t rv_fmax(uint32_t a, uint32_t b, uint32_t* fflags) { - int r; +// simx64 +uint64_t rv_fmin_d(uint64_t a, uint64_t b, uint32_t* fflags) { + long r; + if (isNaNF64UI(a) && isNaNF64UI(b)) { + r = defaultNaNF64UI; + } else { + auto fa = to_float64_t(a); + auto fb = to_float64_t(b); + if ((f64_lt_quiet(fa, fb) || (f64_eq(fa, fb) && (a & F64_SIGN))) + || isNaNF64UI(b)) { + r = a; + } else { + r = b; + } + } + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_fmax(uint32_t a, uint32_t b, uint32_t* fflags) { + long r; if (isNaNF32UI(a) && isNaNF32UI(b)) { r = defaultNaNF32UI; } else { @@ -204,7 +395,26 @@ uint32_t rv_fmax(uint32_t a, uint32_t b, uint32_t* fflags) { return r; } -uint32_t rv_fclss(uint32_t a) { +// simx64 +uint64_t rv_fmax_d(uint64_t a, uint64_t b, uint32_t* fflags) { + long r; + if (isNaNF64UI(a) && isNaNF64UI(b)) { + r = defaultNaNF64UI; + } else { + auto fa = to_float64_t(a); + auto fb = to_float64_t(b); + if ((f64_lt_quiet(fb, fa) || (f64_eq(fb, fa) && (b & F64_SIGN))) + || isNaNF64UI(b)) { + r = a; + } else { + r = b; + } + } + if (fflags) { *fflags = get_fflags(); } + return r; +} + +uint64_t rv_fclss(uint32_t a) { auto infOrNaN = (0xff == expF32UI(a)); auto subnormOrZero = (0 == expF32UI(a)); bool sign = signF32UI(a); @@ -227,7 +437,31 @@ uint32_t rv_fclss(uint32_t a) { return r; } -uint32_t rv_fsgnj(uint32_t a, uint32_t b) { +// simx64 +uint64_t rv_fclss_d(uint64_t a) { + auto infOrNaN = (0x7ff == expF64UI(a)); + auto subnormOrZero = (0 == expF64UI(a)); + bool sign = signF64UI(a); + bool fracZero = (0 == fracF64UI(a)); + bool isNaN = isNaNF64UI(a); + bool isSNaN = softfloat_isSigNaNF64UI(a); + + int r = + ( sign && infOrNaN && fracZero ) << 0 | + ( sign && !infOrNaN && !subnormOrZero ) << 1 | + ( sign && subnormOrZero && !fracZero ) << 2 | + ( sign && subnormOrZero && fracZero ) << 3 | + ( !sign && infOrNaN && fracZero ) << 7 | + ( !sign && !infOrNaN && !subnormOrZero ) << 6 | + ( !sign && subnormOrZero && !fracZero ) << 5 | + ( !sign && subnormOrZero && fracZero ) << 4 | + ( isNaN && isSNaN ) << 8 | + ( isNaN && !isSNaN ) << 9; + + return r; +} + +uint64_t rv_fsgnj(uint32_t a, uint32_t b) { int sign = b & F32_SIGN; int r = sign | (a & ~F32_SIGN); @@ -235,7 +469,16 @@ uint32_t rv_fsgnj(uint32_t a, uint32_t b) { return r; } -uint32_t rv_fsgnjn(uint32_t a, uint32_t b) { +// simx64 +uint64_t rv_fsgnj_d(uint64_t a, uint64_t b) { + + long sign = b & F64_SIGN; + long r = sign | (a & ~F64_SIGN); + + return r; +} + +uint64_t rv_fsgnjn(uint32_t a, uint32_t b) { int sign = ~b & F32_SIGN; int r = sign | (a & ~F32_SIGN); @@ -243,7 +486,16 @@ uint32_t rv_fsgnjn(uint32_t a, uint32_t b) { return r; } -uint32_t rv_fsgnjx(uint32_t a, uint32_t b) { +// simx64 +uint64_t rv_fsgnjn_d(uint64_t a, uint64_t b) { + + long sign = ~b & F64_SIGN; + long r = sign | (a & ~F64_SIGN); + + return r; +} + +uint64_t rv_fsgnjx(uint32_t a, uint32_t b) { int sign1 = a & F32_SIGN; int sign2 = b & F32_SIGN; @@ -252,6 +504,30 @@ uint32_t rv_fsgnjx(uint32_t a, uint32_t b) { return r; } +// simx64 +uint64_t rv_fsgnjx_d(uint64_t a, uint64_t b) { + + long sign1 = a & F64_SIGN; + long sign2 = b & F64_SIGN; + long r = (sign1 ^ sign2) | (a & ~F64_SIGN); + + return r; +} + +// simx64 +uint64_t rv_dtof(uint64_t a) { + + auto r = f64_to_f32(to_float64_t(a)); + return from_float32_t(r); +} + +// simx64 +uint64_t rv_ftod(uint32_t a) { + + auto r = f32_to_f64(to_float32_t(a)); + return from_float64_t(r); +} + #ifdef __cplusplus } #endif diff --git a/sim/common/rvfloats.h b/sim/common/rvfloats.h index 69609a44..2e36e16a 100644 --- a/sim/common/rvfloats.h +++ b/sim/common/rvfloats.h @@ -7,38 +7,76 @@ extern "C" { #endif -uint32_t rv_fadd(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); -uint32_t rv_fsub(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); -uint32_t rv_fmul(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); -uint32_t rv_fmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); -uint32_t rv_fmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); -uint32_t rv_fnmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); -uint32_t rv_fnmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fadd(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fsub(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fmul(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fnmadd(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fnmsub(uint32_t a, uint32_t b, uint32_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fdiv(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_fdiv(uint32_t a, uint32_t b, uint32_t frm, uint32_t* fflags); -uint32_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags); - -uint32_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags); // simx64 uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags); -uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags); // simx64 -uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags); +// simx64 +uint64_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags); +// simx64 +uint64_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags); -uint32_t rv_fclss(uint32_t a); -uint32_t rv_fsgnj(uint32_t a, uint32_t b); -uint32_t rv_fsgnjn(uint32_t a, uint32_t b); -uint32_t rv_fsgnjx(uint32_t a, uint32_t b); +uint64_t rv_fclss(uint32_t a); +uint64_t rv_fsgnj(uint32_t a, uint32_t b); +uint64_t rv_fsgnjn(uint32_t a, uint32_t b); +uint64_t rv_fsgnjx(uint32_t a, uint32_t b); -uint32_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags); -uint32_t rv_fle(uint32_t a, uint32_t b, uint32_t* fflags); -uint32_t rv_feq(uint32_t a, uint32_t b, uint32_t* fflags); -uint32_t rv_fmin(uint32_t a, uint32_t b, uint32_t* fflags); -uint32_t rv_fmax(uint32_t a, uint32_t b, uint32_t* fflags); +uint64_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags); +uint64_t rv_fle(uint32_t a, uint32_t b, uint32_t* fflags); +uint64_t rv_feq(uint32_t a, uint32_t b, uint32_t* fflags); +uint64_t rv_fmin(uint32_t a, uint32_t b, uint32_t* fflags); +uint64_t rv_fmax(uint32_t a, uint32_t b, uint32_t* fflags); + + + +// simx64 +uint64_t rv_fadd_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fsub_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fmul_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fdiv_d(uint64_t a, uint64_t b, uint32_t frm, uint32_t* fflags); +uint64_t rv_fsqrt_d(uint64_t a, uint32_t frm, uint32_t* fflags); + +uint64_t rv_fmadd_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fmsub_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fnmadd_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags); +uint64_t rv_fnmsub_d(uint64_t a, uint64_t b, uint64_t c, uint32_t frm, uint32_t* fflags); + +uint64_t rv_ftoi_d(uint64_t a, uint64_t frm, uint32_t* fflags); +uint64_t rv_ftou_d(uint64_t a, uint64_t frm, uint32_t* fflags); +uint64_t rv_ftol_d(uint64_t a, uint64_t frm, uint32_t* fflags); +uint64_t rv_ftolu_d(uint64_t a, uint64_t frm, uint32_t* fflags); +uint64_t rv_itof_d(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_utof_d(uint32_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_ltof_d(uint64_t a, uint32_t frm, uint32_t* fflags); +uint64_t rv_lutof_d(uint64_t a, uint32_t frm, uint32_t* fflags); + +uint64_t rv_fclss_d(uint64_t a); +uint64_t rv_fsgnj_d(uint64_t a, uint64_t b); +uint64_t rv_fsgnjn_d(uint64_t a, uint64_t b); +uint64_t rv_fsgnjx_d(uint64_t a, uint64_t b); + +uint64_t rv_flt_d(uint64_t a, uint64_t b, uint32_t* fflags); +uint64_t rv_fle_d(uint64_t a, uint64_t b, uint32_t* fflags); +uint64_t rv_feq_d(uint64_t a, uint64_t b, uint32_t* fflags); +uint64_t rv_fmin_d(uint64_t a, uint64_t b, uint32_t* fflags); +uint64_t rv_fmax_d(uint64_t a, uint64_t b, uint32_t* fflags); + +uint64_t rv_dtof(uint64_t a); +uint64_t rv_ftod(uint32_t a); #ifdef __cplusplus } diff --git a/sim/simX/Makefile b/sim/simX/Makefile index 29b53fc3..0feba083 100644 --- a/sim/simX/Makefile +++ b/sim/simX/Makefile @@ -1,6 +1,6 @@ RTL_DIR = ../hw/rtl -CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors +CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors -Werror -g CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I. -I../common -I../../hw CXXFLAGS += -I../common/softfloat/source/include diff --git a/sim/simX/decode.cpp b/sim/simX/decode.cpp index 4c755070..854f0935 100644 --- a/sim/simX/decode.cpp +++ b/sim/simX/decode.cpp @@ -46,6 +46,8 @@ static const std::unordered_map sc_instTable = { }; static const char* op_string(const Instr &instr) { + // simx64 + Word func2 = instr.getFunc2(); Word func3 = instr.getFunc3(); Word func7 = instr.getFunc7(); Word rs2 = instr.getRSrc(1); @@ -169,35 +171,80 @@ static const char* op_string(const Instr &instr) { std::abort(); } case Opcode::FENCE: return "FENCE"; - case Opcode::FL: return (func3 == 0x2) ? "FL" : "VL"; - case Opcode::FS: return (func3 == 0x2) ? "FS" : "VS"; + // simx64 + case Opcode::FL: + switch (func3) { + case 0x1: return "VL"; + case 0x2: return "FLW"; + case 0x3: return "FLD"; + default: + std::abort(); + } + case Opcode::FS: + switch (func3) { + case 0x1: return "VS"; + case 0x2: return "FSW"; + case 0x3: return "FSD"; + default: + std::abort(); + } case Opcode::FCI: switch (func7) { - case 0x00: return "FADD"; - case 0x04: return "FSUB"; - case 0x08: return "FMUL"; - case 0x0c: return "FDIV"; - case 0x2c: return "FSQRT"; + case 0x00: return "FADD.S"; + case 0x01: return "FADD.D"; + case 0x04: return "FSUB.S"; + case 0x05: return "FSUB.D"; + case 0x08: return "FMUL.S"; + case 0x09: return "FMUL.D"; + case 0x0c: return "FDIV.S"; + case 0x0d: return "FDIV.D"; + case 0x2c: return "FSQRT.S"; + case 0x2d: return "FSQRT.D"; case 0x10: switch (func3) { - case 0: return "FSGNJ"; - case 1: return "FSGNJN"; - case 2: return "FSGNJX"; + case 0: return "FSGNJ.S"; + case 1: return "FSGNJN.S"; + case 2: return "FSGNJX.S"; + default: + std::abort(); + } + case 0x11: + switch (func3) { + case 0: return "FSGNJ.D"; + case 1: return "FSGNJN.D"; + case 2: return "FSGNJX.D"; default: std::abort(); } case 0x14: switch (func3) { - case 0: return "FMIM"; - case 1: return "FMAX"; + case 0: return "FMIN.S"; + case 1: return "FMAX.S"; default: std::abort(); } + case 0x15: + switch (func3) { + case 0: return "FMIN.D"; + case 1: return "FMAX.D"; + default: + std::abort(); + } + case 0x20: return "FCVT.S.D"; + case 0x21: return "FCVT.D.S"; case 0x50: switch (func3) { - case 0: return "FLE"; - case 1: return "FLT"; - case 2: return "FEQ"; + case 0: return "FLE.S"; + case 1: return "FLT.S"; + case 2: return "FEQ.S"; + default: + std::abort(); + } + case 0x51: + switch (func3) { + case 0: return "FLE.D"; + case 1: return "FLT.D"; + case 2: return "FEQ.D"; default: std::abort(); } @@ -211,6 +258,15 @@ static const char* op_string(const Instr &instr) { default: std::abort(); } + case 0x61: + switch (rs2) { + case 0: return "FCVT.W.D"; + case 1: return "FCVT.WU.D"; + case 2: return "FCVT.L.D"; + case 3: return "FCVT.LU.D"; + default: + std::abort(); + } case 0x68: switch (rs2) { case 0: return "FCVT.S.W"; @@ -220,15 +276,26 @@ static const char* op_string(const Instr &instr) { default: std::abort(); } - case 0x70: return func3 ? "FLASS" : "FMV.X.W"; + case 0x69: + switch (rs2) { + case 0: return "FCVT.D.W"; + case 1: return "FCVT.D.WU"; + case 2: return "FCVT.D.L"; + case 3: return "FCVT.D.LU"; + default: + std::abort(); + } + case 0x70: return func3 ? "FCLASS.S" : "FMV.X.W"; + case 0x71: return func3 ? "FCLASS.D" : "FMV.X.D"; case 0x78: return "FMV.W.X"; + case 0x79: return "FMV.D.X"; default: std::abort(); } - case Opcode::FMADD: return "FMADD"; - case Opcode::FMSUB: return "FMSUB"; - case Opcode::FMNMADD: return "FMNMADD"; - case Opcode::FMNMSUB: return "FMNMSUB"; + case Opcode::FMADD: return func2 ? "FMADD.D" : "FMADD.S"; + case Opcode::FMSUB: return func2 ? "FMSUB.D" : "FMSUB.S"; + case Opcode::FMNMADD: return func2 ? "FNMADD.D" : "FNMADD.S"; + case Opcode::FMNMSUB: return func2 ? "FNMSUB.D" : "FNMSUB.S"; case Opcode::VSET: return "VSET"; case Opcode::GPGPU: switch (func3) { @@ -324,7 +391,8 @@ Decoder::Decoder(const ArchDef &arch) { shift_vset_ = shift_func7_ + 6; reg_mask_ = 0x1f; - func2_mask_ = 0x2; + // simx64 + func2_mask_ = 0x3; func3_mask_ = 0x7; func6_mask_ = 0x3f; func7_mask_ = 0x7f; @@ -343,11 +411,12 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_); instr->setOpcode(op); + // simx64 + Word func2 = (code >> shift_func7_) & func2_mask_; Word func3 = (code >> shift_func3_) & func3_mask_; Word func6 = (code >> shift_func6_) & func6_mask_; Word func7 = (code >> shift_func7_) & func7_mask_; - // simx64 int rd = (code >> shift_rd_) & reg_mask_; int rs1 = (code >> shift_rs1_) & reg_mask_; int rs2 = (code >> shift_rs2_) & reg_mask_; @@ -361,7 +430,8 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { auto iType = op_it->second.iType; if (op == Opcode::FL || op == Opcode::FS) { - if (func3 != 0x2) { + // simx64 + if (func3 != 0x2 && func3 != 0x3) { iType = InstType::V_TYPE; } } @@ -373,8 +443,10 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { case InstType::R_TYPE: if (op == Opcode::FCI) { switch (func7) { - case 0x68: // FCVT.S.W, FCVT.S.WU + case 0x68: // FCVT.S.W, FCVT.S.WU, FCVT.S.L, FCVT.S.LU + case 0x69: // FCVT.D.W, FCVT.D.WU, FCVT.D.L, FCVT.D.LU case 0x78: // FMV.W.X + case 0x79: // FMV.D.X instr->setSrcReg(rs1); break; default: @@ -382,9 +454,12 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { } instr->setSrcFReg(rs2); switch (func7) { - case 0x50: // FLE, FLT, FEQ - case 0x60: // FCVT.WU.S, FCVT.W.S - case 0x70: // FLASS, FMV.X.W + case 0x50: // FLE.S, FLT.S, FEQ.S + case 0x51: // FLE.D, FLT.D, FEQ.D + case 0x60: // FCVT.WU.S, FCVT.W.S, FCVT.L.S, FCVT.LU.S + case 0x61: // FCVT.W.D, FCVT.WU.D, FCVT.L.D, FCVT.LU.D + case 0x70: // FLASS.S, FMV.X.W + case 0x71: // FCLASS.D, FMV.X.D instr->setDestReg(rd); break; default: @@ -512,6 +587,8 @@ std::shared_ptr Decoder::decode(Word code, Word PC) { instr->setSrcFReg(rs2); instr->setSrcFReg(rs3); instr->setFunc3(func3); + // simx64 + instr->setFunc2(func2); break; default: std::abort(); diff --git a/sim/simX/execute.cpp b/sim/simX/execute.cpp index 5a321c80..5852b3a2 100644 --- a/sim/simX/execute.cpp +++ b/sim/simX/execute.cpp @@ -59,6 +59,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { Word func3 = instr.getFunc3(); Word func6 = instr.getFunc6(); Word func7 = instr.getFunc7(); + Word func2 = instr.getFunc2(); auto opcode = instr.getOpcode(); int rdest = instr.getRDest(); @@ -346,8 +347,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rd_write = true; break; case L_INST: { - DoubleWord memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // DoubleWord aligned - DoubleWord shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8; + DoubleWord memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFF8); // DoubleWord aligned + DoubleWord shift_by = ((rsdata[0] + immsrc) & 0x00000007) * 8; DoubleWord data_read = core_->dcache_read(memAddr, 8); D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); switch (func3) { @@ -583,8 +584,13 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { DoubleWord memAddr = rsdata[0] + immsrc; DoubleWord data_read = core_->dcache_read(memAddr, 4); D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); - // simx64 rddata = data_read | 0xFFFFFFFF00000000; + } else if (func3 == 0x3) { + // RV32D: FLD + DoubleWord memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFF8); + DoubleWord data_read = core_->dcache_read(memAddr, 8); + D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read); + rddata = data_read; } else { D(3, "Executing vector load"); D(3, "lmul: " << vtype_.vlmul << " VLEN:" << (core_->arch().vsize() * 8) << "sew: " << vtype_.vsew); @@ -615,9 +621,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; case (FS | VS): if (func3 == 0x2) { + // RV32F: FSW DoubleWord memAddr = rsdata[0] + immsrc; core_->dcache_write(memAddr, rsdata[1], 4); D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); + } else if (func3 == 0x3){ + // RV32D: FSD + DoubleWord memAddr = rsdata[0] + immsrc; + core_->dcache_write(memAddr, rsdata[1], 8); + D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr); } else { for (int i = 0; i < vl_; i++) { DoubleWord memAddr = rsdata[0] + (i * vtype_.vsew / 8); @@ -639,31 +651,59 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { uint32_t frm = get_fpu_rm(func3, core_, t, id_); uint32_t fflags = 0; switch (func7) { - case 0x00: // RV32F: FADD + case 0x00: // RV32F: FADD.S rddata = rv_fadd(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x04: // RV32F: FSUB + case 0x01: // RV32D: FADD.D + rddata = rv_fadd_d(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x04: // RV32F: FSUB.S rddata = rv_fsub(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x08: // RV32F: FMUL + case 0x05: // RV32D: FSUB.D + rddata = rv_fsub_d(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x08: // RV32F: FMUL.S rddata = rv_fmul(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x0c: // RV32F: FDIV + case 0x09: // RV32D: FMUL.D + rddata = rv_fmul_d(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x0c: // RV32F: FDIV.S rddata = rv_fdiv(rsdata[0], rsdata[1], frm, &fflags); break; - case 0x2c: // RV32F: FSQRT + case 0x0d: // RV32D: FDIV.D + rddata = rv_fdiv_d(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x2c: // RV32F: FSQRT.S rddata = rv_fsqrt(rsdata[0], frm, &fflags); + break; + case 0x2d: // RV32D: FSQRT.D + rddata = rv_fsqrt_d(rsdata[0], frm, &fflags); break; case 0x10: switch (func3) { case 0: // RV32F: FSGNJ.S - rddata = rv_fsgnj(rsdata[0], rsdata[1]); + rddata = rv_fsgnj((Word)rsdata[0], (Word)rsdata[1]) | 0xFFFFFFFF00000000; break; case 1: // RV32F: FSGNJN.S - rddata = rv_fsgnjn(rsdata[0], rsdata[1]); + rddata = rv_fsgnjn((Word)rsdata[0], (Word)rsdata[1]) | 0xFFFFFFFF00000000; break; case 2: // RV32F: FSGNJX.S - rddata = rv_fsgnjx(rsdata[0], rsdata[1]); + rddata = rv_fsgnjx((Word)rsdata[0], (Word)rsdata[1]) | 0xFFFFFFFF00000000; + break; + } + break; + case 0x11: + switch (func3) { + case 0: // RV32D: FSGNJ.D + rddata = rv_fsgnj_d(rsdata[0], rsdata[1]); + break; + case 1: // RV32D: FSGNJN.D + rddata = rv_fsgnjn_d(rsdata[0], rsdata[1]); + break; + case 2: // RV32D: FSGNJX.D + rddata = rv_fsgnjx_d(rsdata[0], rsdata[1]); break; } break; @@ -676,6 +716,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rddata = rv_fmin(rsdata[0], rsdata[1], &fflags); } break; + case 0x15: + if (func3) { + // RV32D: FMAX.D + rddata = rv_fmax_d(rsdata[0], rsdata[1], &fflags); + } else { + // RV32D: FMIN.D + rddata = rv_fmin_d(rsdata[0], rsdata[1], &fflags); + } + break; + case 0x20: rddata = rv_dtof(rsdata[0]); + break; + case 0x21: rddata = rv_ftod(rsdata[0]); + break; case 0x60: switch(rsrc1) { case 0: @@ -696,6 +749,26 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; } break; + case 0x61: + switch(rsrc1) { + case 0: + // RV32D: FCVT.W.D + rddata = signExt(rv_ftoi_d(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF); + break; + case 1: + // RV32D: FCVT.WU.D + rddata = signExt(rv_ftou_d(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF); + break; + case 2: + // RV64D: FCVT.L.D + rddata = rv_ftol_d(rsdata[0], frm, &fflags); + break; + case 3: + // RV64D: FCVT.LU.D + rddata = rv_ftolu_d(rsdata[0], frm, &fflags); + break; + } + break; case 0x70: if (func3) { // RV32F: FCLASS.S @@ -705,6 +778,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { rddata = signExt((Word)rsdata[0], 32, 0xFFFFFFFF); } break; + case 0x71: + if (func3) { + // RV32D: FCLASS.D + rddata = rv_fclss_d(rsdata[0]); + } else { + // RV64D: FMV.X.D + rddata = rsdata[0]; + } + break; case 0x50: switch(func3) { case 0: @@ -719,7 +801,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { // RV32F: FEQ.S rddata = rv_feq(rsdata[0], rsdata[1], &fflags); break; - } break; + } break; + case 0x51: + switch(func3) { + case 0: + // RV32D: FLE.D + rddata = rv_fle_d(rsdata[0], rsdata[1], &fflags); + break; + case 1: + // RV32D: FLT.D + rddata = rv_flt_d(rsdata[0], rsdata[1], &fflags); + break; + case 2: + // RV32D: FEQ.D + rddata = rv_feq_d(rsdata[0], rsdata[1], &fflags); + break; + } break; case 0x68: switch(rsrc1) { case 0: @@ -740,10 +837,34 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { break; } break; + case 0x69: + switch(rsrc1) { + case 0: + // RV32D: FCVT.D.W + rddata = rv_itof_d(rsdata[0], frm, &fflags); + break; + case 1: + // RV32F: FCVT.D.WU + rddata = rv_utof_d(rsdata[0], frm, &fflags); + break; + case 2: + // RV64D: FCVT.D.L + rddata = rv_ltof_d(rsdata[0], frm, &fflags); + break; + case 3: + // RV64D: FCVT.D.LU + rddata = rv_lutof_d(rsdata[0], frm, &fflags); + break; + } + break; case 0x78: // RV32F: FMV.W.X rddata = rsdata[0]; break; + case 0x79: + // RV64D: FMV.D.X + rddata = rsdata[0]; + break; } update_fcrs(fflags, core_, t, id_); rd_write = true; @@ -757,20 +878,36 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { Word fflags = 0; switch (opcode) { case FMADD: - // RV32F: FMADD - rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + if (func2) + // RV32D: FMADD.D + rddata = rv_fmadd_d(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + else + // RV32F: FMADD.S + rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMSUB: - // RV32F: FMSUB - rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + if (func2) + // RV32D: FMSUB.D + rddata = rv_fmsub_d(rsdata[0],rsdata[1], rsdata[2], frm, &fflags); + else + // RV32F: FMSUB.S + rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMNMADD: - // RV32F: FNMADD - rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + if (func2) + // RV32D: FNMADD.D + rddata = rv_fnmadd_d(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + else + // RV32F: FNMADD.S + rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; case FMNMSUB: - // RV32F: FNMSUB - rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + if (func2) + // RV32D: FNMSUB.D + rddata = rv_fnmsub_d(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + else + // RV32F: FNMSUB.S + rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); break; default: break; diff --git a/sim/simX/instr.h b/sim/simX/instr.h index 824ce5b2..68c28ca6 100644 --- a/sim/simX/instr.h +++ b/sim/simX/instr.h @@ -73,6 +73,7 @@ public: void setSrcFReg(int srcReg) { rsrc_type_[num_rsrcs_] = 2; rsrc_[num_rsrcs_++] = srcReg; } void setDestVReg(int destReg) { rdest_type_ = 3; rdest_ = destReg; } void setSrcVReg(int srcReg) { rsrc_type_[num_rsrcs_] = 3; rsrc_[num_rsrcs_++] = srcReg; } + void setFunc2(Word func2) { func2_ = func2;} void setFunc3(Word func3) { func3_ = func3; } void setFunc7(Word func7) { func7_ = func7; } void setImm(DoubleWord imm) { has_imm_ = true; imm_ = imm; } @@ -88,6 +89,7 @@ public: /* Getters used by encoders. */ Opcode getOpcode() const { return opcode_; } + Word getFunc2() const { return func2_; } Word getFunc3() const { return func3_; } Word getFunc6() const { return func6_; } Word getFunc7() const { return func7_; } @@ -124,6 +126,7 @@ private: int rsrc_type_[MAX_REG_SOURCES]; int rsrc_[MAX_REG_SOURCES]; int rdest_; + Word func2_; Word func3_; Word func7_; diff --git a/tests/riscv/isa64/Makefile b/tests/riscv/isa64/Makefile index e72d7df5..136ea5e2 100644 --- a/tests/riscv/isa64/Makefile +++ b/tests/riscv/isa64/Makefile @@ -9,10 +9,16 @@ # TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS)) +ALL_TESTS := $(wildcard *.hex) + +EXCLUDED_TESTS := rv64ud-p-move.hex + I_TESTS := $(wildcard *ui-p-*.hex) M_TESTS := $(wildcard *um-p-*.hex) F_TESTS := $(wildcard *uf-p-*.hex) -TESTS := $(I_TESTS) $(M_TESTS) $(F_TESTS) +D_TESTS := $(filter-out $(EXCLUDED_TESTS), $(wildcard *ud-p-*.hex)) + +TESTS := $(I_TESTS) $(M_TESTS) $(F_TESTS) $(D_TESTS) all: @@ -20,10 +26,13 @@ run-simx-i: $(foreach test, $(I_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) run-simx-m: - $(foreach test, $(M_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) + $(foreach test, $(M_TESTS), ../../../sim/simX/simX -r -a rv64im -c 1 -i $(test) || exit;) run-simx-f: - $(foreach test, $(F_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;) + $(foreach test, $(F_TESTS), ../../../sim/simX/simX -r -a rv64imf -c 1 -i $(test) || exit;) + +run-simx-d: + $(foreach test, $(D_TESTS), ../../../sim/simX/simX -r -a rv64imfd -c 1 -i $(test) || exit;) run-simx: $(foreach test, $(TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;)