inline float32_t f32(freg_t r) { return f32(unboxF32(r)); }
inline float64_t f64(freg_t r) { return f64(unboxF64(r)); }
inline float128_t f128(freg_t r) { return r; }
+inline freg_t freg(float16_t f) { return { ((uint64_t)-1 << 16) | f.v, (uint64_t)-1 }; }
inline freg_t freg(float32_t f) { return { ((uint64_t)-1 << 32) | f.v, (uint64_t)-1 }; }
inline freg_t freg(float64_t f) { return { f.v, (uint64_t)-1 }; }
inline freg_t freg(float128_t f) { return f; }
void (sv_proc_t::WRITE_FRD)(sv_float32_t value)
{
- fprintf(stderr, "WRITE_FRD sv_float32_t %lx\n",
- ((float32_t)value).v);
- sv_freg_t v = sv_freg_t(freg(value), xlen, value.get_elwidth());
- DO_WRITE_FREG( _insn->rd(), v);
+ reg_t reg = _insn->rd().reg;
+ uint8_t dest_elwidth = _insn->reg_elwidth(reg, false);
+ fprintf(stderr, "WRITE_FRD rd %ld ew %d sv_float32_t %x\n",
+ reg, dest_elwidth, ((float32_t)value).v);
+ freg_t v;
+ switch (dest_elwidth)
+ {
+ // 8-bit
+ case 1: throw trap_illegal_instruction(0); // XXX for now
+ // 16-bit data, up-convert to f32
+ case 2:
+ {
+ float16_t x16 = ::f32_to_f16((float32_t)value);
+ v = freg(x16);
+ break;
+ }
+ case 3:
+ {
+ v = freg(value);
+ //float32_t x32 = ::f128_to_f32((float32_t)value);
+ //v = ::f32_to_f128(x32);
+ break;
+ }
+ default:
+ {
+ v = freg(value);
+ break;
+ }
+ }
+ sv_freg_t vf = sv_freg_t(v, xlen, value.get_elwidth());
+ DO_WRITE_FREG( _insn->rd(), vf);
}
void (sv_proc_t::WRITE_FRD)(sv_float64_t value)
if (spec.offset) {
reg += *spec.offset;
}
- sv_freg_t v(value);
- switch (dest_elwidth)
- {
- // 8-bit
- case 1: throw trap_illegal_instruction(0); // XXX for now
- // 16-bit data, up-convert to f32
- case 2:
- {
- float16_t x16 = ::f128_to_f16((freg_t)value);
- v = sv_freg_t(::f16_to_f128(x16));
- break;
- }
- case 3:
- {
- float32_t x32 = ::f128_to_f32((freg_t)value);
- v = sv_freg_t(::f32_to_f128(x32));
- break;
- }
- default:
- {
- v = value;
- break;
- }
- }
- STATE.FPR.write(reg, v);
+ fprintf(stderr, "DO_WRITE_FRD rd %ld ew %d data %lx %lx\n",
+ reg, dest_elwidth, ((freg_t)value).v[0], ((freg_t)value).v[1]);
+ STATE.FPR.write(reg, value);
dirty_fp_state;
}
if (spec.offset) {
reg += *spec.offset;
}
- return _insn->p->get_state()->FPR[reg]; // XXX TODO: offset
+ freg_t value = _insn->p->get_state()->FPR[reg];
+ fprintf(stderr, "READ_FREG rd %ld ew %d data %lx %lx\n",
+ reg, elwidth, ((freg_t)value).v[0], ((freg_t)value).v[1]);
+ return value;
}
reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,