From: Dave Airlie <airl...@redhat.com> This adds support for 64-bit integer constants to the parser, ast and ir.
v2: fix a few issues found in testing. Signed-off-by: Dave Airlie <airl...@redhat.com> --- src/compiler/glsl/ast.h | 4 ++ src/compiler/glsl/ast_function.cpp | 8 ++- src/compiler/glsl/ast_to_hir.cpp | 14 ++++ src/compiler/glsl/glsl_lexer.ll | 27 ++++++-- src/compiler/glsl/glsl_parser.yy | 16 +++++ src/compiler/glsl/glsl_parser_extras.cpp | 8 +++ src/compiler/glsl/ir.cpp | 112 +++++++++++++++++++++++++++++++ src/compiler/glsl/ir.h | 6 ++ 8 files changed, 188 insertions(+), 7 deletions(-) diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h index 06c7b03..5b4ab44 100644 --- a/src/compiler/glsl/ast.h +++ b/src/compiler/glsl/ast.h @@ -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 @@ -246,6 +248,8 @@ public: unsigned uint_constant; int bool_constant; double double_constant; + uint64_t uint64_constant; + int64_t int64_constant; } primary_expression; diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp index f74394f..c472aae 100644 --- a/src/compiler/glsl/ast_function.cpp +++ b/src/compiler/glsl/ast_function.cpp @@ -1266,7 +1266,13 @@ emit_inline_vector_constructor(const glsl_type *type, case GLSL_TYPE_BOOL: data.b[i + base_component] = c->get_bool_component(i); break; - default: + 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; } diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 29514a5..55b187c 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -1254,6 +1254,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); @@ -1973,6 +1977,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. @@ -2099,6 +2111,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: diff --git a/src/compiler/glsl/glsl_lexer.ll b/src/compiler/glsl/glsl_lexer.ll index 9c6d943..7145b23 100644 --- a/src/compiler/glsl/glsl_lexer.ll +++ b/src/compiler/glsl/glsl_lexer.ll @@ -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) \ @@ -458,13 +473,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); } diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index 2cd4ed8..a630e4a 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -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 @@ -454,6 +456,20 @@ primary_expression: $$->set_location(@1); $$->primary_expression.uint_constant = $1; } + | INT64CONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_int64_constant, NULL, NULL, NULL); + $$->set_location(@1); + $$->primary_expression.int64_constant = $1; + } + | UINT64CONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_uint64_constant, NULL, NULL, NULL); + $$->set_location(@1); + $$->primary_expression.uint64_constant = $1; + } | FLOATCONSTANT { void *ctx = state; diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index e2b58a9..31d2770 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -1195,6 +1195,14 @@ ast_expression::print(void) const printf("%f ", primary_expression.double_constant); break; + case ast_int64_constant: + printf("%ld ", primary_expression.int64_constant); + break; + + case ast_uint64_constant: + printf("%lu ", primary_expression.uint64_constant); + break; + case ast_bool_constant: printf("%s ", primary_expression.bool_constant diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp index 7961f00..8b7572c 100644 --- a/src/compiler/glsl/ir.cpp +++ b/src/compiler/glsl/ir.cpp @@ -740,6 +740,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) { @@ -905,6 +931,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. */ @@ -958,6 +990,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; } @@ -976,6 +1010,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; } @@ -994,6 +1030,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; } @@ -1012,6 +1050,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; } @@ -1030,6 +1070,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; } @@ -1095,6 +1177,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); @@ -1115,6 +1199,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; } @@ -1174,6 +1264,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; @@ -1238,6 +1334,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; @@ -1279,6 +1383,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 diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index 3629356..5a325c2 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -2292,6 +2292,8 @@ union ir_constant_data { float f[16]; bool b[16]; double d[16]; + uint64_t u64[16]; + int64_t i64[16]; }; @@ -2303,6 +2305,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 @@ -2353,6 +2357,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; -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev