ir_reader.cpp revision 9f2bf3d65cf0745a34185c1966d52389fbd1ca90
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 *);
54b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_return *read_return(s_expression *);
55b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *read_rvalue(s_expression *);
56b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_assignment *read_assignment(s_expression *);
57b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_expression *read_expression(s_expression *);
58b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_call *read_call(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 *);
64b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke};
65b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
66b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::ir_reader(_mesa_glsl_parse_state *state) : state(state)
67b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke{
68b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   this->mem_ctx = state;
69b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke}
70f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
7134350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunkevoid
7234350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
7343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke		   const char *src, bool scan_for_protos)
7434350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke{
75b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_reader r(state);
76b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   r.read(instructions, src, scan_for_protos);
77b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke}
78b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke
79b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
80b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
81b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke{
82b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   s_expression *expr = s_expression::read_expression(mem_ctx, src);
8334350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   if (expr == NULL) {
84b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "couldn't parse S-Expression.");
8534350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke      return;
8634350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke   }
8734350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
8843ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (scan_for_protos) {
89b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      scan_for_prototypes(instructions, expr);
9043ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      if (state->error)
9143ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke	 return;
9243ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   }
9309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
94b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(instructions, expr, NULL);
9578062273de65bf8133f2550aa2a26040a82a65aaKenneth Graunke   talloc_free(expr);
9679088746a231d361232fc87ab4d578b08c7ce2a7Kenneth Graunke
979a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke   if (debug)
989a3df46fbcfbad10163686ae4c034a3a55116947Kenneth Graunke      validate_ir_tree(instructions);
9934350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke}
10034350be2cdb0cb769657d5ce82bc37d906eb3eb5Kenneth Graunke
101b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
102b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::ir_read_error(s_expression *expr, const char *fmt, ...)
103f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
104f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_list ap;
105f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
1064ec982fb86ae2476508d2027464241489243a170Kenneth Graunke   state->error = true;
107f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
108a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke   if (state->current_function != NULL)
109a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke      state->info_log = talloc_asprintf_append(state->info_log,
110a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke			   "In function %s:\n",
111a71b46a8ad344a86de2b13fe0c283ac2036c5f76Kenneth Graunke			   state->current_function->function_name());
112b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_strdup_append(state->info_log, "error: ");
113f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
114f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_start(ap, fmt);
115b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
116f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_end(ap);
117b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke   state->info_log = talloc_strdup_append(state->info_log, "\n");
118f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
11946a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   if (expr != NULL) {
120b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke      state->info_log = talloc_strdup_append(state->info_log,
121b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke					     "...in this context:\n   ");
12246a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      expr->print();
123b2ba6fac09df1f06161a7ea1ef1f25bb9fbe8a5aKenneth Graunke      state->info_log = talloc_strdup_append(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);
35246ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "return") == 0) {
353b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_return(list);
3548df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   } else if (strcmp(tag->value(), "function") == 0) {
355b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_function(list, false);
35646ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else {
357b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_rvalue(list);
35846ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke      if (inst == NULL)
359b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading instruction");
36046ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   }
361d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return inst;
362d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
363d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
364b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_variable *
365b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_declaration(s_expression *expr)
366d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
367daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_quals;
368daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
369daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_name;
370daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
371daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
372e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
373b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (declare (<qualifiers>) <type> <name>)");
374d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
375d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
376d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
377b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(s_type);
378d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (type == NULL)
379d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
380d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
381b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
382b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke					       ir_var_auto);
383d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
384daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
385d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      s_symbol *qualifier = SX_AS_SYMBOL(it.get());
386d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (qualifier == NULL) {
387b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "qualifier list must contain only symbols");
388d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
389d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
390d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
391d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      // FINISHME: Check for duplicate/conflicting qualifiers.
392d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (strcmp(qualifier->value(), "centroid") == 0) {
393d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->centroid = 1;
394d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "invariant") == 0) {
395d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->invariant = 1;
396d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "uniform") == 0) {
397d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_uniform;
398d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "auto") == 0) {
399d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_auto;
400d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "in") == 0) {
401d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_in;
402d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "out") == 0) {
403d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_out;
404d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "inout") == 0) {
405d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_inout;
406d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "smooth") == 0) {
407d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_smooth;
408d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "flat") == 0) {
409d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_flat;
410d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "noperspective") == 0) {
411d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->interpolation = ir_var_noperspective;
412d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else {
413b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "unknown qualifier: %s", qualifier->value());
414d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
415d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
416d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
417d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
418d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   // Add the variable to the symbol table
419b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->add_variable(var);
420d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
421d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return var;
422d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
423d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
424d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
425b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_if *
426b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_if(s_expression *expr, ir_loop *loop_ctx)
4273ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
428daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_cond;
429daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_then;
430daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_else;
431daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
432daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "if", s_cond, s_then, s_else };
433e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
434b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (if <condition> (<then>...) (<else>...))");
4353ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4363ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4373ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
438b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *condition = read_rvalue(s_cond);
4393ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (condition == NULL) {
440b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading condition of (if ...)");
4413ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return NULL;
4423ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4433ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
444b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_if *iff = new(mem_ctx) ir_if(condition);
4453ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
446b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&iff->then_instructions, s_then, loop_ctx);
447b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&iff->else_instructions, s_else, loop_ctx);
448b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (state->error) {
4493ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      delete iff;
4503ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      iff = NULL;
4513ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
4523ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   return iff;
4533ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
4543ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
4553ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
456b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_loop *
457b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_loop(s_expression *expr)
45832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke{
459daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
460daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
461daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
462e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
463b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (loop <counter> <from> <to> "
464b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<increment> <body>)");
46532b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      return NULL;
46632b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
46732b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
46832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   // FINISHME: actually read the count/from/to fields.
46932b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
470b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_loop *loop = new(mem_ctx) ir_loop;
471b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   read_instructions(&loop->body_instructions, s_body, loop);
472b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (state->error) {
47332b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      delete loop;
47432b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke      loop = NULL;
47532b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   }
47632b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   return loop;
47732b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke}
47832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
47932b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke
480b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_return *
481b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_return(s_expression *expr)
4829d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke{
483e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   s_expression *s_retval;
484daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
485e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   s_pattern pat[] = { "return", s_retval};
486e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
487b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (return <rvalue>)");
4889d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      return NULL;
4899d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   }
4909d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
491b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *retval = read_rvalue(s_retval);
4929d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   if (retval == NULL) {
493b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading return value");
4949d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke      return NULL;
4959d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke   }
4969d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
497b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_return(retval);
4989d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke}
4999d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
5009d2ff7617a08fa1dc26c7661e813b0d6cb8acc2bKenneth Graunke
501b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_rvalue *
502b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_rvalue(s_expression *expr)
503f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
504f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
505f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty())
506f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
507f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
508f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
509f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (tag == NULL) {
510b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected rvalue tag");
511f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
512f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
513f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
514b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rvalue = read_dereference(list);
515b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   if (rvalue != NULL || state->error)
5163c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke      return rvalue;
5173c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke   else if (strcmp(tag->value(), "swiz") == 0) {
518b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_swizzle(list);
519451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "expression") == 0) {
520b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_expression(list);
521b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   } else if (strcmp(tag->value(), "call") == 0) {
522b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_call(list);
523451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else if (strcmp(tag->value(), "constant") == 0) {
524b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_constant(list);
525451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   } else {
526b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      rvalue = read_texture(list);
527b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      if (rvalue == NULL && !state->error)
528b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value());
529451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke   }
530f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
531f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return rvalue;
532f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
533f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
534b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_assignment *
535b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_assignment(s_expression *expr)
536f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
537bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_expression *cond_expr = NULL;
538bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_expression *lhs_expr, *rhs_expr;
539daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list       *mask_list;
540daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
541bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_pattern pat4[] = { "assign",            mask_list, lhs_expr, rhs_expr };
542bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   s_pattern pat5[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr };
543bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   if (!MATCH(expr, pat4) && !MATCH(expr, pat5)) {
544bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      ir_read_error(expr, "expected (assign [<condition>] (<write mask>) "
545b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<lhs> <rhs>)");
546f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
547f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
548f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
549bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   ir_rvalue *condition = NULL;
550bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke   if (cond_expr != NULL) {
551bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      condition = read_rvalue(cond_expr);
552bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      if (condition == NULL) {
553bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke	 ir_read_error(NULL, "when reading condition of assignment");
554bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke	 return NULL;
555bbafd2b849629d3155fe0eef655bbc166a901925Kenneth Graunke      }
556f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
557f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
55803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   unsigned mask = 0;
55903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
560daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *mask_symbol;
561daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern mask_pat[] = { mask_symbol };
562daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(mask_list, mask_pat)) {
56303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const char *mask_str = mask_symbol->value();
56403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      unsigned mask_length = strlen(mask_str);
56503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      if (mask_length > 4) {
566b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "invalid write mask: %s", mask_str);
56703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 return NULL;
56803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
56903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
57003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
57103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
57203a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      for (unsigned i = 0; i < mask_length; i++) {
57303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
574b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(expr, "write mask contains invalid character: %c",
57503a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke			  mask_str[i]);
57603a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	    return NULL;
57703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 }
57803a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke	 mask |= 1 << idx_map[mask_str[i] - 'w'];
57903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      }
580daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   } else if (!mask_list->subexpressions.is_empty()) {
581b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(mask_list, "expected () or (<write mask>)");
582daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
58303a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
58403a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
585b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *lhs = read_dereference(lhs_expr);
586f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (lhs == NULL) {
587b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading left-hand side of assignment");
588f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
589f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
590f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
591b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rhs = read_rvalue(rhs_expr);
592f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rhs == NULL) {
593b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading right-hand side of assignment");
594f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
595f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
596f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
59703a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
598b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "non-zero write mask required.");
59903a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke      return NULL;
60003a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke   }
60103a6276477702404f5c7a4f5f2fbb713371c7eedKenneth Graunke
602b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_assignment(lhs, rhs, condition, mask);
603f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
604f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
605b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_call *
606b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_call(s_expression *expr)
607b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke{
608daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
609daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *params;
610b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
611daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "call", name, params };
612e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
613b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (call <name> (<param> ...))");
614b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
615b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
616b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
617b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   exec_list parameters;
618b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
619b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   foreach_iter(exec_list_iterator, it, params->subexpressions) {
620b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
621b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *param = read_rvalue(expr);
622b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      if (param == NULL) {
623b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "when reading parameter to function call");
624b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke	 return NULL;
625b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      }
626b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      parameters.push_tail(param);
627b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
628b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
629b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_function *f = state->symbols->get_function(name->value());
630b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (f == NULL) {
631b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "found call to undefined function %s",
632b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke		    name->value());
633b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
634b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
635b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
6361f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt   ir_function_signature *callee = f->matching_signature(&parameters);
637b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   if (callee == NULL) {
638b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "couldn't find matching signature for function "
639b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke                    "%s", name->value());
640b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke      return NULL;
641b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke   }
642b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke
643b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_call(callee, &parameters);
644b51557fbe2b3543cb2e2ed5a3a3637964ca81e17Kenneth Graunke}
645f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
646b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_expression *
647b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_expression(s_expression *expr)
648f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
649daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
650daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_op;
651daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg1;
652daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
653daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
654e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
655b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (expression <type> <operator> "
656b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "<operand> [<operand>])");
657f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
658f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
659daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
660f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
661b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(s_type);
662f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
663f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
664f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
665f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   /* Read the operator */
666daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_expression_operation op = ir_expression::get_operator(s_op->value());
667f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (op == (ir_expression_operation) -1) {
668b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid operator: %s", s_op->value());
669f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
670f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
671f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
672daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   unsigned num_operands = ir_expression::get_num_operands(op);
673daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
674b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (expression <type> %s <operand>)",
675daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    s_op->value());
676daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return NULL;
677f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
678f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
679b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *arg1 = read_rvalue(s_arg1);
680daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   ir_rvalue *arg2 = NULL;
681f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (arg1 == NULL) {
682b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading first operand of %s", 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()) {
688b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "expected (expression <type> %s <operand> "
689b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			     "<operand>)", s_op->value());
690daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
691daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
692b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      arg2 = read_rvalue(s_arg2);
693f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (arg2 == NULL) {
694b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading second operand of %s",
695daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       s_op->value());
696f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
697f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
698f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
699f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
700b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_expression(op, type, arg1, arg2);
701f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
702f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
703b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_swizzle *
704b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_swizzle(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)) {
711b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (swiz <swizzle> <rvalue>)");
712f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
713f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
714f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
715951632253f4f37ce058e2466bca5b96bb43ccfbfKenneth Graunke   if (strlen(swiz->value()) > 4) {
716b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected a valid swizzle; found %s", swiz->value());
717f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
718f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
719f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
720b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_rvalue *rvalue = read_rvalue(sub);
721f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (rvalue == NULL)
722f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
723f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
724bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
725bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke				       rvalue->type->vector_elements);
726bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   if (ir == NULL)
727b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid swizzle");
728bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke
729bf783ecea69c6b4a3fb5f616e91707cf6d806040Kenneth Graunke   return ir;
730f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
731f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
732b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_constant *
733b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_constant(s_expression *expr)
734f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
735daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
736daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *values;
737daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
738daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "constant", type_expr, values };
739e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
740b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (constant <type> (...))");
741f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
742f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
743f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
744b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(type_expr);
745f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
746f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
747f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
748f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (values == NULL) {
749b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (constant <type> (...))");
750f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
751f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
752f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
753ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   if (type->is_array()) {
754d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      unsigned elements_supplied = 0;
755ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      exec_list elements;
756ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      foreach_iter(exec_list_iterator, it, values->subexpressions) {
757e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke	 s_expression *elt = (s_expression *) it.get();
758b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_constant *ir_elt = read_constant(elt);
759ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 if (ir_elt == NULL)
760ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	    return NULL;
761ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke	 elements.push_tail(ir_elt);
762d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 elements_supplied++;
763d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      }
764d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke
765d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke      if (elements_supplied != type->length) {
766b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(values, "expected exactly %u array elements, "
767d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke		       "given %u", type->length, elements_supplied);
768d7988152722cd5f3930064a139b567cbcb0e5f53Kenneth Graunke	 return NULL;
769ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke      }
770b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_constant(type, &elements);
771ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke   }
772ef2c38b2450eb366a2e6f6a46d1725aa6c14d74bKenneth Graunke
773f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   const glsl_type *const base_type = type->get_base_type();
774f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
775b43611b79c1f0a5caff80c17c9e7840a718f07c9Vinson Lee   ir_constant_data data = { { 0 } };
776f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
777f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   // Read in list of values (at most 16).
778f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   int k = 0;
779f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   foreach_iter(exec_list_iterator, it, values->subexpressions) {
780f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (k >= 16) {
781b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(values, "expected at most 16 numbers");
782f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
783f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
784f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
785f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      s_expression *expr = (s_expression*) it.get();
786f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
787f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      if (base_type->base_type == GLSL_TYPE_FLOAT) {
788f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_number *value = SX_AS_NUMBER(expr);
789f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
790b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "expected numbers");
791f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
792f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
7934976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	 data.f[k] = value->fvalue();
794f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      } else {
795f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 s_int *value = SX_AS_INT(expr);
796f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 if (value == NULL) {
797b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "expected integers");
798f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
799f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
800f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
801f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 switch (base_type->base_type) {
802f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_UINT: {
8034976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.u[k] = value->value();
804f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
805f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
806f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_INT: {
8074976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.i[k] = value->value();
808f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
809f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
810f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 case GLSL_TYPE_BOOL: {
8114976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick	    data.b[k] = value->value();
812f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    break;
813f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
814f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 default:
815b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(values, "unsupported constant type");
816f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	    return NULL;
817f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 }
818f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
819f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      ++k;
820f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
8214976e57448b2d4ca753e95ef2162758542a69a77Ian Romanick
822b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   return new(mem_ctx) ir_constant(type, &data);
823f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
824451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke
825b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_dereference *
826b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_dereference(s_expression *expr)
8273c7934bfaae5dff410cddba3ac6696a8911c0c68Kenneth Graunke{
828ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_symbol *s_var;
829ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_expression *s_subject;
830ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_expression *s_index;
831ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_symbol *s_field;
832ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke
833ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_pattern var_pat[] = { "var_ref", s_var };
834ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_pattern array_pat[] = { "array_ref", s_subject, s_index };
835ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   s_pattern record_pat[] = { "record_ref", s_subject, s_field };
836ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke
837ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   if (MATCH(expr, var_pat)) {
838b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_variable *var = state->symbols->get_variable(s_var->value());
839ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (var == NULL) {
840b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "undeclared variable: %s", s_var->value());
841ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
842ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
843b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_variable(var);
844ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   } else if (MATCH(expr, array_pat)) {
845b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *subject = read_rvalue(s_subject);
846ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
847b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the subject of an array_ref");
848ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
849ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
85013e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke
851b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *idx = read_rvalue(s_index);
852ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
853b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the index of an array_ref");
854ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
855ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
856b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_array(subject, idx);
857ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   } else if (MATCH(expr, record_pat)) {
858b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_rvalue *subject = read_rvalue(s_subject);
859ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      if (subject == NULL) {
860b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading the subject of a record_ref");
861ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke	 return NULL;
862ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke      }
863b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      return new(mem_ctx) ir_dereference_record(subject, s_field->value());
86413e1b6b725def5a22952ecd4e2e8b1e61cb3bcfaKenneth Graunke   }
865ec7e4f0ec5c9b718bbfa33a706149030be86d2d9Kenneth Graunke   return NULL;
866451381c220f145ac27a177c955dde30a9618fd00Kenneth Graunke}
867dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
868b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_texture *
869b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_texture(s_expression *expr)
870dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke{
871daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *tag = NULL;
872daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_sampler = NULL;
873daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_coord = NULL;
874daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_offset = NULL;
875daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_proj = NULL;
876daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_shadow = NULL;
877daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_lod = NULL;
878daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
8799f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   ir_texture_opcode op = ir_tex; /* silence warning */
880daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
881daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern tex_pattern[] =
882daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
883daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern txf_pattern[] =
884daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { "txf", s_sampler, s_coord, s_offset, s_lod };
885daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern other_pattern[] =
886daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
887daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
888e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (MATCH(expr, tex_pattern)) {
889daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_tex;
890e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, txf_pattern)) {
891daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_txf;
892e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, other_pattern)) {
893daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_texture::get_opcode(tag->value());
894daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (op == -1)
895daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
8969f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   } else {
8979f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      ir_read_error(NULL, "unexpected texture pattern");
8989f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      return NULL;
899dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
900dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
901b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_texture *tex = new(mem_ctx) ir_texture(op);
902dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
903dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read sampler (must be a deref)
904b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *sampler = read_dereference(s_sampler);
90556d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   if (sampler == NULL) {
906b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading sampler in (%s ...)",
907daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
908dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
909dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
91056d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   tex->set_sampler(sampler);
911dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
912dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read coordinate (any rvalue)
913b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   tex->coordinate = read_rvalue(s_coord);
914dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   if (tex->coordinate == NULL) {
915b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading coordinate in (%s ...)",
916daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
917dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
918dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
919dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
920dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read texel offset, i.e. (0 0 0)
921daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_x;
922daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_y;
923daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *offset_z;
924daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
925daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (!MATCH(s_offset, offset_pat)) {
926b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(s_offset, "expected (<int> <int> <int>)");
927dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
928dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
929dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[0] = offset_x->value();
930dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[1] = offset_y->value();
931dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   tex->offsets[2] = offset_z->value();
932dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
933daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (op != ir_txf) {
934daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_int *proj_as_int = SX_AS_INT(s_proj);
935dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      if (proj_as_int && proj_as_int->value() == 1) {
936dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 tex->projector = NULL;
937dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
938b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->projector = read_rvalue(s_proj);
939dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->projector == NULL) {
940b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading projective divide in (%s ..)",
941daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	                  tex->opcode_string());
942dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
943dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
944dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
945dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
946daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_shadow->subexpressions.is_empty()) {
947daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->shadow_comparitor = NULL;
948dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
949b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->shadow_comparitor = read_rvalue(s_shadow);
950dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->shadow_comparitor == NULL) {
951b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading shadow comparitor in (%s ..)",
952daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			  tex->opcode_string());
953dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
954dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
955dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
956daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   }
957dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
958daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   switch (op) {
959daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txb:
960b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.bias = read_rvalue(s_lod);
961daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.bias == NULL) {
962b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD bias in (txb ...)");
963daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
964daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
965daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
966daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txl:
967daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txf:
968b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.lod = read_rvalue(s_lod);
969daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.lod == NULL) {
970b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD in (%s ...)",
971daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       tex->opcode_string());
972daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
973daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
974daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
975daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txd: {
976daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_dx, *s_dy;
977daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_pattern dxdy_pat[] = { s_dx, s_dy };
978daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (!MATCH(s_lod, dxdy_pat)) {
979b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(s_lod, "expected (dPdx dPdy) in (txd ...)");
980daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
981daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
982b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdx = read_rvalue(s_dx);
983daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdx == NULL) {
984b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdx in (txd ...)");
985daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
986daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
987b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdy = read_rvalue(s_dy);
988daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdy == NULL) {
989b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdy in (txd ...)");
990daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
991dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
992daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
993dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
994daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   default:
995daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      // tex doesn't have any extra parameters.
996daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
997daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   };
998dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   return tex;
999dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke}
1000