From: Kenneth Graunke Date: Mon, 12 Apr 2010 21:27:39 +0000 (-0700) Subject: ir_reader: Add support for reading (var_ref ...) and (array_ref ...) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=451381c220f145ac27a177c955dde30a9618fd00;p=mesa.git ir_reader: Add support for reading (var_ref ...) and (array_ref ...) --- diff --git a/ir_reader.cpp b/ir_reader.cpp index 9eadce21195..ee849a8c919 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -43,6 +43,9 @@ static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *); static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *); static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *); static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_array_ref(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_record_ref(_mesa_glsl_parse_state *, s_list *); void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, @@ -327,18 +330,24 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) } ir_rvalue *rvalue = NULL; - if (strcmp(tag->value(), "swiz") == 0) + if (strcmp(tag->value(), "swiz") == 0) { rvalue = read_swizzle(st, list); - else if (strcmp(tag->value(), "assign") == 0) + } else if (strcmp(tag->value(), "assign") == 0) { rvalue = read_assignment(st, list); - else if (strcmp(tag->value(), "expression") == 0) + } else if (strcmp(tag->value(), "expression") == 0) { rvalue = read_expression(st, list); // FINISHME: ir_call - // FINISHME: dereference - else if (strcmp(tag->value(), "constant") == 0) + } else if (strcmp(tag->value(), "constant") == 0) { rvalue = read_constant(st, list); - else + } else if (strcmp(tag->value(), "var_ref") == 0) { + rvalue = read_var_ref(st, list); + } else if (strcmp(tag->value(), "array_ref") == 0) { + rvalue = read_array_ref(st, list); + } else if (strcmp(tag->value(), "record_ref") == 0) { + rvalue = read_record_ref(st, list); + } else { ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value()); + } return rvalue; } @@ -557,3 +566,67 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list) } return NULL; // should not be reached } + +static ir_instruction * +read_dereferencable(_mesa_glsl_parse_state *st, s_expression *expr) +{ + // Read the subject of a dereference - either a variable name or a swizzle + s_symbol *var_name = SX_AS_SYMBOL(expr); + if (var_name != NULL) { + ir_variable *var = st->symbols->get_variable(var_name->value()); + if (var == NULL) { + ir_read_error(expr, "undeclared variable: %s", var_name->value()); + } + return var; + } else { + // Hopefully a (swiz ...) + s_list *list = SX_AS_LIST(expr); + if (list != NULL && !list->subexpressions.is_empty()) { + s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head); + if (tag != NULL && strcmp(tag->value(), "swiz") == 0) + return read_swizzle(st, list); + } + } + ir_read_error(expr, "expected variable name or (swiz ...)"); + return NULL; +} + +static ir_dereference * +read_var_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + if (list->length() != 2) { + ir_read_error(list, "expected (var_ref )"); + return NULL; + } + s_expression *subj_expr = (s_expression*) list->subexpressions.head->next; + ir_instruction *subject = read_dereferencable(st, subj_expr); + if (subject == NULL) + return NULL; + return new ir_dereference(subject); +} + +static ir_dereference * +read_array_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + if (list->length() != 3) { + ir_read_error(list, "expected (array_ref " + ")"); + return NULL; + } + + s_expression *subj_expr = (s_expression*) list->subexpressions.head->next; + ir_instruction *subject = read_dereferencable(st, subj_expr); + if (subject == NULL) + return NULL; + + s_expression *idx_expr = (s_expression*) subj_expr->next; + ir_rvalue *idx = read_rvalue(st, idx_expr); + return new ir_dereference(subject, idx); +} + +static ir_dereference * +read_record_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + ir_read_error(list, "FINISHME: record refs not yet supported."); + return NULL; +}