Implement "sign" builtin via a new expression operator.
[mesa.git] / ir.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 <string.h>
24 #include "main/imports.h"
25 #include "ir.h"
26 #include "ir_visitor.h"
27 #include "glsl_types.h"
28
29 ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
30 ir_rvalue *condition)
31 {
32 this->lhs = lhs;
33 this->rhs = rhs;
34 this->condition = condition;
35 }
36
37
38 ir_expression::ir_expression(int op, const struct glsl_type *type,
39 ir_rvalue *op0, ir_rvalue *op1)
40 {
41 this->type = type;
42 this->operation = ir_expression_operation(op);
43 this->operands[0] = op0;
44 this->operands[1] = op1;
45 }
46
47 unsigned int
48 ir_expression::get_num_operands(ir_expression_operation op)
49 {
50 /* Update ir_print_visitor.cpp when updating this list. */
51 const int num_operands[] = {
52 1, /* ir_unop_bit_not */
53 1, /* ir_unop_logic_not */
54 1, /* ir_unop_neg */
55 1, /* ir_unop_abs */
56 1, /* ir_unop_sign */
57 1, /* ir_unop_rcp */
58 1, /* ir_unop_rsq */
59 1, /* ir_unop_sqrt */
60 1, /* ir_unop_exp */
61 1, /* ir_unop_log */
62 1, /* ir_unop_exp2 */
63 1, /* ir_unop_log2 */
64 1, /* ir_unop_f2i */
65 1, /* ir_unop_i2f */
66 1, /* ir_unop_f2b */
67 1, /* ir_unop_b2f */
68 1, /* ir_unop_i2b */
69 1, /* ir_unop_b2i */
70 1, /* ir_unop_u2f */
71
72 1, /* ir_unop_trunc */
73 1, /* ir_unop_ceil */
74 1, /* ir_unop_floor */
75
76 2, /* ir_binop_add */
77 2, /* ir_binop_sub */
78 2, /* ir_binop_mul */
79 2, /* ir_binop_div */
80 2, /* ir_binop_mod */
81
82 2, /* ir_binop_less */
83 2, /* ir_binop_greater */
84 2, /* ir_binop_lequal */
85 2, /* ir_binop_gequal */
86 2, /* ir_binop_equal */
87 2, /* ir_binop_nequal */
88
89 2, /* ir_binop_lshift */
90 2, /* ir_binop_rshift */
91 2, /* ir_binop_bit_and */
92 2, /* ir_binop_bit_xor */
93 2, /* ir_binop_bit_or */
94
95 2, /* ir_binop_logic_and */
96 2, /* ir_binop_logic_xor */
97 2, /* ir_binop_logic_or */
98
99 2, /* ir_binop_dot */
100 2, /* ir_binop_min */
101 2, /* ir_binop_max */
102
103 2, /* ir_binop_pow */
104 };
105
106 assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1);
107
108 return num_operands[op];
109 }
110
111 static const char *const operator_strs[] = {
112 "~",
113 "!",
114 "neg",
115 "abs",
116 "sign",
117 "rcp",
118 "rsq",
119 "sqrt",
120 "exp",
121 "log",
122 "exp2",
123 "log2",
124 "f2i",
125 "i2f",
126 "f2b",
127 "b2f",
128 "i2b",
129 "b2i",
130 "u2f",
131 "trunc",
132 "ceil",
133 "floor",
134 "+",
135 "-",
136 "*",
137 "/",
138 "%",
139 "<",
140 ">",
141 "<=",
142 ">=",
143 "==",
144 "!=",
145 "<<",
146 ">>",
147 "&",
148 "^",
149 "|",
150 "&&",
151 "^^",
152 "||",
153 "dot",
154 "min",
155 "max",
156 "pow",
157 };
158
159 const char *ir_expression::operator_string()
160 {
161 assert((unsigned int) operation <=
162 sizeof(operator_strs) / sizeof(operator_strs[0]));
163 return operator_strs[operation];
164 }
165
166 ir_expression_operation
167 ir_expression::get_operator(const char *str)
168 {
169 const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
170 for (int op = 0; op < operator_count; op++) {
171 if (strcmp(str, operator_strs[op]) == 0)
172 return (ir_expression_operation) op;
173 }
174 return (ir_expression_operation) -1;
175 }
176
177 ir_constant::ir_constant(const struct glsl_type *type, const void *data)
178 {
179 unsigned size = 0;
180
181 this->type = type;
182 switch (type->base_type) {
183 case GLSL_TYPE_UINT: size = sizeof(this->value.u[0]); break;
184 case GLSL_TYPE_INT: size = sizeof(this->value.i[0]); break;
185 case GLSL_TYPE_FLOAT: size = sizeof(this->value.f[0]); break;
186 case GLSL_TYPE_BOOL: size = sizeof(this->value.b[0]); break;
187 default:
188 /* FINISHME: What to do? Exceptions are not the answer.
189 */
190 break;
191 }
192
193 memcpy(& this->value, data, size * type->components());
194 }
195
196 ir_constant::ir_constant(float f)
197 {
198 this->type = glsl_type::float_type;
199 this->value.f[0] = f;
200 }
201
202 ir_constant::ir_constant(unsigned int u)
203 {
204 this->type = glsl_type::uint_type;
205 this->value.u[0] = u;
206 }
207
208 ir_constant::ir_constant(int i)
209 {
210 this->type = glsl_type::int_type;
211 this->value.i[0] = i;
212 }
213
214 ir_constant::ir_constant(bool b)
215 {
216 this->type = glsl_type::bool_type;
217 this->value.b[0] = b;
218 }
219
220
221 ir_dereference::ir_dereference(ir_instruction *var)
222 {
223 this->mode = ir_reference_variable;
224 this->var = var;
225 this->type = (var != NULL) ? var->type : glsl_type::error_type;
226 }
227
228
229 ir_dereference::ir_dereference(ir_instruction *var,
230 ir_rvalue *array_index)
231 : mode(ir_reference_array), var(var)
232 {
233 type = glsl_type::error_type;
234
235 if (var != NULL) {
236 const glsl_type *const vt = var->type;
237
238 if (vt->is_array()) {
239 type = vt->element_type();
240 } else if (vt->is_matrix()) {
241 type = vt->column_type();
242 } else if (vt->is_vector()) {
243 type = vt->get_base_type();
244 }
245 }
246
247 this->selector.array_index = array_index;
248 }
249
250 ir_dereference::ir_dereference(ir_instruction *variable, const char *field)
251 : mode(ir_reference_record), var(variable)
252 {
253 this->selector.field = field;
254 this->type = (var != NULL)
255 ? var->type->field_type(field) : glsl_type::error_type;
256 }
257
258 bool
259 ir_dereference::is_lvalue()
260 {
261 if (var == NULL)
262 return false;
263
264 ir_variable *const as_var = var->as_variable();
265 if (mode == ir_reference_variable) {
266 if (as_var == NULL)
267 return false;
268
269 if (as_var->type->is_array() && !as_var->array_lvalue)
270 return false;
271 }
272
273 if (as_var != NULL)
274 return !as_var->read_only;
275
276 /* Walk up the dereference chain and figure out if the variable is read-only.
277 */
278 return this->var->as_rvalue()->is_lvalue();
279 }
280
281 ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
282 unsigned w, unsigned count)
283 : val(val)
284 {
285 assert((count >= 1) && (count <= 4));
286
287 const unsigned dup_mask = 0
288 | ((count > 1) ? ((1U << y) & ((1U << x) )) : 0)
289 | ((count > 2) ? ((1U << z) & ((1U << x) | (1U << y) )) : 0)
290 | ((count > 3) ? ((1U << w) & ((1U << x) | (1U << y) | (1U << z))) : 0);
291
292 assert(x <= 3);
293 assert(y <= 3);
294 assert(z <= 3);
295 assert(w <= 3);
296
297 mask.x = x;
298 mask.y = y;
299 mask.z = z;
300 mask.w = w;
301 mask.num_components = count;
302 mask.has_duplicates = dup_mask != 0;
303
304 /* Based on the number of elements in the swizzle and the base type
305 * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
306 * generate the type of the resulting value.
307 */
308 type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
309 }
310
311 ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
312 {
313 this->val = val;
314 this->mask = mask;
315 this->type = glsl_type::get_instance(val->type->base_type,
316 mask.num_components, 1);
317 }
318
319 #define X 1
320 #define R 5
321 #define S 9
322 #define I 13
323
324 ir_swizzle *
325 ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
326 {
327 /* For each possible swizzle character, this table encodes the value in
328 * \c idx_map that represents the 0th element of the vector. For invalid
329 * swizzle characters (e.g., 'k'), a special value is used that will allow
330 * detection of errors.
331 */
332 static const unsigned char base_idx[26] = {
333 /* a b c d e f g h i j k l m */
334 R, R, I, I, I, I, R, I, I, I, I, I, I,
335 /* n o p q r s t u v w x y z */
336 I, I, S, S, R, S, S, I, I, X, X, X, X
337 };
338
339 /* Each valid swizzle character has an entry in the previous table. This
340 * table encodes the base index encoded in the previous table plus the actual
341 * index of the swizzle character. When processing swizzles, the first
342 * character in the string is indexed in the previous table. Each character
343 * in the string is indexed in this table, and the value found there has the
344 * value form the first table subtracted. The result must be on the range
345 * [0,3].
346 *
347 * For example, the string "wzyx" will get X from the first table. Each of
348 * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
349 * subtraction, the swizzle values are { 3, 2, 1, 0 }.
350 *
351 * The string "wzrg" will get X from the first table. Each of the characters
352 * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
353 * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
354 * [0,3], the error is detected.
355 */
356 static const unsigned char idx_map[26] = {
357 /* a b c d e f g h i j k l m */
358 R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
359 /* n o p q r s t u v w x y z */
360 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
361 };
362
363 int swiz_idx[4] = { 0, 0, 0, 0 };
364 unsigned i;
365
366
367 /* Validate the first character in the swizzle string and look up the base
368 * index value as described above.
369 */
370 if ((str[0] < 'a') || (str[0] > 'z'))
371 return NULL;
372
373 const unsigned base = base_idx[str[0] - 'a'];
374
375
376 for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
377 /* Validate the next character, and, as described above, convert it to a
378 * swizzle index.
379 */
380 if ((str[i] < 'a') || (str[i] > 'z'))
381 return NULL;
382
383 swiz_idx[i] = idx_map[str[i] - 'a'] - base;
384 if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
385 return NULL;
386 }
387
388 if (str[i] != '\0')
389 return NULL;
390
391 return new ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
392 swiz_idx[3], i);
393 }
394
395 #undef X
396 #undef R
397 #undef S
398 #undef I
399
400
401 ir_variable::ir_variable(const struct glsl_type *type, const char *name)
402 : max_array_access(0), read_only(false), centroid(false), invariant(false),
403 mode(ir_var_auto), interpolation(ir_var_smooth)
404 {
405 this->type = type;
406 this->name = name;
407 this->constant_value = NULL;
408
409 if (type && type->base_type == GLSL_TYPE_SAMPLER)
410 this->read_only = true;
411 }
412
413
414 ir_function_signature::ir_function_signature(const glsl_type *return_type)
415 : return_type(return_type), is_defined(false)
416 {
417 /* empty */
418 }
419
420
421 const char *
422 ir_function_signature::qualifiers_match(exec_list *params)
423 {
424 exec_list_iterator iter_a = parameters.iterator();
425 exec_list_iterator iter_b = params->iterator();
426
427 /* check that the qualifiers match. */
428 while (iter_a.has_next()) {
429 ir_variable *a = (ir_variable *)iter_a.get();
430 ir_variable *b = (ir_variable *)iter_b.get();
431
432 if (a->read_only != b->read_only ||
433 a->interpolation != b->interpolation ||
434 a->centroid != b->centroid) {
435
436 /* parameter a's qualifiers don't match */
437 return a->name;
438 }
439
440 iter_a.next();
441 iter_b.next();
442 }
443 return NULL;
444 }
445
446
447 void
448 ir_function_signature::replace_parameters(exec_list *new_params)
449 {
450 /* Destroy all of the previous parameter information. If the previous
451 * parameter information comes from the function prototype, it may either
452 * specify incorrect parameter names or not have names at all.
453 */
454 foreach_iter(exec_list_iterator, iter, parameters) {
455 assert(((ir_instruction *) iter.get())->as_variable() != NULL);
456
457 iter.remove();
458 delete (ir_instruction*) iter.get();
459 }
460
461 new_params->move_nodes_to(&parameters);
462 }
463
464
465 ir_function::ir_function(const char *name)
466 : name(name)
467 {
468 /* empty */
469 }
470
471
472 ir_call *
473 ir_call::get_error_instruction()
474 {
475 ir_call *call = new ir_call;
476
477 call->type = glsl_type::error_type;
478 return call;
479 }
480
481 void
482 visit_exec_list(exec_list *list, ir_visitor *visitor)
483 {
484 foreach_iter(exec_list_iterator, iter, *list) {
485 ((ir_instruction *)iter.get())->accept(visitor);
486 }
487 }
488