glsl/ast/ir: Add 64-bit integer constant support
This adds support for 64-bit integer constants to the parser, ast and ir. v2: fix a few issues found in testing. v3: Add missing ir_constant copy contructor support. v4: Use PRIu64 and PRId64 in printfs in glsl_parser_extras.cpp. Suggested by Nicolai. Rebase on Marek's linalloc changes. Signed-off-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> [v2] Reviewed-by: Matt Turner <mattst88@gmail.com> [v3] Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:

committed by
Ian Romanick

parent
249007d13c
commit
bbce1c538d
@@ -195,6 +195,8 @@ enum ast_operators {
|
||||
ast_float_constant,
|
||||
ast_bool_constant,
|
||||
ast_double_constant,
|
||||
ast_int64_constant,
|
||||
ast_uint64_constant,
|
||||
|
||||
ast_sequence,
|
||||
ast_aggregate
|
||||
@@ -255,6 +257,8 @@ public:
|
||||
unsigned uint_constant;
|
||||
int bool_constant;
|
||||
double double_constant;
|
||||
uint64_t uint64_constant;
|
||||
int64_t int64_constant;
|
||||
} primary_expression;
|
||||
|
||||
|
||||
|
@@ -1260,6 +1260,12 @@ emit_inline_vector_constructor(const glsl_type *type,
|
||||
case GLSL_TYPE_BOOL:
|
||||
data.b[i + base_component] = c->get_bool_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
data.u64[i + base_component] = c->get_uint64_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
data.i64[i + base_component] = c->get_int64_component(i);
|
||||
break;
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
break;
|
||||
@@ -1267,8 +1273,7 @@ emit_inline_vector_constructor(const glsl_type *type,
|
||||
}
|
||||
|
||||
/* Mask of fields to be written in the assignment. */
|
||||
constant_mask |=
|
||||
((1U << rhs_components) - 1) << base_lhs_component;
|
||||
constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component;
|
||||
constant_components += rhs_components;
|
||||
|
||||
base_component += rhs_components;
|
||||
|
@@ -1258,6 +1258,10 @@ constant_one_for_inc_dec(void *ctx, const glsl_type *type)
|
||||
return new(ctx) ir_constant((unsigned) 1);
|
||||
case GLSL_TYPE_INT:
|
||||
return new(ctx) ir_constant(1);
|
||||
case GLSL_TYPE_UINT64:
|
||||
return new(ctx) ir_constant((uint64_t) 1);
|
||||
case GLSL_TYPE_INT64:
|
||||
return new(ctx) ir_constant((int64_t) 1);
|
||||
default:
|
||||
case GLSL_TYPE_FLOAT:
|
||||
return new(ctx) ir_constant(1.0f);
|
||||
@@ -2008,6 +2012,14 @@ ast_expression::do_hir(exec_list *instructions,
|
||||
result = new(ctx) ir_constant(this->primary_expression.double_constant);
|
||||
break;
|
||||
|
||||
case ast_uint64_constant:
|
||||
result = new(ctx) ir_constant(this->primary_expression.uint64_constant);
|
||||
break;
|
||||
|
||||
case ast_int64_constant:
|
||||
result = new(ctx) ir_constant(this->primary_expression.int64_constant);
|
||||
break;
|
||||
|
||||
case ast_sequence: {
|
||||
/* It should not be possible to generate a sequence in the AST without
|
||||
* any expressions in it.
|
||||
@@ -2134,6 +2146,8 @@ ast_expression::has_sequence_subexpression() const
|
||||
case ast_float_constant:
|
||||
case ast_bool_constant:
|
||||
case ast_double_constant:
|
||||
case ast_int64_constant:
|
||||
case ast_uint64_constant:
|
||||
return false;
|
||||
|
||||
case ast_aggregate:
|
||||
|
@@ -107,17 +107,29 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
|
||||
{
|
||||
bool is_uint = (text[len - 1] == 'u' ||
|
||||
text[len - 1] == 'U');
|
||||
bool is_long = (text[len - 1] == 'l' || text[len - 1] == 'L');
|
||||
const char *digits = text;
|
||||
|
||||
if (is_long)
|
||||
is_uint = (text[len - 2] == 'u' && text[len - 1] == 'l') ||
|
||||
(text[len - 2] == 'U' && text[len - 1] == 'L');
|
||||
/* Skip "0x" */
|
||||
if (base == 16)
|
||||
digits += 2;
|
||||
|
||||
unsigned long long value = strtoull(digits, NULL, base);
|
||||
|
||||
lval->n = (int)value;
|
||||
if (is_long)
|
||||
lval->n64 = (int64_t)value;
|
||||
else
|
||||
lval->n = (int)value;
|
||||
|
||||
if (value > UINT_MAX) {
|
||||
if (is_long && !is_uint && base == 10 && value > (uint64_t)LLONG_MAX + 1) {
|
||||
/* Tries to catch unintentionally providing a negative value. */
|
||||
_mesa_glsl_warning(lloc, state,
|
||||
"signed literal value `%s' is interpreted as %lld",
|
||||
text, lval->n64);
|
||||
} else if (!is_long && value > UINT_MAX) {
|
||||
/* Note that signed 0xffffffff is valid, not out of range! */
|
||||
if (state->is_version(130, 300)) {
|
||||
_mesa_glsl_error(lloc, state,
|
||||
@@ -135,7 +147,10 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
|
||||
"signed literal value `%s' is interpreted as %d",
|
||||
text, lval->n);
|
||||
}
|
||||
return is_uint ? UINTCONSTANT : INTCONSTANT;
|
||||
if (is_long)
|
||||
return is_uint ? UINT64CONSTANT : INT64CONSTANT;
|
||||
else
|
||||
return is_uint ? UINTCONSTANT : INTCONSTANT;
|
||||
}
|
||||
|
||||
#define LITERAL_INTEGER(base) \
|
||||
@@ -462,13 +477,13 @@ layout {
|
||||
\|= return OR_ASSIGN;
|
||||
-= return SUB_ASSIGN;
|
||||
|
||||
[1-9][0-9]*[uU]? {
|
||||
[1-9][0-9]*([uU]|[lL]|ul|UL)? {
|
||||
return LITERAL_INTEGER(10);
|
||||
}
|
||||
0[xX][0-9a-fA-F]+[uU]? {
|
||||
0[xX][0-9a-fA-F]+([uU]|[lL]|ul|UL)? {
|
||||
return LITERAL_INTEGER(16);
|
||||
}
|
||||
0[0-7]*[uU]? {
|
||||
0[0-7]*([uU]|[lL]|ul|UL)? {
|
||||
return LITERAL_INTEGER(8);
|
||||
}
|
||||
|
||||
|
@@ -97,6 +97,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
|
||||
|
||||
%union {
|
||||
int n;
|
||||
int64_t n64;
|
||||
float real;
|
||||
double dreal;
|
||||
const char *identifier;
|
||||
@@ -174,6 +175,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
|
||||
%token <real> FLOATCONSTANT
|
||||
%token <dreal> DOUBLECONSTANT
|
||||
%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
|
||||
%token <n64> INT64CONSTANT UINT64CONSTANT
|
||||
%token <identifier> FIELD_SELECTION
|
||||
%token LEFT_OP RIGHT_OP
|
||||
%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
|
||||
@@ -452,6 +454,20 @@ primary_expression:
|
||||
$$->set_location(@1);
|
||||
$$->primary_expression.uint_constant = $1;
|
||||
}
|
||||
| INT64CONSTANT
|
||||
{
|
||||
void *ctx = state->linalloc;
|
||||
$$ = new(ctx) ast_expression(ast_int64_constant, NULL, NULL, NULL);
|
||||
$$->set_location(@1);
|
||||
$$->primary_expression.int64_constant = $1;
|
||||
}
|
||||
| UINT64CONSTANT
|
||||
{
|
||||
void *ctx = state->linalloc;
|
||||
$$ = new(ctx) ast_expression(ast_uint64_constant, NULL, NULL, NULL);
|
||||
$$->set_location(@1);
|
||||
$$->primary_expression.uint64_constant = $1;
|
||||
}
|
||||
| FLOATCONSTANT
|
||||
{
|
||||
void *ctx = state->linalloc;
|
||||
|
@@ -1248,6 +1248,14 @@ ast_expression::print(void) const
|
||||
printf("%f ", primary_expression.double_constant);
|
||||
break;
|
||||
|
||||
case ast_int64_constant:
|
||||
printf("%" PRId64 " ", primary_expression.int64_constant);
|
||||
break;
|
||||
|
||||
case ast_uint64_constant:
|
||||
printf("%" PRIu64 " ", primary_expression.uint64_constant);
|
||||
break;
|
||||
|
||||
case ast_bool_constant:
|
||||
printf("%s ",
|
||||
primary_expression.bool_constant
|
||||
|
@@ -613,6 +613,32 @@ ir_constant::ir_constant(int integer, unsigned vector_elements)
|
||||
}
|
||||
}
|
||||
|
||||
ir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
|
||||
: ir_rvalue(ir_type_constant)
|
||||
{
|
||||
assert(vector_elements <= 4);
|
||||
this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1);
|
||||
for (unsigned i = 0; i < vector_elements; i++) {
|
||||
this->value.u64[i] = u64;
|
||||
}
|
||||
for (unsigned i = vector_elements; i < 16; i++) {
|
||||
this->value.u64[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ir_constant::ir_constant(int64_t int64, unsigned vector_elements)
|
||||
: ir_rvalue(ir_type_constant)
|
||||
{
|
||||
assert(vector_elements <= 4);
|
||||
this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1);
|
||||
for (unsigned i = 0; i < vector_elements; i++) {
|
||||
this->value.i64[i] = int64;
|
||||
}
|
||||
for (unsigned i = vector_elements; i < 16; i++) {
|
||||
this->value.i64[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ir_constant::ir_constant(bool b, unsigned vector_elements)
|
||||
: ir_rvalue(ir_type_constant)
|
||||
{
|
||||
@@ -716,6 +742,11 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
|
||||
for (unsigned i = 0; i < type->components(); i++)
|
||||
this->value.d[i] = value->value.d[0];
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
case GLSL_TYPE_INT64:
|
||||
for (unsigned i = 0; i < type->components(); i++)
|
||||
this->value.u64[i] = value->value.u64[0];
|
||||
break;
|
||||
case GLSL_TYPE_BOOL:
|
||||
for (unsigned i = 0; i < type->components(); i++)
|
||||
this->value.b[i] = value->value.b[0];
|
||||
@@ -778,6 +809,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
|
||||
case GLSL_TYPE_DOUBLE:
|
||||
this->value.d[i] = value->get_double_component(j);
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
this->value.u64[i] = value->get_uint64_component(j);
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
this->value.i64[i] = value->get_int64_component(j);
|
||||
break;
|
||||
default:
|
||||
/* FINISHME: What to do? Exceptions are not the answer.
|
||||
*/
|
||||
@@ -831,6 +868,8 @@ ir_constant::get_bool_component(unsigned i) const
|
||||
case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i];
|
||||
case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
|
||||
case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
|
||||
case GLSL_TYPE_INT64: return this->value.i64[i] != 0;
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
@@ -849,6 +888,8 @@ ir_constant::get_float_component(unsigned i) const
|
||||
case GLSL_TYPE_FLOAT: return this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f;
|
||||
case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return (float) this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
@@ -867,6 +908,8 @@ ir_constant::get_double_component(unsigned i) const
|
||||
case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0;
|
||||
case GLSL_TYPE_DOUBLE: return this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return (double) this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
@@ -885,6 +928,8 @@ ir_constant::get_int_component(unsigned i) const
|
||||
case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
|
||||
case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return (int) this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
@@ -903,6 +948,48 @@ ir_constant::get_uint_component(unsigned i) const
|
||||
case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
|
||||
case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return (unsigned) this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
/* Must return something to make the compiler happy. This is clearly an
|
||||
* error case.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t
|
||||
ir_constant::get_int64_component(unsigned i) const
|
||||
{
|
||||
switch (this->type->base_type) {
|
||||
case GLSL_TYPE_UINT: return this->value.u[i];
|
||||
case GLSL_TYPE_INT: return this->value.i[i];
|
||||
case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
|
||||
case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
/* Must return something to make the compiler happy. This is clearly an
|
||||
* error case.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ir_constant::get_uint64_component(unsigned i) const
|
||||
{
|
||||
switch (this->type->base_type) {
|
||||
case GLSL_TYPE_UINT: return this->value.u[i];
|
||||
case GLSL_TYPE_INT: return this->value.i[i];
|
||||
case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
|
||||
case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
|
||||
case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
|
||||
case GLSL_TYPE_UINT64: return this->value.u64[i];
|
||||
case GLSL_TYPE_INT64: return (uint64_t) this->value.i64[i];
|
||||
default: assert(!"Should not get here."); break;
|
||||
}
|
||||
|
||||
@@ -968,6 +1055,8 @@ ir_constant::copy_offset(ir_constant *src, int offset)
|
||||
case GLSL_TYPE_INT:
|
||||
case GLSL_TYPE_FLOAT:
|
||||
case GLSL_TYPE_DOUBLE:
|
||||
case GLSL_TYPE_UINT64:
|
||||
case GLSL_TYPE_INT64:
|
||||
case GLSL_TYPE_BOOL: {
|
||||
unsigned int size = src->type->components();
|
||||
assert (size <= this->type->components() - offset);
|
||||
@@ -988,6 +1077,12 @@ ir_constant::copy_offset(ir_constant *src, int offset)
|
||||
case GLSL_TYPE_DOUBLE:
|
||||
value.d[i+offset] = src->get_double_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
value.u64[i+offset] = src->get_uint64_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
value.i64[i+offset] = src->get_int64_component(i);
|
||||
break;
|
||||
default: // Shut up the compiler
|
||||
break;
|
||||
}
|
||||
@@ -1047,6 +1142,12 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
|
||||
case GLSL_TYPE_DOUBLE:
|
||||
value.d[i+offset] = src->get_double_component(id++);
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
value.u64[i+offset] = src->get_uint64_component(id++);
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
value.i64[i+offset] = src->get_int64_component(id++);
|
||||
break;
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
return;
|
||||
@@ -1111,6 +1212,14 @@ ir_constant::has_value(const ir_constant *c) const
|
||||
if (this->value.d[i] != c->value.d[i])
|
||||
return false;
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
if (this->value.u64[i] != c->value.u64[i])
|
||||
return false;
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
if (this->value.i64[i] != c->value.i64[i])
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
return false;
|
||||
@@ -1152,6 +1261,14 @@ ir_constant::is_value(float f, int i) const
|
||||
if (this->value.d[c] != double(f))
|
||||
return false;
|
||||
break;
|
||||
case GLSL_TYPE_UINT64:
|
||||
if (this->value.u64[c] != uint64_t(i))
|
||||
return false;
|
||||
break;
|
||||
case GLSL_TYPE_INT64:
|
||||
if (this->value.i64[c] != i)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
/* The only other base types are structures, arrays, and samplers.
|
||||
* Samplers cannot be constants, and the others should have been
|
||||
|
@@ -2093,6 +2093,8 @@ union ir_constant_data {
|
||||
float f[16];
|
||||
bool b[16];
|
||||
double d[16];
|
||||
uint64_t u64[16];
|
||||
int64_t i64[16];
|
||||
};
|
||||
|
||||
|
||||
@@ -2104,6 +2106,8 @@ public:
|
||||
ir_constant(int i, unsigned vector_elements=1);
|
||||
ir_constant(float f, unsigned vector_elements=1);
|
||||
ir_constant(double d, unsigned vector_elements=1);
|
||||
ir_constant(uint64_t u64, unsigned vector_elements=1);
|
||||
ir_constant(int64_t i64, unsigned vector_elements=1);
|
||||
|
||||
/**
|
||||
* Construct an ir_constant from a list of ir_constant values
|
||||
@@ -2154,6 +2158,8 @@ public:
|
||||
double get_double_component(unsigned i) const;
|
||||
int get_int_component(unsigned i) const;
|
||||
unsigned get_uint_component(unsigned i) const;
|
||||
int64_t get_int64_component(unsigned i) const;
|
||||
uint64_t get_uint64_component(unsigned i) const;
|
||||
/*@}*/
|
||||
|
||||
ir_constant *get_array_element(unsigned i) const;
|
||||
|
Reference in New Issue
Block a user