When writing, box the 16bit value with all ones in high part[63:16] When reading, unbox the 16bit value from 64bit storage and validate it
Signed-off-by: Chih-Min Chao <chihmin.c...@sifive.com> --- target/riscv/internals.h | 16 ++++++++++++++++ target/riscv/translate.c | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/target/riscv/internals.h b/target/riscv/internals.h index f1a546d..522c306 100644 --- a/target/riscv/internals.h +++ b/target/riscv/internals.h @@ -54,4 +54,20 @@ static inline float32 check_nanbox_s(uint64_t f) } } +static inline uint64_t nanbox_h(float16 f) +{ + return f | MAKE_64BIT_MASK(16, 48); +} + +static inline float16 check_nanbox_h(uint64_t f) +{ + uint64_t mask = MAKE_64BIT_MASK(16, 48); + + if (likely((f & mask) == mask)) { + return (uint16_t)f; + } else { + return 0x7E00u; /* default qnan */ + } +} + #endif diff --git a/target/riscv/translate.c b/target/riscv/translate.c index bf35182..e227534 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -119,6 +119,21 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in) tcg_temp_free_i64(t_nan); } +static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in) +{ + tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48)); +} + +static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in) +{ + TCGv_i64 t_max = tcg_const_i64(0xffffffffffff0000ull); + TCGv_i64 t_nan = tcg_const_i64(0xffffffffffff7e00ull); + + tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan); + tcg_temp_free_i64(t_max); + tcg_temp_free_i64(t_nan); +} + static void generate_exception(DisasContext *ctx, int excp) { tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); -- 2.7.4