summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/ir_constant_expression.cpp48
1 files changed, 23 insertions, 25 deletions
diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp
index d415b5d448c..10e5e3d4502 100644
--- a/src/compiler/glsl/ir_constant_expression.cpp
+++ b/src/compiler/glsl/ir_constant_expression.cpp
@@ -569,6 +569,26 @@ bitfield_extract_int(int32_t value, int offset, int bits)
}
}
+static uint32_t
+bitfield_insert(uint32_t base, uint32_t insert, int offset, int bits)
+{
+ if (bits == 0)
+ return base;
+ else if (offset < 0 || bits < 0)
+ return 0; /* Undefined, per spec. */
+ else if (offset + bits > 32)
+ return 0; /* Undefined, per spec. */
+ else {
+ unsigned insert_mask = ((1ull << bits) - 1) << offset;
+
+ insert <<= offset;
+ insert &= insert_mask;
+ base &= ~insert_mask;
+
+ return base | insert;
+ }
+}
+
ir_constant *
ir_expression::constant_expression_value(struct hash_table *variable_context)
{
@@ -1744,32 +1764,10 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
break;
}
- case ir_quadop_bitfield_insert: {
- for (unsigned c = 0; c < components; c++) {
- int offset = op[2]->value.i[c];
- int bits = op[3]->value.i[c];
-
- if (bits == 0)
- data.u[c] = op[0]->value.u[c];
- else if (offset < 0 || bits < 0)
- data.u[c] = 0; /* Undefined, per spec. */
- else if (offset + bits > 32)
- data.u[c] = 0; /* Undefined, per spec. */
- else {
- unsigned insert_mask = ((1ull << bits) - 1) << offset;
-
- unsigned insert = op[1]->value.u[c];
- insert <<= offset;
- insert &= insert_mask;
-
- unsigned base = op[0]->value.u[c];
- base &= ~insert_mask;
-
- data.u[c] = base | insert;
- }
- }
+ case ir_quadop_bitfield_insert:
+ for (unsigned c = 0; c < components; c++)
+ data.u[c] = bitfield_insert(op[0]->value.u[c], op[1]->value.u[c], op[2]->value.i[c], op[3]->value.i[c]);
break;
- }
case ir_quadop_vector:
for (unsigned c = 0; c < this->type->vector_elements; c++) {