summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2019-06-20 10:36:10 -0500
committerJuan A. Suarez Romero <[email protected]>2019-07-15 10:09:44 +0000
commitafaec581a880a5e1c7ecaf7ba45f48d2be437792 (patch)
treee45a150d867b175cebd4d0d9a5b27a2f4d12b764
parentf5e70045e1ad7ff6c2cdd9a8eff682fcdd166067 (diff)
nir: Add more helpers for working with const values
Reviewed-by: Timothy Arceri <[email protected]> (cherry picked from commit ce5581e23e54be91e4c1ad6a6c5990eca6677ceb)
-rw-r--r--src/compiler/nir/nir.c35
-rw-r--r--src/compiler/nir/nir.h100
2 files changed, 135 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 5b75585498e..5c1e0e8a3b3 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -1204,6 +1204,41 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
return nir_foreach_dest(instr, visit_dest_indirect, &dest_state);
}
+nir_const_value
+nir_const_value_for_float(double f, unsigned bit_size)
+{
+ nir_const_value v;
+ memset(&v, 0, sizeof(v));
+
+ switch (bit_size) {
+ case 16:
+ v.u16 = _mesa_float_to_half(f);
+ break;
+ case 32:
+ v.f32 = f;
+ break;
+ case 64:
+ v.f64 = f;
+ break;
+ default:
+ unreachable("Invalid bit size");
+ }
+
+ return v;
+}
+
+double
+nir_const_value_as_float(nir_const_value value, unsigned bit_size)
+{
+ switch (bit_size) {
+ case 16: return _mesa_half_to_float(value.u16);
+ case 32: return value.f32;
+ case 64: return value.f64;
+ default:
+ unreachable("Invalid bit size");
+ }
+}
+
int64_t
nir_src_comp_as_int(nir_src src, unsigned comp)
{
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 980272048da..c53979a2e42 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -140,6 +140,106 @@ typedef union {
arr[i] = c[i].m; \
} while (false)
+static inline nir_const_value
+nir_const_value_for_raw_uint(uint64_t x, unsigned bit_size)
+{
+ nir_const_value v;
+ memset(&v, 0, sizeof(v));
+
+ switch (bit_size) {
+ case 1: v.b = x; break;
+ case 8: v.u8 = x; break;
+ case 16: v.u16 = x; break;
+ case 32: v.u32 = x; break;
+ case 64: v.u64 = x; break;
+ default:
+ unreachable("Invalid bit size");
+ }
+
+ return v;
+}
+
+static inline nir_const_value
+nir_const_value_for_int(int64_t i, unsigned bit_size)
+{
+ nir_const_value v;
+ memset(&v, 0, sizeof(v));
+
+ assert(bit_size <= 64);
+ if (bit_size < 64) {
+ assert(i >= (-(1ll << (bit_size - 1))));
+ assert(i < (1ll << (bit_size - 1)));
+ }
+
+ return nir_const_value_for_raw_uint(i, bit_size);
+}
+
+static inline nir_const_value
+nir_const_value_for_uint(uint64_t u, unsigned bit_size)
+{
+ nir_const_value v;
+ memset(&v, 0, sizeof(v));
+
+ assert(bit_size <= 64);
+ if (bit_size < 64)
+ assert(u < (1ull << bit_size));
+
+ return nir_const_value_for_raw_uint(u, bit_size);
+}
+
+static inline nir_const_value
+nir_const_value_for_bool(bool b, unsigned bit_size)
+{
+ /* Booleans use a 0/-1 convention */
+ return nir_const_value_for_int(-(int)b, bit_size);
+}
+
+/* This one isn't inline because it requires half-float conversion */
+nir_const_value nir_const_value_for_float(double b, unsigned bit_size);
+
+static inline int64_t
+nir_const_value_as_int(nir_const_value value, unsigned bit_size)
+{
+ switch (bit_size) {
+ /* int1_t uses 0/-1 convention */
+ case 1: return -(int)value.b;
+ case 8: return value.i8;
+ case 16: return value.i16;
+ case 32: return value.i32;
+ case 64: return value.i64;
+ default:
+ unreachable("Invalid bit size");
+ }
+}
+
+static inline int64_t
+nir_const_value_as_uint(nir_const_value value, unsigned bit_size)
+{
+ switch (bit_size) {
+ case 1: return value.b;
+ case 8: return value.u8;
+ case 16: return value.u16;
+ case 32: return value.u32;
+ case 64: return value.u64;
+ default:
+ unreachable("Invalid bit size");
+ }
+}
+
+static inline bool
+nir_const_value_as_bool(nir_const_value value, unsigned bit_size)
+{
+ int64_t i = nir_const_value_as_int(value, bit_size);
+
+ /* Booleans of any size use 0/-1 convention */
+ assert(i == 0 || i == -1);
+
+ return i;
+}
+
+/* This one isn't inline because it requires half-float conversion */
+double nir_const_value_as_float(nir_const_value value, unsigned bit_size);
+
typedef struct nir_constant {
/**
* Value of the constant.