ir_reader.cpp revision 233b88eab9d8095523ebae3c4be1dbf2e2bd856a
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);
95d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_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)
109d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_asprintf_append(&state->info_log, "In function %s:\n",
110d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke			     state->current_function->function_name());
111d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_strcat(&state->info_log, "error: ");
112f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
113f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_start(ap, fmt);
114d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_vasprintf_append(&state->info_log, fmt, ap);
115f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   va_end(ap);
116d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   ralloc_strcat(&state->info_log, "\n");
117f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
11846a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   if (expr != NULL) {
119d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_strcat(&state->info_log, "...in this context:\n   ");
12046a223224c55eaed7bf634d901f733098e674457Kenneth Graunke      expr->print();
121d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      ralloc_strcat(&state->info_log, "\n\n");
12246a223224c55eaed7bf634d901f733098e674457Kenneth Graunke   }
123f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
124f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
125b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeconst glsl_type *
126b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_type(s_expression *expr)
127f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke{
128daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_base_type;
129daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_int *s_size;
130daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
131daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "array", s_base_type, s_size };
132daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (MATCH(expr, pat)) {
133b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      const glsl_type *base_type = read_type(s_base_type);
134daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (base_type == NULL) {
135b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading base type of array type");
136f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke	 return NULL;
137f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      }
13857944975427769b08e00f274ff4d9a3e9849a5a2Kenneth Graunke
139daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      return glsl_type::get_array_instance(base_type, s_size->value());
140f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
141f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
142f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   s_symbol *type_sym = SX_AS_SYMBOL(expr);
143f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type_sym == NULL) {
144b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected <type>");
145f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke      return NULL;
146f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   }
147f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
148b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = state->symbols->get_type(type_sym->value());
149f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   if (type == NULL)
150b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "invalid type: %s", type_sym->value());
151f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
152f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke   return type;
153f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke}
154f955649af3f23367d5e70f33a2bf958b11c2e127Kenneth Graunke
155d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
156b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
157b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
15809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
15909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
16009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (list == NULL) {
161b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
16209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      return;
16309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
16409cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
16509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
16609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_list *sub = SX_AS_LIST(it.get());
16709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (sub == NULL)
16809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
16909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
17009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
17109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      if (tag == NULL || strcmp(tag->value(), "function") != 0)
17209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 continue; // not a (function ...); ignore it.
17309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
174b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_function *f = read_function(sub, true);
1758df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      if (f == NULL)
17609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke	 return;
1778df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      instructions->push_tail(f);
17809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
17909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
18009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
181b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_function *
182b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_function(s_expression *expr, bool skip_body)
18309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
184e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   bool added = false;
185daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *name;
18609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
187daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "function", name };
188e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!PARTIAL_MATCH(expr, pat)) {
189b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (function <name> (signature ...) ...)");
1908df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      return NULL;
19109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
19209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
193b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_function *f = state->symbols->get_function(name->value());
1948df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   if (f == NULL) {
195b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      f = new(mem_ctx) ir_function(name->value());
196b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      added = state->symbols->add_function(f);
1978df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke      assert(added);
19809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
19909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
200e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
20109cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip "function" tag
20209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   it.next(); // skip function name
20309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (/* nothing */; it.has_next(); it.next()) {
204daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_sig = (s_expression *) it.get();
205b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      read_function_sig(f, s_sig, skip_body);
20609cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
207e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   return added ? f : NULL;
20809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
20909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
210b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
211b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
21209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke{
213daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *type_expr;
214daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *paramlist;
215daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *body_list;
216daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
217daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "signature", type_expr, paramlist, body_list };
218daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (!MATCH(expr, pat)) {
219b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (signature <type> (parameters ...) "
220b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			  "(<instruction> ...))");
221b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
22309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
224b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *return_type = read_type(type_expr);
22509cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (return_type == NULL)
226b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
22709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
22809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
22909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
230b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(paramlist, "Expected (parameters ...)");
231b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      return;
23209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
23309cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
234b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   // Read the parameters list into a temporary place.
235b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   exec_list hir_parameters;
236b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->push_scope();
2378df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
23809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   exec_list_iterator it = paramlist->subexpressions.iterator();
23909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
240b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_variable *var = read_declaration((s_expression *) it.get());
241b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (var == NULL)
242b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
243b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
244b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      hir_parameters.push_tail(var);
245b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
246b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
247b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
24843ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   if (sig == NULL && skip_body) {
24943ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* If scanning for prototypes, generate a new signature. */
250b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      sig = new(mem_ctx) ir_function_signature(return_type);
251f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke      sig->is_builtin = true;
25243ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      f->add_signature(sig);
25343ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   } else if (sig != NULL) {
254b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      const char *badvar = sig->qualifiers_match(&hir_parameters);
255b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (badvar != NULL) {
256b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function `%s' parameter `%s' qualifiers "
257b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "don't match prototype", f->name, badvar);
258b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
25909cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke      }
26009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
261b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->return_type != return_type) {
262b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function `%s' return type doesn't "
263b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke		       "match prototype", f->name);
264b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
265b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
266b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   } else {
26743ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      /* No prototype for this body exists - skip it. */
268b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->symbols->pop_scope();
26943ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke      return;
27009cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke   }
27143ff8f1a4b90554eae489cebb7e05f983dd9ad66Kenneth Graunke   assert(sig != NULL);
27209cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
273b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   sig->replace_parameters(&hir_parameters);
274b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke
275d802ba110f78c3eee9541867cde819ada1b2c449Kenneth Graunke   if (!skip_body && !body_list->subexpressions.is_empty()) {
276b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      if (sig->is_defined) {
277b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "function %s redefined", f->name);
278b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke	 return;
279b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke      }
280b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->current_function = sig;
281b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      read_instructions(&sig->body, body_list, NULL);
282b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      state->current_function = NULL;
283f6c90d8b3484864cd7f3abf895746e0655929a13Kenneth Graunke      sig->is_defined = true;
284b142aeeb20f1b1d5f3752b973ecb0da61e7a574eKenneth Graunke   }
2858df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke
286b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   state->symbols->pop_scope();
28709cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke}
28809cad1339d8e6eebe5b13d95a9e1d2a1da2fce29Kenneth Graunke
289b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkevoid
290b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_instructions(exec_list *instructions, s_expression *expr,
291b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke			     ir_loop *loop_ctx)
2923ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke{
2933ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   // Read in a list of instructions
2943ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
2953ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   if (list == NULL) {
296b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
2973ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      return;
2983ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
2993ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3003ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   foreach_iter(exec_list_iterator, it, list->subexpressions) {
3013ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke      s_expression *sub = (s_expression*) it.get();
302b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_instruction *ir = read_instruction(sub, loop_ctx);
3032809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      if (ir != NULL) {
3042809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 /* Global variable declarations should be moved to the top, before
3052809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * any functions that might use them.  Functions are added to the
3062809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * instruction stream when scanning for prototypes, so without this
3072809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  * hack, they always appear before variable declarations.
3082809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	  */
309b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 if (state->current_function == NULL && ir->as_variable() != NULL)
3102809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_head(ir);
3112809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	 else
3122809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke	    instructions->push_tail(ir);
3132809d707231fba0e91abe1dd32e9f2d3284b9d3aKenneth Graunke      }
3143ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke   }
3153ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke}
3163ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
3173ea0582803ea3070a1856455137daef9ddd86cb9Kenneth Graunke
318b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_instruction *
319b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
320d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
321396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   s_symbol *symbol = SX_AS_SYMBOL(expr);
322396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   if (symbol != NULL) {
323396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
324b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
325396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke      if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
326b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
327396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke   }
328396fa9eba65a764a475a1ff186a94f1a4038af8aKenneth Graunke
329d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_list *list = SX_AS_LIST(expr);
330e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   if (list == NULL || list->subexpressions.is_empty()) {
331b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "Invalid instruction.\n");
332d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
333e024c5c6900c068634c2726d9ccfb9beac966c57Kenneth Graunke   }
334d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
335d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
336d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (tag == NULL) {
337b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected instruction tag");
338d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
339d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
340d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
341d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   ir_instruction *inst = NULL;
34246ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   if (strcmp(tag->value(), "declare") == 0) {
343b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_declaration(list);
3443c033637de7def553559c11d037f2e8bbb750f77Kenneth Graunke   } else if (strcmp(tag->value(), "assign") == 0) {
345b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_assignment(list);
34646ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "if") == 0) {
347b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_if(list, loop_ctx);
34832b305207cca7d8a084473f82f340e4b2fe188faKenneth Graunke   } else if (strcmp(tag->value(), "loop") == 0) {
349b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_loop(list);
35046ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else if (strcmp(tag->value(), "return") == 0) {
351b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_return(list);
3528df335d7f9ab8b3699c312f2b4b42be2e8eeba27Kenneth Graunke   } else if (strcmp(tag->value(), "function") == 0) {
353b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_function(list, false);
35446ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   } else {
355b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      inst = read_rvalue(list);
35646ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke      if (inst == NULL)
357b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading instruction");
35846ef8f19d76b33446c2ce6e7f1379bd348fe7fe4Kenneth Graunke   }
359d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   return inst;
360d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke}
361d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
362b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_variable *
363b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunkeir_reader::read_declaration(s_expression *expr)
364d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke{
365daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_quals;
366daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_type;
367daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_symbol *s_name;
368daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
369daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
370e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (!MATCH(expr, pat)) {
371b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(expr, "expected (declare (<qualifiers>) <type> <name>)");
372d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
373d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   }
374d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
375b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   const glsl_type *type = read_type(s_type);
376d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke   if (type == NULL)
377d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      return NULL;
378d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
379b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
380b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke					       ir_var_auto);
381d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
382daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
383d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      s_symbol *qualifier = SX_AS_SYMBOL(it.get());
384d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (qualifier == NULL) {
385b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(expr, "qualifier list must contain only symbols");
386d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 return NULL;
387d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      }
388d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke
389d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      // FINISHME: Check for duplicate/conflicting qualifiers.
390d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      if (strcmp(qualifier->value(), "centroid") == 0) {
391d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->centroid = 1;
392d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "invariant") == 0) {
393d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->invariant = 1;
394d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "uniform") == 0) {
395d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_uniform;
396d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "auto") == 0) {
397d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_auto;
398d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke      } else if (strcmp(qualifier->value(), "in") == 0) {
399d1d2ada3c6bdf5a99c07147c157da75f07100847Kenneth Graunke	 var->mode = ir_var_in;
400819d57fce94b20fa0d34da6f037f0a53c4a5bdc2Kenneth Graunke      } else if (strcmp(qualifier->value(), "const_in") == 0) {
401819d57fce94b20fa0d34da6f037f0a53c4a5bdc2Kenneth Graunke	 var->mode = ir_var_const_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;
872233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   s_expression *s_type = NULL;
873daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_sampler = NULL;
874daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_coord = NULL;
875c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke   s_expression *s_offset = NULL;
876daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_proj = NULL;
877daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_list *s_shadow = NULL;
878daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_expression *s_lod = NULL;
879daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
8809f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   ir_texture_opcode op = ir_tex; /* silence warning */
881daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
882daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern tex_pattern[] =
883233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
884daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern txf_pattern[] =
885233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
886daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   s_pattern other_pattern[] =
887233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
888daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke
889e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   if (MATCH(expr, tex_pattern)) {
890daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_tex;
891e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, txf_pattern)) {
892daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_txf;
893e486fca2d3b430065cbcb27c5d1b545642e11ab5Kenneth Graunke   } else if (MATCH(expr, other_pattern)) {
894daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      op = ir_texture::get_opcode(tag->value());
895daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (op == -1)
896daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
8979f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul   } else {
8989f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      ir_read_error(NULL, "unexpected texture pattern");
8999f2bf3d65cf0745a34185c1966d52389fbd1ca90Brian Paul      return NULL;
900dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
901dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
902b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_texture *tex = new(mem_ctx) ir_texture(op);
903dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
904233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   // Read return type
905233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   const glsl_type *type = read_type(s_type);
906233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   if (type == NULL) {
907233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      ir_read_error(NULL, "when reading type in (%s ...)",
908233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke		    tex->opcode_string());
909233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke      return NULL;
910233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   }
911233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke
912dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read sampler (must be a deref)
913b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   ir_dereference *sampler = read_dereference(s_sampler);
91456d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke   if (sampler == NULL) {
915b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading sampler in (%s ...)",
916daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
917dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
918dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
919233b88eab9d8095523ebae3c4be1dbf2e2bd856aKenneth Graunke   tex->set_sampler(sampler, type);
920dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
921dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   // Read coordinate (any rvalue)
922b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke   tex->coordinate = read_rvalue(s_coord);
923dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   if (tex->coordinate == NULL) {
924b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      ir_read_error(NULL, "when reading coordinate in (%s ...)",
925daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		    tex->opcode_string());
926dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      return NULL;
927dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
928dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
929c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke   // Read texel offset - either 0 or an rvalue.
930c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke   s_int *si_offset = SX_AS_INT(s_offset);
931c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke   if (si_offset == NULL || si_offset->value() != 0) {
932c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke      tex->offset = read_rvalue(s_offset);
933c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke      if (tex->offset == NULL) {
934c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke	 ir_read_error(s_offset, "expected 0 or an expression");
935c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke	 return NULL;
936c5a27b5939427bdc95c926b450ed3de1ff4baafbKenneth Graunke      }
937dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
938dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
939daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   if (op != ir_txf) {
940daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_int *proj_as_int = SX_AS_INT(s_proj);
941dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      if (proj_as_int && proj_as_int->value() == 1) {
942dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 tex->projector = NULL;
943dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
944b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->projector = read_rvalue(s_proj);
945dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->projector == NULL) {
946b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading projective divide in (%s ..)",
947daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	                  tex->opcode_string());
948dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
949dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
950dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
951dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
952daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (s_shadow->subexpressions.is_empty()) {
953daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 tex->shadow_comparitor = NULL;
954dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      } else {
955b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 tex->shadow_comparitor = read_rvalue(s_shadow);
956dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 if (tex->shadow_comparitor == NULL) {
957b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	    ir_read_error(NULL, "when reading shadow comparitor in (%s ..)",
958daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke			  tex->opcode_string());
959dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	    return NULL;
960dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke	 }
961dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
962daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   }
963dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke
964daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   switch (op) {
965daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txb:
966b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.bias = read_rvalue(s_lod);
967daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.bias == NULL) {
968b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD bias in (txb ...)");
969daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
970daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
971daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
972daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txl:
973daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txf:
974b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.lod = read_rvalue(s_lod);
975daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.lod == NULL) {
976b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading LOD in (%s ...)",
977daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke		       tex->opcode_string());
978daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
979daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
980daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
981daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   case ir_txd: {
982daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_expression *s_dx, *s_dy;
983daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      s_pattern dxdy_pat[] = { s_dx, s_dy };
984daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (!MATCH(s_lod, dxdy_pat)) {
985b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(s_lod, "expected (dPdx dPdy) in (txd ...)");
986daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
987daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
988b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdx = read_rvalue(s_dx);
989daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdx == NULL) {
990b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdx in (txd ...)");
991daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
992daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      }
993b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke      tex->lod_info.grad.dPdy = read_rvalue(s_dy);
994daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      if (tex->lod_info.grad.dPdy == NULL) {
995b74ff382a42bcb81bbf0dc6a85bb38404c46260dKenneth Graunke	 ir_read_error(NULL, "when reading dPdy in (txd ...)");
996daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke	 return NULL;
997dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke      }
998daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
999dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   }
1000daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   default:
1001daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      // tex doesn't have any extra parameters.
1002daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke      break;
1003daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke   };
1004dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke   return tex;
1005dd5b4a544bd53f192cc86441f4e7e95d93707382Kenneth Graunke}
1006