glsl_to_nir: fix crashes with int16 shifts
[mesa.git] / src / compiler / nir / nir_algebraic.py
index d8d0a95a6d332f3bfa1ec68f39397b1f22081a53..6871af36ef8f06ace44749b0bbd63ad2d9ea67f2 100644 (file)
@@ -200,7 +200,7 @@ class Value(object):
    ${val.cond if val.cond else 'NULL'},
    ${val.swizzle()},
 % elif isinstance(val, Expression):
-   ${'true' if val.inexact else 'false'},
+   ${'true' if val.inexact else 'false'}, ${'true' if val.exact else 'false'},
    ${val.comm_expr_idx}, ${val.comm_exprs},
    ${val.c_opcode()},
    { ${', '.join(src.c_value_ptr(cache) for src in val.sources)} },
@@ -283,17 +283,21 @@ class Constant(Value):
 
       return self.value == other.value
 
+# The $ at the end forces there to be an error if any part of the string
+# doesn't match one of the field patterns.
 _var_name_re = re.compile(r"(?P<const>#)?(?P<name>\w+)"
                           r"(?:@(?P<type>int|uint|bool|float)?(?P<bits>\d+)?)?"
                           r"(?P<cond>\([^\)]+\))?"
-                          r"(?P<swiz>\.[xyzw]+)?")
+                          r"(?P<swiz>\.[xyzw]+)?"
+                          r"$")
 
 class Variable(Value):
    def __init__(self, val, name, varset):
       Value.__init__(self, val, name, "variable")
 
       m = _var_name_re.match(val)
-      assert m and m.group('name') is not None
+      assert m and m.group('name') is not None, \
+            "Malformed variable name \"{}\".".format(val)
 
       self.var_name = m.group('name')
 
@@ -301,8 +305,8 @@ class Variable(Value):
       # constant.  If we want to support names that have numeric or
       # punctuation characters, we can me the first assertion more flexible.
       assert self.var_name.isalpha()
-      assert self.var_name is not 'True'
-      assert self.var_name is not 'False'
+      assert self.var_name != 'True'
+      assert self.var_name != 'False'
 
       self.is_constant = m.group('const') is not None
       self.cond = m.group('cond')
@@ -344,11 +348,15 @@ class Variable(Value):
 
    def swizzle(self):
       if self.swiz is not None:
-         swizzles = {'x' : 0, 'y' : 1, 'z' : 2, 'w': 3}
+         swizzles = {'x' : 0, 'y' : 1, 'z' : 2, 'w' : 3,
+                     'a' : 0, 'b' : 1, 'c' : 2, 'd' : 3,
+                     'e' : 4, 'f' : 5, 'g' : 6, 'h' : 7,
+                     'i' : 8, 'j' : 9, 'k' : 10, 'l' : 11,
+                     'm' : 12, 'n' : 13, 'o' : 14, 'p' : 15 }
          return '{' + ', '.join([str(swizzles[c]) for c in self.swiz[1:]]) + '}'
-      return '{0, 1, 2, 3}'
+      return '{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}'
 
-_opcode_re = re.compile(r"(?P<inexact>~)?(?P<opcode>\w+)(?:@(?P<bits>\d+))?"
+_opcode_re = re.compile(r"(?P<inexact>~)?(?P<exact>!)?(?P<opcode>\w+)(?:@(?P<bits>\d+))?"
                         r"(?P<cond>\([^\)]+\))?")
 
 class Expression(Value):
@@ -362,8 +370,12 @@ class Expression(Value):
       self.opcode = m.group('opcode')
       self._bit_size = int(m.group('bits')) if m.group('bits') else None
       self.inexact = m.group('inexact') is not None
+      self.exact = m.group('exact') is not None
       self.cond = m.group('cond')
 
+      assert not self.inexact or not self.exact, \
+            'Expression cannot be both exact and inexact.'
+
       # "many-comm-expr" isn't really a condition.  It's notification to the
       # generator that this pattern is known to have too many commutative
       # expressions, and an error should not be generated for this case.