#define fsgnj64(a, b, n, x) \
f64((((float64_t)f64(a)).v & ~F64_SIGN) | ((((x) ? ((float64_t)f64(a)).v : (n) ? F64_SIGN : 0) ^ ((float64_t)f64(b)).v) & F64_SIGN))
-#define isNaNF128(x) isNaNF128UI(x.v[1], x.v[0])
+#define isNaNF128(x) isNaNF128UI(((float128_t)x).v[1], ((float128_t)x).v[0])
inline float128_t defaultNaNF128()
{
float128_t nan;
require_extension('Q');
require_fp;
bool greater = f128_lt_quiet(f128(FRS2), f128(FRS1)) ||
- (f128_eq(f128(FRS2), f128(FRS1)) && (f128(FRS2).v[1] & F64_SIGN));
+ (f128_eq(f128(FRS2), f128(FRS1)) && (((float128_t)f128(FRS2)).v[1] & F64_SIGN));
if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2)))
WRITE_FRD(f128(defaultNaNF128()));
else
require_extension('Q');
require_fp;
bool less = f128_lt_quiet(f128(FRS1), f128(FRS2)) ||
- (f128_eq(f128(FRS1), f128(FRS2)) && (f128(FRS1).v[1] & F64_SIGN));
+ (f128_eq(f128(FRS1), f128(FRS2)) && (((float128_t)f128(FRS1)).v[1] & F64_SIGN));
if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2)))
WRITE_FRD(f128(defaultNaNF128()));
else
DO_WRITE_FREG( _insn->rd(), freg(value) );
}
+void (sv_proc_t::WRITE_FRD)(sv_float128_t value)
+{
+ fprintf(stderr, "WRITE_FRD sv_float128_t %g\n",
+ (double)((float128_t)value).v[0]);
+ DO_WRITE_FREG( _insn->rd(), freg(((float128_t)value)) );
+}
+
void (sv_proc_t::WRITE_FRD)(sv_freg_t value)
{
fprintf(stderr, "WRITE_FRD fsv_reg_t %lx\n", ((freg_t)value).v[0]);
return ::f128_lt_quiet(a, b);
}
+sv_freg_t sv_proc_t::fsgnj128(sv_freg_t a, sv_freg_t b, bool n, bool x)
+{
+ return sv_freg_t(::fsgnj128(a, b, n, x), a.get_xlen(), a.get_elwidth());
+}
+
+sv_float128_t sv_proc_t::f32_to_f128( sv_float32_t a)
+{
+ return ::f32_to_f128(a);
+}
+
+sv_float128_t sv_proc_t::f128( float128_t a)
+{
+ return ::f128(a);
+}
+
+sv_float128_t sv_proc_t::f64_to_f128( sv_float64_t a)
+{
+ return ::f64_to_f128(a);
+}
+
//typedef sreg_t sv_sreg_t;
//typedef float32_t sv_float32_t;
//typedef float64_t sv_float64_t;
-typedef float128_t sv_float128_t;
+//typedef float128_t sv_float128_t;
//typedef freg_t sv_freg_t;
class sv_proc_t
void (WRITE_REG)(reg_spec_t const®, sv_reg_t const& value);
//void (WRITE_REG)(reg_t reg, sv_sreg_t value);
void (WRITE_FRD)(sv_freg_t value);
+ void (WRITE_FRD)(sv_float128_t value);
void (WRITE_FRD)(sv_float64_t value);
void (WRITE_FRD)(sv_float32_t value);
reg_t (READ_REG)(reg_spec_t const& i);
sv_reg_t sv_reg_uint32(sv_reg_t const&);
sv_reg_t sv_reg_int32(sv_reg_t const&);
+ sv_float128_t (f128)(float128_t v);
sv_float64_t (f64)(sv_freg_t v);
sv_float64_t (f64)(sv_reg_t const&v);
sv_float32_t (f32)(sv_reg_t const&v);
sv_reg_t (mulhu)(sv_reg_t const& a, sv_reg_t const& b);
sv_sreg_t (mulh)(sv_sreg_t const& a, sv_sreg_t const& b);
+ sv_float128_t f64_to_f128( sv_float64_t );
sv_float64_t f64_add( sv_float64_t, sv_float64_t );
sv_float64_t f64_sub( sv_float64_t, sv_float64_t );
sv_float64_t f64_mul( sv_float64_t, sv_float64_t );
bool f64_le_quiet( sv_float64_t, sv_float64_t );
bool f64_lt_quiet( sv_float64_t, sv_float64_t );
+ sv_float128_t f32_to_f128( sv_float32_t );
sv_float32_t f32_add( sv_float32_t, sv_float32_t );
sv_float32_t f32_sub( sv_float32_t, sv_float32_t );
sv_float32_t f32_mul( sv_float32_t, sv_float32_t );
bool f128_le_quiet( sv_float128_t, sv_float128_t );
bool f128_lt_quiet( sv_float128_t, sv_float128_t );
+ sv_freg_t fsgnj128(sv_freg_t a, sv_freg_t b, bool n, bool x);
+
#include "sv_insn_decl.h"
};
mmu_t::store_float128(addr, val);
}
- float128_t load_float128(sv_reg_t const& addr)
+ sv_float128_t load_float128(sv_reg_t const& addr)
{
return mmu_t::load_float128(addr);
}
operator float64_t() const& { return reg; }
};
+class sv_float128_t : public sv_regbase_t {
+public:
+ sv_float128_t(float128_t _reg) : sv_regbase_t(), reg(_reg) { } // default elwidth
+ sv_float128_t(float128_t _reg, uint8_t _elwidth) :
+ sv_regbase_t(_elwidth), reg(_reg)
+ {}
+ sv_float128_t(float128_t _reg, int xlen, uint8_t _elwidth) :
+ sv_regbase_t(xlen, _elwidth), reg(_reg)
+ {}
+
+ float128_t reg;
+public:
+
+ operator float128_t() const& { return reg; }
+};
+
#endif