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
2434350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "ir_reader.h"
2534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "glsl_parser_extras.h"
2634350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "glsl_types.h"
2734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke#include "s_expression.h"
2834350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
299a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunkeconst static bool debug = false;
309a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke
31b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeclass ir_reader {
32b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkepublic:
33b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_reader(_mesa_glsl_parse_state *);
34b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
35b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void read(exec_list *instructions, const char *src, bool scan_for_protos);
36b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
37b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeprivate:
38b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void *mem_ctx;
39b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   _mesa_glsl_parse_state *state;
40b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
41b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void ir_read_error(s_expression *, const char *fmt, ...);
42b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
43b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *read_type(s_expression *);
44b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
45b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void scan_for_prototypes(exec_list *, s_expression *);
46b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_function *read_function(s_expression *, bool skip_body);
47b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void read_function_sig(ir_function *, s_expression *, bool skip_body);
48b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
49b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   void read_instructions(exec_list *, s_expression *, ir_loop *);
50b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_instruction *read_instruction(s_expression *, ir_loop *);
51b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_variable *read_declaration(s_expression *);
52b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_if *read_if(s_expression *, ir_loop *);
53b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_loop *read_loop(s_expression *);
54d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   ir_call *read_call(s_expression *);
55b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_return *read_return(s_expression *);
56b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *read_rvalue(s_expression *);
57b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_assignment *read_assignment(s_expression *);
58b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_expression *read_expression(s_expression *);
59b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_swizzle *read_swizzle(s_expression *);
60b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_constant *read_constant(s_expression *);
61b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_texture *read_texture(s_expression *);
62b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
63b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *read_dereference(s_expression *);
64622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   ir_dereference_variable *read_var_ref(s_expression *);
65b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke};
66b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
67b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::ir_reader(_mesa_glsl_parse_state *state) : state(state)
68b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke{
69b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   this->mem_ctx = state;
70b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke}
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{
76b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_reader r(state);
77b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   r.read(instructions, src, scan_for_protos);
78b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke}
79b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
80b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
81b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
82b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke{
830d949a51bb44da51cd843abcf6ecddc5e3d3a2f1Kenneth Graunke   void *sx_mem_ctx = ralloc_context(NULL);
840d949a51bb44da51cd843abcf6ecddc5e3d3a2f1Kenneth Graunke   s_expression *expr = s_expression::read_expression(sx_mem_ctx, src);
8534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   if (expr == NULL) {
86b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "couldn't parse S-Expression.");
8734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke      return;
8834350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   }
8934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
9043ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (scan_for_protos) {
91b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      scan_for_prototypes(instructions, expr);
9243ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      if (state->error)
9343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke	 return;
9443ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   }
9509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
96b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(instructions, expr, NULL);
970d949a51bb44da51cd843abcf6ecddc5e3d3a2f1Kenneth Graunke   ralloc_free(sx_mem_ctx);
9879088746a231d361232fc87ab4d578b08c7ce2a7Kenneth Graunke
999a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke   if (debug)
1009a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke      validate_ir_tree(instructions);
10134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke}
10234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
103b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
104b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::ir_read_error(s_expression *expr, const char *fmt, ...)
105f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
106f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_list ap;
107f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
1084ec982fb86ae2476508d2027464241489243a170Kenneth Graunke   state->error = true;
109f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
110a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke   if (state->current_function != NULL)
111d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_asprintf_append(&state->info_log, "In function %s:\n",
112d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke			     state->current_function->function_name());
113d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_strcat(&state->info_log, "error: ");
114f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
115f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_start(ap, fmt);
116d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_vasprintf_append(&state->info_log, fmt, ap);
117f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_end(ap);
118d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_strcat(&state->info_log, "\n");
119f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
12046a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   if (expr != NULL) {
121d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_strcat(&state->info_log, "...in this context:\n   ");
12246a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      expr->print();
123d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_strcat(&state->info_log, "\n\n");
12446a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   }
125f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
126f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
127b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeconst glsl_type *
128b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_type(s_expression *expr)
129f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
130daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_base_type;
131daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *s_size;
132daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
133daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "array", s_base_type, s_size };
134daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(expr, pat)) {
135b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      const glsl_type *base_type = read_type(s_base_type);
136daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (base_type == NULL) {
137b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading base type of array type");
138f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
139f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
14057944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunke
141daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return glsl_type::get_array_instance(base_type, s_size->value());
142f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
143f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
144f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *type_sym = SX_AS_SYMBOL(expr);
145f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type_sym == NULL) {
146b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected <type>");
147f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
148f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
149f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
150b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = state->symbols->get_type(type_sym->value());
151f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
152b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid type: %s", type_sym->value());
153f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
154f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return type;
155f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
156f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
157d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
158b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
159b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
16009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
16109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
16209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (list == NULL) {
163b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
16409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      return;
16509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
16609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
16709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
16809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_list *sub = SX_AS_LIST(it.get());
16909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (sub == NULL)
17009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
17109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
17209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
17309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (tag == NULL || strcmp(tag->value(), "function") != 0)
17409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
17509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
176b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_function *f = read_function(sub, true);
1778df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      if (f == NULL)
17809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 return;
1798df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      instructions->push_tail(f);
18009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
18109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
18209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
183b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_function *
184b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_function(s_expression *expr, bool skip_body)
18509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
186e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   bool added = false;
187daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
18809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
189daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "function", name };
190e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
191b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (function <name> (signature ...) ...)");
1928df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      return NULL;
19309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
19409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
195b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_function *f = state->symbols->get_function(name->value());
1968df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   if (f == NULL) {
197b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      f = new(mem_ctx) ir_function(name->value());
198b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      added = state->symbols->add_function(f);
1998df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      assert(added);
20009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
20109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
202e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
20309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip "function" tag
20409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip function name
20509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (/* nothing */; it.has_next(); it.next()) {
206daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_sig = (s_expression *) it.get();
207b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      read_function_sig(f, s_sig, skip_body);
20809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
209e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   return added ? f : NULL;
21009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
21109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
212b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
213b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
21409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
215daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
216daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *paramlist;
217daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *body_list;
218daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
219daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "signature", type_expr, paramlist, body_list };
220daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (!MATCH(expr, pat)) {
221b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (signature <type> (parameters ...) "
222b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "(<instruction> ...))");
223b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
22509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
226b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *return_type = read_type(type_expr);
22709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (return_type == NULL)
228b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
23009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
23109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
232b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(paramlist, "Expected (parameters ...)");
233b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
23409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
23509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
236b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   // Read the parameters list into a temporary place.
237b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   exec_list hir_parameters;
238b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->push_scope();
2398df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
24009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   exec_list_iterator it = paramlist->subexpressions.iterator();
24109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
242b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_variable *var = read_declaration((s_expression *) it.get());
243b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (var == NULL)
244b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
245b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
246b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      hir_parameters.push_tail(var);
247b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
248b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
249b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
25043ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (sig == NULL && skip_body) {
25143ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* If scanning for prototypes, generate a new signature. */
252b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      sig = new(mem_ctx) ir_function_signature(return_type);
253f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke      sig->is_builtin = true;
25443ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      f->add_signature(sig);
25543ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   } else if (sig != NULL) {
256b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      const char *badvar = sig->qualifiers_match(&hir_parameters);
257b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (badvar != NULL) {
258b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function `%s' parameter `%s' qualifiers "
259b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "don't match prototype", f->name, badvar);
260b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
26109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      }
26209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
263b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->return_type != return_type) {
264b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function `%s' return type doesn't "
265b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "match prototype", f->name);
266b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
267b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
268b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   } else {
26943ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* No prototype for this body exists - skip it. */
270b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->symbols->pop_scope();
27143ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      return;
27209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
27343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   assert(sig != NULL);
27409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
275b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   sig->replace_parameters(&hir_parameters);
276b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
277d802ba110f78c3eee9541867cde819ada1b2c449Kenneth Graunke   if (!skip_body && !body_list->subexpressions.is_empty()) {
278b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->is_defined) {
279b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function %s redefined", f->name);
280b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
281b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
282b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->current_function = sig;
283b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      read_instructions(&sig->body, body_list, NULL);
284b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->current_function = NULL;
285f6c90d8b3484864cd7f3abf895746e0655929a13Kenneth Graunke      sig->is_defined = true;
286b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
2878df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
288b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->pop_scope();
28909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
29009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
291b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
292b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_instructions(exec_list *instructions, s_expression *expr,
293b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			     ir_loop *loop_ctx)
2943ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
2953ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   // Read in a list of instructions
2963ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
2973ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (list == NULL) {
298b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
2993ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return;
3003ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
3013ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3023ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
3033ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      s_expression *sub = (s_expression*) it.get();
304b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_instruction *ir = read_instruction(sub, loop_ctx);
3052809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      if (ir != NULL) {
3062809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 /* Global variable declarations should be moved to the top, before
3072809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * any functions that might use them.  Functions are added to the
3082809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * instruction stream when scanning for prototypes, so without this
3092809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * hack, they always appear before variable declarations.
3102809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  */
311b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 if (state->current_function == NULL && ir->as_variable() != NULL)
3122809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_head(ir);
3132809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 else
3142809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_tail(ir);
3152809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      }
3163ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
3173ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
3183ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3193ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
320b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_instruction *
321b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
322d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
323396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   s_symbol *symbol = SX_AS_SYMBOL(expr);
324396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   if (symbol != NULL) {
325396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
326b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
327396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
328b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
329396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   }
330396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke
331d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
332e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty()) {
333b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Invalid instruction.\n");
334d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
335e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   }
336d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
337d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
338d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (tag == NULL) {
339b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected instruction tag");
340d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
341d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
342d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
343d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   ir_instruction *inst = NULL;
34446ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   if (strcmp(tag->value(), "declare") == 0) {
345b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_declaration(list);
3463c033637de7def553559c11d037f2e8bbb750f77Kenneth Graunke   } else if (strcmp(tag->value(), "assign") == 0) {
347b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_assignment(list);
34846ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "if") == 0) {
349b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_if(list, loop_ctx);
35032b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   } else if (strcmp(tag->value(), "loop") == 0) {
351b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_loop(list);
352d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   } else if (strcmp(tag->value(), "call") == 0) {
353d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      inst = read_call(list);
35446ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "return") == 0) {
355b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_return(list);
3568df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   } else if (strcmp(tag->value(), "function") == 0) {
357b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_function(list, false);
35846ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else {
359b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_rvalue(list);
36046ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke      if (inst == NULL)
361b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading instruction");
36246ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   }
363d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return inst;
364d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
365d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
366b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_variable *
367b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_declaration(s_expression *expr)
368d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
369daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_quals;
370daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
371daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_name;
372daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
373daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
374e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
375b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (declare (<qualifiers>) <type> <name>)");
376d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
377d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
378d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
379b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(s_type);
380d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (type == NULL)
381d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
382d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
383b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
384b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke					       ir_var_auto);
385d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
386daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
387d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      s_symbol *qualifier = SX_AS_SYMBOL(it.get());
388d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (qualifier == NULL) {
389b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "qualifier list must contain only symbols");
390d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
391d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
392d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
393d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      // FINISHME: Check for duplicate/conflicting qualifiers.
394d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (strcmp(qualifier->value(), "centroid") == 0) {
395d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->centroid = 1;
396d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "invariant") == 0) {
397d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->invariant = 1;
398d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "uniform") == 0) {
399d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_uniform;
400d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "auto") == 0) {
401d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_auto;
402d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "in") == 0) {
403d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_in;
404819d57fce94b20fa0d34da6f037f0a53c4a5bdc2Kenneth Graunke      } else if (strcmp(qualifier->value(), "const_in") == 0) {
405819d57fce94b20fa0d34da6f037f0a53c4a5bdc2Kenneth Graunke	 var->mode = ir_var_const_in;
406d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "out") == 0) {
407d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_out;
408d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "inout") == 0) {
409d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_inout;
41041b47441d720957d7b8a63afa26d94c752c8740bEric Anholt      } else if (strcmp(qualifier->value(), "temporary") == 0) {
41141b47441d720957d7b8a63afa26d94c752c8740bEric Anholt	 var->mode = ir_var_temporary;
412d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "smooth") == 0) {
413cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry	 var->interpolation = INTERP_QUALIFIER_SMOOTH;
414d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "flat") == 0) {
415cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry	 var->interpolation = INTERP_QUALIFIER_FLAT;
416d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "noperspective") == 0) {
417cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry	 var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
418d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else {
419b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "unknown qualifier: %s", qualifier->value());
420d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
421d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
422d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
423d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
424d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   // Add the variable to the symbol table
425b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->add_variable(var);
426d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
427d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return var;
428d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
429d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
430d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
431b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_if *
432b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_if(s_expression *expr, ir_loop *loop_ctx)
4333ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
434daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_cond;
435daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_then;
436daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_else;
437daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
438daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "if", s_cond, s_then, s_else };
439e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
440b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (if <condition> (<then>...) (<else>...))");
4413ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4423ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4433ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
444b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *condition = read_rvalue(s_cond);
4453ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (condition == NULL) {
446b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading condition of (if ...)");
4473ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4483ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4493ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
450b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_if *iff = new(mem_ctx) ir_if(condition);
4513ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
452b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&iff->then_instructions, s_then, loop_ctx);
453b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&iff->else_instructions, s_else, loop_ctx);
454b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (state->error) {
4553ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      delete iff;
4563ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      iff = NULL;
4573ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4583ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   return iff;
4593ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
4603ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
4613ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
462b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_loop *
463b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_loop(s_expression *expr)
46432b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke{
465daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
466daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
467daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
468e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
469b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (loop <counter> <from> <to> "
470b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<increment> <body>)");
47132b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      return NULL;
47232b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
47332b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
47432b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   // FINISHME: actually read the count/from/to fields.
47532b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
476b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_loop *loop = new(mem_ctx) ir_loop;
477b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&loop->body_instructions, s_body, loop);
478b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (state->error) {
47932b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      delete loop;
48032b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      loop = NULL;
48132b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
48232b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   return loop;
48332b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke}
48432b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
48532b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
486b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_return *
487b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_return(s_expression *expr)
4889d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke{
489e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   s_expression *s_retval;
490daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
491f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry   s_pattern return_value_pat[] = { "return", s_retval};
492f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry   s_pattern return_void_pat[] = { "return" };
493f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry   if (MATCH(expr, return_value_pat)) {
494f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      ir_rvalue *retval = read_rvalue(s_retval);
495f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      if (retval == NULL) {
496f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry         ir_read_error(NULL, "when reading return value");
497f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry         return NULL;
498f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      }
499f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      return new(mem_ctx) ir_return(retval);
500f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry   } else if (MATCH(expr, return_void_pat)) {
501f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      return new(mem_ctx) ir_return;
502f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry   } else {
503f4830be938c8fa33086f73cab19a53ab3e14cb9cPaul Berry      ir_read_error(expr, "expected (return <rvalue>) or (return)");
5049d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      return NULL;
5059d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   }
5069d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke}
5079d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
5089d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
509b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_rvalue *
510b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_rvalue(s_expression *expr)
511f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
512f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
513f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty())
514f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
515f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
516f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
517f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (tag == NULL) {
518b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected rvalue tag");
519f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
520f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
521f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
522b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rvalue = read_dereference(list);
523b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (rvalue != NULL || state->error)
5243c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return rvalue;
5253c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   else if (strcmp(tag->value(), "swiz") == 0) {
526b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_swizzle(list);
527451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "expression") == 0) {
528b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_expression(list);
529451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "constant") == 0) {
530b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_constant(list);
531451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else {
532b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_texture(list);
533b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      if (rvalue == NULL && !state->error)
534b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value());
535451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   }
536f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
537f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return rvalue;
538f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
539f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
540b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_assignment *
541b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_assignment(s_expression *expr)
542f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
543bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_expression *cond_expr = NULL;
544bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_expression *lhs_expr, *rhs_expr;
545daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list       *mask_list;
546daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
547bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_pattern pat4[] = { "assign",            mask_list, lhs_expr, rhs_expr };
548bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_pattern pat5[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr };
549bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   if (!MATCH(expr, pat4) && !MATCH(expr, pat5)) {
550bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      ir_read_error(expr, "expected (assign [<condition>] (<write mask>) "
551b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<lhs> <rhs>)");
552f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
553f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
554f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
555bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   ir_rvalue *condition = NULL;
556bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   if (cond_expr != NULL) {
557bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      condition = read_rvalue(cond_expr);
558bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      if (condition == NULL) {
559bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke	 ir_read_error(NULL, "when reading condition of assignment");
560bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke	 return NULL;
561bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      }
562f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
563f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
56403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   unsigned mask = 0;
56503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
566daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *mask_symbol;
567daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern mask_pat[] = { mask_symbol };
568daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(mask_list, mask_pat)) {
56903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const char *mask_str = mask_symbol->value();
57003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      unsigned mask_length = strlen(mask_str);
57103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      if (mask_length > 4) {
572b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "invalid write mask: %s", mask_str);
57303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 return NULL;
57403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
57503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
57603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
57703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
57803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      for (unsigned i = 0; i < mask_length; i++) {
57903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
580b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(expr, "write mask contains invalid character: %c",
58103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke			  mask_str[i]);
58203a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	    return NULL;
58303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 }
58403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 mask |= 1 << idx_map[mask_str[i] - 'w'];
58503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
586daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   } else if (!mask_list->subexpressions.is_empty()) {
587b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(mask_list, "expected () or (<write mask>)");
588daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
58903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
59003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
591b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *lhs = read_dereference(lhs_expr);
592f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (lhs == NULL) {
593b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading left-hand side of assignment");
594f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
595f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
596f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
597b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rhs = read_rvalue(rhs_expr);
598f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rhs == NULL) {
599b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading right-hand side of assignment");
600f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
601f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
602f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
60303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
604b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "non-zero write mask required.");
60503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      return NULL;
60603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
60703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
608b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_assignment(lhs, rhs, condition, mask);
609f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
610f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
611b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_call *
612b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_call(s_expression *expr)
613b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke{
614daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
615daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *params;
616d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   s_list *s_return = NULL;
617b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
618d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   ir_dereference_variable *return_deref = NULL;
619d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke
620d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   s_pattern void_pat[] = { "call", name, params };
621d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   s_pattern non_void_pat[] = { "call", name, s_return, params };
622d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   if (MATCH(expr, non_void_pat)) {
623d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      return_deref = read_var_ref(s_return);
624d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      if (return_deref == NULL) {
625d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke	 ir_read_error(s_return, "when reading a call's return storage");
626d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke	 return NULL;
627d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      }
628d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   } else if (!MATCH(expr, void_pat)) {
629d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      ir_read_error(expr, "expected (call <name> [<deref>] (<param> ...))");
630b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
631b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
632b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
633b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   exec_list parameters;
634b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
635b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   foreach_iter(exec_list_iterator, it, params->subexpressions) {
636b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
637b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *param = read_rvalue(expr);
638b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      if (param == NULL) {
639b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "when reading parameter to function call");
640b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke	 return NULL;
641b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      }
642b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      parameters.push_tail(param);
643b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
644b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
645b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_function *f = state->symbols->get_function(name->value());
646b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (f == NULL) {
647b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "found call to undefined function %s",
648b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke		    name->value());
649b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
650b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
651b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
6521f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt   ir_function_signature *callee = f->matching_signature(&parameters);
653b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (callee == NULL) {
654b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "couldn't find matching signature for function "
655b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke                    "%s", name->value());
656b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
657b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
658b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
659d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   if (callee->return_type == glsl_type::void_type && return_deref) {
660d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      ir_read_error(expr, "call has return value storage but void type");
661d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      return NULL;
662d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   } else if (callee->return_type != glsl_type::void_type && !return_deref) {
663d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      ir_read_error(expr, "call has non-void type but no return value storage");
664d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke      return NULL;
665d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   }
666d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke
667d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke   return new(mem_ctx) ir_call(callee, return_deref, &parameters);
668b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke}
669f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
670b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_expression *
671b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_expression(s_expression *expr)
672f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
673daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
674daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_op;
675daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg1;
676daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
677daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
678e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
679b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (expression <type> <operator> "
680b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<operand> [<operand>])");
681f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
682f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
683daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
684f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
685b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(s_type);
686f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
687f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
688f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
689f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   /* Read the operator */
690daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_expression_operation op = ir_expression::get_operator(s_op->value());
691f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (op == (ir_expression_operation) -1) {
692b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid operator: %s", s_op->value());
693f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
694f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
695f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
696daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   unsigned num_operands = ir_expression::get_num_operands(op);
697daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
698b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (expression <type> %s <operand>)",
699daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    s_op->value());
700daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
701f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
702f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
703b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *arg1 = read_rvalue(s_arg1);
704daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_rvalue *arg2 = NULL;
705f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (arg1 == NULL) {
706b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading first operand of %s", s_op->value());
707f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
708f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
709f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
710daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (num_operands == 2) {
711daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) {
712b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "expected (expression <type> %s <operand> "
713b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			     "<operand>)", s_op->value());
714daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
715daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
716b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      arg2 = read_rvalue(s_arg2);
717f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (arg2 == NULL) {
718b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading second operand of %s",
719daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       s_op->value());
720f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
721f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
722f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
723f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
724b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_expression(op, type, arg1, arg2);
725f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
726f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
727b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_swizzle *
728b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_swizzle(s_expression *expr)
729f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
730daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *swiz;
731daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *sub;
732f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
733daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "swiz", swiz, sub };
734e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
735b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (swiz <swizzle> <rvalue>)");
736f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
737f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
738f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
739951632253f4f37ce058e2466bca5b96bb43ccfbfKenneth Graunke   if (strlen(swiz->value()) > 4) {
740b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected a valid swizzle; found %s", swiz->value());
741f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
742f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
743f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
744b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rvalue = read_rvalue(sub);
745f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rvalue == NULL)
746f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
747f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
748bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
749bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke				       rvalue->type->vector_elements);
750bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   if (ir == NULL)
751b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid swizzle");
752bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke
753bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   return ir;
754f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
755f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
756b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_constant *
757b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_constant(s_expression *expr)
758f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
759daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
760daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *values;
761daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
762daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "constant", type_expr, values };
763e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
764b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (constant <type> (...))");
765f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
766f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
767f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
768b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(type_expr);
769f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
770f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
771f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
772f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (values == NULL) {
773b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (constant <type> (...))");
774f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
775f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
776f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
777ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   if (type->is_array()) {
778d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      unsigned elements_supplied = 0;
779ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      exec_list elements;
780ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      foreach_iter(exec_list_iterator, it, values->subexpressions) {
781e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 s_expression *elt = (s_expression *) it.get();
782b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_constant *ir_elt = read_constant(elt);
783ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 if (ir_elt == NULL)
784ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	    return NULL;
785ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 elements.push_tail(ir_elt);
786d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 elements_supplied++;
787d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      }
788d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke
789d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      if (elements_supplied != type->length) {
790b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(values, "expected exactly %u array elements, "
791d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke		       "given %u", type->length, elements_supplied);
792d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 return NULL;
793ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      }
794b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_constant(type, &elements);
795ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   }
796ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke
797b43611b79c1f0a5caff80c17c9e7840a718f07c9Vinson Lee   ir_constant_data data = { { 0 } };
798f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
799f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   // Read in list of values (at most 16).
800c0470bf77a038fd45441d1e55e6c89100996ff4bBrian Paul   unsigned k = 0;
801f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   foreach_iter(exec_list_iterator, it, values->subexpressions) {
802f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (k >= 16) {
803b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(values, "expected at most 16 numbers");
804f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
805f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
806f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
807f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
808f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
8093b4d2eac6001b464df11b175bd14fd4d3c4e412fKenneth Graunke      if (type->base_type == GLSL_TYPE_FLOAT) {
810f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_number *value = SX_AS_NUMBER(expr);
811f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
812b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "expected numbers");
813f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
814f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
8154976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	 data.f[k] = value->fvalue();
816f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      } else {
817f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_int *value = SX_AS_INT(expr);
818f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
819b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "expected integers");
820f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
821f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
822f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
8233b4d2eac6001b464df11b175bd14fd4d3c4e412fKenneth Graunke	 switch (type->base_type) {
824f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_UINT: {
8254976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.u[k] = value->value();
826f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
827f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
828f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_INT: {
8294976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.i[k] = value->value();
830f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
831f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
832f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_BOOL: {
8334976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.b[k] = value->value();
834f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
835f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
836f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 default:
837b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "unsupported constant type");
838f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
839f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
840f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
841f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      ++k;
842f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
8438ceb235c9cbb9504e32479db54287ed9387df75aKenneth Graunke   if (k != type->components()) {
844c0470bf77a038fd45441d1e55e6c89100996ff4bBrian Paul      ir_read_error(values, "expected %u constant values, found %u",
8458ceb235c9cbb9504e32479db54287ed9387df75aKenneth Graunke		    type->components(), k);
8468ceb235c9cbb9504e32479db54287ed9387df75aKenneth Graunke      return NULL;
8478ceb235c9cbb9504e32479db54287ed9387df75aKenneth Graunke   }
8484976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick
849b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_constant(type, &data);
850f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
851451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
852622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunkeir_dereference_variable *
853622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunkeir_reader::read_var_ref(s_expression *expr)
8543c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke{
855ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_symbol *s_var;
856ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_pattern var_pat[] = { "var_ref", s_var };
857ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke
858ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   if (MATCH(expr, var_pat)) {
859b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_variable *var = state->symbols->get_variable(s_var->value());
860ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (var == NULL) {
861b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "undeclared variable: %s", s_var->value());
862ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
863ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
864b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_variable(var);
865622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   }
866622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   return NULL;
867622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke}
868622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke
869622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunkeir_dereference *
870622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunkeir_reader::read_dereference(s_expression *expr)
871622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke{
872622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   s_expression *s_subject;
873622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   s_expression *s_index;
874622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   s_symbol *s_field;
875622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke
876622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   s_pattern array_pat[] = { "array_ref", s_subject, s_index };
877622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   s_pattern record_pat[] = { "record_ref", s_subject, s_field };
878622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke
879622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   ir_dereference_variable *var_ref = read_var_ref(expr);
880622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke   if (var_ref != NULL) {
881622eed075092a0325e0927bf2f9ef29f20bbf416Kenneth Graunke      return var_ref;
882ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   } else if (MATCH(expr, array_pat)) {
883b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *subject = read_rvalue(s_subject);
884ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
885b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the subject of an array_ref");
886ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
887ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
88813e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke
889b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *idx = read_rvalue(s_index);
890ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
891b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the index of an array_ref");
892ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
893ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
894b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_array(subject, idx);
895ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   } else if (MATCH(expr, record_pat)) {
896b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *subject = read_rvalue(s_subject);
897ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
898b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the subject of a record_ref");
899ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
900ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
901b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_record(subject, s_field->value());
90213e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   }
903ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   return NULL;
904451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke}
905dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
906b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_texture *
907b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_texture(s_expression *expr)
908dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke{
909daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *tag = NULL;
910233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   s_expression *s_type = NULL;
911daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_sampler = NULL;
912daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_coord = NULL;
913c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke   s_expression *s_offset = NULL;
914daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_proj = NULL;
915daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_shadow = NULL;
916daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_lod = NULL;
917daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
9189f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   ir_texture_opcode op = ir_tex; /* silence warning */
919daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
920daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern tex_pattern[] =
921233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
922daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern txf_pattern[] =
923233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
9241e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   s_pattern txs_pattern[] =
9251e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      { "txs", s_type, s_sampler, s_lod };
926daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern other_pattern[] =
927233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
928daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
929e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (MATCH(expr, tex_pattern)) {
930daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_tex;
931e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, txf_pattern)) {
932daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_txf;
9331e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   } else if (MATCH(expr, txs_pattern)) {
9341e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      op = ir_txs;
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;
9399f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   } else {
9409f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      ir_read_error(NULL, "unexpected texture pattern");
9419f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      return NULL;
942dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
943dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
944b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_texture *tex = new(mem_ctx) ir_texture(op);
945dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
946233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   // Read return type
947233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   const glsl_type *type = read_type(s_type);
948233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   if (type == NULL) {
949233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      ir_read_error(NULL, "when reading type in (%s ...)",
950233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke		    tex->opcode_string());
951233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      return NULL;
952233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   }
953233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke
954dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read sampler (must be a deref)
955b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *sampler = read_dereference(s_sampler);
95656d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   if (sampler == NULL) {
957b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading sampler in (%s ...)",
958daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
959dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
960dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
961233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   tex->set_sampler(sampler, type);
962dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
9631e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   if (op != ir_txs) {
9641e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      // Read coordinate (any rvalue)
9651e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      tex->coordinate = read_rvalue(s_coord);
9661e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      if (tex->coordinate == NULL) {
9671e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	 ir_read_error(NULL, "when reading coordinate in (%s ...)",
9681e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke		       tex->opcode_string());
969c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke	 return NULL;
970c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke      }
9711e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke
9721e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      // Read texel offset - either 0 or an rvalue.
9731e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      s_int *si_offset = SX_AS_INT(s_offset);
9741e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      if (si_offset == NULL || si_offset->value() != 0) {
9751e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	 tex->offset = read_rvalue(s_offset);
9761e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	 if (tex->offset == NULL) {
9771e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	    ir_read_error(s_offset, "expected 0 or an expression");
9781e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	    return NULL;
9791e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke	 }
9801e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke      }
981dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
982dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
9831e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   if (op != ir_txf && op != ir_txs) {
984daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_int *proj_as_int = SX_AS_INT(s_proj);
985dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      if (proj_as_int && proj_as_int->value() == 1) {
986dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 tex->projector = NULL;
987dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
988b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->projector = read_rvalue(s_proj);
989dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->projector == NULL) {
990b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading projective divide in (%s ..)",
991daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	                  tex->opcode_string());
992dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
993dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
994dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
995dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
996daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_shadow->subexpressions.is_empty()) {
997daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->shadow_comparitor = NULL;
998dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
999b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->shadow_comparitor = read_rvalue(s_shadow);
1000dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->shadow_comparitor == NULL) {
1001b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading shadow comparitor in (%s ..)",
1002daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			  tex->opcode_string());
1003dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
1004dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
1005dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
1006daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   }
1007dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
1008daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   switch (op) {
1009daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txb:
1010b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.bias = read_rvalue(s_lod);
1011daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.bias == NULL) {
1012b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD bias in (txb ...)");
1013daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1014daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1015daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1016daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txl:
1017daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txf:
10181e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
1019b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.lod = read_rvalue(s_lod);
1020daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.lod == NULL) {
1021b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD in (%s ...)",
1022daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       tex->opcode_string());
1023daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1024daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1025daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1026daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txd: {
1027daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_dx, *s_dy;
1028daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_pattern dxdy_pat[] = { s_dx, s_dy };
1029daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (!MATCH(s_lod, dxdy_pat)) {
1030b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(s_lod, "expected (dPdx dPdy) in (txd ...)");
1031daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1032daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1033b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdx = read_rvalue(s_dx);
1034daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdx == NULL) {
1035b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdx in (txd ...)");
1036daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1037daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
1038b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdy = read_rvalue(s_dy);
1039daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdy == NULL) {
1040b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdy in (txd ...)");
1041daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
1042dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
1043daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1044dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
1045daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   default:
1046daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      // tex doesn't have any extra parameters.
1047daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1048daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   };
1049dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   return tex;
1050dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke}
1051