summaryrefslogtreecommitdiff
path: root/src/mesa/shader/program_parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/shader/program_parse.y')
-rw-r--r--src/mesa/shader/program_parse.y118
1 files changed, 86 insertions, 32 deletions
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index 9703e8e670..8ca6f9805b 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -66,8 +66,14 @@ static int validate_inputs(struct YYLTYPE *locp,
static void init_dst_reg(struct prog_dst_register *r);
+static void set_dst_reg(struct prog_dst_register *r,
+ gl_register_file file, GLint index);
+
static void init_src_reg(struct asm_src_register *r);
+static void set_src_reg(struct asm_src_register *r,
+ gl_register_file file, GLint index);
+
static void asm_instruction_set_operands(struct asm_instruction *inst,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
@@ -303,6 +309,8 @@ option: OPTION string ';'
}
+ free($2);
+
if (!valid) {
const char *const err_str = (state->mode == ARB_vertex)
? "invalid ARB vertex program option"
@@ -580,9 +588,7 @@ scalarUse: srcReg scalarSuffix
temp_sym.param_binding_begin = ~0;
initialize_symbol_from_const(state->prog, & temp_sym, & $1);
- init_src_reg(& $$);
- $$.Base.File = PROGRAM_CONSTANT;
- $$.Base.Index = temp_sym.param_binding_begin;
+ set_src_reg(& $$, PROGRAM_CONSTANT, temp_sym.param_binding_begin);
}
;
@@ -637,16 +643,14 @@ maskedDstReg: dstReg optionalMask optionalCcMask
YYERROR;
}
- state->prog->OutputsWritten |= (1U << $$.Index);
+ state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
}
}
;
maskedAddrReg: addrReg addrWriteMask
{
- init_dst_reg(& $$);
- $$.File = PROGRAM_ADDRESS;
- $$.Index = 0;
+ set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
$$.WriteMask = $2.mask;
}
;
@@ -708,12 +712,17 @@ extSwizSel: INTEGER
}
| string
{
+ char s;
+
if (strlen($1) > 1) {
yyerror(& @1, state, "invalid extended swizzle selector");
YYERROR;
}
- switch ($1[0]) {
+ s = $1[0];
+ free($1);
+
+ switch (s) {
case 'x':
$$.swz = SWIZZLE_X;
$$.xyzw_valid = 1;
@@ -761,6 +770,8 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
@@ -776,16 +787,13 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
init_src_reg(& $$);
switch (s->type) {
case at_temp:
- $$.Base.File = PROGRAM_TEMPORARY;
- $$.Base.Index = s->temp_binding;
+ set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
break;
case at_param:
- $$.Base.File = s->param_binding_type;
- $$.Base.Index = s->param_binding_begin;
+ set_src_reg(& $$, s->param_binding_type, s->param_binding_begin);
break;
case at_attrib:
- $$.Base.File = PROGRAM_INPUT;
- $$.Base.Index = s->attrib_binding;
+ set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
state->prog->InputsRead |= (1U << $$.Base.Index);
if (!validate_inputs(& @1, state)) {
@@ -800,9 +808,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
}
| attribBinding
{
- init_src_reg(& $$);
- $$.Base.File = PROGRAM_INPUT;
- $$.Base.Index = $1;
+ set_src_reg(& $$, PROGRAM_INPUT, $1);
state->prog->InputsRead |= (1U << $$.Base.Index);
if (!validate_inputs(& @1, state)) {
@@ -832,25 +838,24 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
}
| paramSingleItemUse
{
- init_src_reg(& $$);
- $$.Base.File = ($1.name != NULL)
+ gl_register_file file = ($1.name != NULL)
? $1.param_binding_type
: PROGRAM_CONSTANT;
- $$.Base.Index = $1.param_binding_begin;
+ set_src_reg(& $$, file, $1.param_binding_begin);
}
;
dstReg: resultBinding
{
- init_dst_reg(& $$);
- $$.File = PROGRAM_OUTPUT;
- $$.Index = $1;
+ set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
}
| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
@@ -859,19 +864,15 @@ dstReg: resultBinding
YYERROR;
}
- init_dst_reg(& $$);
switch (s->type) {
case at_temp:
- $$.File = PROGRAM_TEMPORARY;
- $$.Index = s->temp_binding;
+ set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
break;
case at_output:
- $$.File = PROGRAM_OUTPUT;
- $$.Index = s->output_binding;
+ set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
break;
default:
- $$.File = s->param_binding_type;
- $$.Index = s->param_binding_begin;
+ set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
break;
}
}
@@ -882,6 +883,8 @@ progParamArray: USED_IDENTIFIER
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
@@ -953,6 +956,8 @@ addrReg: USED_IDENTIFIER
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid array member");
YYERROR;
@@ -1091,6 +1096,7 @@ ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
declare_variable(state, $2, at_attrib, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->attrib_binding = $4;
@@ -1198,6 +1204,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
declare_variable(state, $2, at_param, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->param_binding_type = $3.param_binding_type;
@@ -1211,6 +1218,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
{
if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+ free($2);
yyerror(& @4, state,
"parameter array size and number of bindings must match");
YYERROR;
@@ -1219,6 +1227,7 @@ PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
declare_variable(state, $2, $6.type, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->param_binding_type = $6.param_binding_type;
@@ -1236,7 +1245,7 @@ optArraySize:
}
| INTEGER
{
- if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) {
+ if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
yyerror(& @1, state, "invalid parameter array size");
YYERROR;
} else {
@@ -1953,12 +1962,14 @@ ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
varNameList: varNameList ',' IDENTIFIER
{
if (!declare_variable(state, $3, $<integer>0, & @3)) {
+ free($3);
YYERROR;
}
}
| IDENTIFIER
{
if (!declare_variable(state, $1, $<integer>0, & @1)) {
+ free($1);
YYERROR;
}
}
@@ -1970,6 +1981,7 @@ OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
declare_variable(state, $3, at_output, & @3);
if (s == NULL) {
+ free($3);
YYERROR;
} else {
s->output_binding = $5;
@@ -2146,11 +2158,16 @@ ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
struct asm_symbol *target = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $4);
+ free($4);
if (exist != NULL) {
- yyerror(& @2, state, "redeclared identifier");
+ char m[1000];
+ _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
+ free($2);
+ yyerror(& @2, state, m);
YYERROR;
} else if (target == NULL) {
+ free($2);
yyerror(& @4, state,
"undefined variable binding in ALIAS statement");
YYERROR;
@@ -2263,6 +2280,26 @@ init_dst_reg(struct prog_dst_register *r)
}
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+ const GLint maxIndex = 1 << INST_INDEX_BITS;
+ const GLint minIndex = 0;
+ ASSERT(index >= minIndex);
+ ASSERT(index <= maxIndex);
+ ASSERT(file == PROGRAM_TEMPORARY ||
+ file == PROGRAM_ADDRESS ||
+ file == PROGRAM_OUTPUT);
+ memset(r, 0, sizeof(*r));
+ r->File = file;
+ r->Index = index;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
void
init_src_reg(struct asm_src_register *r)
{
@@ -2273,6 +2310,23 @@ init_src_reg(struct asm_src_register *r)
}
+/** Like init_src_reg() but set the File and Index fields. */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+ const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+ const GLint minIndex = -(1 << INST_INDEX_BITS);
+ ASSERT(index >= minIndex);
+ ASSERT(index <= maxIndex);
+ ASSERT(file < PROGRAM_FILE_MAX);
+ memset(r, 0, sizeof(*r));
+ r->Base.File = file;
+ r->Base.Index = index;
+ r->Base.Swizzle = SWIZZLE_NOOP;
+ r->Symbol = NULL;
+}
+
+
/**
* Validate the set of inputs used by a program
*