Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 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 
24
#include "main/core.h" /* for MAX2 */
25
#include "ir.h"
26
#include "ir_visitor.h"
27
#include "glsl_types.h"
28
 
29
ir_rvalue::ir_rvalue()
30
{
31
   this->type = glsl_type::error_type;
32
}
33
 
34
bool ir_rvalue::is_zero() const
35
{
36
   return false;
37
}
38
 
39
bool ir_rvalue::is_one() const
40
{
41
   return false;
42
}
43
 
44
bool ir_rvalue::is_negative_one() const
45
{
46
   return false;
47
}
48
 
49
/**
50
 * Modify the swizzle make to move one component to another
51
 *
52
 * \param m    IR swizzle to be modified
53
 * \param from Component in the RHS that is to be swizzled
54
 * \param to   Desired swizzle location of \c from
55
 */
56
static void
57
update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
58
{
59
   switch (to) {
60
   case 0: m.x = from; break;
61
   case 1: m.y = from; break;
62
   case 2: m.z = from; break;
63
   case 3: m.w = from; break;
64
   default: assert(!"Should not get here.");
65
   }
66
 
67
   m.num_components = MAX2(m.num_components, (to + 1));
68
}
69
 
70
void
71
ir_assignment::set_lhs(ir_rvalue *lhs)
72
{
73
   void *mem_ctx = this;
74
   bool swizzled = false;
75
 
76
   while (lhs != NULL) {
77
      ir_swizzle *swiz = lhs->as_swizzle();
78
 
79
      if (swiz == NULL)
80
	 break;
81
 
82
      unsigned write_mask = 0;
83
      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
84
 
85
      for (unsigned i = 0; i < swiz->mask.num_components; i++) {
86
	 unsigned c = 0;
87
 
88
	 switch (i) {
89
	 case 0: c = swiz->mask.x; break;
90
	 case 1: c = swiz->mask.y; break;
91
	 case 2: c = swiz->mask.z; break;
92
	 case 3: c = swiz->mask.w; break;
93
	 default: assert(!"Should not get here.");
94
	 }
95
 
96
	 write_mask |= (((this->write_mask >> i) & 1) << c);
97
	 update_rhs_swizzle(rhs_swiz, i, c);
98
      }
99
 
100
      this->write_mask = write_mask;
101
      lhs = swiz->val;
102
 
103
      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
104
      swizzled = true;
105
   }
106
 
107
   if (swizzled) {
108
      /* Now, RHS channels line up with the LHS writemask.  Collapse it
109
       * to just the channels that will be written.
110
       */
111
      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
112
      int rhs_chan = 0;
113
      for (int i = 0; i < 4; i++) {
114
	 if (write_mask & (1 << i))
115
	    update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
116
      }
117
      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
118
   }
119
 
120
   assert((lhs == NULL) || lhs->as_dereference());
121
 
122
   this->lhs = (ir_dereference *) lhs;
123
}
124
 
125
ir_variable *
126
ir_assignment::whole_variable_written()
127
{
128
   ir_variable *v = this->lhs->whole_variable_referenced();
129
 
130
   if (v == NULL)
131
      return NULL;
132
 
133
   if (v->type->is_scalar())
134
      return v;
135
 
136
   if (v->type->is_vector()) {
137
      const unsigned mask = (1U << v->type->vector_elements) - 1;
138
 
139
      if (mask != this->write_mask)
140
	 return NULL;
141
   }
142
 
143
   /* Either all the vector components are assigned or the variable is some
144
    * composite type (and the whole thing is assigned.
145
    */
146
   return v;
147
}
148
 
149
ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
150
			     ir_rvalue *condition, unsigned write_mask)
151
{
152
   this->ir_type = ir_type_assignment;
153
   this->condition = condition;
154
   this->rhs = rhs;
155
   this->lhs = lhs;
156
   this->write_mask = write_mask;
157
 
158
   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
159
      int lhs_components = 0;
160
      for (int i = 0; i < 4; i++) {
161
	 if (write_mask & (1 << i))
162
	    lhs_components++;
163
      }
164
 
165
      assert(lhs_components == this->rhs->type->vector_elements);
166
   }
167
}
168
 
169
ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
170
			     ir_rvalue *condition)
171
{
172
   this->ir_type = ir_type_assignment;
173
   this->condition = condition;
174
   this->rhs = rhs;
175
 
176
   /* If the RHS is a vector type, assume that all components of the vector
177
    * type are being written to the LHS.  The write mask comes from the RHS
178
    * because we can have a case where the LHS is a vec4 and the RHS is a
179
    * vec3.  In that case, the assignment is:
180
    *
181
    *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
182
    */
183
   if (rhs->type->is_vector())
184
      this->write_mask = (1U << rhs->type->vector_elements) - 1;
185
   else if (rhs->type->is_scalar())
186
      this->write_mask = 1;
187
   else
188
      this->write_mask = 0;
189
 
190
   this->set_lhs(lhs);
191
}
192
 
193
 
194
ir_expression::ir_expression(int op, const struct glsl_type *type,
195
			     ir_rvalue *op0)
196
{
197
   assert(get_num_operands(ir_expression_operation(op)) == 1);
198
   this->ir_type = ir_type_expression;
199
   this->type = type;
200
   this->operation = ir_expression_operation(op);
201
   this->operands[0] = op0;
202
   this->operands[1] = NULL;
203
   this->operands[2] = NULL;
204
   this->operands[3] = NULL;
205
}
206
 
207
ir_expression::ir_expression(int op, const struct glsl_type *type,
208
			     ir_rvalue *op0, ir_rvalue *op1)
209
{
210
   assert(((op1 == NULL) && (get_num_operands(ir_expression_operation(op)) == 1))
211
	  || (get_num_operands(ir_expression_operation(op)) == 2));
212
   this->ir_type = ir_type_expression;
213
   this->type = type;
214
   this->operation = ir_expression_operation(op);
215
   this->operands[0] = op0;
216
   this->operands[1] = op1;
217
   this->operands[2] = NULL;
218
   this->operands[3] = NULL;
219
}
220
 
221
ir_expression::ir_expression(int op, const struct glsl_type *type,
222
			     ir_rvalue *op0, ir_rvalue *op1,
223
			     ir_rvalue *op2, ir_rvalue *op3)
224
{
225
   this->ir_type = ir_type_expression;
226
   this->type = type;
227
   this->operation = ir_expression_operation(op);
228
   this->operands[0] = op0;
229
   this->operands[1] = op1;
230
   this->operands[2] = op2;
231
   this->operands[3] = op3;
232
}
233
 
234
ir_expression::ir_expression(int op, ir_rvalue *op0)
235
{
236
   this->ir_type = ir_type_expression;
237
 
238
   this->operation = ir_expression_operation(op);
239
   this->operands[0] = op0;
240
   this->operands[1] = NULL;
241
   this->operands[2] = NULL;
242
   this->operands[3] = NULL;
243
 
244
   assert(op <= ir_last_unop);
245
 
246
   switch (this->operation) {
247
   case ir_unop_bit_not:
248
   case ir_unop_logic_not:
249
   case ir_unop_neg:
250
   case ir_unop_abs:
251
   case ir_unop_sign:
252
   case ir_unop_rcp:
253
   case ir_unop_rsq:
254
   case ir_unop_sqrt:
255
   case ir_unop_exp:
256
   case ir_unop_log:
257
   case ir_unop_exp2:
258
   case ir_unop_log2:
259
   case ir_unop_trunc:
260
   case ir_unop_ceil:
261
   case ir_unop_floor:
262
   case ir_unop_fract:
263
   case ir_unop_round_even:
264
   case ir_unop_cos:
265
   case ir_unop_dFdx:
266
   case ir_unop_dFdy:
267
      this->type = op0->type;
268
      break;
269
 
270
   case ir_unop_any:
271
      this->type = glsl_type::bool_type;
272
      break;
273
 
274
   default:
275
      assert(!"not reached: missing automatic type setup for ir_expression");
276
      this->type = op0->type;
277
      break;
278
   }
279
}
280
 
281
ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
282
{
283
   this->ir_type = ir_type_expression;
284
 
285
   this->operation = ir_expression_operation(op);
286
   this->operands[0] = op0;
287
   this->operands[1] = op1;
288
   this->operands[2] = NULL;
289
   this->operands[3] = NULL;
290
 
291
   assert(op > ir_last_unop);
292
 
293
   switch (this->operation) {
294
   case ir_binop_all_equal:
295
   case ir_binop_any_nequal:
296
      this->type = glsl_type::bool_type;
297
      break;
298
 
299
   case ir_binop_add:
300
   case ir_binop_sub:
301
   case ir_binop_min:
302
   case ir_binop_max:
303
   case ir_binop_pow:
304
   case ir_binop_mul:
305
      if (op0->type->is_scalar()) {
306
	 this->type = op1->type;
307
      } else if (op1->type->is_scalar()) {
308
	 this->type = op0->type;
309
      } else {
310
	 /* FINISHME: matrix types */
311
	 assert(!op0->type->is_matrix() && !op1->type->is_matrix());
312
	 assert(op0->type == op1->type);
313
	 this->type = op0->type;
314
      }
315
      break;
316
 
317
   case ir_binop_logic_and:
318
   case ir_binop_logic_or:
319
      if (op0->type->is_scalar()) {
320
	 this->type = op1->type;
321
      } else if (op1->type->is_scalar()) {
322
	 this->type = op0->type;
323
      }
324
      break;
325
 
326
   case ir_binop_dot:
327
      this->type = glsl_type::float_type;
328
      break;
329
 
330
   default:
331
      assert(!"not reached: missing automatic type setup for ir_expression");
332
      this->type = glsl_type::float_type;
333
   }
334
}
335
 
336
unsigned int
337
ir_expression::get_num_operands(ir_expression_operation op)
338
{
339
   assert(op <= ir_last_opcode);
340
 
341
   if (op <= ir_last_unop)
342
      return 1;
343
 
344
   if (op <= ir_last_binop)
345
      return 2;
346
 
347
   if (op == ir_quadop_vector)
348
      return 4;
349
 
350
   assert(false);
351
   return 0;
352
}
353
 
354
static const char *const operator_strs[] = {
355
   "~",
356
   "!",
357
   "neg",
358
   "abs",
359
   "sign",
360
   "rcp",
361
   "rsq",
362
   "sqrt",
363
   "exp",
364
   "log",
365
   "exp2",
366
   "log2",
367
   "f2i",
368
   "i2f",
369
   "f2b",
370
   "b2f",
371
   "i2b",
372
   "b2i",
373
   "u2f",
374
   "any",
375
   "trunc",
376
   "ceil",
377
   "floor",
378
   "fract",
379
   "round_even",
380
   "sin",
381
   "cos",
382
   "sin_reduced",
383
   "cos_reduced",
384
   "dFdx",
385
   "dFdy",
386
   "noise",
387
   "+",
388
   "-",
389
   "*",
390
   "/",
391
   "%",
392
   "<",
393
   ">",
394
   "<=",
395
   ">=",
396
   "==",
397
   "!=",
398
   "all_equal",
399
   "any_nequal",
400
   "<<",
401
   ">>",
402
   "&",
403
   "^",
404
   "|",
405
   "&&",
406
   "^^",
407
   "||",
408
   "dot",
409
   "min",
410
   "max",
411
   "pow",
412
   "vector",
413
};
414
 
415
const char *ir_expression::operator_string(ir_expression_operation op)
416
{
417
   assert((unsigned int) op < Elements(operator_strs));
418
   assert(Elements(operator_strs) == (ir_quadop_vector + 1));
419
   return operator_strs[op];
420
}
421
 
422
const char *ir_expression::operator_string()
423
{
424
   return operator_string(this->operation);
425
}
426
 
427
ir_expression_operation
428
ir_expression::get_operator(const char *str)
429
{
430
   const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
431
   for (int op = 0; op < operator_count; op++) {
432
      if (strcmp(str, operator_strs[op]) == 0)
433
	 return (ir_expression_operation) op;
434
   }
435
   return (ir_expression_operation) -1;
436
}
437
 
438
ir_constant::ir_constant()
439
{
440
   this->ir_type = ir_type_constant;
441
}
442
 
443
ir_constant::ir_constant(const struct glsl_type *type,
444
			 const ir_constant_data *data)
445
{
446
   assert((type->base_type >= GLSL_TYPE_UINT)
447
	  && (type->base_type <= GLSL_TYPE_BOOL));
448
 
449
   this->ir_type = ir_type_constant;
450
   this->type = type;
451
   memcpy(& this->value, data, sizeof(this->value));
452
}
453
 
454
ir_constant::ir_constant(float f)
455
{
456
   this->ir_type = ir_type_constant;
457
   this->type = glsl_type::float_type;
458
   this->value.f[0] = f;
459
   for (int i = 1; i < 16; i++)  {
460
      this->value.f[i] = 0;
461
   }
462
}
463
 
464
ir_constant::ir_constant(unsigned int u)
465
{
466
   this->ir_type = ir_type_constant;
467
   this->type = glsl_type::uint_type;
468
   this->value.u[0] = u;
469
   for (int i = 1; i < 16; i++) {
470
      this->value.u[i] = 0;
471
   }
472
}
473
 
474
ir_constant::ir_constant(int i)
475
{
476
   this->ir_type = ir_type_constant;
477
   this->type = glsl_type::int_type;
478
   this->value.i[0] = i;
479
   for (int i = 1; i < 16; i++) {
480
      this->value.i[i] = 0;
481
   }
482
}
483
 
484
ir_constant::ir_constant(bool b)
485
{
486
   this->ir_type = ir_type_constant;
487
   this->type = glsl_type::bool_type;
488
   this->value.b[0] = b;
489
   for (int i = 1; i < 16; i++) {
490
      this->value.b[i] = false;
491
   }
492
}
493
 
494
ir_constant::ir_constant(const ir_constant *c, unsigned i)
495
{
496
   this->ir_type = ir_type_constant;
497
   this->type = c->type->get_base_type();
498
 
499
   switch (this->type->base_type) {
500
   case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
501
   case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
502
   case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
503
   case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
504
   default:              assert(!"Should not get here."); break;
505
   }
506
}
507
 
508
ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
509
{
510
   this->ir_type = ir_type_constant;
511
   this->type = type;
512
 
513
   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
514
	  || type->is_record() || type->is_array());
515
 
516
   if (type->is_array()) {
517
      this->array_elements = ralloc_array(this, ir_constant *, type->length);
518
      unsigned i = 0;
519
      foreach_list(node, value_list) {
520
	 ir_constant *value = (ir_constant *) node;
521
	 assert(value->as_constant() != NULL);
522
 
523
	 this->array_elements[i++] = value;
524
      }
525
      return;
526
   }
527
 
528
   /* If the constant is a record, the types of each of the entries in
529
    * value_list must be a 1-for-1 match with the structure components.  Each
530
    * entry must also be a constant.  Just move the nodes from the value_list
531
    * to the list in the ir_constant.
532
    */
533
   /* FINISHME: Should there be some type checking and / or assertions here? */
534
   /* FINISHME: Should the new constant take ownership of the nodes from
535
    * FINISHME: value_list, or should it make copies?
536
    */
537
   if (type->is_record()) {
538
      value_list->move_nodes_to(& this->components);
539
      return;
540
   }
541
 
542
   for (unsigned i = 0; i < 16; i++) {
543
      this->value.u[i] = 0;
544
   }
545
 
546
   ir_constant *value = (ir_constant *) (value_list->head);
547
 
548
   /* Constructors with exactly one scalar argument are special for vectors
549
    * and matrices.  For vectors, the scalar value is replicated to fill all
550
    * the components.  For matrices, the scalar fills the components of the
551
    * diagonal while the rest is filled with 0.
552
    */
553
   if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
554
      if (type->is_matrix()) {
555
	 /* Matrix - fill diagonal (rest is already set to 0) */
556
	 assert(type->base_type == GLSL_TYPE_FLOAT);
557
	 for (unsigned i = 0; i < type->matrix_columns; i++)
558
	    this->value.f[i * type->vector_elements + i] = value->value.f[0];
559
      } else {
560
	 /* Vector or scalar - fill all components */
561
	 switch (type->base_type) {
562
	 case GLSL_TYPE_UINT:
563
	 case GLSL_TYPE_INT:
564
	    for (unsigned i = 0; i < type->components(); i++)
565
	       this->value.u[i] = value->value.u[0];
566
	    break;
567
	 case GLSL_TYPE_FLOAT:
568
	    for (unsigned i = 0; i < type->components(); i++)
569
	       this->value.f[i] = value->value.f[0];
570
	    break;
571
	 case GLSL_TYPE_BOOL:
572
	    for (unsigned i = 0; i < type->components(); i++)
573
	       this->value.b[i] = value->value.b[0];
574
	    break;
575
	 default:
576
	    assert(!"Should not get here.");
577
	    break;
578
	 }
579
      }
580
      return;
581
   }
582
 
583
   if (type->is_matrix() && value->type->is_matrix()) {
584
      assert(value->next->is_tail_sentinel());
585
 
586
      /* From section 5.4.2 of the GLSL 1.20 spec:
587
       * "If a matrix is constructed from a matrix, then each component
588
       *  (column i, row j) in the result that has a corresponding component
589
       *  (column i, row j) in the argument will be initialized from there."
590
       */
591
      unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
592
      unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
593
      for (unsigned i = 0; i < cols; i++) {
594
	 for (unsigned j = 0; j < rows; j++) {
595
	    const unsigned src = i * value->type->vector_elements + j;
596
	    const unsigned dst = i * type->vector_elements + j;
597
	    this->value.f[dst] = value->value.f[src];
598
	 }
599
      }
600
 
601
      /* "All other components will be initialized to the identity matrix." */
602
      for (unsigned i = cols; i < type->matrix_columns; i++)
603
	 this->value.f[i * type->vector_elements + i] = 1.0;
604
 
605
      return;
606
   }
607
 
608
   /* Use each component from each entry in the value_list to initialize one
609
    * component of the constant being constructed.
610
    */
611
   for (unsigned i = 0; i < type->components(); /* empty */) {
612
      assert(value->as_constant() != NULL);
613
      assert(!value->is_tail_sentinel());
614
 
615
      for (unsigned j = 0; j < value->type->components(); j++) {
616
	 switch (type->base_type) {
617
	 case GLSL_TYPE_UINT:
618
	    this->value.u[i] = value->get_uint_component(j);
619
	    break;
620
	 case GLSL_TYPE_INT:
621
	    this->value.i[i] = value->get_int_component(j);
622
	    break;
623
	 case GLSL_TYPE_FLOAT:
624
	    this->value.f[i] = value->get_float_component(j);
625
	    break;
626
	 case GLSL_TYPE_BOOL:
627
	    this->value.b[i] = value->get_bool_component(j);
628
	    break;
629
	 default:
630
	    /* FINISHME: What to do?  Exceptions are not the answer.
631
	     */
632
	    break;
633
	 }
634
 
635
	 i++;
636
	 if (i >= type->components())
637
	    break;
638
      }
639
 
640
      value = (ir_constant *) value->next;
641
   }
642
}
643
 
644
ir_constant *
645
ir_constant::zero(void *mem_ctx, const glsl_type *type)
646
{
647
   assert(type->is_numeric() || type->is_boolean());
648
 
649
   ir_constant *c = new(mem_ctx) ir_constant;
650
   c->type = type;
651
   memset(&c->value, 0, sizeof(c->value));
652
 
653
   return c;
654
}
655
 
656
bool
657
ir_constant::get_bool_component(unsigned i) const
658
{
659
   switch (this->type->base_type) {
660
   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
661
   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
662
   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
663
   case GLSL_TYPE_BOOL:  return this->value.b[i];
664
   default:              assert(!"Should not get here."); break;
665
   }
666
 
667
   /* Must return something to make the compiler happy.  This is clearly an
668
    * error case.
669
    */
670
   return false;
671
}
672
 
673
float
674
ir_constant::get_float_component(unsigned i) const
675
{
676
   switch (this->type->base_type) {
677
   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
678
   case GLSL_TYPE_INT:   return (float) this->value.i[i];
679
   case GLSL_TYPE_FLOAT: return this->value.f[i];
680
   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
681
   default:              assert(!"Should not get here."); break;
682
   }
683
 
684
   /* Must return something to make the compiler happy.  This is clearly an
685
    * error case.
686
    */
687
   return 0.0;
688
}
689
 
690
int
691
ir_constant::get_int_component(unsigned i) const
692
{
693
   switch (this->type->base_type) {
694
   case GLSL_TYPE_UINT:  return this->value.u[i];
695
   case GLSL_TYPE_INT:   return this->value.i[i];
696
   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
697
   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
698
   default:              assert(!"Should not get here."); break;
699
   }
700
 
701
   /* Must return something to make the compiler happy.  This is clearly an
702
    * error case.
703
    */
704
   return 0;
705
}
706
 
707
unsigned
708
ir_constant::get_uint_component(unsigned i) const
709
{
710
   switch (this->type->base_type) {
711
   case GLSL_TYPE_UINT:  return this->value.u[i];
712
   case GLSL_TYPE_INT:   return this->value.i[i];
713
   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
714
   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
715
   default:              assert(!"Should not get here."); break;
716
   }
717
 
718
   /* Must return something to make the compiler happy.  This is clearly an
719
    * error case.
720
    */
721
   return 0;
722
}
723
 
724
ir_constant *
725
ir_constant::get_array_element(unsigned i) const
726
{
727
   assert(this->type->is_array());
728
 
729
   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
730
    *
731
    *     "Behavior is undefined if a shader subscripts an array with an index
732
    *     less than 0 or greater than or equal to the size the array was
733
    *     declared with."
734
    *
735
    * Most out-of-bounds accesses are removed before things could get this far.
736
    * There are cases where non-constant array index values can get constant
737
    * folded.
738
    */
739
   if (int(i) < 0)
740
      i = 0;
741
   else if (i >= this->type->length)
742
      i = this->type->length - 1;
743
 
744
   return array_elements[i];
745
}
746
 
747
ir_constant *
748
ir_constant::get_record_field(const char *name)
749
{
750
   int idx = this->type->field_index(name);
751
 
752
   if (idx < 0)
753
      return NULL;
754
 
755
   if (this->components.is_empty())
756
      return NULL;
757
 
758
   exec_node *node = this->components.head;
759
   for (int i = 0; i < idx; i++) {
760
      node = node->next;
761
 
762
      /* If the end of the list is encountered before the element matching the
763
       * requested field is found, return NULL.
764
       */
765
      if (node->is_tail_sentinel())
766
	 return NULL;
767
   }
768
 
769
   return (ir_constant *) node;
770
}
771
 
772
 
773
bool
774
ir_constant::has_value(const ir_constant *c) const
775
{
776
   if (this->type != c->type)
777
      return false;
778
 
779
   if (this->type->is_array()) {
780
      for (unsigned i = 0; i < this->type->length; i++) {
781
	 if (!this->array_elements[i]->has_value(c->array_elements[i]))
782
	    return false;
783
      }
784
      return true;
785
   }
786
 
787
   if (this->type->base_type == GLSL_TYPE_STRUCT) {
788
      const exec_node *a_node = this->components.head;
789
      const exec_node *b_node = c->components.head;
790
 
791
      while (!a_node->is_tail_sentinel()) {
792
	 assert(!b_node->is_tail_sentinel());
793
 
794
	 const ir_constant *const a_field = (ir_constant *) a_node;
795
	 const ir_constant *const b_field = (ir_constant *) b_node;
796
 
797
	 if (!a_field->has_value(b_field))
798
	    return false;
799
 
800
	 a_node = a_node->next;
801
	 b_node = b_node->next;
802
      }
803
 
804
      return true;
805
   }
806
 
807
   for (unsigned i = 0; i < this->type->components(); i++) {
808
      switch (this->type->base_type) {
809
      case GLSL_TYPE_UINT:
810
	 if (this->value.u[i] != c->value.u[i])
811
	    return false;
812
	 break;
813
      case GLSL_TYPE_INT:
814
	 if (this->value.i[i] != c->value.i[i])
815
	    return false;
816
	 break;
817
      case GLSL_TYPE_FLOAT:
818
	 if (this->value.f[i] != c->value.f[i])
819
	    return false;
820
	 break;
821
      case GLSL_TYPE_BOOL:
822
	 if (this->value.b[i] != c->value.b[i])
823
	    return false;
824
	 break;
825
      default:
826
	 assert(!"Should not get here.");
827
	 return false;
828
      }
829
   }
830
 
831
   return true;
832
}
833
 
834
bool
835
ir_constant::is_zero() const
836
{
837
   if (!this->type->is_scalar() && !this->type->is_vector())
838
      return false;
839
 
840
   for (unsigned c = 0; c < this->type->vector_elements; c++) {
841
      switch (this->type->base_type) {
842
      case GLSL_TYPE_FLOAT:
843
	 if (this->value.f[c] != 0.0)
844
	    return false;
845
	 break;
846
      case GLSL_TYPE_INT:
847
	 if (this->value.i[c] != 0)
848
	    return false;
849
	 break;
850
      case GLSL_TYPE_UINT:
851
	 if (this->value.u[c] != 0)
852
	    return false;
853
	 break;
854
      case GLSL_TYPE_BOOL:
855
	 if (this->value.b[c] != false)
856
	    return false;
857
	 break;
858
      default:
859
	 /* The only other base types are structures, arrays, and samplers.
860
	  * Samplers cannot be constants, and the others should have been
861
	  * filtered out above.
862
	  */
863
	 assert(!"Should not get here.");
864
	 return false;
865
      }
866
   }
867
 
868
   return true;
869
}
870
 
871
bool
872
ir_constant::is_one() const
873
{
874
   if (!this->type->is_scalar() && !this->type->is_vector())
875
      return false;
876
 
877
   for (unsigned c = 0; c < this->type->vector_elements; c++) {
878
      switch (this->type->base_type) {
879
      case GLSL_TYPE_FLOAT:
880
	 if (this->value.f[c] != 1.0)
881
	    return false;
882
	 break;
883
      case GLSL_TYPE_INT:
884
	 if (this->value.i[c] != 1)
885
	    return false;
886
	 break;
887
      case GLSL_TYPE_UINT:
888
	 if (this->value.u[c] != 1)
889
	    return false;
890
	 break;
891
      case GLSL_TYPE_BOOL:
892
	 if (this->value.b[c] != true)
893
	    return false;
894
	 break;
895
      default:
896
	 /* The only other base types are structures, arrays, and samplers.
897
	  * Samplers cannot be constants, and the others should have been
898
	  * filtered out above.
899
	  */
900
	 assert(!"Should not get here.");
901
	 return false;
902
      }
903
   }
904
 
905
   return true;
906
}
907
 
908
bool
909
ir_constant::is_negative_one() const
910
{
911
   if (!this->type->is_scalar() && !this->type->is_vector())
912
      return false;
913
 
914
   if (this->type->is_boolean())
915
      return false;
916
 
917
   for (unsigned c = 0; c < this->type->vector_elements; c++) {
918
      switch (this->type->base_type) {
919
      case GLSL_TYPE_FLOAT:
920
	 if (this->value.f[c] != -1.0)
921
	    return false;
922
	 break;
923
      case GLSL_TYPE_INT:
924
	 if (this->value.i[c] != -1)
925
	    return false;
926
	 break;
927
      case GLSL_TYPE_UINT:
928
	 if (int(this->value.u[c]) != -1)
929
	    return false;
930
	 break;
931
      default:
932
	 /* The only other base types are structures, arrays, samplers, and
933
	  * booleans.  Samplers cannot be constants, and the others should
934
	  * have been filtered out above.
935
	  */
936
	 assert(!"Should not get here.");
937
	 return false;
938
      }
939
   }
940
 
941
   return true;
942
}
943
 
944
ir_loop::ir_loop()
945
{
946
   this->ir_type = ir_type_loop;
947
   this->cmp = ir_unop_neg;
948
   this->from = NULL;
949
   this->to = NULL;
950
   this->increment = NULL;
951
   this->counter = NULL;
952
}
953
 
954
 
955
ir_dereference_variable::ir_dereference_variable(ir_variable *var)
956
{
957
   this->ir_type = ir_type_dereference_variable;
958
   this->var = var;
959
   this->type = (var != NULL) ? var->type : glsl_type::error_type;
960
}
961
 
962
 
963
ir_dereference_array::ir_dereference_array(ir_rvalue *value,
964
					   ir_rvalue *array_index)
965
{
966
   this->ir_type = ir_type_dereference_array;
967
   this->array_index = array_index;
968
   this->set_array(value);
969
}
970
 
971
 
972
ir_dereference_array::ir_dereference_array(ir_variable *var,
973
					   ir_rvalue *array_index)
974
{
975
   void *ctx = ralloc_parent(var);
976
 
977
   this->ir_type = ir_type_dereference_array;
978
   this->array_index = array_index;
979
   this->set_array(new(ctx) ir_dereference_variable(var));
980
}
981
 
982
 
983
void
984
ir_dereference_array::set_array(ir_rvalue *value)
985
{
986
   this->array = value;
987
   this->type = glsl_type::error_type;
988
 
989
   if (this->array != NULL) {
990
      const glsl_type *const vt = this->array->type;
991
 
992
      if (vt->is_array()) {
993
	 type = vt->element_type();
994
      } else if (vt->is_matrix()) {
995
	 type = vt->column_type();
996
      } else if (vt->is_vector()) {
997
	 type = vt->get_base_type();
998
      }
999
   }
1000
}
1001
 
1002
 
1003
ir_dereference_record::ir_dereference_record(ir_rvalue *value,
1004
					     const char *field)
1005
{
1006
   this->ir_type = ir_type_dereference_record;
1007
   this->record = value;
1008
   this->field = ralloc_strdup(this, field);
1009
   this->type = (this->record != NULL)
1010
      ? this->record->type->field_type(field) : glsl_type::error_type;
1011
}
1012
 
1013
 
1014
ir_dereference_record::ir_dereference_record(ir_variable *var,
1015
					     const char *field)
1016
{
1017
   void *ctx = ralloc_parent(var);
1018
 
1019
   this->ir_type = ir_type_dereference_record;
1020
   this->record = new(ctx) ir_dereference_variable(var);
1021
   this->field = ralloc_strdup(this, field);
1022
   this->type = (this->record != NULL)
1023
      ? this->record->type->field_type(field) : glsl_type::error_type;
1024
}
1025
 
1026
bool type_contains_sampler(const glsl_type *type)
1027
{
1028
   if (type->is_array()) {
1029
      return type_contains_sampler(type->fields.array);
1030
   } else if (type->is_record()) {
1031
      for (unsigned int i = 0; i < type->length; i++) {
1032
	 if (type_contains_sampler(type->fields.structure[i].type))
1033
	    return true;
1034
      }
1035
      return false;
1036
   } else {
1037
      return type->is_sampler();
1038
   }
1039
}
1040
 
1041
bool
1042
ir_dereference::is_lvalue()
1043
{
1044
   ir_variable *var = this->variable_referenced();
1045
 
1046
   /* Every l-value derference chain eventually ends in a variable.
1047
    */
1048
   if ((var == NULL) || var->read_only)
1049
      return false;
1050
 
1051
   if (this->type->is_array() && !var->array_lvalue)
1052
      return false;
1053
 
1054
   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
1055
    *
1056
    *    "Samplers cannot be treated as l-values; hence cannot be used
1057
    *     as out or inout function parameters, nor can they be
1058
    *     assigned into."
1059
    */
1060
   if (type_contains_sampler(this->type))
1061
      return false;
1062
 
1063
   return true;
1064
}
1065
 
1066
 
1067
const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
1068
 
1069
const char *ir_texture::opcode_string()
1070
{
1071
   assert((unsigned int) op <=
1072
	  sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
1073
   return tex_opcode_strs[op];
1074
}
1075
 
1076
ir_texture_opcode
1077
ir_texture::get_opcode(const char *str)
1078
{
1079
   const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
1080
   for (int op = 0; op < count; op++) {
1081
      if (strcmp(str, tex_opcode_strs[op]) == 0)
1082
	 return (ir_texture_opcode) op;
1083
   }
1084
   return (ir_texture_opcode) -1;
1085
}
1086
 
1087
 
1088
void
1089
ir_texture::set_sampler(ir_dereference *sampler)
1090
{
1091
   assert(sampler != NULL);
1092
   this->sampler = sampler;
1093
 
1094
   switch (sampler->type->sampler_type) {
1095
   case GLSL_TYPE_FLOAT:
1096
      this->type = glsl_type::vec4_type;
1097
      break;
1098
   case GLSL_TYPE_INT:
1099
      this->type = glsl_type::ivec4_type;
1100
      break;
1101
   case GLSL_TYPE_UINT:
1102
      this->type = glsl_type::uvec4_type;
1103
      break;
1104
   }
1105
}
1106
 
1107
 
1108
void
1109
ir_swizzle::init_mask(const unsigned *comp, unsigned count)
1110
{
1111
   assert((count >= 1) && (count <= 4));
1112
 
1113
   memset(&this->mask, 0, sizeof(this->mask));
1114
   this->mask.num_components = count;
1115
 
1116
   unsigned dup_mask = 0;
1117
   switch (count) {
1118
   case 4:
1119
      assert(comp[3] <= 3);
1120
      dup_mask |= (1U << comp[3])
1121
	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
1122
      this->mask.w = comp[3];
1123
 
1124
   case 3:
1125
      assert(comp[2] <= 3);
1126
      dup_mask |= (1U << comp[2])
1127
	 & ((1U << comp[0]) | (1U << comp[1]));
1128
      this->mask.z = comp[2];
1129
 
1130
   case 2:
1131
      assert(comp[1] <= 3);
1132
      dup_mask |= (1U << comp[1])
1133
	 & ((1U << comp[0]));
1134
      this->mask.y = comp[1];
1135
 
1136
   case 1:
1137
      assert(comp[0] <= 3);
1138
      this->mask.x = comp[0];
1139
   }
1140
 
1141
   this->mask.has_duplicates = dup_mask != 0;
1142
 
1143
   /* Based on the number of elements in the swizzle and the base type
1144
    * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
1145
    * generate the type of the resulting value.
1146
    */
1147
   type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
1148
}
1149
 
1150
ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
1151
		       unsigned w, unsigned count)
1152
   : val(val)
1153
{
1154
   const unsigned components[4] = { x, y, z, w };
1155
   this->ir_type = ir_type_swizzle;
1156
   this->init_mask(components, count);
1157
}
1158
 
1159
ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
1160
		       unsigned count)
1161
   : val(val)
1162
{
1163
   this->ir_type = ir_type_swizzle;
1164
   this->init_mask(comp, count);
1165
}
1166
 
1167
ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
1168
{
1169
   this->ir_type = ir_type_swizzle;
1170
   this->val = val;
1171
   this->mask = mask;
1172
   this->type = glsl_type::get_instance(val->type->base_type,
1173
					mask.num_components, 1);
1174
}
1175
 
1176
#define X 1
1177
#define R 5
1178
#define S 9
1179
#define I 13
1180
 
1181
ir_swizzle *
1182
ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
1183
{
1184
   void *ctx = ralloc_parent(val);
1185
 
1186
   /* For each possible swizzle character, this table encodes the value in
1187
    * \c idx_map that represents the 0th element of the vector.  For invalid
1188
    * swizzle characters (e.g., 'k'), a special value is used that will allow
1189
    * detection of errors.
1190
    */
1191
   static const unsigned char base_idx[26] = {
1192
   /* a  b  c  d  e  f  g  h  i  j  k  l  m */
1193
      R, R, I, I, I, I, R, I, I, I, I, I, I,
1194
   /* n  o  p  q  r  s  t  u  v  w  x  y  z */
1195
      I, I, S, S, R, S, S, I, I, X, X, X, X
1196
   };
1197
 
1198
   /* Each valid swizzle character has an entry in the previous table.  This
1199
    * table encodes the base index encoded in the previous table plus the actual
1200
    * index of the swizzle character.  When processing swizzles, the first
1201
    * character in the string is indexed in the previous table.  Each character
1202
    * in the string is indexed in this table, and the value found there has the
1203
    * value form the first table subtracted.  The result must be on the range
1204
    * [0,3].
1205
    *
1206
    * For example, the string "wzyx" will get X from the first table.  Each of
1207
    * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
1208
    * subtraction, the swizzle values are { 3, 2, 1, 0 }.
1209
    *
1210
    * The string "wzrg" will get X from the first table.  Each of the characters
1211
    * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
1212
    * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
1213
    * [0,3], the error is detected.
1214
    */
1215
   static const unsigned char idx_map[26] = {
1216
   /* a    b    c    d    e    f    g    h    i    j    k    l    m */
1217
      R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
1218
   /* n    o    p    q    r    s    t    u    v    w    x    y    z */
1219
      0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
1220
   };
1221
 
1222
   int swiz_idx[4] = { 0, 0, 0, 0 };
1223
   unsigned i;
1224
 
1225
 
1226
   /* Validate the first character in the swizzle string and look up the base
1227
    * index value as described above.
1228
    */
1229
   if ((str[0] < 'a') || (str[0] > 'z'))
1230
      return NULL;
1231
 
1232
   const unsigned base = base_idx[str[0] - 'a'];
1233
 
1234
 
1235
   for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
1236
      /* Validate the next character, and, as described above, convert it to a
1237
       * swizzle index.
1238
       */
1239
      if ((str[i] < 'a') || (str[i] > 'z'))
1240
	 return NULL;
1241
 
1242
      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
1243
      if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
1244
	 return NULL;
1245
   }
1246
 
1247
   if (str[i] != '\0')
1248
	 return NULL;
1249
 
1250
   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
1251
			      swiz_idx[3], i);
1252
}
1253
 
1254
#undef X
1255
#undef R
1256
#undef S
1257
#undef I
1258
 
1259
ir_variable *
1260
ir_swizzle::variable_referenced()
1261
{
1262
   return this->val->variable_referenced();
1263
}
1264
 
1265
 
1266
ir_variable::ir_variable(const struct glsl_type *type, const char *name,
1267
			 ir_variable_mode mode)
1268
   : max_array_access(0), read_only(false), centroid(false), invariant(false),
1269
     mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
1270
{
1271
   this->ir_type = ir_type_variable;
1272
   this->type = type;
1273
   this->name = ralloc_strdup(this, name);
1274
   this->explicit_location = false;
1275
   this->location = -1;
1276
   this->warn_extension = NULL;
1277
   this->constant_value = NULL;
1278
   this->origin_upper_left = false;
1279
   this->pixel_center_integer = false;
1280
   this->used = false;
1281
 
1282
   if (type && type->base_type == GLSL_TYPE_SAMPLER)
1283
      this->read_only = true;
1284
}
1285
 
1286
 
1287
const char *
1288
ir_variable::interpolation_string() const
1289
{
1290
   switch (this->interpolation) {
1291
   case ir_var_smooth:        return "smooth";
1292
   case ir_var_flat:          return "flat";
1293
   case ir_var_noperspective: return "noperspective";
1294
   }
1295
 
1296
   assert(!"Should not get here.");
1297
   return "";
1298
}
1299
 
1300
 
1301
unsigned
1302
ir_variable::component_slots() const
1303
{
1304
   /* FINISHME: Sparsely accessed arrays require fewer slots. */
1305
   return this->type->component_slots();
1306
}
1307
 
1308
 
1309
ir_function_signature::ir_function_signature(const glsl_type *return_type)
1310
   : return_type(return_type), is_defined(false), _function(NULL)
1311
{
1312
   this->ir_type = ir_type_function_signature;
1313
   this->is_builtin = false;
1314
}
1315
 
1316
 
1317
const char *
1318
ir_function_signature::qualifiers_match(exec_list *params)
1319
{
1320
   exec_list_iterator iter_a = parameters.iterator();
1321
   exec_list_iterator iter_b = params->iterator();
1322
 
1323
   /* check that the qualifiers match. */
1324
   while (iter_a.has_next()) {
1325
      ir_variable *a = (ir_variable *)iter_a.get();
1326
      ir_variable *b = (ir_variable *)iter_b.get();
1327
 
1328
      if (a->read_only != b->read_only ||
1329
	  a->mode != b->mode ||
1330
	  a->interpolation != b->interpolation ||
1331
	  a->centroid != b->centroid) {
1332
 
1333
	 /* parameter a's qualifiers don't match */
1334
	 return a->name;
1335
      }
1336
 
1337
      iter_a.next();
1338
      iter_b.next();
1339
   }
1340
   return NULL;
1341
}
1342
 
1343
 
1344
void
1345
ir_function_signature::replace_parameters(exec_list *new_params)
1346
{
1347
   /* Destroy all of the previous parameter information.  If the previous
1348
    * parameter information comes from the function prototype, it may either
1349
    * specify incorrect parameter names or not have names at all.
1350
    */
1351
   foreach_iter(exec_list_iterator, iter, parameters) {
1352
      assert(((ir_instruction *) iter.get())->as_variable() != NULL);
1353
 
1354
      iter.remove();
1355
   }
1356
 
1357
   new_params->move_nodes_to(¶meters);
1358
}
1359
 
1360
 
1361
ir_function::ir_function(const char *name)
1362
{
1363
   this->ir_type = ir_type_function;
1364
   this->name = ralloc_strdup(this, name);
1365
}
1366
 
1367
 
1368
bool
1369
ir_function::has_user_signature()
1370
{
1371
   foreach_list(n, &this->signatures) {
1372
      ir_function_signature *const sig = (ir_function_signature *) n;
1373
      if (!sig->is_builtin)
1374
	 return true;
1375
   }
1376
   return false;
1377
}
1378
 
1379
 
1380
ir_call *
1381
ir_call::get_error_instruction(void *ctx)
1382
{
1383
   ir_call *call = new(ctx) ir_call;
1384
 
1385
   call->type = glsl_type::error_type;
1386
   return call;
1387
}
1388
 
1389
void
1390
ir_call::set_callee(ir_function_signature *sig)
1391
{
1392
   assert((this->type == NULL) || (this->type == sig->return_type));
1393
 
1394
   this->callee = sig;
1395
}
1396
 
1397
void
1398
visit_exec_list(exec_list *list, ir_visitor *visitor)
1399
{
1400
   foreach_iter(exec_list_iterator, iter, *list) {
1401
      ((ir_instruction *)iter.get())->accept(visitor);
1402
   }
1403
}
1404
 
1405
 
1406
static void
1407
steal_memory(ir_instruction *ir, void *new_ctx)
1408
{
1409
   ir_variable *var = ir->as_variable();
1410
   ir_constant *constant = ir->as_constant();
1411
   if (var != NULL && var->constant_value != NULL)
1412
      steal_memory(var->constant_value, ir);
1413
 
1414
   /* The components of aggregate constants are not visited by the normal
1415
    * visitor, so steal their values by hand.
1416
    */
1417
   if (constant != NULL) {
1418
      if (constant->type->is_record()) {
1419
	 foreach_iter(exec_list_iterator, iter, constant->components) {
1420
	    ir_constant *field = (ir_constant *)iter.get();
1421
	    steal_memory(field, ir);
1422
	 }
1423
      } else if (constant->type->is_array()) {
1424
	 for (unsigned int i = 0; i < constant->type->length; i++) {
1425
	    steal_memory(constant->array_elements[i], ir);
1426
	 }
1427
      }
1428
   }
1429
 
1430
   ralloc_steal(new_ctx, ir);
1431
}
1432
 
1433
 
1434
void
1435
reparent_ir(exec_list *list, void *mem_ctx)
1436
{
1437
   foreach_list(node, list) {
1438
      visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
1439
   }
1440
}
1441
 
1442
 
1443
static ir_rvalue *
1444
try_min_one(ir_rvalue *ir)
1445
{
1446
   ir_expression *expr = ir->as_expression();
1447
 
1448
   if (!expr || expr->operation != ir_binop_min)
1449
      return NULL;
1450
 
1451
   if (expr->operands[0]->is_one())
1452
      return expr->operands[1];
1453
 
1454
   if (expr->operands[1]->is_one())
1455
      return expr->operands[0];
1456
 
1457
   return NULL;
1458
}
1459
 
1460
static ir_rvalue *
1461
try_max_zero(ir_rvalue *ir)
1462
{
1463
   ir_expression *expr = ir->as_expression();
1464
 
1465
   if (!expr || expr->operation != ir_binop_max)
1466
      return NULL;
1467
 
1468
   if (expr->operands[0]->is_zero())
1469
      return expr->operands[1];
1470
 
1471
   if (expr->operands[1]->is_zero())
1472
      return expr->operands[0];
1473
 
1474
   return NULL;
1475
}
1476
 
1477
ir_rvalue *
1478
ir_rvalue::as_rvalue_to_saturate()
1479
{
1480
   ir_expression *expr = this->as_expression();
1481
 
1482
   if (!expr)
1483
      return NULL;
1484
 
1485
   ir_rvalue *max_zero = try_max_zero(expr);
1486
   if (max_zero) {
1487
      return try_min_one(max_zero);
1488
   } else {
1489
      ir_rvalue *min_one = try_min_one(expr);
1490
      if (min_one) {
1491
	 return try_max_zero(min_one);
1492
      }
1493
   }
1494
 
1495
   return NULL;
1496
}