ir_reader.cpp revision e486fca2d3b430065cbcb27c5d1b545642e11ab5
134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke/*
234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * Copyright © 2010 Intel Corporation
334350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke *
434350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * Permission is hereby granted, free of charge, to any person obtaining a
534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * copy of this software and associated documentation files (the "Software"),
634350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * to deal in the Software without restriction, including without limitation
734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * the rights to use, copy, modify, merge, publish, distribute, sublicense,
834350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * and/or sell copies of the Software, and to permit persons to whom the
934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * Software is furnished to do so, subject to the following conditions:
1034350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke *
1134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * The above copyright notice and this permission notice (including the next
1234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * paragraph) shall be included in all copies or substantial portions of the
1334350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * Software.
1434350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke *
1534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1634350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1834350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2034350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke * DEALINGS IN THE SOFTWARE.
2234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke */
23ac95f2f8c88d39aaa878f61172d9748af13e2c80Eric Anholt
24b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunkeextern "C" {
25b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke#include <talloc.h>
26b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke}
27b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke
2834350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "ir_reader.h"
2934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "glsl_parser_extras.h"
3034350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "glsl_types.h"
3134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "s_expression.h"
3234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
339a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunkeconst static bool debug = false;
349a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke
354ec982fb86ae2476508d2027464241489243a170Kenneth Graunkestatic void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
364ec982fb86ae2476508d2027464241489243a170Kenneth Graunke			  const char *fmt, ...);
3757944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunkestatic const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
38d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
3909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunkestatic void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
4009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke			        s_expression *);
41e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_function *read_function(_mesa_glsl_parse_state *, s_expression *,
428df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke				  bool skip_body);
43b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunkestatic void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
44daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			      s_expression *, bool skip_body);
4509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
463ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunkestatic void read_instructions(_mesa_glsl_parse_state *, exec_list *,
47396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke			      s_expression *, ir_loop *);
48d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunkestatic ir_instruction *read_instruction(_mesa_glsl_parse_state *,
49396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke				        s_expression *, ir_loop *);
50e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_variable *read_declaration(_mesa_glsl_parse_state *, s_expression *);
51e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_if *read_if(_mesa_glsl_parse_state *, s_expression *, ir_loop *);
52e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_loop *read_loop(_mesa_glsl_parse_state *st, s_expression *);
53e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_return *read_return(_mesa_glsl_parse_state *, s_expression *);
54d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
55f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
56e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_expression *);
57e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_expression *read_expression(_mesa_glsl_parse_state *, s_expression *);
58e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_call *read_call(_mesa_glsl_parse_state *, s_expression *);
59e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_expression *);
60e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_constant *read_constant(_mesa_glsl_parse_state *, s_expression *);
61e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkestatic ir_texture *read_texture(_mesa_glsl_parse_state *, s_expression *);
623c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke
633c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunkestatic ir_dereference *read_dereference(_mesa_glsl_parse_state *,
643c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke				        s_expression *);
650fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_variable *
66e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_var_ref(_mesa_glsl_parse_state *, s_expression *);
670fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_array *
68e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_array_ref(_mesa_glsl_parse_state *, s_expression *);
690fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_record *
70e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_record_ref(_mesa_glsl_parse_state *, s_expression *);
71f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
7234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunkevoid
7334350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
7443ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke		   const char *src, bool scan_for_protos)
7534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke{
7678062273de65bf8133f2550aa2a26040a82a65aaKenneth Graunke   s_expression *expr = s_expression::read_expression(state, src);
7734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   if (expr == NULL) {
784ec982fb86ae2476508d2027464241489243a170Kenneth Graunke      ir_read_error(state, NULL, "couldn't parse S-Expression.");
7934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke      return;
8034350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   }
8134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
8243ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (scan_for_protos) {
8343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      scan_for_prototypes(state, instructions, expr);
8443ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      if (state->error)
8543ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke	 return;
8643ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   }
8709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
88396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   read_instructions(state, instructions, expr, NULL);
8978062273de65bf8133f2550aa2a26040a82a65aaKenneth Graunke   talloc_free(expr);
9079088746a231d361232fc87ab4d578b08c7ce2a7Kenneth Graunke
919a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke   if (debug)
929a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke      validate_ir_tree(instructions);
9334350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke}
9434350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
95f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic void
964ec982fb86ae2476508d2027464241489243a170Kenneth Graunkeir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
974ec982fb86ae2476508d2027464241489243a170Kenneth Graunke	      const char *fmt, ...)
98f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
99f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_list ap;
100f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
1014ec982fb86ae2476508d2027464241489243a170Kenneth Graunke   state->error = true;
102f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
103a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke   if (state->current_function != NULL)
104a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke      state->info_log = talloc_asprintf_append(state->info_log,
105a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke			   "In function %s:\n",
106a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke			   state->current_function->function_name());
107b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_strdup_append(state->info_log, "error: ");
108f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
109f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_start(ap, fmt);
110b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
111f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_end(ap);
112b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_strdup_append(state->info_log, "\n");
113f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
11446a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   if (expr != NULL) {
115b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke      state->info_log = talloc_strdup_append(state->info_log,
116b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke					     "...in this context:\n   ");
11746a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      expr->print();
118b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke      state->info_log = talloc_strdup_append(state->info_log, "\n\n");
11946a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   }
120f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
121f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
12257944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunkestatic const glsl_type *
123f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkeread_type(_mesa_glsl_parse_state *st, s_expression *expr)
124f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
125daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_base_type;
126daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *s_size;
127daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
128daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "array", s_base_type, s_size };
129daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(expr, pat)) {
130daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      const glsl_type *base_type = read_type(st, s_base_type);
131daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (base_type == NULL) {
132daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, NULL, "when reading base type of array type");
133f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
134f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
13557944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunke
136daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return glsl_type::get_array_instance(base_type, s_size->value());
137f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
138f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
139f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *type_sym = SX_AS_SYMBOL(expr);
140f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type_sym == NULL) {
141daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      ir_read_error(st, expr, "expected <type>");
142f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
143f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
144f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
14557944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunke   const glsl_type *type = st->symbols->get_type(type_sym->value());
146f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
1474ec982fb86ae2476508d2027464241489243a170Kenneth Graunke      ir_read_error(st, expr, "invalid type: %s", type_sym->value());
148f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
149f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return type;
150f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
151f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
152d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
1533ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunkestatic void
15409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunkescan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
15509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke		    s_expression *expr)
15609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
15709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
15809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (list == NULL) {
15909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
16009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      return;
16109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
16209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
16309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
16409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_list *sub = SX_AS_LIST(it.get());
16509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (sub == NULL)
16609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
16709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
16809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
16909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (tag == NULL || strcmp(tag->value(), "function") != 0)
17009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
17109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
1728df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      ir_function *f = read_function(st, sub, true);
1738df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      if (f == NULL)
17409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 return;
1758df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      instructions->push_tail(f);
17609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
17709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
17809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
1798df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunkestatic ir_function *
180e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_function(_mesa_glsl_parse_state *st, s_expression *expr, bool skip_body)
18109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
182953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
183e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   bool added = false;
184daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
18509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
186daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "function", name };
187e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
188e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "Expected (function <name> (signature ...) ...)");
1898df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      return NULL;
19009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
19109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
1928df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   ir_function *f = st->symbols->get_function(name->value());
1938df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   if (f == NULL) {
1941660a2954797e056caba319c5d6c70b0d4be22feCarl Worth      f = new(ctx) ir_function(name->value());
195e8f5ebf313da3ce33ccbbcf9b72946853035fbddEric Anholt      added = st->symbols->add_function(f);
1968df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      assert(added);
19709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
19809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
199e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
20009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip "function" tag
20109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip function name
20209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (/* nothing */; it.has_next(); it.next()) {
203daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_sig = (s_expression *) it.get();
204daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      read_function_sig(st, f, s_sig, skip_body);
20509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
206e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   return added ? f : NULL;
20709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
20809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
209b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunkestatic void
210daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkeread_function_sig(_mesa_glsl_parse_state *st, ir_function *f,
211daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		  s_expression *expr, bool skip_body)
21209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
213953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
214daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
215daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *paramlist;
216daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *body_list;
217daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
218daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "signature", type_expr, paramlist, body_list };
219daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (!MATCH(expr, pat)) {
220daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      ir_read_error(st, expr, "Expected (signature <type> (parameters ...) "
22109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke			      "(<instruction> ...))");
222b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
22409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
22509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   const glsl_type *return_type = read_type(st, type_expr);
22609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (return_type == NULL)
227b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
22909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
23009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
23109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      ir_read_error(st, paramlist, "Expected (parameters ...)");
232b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
23309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
23409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
235b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   // Read the parameters list into a temporary place.
236b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   exec_list hir_parameters;
2378df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   st->symbols->push_scope();
2388df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
23909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   exec_list_iterator it = paramlist->subexpressions.iterator();
24009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
241e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_variable *var = read_declaration(st, (s_expression *) it.get());
242b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (var == NULL)
243b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
244b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
245b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      hir_parameters.push_tail(var);
246b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
247b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
248b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
24943ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (sig == NULL && skip_body) {
25043ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* If scanning for prototypes, generate a new signature. */
25143ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      sig = new(ctx) ir_function_signature(return_type);
252f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke      sig->is_builtin = true;
25343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      f->add_signature(sig);
25443ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   } else if (sig != NULL) {
255b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      const char *badvar = sig->qualifiers_match(&hir_parameters);
256b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (badvar != NULL) {
257daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, expr, "function `%s' parameter `%s' qualifiers "
258b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "don't match prototype", f->name, badvar);
259b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
26009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      }
26109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
262b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->return_type != return_type) {
263daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, expr, "function `%s' return type doesn't "
264b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "match prototype", f->name);
265b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
266b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
267b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   } else {
26843ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* No prototype for this body exists - skip it. */
26943ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      st->symbols->pop_scope();
27043ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      return;
27109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
27243ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   assert(sig != NULL);
27309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
274b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   sig->replace_parameters(&hir_parameters);
275b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
276d802ba110f78c3eee9541867cde819ada1b2c449Kenneth Graunke   if (!skip_body && !body_list->subexpressions.is_empty()) {
277b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->is_defined) {
278daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, expr, "function %s redefined", f->name);
279b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
280b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
281a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke      st->current_function = sig;
2828df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      read_instructions(st, &sig->body, body_list, NULL);
283a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke      st->current_function = NULL;
284f6c90d8b3484864cd7f3abf895746e0655929a13Kenneth Graunke      sig->is_defined = true;
285b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
2868df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
2878df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   st->symbols->pop_scope();
28809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
28909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
29009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunkestatic void
2913ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunkeread_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
292396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke		  s_expression *expr, ir_loop *loop_ctx)
2933ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
2943ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   // Read in a list of instructions
2953ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
2963ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (list == NULL) {
2974ec982fb86ae2476508d2027464241489243a170Kenneth Graunke      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
2983ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return;
2993ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
3003ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3013ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
3023ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      s_expression *sub = (s_expression*) it.get();
303396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      ir_instruction *ir = read_instruction(st, sub, loop_ctx);
3042809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      if (ir != NULL) {
3052809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 /* Global variable declarations should be moved to the top, before
3062809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * any functions that might use them.  Functions are added to the
3072809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * instruction stream when scanning for prototypes, so without this
3082809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * hack, they always appear before variable declarations.
3092809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  */
3102809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 if (st->current_function == NULL && ir->as_variable() != NULL)
3112809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_head(ir);
3122809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 else
3132809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_tail(ir);
3142809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      }
3153ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
3163ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
3173ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3183ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
319d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunkestatic ir_instruction *
320396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunkeread_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
321396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke	         ir_loop *loop_ctx)
322d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
323953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
324396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   s_symbol *symbol = SX_AS_SYMBOL(expr);
325396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   if (symbol != NULL) {
326396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
3271660a2954797e056caba319c5d6c70b0d4be22feCarl Worth	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
328396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
3291660a2954797e056caba319c5d6c70b0d4be22feCarl Worth	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
330396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   }
331396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke
332d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
333e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty()) {
334e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke      ir_read_error(st, expr, "Invalid instruction.\n");
335d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
336e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   }
337d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
338d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
339d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (tag == NULL) {
3404ec982fb86ae2476508d2027464241489243a170Kenneth Graunke      ir_read_error(st, expr, "expected instruction tag");
341d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
342d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
343d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
344d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   ir_instruction *inst = NULL;
34546ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   if (strcmp(tag->value(), "declare") == 0) {
346d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      inst = read_declaration(st, list);
3473c033637de7def553559c11d037f2e8bbb750f77Kenneth Graunke   } else if (strcmp(tag->value(), "assign") == 0) {
3483c033637de7def553559c11d037f2e8bbb750f77Kenneth Graunke      inst = read_assignment(st, list);
34946ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "if") == 0) {
350396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      inst = read_if(st, list, loop_ctx);
35132b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   } else if (strcmp(tag->value(), "loop") == 0) {
35232b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      inst = read_loop(st, list);
35346ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "return") == 0) {
3549d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      inst = read_return(st, list);
3558df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   } else if (strcmp(tag->value(), "function") == 0) {
3568df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      inst = read_function(st, list, false);
35746ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else {
35846ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke      inst = read_rvalue(st, list);
35946ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke      if (inst == NULL)
36046a223224c55eaed7bf634d901f733098e674457Kenneth Graunke	 ir_read_error(st, NULL, "when reading instruction");
36146ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   }
362d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return inst;
363d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
364d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
365d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunkestatic ir_variable *
366e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_declaration(_mesa_glsl_parse_state *st, s_expression *expr)
367d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
368daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_quals;
369daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
370daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_name;
371daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
372daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
373e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
374e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (declare (<qualifiers>) <type> "
3754ec982fb86ae2476508d2027464241489243a170Kenneth Graunke			      "<name>)");
376d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
377d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
378d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
379daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   const glsl_type *type = read_type(st, s_type);
380d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (type == NULL)
381d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
382d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
383daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_variable *var = new(st) ir_variable(type, s_name->value(), ir_var_auto);
384d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
385daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
386d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      s_symbol *qualifier = SX_AS_SYMBOL(it.get());
387d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (qualifier == NULL) {
388e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 ir_read_error(st, expr, "qualifier list must contain only symbols");
389d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
390d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
391d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
392d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      // FINISHME: Check for duplicate/conflicting qualifiers.
393d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (strcmp(qualifier->value(), "centroid") == 0) {
394d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->centroid = 1;
395d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "invariant") == 0) {
396d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->invariant = 1;
397d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "uniform") == 0) {
398d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_uniform;
399d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "auto") == 0) {
400d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_auto;
401d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "in") == 0) {
402d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_in;
403d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "out") == 0) {
404d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_out;
405d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "inout") == 0) {
406d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_inout;
407d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "smooth") == 0) {
408d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_smooth;
409d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "flat") == 0) {
410d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_flat;
411d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "noperspective") == 0) {
412d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_noperspective;
413d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else {
414e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 ir_read_error(st, expr, "unknown qualifier: %s", qualifier->value());
415d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
416d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
417d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
418d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
419d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   // Add the variable to the symbol table
420001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholt   st->symbols->add_variable(var);
421d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
422d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return var;
423d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
424d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
425d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
4263ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunkestatic ir_if *
427e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_if(_mesa_glsl_parse_state *st, s_expression *expr, ir_loop *loop_ctx)
4283ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
429daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_cond;
430daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_then;
431daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_else;
432daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
433daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "if", s_cond, s_then, s_else };
434e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
435e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (if <condition> (<then> ...) "
436daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			      "(<else> ...))");
4373ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4383ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4393ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
440daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_rvalue *condition = read_rvalue(st, s_cond);
4413ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (condition == NULL) {
44246a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading condition of (if ...)");
4433ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4443ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4453ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
446daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_if *iff = new(st) ir_if(condition);
4473ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
448daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   read_instructions(st, &iff->then_instructions, s_then, loop_ctx);
449daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   read_instructions(st, &iff->else_instructions, s_else, loop_ctx);
4503ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (st->error) {
4513ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      delete iff;
4523ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      iff = NULL;
4533ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4543ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   return iff;
4553ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
4563ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
4573ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
45832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunkestatic ir_loop *
459e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_loop(_mesa_glsl_parse_state *st, s_expression *expr)
46032b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke{
461daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
462daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
463daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
464e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
465e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (loop <counter> <from> <to> "
4664ec982fb86ae2476508d2027464241489243a170Kenneth Graunke			      "<increment> <body>)");
46732b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      return NULL;
46832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
46932b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
47032b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   // FINISHME: actually read the count/from/to fields.
47132b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
472daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_loop *loop = new(st) ir_loop;
473daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   read_instructions(st, &loop->body_instructions, s_body, loop);
47432b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   if (st->error) {
47532b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      delete loop;
47632b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      loop = NULL;
47732b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
47832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   return loop;
47932b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke}
48032b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
48132b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
4829d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunkestatic ir_return *
483e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_return(_mesa_glsl_parse_state *st, s_expression *expr)
4849d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke{
485e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   s_expression *s_retval;
486daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
487e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   s_pattern pat[] = { "return", s_retval};
488e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
489e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (return <rvalue>)");
4909d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      return NULL;
4919d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   }
4929d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
493e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   ir_rvalue *retval = read_rvalue(st, s_retval);
4949d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   if (retval == NULL) {
49546a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading return value");
4969d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      return NULL;
4979d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   }
4989d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
499daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   return new(st) ir_return(retval);
5009d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke}
5019d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
5029d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
503f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_rvalue *
504f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkeread_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
505f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
506f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
507f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty())
508f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
509f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
510f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
511f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (tag == NULL) {
5124ec982fb86ae2476508d2027464241489243a170Kenneth Graunke      ir_read_error(st, expr, "expected rvalue tag");
513f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
514f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
515f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
5163c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   ir_rvalue *rvalue = read_dereference(st, list);
5173c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   if (rvalue != NULL || st->error)
5183c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return rvalue;
5193c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   else if (strcmp(tag->value(), "swiz") == 0) {
520f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      rvalue = read_swizzle(st, list);
521451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "expression") == 0) {
522f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      rvalue = read_expression(st, list);
523b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   } else if (strcmp(tag->value(), "call") == 0) {
524b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      rvalue = read_call(st, list);
525451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "constant") == 0) {
526f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      rvalue = read_constant(st, list);
527451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else {
528dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      rvalue = read_texture(st, list);
529dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      if (rvalue == NULL && !st->error)
530dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
531451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   }
532f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
533f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return rvalue;
534f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
535f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
536f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_assignment *
537e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_assignment(_mesa_glsl_parse_state *st, s_expression *expr)
538f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
539daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *cond_expr, *lhs_expr, *rhs_expr;
540daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list       *mask_list;
541daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
542daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr };
543e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
544e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (assign <condition> (<write mask>) "
54503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke			      "<lhs> <rhs>)");
546f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
547f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
548f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
549f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   ir_rvalue *condition = read_rvalue(st, cond_expr);
550f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (condition == NULL) {
55146a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading condition of assignment");
552f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
553f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
554f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
55503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   unsigned mask = 0;
55603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
557daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *mask_symbol;
558daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern mask_pat[] = { mask_symbol };
559daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(mask_list, mask_pat)) {
56003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const char *mask_str = mask_symbol->value();
56103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      unsigned mask_length = strlen(mask_str);
56203a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      if (mask_length > 4) {
563e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 ir_read_error(st, expr, "invalid write mask: %s", mask_str);
56403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 return NULL;
56503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
56603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
56703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
56803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
56903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      for (unsigned i = 0; i < mask_length; i++) {
57003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
571e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	    ir_read_error(st, expr, "write mask contains invalid character: %c",
57203a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke			  mask_str[i]);
57303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	    return NULL;
57403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 }
57503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 mask |= 1 << idx_map[mask_str[i] - 'w'];
57603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
577daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   } else if (!mask_list->subexpressions.is_empty()) {
578daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      ir_read_error(st, mask_list, "expected () or (<write mask>)");
579daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
58003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
58103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
58203a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   ir_dereference *lhs = read_dereference(st, lhs_expr);
583f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (lhs == NULL) {
58446a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading left-hand side of assignment");
585f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
586f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
587f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
588f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   ir_rvalue *rhs = read_rvalue(st, rhs_expr);
589f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rhs == NULL) {
59046a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading right-hand side of assignment");
591f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
592f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
593f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
59403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
595e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "non-zero write mask required.");
59603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      return NULL;
59703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
59803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
599daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   return new(st) ir_assignment(lhs, rhs, condition, mask);
600f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
601f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
602b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunkestatic ir_call *
603e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_call(_mesa_glsl_parse_state *st, s_expression *expr)
604b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke{
605953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
606daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
607daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *params;
608b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
609daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "call", name, params };
610e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
611e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (call <name> (<param> ...))");
612b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
613b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
614b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
615b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   exec_list parameters;
616b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
617b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   foreach_iter(exec_list_iterator, it, params->subexpressions) {
618b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
619b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      ir_rvalue *param = read_rvalue(st, expr);
620b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      if (param == NULL) {
621e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 ir_read_error(st, expr, "when reading parameter to function call");
622b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke	 return NULL;
623b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      }
624b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      parameters.push_tail(param);
625b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
626b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
627b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   ir_function *f = st->symbols->get_function(name->value());
628b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (f == NULL) {
629e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "found call to undefined function %s",
630b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke		    name->value());
631b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
632b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
633b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
6341f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt   ir_function_signature *callee = f->matching_signature(&parameters);
635b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (callee == NULL) {
636e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "couldn't find matching signature for function "
637b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke                    "%s", name->value());
638b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
639b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
640b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
6411660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_call(callee, &parameters);
642b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke}
643f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
644f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_expression *
645e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_expression(_mesa_glsl_parse_state *st, s_expression *expr)
646f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
647953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
648daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
649daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_op;
650daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg1;
651daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
652daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
653e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
654e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (expression <type> <operator> "
6554ec982fb86ae2476508d2027464241489243a170Kenneth Graunke			      "<operand> [<operand>])");
656f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
657f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
658daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
659f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
660daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   const glsl_type *type = read_type(st, s_type);
661f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
662f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
663f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
664f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   /* Read the operator */
665daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_expression_operation op = ir_expression::get_operator(s_op->value());
666f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (op == (ir_expression_operation) -1) {
667e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "invalid operator: %s", s_op->value());
668f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
669f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
670f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
671daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   unsigned num_operands = ir_expression::get_num_operands(op);
672daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
673e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (expression <type> %s <operand>)",
674daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    s_op->value());
675daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
676f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
677f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
678daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_rvalue *arg1 = read_rvalue(st, s_arg1);
679daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_rvalue *arg2 = NULL;
680f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (arg1 == NULL) {
68146a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      ir_read_error(st, NULL, "when reading first operand of %s",
682daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    s_op->value());
683f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
684f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
685f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
686daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (num_operands == 2) {
687daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) {
688e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 ir_read_error(st, expr, "expected (expression <type> %s <operand> "
689daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke				 "<operand>)", s_op->value());
690daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
691daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
692daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      arg2 = read_rvalue(st, s_arg2);
693f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (arg2 == NULL) {
69446a223224c55eaed7bf634d901f733098e674457Kenneth Graunke	 ir_read_error(st, NULL, "when reading second operand of %s",
695daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       s_op->value());
696f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
697f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
698f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
699f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
7001660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_expression(op, type, arg1, arg2);
701f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
702f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
703f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_swizzle *
704e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_swizzle(_mesa_glsl_parse_state *st, s_expression *expr)
705f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
706daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *swiz;
707daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *sub;
708f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
709daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "swiz", swiz, sub };
710e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
711e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (swiz <swizzle> <rvalue>)");
712f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
713f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
714f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
715951632253f4f37ce058e2466bca5b96bb43ccfbfKenneth Graunke   if (strlen(swiz->value()) > 4) {
716e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected a valid swizzle; found %s",
7174ec982fb86ae2476508d2027464241489243a170Kenneth Graunke		    swiz->value());
718f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
719f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
720f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
721f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   ir_rvalue *rvalue = read_rvalue(st, sub);
722f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rvalue == NULL)
723f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
724f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
725bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
726bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke				       rvalue->type->vector_elements);
727bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   if (ir == NULL)
728e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "invalid swizzle");
729bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke
730bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   return ir;
731f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
732f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
733f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunkestatic ir_constant *
734e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_constant(_mesa_glsl_parse_state *st, s_expression *expr)
735f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
736953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
737daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
738daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *values;
739daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
740daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "constant", type_expr, values };
741e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
742e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (constant <type> (...))");
743f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
744f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
745f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
74657944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunke   const glsl_type *type = read_type(st, type_expr);
747f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
748f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
749f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
750f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (values == NULL) {
751e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (constant <type> (...))");
752f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
753f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
754f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
755ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   if (type->is_array()) {
756d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      unsigned elements_supplied = 0;
757ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      exec_list elements;
758ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      foreach_iter(exec_list_iterator, it, values->subexpressions) {
759e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 s_expression *elt = (s_expression *) it.get();
760ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 ir_constant *ir_elt = read_constant(st, elt);
761ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 if (ir_elt == NULL)
762ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	    return NULL;
763ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 elements.push_tail(ir_elt);
764d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 elements_supplied++;
765d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      }
766d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke
767d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      if (elements_supplied != type->length) {
768d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 ir_read_error(st, values, "expected exactly %u array elements, "
769d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke		       "given %u", type->length, elements_supplied);
770d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 return NULL;
771ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      }
772ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      return new(ctx) ir_constant(type, &elements);
773ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   }
774ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke
775f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   const glsl_type *const base_type = type->get_base_type();
776f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
777b43611b79c1f0a5caff80c17c9e7840a718f07c9Vinson Lee   ir_constant_data data = { { 0 } };
778f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
779f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   // Read in list of values (at most 16).
780f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   int k = 0;
781f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   foreach_iter(exec_list_iterator, it, values->subexpressions) {
782f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (k >= 16) {
7834ec982fb86ae2476508d2027464241489243a170Kenneth Graunke	 ir_read_error(st, values, "expected at most 16 numbers");
784f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
785f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
786f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
787f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
788f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
789f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (base_type->base_type == GLSL_TYPE_FLOAT) {
790f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_number *value = SX_AS_NUMBER(expr);
791f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
7924ec982fb86ae2476508d2027464241489243a170Kenneth Graunke	    ir_read_error(st, values, "expected numbers");
793f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
794f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
7954976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	 data.f[k] = value->fvalue();
796f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      } else {
797f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_int *value = SX_AS_INT(expr);
798f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
7994ec982fb86ae2476508d2027464241489243a170Kenneth Graunke	    ir_read_error(st, values, "expected integers");
800f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
801f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
802f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
803f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 switch (base_type->base_type) {
804f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_UINT: {
8054976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.u[k] = value->value();
806f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
807f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
808f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_INT: {
8094976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.i[k] = value->value();
810f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
811f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
812f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_BOOL: {
8134976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.b[k] = value->value();
814f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
815f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
816f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 default:
8174ec982fb86ae2476508d2027464241489243a170Kenneth Graunke	    ir_read_error(st, values, "unsupported constant type");
818f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
819f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
820f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
821f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      ++k;
822f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
8234976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick
8241660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_constant(type, &data);
825f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
826451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
827451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunkestatic ir_dereference *
8283c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunkeread_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
8293c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke{
8303c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
8313c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty())
8323c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return NULL;
8333c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke
8343c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
8353c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   assert(tag != NULL);
8363c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke
8373c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   if (strcmp(tag->value(), "var_ref") == 0)
8383c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return read_var_ref(st, list);
8393c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   if (strcmp(tag->value(), "array_ref") == 0)
8403c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return read_array_ref(st, list);
8413c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   if (strcmp(tag->value(), "record_ref") == 0)
8423c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return read_record_ref(st, list);
8433c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   return NULL;
8443c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke}
8453c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke
8460fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_variable *
847e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_var_ref(_mesa_glsl_parse_state *st, s_expression *expr)
848451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke{
849953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
850daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *var_name;
851daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
852daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "var_ref", var_name };
853e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
854e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (var_ref <variable name>)");
855350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke      return NULL;
856350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   }
857350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke
858350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   ir_variable *var = st->symbols->get_variable(var_name->value());
859350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   if (var == NULL) {
860e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "undeclared variable: %s", var_name->value());
861451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke      return NULL;
862350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   }
863350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke
8641660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_dereference_variable(var);
865451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke}
866451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
8670fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_array *
868e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_array_ref(_mesa_glsl_parse_state *st, s_expression *expr)
869451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke{
870953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
871daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *subj_expr;
872daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *idx_expr;
873daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
874daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "array_ref", subj_expr, idx_expr };
875e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
876e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (array_ref <rvalue> <index>)");
877451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke      return NULL;
878451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   }
879451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
880350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   ir_rvalue *subject = read_rvalue(st, subj_expr);
881350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   if (subject == NULL) {
882350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke      ir_read_error(st, NULL, "when reading the subject of an array_ref");
883451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke      return NULL;
884350bd703480d4e4f8dea1813cec6ee8964bce3beKenneth Graunke   }
885451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
886451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   ir_rvalue *idx = read_rvalue(st, idx_expr);
8871660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_dereference_array(subject, idx);
888451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke}
889451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
8900fd665ca63ba37b9a3022f21a8d9f363530e2038Kenneth Graunkestatic ir_dereference_record *
891e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_record_ref(_mesa_glsl_parse_state *st, s_expression *expr)
892451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke{
893953ff1283d3d52e6a6b4850c2b0b574111625010Kenneth Graunke   void *ctx = st;
894daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *subj_expr;
895daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *field;
896daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
897daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "record_ref", subj_expr, field };
898e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
899e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke      ir_read_error(st, expr, "expected (record_ref <rvalue> <field>)");
90013e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke      return NULL;
90113e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   }
90213e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke
90313e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   ir_rvalue *subject = read_rvalue(st, subj_expr);
90413e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   if (subject == NULL) {
90513e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke      ir_read_error(st, NULL, "when reading the subject of a record_ref");
90613e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke      return NULL;
90713e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   }
9081660a2954797e056caba319c5d6c70b0d4be22feCarl Worth   return new(ctx) ir_dereference_record(subject, field->value());
909451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke}
910dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
911dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunkestatic ir_texture *
912e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunkeread_texture(_mesa_glsl_parse_state *st, s_expression *expr)
913dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke{
914daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *tag = NULL;
915daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_sampler = NULL;
916daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_coord = NULL;
917daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_offset = NULL;
918daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_proj = NULL;
919daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_shadow = NULL;
920daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_lod = NULL;
921daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
922daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_texture_opcode op;
923daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
924daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern tex_pattern[] =
925daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
926daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern txf_pattern[] =
927daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { "txf", s_sampler, s_coord, s_offset, s_lod };
928daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern other_pattern[] =
929daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
930daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
931e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (MATCH(expr, tex_pattern)) {
932daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_tex;
933e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, txf_pattern)) {
934daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_txf;
935e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, other_pattern)) {
936daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_texture::get_opcode(tag->value());
937daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (op == -1)
938daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
939dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
940dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
941daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_texture *tex = new(st) ir_texture(op);
942dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
943dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read sampler (must be a deref)
944daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_dereference *sampler = read_dereference(st, s_sampler);
94556d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   if (sampler == NULL) {
946daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      ir_read_error(st, NULL, "when reading sampler in (%s ...)",
947daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
948dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
949dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
95056d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   tex->set_sampler(sampler);
951dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
952dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read coordinate (any rvalue)
953daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   tex->coordinate = read_rvalue(st, s_coord);
954dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   if (tex->coordinate == NULL) {
955dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
956daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
957dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
958dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
959dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
960dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read texel offset, i.e. (0 0 0)
961daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_x;
962daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_y;
963daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_z;
964daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
965daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (!MATCH(s_offset, offset_pat)) {
966daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      ir_read_error(st, s_offset, "expected (<int> <int> <int>)");
967dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
968dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
969dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[0] = offset_x->value();
970dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[1] = offset_y->value();
971dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[2] = offset_z->value();
972dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
973daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (op != ir_txf) {
974daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_int *proj_as_int = SX_AS_INT(s_proj);
975dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      if (proj_as_int && proj_as_int->value() == 1) {
976dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 tex->projector = NULL;
977dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
978daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->projector = read_rvalue(st, s_proj);
979dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->projector == NULL) {
980dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
981daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	                  tex->opcode_string());
982dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
983dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
984dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
985dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
986daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_shadow->subexpressions.is_empty()) {
987daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->shadow_comparitor = NULL;
988dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
989daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->shadow_comparitor = read_rvalue(st, s_shadow);
990dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->shadow_comparitor == NULL) {
991dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
992daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			  tex->opcode_string());
993dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
994dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
995dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
996daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   }
997dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
998daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   switch (op) {
999daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txb:
1000daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      tex->lod_info.bias = read_rvalue(st, s_lod);
1001daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.bias == NULL) {
1002daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
1003daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1004daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1005daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1006daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txl:
1007daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txf:
1008daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      tex->lod_info.lod = read_rvalue(st, s_lod);
1009daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.lod == NULL) {
1010daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, NULL, "when reading LOD in (%s ...)",
1011daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       tex->opcode_string());
1012daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1013daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1014daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1015daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txd: {
1016daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_dx, *s_dy;
1017daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_pattern dxdy_pat[] = { s_dx, s_dy };
1018daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (!MATCH(s_lod, dxdy_pat)) {
1019daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, s_lod, "expected (dPdx dPdy) in (txd ...)");
1020daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1021daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1022daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      tex->lod_info.grad.dPdx = read_rvalue(st, s_dx);
1023daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdx == NULL) {
1024daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
1025daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1026daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1027daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      tex->lod_info.grad.dPdy = read_rvalue(st, s_dy);
1028daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdy == NULL) {
1029daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
1030daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1031dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
1032daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1033dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
1034daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   default:
1035daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      // tex doesn't have any extra parameters.
1036daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1037daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   };
1038dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   return tex;
1039dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke}
1040