From 9f50b19534a2a534a5cc509516211656f84f2f08 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 13 Apr 2020 16:38:40 -0400 Subject: [PATCH] pan/bit: Add BI_CONVERT interpretation Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/bifrost/test/bi_interpret.c | 109 ++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/src/panfrost/bifrost/test/bi_interpret.c b/src/panfrost/bifrost/test/bi_interpret.c index f0068398df4..2f3295772d9 100644 --- a/src/panfrost/bifrost/test/bi_interpret.c +++ b/src/panfrost/bifrost/test/bi_interpret.c @@ -264,6 +264,82 @@ biti_special(float Q, enum bi_special_op op) } } +/* For BI_CONVERT. */ + +#define _AS_ROUNDMODE(mode) \ + ((mode == BIFROST_RTZ) ? FP_INT_TOWARDZERO : \ + (mode == BIFROST_RTE) ? FP_INT_TONEAREST : \ + (mode == BIFROST_RTN) ? FP_INT_DOWNWARD : \ + FP_INT_UPWARD) + +static float +bit_as_float32(nir_alu_type T, bit_t src, unsigned C) +{ + switch (T) { + case nir_type_int32: return src.i32; + case nir_type_uint32: return src.u32; + case nir_type_float16: return bf(src.u16[C]); + default: unreachable("Invalid"); + } +} + +static uint32_t +bit_as_uint32(nir_alu_type T, bit_t src, unsigned C, enum bifrost_roundmode rm) +{ + switch (T) { + case nir_type_float16: return bf(src.u16[C]); + case nir_type_float32: return ufromfpf(src.f32, _AS_ROUNDMODE(rm), 32); + default: unreachable("Invalid"); + } +} + +static int32_t +bit_as_int32(nir_alu_type T, bit_t src, unsigned C, enum bifrost_roundmode rm) +{ + switch (T) { + case nir_type_float16: return bf(src.u16[C]); + case nir_type_float32: return fromfpf(src.f32, _AS_ROUNDMODE(rm), 32); + default: unreachable("Invalid"); + } +} + +static uint16_t +bit_as_float16(nir_alu_type T, bit_t src, unsigned C) +{ + switch (T) { + case nir_type_int32: return bh(src.i32); + case nir_type_uint32: return bh(src.u32); + case nir_type_float32: return bh(src.f32); + case nir_type_int16: return bh(src.i16[C]); + case nir_type_uint16: return bh(src.u16[C]); + default: unreachable("Invalid"); + } +} + +static uint16_t +bit_as_uint16(nir_alu_type T, bit_t src, unsigned C, enum bifrost_roundmode rm) +{ + switch (T) { + case nir_type_int32: return src.i32; + case nir_type_uint32: return src.u32; + case nir_type_float16: return ufromfpf(bf(src.u16[C]), _AS_ROUNDMODE(rm), 16); + case nir_type_float32: return src.f32; + default: unreachable("Invalid"); + } +} + +static int16_t +bit_as_int16(nir_alu_type T, bit_t src, unsigned C, enum bifrost_roundmode rm) +{ + switch (T) { + case nir_type_int32: return src.i32; + case nir_type_uint32: return src.u32; + case nir_type_float16: return fromfpf(bf(src.u16[C]), _AS_ROUNDMODE(rm), 16); + case nir_type_float32: return src.f32; + default: unreachable("Invalid"); + } +} + void bit_step(struct bit_state *s, bi_instruction *ins, bool FMA) { @@ -300,9 +376,40 @@ bit_step(struct bit_state *s, bi_instruction *ins, bool FMA) case BI_BRANCH: case BI_CMP: case BI_BITWISE: - case BI_CONVERT: unreachable("Unsupported op"); + case BI_CONVERT: { + /* If it exists */ + unsigned comp = ins->swizzle[0][1]; + + if (ins->dest_type == nir_type_float32) + dest.f32 = bit_as_float32(ins->src_types[0], srcs[0], comp); + else if (ins->dest_type == nir_type_uint32) + dest.u32 = bit_as_uint32(ins->src_types[0], srcs[0], comp, ins->roundmode); + else if (ins->dest_type == nir_type_int32) + dest.i32 = bit_as_int32(ins->src_types[0], srcs[0], comp, ins->roundmode); + else if (ins->dest_type == nir_type_float16) { + dest.u16[0] = bit_as_float16(ins->src_types[0], srcs[0], ins->swizzle[0][0]); + + if (ins->src_types[0] == nir_type_float32) { + /* TODO: Second argument */ + dest.u16[1] = 0; + } else { + dest.u16[1] = bit_as_float16(ins->src_types[0], srcs[0], ins->swizzle[0][1]); + } + } else if (ins->dest_type == nir_type_uint16) { + dest.u16[0] = bit_as_uint16(ins->src_types[0], srcs[0], ins->swizzle[0][0], ins->roundmode); + dest.u16[1] = bit_as_uint16(ins->src_types[0], srcs[0], ins->swizzle[0][1], ins->roundmode); + } else if (ins->dest_type == nir_type_int16) { + dest.i16[0] = bit_as_int16(ins->src_types[0], srcs[0], ins->swizzle[0][0], ins->roundmode); + dest.i16[1] = bit_as_int16(ins->src_types[0], srcs[0], ins->swizzle[0][1], ins->roundmode); + } else { + unreachable("Unknown convert type"); + } + + break; + } + case BI_CSEL: { bool direct = ins->csel_cond == BI_COND_ALWAYS; bool cond = direct ? srcs[0].u32 : -- 2.30.2