diff mbox series

[1/3] target/riscv: add NaN-Boxing helper for half-float

Message ID 1597136381-17296-2-git-send-email-chihmin.chao@sifive.com (mailing list archive)
State New, archived
Headers show
Series RFC: target/riscv: add half-precision floating-point extension | expand

Commit Message

Chih-Min Chao Aug. 11, 2020, 8:59 a.m. UTC
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.chao@sifive.com>
---
 target/riscv/internals.h | 16 ++++++++++++++++
 target/riscv/translate.c | 15 +++++++++++++++
 2 files changed, 31 insertions(+)
diff mbox series

Patch

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);