ir_reader.cpp revision ec7e4f0ec5c9b718bbfa33a706149030be86d2d9
1/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24extern "C" {
25#include <talloc.h>
26}
27
28#include "ir_reader.h"
29#include "glsl_parser_extras.h"
30#include "glsl_types.h"
31#include "s_expression.h"
32
33const static bool debug = false;
34
35static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
36			  const char *fmt, ...);
37static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
38
39static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
40			        s_expression *);
41static ir_function *read_function(_mesa_glsl_parse_state *, s_expression *,
42				  bool skip_body);
43static void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
44			      s_expression *, bool skip_body);
45
46static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
47			      s_expression *, ir_loop *);
48static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
49				        s_expression *, ir_loop *);
50static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_expression *);
51static ir_if *read_if(_mesa_glsl_parse_state *, s_expression *, ir_loop *);
52static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_expression *);
53static ir_return *read_return(_mesa_glsl_parse_state *, s_expression *);
54
55static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
56static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_expression *);
57static ir_expression *read_expression(_mesa_glsl_parse_state *, s_expression *);
58static ir_call *read_call(_mesa_glsl_parse_state *, s_expression *);
59static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_expression *);
60static ir_constant *read_constant(_mesa_glsl_parse_state *, s_expression *);
61static ir_texture *read_texture(_mesa_glsl_parse_state *, s_expression *);
62
63static ir_dereference *read_dereference(_mesa_glsl_parse_state *,
64				        s_expression *);
65
66void
67_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
68		   const char *src, bool scan_for_protos)
69{
70   s_expression *expr = s_expression::read_expression(state, src);
71   if (expr == NULL) {
72      ir_read_error(state, NULL, "couldn't parse S-Expression.");
73      return;
74   }
75
76   if (scan_for_protos) {
77      scan_for_prototypes(state, instructions, expr);
78      if (state->error)
79	 return;
80   }
81
82   read_instructions(state, instructions, expr, NULL);
83   talloc_free(expr);
84
85   if (debug)
86      validate_ir_tree(instructions);
87}
88
89static void
90ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
91	      const char *fmt, ...)
92{
93   va_list ap;
94
95   state->error = true;
96
97   if (state->current_function != NULL)
98      state->info_log = talloc_asprintf_append(state->info_log,
99			   "In function %s:\n",
100			   state->current_function->function_name());
101   state->info_log = talloc_strdup_append(state->info_log, "error: ");
102
103   va_start(ap, fmt);
104   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
105   va_end(ap);
106   state->info_log = talloc_strdup_append(state->info_log, "\n");
107
108   if (expr != NULL) {
109      state->info_log = talloc_strdup_append(state->info_log,
110					     "...in this context:\n   ");
111      expr->print();
112      state->info_log = talloc_strdup_append(state->info_log, "\n\n");
113   }
114}
115
116static const glsl_type *
117read_type(_mesa_glsl_parse_state *st, s_expression *expr)
118{
119   s_expression *s_base_type;
120   s_int *s_size;
121
122   s_pattern pat[] = { "array", s_base_type, s_size };
123   if (MATCH(expr, pat)) {
124      const glsl_type *base_type = read_type(st, s_base_type);
125      if (base_type == NULL) {
126	 ir_read_error(st, NULL, "when reading base type of array type");
127	 return NULL;
128      }
129
130      return glsl_type::get_array_instance(base_type, s_size->value());
131   }
132
133   s_symbol *type_sym = SX_AS_SYMBOL(expr);
134   if (type_sym == NULL) {
135      ir_read_error(st, expr, "expected <type>");
136      return NULL;
137   }
138
139   const glsl_type *type = st->symbols->get_type(type_sym->value());
140   if (type == NULL)
141      ir_read_error(st, expr, "invalid type: %s", type_sym->value());
142
143   return type;
144}
145
146
147static void
148scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
149		    s_expression *expr)
150{
151   s_list *list = SX_AS_LIST(expr);
152   if (list == NULL) {
153      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
154      return;
155   }
156
157   foreach_iter(exec_list_iterator, it, list->subexpressions) {
158      s_list *sub = SX_AS_LIST(it.get());
159      if (sub == NULL)
160	 continue; // not a (function ...); ignore it.
161
162      s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
163      if (tag == NULL || strcmp(tag->value(), "function") != 0)
164	 continue; // not a (function ...); ignore it.
165
166      ir_function *f = read_function(st, sub, true);
167      if (f == NULL)
168	 return;
169      instructions->push_tail(f);
170   }
171}
172
173static ir_function *
174read_function(_mesa_glsl_parse_state *st, s_expression *expr, bool skip_body)
175{
176   void *ctx = st;
177   bool added = false;
178   s_symbol *name;
179
180   s_pattern pat[] = { "function", name };
181   if (!PARTIAL_MATCH(expr, pat)) {
182      ir_read_error(st, expr, "Expected (function <name> (signature ...) ...)");
183      return NULL;
184   }
185
186   ir_function *f = st->symbols->get_function(name->value());
187   if (f == NULL) {
188      f = new(ctx) ir_function(name->value());
189      added = st->symbols->add_function(f);
190      assert(added);
191   }
192
193   exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
194   it.next(); // skip "function" tag
195   it.next(); // skip function name
196   for (/* nothing */; it.has_next(); it.next()) {
197      s_expression *s_sig = (s_expression *) it.get();
198      read_function_sig(st, f, s_sig, skip_body);
199   }
200   return added ? f : NULL;
201}
202
203static void
204read_function_sig(_mesa_glsl_parse_state *st, ir_function *f,
205		  s_expression *expr, bool skip_body)
206{
207   void *ctx = st;
208   s_expression *type_expr;
209   s_list *paramlist;
210   s_list *body_list;
211
212   s_pattern pat[] = { "signature", type_expr, paramlist, body_list };
213   if (!MATCH(expr, pat)) {
214      ir_read_error(st, expr, "Expected (signature <type> (parameters ...) "
215			      "(<instruction> ...))");
216      return;
217   }
218
219   const glsl_type *return_type = read_type(st, type_expr);
220   if (return_type == NULL)
221      return;
222
223   s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
224   if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
225      ir_read_error(st, paramlist, "Expected (parameters ...)");
226      return;
227   }
228
229   // Read the parameters list into a temporary place.
230   exec_list hir_parameters;
231   st->symbols->push_scope();
232
233   exec_list_iterator it = paramlist->subexpressions.iterator();
234   for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
235      ir_variable *var = read_declaration(st, (s_expression *) it.get());
236      if (var == NULL)
237	 return;
238
239      hir_parameters.push_tail(var);
240   }
241
242   ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
243   if (sig == NULL && skip_body) {
244      /* If scanning for prototypes, generate a new signature. */
245      sig = new(ctx) ir_function_signature(return_type);
246      sig->is_builtin = true;
247      f->add_signature(sig);
248   } else if (sig != NULL) {
249      const char *badvar = sig->qualifiers_match(&hir_parameters);
250      if (badvar != NULL) {
251	 ir_read_error(st, expr, "function `%s' parameter `%s' qualifiers "
252		       "don't match prototype", f->name, badvar);
253	 return;
254      }
255
256      if (sig->return_type != return_type) {
257	 ir_read_error(st, expr, "function `%s' return type doesn't "
258		       "match prototype", f->name);
259	 return;
260      }
261   } else {
262      /* No prototype for this body exists - skip it. */
263      st->symbols->pop_scope();
264      return;
265   }
266   assert(sig != NULL);
267
268   sig->replace_parameters(&hir_parameters);
269
270   if (!skip_body && !body_list->subexpressions.is_empty()) {
271      if (sig->is_defined) {
272	 ir_read_error(st, expr, "function %s redefined", f->name);
273	 return;
274      }
275      st->current_function = sig;
276      read_instructions(st, &sig->body, body_list, NULL);
277      st->current_function = NULL;
278      sig->is_defined = true;
279   }
280
281   st->symbols->pop_scope();
282}
283
284static void
285read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
286		  s_expression *expr, ir_loop *loop_ctx)
287{
288   // Read in a list of instructions
289   s_list *list = SX_AS_LIST(expr);
290   if (list == NULL) {
291      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
292      return;
293   }
294
295   foreach_iter(exec_list_iterator, it, list->subexpressions) {
296      s_expression *sub = (s_expression*) it.get();
297      ir_instruction *ir = read_instruction(st, sub, loop_ctx);
298      if (ir != NULL) {
299	 /* Global variable declarations should be moved to the top, before
300	  * any functions that might use them.  Functions are added to the
301	  * instruction stream when scanning for prototypes, so without this
302	  * hack, they always appear before variable declarations.
303	  */
304	 if (st->current_function == NULL && ir->as_variable() != NULL)
305	    instructions->push_head(ir);
306	 else
307	    instructions->push_tail(ir);
308      }
309   }
310}
311
312
313static ir_instruction *
314read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
315	         ir_loop *loop_ctx)
316{
317   void *ctx = st;
318   s_symbol *symbol = SX_AS_SYMBOL(expr);
319   if (symbol != NULL) {
320      if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
321	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
322      if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
323	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
324   }
325
326   s_list *list = SX_AS_LIST(expr);
327   if (list == NULL || list->subexpressions.is_empty()) {
328      ir_read_error(st, expr, "Invalid instruction.\n");
329      return NULL;
330   }
331
332   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
333   if (tag == NULL) {
334      ir_read_error(st, expr, "expected instruction tag");
335      return NULL;
336   }
337
338   ir_instruction *inst = NULL;
339   if (strcmp(tag->value(), "declare") == 0) {
340      inst = read_declaration(st, list);
341   } else if (strcmp(tag->value(), "assign") == 0) {
342      inst = read_assignment(st, list);
343   } else if (strcmp(tag->value(), "if") == 0) {
344      inst = read_if(st, list, loop_ctx);
345   } else if (strcmp(tag->value(), "loop") == 0) {
346      inst = read_loop(st, list);
347   } else if (strcmp(tag->value(), "return") == 0) {
348      inst = read_return(st, list);
349   } else if (strcmp(tag->value(), "function") == 0) {
350      inst = read_function(st, list, false);
351   } else {
352      inst = read_rvalue(st, list);
353      if (inst == NULL)
354	 ir_read_error(st, NULL, "when reading instruction");
355   }
356   return inst;
357}
358
359static ir_variable *
360read_declaration(_mesa_glsl_parse_state *st, s_expression *expr)
361{
362   s_list *s_quals;
363   s_expression *s_type;
364   s_symbol *s_name;
365
366   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
367   if (!MATCH(expr, pat)) {
368      ir_read_error(st, expr, "expected (declare (<qualifiers>) <type> "
369			      "<name>)");
370      return NULL;
371   }
372
373   const glsl_type *type = read_type(st, s_type);
374   if (type == NULL)
375      return NULL;
376
377   ir_variable *var = new(st) ir_variable(type, s_name->value(), ir_var_auto);
378
379   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
380      s_symbol *qualifier = SX_AS_SYMBOL(it.get());
381      if (qualifier == NULL) {
382	 ir_read_error(st, expr, "qualifier list must contain only symbols");
383	 return NULL;
384      }
385
386      // FINISHME: Check for duplicate/conflicting qualifiers.
387      if (strcmp(qualifier->value(), "centroid") == 0) {
388	 var->centroid = 1;
389      } else if (strcmp(qualifier->value(), "invariant") == 0) {
390	 var->invariant = 1;
391      } else if (strcmp(qualifier->value(), "uniform") == 0) {
392	 var->mode = ir_var_uniform;
393      } else if (strcmp(qualifier->value(), "auto") == 0) {
394	 var->mode = ir_var_auto;
395      } else if (strcmp(qualifier->value(), "in") == 0) {
396	 var->mode = ir_var_in;
397      } else if (strcmp(qualifier->value(), "out") == 0) {
398	 var->mode = ir_var_out;
399      } else if (strcmp(qualifier->value(), "inout") == 0) {
400	 var->mode = ir_var_inout;
401      } else if (strcmp(qualifier->value(), "smooth") == 0) {
402	 var->interpolation = ir_var_smooth;
403      } else if (strcmp(qualifier->value(), "flat") == 0) {
404	 var->interpolation = ir_var_flat;
405      } else if (strcmp(qualifier->value(), "noperspective") == 0) {
406	 var->interpolation = ir_var_noperspective;
407      } else {
408	 ir_read_error(st, expr, "unknown qualifier: %s", qualifier->value());
409	 return NULL;
410      }
411   }
412
413   // Add the variable to the symbol table
414   st->symbols->add_variable(var);
415
416   return var;
417}
418
419
420static ir_if *
421read_if(_mesa_glsl_parse_state *st, s_expression *expr, ir_loop *loop_ctx)
422{
423   s_expression *s_cond;
424   s_expression *s_then;
425   s_expression *s_else;
426
427   s_pattern pat[] = { "if", s_cond, s_then, s_else };
428   if (!MATCH(expr, pat)) {
429      ir_read_error(st, expr, "expected (if <condition> (<then> ...) "
430			      "(<else> ...))");
431      return NULL;
432   }
433
434   ir_rvalue *condition = read_rvalue(st, s_cond);
435   if (condition == NULL) {
436      ir_read_error(st, NULL, "when reading condition of (if ...)");
437      return NULL;
438   }
439
440   ir_if *iff = new(st) ir_if(condition);
441
442   read_instructions(st, &iff->then_instructions, s_then, loop_ctx);
443   read_instructions(st, &iff->else_instructions, s_else, loop_ctx);
444   if (st->error) {
445      delete iff;
446      iff = NULL;
447   }
448   return iff;
449}
450
451
452static ir_loop *
453read_loop(_mesa_glsl_parse_state *st, s_expression *expr)
454{
455   s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
456
457   s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
458   if (!MATCH(expr, pat)) {
459      ir_read_error(st, expr, "expected (loop <counter> <from> <to> "
460			      "<increment> <body>)");
461      return NULL;
462   }
463
464   // FINISHME: actually read the count/from/to fields.
465
466   ir_loop *loop = new(st) ir_loop;
467   read_instructions(st, &loop->body_instructions, s_body, loop);
468   if (st->error) {
469      delete loop;
470      loop = NULL;
471   }
472   return loop;
473}
474
475
476static ir_return *
477read_return(_mesa_glsl_parse_state *st, s_expression *expr)
478{
479   s_expression *s_retval;
480
481   s_pattern pat[] = { "return", s_retval};
482   if (!MATCH(expr, pat)) {
483      ir_read_error(st, expr, "expected (return <rvalue>)");
484      return NULL;
485   }
486
487   ir_rvalue *retval = read_rvalue(st, s_retval);
488   if (retval == NULL) {
489      ir_read_error(st, NULL, "when reading return value");
490      return NULL;
491   }
492
493   return new(st) ir_return(retval);
494}
495
496
497static ir_rvalue *
498read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
499{
500   s_list *list = SX_AS_LIST(expr);
501   if (list == NULL || list->subexpressions.is_empty())
502      return NULL;
503
504   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
505   if (tag == NULL) {
506      ir_read_error(st, expr, "expected rvalue tag");
507      return NULL;
508   }
509
510   ir_rvalue *rvalue = read_dereference(st, list);
511   if (rvalue != NULL || st->error)
512      return rvalue;
513   else if (strcmp(tag->value(), "swiz") == 0) {
514      rvalue = read_swizzle(st, list);
515   } else if (strcmp(tag->value(), "expression") == 0) {
516      rvalue = read_expression(st, list);
517   } else if (strcmp(tag->value(), "call") == 0) {
518      rvalue = read_call(st, list);
519   } else if (strcmp(tag->value(), "constant") == 0) {
520      rvalue = read_constant(st, list);
521   } else {
522      rvalue = read_texture(st, list);
523      if (rvalue == NULL && !st->error)
524	 ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
525   }
526
527   return rvalue;
528}
529
530static ir_assignment *
531read_assignment(_mesa_glsl_parse_state *st, s_expression *expr)
532{
533   s_expression *cond_expr, *lhs_expr, *rhs_expr;
534   s_list       *mask_list;
535
536   s_pattern pat[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr };
537   if (!MATCH(expr, pat)) {
538      ir_read_error(st, expr, "expected (assign <condition> (<write mask>) "
539			      "<lhs> <rhs>)");
540      return NULL;
541   }
542
543   ir_rvalue *condition = read_rvalue(st, cond_expr);
544   if (condition == NULL) {
545      ir_read_error(st, NULL, "when reading condition of assignment");
546      return NULL;
547   }
548
549   unsigned mask = 0;
550
551   s_symbol *mask_symbol;
552   s_pattern mask_pat[] = { mask_symbol };
553   if (MATCH(mask_list, mask_pat)) {
554      const char *mask_str = mask_symbol->value();
555      unsigned mask_length = strlen(mask_str);
556      if (mask_length > 4) {
557	 ir_read_error(st, expr, "invalid write mask: %s", mask_str);
558	 return NULL;
559      }
560
561      const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
562
563      for (unsigned i = 0; i < mask_length; i++) {
564	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
565	    ir_read_error(st, expr, "write mask contains invalid character: %c",
566			  mask_str[i]);
567	    return NULL;
568	 }
569	 mask |= 1 << idx_map[mask_str[i] - 'w'];
570      }
571   } else if (!mask_list->subexpressions.is_empty()) {
572      ir_read_error(st, mask_list, "expected () or (<write mask>)");
573      return NULL;
574   }
575
576   ir_dereference *lhs = read_dereference(st, lhs_expr);
577   if (lhs == NULL) {
578      ir_read_error(st, NULL, "when reading left-hand side of assignment");
579      return NULL;
580   }
581
582   ir_rvalue *rhs = read_rvalue(st, rhs_expr);
583   if (rhs == NULL) {
584      ir_read_error(st, NULL, "when reading right-hand side of assignment");
585      return NULL;
586   }
587
588   if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
589      ir_read_error(st, expr, "non-zero write mask required.");
590      return NULL;
591   }
592
593   return new(st) ir_assignment(lhs, rhs, condition, mask);
594}
595
596static ir_call *
597read_call(_mesa_glsl_parse_state *st, s_expression *expr)
598{
599   void *ctx = st;
600   s_symbol *name;
601   s_list *params;
602
603   s_pattern pat[] = { "call", name, params };
604   if (!MATCH(expr, pat)) {
605      ir_read_error(st, expr, "expected (call <name> (<param> ...))");
606      return NULL;
607   }
608
609   exec_list parameters;
610
611   foreach_iter(exec_list_iterator, it, params->subexpressions) {
612      s_expression *expr = (s_expression*) it.get();
613      ir_rvalue *param = read_rvalue(st, expr);
614      if (param == NULL) {
615	 ir_read_error(st, expr, "when reading parameter to function call");
616	 return NULL;
617      }
618      parameters.push_tail(param);
619   }
620
621   ir_function *f = st->symbols->get_function(name->value());
622   if (f == NULL) {
623      ir_read_error(st, expr, "found call to undefined function %s",
624		    name->value());
625      return NULL;
626   }
627
628   ir_function_signature *callee = f->matching_signature(&parameters);
629   if (callee == NULL) {
630      ir_read_error(st, expr, "couldn't find matching signature for function "
631                    "%s", name->value());
632      return NULL;
633   }
634
635   return new(ctx) ir_call(callee, &parameters);
636}
637
638static ir_expression *
639read_expression(_mesa_glsl_parse_state *st, s_expression *expr)
640{
641   void *ctx = st;
642   s_expression *s_type;
643   s_symbol *s_op;
644   s_expression *s_arg1;
645
646   s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
647   if (!PARTIAL_MATCH(expr, pat)) {
648      ir_read_error(st, expr, "expected (expression <type> <operator> "
649			      "<operand> [<operand>])");
650      return NULL;
651   }
652   s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
653
654   const glsl_type *type = read_type(st, s_type);
655   if (type == NULL)
656      return NULL;
657
658   /* Read the operator */
659   ir_expression_operation op = ir_expression::get_operator(s_op->value());
660   if (op == (ir_expression_operation) -1) {
661      ir_read_error(st, expr, "invalid operator: %s", s_op->value());
662      return NULL;
663   }
664
665   unsigned num_operands = ir_expression::get_num_operands(op);
666   if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
667      ir_read_error(st, expr, "expected (expression <type> %s <operand>)",
668		    s_op->value());
669      return NULL;
670   }
671
672   ir_rvalue *arg1 = read_rvalue(st, s_arg1);
673   ir_rvalue *arg2 = NULL;
674   if (arg1 == NULL) {
675      ir_read_error(st, NULL, "when reading first operand of %s",
676		    s_op->value());
677      return NULL;
678   }
679
680   if (num_operands == 2) {
681      if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) {
682	 ir_read_error(st, expr, "expected (expression <type> %s <operand> "
683				 "<operand>)", s_op->value());
684	 return NULL;
685      }
686      arg2 = read_rvalue(st, s_arg2);
687      if (arg2 == NULL) {
688	 ir_read_error(st, NULL, "when reading second operand of %s",
689		       s_op->value());
690	 return NULL;
691      }
692   }
693
694   return new(ctx) ir_expression(op, type, arg1, arg2);
695}
696
697static ir_swizzle *
698read_swizzle(_mesa_glsl_parse_state *st, s_expression *expr)
699{
700   s_symbol *swiz;
701   s_expression *sub;
702
703   s_pattern pat[] = { "swiz", swiz, sub };
704   if (!MATCH(expr, pat)) {
705      ir_read_error(st, expr, "expected (swiz <swizzle> <rvalue>)");
706      return NULL;
707   }
708
709   if (strlen(swiz->value()) > 4) {
710      ir_read_error(st, expr, "expected a valid swizzle; found %s",
711		    swiz->value());
712      return NULL;
713   }
714
715   ir_rvalue *rvalue = read_rvalue(st, sub);
716   if (rvalue == NULL)
717      return NULL;
718
719   ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
720				       rvalue->type->vector_elements);
721   if (ir == NULL)
722      ir_read_error(st, expr, "invalid swizzle");
723
724   return ir;
725}
726
727static ir_constant *
728read_constant(_mesa_glsl_parse_state *st, s_expression *expr)
729{
730   void *ctx = st;
731   s_expression *type_expr;
732   s_list *values;
733
734   s_pattern pat[] = { "constant", type_expr, values };
735   if (!MATCH(expr, pat)) {
736      ir_read_error(st, expr, "expected (constant <type> (...))");
737      return NULL;
738   }
739
740   const glsl_type *type = read_type(st, type_expr);
741   if (type == NULL)
742      return NULL;
743
744   if (values == NULL) {
745      ir_read_error(st, expr, "expected (constant <type> (...))");
746      return NULL;
747   }
748
749   if (type->is_array()) {
750      unsigned elements_supplied = 0;
751      exec_list elements;
752      foreach_iter(exec_list_iterator, it, values->subexpressions) {
753	 s_expression *elt = (s_expression *) it.get();
754	 ir_constant *ir_elt = read_constant(st, elt);
755	 if (ir_elt == NULL)
756	    return NULL;
757	 elements.push_tail(ir_elt);
758	 elements_supplied++;
759      }
760
761      if (elements_supplied != type->length) {
762	 ir_read_error(st, values, "expected exactly %u array elements, "
763		       "given %u", type->length, elements_supplied);
764	 return NULL;
765      }
766      return new(ctx) ir_constant(type, &elements);
767   }
768
769   const glsl_type *const base_type = type->get_base_type();
770
771   ir_constant_data data = { { 0 } };
772
773   // Read in list of values (at most 16).
774   int k = 0;
775   foreach_iter(exec_list_iterator, it, values->subexpressions) {
776      if (k >= 16) {
777	 ir_read_error(st, values, "expected at most 16 numbers");
778	 return NULL;
779      }
780
781      s_expression *expr = (s_expression*) it.get();
782
783      if (base_type->base_type == GLSL_TYPE_FLOAT) {
784	 s_number *value = SX_AS_NUMBER(expr);
785	 if (value == NULL) {
786	    ir_read_error(st, values, "expected numbers");
787	    return NULL;
788	 }
789	 data.f[k] = value->fvalue();
790      } else {
791	 s_int *value = SX_AS_INT(expr);
792	 if (value == NULL) {
793	    ir_read_error(st, values, "expected integers");
794	    return NULL;
795	 }
796
797	 switch (base_type->base_type) {
798	 case GLSL_TYPE_UINT: {
799	    data.u[k] = value->value();
800	    break;
801	 }
802	 case GLSL_TYPE_INT: {
803	    data.i[k] = value->value();
804	    break;
805	 }
806	 case GLSL_TYPE_BOOL: {
807	    data.b[k] = value->value();
808	    break;
809	 }
810	 default:
811	    ir_read_error(st, values, "unsupported constant type");
812	    return NULL;
813	 }
814      }
815      ++k;
816   }
817
818   return new(ctx) ir_constant(type, &data);
819}
820
821static ir_dereference *
822read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
823{
824   s_symbol *s_var;
825   s_expression *s_subject;
826   s_expression *s_index;
827   s_symbol *s_field;
828
829   s_pattern var_pat[] = { "var_ref", s_var };
830   s_pattern array_pat[] = { "array_ref", s_subject, s_index };
831   s_pattern record_pat[] = { "record_ref", s_subject, s_field };
832
833   if (MATCH(expr, var_pat)) {
834      ir_variable *var = st->symbols->get_variable(s_var->value());
835      if (var == NULL) {
836	 ir_read_error(st, expr, "undeclared variable: %s", s_var->value());
837	 return NULL;
838      }
839      return new(st) ir_dereference_variable(var);
840   } else if (MATCH(expr, array_pat)) {
841      ir_rvalue *subject = read_rvalue(st, s_subject);
842      if (subject == NULL) {
843	 ir_read_error(st, NULL, "when reading the subject of an array_ref");
844	 return NULL;
845      }
846
847      ir_rvalue *idx = read_rvalue(st, s_index);
848      if (subject == NULL) {
849	 ir_read_error(st, NULL, "when reading the index of an array_ref");
850	 return NULL;
851      }
852      return new(st) ir_dereference_array(subject, idx);
853   } else if (MATCH(expr, record_pat)) {
854      ir_rvalue *subject = read_rvalue(st, s_subject);
855      if (subject == NULL) {
856	 ir_read_error(st, NULL, "when reading the subject of a record_ref");
857	 return NULL;
858      }
859      return new(st) ir_dereference_record(subject, s_field->value());
860   }
861   return NULL;
862}
863
864static ir_texture *
865read_texture(_mesa_glsl_parse_state *st, s_expression *expr)
866{
867   s_symbol *tag = NULL;
868   s_expression *s_sampler = NULL;
869   s_expression *s_coord = NULL;
870   s_list *s_offset = NULL;
871   s_expression *s_proj = NULL;
872   s_list *s_shadow = NULL;
873   s_expression *s_lod = NULL;
874
875   ir_texture_opcode op;
876
877   s_pattern tex_pattern[] =
878      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
879   s_pattern txf_pattern[] =
880      { "txf", s_sampler, s_coord, s_offset, s_lod };
881   s_pattern other_pattern[] =
882      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
883
884   if (MATCH(expr, tex_pattern)) {
885      op = ir_tex;
886   } else if (MATCH(expr, txf_pattern)) {
887      op = ir_txf;
888   } else if (MATCH(expr, other_pattern)) {
889      op = ir_texture::get_opcode(tag->value());
890      if (op == -1)
891	 return NULL;
892   }
893
894   ir_texture *tex = new(st) ir_texture(op);
895
896   // Read sampler (must be a deref)
897   ir_dereference *sampler = read_dereference(st, s_sampler);
898   if (sampler == NULL) {
899      ir_read_error(st, NULL, "when reading sampler in (%s ...)",
900		    tex->opcode_string());
901      return NULL;
902   }
903   tex->set_sampler(sampler);
904
905   // Read coordinate (any rvalue)
906   tex->coordinate = read_rvalue(st, s_coord);
907   if (tex->coordinate == NULL) {
908      ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
909		    tex->opcode_string());
910      return NULL;
911   }
912
913   // Read texel offset, i.e. (0 0 0)
914   s_int *offset_x;
915   s_int *offset_y;
916   s_int *offset_z;
917   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
918   if (!MATCH(s_offset, offset_pat)) {
919      ir_read_error(st, s_offset, "expected (<int> <int> <int>)");
920      return NULL;
921   }
922   tex->offsets[0] = offset_x->value();
923   tex->offsets[1] = offset_y->value();
924   tex->offsets[2] = offset_z->value();
925
926   if (op != ir_txf) {
927      s_int *proj_as_int = SX_AS_INT(s_proj);
928      if (proj_as_int && proj_as_int->value() == 1) {
929	 tex->projector = NULL;
930      } else {
931	 tex->projector = read_rvalue(st, s_proj);
932	 if (tex->projector == NULL) {
933	    ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
934	                  tex->opcode_string());
935	    return NULL;
936	 }
937      }
938
939      if (s_shadow->subexpressions.is_empty()) {
940	 tex->shadow_comparitor = NULL;
941      } else {
942	 tex->shadow_comparitor = read_rvalue(st, s_shadow);
943	 if (tex->shadow_comparitor == NULL) {
944	    ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
945			  tex->opcode_string());
946	    return NULL;
947	 }
948      }
949   }
950
951   switch (op) {
952   case ir_txb:
953      tex->lod_info.bias = read_rvalue(st, s_lod);
954      if (tex->lod_info.bias == NULL) {
955	 ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
956	 return NULL;
957      }
958      break;
959   case ir_txl:
960   case ir_txf:
961      tex->lod_info.lod = read_rvalue(st, s_lod);
962      if (tex->lod_info.lod == NULL) {
963	 ir_read_error(st, NULL, "when reading LOD in (%s ...)",
964		       tex->opcode_string());
965	 return NULL;
966      }
967      break;
968   case ir_txd: {
969      s_expression *s_dx, *s_dy;
970      s_pattern dxdy_pat[] = { s_dx, s_dy };
971      if (!MATCH(s_lod, dxdy_pat)) {
972	 ir_read_error(st, s_lod, "expected (dPdx dPdy) in (txd ...)");
973	 return NULL;
974      }
975      tex->lod_info.grad.dPdx = read_rvalue(st, s_dx);
976      if (tex->lod_info.grad.dPdx == NULL) {
977	 ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
978	 return NULL;
979      }
980      tex->lod_info.grad.dPdy = read_rvalue(st, s_dy);
981      if (tex->lod_info.grad.dPdy == NULL) {
982	 ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
983	 return NULL;
984      }
985      break;
986   }
987   default:
988      // tex doesn't have any extra parameters.
989      break;
990   };
991   return tex;
992}
993