[Mesa-dev] [PATCH 06/23] glsl/ast/ir: add 64-bit integer constant support
Dave Airlie
airlied at gmail.com
Thu Jun 9 00:48:07 UTC 2016
From: Dave Airlie <airlied at redhat.com>
This adds support for 64-bit integer constants to the parser,
ast and ir.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
src/compiler/glsl/ast.h | 4 ++++
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/ir.cpp | 42 ++++++++++++++++++++++++++++++++++++++++
src/compiler/glsl/ir.h | 6 ++++++
6 files changed, 103 insertions(+), 6 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_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index b75ddbd..0cf0941 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/ir.cpp b/src/compiler/glsl/ir.cpp
index 7961f00..a7c0eac 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)
{
@@ -1238,6 +1264,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 +1313,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
More information about the mesa-dev
mailing list