nir: Add support for 1-bit data types

This commit adds support for 1-bit Booleans and integers.  Booleans
obviously take a value of true or false.  Because we have to define the
semantics of 1-bit signed and unsigned integers, we define uint1_t to
take values of 0 and 1 and int1_t to take values of 0 and -1.  1-bit
arithmetic is then well-defined in the usual way, just with fewer bits.
The definition of int1_t and uint1_t doesn't usually matter but we do
need something for purposes of constant folding.

Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
Jason Ekstrand
2018-10-18 11:59:40 -05:00
committed by Jason Ekstrand
parent 2fe8708ffd
commit 3191a82372
11 changed files with 92 additions and 24 deletions

View File

@@ -638,6 +638,7 @@ const_value_int(int64_t i, unsigned bit_size)
{
nir_const_value v;
switch (bit_size) {
case 1: v.b[0] = i & 1; break;
case 8: v.i8[0] = i; break;
case 16: v.i16[0] = i; break;
case 32: v.i32[0] = i; break;
@@ -1206,6 +1207,8 @@ nir_src_comp_as_int(nir_src src, unsigned comp)
assert(comp < load->def.num_components);
switch (load->def.bit_size) {
/* int1_t uses 0/-1 convention */
case 1: return -(int)load->value.b[comp];
case 8: return load->value.i8[comp];
case 16: return load->value.i16[comp];
case 32: return load->value.i32[comp];
@@ -1223,6 +1226,7 @@ nir_src_comp_as_uint(nir_src src, unsigned comp)
assert(comp < load->def.num_components);
switch (load->def.bit_size) {
case 1: return load->value.b[comp];
case 8: return load->value.u8[comp];
case 16: return load->value.u16[comp];
case 32: return load->value.u32[comp];
@@ -1235,15 +1239,12 @@ nir_src_comp_as_uint(nir_src src, unsigned comp)
bool
nir_src_comp_as_bool(nir_src src, unsigned comp)
{
assert(nir_src_is_const(src));
nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr);
int64_t i = nir_src_comp_as_int(src, comp);
assert(comp < load->def.num_components);
assert(load->def.bit_size == 32);
assert(load->value.u32[comp] == NIR_TRUE ||
load->value.u32[comp] == NIR_FALSE);
/* Booleans of any size use 0/-1 convention */
assert(i == 0 || i == -1);
return load->value.u32[comp];
return i;
}
double