d0c7c7080f8003543a5c04d0b116d6678d745404
[mesa.git] / ir_reader.cpp
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 #include <cstdio>
24 #include <cstdarg>
25 #include "ir_reader.h"
26 #include "glsl_parser_extras.h"
27 #include "glsl_types.h"
28 #include "s_expression.h"
29
30 static void ir_read_error(s_expression *expr, const char *fmt, ...);
31 static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
32
33 static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
34 s_expression *);
35 static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
36 static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
37
38 static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
39 static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *);
40 static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *);
41 static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *);
42 static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *);
43
44 void
45 _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
46 const char *src)
47 {
48 s_expression *expr = s_expression::read_expression(src);
49 if (expr == NULL) {
50 ir_read_error(NULL, "couldn't parse S-Expression.");
51 state->error = true;
52 return;
53 }
54 printf("S-Expression:\n");
55 expr->print();
56 printf("\n-------------\n");
57
58 _mesa_glsl_initialize_types(state);
59 _mesa_glsl_initialize_variables(instructions, state);
60 _mesa_glsl_initialize_constructors(instructions, state);
61 _mesa_glsl_initialize_functions(instructions, state);
62
63 // Read in a list of instructions
64 s_list *list = SX_AS_LIST(expr);
65 if (list == NULL) {
66 ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
67 state->error = true;
68 return;
69 }
70
71 foreach_iter(exec_list_iterator, it, list->subexpressions) {
72 s_expression *sub = (s_expression*) it.get();
73 ir_instruction *ir = read_instruction(state, sub);
74 if (ir == NULL) {
75 ir_read_error(sub, "Invalid instruction.\n");
76 state->error = true;
77 return;
78 }
79 instructions->push_tail(ir);
80 }
81 }
82
83 static void
84 ir_read_error(s_expression *expr, const char *fmt, ...)
85 {
86 char buf[1024];
87 int len;
88 va_list ap;
89
90 // FIXME: state->error = true;
91
92 len = snprintf(buf, sizeof(buf), "error: ");
93
94 va_start(ap, fmt);
95 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
96 va_end(ap);
97
98 printf("%s\n", buf);
99 }
100
101 static const glsl_type *
102 read_type(_mesa_glsl_parse_state *st, s_expression *expr)
103 {
104 s_list *list = SX_AS_LIST(expr);
105 if (list != NULL) {
106 s_symbol *type_sym = SX_AS_SYMBOL(list->subexpressions.get_head());
107 if (type_sym == NULL) {
108 ir_read_error(expr, "expected type (array ...) or (struct ...)");
109 return NULL;
110 }
111 if (strcmp(type_sym->value(), "array") == 0) {
112 if (list->length() != 3) {
113 ir_read_error(expr, "expected type (array <type> <int>)");
114 return NULL;
115 }
116
117 // Read base type
118 s_expression *base_expr = (s_expression*) type_sym->next;
119 const glsl_type *base_type = read_type(st, base_expr);
120 if (base_type == NULL) {
121 ir_read_error(expr, "when reading base type of array");
122 return NULL;
123 }
124
125 // Read array size
126 s_int *size = SX_AS_INT(base_expr->next);
127 if (size == NULL) {
128 ir_read_error(expr, "found non-integer array size");
129 return NULL;
130 }
131
132 return glsl_type::get_array_instance(base_type, size->value());
133 } else if (strcmp(type_sym->value(), "struct") == 0) {
134 assert(false); // FINISHME
135 } else {
136 ir_read_error(expr, "expected (array ...) or (struct ...); found (%s ...)", type_sym->value());
137 return NULL;
138 }
139 }
140
141 s_symbol *type_sym = SX_AS_SYMBOL(expr);
142 if (type_sym == NULL) {
143 ir_read_error(expr, "expected <type> (symbol or list)");
144 return NULL;
145 }
146
147 const glsl_type *type = st->symbols->get_type(type_sym->value());
148 if (type == NULL)
149 ir_read_error(expr, "invalid type: %s", type_sym->value());
150
151 return type;
152 }
153
154
155 static ir_instruction *
156 read_instruction(_mesa_glsl_parse_state *st, s_expression *expr)
157 {
158 s_list *list = SX_AS_LIST(expr);
159 if (list == NULL || list->subexpressions.is_empty())
160 return NULL;
161
162 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
163 if (tag == NULL) {
164 ir_read_error(expr, "expected instruction tag");
165 return NULL;
166 }
167
168 ir_instruction *inst = NULL;
169 if (strcmp(tag->value(), "declare") == 0)
170 inst = read_declaration(st, list);
171 else if (strcmp(tag->value(), "return") == 0)
172 inst = read_return(st, list);
173 else
174 ir_read_error(expr, "unrecognized instruction tag: %s", tag->value());
175
176 return inst;
177 }
178
179
180 static ir_variable *
181 read_declaration(_mesa_glsl_parse_state *st, s_list *list)
182 {
183 if (list->length() != 4) {
184 ir_read_error(list, "expected (declare (<qualifiers>) <type> <name>)");
185 return NULL;
186 }
187
188 s_list *quals = SX_AS_LIST(list->subexpressions.head->next);
189 if (quals == NULL) {
190 ir_read_error(list, "expected a list of variable qualifiers");
191 return NULL;
192 }
193
194 s_expression *type_expr = (s_expression*) quals->next;
195 const glsl_type *type = read_type(st, type_expr);
196 if (type == NULL)
197 return NULL;
198
199 s_symbol *var_name = SX_AS_SYMBOL(type_expr->next);
200 if (var_name == NULL) {
201 ir_read_error(list, "expected variable name, found non-symbol");
202 return NULL;
203 }
204
205 ir_variable *var = new ir_variable(type, var_name->value());
206
207 foreach_iter(exec_list_iterator, it, quals->subexpressions) {
208 s_symbol *qualifier = SX_AS_SYMBOL(it.get());
209 if (qualifier == NULL) {
210 ir_read_error(list, "qualifier list must contain only symbols");
211 delete var;
212 return NULL;
213 }
214
215 // FINISHME: Check for duplicate/conflicting qualifiers.
216 if (strcmp(qualifier->value(), "centroid") == 0) {
217 var->centroid = 1;
218 } else if (strcmp(qualifier->value(), "invariant") == 0) {
219 var->invariant = 1;
220 } else if (strcmp(qualifier->value(), "uniform") == 0) {
221 var->mode = ir_var_uniform;
222 } else if (strcmp(qualifier->value(), "auto") == 0) {
223 var->mode = ir_var_auto;
224 } else if (strcmp(qualifier->value(), "in") == 0) {
225 var->mode = ir_var_in;
226 } else if (strcmp(qualifier->value(), "out") == 0) {
227 var->mode = ir_var_out;
228 } else if (strcmp(qualifier->value(), "inout") == 0) {
229 var->mode = ir_var_inout;
230 } else if (strcmp(qualifier->value(), "smooth") == 0) {
231 var->interpolation = ir_var_smooth;
232 } else if (strcmp(qualifier->value(), "flat") == 0) {
233 var->interpolation = ir_var_flat;
234 } else if (strcmp(qualifier->value(), "noperspective") == 0) {
235 var->interpolation = ir_var_noperspective;
236 } else {
237 ir_read_error(list, "unknown qualifier: %s", qualifier->value());
238 delete var;
239 return NULL;
240 }
241 }
242
243 // Add the variable to the symbol table
244 st->symbols->add_variable(var_name->value(), var);
245
246 return var;
247 }
248
249
250 static ir_return *
251 read_return(_mesa_glsl_parse_state *st, s_list *list)
252 {
253 if (list->length() != 2) {
254 ir_read_error(list, "expected (return <rvalue>)");
255 return NULL;
256 }
257
258 s_expression *expr = (s_expression*) list->subexpressions.head->next;
259
260 ir_rvalue *retval = read_rvalue(st, expr);
261 if (retval == NULL) {
262 ir_read_error(list, "when reading return value");
263 return NULL;
264 }
265
266 return new ir_return(retval);
267 }
268
269
270 static ir_rvalue *
271 read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
272 {
273 s_list *list = SX_AS_LIST(expr);
274 if (list == NULL || list->subexpressions.is_empty())
275 return NULL;
276
277 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
278 if (tag == NULL) {
279 ir_read_error(expr, "expected rvalue tag");
280 return NULL;
281 }
282
283 ir_rvalue *rvalue = NULL;
284 if (strcmp(tag->value(), "swiz") == 0)
285 rvalue = read_swizzle(st, list);
286 else if (strcmp(tag->value(), "assign") == 0)
287 rvalue = read_assignment(st, list);
288 else if (strcmp(tag->value(), "expression") == 0)
289 rvalue = read_expression(st, list);
290 // FINISHME: ir_call
291 // FINISHME: dereference
292 else if (strcmp(tag->value(), "constant") == 0)
293 rvalue = read_constant(st, list);
294 else
295 ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value());
296
297 return rvalue;
298 }
299
300 static ir_assignment *
301 read_assignment(_mesa_glsl_parse_state *st, s_list *list)
302 {
303 if (list->length() != 4) {
304 ir_read_error(list, "expected (assign <condition> <lhs> <rhs>)");
305 return NULL;
306 }
307
308 s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
309 s_expression *lhs_expr = (s_expression*) cond_expr->next;
310 s_expression *rhs_expr = (s_expression*) lhs_expr->next;
311
312 // FINISHME: Deal with "true" condition
313 ir_rvalue *condition = read_rvalue(st, cond_expr);
314 if (condition == NULL) {
315 ir_read_error(list, "when reading condition of assignment");
316 return NULL;
317 }
318
319 ir_rvalue *lhs = read_rvalue(st, lhs_expr);
320 if (lhs == NULL) {
321 ir_read_error(list, "when reading left-hand side of assignment");
322 return NULL;
323 }
324
325 ir_rvalue *rhs = read_rvalue(st, rhs_expr);
326 if (rhs == NULL) {
327 ir_read_error(list, "when reading right-hand side of assignment");
328 return NULL;
329 }
330
331 return new ir_assignment(lhs, rhs, condition);
332 }
333
334
335 static ir_expression *
336 read_expression(_mesa_glsl_parse_state *st, s_list *list)
337 {
338 const unsigned list_length = list->length();
339 if (list_length < 4) {
340 ir_read_error(list, "expected (expression <type> <operator> <operand> "
341 "[<operand>])");
342 return NULL;
343 }
344
345 s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
346 const glsl_type *type = read_type(st, type_expr);
347 if (type == NULL)
348 return NULL;
349
350 /* Read the operator */
351 s_symbol *op_sym = SX_AS_SYMBOL(type_expr->next);
352 if (op_sym == NULL) {
353 ir_read_error(list, "expected operator, found non-symbol");
354 return NULL;
355 }
356
357 ir_expression_operation op = ir_expression::get_operator(op_sym->value());
358 if (op == (ir_expression_operation) -1) {
359 ir_read_error(list, "invalid operator: %s", op_sym->value());
360 return NULL;
361 }
362
363 /* Now that we know the operator, check for the right number of operands */
364 if (ir_expression::get_num_operands(op) == 2) {
365 if (list_length != 5) {
366 ir_read_error(list, "expected (expression %s <operand1> <operand2>)",
367 op_sym->value());
368 return NULL;
369 }
370 } else {
371 if (list_length != 4) {
372 ir_read_error(list, "expected (expression %s <operand>)",
373 op_sym->value());
374 return NULL;
375 }
376 }
377
378 s_expression *exp1 = (s_expression*) (op_sym->next);
379 ir_rvalue *arg1 = read_rvalue(st, exp1);
380 if (arg1 == NULL) {
381 ir_read_error(list, "when reading first operand of %s", op_sym->value());
382 return NULL;
383 }
384
385 ir_rvalue *arg2 = NULL;
386 if (ir_expression::get_num_operands(op) == 2) {
387 s_expression *exp2 = (s_expression*) (exp1->next);
388 arg2 = read_rvalue(st, exp2);
389 if (arg2 == NULL) {
390 ir_read_error(list, "when reading second operand of %s",
391 op_sym->value());
392 return NULL;
393 }
394 }
395
396 return new ir_expression(op, type, arg1, arg2);
397 }
398
399 static ir_swizzle *
400 read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
401 {
402 if (list->length() != 3) {
403 ir_read_error(list, "expected (swiz <swizzle> <rvalue>)");
404 return NULL;
405 }
406
407 s_symbol *swiz = SX_AS_SYMBOL(list->subexpressions.head->next);
408 if (swiz == NULL) {
409 ir_read_error(list, "expected a valid swizzle; found non-symbol");
410 return NULL;
411 }
412
413 unsigned num_components = strlen(swiz->value());
414 if (num_components > 4) {
415 ir_read_error(list, "expected a valid swizzle; found %s", swiz->value());
416 return NULL;
417 }
418
419 s_expression *sub = (s_expression*) swiz->next;
420 if (sub == NULL) {
421 ir_read_error(list, "expected rvalue: (swizzle %s <rvalue>)", swiz->value());
422 return NULL;
423 }
424
425 ir_rvalue *rvalue = read_rvalue(st, sub);
426 if (rvalue == NULL)
427 return NULL;
428
429 return ir_swizzle::create(rvalue, swiz->value(), num_components);
430 }
431
432 static ir_constant *
433 read_constant(_mesa_glsl_parse_state *st, s_list *list)
434 {
435 if (list->length() != 3) {
436 ir_read_error(list, "expected (constant <type> (<num> ... <num>))");
437 return NULL;
438 }
439
440 s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
441 const glsl_type *type = read_type(st, type_expr);
442 if (type == NULL)
443 return NULL;
444
445 s_list *values = SX_AS_LIST(type_expr->next);
446 if (values == NULL) {
447 ir_read_error(list, "expected (constant <type> (<num> ... <num>))");
448 return NULL;
449 }
450
451 const glsl_type *const base_type = type->get_base_type();
452
453 unsigned u[16];
454 int i[16];
455 float f[16];
456 bool b[16];
457
458 // Read in list of values (at most 16).
459 int k = 0;
460 foreach_iter(exec_list_iterator, it, values->subexpressions) {
461 if (k >= 16) {
462 ir_read_error(values, "expected at most 16 numbers");
463 return NULL;
464 }
465
466 s_expression *expr = (s_expression*) it.get();
467
468 if (base_type->base_type == GLSL_TYPE_FLOAT) {
469 s_number *value = SX_AS_NUMBER(expr);
470 if (value == NULL) {
471 ir_read_error(values, "expected numbers");
472 return NULL;
473 }
474 f[k] = value->fvalue();
475 } else {
476 s_int *value = SX_AS_INT(expr);
477 if (value == NULL) {
478 ir_read_error(values, "expected integers");
479 return NULL;
480 }
481
482 switch (base_type->base_type) {
483 case GLSL_TYPE_UINT: {
484 u[k] = value->value();
485 break;
486 }
487 case GLSL_TYPE_INT: {
488 i[k] = value->value();
489 break;
490 }
491 case GLSL_TYPE_BOOL: {
492 b[k] = value->value();
493 break;
494 }
495 default:
496 ir_read_error(values, "unsupported constant type");
497 return NULL;
498 }
499 }
500 ++k;
501 }
502 switch (base_type->base_type) {
503 case GLSL_TYPE_UINT:
504 return new ir_constant(type, u);
505 case GLSL_TYPE_INT:
506 return new ir_constant(type, i);
507 case GLSL_TYPE_BOOL:
508 return new ir_constant(type, b);
509 case GLSL_TYPE_FLOAT:
510 return new ir_constant(type, f);
511 }
512 return NULL; // should not be reached
513 }