Browse Source

bf16: handle invalid Nan-boxed accessing

assume
    0x0000_0000_0000_7d2d at 0x8000_0000
    a0 = 0x8000_0000

    fld ft0, 0(a0)           <-  load 0x0000_0000_0000_7d2d to ft0,
                                 it is invalid Nanboxed

    fcvt.s.bf16  ft1, ft0    <-  read bf16 from ft0.  it should be
                                 0x7fc0 (bf16 QNaN) but not 0x7e00 (f16 QNaN)

Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
pull/1446/head
Chih-Min Chao 3 years ago
parent
commit
eff6c60498
  1. 7
      riscv/decode_macros.h

7
riscv/decode_macros.h

@ -63,13 +63,14 @@
// FPU macros // FPU macros
#define READ_ZDINX_REG(reg) (xlen == 32 ? f64(READ_REG_PAIR(reg)) : f64(STATE.XPR[reg] & (uint64_t)-1)) #define READ_ZDINX_REG(reg) (xlen == 32 ? f64(READ_REG_PAIR(reg)) : f64(STATE.XPR[reg] & (uint64_t)-1))
#define READ_FREG_H(reg) (p->extension_enabled(EXT_ZFINX) ? f16(STATE.XPR[reg] & (uint16_t)-1) : f16(READ_FREG(reg))) #define READ_FREG_H(reg) (p->extension_enabled(EXT_ZFINX) ? f16(STATE.XPR[reg] & (uint16_t)-1) : f16(READ_FREG(reg)))
#define READ_FREG_BF(reg) (p->extension_enabled(EXT_ZFINX) ? bf16(STATE.XPR[reg] & (uint16_t)-1) : bf16(READ_FREG(reg)))
#define READ_FREG_F(reg) (p->extension_enabled(EXT_ZFINX) ? f32(STATE.XPR[reg] & (uint32_t)-1) : f32(READ_FREG(reg))) #define READ_FREG_F(reg) (p->extension_enabled(EXT_ZFINX) ? f32(STATE.XPR[reg] & (uint32_t)-1) : f32(READ_FREG(reg)))
#define READ_FREG_D(reg) (p->extension_enabled(EXT_ZFINX) ? READ_ZDINX_REG(reg) : f64(READ_FREG(reg))) #define READ_FREG_D(reg) (p->extension_enabled(EXT_ZFINX) ? READ_ZDINX_REG(reg) : f64(READ_FREG(reg)))
#define FRS1 READ_FREG(insn.rs1()) #define FRS1 READ_FREG(insn.rs1())
#define FRS2 READ_FREG(insn.rs2()) #define FRS2 READ_FREG(insn.rs2())
#define FRS3 READ_FREG(insn.rs3()) #define FRS3 READ_FREG(insn.rs3())
#define FRS1_H READ_FREG_H(insn.rs1()) #define FRS1_H READ_FREG_H(insn.rs1())
#define FRS1_BF FRS1_H #define FRS1_BF READ_FREG_BF(insn.rs1())
#define FRS1_F READ_FREG_F(insn.rs1()) #define FRS1_F READ_FREG_F(insn.rs1())
#define FRS1_D READ_FREG_D(insn.rs1()) #define FRS1_D READ_FREG_D(insn.rs1())
#define FRS2_H READ_FREG_H(insn.rs2()) #define FRS2_H READ_FREG_H(insn.rs2())
@ -224,14 +225,18 @@ class wait_for_interrupt_t {};
/* Convenience wrappers to simplify softfloat code sequences */ /* Convenience wrappers to simplify softfloat code sequences */
#define isBoxedF16(r) (isBoxedF32(r) && ((uint64_t)((r.v[0] >> 16) + 1) == ((uint64_t)1 << 48))) #define isBoxedF16(r) (isBoxedF32(r) && ((uint64_t)((r.v[0] >> 16) + 1) == ((uint64_t)1 << 48)))
#define unboxF16(r) (isBoxedF16(r) ? (uint16_t)r.v[0] : defaultNaNF16UI) #define unboxF16(r) (isBoxedF16(r) ? (uint16_t)r.v[0] : defaultNaNF16UI)
#define isBoxedBF16(r) isBoxedF16(r)
#define unboxBF16(r) (isBoxedBF16(r) ? (uint16_t)r.v[0] : defaultNaNBF16UI)
#define isBoxedF32(r) (isBoxedF64(r) && ((uint32_t)((r.v[0] >> 32) + 1) == 0)) #define isBoxedF32(r) (isBoxedF64(r) && ((uint32_t)((r.v[0] >> 32) + 1) == 0))
#define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v[0] : defaultNaNF32UI) #define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v[0] : defaultNaNF32UI)
#define isBoxedF64(r) ((r.v[1] + 1) == 0) #define isBoxedF64(r) ((r.v[1] + 1) == 0)
#define unboxF64(r) (isBoxedF64(r) ? r.v[0] : defaultNaNF64UI) #define unboxF64(r) (isBoxedF64(r) ? r.v[0] : defaultNaNF64UI)
inline float16_t f16(uint16_t v) { return { v }; } inline float16_t f16(uint16_t v) { return { v }; }
inline bfloat16_t bf16(uint16_t v) { return { v }; }
inline float32_t f32(uint32_t v) { return { v }; } inline float32_t f32(uint32_t v) { return { v }; }
inline float64_t f64(uint64_t v) { return { v }; } inline float64_t f64(uint64_t v) { return { v }; }
inline float16_t f16(freg_t r) { return f16(unboxF16(r)); } inline float16_t f16(freg_t r) { return f16(unboxF16(r)); }
inline bfloat16_t bf16(freg_t r) { return bf16(unboxBF16(r)); }
inline float32_t f32(freg_t r) { return f32(unboxF32(r)); } inline float32_t f32(freg_t r) { return f32(unboxF32(r)); }
inline float64_t f64(freg_t r) { return f64(unboxF64(r)); } inline float64_t f64(freg_t r) { return f64(unboxF64(r)); }
inline float128_t f128(freg_t r) { return r; } inline float128_t f128(freg_t r) { return r; }

Loading…
Cancel
Save