arm: Add support for ARMv8 (AArch64 & AArch32)
[gem5.git] / src / arch / arm / isa / insts / neon.isa
index b629c6fe8b41290221181bb96620757cc8203dae..ca5c3038cf0d2f1f5c63bd7d4f09af2f24bfd5a6 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2010 ARM Limited
+// Copyright (c) 2010-2011 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -94,8 +94,8 @@ output header {{
     template <template <typename T> class Base>
     StaticInstPtr
     decodeNeonUThreeUSReg(unsigned size,
-                         ExtMachInst machInst, IntRegIndex dest,
-                         IntRegIndex op1, IntRegIndex op2)
+                          ExtMachInst machInst, IntRegIndex dest,
+                          IntRegIndex op1, IntRegIndex op2)
     {
         switch (size) {
           case 0:
@@ -112,8 +112,8 @@ output header {{
     template <template <typename T> class Base>
     StaticInstPtr
     decodeNeonSThreeUSReg(unsigned size,
-                         ExtMachInst machInst, IntRegIndex dest,
-                         IntRegIndex op1, IntRegIndex op2)
+                          ExtMachInst machInst, IntRegIndex dest,
+                          IntRegIndex op1, IntRegIndex op2)
     {
         switch (size) {
           case 0:
@@ -127,6 +127,38 @@ output header {{
         }
     }
 
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonSThreeHAndWReg(unsigned size, ExtMachInst machInst,
+                             IntRegIndex dest, IntRegIndex op1,
+                             IntRegIndex op2)
+    {
+        switch (size) {
+          case 1:
+            return new Base<int16_t>(machInst, dest, op1, op2);
+          case 2:
+            return new Base<int32_t>(machInst, dest, op1, op2);
+          default:
+            return new Unknown(machInst);
+        }
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonSThreeImmHAndWReg(unsigned size, ExtMachInst machInst,
+                                IntRegIndex dest, IntRegIndex op1,
+                                IntRegIndex op2, uint64_t imm)
+    {
+        switch (size) {
+          case 1:
+            return new Base<int16_t>(machInst, dest, op1, op2, imm);
+          case 2:
+            return new Base<int32_t>(machInst, dest, op1, op2, imm);
+          default:
+            return new Unknown(machInst);
+        }
+    }
+
     template <template <typename T> class Base>
     StaticInstPtr
     decodeNeonUSThreeUSReg(bool notSigned, unsigned size,
@@ -174,6 +206,38 @@ output header {{
         }
     }
 
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonSThreeXReg(bool q, unsigned size,
+                         ExtMachInst machInst, IntRegIndex dest,
+                         IntRegIndex op1, IntRegIndex op2)
+    {
+        if (q) {
+            return decodeNeonSThreeUReg<BaseQ>(
+                    size, machInst, dest, op1, op2);
+        } else {
+            return decodeNeonSThreeUSReg<BaseD>(
+                    size, machInst, dest, op1, op2);
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUThreeXReg(bool q, unsigned size,
+                         ExtMachInst machInst, IntRegIndex dest,
+                         IntRegIndex op1, IntRegIndex op2)
+    {
+        if (q) {
+            return decodeNeonUThreeUReg<BaseQ>(
+                    size, machInst, dest, op1, op2);
+        } else {
+            return decodeNeonUThreeUSReg<BaseD>(
+                    size, machInst, dest, op1, op2);
+        }
+    }
+
     template <template <typename T> class BaseD,
               template <typename T> class BaseQ>
     StaticInstPtr
@@ -238,6 +302,124 @@ output header {{
         }
     }
 
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUThreeFpReg(bool q, unsigned size, ExtMachInst machInst,
+                          IntRegIndex dest, IntRegIndex op1, IntRegIndex op2)
+    {
+        if (q) {
+            if (size)
+                return new BaseQ<uint64_t>(machInst, dest, op1, op2);
+            else
+                return new BaseQ<uint32_t>(machInst, dest, op1, op2);
+        } else {
+            if (size)
+                return new Unknown(machInst);
+            else
+                return new BaseD<uint32_t>(machInst, dest, op1, op2);
+        }
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonUThreeScFpReg(bool size, ExtMachInst machInst,
+                            IntRegIndex dest, IntRegIndex op1, IntRegIndex op2)
+    {
+        if (size)
+            return new Base<uint64_t>(machInst, dest, op1, op2);
+        else
+            return new Base<uint32_t>(machInst, dest, op1, op2);
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonUThreeImmScFpReg(bool size, ExtMachInst machInst,
+                               IntRegIndex dest, IntRegIndex op1,
+                               IntRegIndex op2, uint64_t imm)
+    {
+        if (size)
+            return new Base<uint64_t>(machInst, dest, op1, op2, imm);
+        else
+            return new Base<uint32_t>(machInst, dest, op1, op2, imm);
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUThreeImmHAndWReg(bool q, unsigned size, ExtMachInst machInst,
+                                IntRegIndex dest, IntRegIndex op1,
+                                IntRegIndex op2, uint64_t imm)
+    {
+        if (q) {
+            switch (size) {
+              case 1:
+                return new BaseQ<uint16_t>(machInst, dest, op1, op2, imm);
+              case 2:
+                return new BaseQ<uint32_t>(machInst, dest, op1, op2, imm);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 1:
+                return new BaseD<uint16_t>(machInst, dest, op1, op2, imm);
+              case 2:
+                return new BaseD<uint32_t>(machInst, dest, op1, op2, imm);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonSThreeImmHAndWReg(bool q, unsigned size, ExtMachInst machInst,
+                                IntRegIndex dest, IntRegIndex op1,
+                                IntRegIndex op2, uint64_t imm)
+    {
+        if (q) {
+            switch (size) {
+              case 1:
+                return new BaseQ<int16_t>(machInst, dest, op1, op2, imm);
+              case 2:
+                return new BaseQ<int32_t>(machInst, dest, op1, op2, imm);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 1:
+                return new BaseD<int16_t>(machInst, dest, op1, op2, imm);
+              case 2:
+                return new BaseD<int32_t>(machInst, dest, op1, op2, imm);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUThreeImmFpReg(bool q, unsigned size, ExtMachInst machInst,
+                             IntRegIndex dest, IntRegIndex op1,
+                             IntRegIndex op2, uint64_t imm)
+    {
+        if (q) {
+            if (size)
+                return new BaseQ<uint64_t>(machInst, dest, op1, op2, imm);
+            else
+                return new BaseQ<uint32_t>(machInst, dest, op1, op2, imm);
+        } else {
+            if (size)
+                return new Unknown(machInst);
+            else
+                return new BaseD<uint32_t>(machInst, dest, op1, op2, imm);
+        }
+    }
+
     template <template <typename T> class BaseD,
               template <typename T> class BaseQ>
     StaticInstPtr
@@ -345,6 +527,46 @@ output header {{
         }
     }
 
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonUTwoShiftUReg(unsigned size,
+                            ExtMachInst machInst, IntRegIndex dest,
+                            IntRegIndex op1, uint64_t imm)
+    {
+        switch (size) {
+          case 0:
+            return new Base<uint8_t>(machInst, dest, op1, imm);
+          case 1:
+            return new Base<uint16_t>(machInst, dest, op1, imm);
+          case 2:
+            return new Base<uint32_t>(machInst, dest, op1, imm);
+          case 3:
+            return new Base<uint64_t>(machInst, dest, op1, imm);
+          default:
+            return new Unknown(machInst);
+        }
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonSTwoShiftUReg(unsigned size,
+                            ExtMachInst machInst, IntRegIndex dest,
+                            IntRegIndex op1, uint64_t imm)
+    {
+        switch (size) {
+          case 0:
+            return new Base<int8_t>(machInst, dest, op1, imm);
+          case 1:
+            return new Base<int16_t>(machInst, dest, op1, imm);
+          case 2:
+            return new Base<int32_t>(machInst, dest, op1, imm);
+          case 3:
+            return new Base<int64_t>(machInst, dest, op1, imm);
+          default:
+            return new Unknown(machInst);
+        }
+    }
+
     template <template <typename T> class BaseD,
               template <typename T> class BaseQ>
     StaticInstPtr
@@ -411,6 +633,66 @@ output header {{
         }
     }
 
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUTwoShiftXReg(bool q, unsigned size, ExtMachInst machInst,
+                            IntRegIndex dest, IntRegIndex op1, uint64_t imm)
+    {
+        if (q) {
+            return decodeNeonUTwoShiftUReg<BaseQ>(
+                size, machInst, dest, op1, imm);
+        } else {
+            return decodeNeonUTwoShiftUSReg<BaseD>(
+                size, machInst, dest, op1, imm);
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonSTwoShiftXReg(bool q, unsigned size, ExtMachInst machInst,
+                            IntRegIndex dest, IntRegIndex op1, uint64_t imm)
+    {
+        if (q) {
+            return decodeNeonSTwoShiftUReg<BaseQ>(
+                size, machInst, dest, op1, imm);
+        } else {
+            return decodeNeonSTwoShiftUSReg<BaseD>(
+                size, machInst, dest, op1, imm);
+        }
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonUTwoShiftUFpReg(unsigned size, ExtMachInst machInst,
+                              IntRegIndex dest, IntRegIndex op1, uint64_t imm)
+    {
+        if (size)
+            return new Base<uint64_t>(machInst, dest, op1, imm);
+        else
+            return new Base<uint32_t>(machInst, dest, op1, imm);
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUTwoShiftFpReg(bool q, unsigned size, ExtMachInst machInst,
+                             IntRegIndex dest, IntRegIndex op1, uint64_t imm)
+    {
+        if (q) {
+            if (size)
+                return new BaseQ<uint64_t>(machInst, dest, op1, imm);
+            else
+                return new BaseQ<uint32_t>(machInst, dest, op1, imm);
+        } else {
+            if (size)
+                return new Unknown(machInst);
+            else
+                return new BaseD<uint32_t>(machInst, dest, op1, imm);
+        }
+    }
+
     template <template <typename T> class Base>
     StaticInstPtr
     decodeNeonUTwoMiscUSReg(unsigned size,
@@ -451,8 +733,8 @@ output header {{
               template <typename T> class BaseQ>
     StaticInstPtr
     decodeNeonUTwoMiscSReg(bool q, unsigned size,
-                          ExtMachInst machInst, IntRegIndex dest,
-                          IntRegIndex op1)
+                           ExtMachInst machInst, IntRegIndex dest,
+                           IntRegIndex op1)
     {
         if (q) {
             return decodeNeonUTwoMiscUSReg<BaseQ>(size, machInst, dest, op1);
@@ -465,8 +747,8 @@ output header {{
               template <typename T> class BaseQ>
     StaticInstPtr
     decodeNeonSTwoMiscSReg(bool q, unsigned size,
-                          ExtMachInst machInst, IntRegIndex dest,
-                          IntRegIndex op1)
+                           ExtMachInst machInst, IntRegIndex dest,
+                           IntRegIndex op1)
     {
         if (q) {
             return decodeNeonSTwoMiscUSReg<BaseQ>(size, machInst, dest, op1);
@@ -498,8 +780,8 @@ output header {{
     template <template <typename T> class Base>
     StaticInstPtr
     decodeNeonSTwoMiscUReg(unsigned size,
-                            ExtMachInst machInst, IntRegIndex dest,
-                            IntRegIndex op1)
+                           ExtMachInst machInst, IntRegIndex dest,
+                           IntRegIndex op1)
     {
         switch (size) {
           case 0:
@@ -559,13 +841,228 @@ output header {{
         }
     }
 
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUTwoMiscXReg(bool q, unsigned size, ExtMachInst machInst,
+                           IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            return decodeNeonUTwoMiscUReg<BaseQ>(size, machInst, dest, op1);
+        } else {
+            return decodeNeonUTwoMiscUSReg<BaseD>(size, machInst, dest, op1);
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonSTwoMiscXReg(bool q, unsigned size, ExtMachInst machInst,
+                           IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            return decodeNeonSTwoMiscUReg<BaseQ>(size, machInst, dest, op1);
+        } else {
+            return decodeNeonSTwoMiscUSReg<BaseD>(size, machInst, dest, op1);
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUTwoMiscFpReg(bool q, unsigned size, ExtMachInst machInst,
+                            IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            if (size)
+                return new BaseQ<uint64_t>(machInst, dest, op1);
+            else
+                return new BaseQ<uint32_t>(machInst, dest, op1);
+        } else {
+            if (size)
+                return new Unknown(machInst);
+            else
+                return new BaseD<uint32_t>(machInst, dest, op1);
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUTwoMiscPwiseScFpReg(unsigned size, ExtMachInst machInst,
+                                   IntRegIndex dest, IntRegIndex op1)
+    {
+        if (size)
+            return new BaseQ<uint64_t>(machInst, dest, op1);
+        else
+            return new BaseD<uint32_t>(machInst, dest, op1);
+    }
+
+    template <template <typename T> class Base>
+    StaticInstPtr
+    decodeNeonUTwoMiscScFpReg(unsigned size, ExtMachInst machInst,
+                              IntRegIndex dest, IntRegIndex op1)
+    {
+        if (size)
+            return new Base<uint64_t>(machInst, dest, op1);
+        else
+            return new Base<uint32_t>(machInst, dest, op1);
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonUAcrossLanesReg(bool q, unsigned size, ExtMachInst machInst,
+                              IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            switch (size) {
+              case 0x0:
+                return new BaseQ<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseQ<uint16_t>(machInst, dest, op1);
+              case 0x2:
+                return new BaseQ<uint32_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 0x0:
+                return new BaseD<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseD<uint16_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ,
+              template <typename T> class BaseBQ>
+    StaticInstPtr
+    decodeNeonUAcrossLanesReg(bool q, unsigned size, ExtMachInst machInst,
+                              IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            switch (size) {
+              case 0x0:
+                return new BaseQ<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseQ<uint16_t>(machInst, dest, op1);
+              case 0x2:
+                return new BaseBQ<uint32_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 0x0:
+                return new BaseD<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseD<uint16_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ>
+    StaticInstPtr
+    decodeNeonSAcrossLanesReg(bool q, unsigned size, ExtMachInst machInst,
+                              IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            switch (size) {
+              case 0x0:
+                return new BaseQ<int8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseQ<int16_t>(machInst, dest, op1);
+              case 0x2:
+                return new BaseQ<int32_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 0x0:
+                return new BaseD<int8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseD<int16_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ,
+              template <typename T> class BaseBQ>
+    StaticInstPtr
+    decodeNeonUAcrossLanesLongReg(bool q, unsigned size, ExtMachInst machInst,
+                                  IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            switch (size) {
+              case 0x0:
+                return new BaseQ<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseQ<uint16_t>(machInst, dest, op1);
+              case 0x2:
+                return new BaseBQ<uint32_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 0x0:
+                return new BaseD<uint8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseD<uint16_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
+
+    template <template <typename T> class BaseD,
+              template <typename T> class BaseQ,
+              template <typename T> class BaseBQ>
+    StaticInstPtr
+    decodeNeonSAcrossLanesLongReg(bool q, unsigned size, ExtMachInst machInst,
+                                  IntRegIndex dest, IntRegIndex op1)
+    {
+        if (q) {
+            switch (size) {
+              case 0x0:
+                return new BaseQ<int8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseQ<int16_t>(machInst, dest, op1);
+              case 0x2:
+                return new BaseBQ<int32_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        } else {
+            switch (size) {
+              case 0x0:
+                return new BaseD<int8_t>(machInst, dest, op1);
+              case 0x1:
+                return new BaseD<int16_t>(machInst, dest, op1);
+              default:
+                return new Unknown(machInst);
+            }
+        }
+    }
 }};
 
 output exec {{
     static float
     vcgtFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (op1 > op2) ? 0.0 : 1.0;
     }
@@ -573,7 +1070,7 @@ output exec {{
     static float
     vcgeFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (op1 >= op2) ? 0.0 : 1.0;
     }
@@ -589,7 +1086,7 @@ output exec {{
     static float
     vcleFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (op1 <= op2) ? 0.0 : 1.0;
     }
@@ -597,7 +1094,7 @@ output exec {{
     static float
     vcltFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (op1 < op2) ? 0.0 : 1.0;
     }
@@ -605,7 +1102,7 @@ output exec {{
     static float
     vacgtFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (fabsf(op1) > fabsf(op2)) ? 0.0 : 1.0;
     }
@@ -613,7 +1110,7 @@ output exec {{
     static float
     vacgeFunc(float op1, float op2)
     {
-        if (isSnan(op1) || isSnan(op2))
+        if (std::isnan(op1) || std::isnan(op2))
             return 2.0;
         return (fabsf(op1) >= fabsf(op2)) ? 0.0 : 1.0;
     }
@@ -631,20 +1128,20 @@ let {{
     smallTypes = smallUnsignedTypes + smallSignedTypes
     allTypes = unsignedTypes + signedTypes
 
-    def threeEqualRegInst(name, Name, types, rCount, op,
+    def threeEqualRegInst(name, Name, opClass, types, rCount, op,
                           readDest=False, pairwise=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, srcReg2, destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
-                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
+                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -677,13 +1174,14 @@ let {{
             ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -691,10 +1189,10 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def threeEqualRegInstFp(name, Name, types, rCount, op,
+    def threeEqualRegInstFp(name, Name, opClass, types, rCount, op,
                             readDest=False, pairwise=False, toInt=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         typedef FloatReg FloatVect[rCount];
         FloatVect srcRegs1, srcRegs2;
         '''
@@ -757,7 +1255,7 @@ let {{
         for reg in range(rCount):
             if toInt:
                 eWalkCode += '''
-                FpDestP%(reg)d.uw = destRegs.regs[%(reg)d];
+                FpDestP%(reg)d_uw = destRegs.regs[%(reg)d];
                 ''' % { "reg" : reg }
             else:
                 eWalkCode += '''
@@ -767,7 +1265,8 @@ let {{
                             "FpRegRegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -775,7 +1274,7 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def threeUnequalRegInst(name, Name, types, op,
+    def threeUnequalRegInst(name, Name, opClass, types, op,
                             bigSrc1, bigSrc2, bigDest, readDest):
         global header_output, exec_output
         src1Cnt = src2Cnt = destCnt = 2
@@ -789,23 +1288,23 @@ let {{
         if bigDest:
             destCnt = 4
             destPrefix = 'Big'
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
             %sRegVect srcReg1;
             %sRegVect srcReg2;
             %sRegVect destReg;
         ''' % (src1Prefix, src2Prefix, destPrefix)
         for reg in range(src1Cnt):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
         for reg in range(src2Cnt):
             eWalkCode += '''
-                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
+                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw);
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(destCnt):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -824,13 +1323,14 @@ let {{
                 "destPrefix" : destPrefix }
         for reg in range(destCnt):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegRegOp",
                             { "code": eWalkCode,
                               "r_count": 2,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -838,55 +1338,59 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def threeRegNarrowInst(name, Name, types, op, readDest=False):
-        threeUnequalRegInst(name, Name, types, op,
+    def threeRegNarrowInst(name, Name, opClass, types, op, readDest=False):
+        threeUnequalRegInst(name, Name, opClass, types, op,
                             True, True, False, readDest)
 
-    def threeRegLongInst(name, Name, types, op, readDest=False):
-        threeUnequalRegInst(name, Name, types, op,
+    def threeRegLongInst(name, Name, opClass, types, op, readDest=False):
+        threeUnequalRegInst(name, Name, opClass, types, op,
                             False, False, True, readDest)
 
-    def threeRegWideInst(name, Name, types, op, readDest=False):
-        threeUnequalRegInst(name, Name, types, op,
+    def threeRegWideInst(name, Name, opClass, types, op, readDest=False):
+        threeUnequalRegInst(name, Name, opClass, types, op,
                             True, False, True, readDest)
 
-    def twoEqualRegInst(name, Name, types, rCount, op, readDest=False):
+    def twoEqualRegInst(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, srcReg2, destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
-                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
+                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
             readDestCode = 'destElem = gtoh(destReg.elements[i]);'
         eWalkCode += '''
-        assert(imm >= 0 && imm < eCount);
-        for (unsigned i = 0; i < eCount; i++) {
-            Element srcElem1 = gtoh(srcReg1.elements[i]);
-            Element srcElem2 = gtoh(srcReg2.elements[imm]);
-            Element destElem;
-            %(readDest)s
-            %(op)s
-            destReg.elements[i] = htog(destElem);
+        if (imm < 0 && imm >= eCount) {
+            fault = new UndefinedInstruction(machInst, false, mnemonic);
+        } else {
+            for (unsigned i = 0; i < eCount; i++) {
+                Element srcElem1 = gtoh(srcReg1.elements[i]);
+                Element srcElem2 = gtoh(srcReg2.elements[imm]);
+                Element destElem;
+                %(readDest)s
+                %(op)s
+                destReg.elements[i] = htog(destElem);
+            }
         }
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -894,46 +1398,50 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegLongInst(name, Name, types, op, readDest=False):
+    def twoRegLongInst(name, Name, opClass, types, op, readDest=False):
         global header_output, exec_output
         rCount = 2
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, srcReg2;
         BigRegVect destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
-                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);;
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
+                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw);;
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(2 * rCount):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
             readDestCode = 'destElem = gtoh(destReg.elements[i]);'
         eWalkCode += '''
-        assert(imm >= 0 && imm < eCount);
-        for (unsigned i = 0; i < eCount; i++) {
-            Element srcElem1 = gtoh(srcReg1.elements[i]);
-            Element srcElem2 = gtoh(srcReg2.elements[imm]);
-            BigElement destElem;
-            %(readDest)s
-            %(op)s
-            destReg.elements[i] = htog(destElem);
+        if (imm < 0 && imm >= eCount) {
+            fault = new UndefinedInstruction(machInst, false, mnemonic);
+        } else {
+            for (unsigned i = 0; i < eCount; i++) {
+                Element srcElem1 = gtoh(srcReg1.elements[i]);
+                Element srcElem2 = gtoh(srcReg2.elements[imm]);
+                BigElement destElem;
+                %(readDest)s
+                %(op)s
+                destReg.elements[i] = htog(destElem);
+            }
         }
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(2 * rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegImmOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -941,9 +1449,9 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoEqualRegInstFp(name, Name, types, rCount, op, readDest=False):
+    def twoEqualRegInstFp(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         typedef FloatReg FloatVect[rCount];
         FloatVect srcRegs1, srcRegs2, destRegs;
         '''
@@ -960,14 +1468,17 @@ let {{
         if readDest:
             readDestCode = 'destReg = destRegs[i];'
         eWalkCode += '''
-        assert(imm >= 0 && imm < rCount);
-        for (unsigned i = 0; i < rCount; i++) {
-            FloatReg srcReg1 = srcRegs1[i];
-            FloatReg srcReg2 = srcRegs2[imm];
-            FloatReg destReg;
-            %(readDest)s
-            %(op)s
-            destRegs[i] = destReg;
+        if (imm < 0 && imm >= eCount) {
+            fault = new UndefinedInstruction(machInst, false, mnemonic);
+        } else {
+            for (unsigned i = 0; i < rCount; i++) {
+                FloatReg srcReg1 = srcRegs1[i];
+                FloatReg srcReg2 = srcRegs2[imm];
+                FloatReg destReg;
+                %(readDest)s
+                %(op)s
+                destRegs[i] = destReg;
+            }
         }
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
@@ -978,7 +1489,8 @@ let {{
                             "FpRegRegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -986,19 +1498,19 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegShiftInst(name, Name, types, rCount, op,
+    def twoRegShiftInst(name, Name, opClass, types, rCount, op,
             readDest=False, toInt=False, fromInt=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcRegs1, destRegs;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcRegs1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcRegs1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destRegs.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destRegs.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1028,13 +1540,14 @@ let {{
                 "writeDest" : writeDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destRegs.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destRegs.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1042,20 +1555,20 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegNarrowShiftInst(name, Name, types, op, readDest=False):
+    def twoRegNarrowShiftInst(name, Name, opClass, types, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         BigRegVect srcReg1;
         RegVect destReg;
         '''
         for reg in range(4):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(2):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1071,13 +1584,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(2):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": 2,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegImmOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -1085,20 +1599,20 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegLongShiftInst(name, Name, types, op, readDest=False):
+    def twoRegLongShiftInst(name, Name, opClass, types, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1;
         BigRegVect destReg;
         '''
         for reg in range(2):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(4):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1114,13 +1628,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(4):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": 2,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegImmOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -1128,18 +1643,18 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegMiscInst(name, Name, types, rCount, op, readDest=False):
+    def twoRegMiscInst(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1156,13 +1671,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1170,18 +1686,18 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegMiscScInst(name, Name, types, rCount, op, readDest=False):
+    def twoRegMiscScInst(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1197,13 +1713,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1211,15 +1728,15 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegMiscScramble(name, Name, types, rCount, op, readDest=False):
+    def twoRegMiscScramble(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1, destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
-                destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
+                destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
@@ -1230,14 +1747,15 @@ let {{
         eWalkCode += op
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
-            FpOp1P%(reg)d.uw = gtoh(srcReg1.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
+            FpOp1P%(reg)d_uw = gtoh(srcReg1.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1245,10 +1763,10 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegMiscInstFp(name, Name, types, rCount, op,
+    def twoRegMiscInstFp(name, Name, opClass, types, rCount, op,
             readDest=False, toInt=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         typedef FloatReg FloatVect[rCount];
         FloatVect srcRegs1;
         '''
@@ -1292,7 +1810,7 @@ let {{
         for reg in range(rCount):
             if toInt:
                 eWalkCode += '''
-                FpDestP%(reg)d.uw = destRegs.regs[%(reg)d];
+                FpDestP%(reg)d_uw = destRegs.regs[%(reg)d];
                 ''' % { "reg" : reg }
             else:
                 eWalkCode += '''
@@ -1302,7 +1820,8 @@ let {{
                             "FpRegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1310,19 +1829,19 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegCondenseInst(name, Name, types, rCount, op, readDest=False):
+    def twoRegCondenseInst(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcRegs;
         BigRegVect destReg;
         '''
         for reg in range(rCount):
             eWalkCode += '''
-                srcRegs.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcRegs.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
             if readDest:
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1339,13 +1858,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -1353,20 +1873,20 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegNarrowMiscInst(name, Name, types, op, readDest=False):
+    def twoRegNarrowMiscInst(name, Name, opClass, types, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         BigRegVect srcReg1;
         RegVect destReg;
         '''
         for reg in range(4):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(2):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1382,13 +1902,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(2):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": 2,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -1396,15 +1917,15 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def oneRegImmInst(name, Name, types, rCount, op, readDest=False):
+    def oneRegImmInst(name, Name, opClass, types, rCount, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect destReg;
         '''
         if readDest:
             for reg in range(rCount):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1419,13 +1940,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -1433,20 +1955,20 @@ let {{
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
 
-    def twoRegLongMiscInst(name, Name, types, op, readDest=False):
+    def twoRegLongMiscInst(name, Name, opClass, types, op, readDest=False):
         global header_output, exec_output
-        eWalkCode = '''
+        eWalkCode = simdEnabledCheckCode + '''
         RegVect srcReg1;
         BigRegVect destReg;
         '''
         for reg in range(2):
             eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
             ''' % { "reg" : reg }
         if readDest:
             for reg in range(4):
                 eWalkCode += '''
-                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d.uw);
+                    destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw);
                 ''' % { "reg" : reg }
         readDestCode = ''
         if readDest:
@@ -1462,13 +1984,14 @@ let {{
         ''' % { "op" : op, "readDest" : readDestCode }
         for reg in range(4):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": 2,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonUnequalRegExecute.subst(iop)
         for type in types:
@@ -1486,8 +2009,8 @@ let {{
         destElem = (((srcElem1 & ~(Element)1) / 2) +
                     ((srcElem2 & ~(Element)1) / 2)) + carryBit;
     '''
-    threeEqualRegInst("vhadd", "VhaddD", allTypes, 2, vhaddCode)
-    threeEqualRegInst("vhadd", "VhaddQ", allTypes, 4, vhaddCode)
+    threeEqualRegInst("vhadd", "VhaddD", "SimdAddOp", allTypes, 2, vhaddCode)
+    threeEqualRegInst("vhadd", "VhaddQ", "SimdAddOp", allTypes, 4, vhaddCode)
 
     vrhaddCode = '''
         Element carryBit =
@@ -1499,8 +2022,8 @@ let {{
         destElem = (((srcElem1 & ~(Element)1) / 2) +
                     ((srcElem2 & ~(Element)1) / 2)) + carryBit;
     '''
-    threeEqualRegInst("vrhadd", "VrhaddD", allTypes, 2, vrhaddCode)
-    threeEqualRegInst("vrhadd", "VrhaddQ", allTypes, 4, vrhaddCode)
+    threeEqualRegInst("vrhadd", "VrhaddD", "SimdAddOp", allTypes, 2, vrhaddCode)
+    threeEqualRegInst("vrhadd", "VrhaddQ", "SimdAddOp", allTypes, 4, vrhaddCode)
 
     vhsubCode = '''
         Element barrowBit =
@@ -1511,134 +2034,132 @@ let {{
         destElem = (((srcElem1 & ~(Element)1) / 2) -
                     ((srcElem2 & ~(Element)1) / 2)) - barrowBit;
     '''
-    threeEqualRegInst("vhsub", "VhsubD", allTypes, 2, vhsubCode)
-    threeEqualRegInst("vhsub", "VhsubQ", allTypes, 4, vhsubCode)
+    threeEqualRegInst("vhsub", "VhsubD", "SimdAddOp", allTypes, 2, vhsubCode)
+    threeEqualRegInst("vhsub", "VhsubQ", "SimdAddOp", allTypes, 4, vhsubCode)
 
     vandCode = '''
         destElem = srcElem1 & srcElem2;
     '''
-    threeEqualRegInst("vand", "VandD", unsignedTypes, 2, vandCode)
-    threeEqualRegInst("vand", "VandQ", unsignedTypes, 4, vandCode)
+    threeEqualRegInst("vand", "VandD", "SimdAluOp", unsignedTypes, 2, vandCode)
+    threeEqualRegInst("vand", "VandQ", "SimdAluOp", unsignedTypes, 4, vandCode)
 
     vbicCode = '''
         destElem = srcElem1 & ~srcElem2;
     '''
-    threeEqualRegInst("vbic", "VbicD", unsignedTypes, 2, vbicCode)
-    threeEqualRegInst("vbic", "VbicQ", unsignedTypes, 4, vbicCode)
+    threeEqualRegInst("vbic", "VbicD", "SimdAluOp", unsignedTypes, 2, vbicCode)
+    threeEqualRegInst("vbic", "VbicQ", "SimdAluOp", unsignedTypes, 4, vbicCode)
 
     vorrCode = '''
         destElem = srcElem1 | srcElem2;
     '''
-    threeEqualRegInst("vorr", "VorrD", unsignedTypes, 2, vorrCode)
-    threeEqualRegInst("vorr", "VorrQ", unsignedTypes, 4, vorrCode)
+    threeEqualRegInst("vorr", "VorrD", "SimdAluOp", unsignedTypes, 2, vorrCode)
+    threeEqualRegInst("vorr", "VorrQ", "SimdAluOp", unsignedTypes, 4, vorrCode)
 
-    threeEqualRegInst("vmov", "VmovD", unsignedTypes, 2, vorrCode)
-    threeEqualRegInst("vmov", "VmovQ", unsignedTypes, 4, vorrCode)
+    threeEqualRegInst("vmov", "VmovD", "SimdMiscOp", unsignedTypes, 2, vorrCode)
+    threeEqualRegInst("vmov", "VmovQ", "SimdMiscOp", unsignedTypes, 4, vorrCode)
 
     vornCode = '''
         destElem = srcElem1 | ~srcElem2;
     '''
-    threeEqualRegInst("vorn", "VornD", unsignedTypes, 2, vornCode)
-    threeEqualRegInst("vorn", "VornQ", unsignedTypes, 4, vornCode)
+    threeEqualRegInst("vorn", "VornD", "SimdAluOp", unsignedTypes, 2, vornCode)
+    threeEqualRegInst("vorn", "VornQ", "SimdAluOp", unsignedTypes, 4, vornCode)
 
     veorCode = '''
         destElem = srcElem1 ^ srcElem2;
     '''
-    threeEqualRegInst("veor", "VeorD", unsignedTypes, 2, veorCode)
-    threeEqualRegInst("veor", "VeorQ", unsignedTypes, 4, veorCode)
+    threeEqualRegInst("veor", "VeorD", "SimdAluOp", unsignedTypes, 2, veorCode)
+    threeEqualRegInst("veor", "VeorQ", "SimdAluOp", unsignedTypes, 4, veorCode)
 
     vbifCode = '''
         destElem = (destElem & srcElem2) | (srcElem1 & ~srcElem2);
     '''
-    threeEqualRegInst("vbif", "VbifD", unsignedTypes, 2, vbifCode, True)
-    threeEqualRegInst("vbif", "VbifQ", unsignedTypes, 4, vbifCode, True)
+    threeEqualRegInst("vbif", "VbifD", "SimdAluOp", unsignedTypes, 2, vbifCode, True)
+    threeEqualRegInst("vbif", "VbifQ", "SimdAluOp", unsignedTypes, 4, vbifCode, True)
     vbitCode = '''
         destElem = (srcElem1 & srcElem2) | (destElem & ~srcElem2);
     '''
-    threeEqualRegInst("vbit", "VbitD", unsignedTypes, 2, vbitCode, True)
-    threeEqualRegInst("vbit", "VbitQ", unsignedTypes, 4, vbitCode, True)
+    threeEqualRegInst("vbit", "VbitD", "SimdAluOp", unsignedTypes, 2, vbitCode, True)
+    threeEqualRegInst("vbit", "VbitQ", "SimdAluOp", unsignedTypes, 4, vbitCode, True)
     vbslCode = '''
         destElem = (srcElem1 & destElem) | (srcElem2 & ~destElem);
     '''
-    threeEqualRegInst("vbsl", "VbslD", unsignedTypes, 2, vbslCode, True)
-    threeEqualRegInst("vbsl", "VbslQ", unsignedTypes, 4, vbslCode, True)
+    threeEqualRegInst("vbsl", "VbslD", "SimdAluOp", unsignedTypes, 2, vbslCode, True)
+    threeEqualRegInst("vbsl", "VbslQ", "SimdAluOp", unsignedTypes, 4, vbslCode, True)
 
     vmaxCode = '''
         destElem = (srcElem1 > srcElem2) ? srcElem1 : srcElem2;
     '''
-    threeEqualRegInst("vmax", "VmaxD", allTypes, 2, vmaxCode)
-    threeEqualRegInst("vmax", "VmaxQ", allTypes, 4, vmaxCode)
+    threeEqualRegInst("vmax", "VmaxD", "SimdCmpOp", allTypes, 2, vmaxCode)
+    threeEqualRegInst("vmax", "VmaxQ", "SimdCmpOp", allTypes, 4, vmaxCode)
 
     vminCode = '''
         destElem = (srcElem1 < srcElem2) ? srcElem1 : srcElem2;
     '''
-    threeEqualRegInst("vmin", "VminD", allTypes, 2, vminCode)
-    threeEqualRegInst("vmin", "VminQ", allTypes, 4, vminCode)
+    threeEqualRegInst("vmin", "VminD", "SimdCmpOp", allTypes, 2, vminCode)
+    threeEqualRegInst("vmin", "VminQ", "SimdCmpOp", allTypes, 4, vminCode)
 
     vaddCode = '''
         destElem = srcElem1 + srcElem2;
     '''
-    threeEqualRegInst("vadd", "NVaddD", unsignedTypes, 2, vaddCode)
-    threeEqualRegInst("vadd", "NVaddQ", unsignedTypes, 4, vaddCode)
+    threeEqualRegInst("vadd", "NVaddD", "SimdAddOp", unsignedTypes, 2, vaddCode)
+    threeEqualRegInst("vadd", "NVaddQ", "SimdAddOp", unsignedTypes, 4, vaddCode)
 
-    threeEqualRegInst("vpadd", "NVpaddD", unsignedTypes,
+    threeEqualRegInst("vpadd", "NVpaddD", "SimdAddOp", smallUnsignedTypes,
                       2, vaddCode, pairwise=True)
-    threeEqualRegInst("vpadd", "NVpaddQ", unsignedTypes,
-                      4, vaddCode, pairwise=True)
     vaddlwCode = '''
         destElem = (BigElement)srcElem1 + (BigElement)srcElem2;
     '''
-    threeRegLongInst("vaddl", "Vaddl", smallTypes, vaddlwCode)
-    threeRegWideInst("vaddw", "Vaddw", smallTypes, vaddlwCode)
+    threeRegLongInst("vaddl", "Vaddl", "SimdAddOp", smallTypes, vaddlwCode)
+    threeRegWideInst("vaddw", "Vaddw", "SimdAddOp", smallTypes, vaddlwCode)
     vaddhnCode = '''
         destElem = ((BigElement)srcElem1 + (BigElement)srcElem2) >>
                    (sizeof(Element) * 8);
     '''
-    threeRegNarrowInst("vaddhn", "Vaddhn", smallTypes, vaddhnCode)
+    threeRegNarrowInst("vaddhn", "Vaddhn", "SimdAddOp", smallTypes, vaddhnCode)
     vraddhnCode = '''
         destElem = ((BigElement)srcElem1 + (BigElement)srcElem2 +
                     ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
                    (sizeof(Element) * 8);
     '''
-    threeRegNarrowInst("vraddhn", "Vraddhn", smallTypes, vraddhnCode)
+    threeRegNarrowInst("vraddhn", "Vraddhn", "SimdAddOp", smallTypes, vraddhnCode)
 
     vsubCode = '''
         destElem = srcElem1 - srcElem2;
     '''
-    threeEqualRegInst("vsub", "NVsubD", unsignedTypes, 2, vsubCode)
-    threeEqualRegInst("vsub", "NVsubQ", unsignedTypes, 4, vsubCode)
+    threeEqualRegInst("vsub", "NVsubD", "SimdAddOp", unsignedTypes, 2, vsubCode)
+    threeEqualRegInst("vsub", "NVsubQ", "SimdAddOp", unsignedTypes, 4, vsubCode)
     vsublwCode = '''
         destElem = (BigElement)srcElem1 - (BigElement)srcElem2;
     '''
-    threeRegLongInst("vsubl", "Vsubl", smallTypes, vsublwCode)
-    threeRegWideInst("vsubw", "Vsubw", smallTypes, vsublwCode)
+    threeRegLongInst("vsubl", "Vsubl", "SimdAddOp", smallTypes, vsublwCode)
+    threeRegWideInst("vsubw", "Vsubw", "SimdAddOp", smallTypes, vsublwCode)
 
     vqaddUCode = '''
         destElem = srcElem1 + srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (destElem < srcElem1 || destElem < srcElem2) {
             destElem = (Element)(-1);
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqadd", "VqaddUD", unsignedTypes, 2, vqaddUCode)
-    threeEqualRegInst("vqadd", "VqaddUQ", unsignedTypes, 4, vqaddUCode)
+    threeEqualRegInst("vqadd", "VqaddUD", "SimdAddOp", unsignedTypes, 2, vqaddUCode)
+    threeEqualRegInst("vqadd", "VqaddUQ", "SimdAddOp", unsignedTypes, 4, vqaddUCode)
     vsubhnCode = '''
         destElem = ((BigElement)srcElem1 - (BigElement)srcElem2) >>
                    (sizeof(Element) * 8);
     '''
-    threeRegNarrowInst("vsubhn", "Vsubhn", smallTypes, vsubhnCode)
+    threeRegNarrowInst("vsubhn", "Vsubhn", "SimdAddOp", smallTypes, vsubhnCode)
     vrsubhnCode = '''
         destElem = ((BigElement)srcElem1 - (BigElement)srcElem2 +
                     ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
                    (sizeof(Element) * 8);
     '''
-    threeRegNarrowInst("vrsubhn", "Vrsubhn", smallTypes, vrsubhnCode)
+    threeRegNarrowInst("vrsubhn", "Vrsubhn", "SimdAddOp", smallTypes, vrsubhnCode)
 
     vqaddSCode = '''
         destElem = srcElem1 + srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         bool negDest = (destElem < 0);
         bool negSrc1 = (srcElem1 < 0);
         bool negSrc2 = (srcElem2 < 0);
@@ -1648,26 +2169,26 @@ let {{
                 destElem -= 1;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqadd", "VqaddSD", signedTypes, 2, vqaddSCode)
-    threeEqualRegInst("vqadd", "VqaddSQ", signedTypes, 4, vqaddSCode)
+    threeEqualRegInst("vqadd", "VqaddSD", "SimdAddOp", signedTypes, 2, vqaddSCode)
+    threeEqualRegInst("vqadd", "VqaddSQ", "SimdAddOp", signedTypes, 4, vqaddSCode)
 
     vqsubUCode = '''
         destElem = srcElem1 - srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (destElem > srcElem1) {
             destElem = 0;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqsub", "VqsubUD", unsignedTypes, 2, vqsubUCode)
-    threeEqualRegInst("vqsub", "VqsubUQ", unsignedTypes, 4, vqsubUCode)
+    threeEqualRegInst("vqsub", "VqsubUD", "SimdAddOp", unsignedTypes, 2, vqsubUCode)
+    threeEqualRegInst("vqsub", "VqsubUQ", "SimdAddOp", unsignedTypes, 4, vqsubUCode)
 
     vqsubSCode = '''
         destElem = srcElem1 - srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         bool negDest = (destElem < 0);
         bool negSrc1 = (srcElem1 < 0);
         bool posSrc2 = (srcElem2 >= 0);
@@ -1677,28 +2198,28 @@ let {{
                 destElem -= 1;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqsub", "VqsubSD", signedTypes, 2, vqsubSCode)
-    threeEqualRegInst("vqsub", "VqsubSQ", signedTypes, 4, vqsubSCode)
+    threeEqualRegInst("vqsub", "VqsubSD", "SimdAddOp", signedTypes, 2, vqsubSCode)
+    threeEqualRegInst("vqsub", "VqsubSQ", "SimdAddOp", signedTypes, 4, vqsubSCode)
 
     vcgtCode = '''
         destElem =  (srcElem1 > srcElem2) ? (Element)(-1) : 0;
     '''
-    threeEqualRegInst("vcgt", "VcgtD", allTypes, 2, vcgtCode)
-    threeEqualRegInst("vcgt", "VcgtQ", allTypes, 4, vcgtCode)
+    threeEqualRegInst("vcgt", "VcgtD", "SimdCmpOp", allTypes, 2, vcgtCode)
+    threeEqualRegInst("vcgt", "VcgtQ", "SimdCmpOp", allTypes, 4, vcgtCode)
 
     vcgeCode = '''
         destElem =  (srcElem1 >= srcElem2) ? (Element)(-1) : 0;
     '''
-    threeEqualRegInst("vcge", "VcgeD", allTypes, 2, vcgeCode)
-    threeEqualRegInst("vcge", "VcgeQ", allTypes, 4, vcgeCode)
+    threeEqualRegInst("vcge", "VcgeD", "SimdCmpOp", allTypes, 2, vcgeCode)
+    threeEqualRegInst("vcge", "VcgeQ", "SimdCmpOp", allTypes, 4, vcgeCode)
 
     vceqCode = '''
         destElem =  (srcElem1 == srcElem2) ? (Element)(-1) : 0;
     '''
-    threeEqualRegInst("vceq", "VceqD", unsignedTypes, 2, vceqCode)
-    threeEqualRegInst("vceq", "VceqQ", unsignedTypes, 4, vceqCode)
+    threeEqualRegInst("vceq", "VceqD", "SimdCmpOp", unsignedTypes, 2, vceqCode)
+    threeEqualRegInst("vceq", "VceqQ", "SimdCmpOp", unsignedTypes, 4, vceqCode)
 
     vshlCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
@@ -1711,7 +2232,7 @@ let {{
                 destElem = (srcElem1 >> shiftAmt);
             }
             // Make sure the right shift sign extended when it should.
-            if (srcElem1 < 0 && destElem >= 0) {
+            if (ltz(srcElem1) && !ltz(destElem)) {
                 destElem |= -((Element)1 << (sizeof(Element) * 8 -
                                              1 - shiftAmt));
             }
@@ -1723,8 +2244,8 @@ let {{
             }
         }
     '''
-    threeEqualRegInst("vshl", "VshlD", allTypes, 2, vshlCode)
-    threeEqualRegInst("vshl", "VshlQ", allTypes, 4, vshlCode)
+    threeEqualRegInst("vshl", "VshlD", "SimdShiftOp", allTypes, 2, vshlCode)
+    threeEqualRegInst("vshl", "VshlQ", "SimdShiftOp", allTypes, 4, vshlCode)
 
     vrshlCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
@@ -1733,7 +2254,7 @@ let {{
             Element rBit = 0;
             if (shiftAmt <= sizeof(Element) * 8)
                 rBit = bits(srcElem1, shiftAmt - 1);
-            if (shiftAmt > sizeof(Element) * 8 && srcElem1 < 0)
+            if (shiftAmt > sizeof(Element) * 8 && ltz(srcElem1))
                 rBit = 1;
             if (shiftAmt >= sizeof(Element) * 8) {
                 shiftAmt = sizeof(Element) * 8 - 1;
@@ -1742,7 +2263,7 @@ let {{
                 destElem = (srcElem1 >> shiftAmt);
             }
             // Make sure the right shift sign extended when it should.
-            if (srcElem1 < 0 && destElem >= 0) {
+            if (ltz(srcElem1) && !ltz(destElem)) {
                 destElem |= -((Element)1 << (sizeof(Element) * 8 -
                                              1 - shiftAmt));
             }
@@ -1757,12 +2278,12 @@ let {{
             destElem = srcElem1;
         }
     '''
-    threeEqualRegInst("vrshl", "VrshlD", allTypes, 2, vrshlCode)
-    threeEqualRegInst("vrshl", "VrshlQ", allTypes, 4, vrshlCode)
+    threeEqualRegInst("vrshl", "VrshlD", "SimdAluOp", allTypes, 2, vrshlCode)
+    threeEqualRegInst("vrshl", "VrshlQ", "SimdAluOp", allTypes, 4, vrshlCode)
 
     vqshlUCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (shiftAmt < 0) {
             shiftAmt = -shiftAmt;
             if (shiftAmt >= sizeof(Element) * 8) {
@@ -1771,11 +2292,6 @@ let {{
             } else {
                 destElem = (srcElem1 >> shiftAmt);
             }
-            // Make sure the right shift sign extended when it should.
-            if (srcElem1 < 0 && destElem >= 0) {
-                destElem |= -((Element)1 << (sizeof(Element) * 8 -
-                                             1 - shiftAmt));
-            }
         } else if (shiftAmt > 0) {
             if (shiftAmt >= sizeof(Element) * 8) {
                 if (srcElem1 != 0) {
@@ -1796,14 +2312,14 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqshl", "VqshlUD", unsignedTypes, 2, vqshlUCode)
-    threeEqualRegInst("vqshl", "VqshlUQ", unsignedTypes, 4, vqshlUCode)
+    threeEqualRegInst("vqshl", "VqshlUD", "SimdAluOp", unsignedTypes, 2, vqshlUCode)
+    threeEqualRegInst("vqshl", "VqshlUQ", "SimdAluOp", unsignedTypes, 4, vqshlUCode)
 
     vqshlSCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (shiftAmt < 0) {
             shiftAmt = -shiftAmt;
             if (shiftAmt >= sizeof(Element) * 8) {
@@ -1842,32 +2358,25 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqshl", "VqshlSD", signedTypes, 2, vqshlSCode)
-    threeEqualRegInst("vqshl", "VqshlSQ", signedTypes, 4, vqshlSCode)
+    threeEqualRegInst("vqshl", "VqshlSD", "SimdCmpOp", signedTypes, 2, vqshlSCode)
+    threeEqualRegInst("vqshl", "VqshlSQ", "SimdCmpOp", signedTypes, 4, vqshlSCode)
 
     vqrshlUCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (shiftAmt < 0) {
             shiftAmt = -shiftAmt;
             Element rBit = 0;
             if (shiftAmt <= sizeof(Element) * 8)
                 rBit = bits(srcElem1, shiftAmt - 1);
-            if (shiftAmt > sizeof(Element) * 8 && srcElem1 < 0)
-                rBit = 1;
             if (shiftAmt >= sizeof(Element) * 8) {
                 shiftAmt = sizeof(Element) * 8 - 1;
                 destElem = 0;
             } else {
                 destElem = (srcElem1 >> shiftAmt);
             }
-            // Make sure the right shift sign extended when it should.
-            if (srcElem1 < 0 && destElem >= 0) {
-                destElem |= -((Element)1 << (sizeof(Element) * 8 -
-                                             1 - shiftAmt));
-            }
             destElem += rBit;
         } else {
             if (shiftAmt >= sizeof(Element) * 8) {
@@ -1887,14 +2396,14 @@ let {{
                 }
             }
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqrshl", "VqrshlUD", unsignedTypes, 2, vqrshlUCode)
-    threeEqualRegInst("vqrshl", "VqrshlUQ", unsignedTypes, 4, vqrshlUCode)
+    threeEqualRegInst("vqrshl", "VqrshlUD", "SimdCmpOp", unsignedTypes, 2, vqrshlUCode)
+    threeEqualRegInst("vqrshl", "VqrshlUQ", "SimdCmpOp", unsignedTypes, 4, vqrshlUCode)
 
     vqrshlSCode = '''
         int16_t shiftAmt = (int8_t)srcElem2;
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (shiftAmt < 0) {
             shiftAmt = -shiftAmt;
             Element rBit = 0;
@@ -1939,65 +2448,65 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqrshl", "VqrshlSD", signedTypes, 2, vqrshlSCode)
-    threeEqualRegInst("vqrshl", "VqrshlSQ", signedTypes, 4, vqrshlSCode)
+    threeEqualRegInst("vqrshl", "VqrshlSD", "SimdCmpOp", signedTypes, 2, vqrshlSCode)
+    threeEqualRegInst("vqrshl", "VqrshlSQ", "SimdCmpOp", signedTypes, 4, vqrshlSCode)
 
     vabaCode = '''
         destElem += (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
                                             (srcElem2 - srcElem1);
     '''
-    threeEqualRegInst("vaba", "VabaD", allTypes, 2, vabaCode, True)
-    threeEqualRegInst("vaba", "VabaQ", allTypes, 4, vabaCode, True)
+    threeEqualRegInst("vaba", "VabaD", "SimdAddAccOp", allTypes, 2, vabaCode, True)
+    threeEqualRegInst("vaba", "VabaQ", "SimdAddAccOp", allTypes, 4, vabaCode, True)
     vabalCode = '''
         destElem += (srcElem1 > srcElem2) ?
             ((BigElement)srcElem1 - (BigElement)srcElem2) :
             ((BigElement)srcElem2 - (BigElement)srcElem1);
     '''
-    threeRegLongInst("vabal", "Vabal", smallTypes, vabalCode, True)
+    threeRegLongInst("vabal", "Vabal", "SimdAddAccOp", smallTypes, vabalCode, True)
 
     vabdCode = '''
         destElem = (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
                                            (srcElem2 - srcElem1);
     '''
-    threeEqualRegInst("vabd", "VabdD", allTypes, 2, vabdCode)
-    threeEqualRegInst("vabd", "VabdQ", allTypes, 4, vabdCode)
+    threeEqualRegInst("vabd", "VabdD", "SimdAddOp", allTypes, 2, vabdCode)
+    threeEqualRegInst("vabd", "VabdQ", "SimdAddOp", allTypes, 4, vabdCode)
     vabdlCode = '''
         destElem = (srcElem1 > srcElem2) ?
             ((BigElement)srcElem1 - (BigElement)srcElem2) :
             ((BigElement)srcElem2 - (BigElement)srcElem1);
     '''
-    threeRegLongInst("vabdl", "Vabdl", smallTypes, vabdlCode)
+    threeRegLongInst("vabdl", "Vabdl", "SimdAddOp", smallTypes, vabdlCode)
 
     vtstCode = '''
         destElem = (srcElem1 & srcElem2) ? (Element)(-1) : 0;
     '''
-    threeEqualRegInst("vtst", "VtstD", unsignedTypes, 2, vtstCode)
-    threeEqualRegInst("vtst", "VtstQ", unsignedTypes, 4, vtstCode)
+    threeEqualRegInst("vtst", "VtstD", "SimdAluOp", unsignedTypes, 2, vtstCode)
+    threeEqualRegInst("vtst", "VtstQ", "SimdAluOp", unsignedTypes, 4, vtstCode)
 
     vmulCode = '''
         destElem = srcElem1 * srcElem2;
     '''
-    threeEqualRegInst("vmul", "NVmulD", allTypes, 2, vmulCode)
-    threeEqualRegInst("vmul", "NVmulQ", allTypes, 4, vmulCode)
+    threeEqualRegInst("vmul", "NVmulD", "SimdMultOp", allTypes, 2, vmulCode)
+    threeEqualRegInst("vmul", "NVmulQ", "SimdMultOp", allTypes, 4, vmulCode)
     vmullCode = '''
         destElem = (BigElement)srcElem1 * (BigElement)srcElem2;
     '''
-    threeRegLongInst("vmull", "Vmull", smallTypes, vmullCode)
+    threeRegLongInst("vmull", "Vmull", "SimdMultOp", smallTypes, vmullCode)
 
     vmlaCode = '''
         destElem = destElem + srcElem1 * srcElem2;
     '''
-    threeEqualRegInst("vmla", "NVmlaD", allTypes, 2, vmlaCode, True)
-    threeEqualRegInst("vmla", "NVmlaQ", allTypes, 4, vmlaCode, True)
+    threeEqualRegInst("vmla", "NVmlaD", "SimdMultAccOp", allTypes, 2, vmlaCode, True)
+    threeEqualRegInst("vmla", "NVmlaQ", "SimdMultAccOp", allTypes, 4, vmlaCode, True)
     vmlalCode = '''
         destElem = destElem + (BigElement)srcElem1 * (BigElement)srcElem2;
     '''
-    threeRegLongInst("vmlal", "Vmlal", smallTypes, vmlalCode, True)
+    threeRegLongInst("vmlal", "Vmlal", "SimdMultAccOp", smallTypes, vmlalCode, True)
 
     vqdmlalCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
         Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
         Element halfNeg = maxNeg / 2;
@@ -2007,22 +2516,22 @@ let {{
             midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
             fpscr.qc = 1;
         }
-        bool negPreDest = (destElem < 0);
+        bool negPreDest = ltz(destElem);
         destElem += midElem;
-        bool negDest = (destElem < 0);
-        bool negMid = (midElem < 0);
+        bool negDest = ltz(destElem);
+        bool negMid = ltz(midElem);
         if (negPreDest == negMid && negMid != negDest) {
             destElem = mask(sizeof(BigElement) * 8 - 1);
             if (negPreDest)
                 destElem = ~destElem;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeRegLongInst("vqdmlal", "Vqdmlal", smallTypes, vqdmlalCode, True)
+    threeRegLongInst("vqdmlal", "Vqdmlal", "SimdMultAccOp", smallTypes, vqdmlalCode, True)
 
     vqdmlslCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
         Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
         Element halfNeg = maxNeg / 2;
@@ -2032,22 +2541,22 @@ let {{
             midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
             fpscr.qc = 1;
         }
-        bool negPreDest = (destElem < 0);
+        bool negPreDest = ltz(destElem);
         destElem -= midElem;
-        bool negDest = (destElem < 0);
-        bool posMid = (midElem > 0);
+        bool negDest = ltz(destElem);
+        bool posMid = ltz((BigElement)-midElem);
         if (negPreDest == posMid && posMid != negDest) {
             destElem = mask(sizeof(BigElement) * 8 - 1);
             if (negPreDest)
                 destElem = ~destElem;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeRegLongInst("vqdmlsl", "Vqdmlsl", smallTypes, vqdmlslCode, True)
+    threeRegLongInst("vqdmlsl", "Vqdmlsl", "SimdMultAccOp", smallTypes, vqdmlslCode, True)
 
     vqdmullCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
         if (srcElem1 == srcElem2 &&
                 srcElem1 == (Element)((Element)1 <<
@@ -2055,19 +2564,19 @@ let {{
             destElem = ~((BigElement)srcElem1 << (sizeof(Element) * 8));
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeRegLongInst("vqdmull", "Vqdmull", smallTypes, vqdmullCode)
+    threeRegLongInst("vqdmull", "Vqdmull", "SimdMultAccOp", smallTypes, vqdmullCode)
 
     vmlsCode = '''
         destElem = destElem - srcElem1 * srcElem2;
     '''
-    threeEqualRegInst("vmls", "NVmlsD", allTypes, 2, vmlsCode, True)
-    threeEqualRegInst("vmls", "NVmlsQ", allTypes, 4, vmlsCode, True)
+    threeEqualRegInst("vmls", "NVmlsD", "SimdMultAccOp", allTypes, 2, vmlsCode, True)
+    threeEqualRegInst("vmls", "NVmlsQ", "SimdMultAccOp", allTypes, 4, vmlsCode, True)
     vmlslCode = '''
         destElem = destElem - (BigElement)srcElem1 * (BigElement)srcElem2;
     '''
-    threeRegLongInst("vmlsl", "Vmlsl", smallTypes, vmlslCode, True)
+    threeRegLongInst("vmlsl", "Vmlsl", "SimdMultAccOp", smallTypes, vmlslCode, True)
 
     vmulpCode = '''
         destElem = 0;
@@ -2076,8 +2585,8 @@ let {{
                 destElem ^= srcElem1 << j;
         }
     '''
-    threeEqualRegInst("vmul", "NVmulpD", unsignedTypes, 2, vmulpCode)
-    threeEqualRegInst("vmul", "NVmulpQ", unsignedTypes, 4, vmulpCode)
+    threeEqualRegInst("vmul", "NVmulpD", "SimdMultOp", unsignedTypes, 2, vmulpCode)
+    threeEqualRegInst("vmul", "NVmulpQ", "SimdMultOp", unsignedTypes, 4, vmulpCode)
     vmullpCode = '''
         destElem = 0;
         for (unsigned j = 0; j < sizeof(Element) * 8; j++) {
@@ -2085,16 +2594,14 @@ let {{
                 destElem ^= (BigElement)srcElem1 << j;
         }
     '''
-    threeRegLongInst("vmull", "Vmullp", smallUnsignedTypes, vmullpCode)
+    threeRegLongInst("vmull", "Vmullp", "SimdMultOp", smallUnsignedTypes, vmullpCode)
 
-    threeEqualRegInst("vpmax", "VpmaxD", allTypes, 2, vmaxCode, pairwise=True)
-    threeEqualRegInst("vpmax", "VpmaxQ", allTypes, 4, vmaxCode, pairwise=True)
+    threeEqualRegInst("vpmax", "VpmaxD", "SimdCmpOp", smallTypes, 2, vmaxCode, pairwise=True)
 
-    threeEqualRegInst("vpmin", "VpminD", allTypes, 2, vminCode, pairwise=True)
-    threeEqualRegInst("vpmin", "VpminQ", allTypes, 4, vminCode, pairwise=True)
+    threeEqualRegInst("vpmin", "VpminD", "SimdCmpOp", smallTypes, 2, vminCode, pairwise=True)
 
     vqdmulhCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2) >>
                    (sizeof(Element) * 8);
         if (srcElem1 == srcElem2 &&
@@ -2103,13 +2610,13 @@ let {{
             destElem = ~srcElem1;
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    threeEqualRegInst("vqdmulh", "VqdmulhD", smallSignedTypes, 2, vqdmulhCode)
-    threeEqualRegInst("vqdmulh", "VqdmulhQ", smallSignedTypes, 4, vqdmulhCode)
+    threeEqualRegInst("vqdmulh", "VqdmulhD", "SimdMultOp", smallSignedTypes, 2, vqdmulhCode)
+    threeEqualRegInst("vqdmulh", "VqdmulhQ", "SimdMultOp", smallSignedTypes, 4, vqdmulhCode)
 
     vqrdmulhCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2 +
                     ((int64_t)1 << (sizeof(Element) * 8 - 1))) >>
                    (sizeof(Element) * 8);
@@ -2125,236 +2632,254 @@ let {{
             }
             fpscr.qc = 1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     threeEqualRegInst("vqrdmulh", "VqrdmulhD",
-            smallSignedTypes, 2, vqrdmulhCode)
+            "SimdMultOp", smallSignedTypes, 2, vqrdmulhCode)
     threeEqualRegInst("vqrdmulh", "VqrdmulhQ",
-            smallSignedTypes, 4, vqrdmulhCode)
+            "SimdMultOp", smallSignedTypes, 4, vqrdmulhCode)
 
     vmaxfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         bool done;
         destReg = processNans(fpscr, done, true, srcReg1, srcReg2);
         if (!done) {
-            destReg = binaryOp(fpscr, srcReg1, srcReg2, fpMaxS,
+            destReg = binaryOp(fpscr, srcReg1, srcReg2, fpMax<float>,
                                true, true, VfpRoundNearest);
         } else if (flushToZero(srcReg1, srcReg2)) {
             fpscr.idc = 1;
         }
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vmax", "VmaxDFp", ("float",), 2, vmaxfpCode)
-    threeEqualRegInstFp("vmax", "VmaxQFp", ("float",), 4, vmaxfpCode)
+    threeEqualRegInstFp("vmax", "VmaxDFp", "SimdFloatCmpOp", ("float",), 2, vmaxfpCode)
+    threeEqualRegInstFp("vmax", "VmaxQFp", "SimdFloatCmpOp", ("float",), 4, vmaxfpCode)
 
     vminfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         bool done;
         destReg = processNans(fpscr, done, true, srcReg1, srcReg2);
         if (!done) {
-            destReg = binaryOp(fpscr, srcReg1, srcReg2, fpMinS,
+            destReg = binaryOp(fpscr, srcReg1, srcReg2, fpMin<float>,
                                true, true, VfpRoundNearest);
         } else if (flushToZero(srcReg1, srcReg2)) {
             fpscr.idc = 1;
         }
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vmin", "VminDFp", ("float",), 2, vminfpCode)
-    threeEqualRegInstFp("vmin", "VminQFp", ("float",), 4, vminfpCode)
+    threeEqualRegInstFp("vmin", "VminDFp", "SimdFloatCmpOp", ("float",), 2, vminfpCode)
+    threeEqualRegInstFp("vmin", "VminQFp", "SimdFloatCmpOp", ("float",), 4, vminfpCode)
 
-    threeEqualRegInstFp("vpmax", "VpmaxDFp", ("float",),
+    threeEqualRegInstFp("vpmax", "VpmaxDFp", "SimdFloatCmpOp", ("float",),
                         2, vmaxfpCode, pairwise=True)
-    threeEqualRegInstFp("vpmax", "VpmaxQFp", ("float",),
+    threeEqualRegInstFp("vpmax", "VpmaxQFp", "SimdFloatCmpOp", ("float",),
                         4, vmaxfpCode, pairwise=True)
 
-    threeEqualRegInstFp("vpmin", "VpminDFp", ("float",),
+    threeEqualRegInstFp("vpmin", "VpminDFp", "SimdFloatCmpOp", ("float",),
                         2, vminfpCode, pairwise=True)
-    threeEqualRegInstFp("vpmin", "VpminQFp", ("float",),
+    threeEqualRegInstFp("vpmin", "VpminQFp", "SimdFloatCmpOp", ("float",),
                         4, vminfpCode, pairwise=True)
 
     vaddfpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         destReg = binaryOp(fpscr, srcReg1, srcReg2, fpAddS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vadd", "VaddDFp", ("float",), 2, vaddfpCode)
-    threeEqualRegInstFp("vadd", "VaddQFp", ("float",), 4, vaddfpCode)
+    threeEqualRegInstFp("vadd", "VaddDFp", "SimdFloatAddOp", ("float",), 2, vaddfpCode)
+    threeEqualRegInstFp("vadd", "VaddQFp", "SimdFloatAddOp", ("float",), 4, vaddfpCode)
 
-    threeEqualRegInstFp("vpadd", "VpaddDFp", ("float",),
+    threeEqualRegInstFp("vpadd", "VpaddDFp", "SimdFloatAddOp", ("float",),
                         2, vaddfpCode, pairwise=True)
-    threeEqualRegInstFp("vpadd", "VpaddQFp", ("float",),
+    threeEqualRegInstFp("vpadd", "VpaddQFp", "SimdFloatAddOp", ("float",),
                         4, vaddfpCode, pairwise=True)
 
     vsubfpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         destReg = binaryOp(fpscr, srcReg1, srcReg2, fpSubS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vsub", "VsubDFp", ("float",), 2, vsubfpCode)
-    threeEqualRegInstFp("vsub", "VsubQFp", ("float",), 4, vsubfpCode)
+    threeEqualRegInstFp("vsub", "VsubDFp", "SimdFloatAddOp", ("float",), 2, vsubfpCode)
+    threeEqualRegInstFp("vsub", "VsubQFp", "SimdFloatAddOp", ("float",), 4, vsubfpCode)
 
     vmulfpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         destReg = binaryOp(fpscr, srcReg1, srcReg2, fpMulS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vmul", "NVmulDFp", ("float",), 2, vmulfpCode)
-    threeEqualRegInstFp("vmul", "NVmulQFp", ("float",), 4, vmulfpCode)
+    threeEqualRegInstFp("vmul", "NVmulDFp", "SimdFloatMultOp", ("float",), 2, vmulfpCode)
+    threeEqualRegInstFp("vmul", "NVmulQFp", "SimdFloatMultOp", ("float",), 4, vmulfpCode)
 
     vmlafpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float mid = binaryOp(fpscr, srcReg1, srcReg2, fpMulS,
                              true, true, VfpRoundNearest);
         destReg = binaryOp(fpscr, mid, destReg, fpAddS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
+    '''
+    threeEqualRegInstFp("vmla", "NVmlaDFp", "SimdFloatMultAccOp", ("float",), 2, vmlafpCode, True)
+    threeEqualRegInstFp("vmla", "NVmlaQFp", "SimdFloatMultAccOp", ("float",), 4, vmlafpCode, True)
+
+    vfmafpCode = '''
+        FPSCR fpscr = (FPSCR) FpscrExc;
+        destReg = ternaryOp(fpscr, srcReg1, srcReg2, destReg, fpMulAdd<float>,
+                            true, true, VfpRoundNearest);
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vmla", "NVmlaDFp", ("float",), 2, vmlafpCode, True)
-    threeEqualRegInstFp("vmla", "NVmlaQFp", ("float",), 4, vmlafpCode, True)
+    threeEqualRegInstFp("vfma", "NVfmaDFp", "SimdFloatMultAccOp", ("float",), 2, vfmafpCode, True)
+    threeEqualRegInstFp("vfma", "NVfmaQFp", "SimdFloatMultAccOp", ("float",), 4, vfmafpCode, True)
+
+    vfmsfpCode = '''
+        FPSCR fpscr = (FPSCR) FpscrExc;
+        destReg = ternaryOp(fpscr, -srcReg1, srcReg2, destReg, fpMulAdd<float>,
+                            true, true, VfpRoundNearest);
+        FpscrExc = fpscr;
+    '''
+    threeEqualRegInstFp("vfms", "NVfmsDFp", "SimdFloatMultAccOp", ("float",), 2, vfmsfpCode, True)
+    threeEqualRegInstFp("vfms", "NVfmsQFp", "SimdFloatMultAccOp", ("float",), 4, vfmsfpCode, True)
 
     vmlsfpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float mid = binaryOp(fpscr, srcReg1, srcReg2, fpMulS,
                              true, true, VfpRoundNearest);
         destReg = binaryOp(fpscr, destReg, mid, fpSubS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vmls", "NVmlsDFp", ("float",), 2, vmlsfpCode, True)
-    threeEqualRegInstFp("vmls", "NVmlsQFp", ("float",), 4, vmlsfpCode, True)
+    threeEqualRegInstFp("vmls", "NVmlsDFp", "SimdFloatMultAccOp", ("float",), 2, vmlsfpCode, True)
+    threeEqualRegInstFp("vmls", "NVmlsQFp", "SimdFloatMultAccOp", ("float",), 4, vmlsfpCode, True)
 
     vcgtfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, srcReg2, vcgtFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vcgt", "VcgtDFp", ("float",),
+    threeEqualRegInstFp("vcgt", "VcgtDFp", "SimdFloatCmpOp", ("float",),
             2, vcgtfpCode, toInt = True)
-    threeEqualRegInstFp("vcgt", "VcgtQFp", ("float",),
+    threeEqualRegInstFp("vcgt", "VcgtQFp", "SimdFloatCmpOp", ("float",),
             4, vcgtfpCode, toInt = True)
 
     vcgefpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, srcReg2, vcgeFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vcge", "VcgeDFp", ("float",),
+    threeEqualRegInstFp("vcge", "VcgeDFp", "SimdFloatCmpOp", ("float",),
             2, vcgefpCode, toInt = True)
-    threeEqualRegInstFp("vcge", "VcgeQFp", ("float",),
+    threeEqualRegInstFp("vcge", "VcgeQFp", "SimdFloatCmpOp", ("float",),
             4, vcgefpCode, toInt = True)
 
     vacgtfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, srcReg2, vacgtFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vacgt", "VacgtDFp", ("float",),
+    threeEqualRegInstFp("vacgt", "VacgtDFp", "SimdFloatCmpOp", ("float",),
             2, vacgtfpCode, toInt = True)
-    threeEqualRegInstFp("vacgt", "VacgtQFp", ("float",),
+    threeEqualRegInstFp("vacgt", "VacgtQFp", "SimdFloatCmpOp", ("float",),
             4, vacgtfpCode, toInt = True)
 
     vacgefpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, srcReg2, vacgeFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vacge", "VacgeDFp", ("float",),
+    threeEqualRegInstFp("vacge", "VacgeDFp", "SimdFloatCmpOp", ("float",),
             2, vacgefpCode, toInt = True)
-    threeEqualRegInstFp("vacge", "VacgeQFp", ("float",),
+    threeEqualRegInstFp("vacge", "VacgeQFp", "SimdFloatCmpOp", ("float",),
             4, vacgefpCode, toInt = True)
 
     vceqfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, srcReg2, vceqFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vceq", "VceqDFp", ("float",),
+    threeEqualRegInstFp("vceq", "VceqDFp", "SimdFloatCmpOp", ("float",),
             2, vceqfpCode, toInt = True)
-    threeEqualRegInstFp("vceq", "VceqQFp", ("float",),
+    threeEqualRegInstFp("vceq", "VceqQFp", "SimdFloatCmpOp", ("float",),
             4, vceqfpCode, toInt = True)
 
     vrecpsCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         destReg = binaryOp(fpscr, srcReg1, srcReg2, fpRecpsS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vrecps", "VrecpsDFp", ("float",), 2, vrecpsCode)
-    threeEqualRegInstFp("vrecps", "VrecpsQFp", ("float",), 4, vrecpsCode)
+    threeEqualRegInstFp("vrecps", "VrecpsDFp", "SimdFloatMultAccOp", ("float",), 2, vrecpsCode)
+    threeEqualRegInstFp("vrecps", "VrecpsQFp", "SimdFloatMultAccOp", ("float",), 4, vrecpsCode)
 
     vrsqrtsCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         destReg = binaryOp(fpscr, srcReg1, srcReg2, fpRSqrtsS,
                            true, true, VfpRoundNearest);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    threeEqualRegInstFp("vrsqrts", "VrsqrtsDFp", ("float",), 2, vrsqrtsCode)
-    threeEqualRegInstFp("vrsqrts", "VrsqrtsQFp", ("float",), 4, vrsqrtsCode)
+    threeEqualRegInstFp("vrsqrts", "VrsqrtsDFp", "SimdFloatMiscOp", ("float",), 2, vrsqrtsCode)
+    threeEqualRegInstFp("vrsqrts", "VrsqrtsQFp", "SimdFloatMiscOp", ("float",), 4, vrsqrtsCode)
 
     vabdfpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float mid = binaryOp(fpscr, srcReg1, srcReg2, fpSubS,
                              true, true, VfpRoundNearest);
         destReg = fabs(mid);
-        Fpscr = fpscr;
-    '''
-    threeEqualRegInstFp("vabd", "VabdDFp", ("float",), 2, vabdfpCode)
-    threeEqualRegInstFp("vabd", "VabdQFp", ("float",), 4, vabdfpCode)
-
-    twoEqualRegInst("vmla", "VmlasD", unsignedTypes, 2, vmlaCode, True)
-    twoEqualRegInst("vmla", "VmlasQ", unsignedTypes, 4, vmlaCode, True)
-    twoEqualRegInstFp("vmla", "VmlasDFp", ("float",), 2, vmlafpCode, True)
-    twoEqualRegInstFp("vmla", "VmlasQFp", ("float",), 4, vmlafpCode, True)
-    twoRegLongInst("vmlal", "Vmlals", smallTypes, vmlalCode, True)
-
-    twoEqualRegInst("vmls", "VmlssD", allTypes, 2, vmlsCode, True)
-    twoEqualRegInst("vmls", "VmlssQ", allTypes, 4, vmlsCode, True)
-    twoEqualRegInstFp("vmls", "VmlssDFp", ("float",), 2, vmlsfpCode, True)
-    twoEqualRegInstFp("vmls", "VmlssQFp", ("float",), 4, vmlsfpCode, True)
-    twoRegLongInst("vmlsl", "Vmlsls", smallTypes, vmlslCode, True)
-
-    twoEqualRegInst("vmul", "VmulsD", allTypes, 2, vmulCode)
-    twoEqualRegInst("vmul", "VmulsQ", allTypes, 4, vmulCode)
-    twoEqualRegInstFp("vmul", "VmulsDFp", ("float",), 2, vmulfpCode)
-    twoEqualRegInstFp("vmul", "VmulsQFp", ("float",), 4, vmulfpCode)
-    twoRegLongInst("vmull", "Vmulls", smallTypes, vmullCode)
-
-    twoRegLongInst("vqdmull", "Vqdmulls", smallTypes, vqdmullCode)
-    twoRegLongInst("vqdmlal", "Vqdmlals", smallTypes, vqdmlalCode, True)
-    twoRegLongInst("vqdmlsl", "Vqdmlsls", smallTypes, vqdmlslCode, True)
-    twoEqualRegInst("vqdmulh", "VqdmulhsD", smallSignedTypes, 2, vqdmulhCode)
-    twoEqualRegInst("vqdmulh", "VqdmulhsQ", smallSignedTypes, 4, vqdmulhCode)
+        FpscrExc = fpscr;
+    '''
+    threeEqualRegInstFp("vabd", "VabdDFp", "SimdFloatAddOp", ("float",), 2, vabdfpCode)
+    threeEqualRegInstFp("vabd", "VabdQFp", "SimdFloatAddOp", ("float",), 4, vabdfpCode)
+
+    twoEqualRegInst("vmla", "VmlasD", "SimdMultAccOp", unsignedTypes, 2, vmlaCode, True)
+    twoEqualRegInst("vmla", "VmlasQ", "SimdMultAccOp", unsignedTypes, 4, vmlaCode, True)
+    twoEqualRegInstFp("vmla", "VmlasDFp", "SimdFloatMultAccOp", ("float",), 2, vmlafpCode, True)
+    twoEqualRegInstFp("vmla", "VmlasQFp", "SimdFloatMultAccOp", ("float",), 4, vmlafpCode, True)
+    twoRegLongInst("vmlal", "Vmlals", "SimdMultAccOp", smallTypes, vmlalCode, True)
+
+    twoEqualRegInst("vmls", "VmlssD", "SimdMultAccOp", allTypes, 2, vmlsCode, True)
+    twoEqualRegInst("vmls", "VmlssQ", "SimdMultAccOp", allTypes, 4, vmlsCode, True)
+    twoEqualRegInstFp("vmls", "VmlssDFp", "SimdFloatMultAccOp", ("float",), 2, vmlsfpCode, True)
+    twoEqualRegInstFp("vmls", "VmlssQFp", "SimdFloatMultAccOp", ("float",), 4, vmlsfpCode, True)
+    twoRegLongInst("vmlsl", "Vmlsls", "SimdMultAccOp", smallTypes, vmlslCode, True)
+
+    twoEqualRegInst("vmul", "VmulsD", "SimdMultOp", allTypes, 2, vmulCode)
+    twoEqualRegInst("vmul", "VmulsQ", "SimdMultOp", allTypes, 4, vmulCode)
+    twoEqualRegInstFp("vmul", "VmulsDFp", "SimdFloatMultOp", ("float",), 2, vmulfpCode)
+    twoEqualRegInstFp("vmul", "VmulsQFp", "SimdFloatMultOp", ("float",), 4, vmulfpCode)
+    twoRegLongInst("vmull", "Vmulls", "SimdMultOp", smallTypes, vmullCode)
+
+    twoRegLongInst("vqdmull", "Vqdmulls", "SimdMultOp", smallTypes, vqdmullCode)
+    twoRegLongInst("vqdmlal", "Vqdmlals", "SimdMultAccOp", smallTypes, vqdmlalCode, True)
+    twoRegLongInst("vqdmlsl", "Vqdmlsls", "SimdMultAccOp", smallTypes, vqdmlslCode, True)
+    twoEqualRegInst("vqdmulh", "VqdmulhsD", "SimdMultOp", smallSignedTypes, 2, vqdmulhCode)
+    twoEqualRegInst("vqdmulh", "VqdmulhsQ", "SimdMultOp", smallSignedTypes, 4, vqdmulhCode)
     twoEqualRegInst("vqrdmulh", "VqrdmulhsD",
-            smallSignedTypes, 2, vqrdmulhCode)
+            "SimdMultOp", smallSignedTypes, 2, vqrdmulhCode)
     twoEqualRegInst("vqrdmulh", "VqrdmulhsQ",
-            smallSignedTypes, 4, vqrdmulhCode)
+            "SimdMultOp", smallSignedTypes, 4, vqrdmulhCode)
 
     vshrCode = '''
         if (imm >= sizeof(srcElem1) * 8) {
-            if (srcElem1 < 0)
+            if (ltz(srcElem1))
                 destElem = -1;
             else
                 destElem = 0;
@@ -2362,24 +2887,24 @@ let {{
             destElem = srcElem1 >> imm;
         }
     '''
-    twoRegShiftInst("vshr", "NVshrD", allTypes, 2, vshrCode)
-    twoRegShiftInst("vshr", "NVshrQ", allTypes, 4, vshrCode)
+    twoRegShiftInst("vshr", "NVshrD", "SimdShiftOp", allTypes, 2, vshrCode)
+    twoRegShiftInst("vshr", "NVshrQ", "SimdShiftOp", allTypes, 4, vshrCode)
 
     vsraCode = '''
         Element mid;;
         if (imm >= sizeof(srcElem1) * 8) {
-            mid = (srcElem1 < 0) ? -1 : 0;
+            mid = ltz(srcElem1) ? -1 : 0;
         } else {
             mid = srcElem1 >> imm;
-            if (srcElem1 < 0 && mid >= 0) {
+            if (ltz(srcElem1) && !ltz(mid)) {
                 mid |= -(mid & ((Element)1 <<
                             (sizeof(Element) * 8 - 1 - imm)));
             }
         }
         destElem += mid;
     '''
-    twoRegShiftInst("vsra", "NVsraD", allTypes, 2, vsraCode, True)
-    twoRegShiftInst("vsra", "NVsraQ", allTypes, 4, vsraCode, True)
+    twoRegShiftInst("vsra", "NVsraD", "SimdShiftAccOp", allTypes, 2, vsraCode, True)
+    twoRegShiftInst("vsra", "NVsraQ", "SimdShiftAccOp", allTypes, 4, vsraCode, True)
 
     vrshrCode = '''
         if (imm > sizeof(srcElem1) * 8) {
@@ -2391,8 +2916,8 @@ let {{
             destElem = srcElem1;
         }
     '''
-    twoRegShiftInst("vrshr", "NVrshrD", allTypes, 2, vrshrCode)
-    twoRegShiftInst("vrshr", "NVrshrQ", allTypes, 4, vrshrCode)
+    twoRegShiftInst("vrshr", "NVrshrD", "SimdShiftOp", allTypes, 2, vrshrCode)
+    twoRegShiftInst("vrshr", "NVrshrQ", "SimdShiftOp", allTypes, 4, vrshrCode)
 
     vrsraCode = '''
         if (imm > sizeof(srcElem1) * 8) {
@@ -2404,8 +2929,8 @@ let {{
             destElem += srcElem1;
         }
     '''
-    twoRegShiftInst("vrsra", "NVrsraD", allTypes, 2, vrsraCode, True)
-    twoRegShiftInst("vrsra", "NVrsraQ", allTypes, 4, vrsraCode, True)
+    twoRegShiftInst("vrsra", "NVrsraD", "SimdShiftAccOp", allTypes, 2, vrsraCode, True)
+    twoRegShiftInst("vrsra", "NVrsraQ", "SimdShiftAccOp", allTypes, 4, vrsraCode, True)
 
     vsriCode = '''
         if (imm >= sizeof(Element) * 8)
@@ -2414,8 +2939,8 @@ let {{
             destElem = (srcElem1 >> imm) |
                 (destElem & ~mask(sizeof(Element) * 8 - imm));
     '''
-    twoRegShiftInst("vsri", "NVsriD", unsignedTypes, 2, vsriCode, True)
-    twoRegShiftInst("vsri", "NVsriQ", unsignedTypes, 4, vsriCode, True)
+    twoRegShiftInst("vsri", "NVsriD", "SimdShiftOp", unsignedTypes, 2, vsriCode, True)
+    twoRegShiftInst("vsri", "NVsriQ", "SimdShiftOp", unsignedTypes, 4, vsriCode, True)
 
     vshlCode = '''
         if (imm >= sizeof(Element) * 8)
@@ -2423,8 +2948,8 @@ let {{
         else
             destElem = srcElem1 << imm;
     '''
-    twoRegShiftInst("vshl", "NVshlD", unsignedTypes, 2, vshlCode)
-    twoRegShiftInst("vshl", "NVshlQ", unsignedTypes, 4, vshlCode)
+    twoRegShiftInst("vshl", "NVshlD", "SimdShiftOp", unsignedTypes, 2, vshlCode)
+    twoRegShiftInst("vshl", "NVshlQ", "SimdShiftOp", unsignedTypes, 4, vshlCode)
 
     vsliCode = '''
         if (imm >= sizeof(Element) * 8)
@@ -2432,11 +2957,11 @@ let {{
         else
             destElem = (srcElem1 << imm) | (destElem & mask(imm));
     '''
-    twoRegShiftInst("vsli", "NVsliD", unsignedTypes, 2, vsliCode, True)
-    twoRegShiftInst("vsli", "NVsliQ", unsignedTypes, 4, vsliCode, True)
+    twoRegShiftInst("vsli", "NVsliD", "SimdShiftOp", unsignedTypes, 2, vsliCode, True)
+    twoRegShiftInst("vsli", "NVsliQ", "SimdShiftOp", unsignedTypes, 4, vsliCode, True)
 
     vqshlCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm >= sizeof(Element) * 8) {
             if (srcElem1 != 0) {
                 destElem = (Element)1 << (sizeof(Element) * 8 - 1);
@@ -2460,13 +2985,13 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegShiftInst("vqshl", "NVqshlD", signedTypes, 2, vqshlCode)
-    twoRegShiftInst("vqshl", "NVqshlQ", signedTypes, 4, vqshlCode)
+    twoRegShiftInst("vqshl", "NVqshlD", "SimdShiftOp", signedTypes, 2, vqshlCode)
+    twoRegShiftInst("vqshl", "NVqshlQ", "SimdShiftOp", signedTypes, 4, vqshlCode)
 
     vqshluCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm >= sizeof(Element) * 8) {
             if (srcElem1 != 0) {
                 destElem = mask(sizeof(Element) * 8);
@@ -2486,13 +3011,13 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegShiftInst("vqshlu", "NVqshluD", unsignedTypes, 2, vqshluCode)
-    twoRegShiftInst("vqshlu", "NVqshluQ", unsignedTypes, 4, vqshluCode)
+    twoRegShiftInst("vqshlu", "NVqshluD", "SimdShiftOp", unsignedTypes, 2, vqshluCode)
+    twoRegShiftInst("vqshlu", "NVqshluQ", "SimdShiftOp", unsignedTypes, 4, vqshluCode)
 
     vqshlusCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm >= sizeof(Element) * 8) {
             if (srcElem1 < 0) {
                 destElem = 0;
@@ -2523,10 +3048,10 @@ let {{
                 destElem = srcElem1;
             }
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegShiftInst("vqshlus", "NVqshlusD", signedTypes, 2, vqshlusCode)
-    twoRegShiftInst("vqshlus", "NVqshlusQ", signedTypes, 4, vqshlusCode)
+    twoRegShiftInst("vqshlus", "NVqshlusD", "SimdShiftOp", signedTypes, 2, vqshlusCode)
+    twoRegShiftInst("vqshlus", "NVqshlusQ", "SimdShiftOp", signedTypes, 4, vqshlusCode)
 
     vshrnCode = '''
         if (imm >= sizeof(srcElem1) * 8) {
@@ -2535,7 +3060,7 @@ let {{
             destElem = srcElem1 >> imm;
         }
     '''
-    twoRegNarrowShiftInst("vshrn", "NVshrn", smallUnsignedTypes, vshrnCode)
+    twoRegNarrowShiftInst("vshrn", "NVshrn", "SimdShiftOp", smallUnsignedTypes, vshrnCode)
 
     vrshrnCode = '''
         if (imm > sizeof(srcElem1) * 8) {
@@ -2547,10 +3072,10 @@ let {{
             destElem = srcElem1;
         }
     '''
-    twoRegNarrowShiftInst("vrshrn", "NVrshrn", smallUnsignedTypes, vrshrnCode)
+    twoRegNarrowShiftInst("vrshrn", "NVrshrn", "SimdShiftOp", smallUnsignedTypes, vrshrnCode)
 
     vqshrnCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0 && srcElem1 != -1)
                 fpscr.qc = 1;
@@ -2570,12 +3095,12 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegNarrowShiftInst("vqshrn", "NVqshrn", smallSignedTypes, vqshrnCode)
+    twoRegNarrowShiftInst("vqshrn", "NVqshrn", "SimdShiftOp", smallSignedTypes, vqshrnCode)
 
     vqshrunCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0)
                 fpscr.qc = 1;
@@ -2591,13 +3116,13 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     twoRegNarrowShiftInst("vqshrun", "NVqshrun",
-            smallUnsignedTypes, vqshrunCode)
+                          "SimdShiftOp", smallUnsignedTypes, vqshrunCode)
 
     vqshrunsCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0)
                 fpscr.qc = 1;
@@ -2618,13 +3143,13 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     twoRegNarrowShiftInst("vqshrun", "NVqshruns",
-            smallSignedTypes, vqshrunsCode)
+                          "SimdShiftOp", smallSignedTypes, vqshrunsCode)
 
     vqrshrnCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0 && srcElem1 != -1)
                 fpscr.qc = 1;
@@ -2654,13 +3179,13 @@ let {{
                 destElem = srcElem1;
             }
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     twoRegNarrowShiftInst("vqrshrn", "NVqrshrn",
-            smallSignedTypes, vqrshrnCode)
+                          "SimdShiftOp", smallSignedTypes, vqrshrnCode)
 
     vqrshrunCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0)
                 fpscr.qc = 1;
@@ -2679,20 +3204,18 @@ let {{
         } else {
             if (srcElem1 != (Element)srcElem1) {
                 destElem = mask(sizeof(Element) * 8 - 1);
-                if (srcElem1 < 0)
-                    destElem = ~destElem;
                 fpscr.qc = 1;
             } else {
                 destElem = srcElem1;
             }
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     twoRegNarrowShiftInst("vqrshrun", "NVqrshrun",
-            smallUnsignedTypes, vqrshrunCode)
+                          "SimdShiftOp", smallUnsignedTypes, vqrshrunCode)
 
     vqrshrunsCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm > sizeof(srcElem1) * 8) {
             if (srcElem1 != 0)
                 fpscr.qc = 1;
@@ -2723,10 +3246,10 @@ let {{
                 destElem = srcElem1;
             }
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
     twoRegNarrowShiftInst("vqrshrun", "NVqrshruns",
-            smallSignedTypes, vqrshrunsCode)
+                          "SimdShiftOp", smallSignedTypes, vqrshrunsCode)
 
     vshllCode = '''
         if (imm >= sizeof(destElem) * 8) {
@@ -2735,75 +3258,76 @@ let {{
             destElem = (BigElement)srcElem1 << imm;
         }
     '''
-    twoRegLongShiftInst("vshll", "NVshll", smallTypes, vshllCode)
+    twoRegLongShiftInst("vshll", "NVshll", "SimdShiftOp", smallTypes, vshllCode)
 
     vmovlCode = '''
         destElem = srcElem1;
     '''
-    twoRegLongShiftInst("vmovl", "NVmovl", smallTypes, vmovlCode)
+    twoRegLongShiftInst("vmovl", "NVmovl", "SimdMiscOp", smallTypes, vmovlCode)
 
     vcvt2ufxCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         if (flushToZero(srcElem1))
             fpscr.idc = 1;
         VfpSavedState state = prepFpState(VfpRoundNearest);
         __asm__ __volatile__("" : "=m" (srcElem1) : "m" (srcElem1));
-        destReg = vfpFpSToFixed(srcElem1, false, false, imm);
+        destReg = vfpFpToFixed<float>(srcElem1, false, 32, imm);
         __asm__ __volatile__("" :: "m" (destReg));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegShiftInst("vcvt", "NVcvt2ufxD", ("float",),
+    twoRegShiftInst("vcvt", "NVcvt2ufxD", "SimdCvtOp", ("float",),
             2, vcvt2ufxCode, toInt = True)
-    twoRegShiftInst("vcvt", "NVcvt2ufxQ", ("float",),
+    twoRegShiftInst("vcvt", "NVcvt2ufxQ", "SimdCvtOp", ("float",),
             4, vcvt2ufxCode, toInt = True)
 
     vcvt2sfxCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         if (flushToZero(srcElem1))
             fpscr.idc = 1;
         VfpSavedState state = prepFpState(VfpRoundNearest);
         __asm__ __volatile__("" : "=m" (srcElem1) : "m" (srcElem1));
-        destReg = vfpFpSToFixed(srcElem1, true, false, imm);
+        destReg = vfpFpToFixed<float>(srcElem1, true, 32, imm);
         __asm__ __volatile__("" :: "m" (destReg));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegShiftInst("vcvt", "NVcvt2sfxD", ("float",),
+    twoRegShiftInst("vcvt", "NVcvt2sfxD", "SimdCvtOp", ("float",),
             2, vcvt2sfxCode, toInt = True)
-    twoRegShiftInst("vcvt", "NVcvt2sfxQ", ("float",),
+    twoRegShiftInst("vcvt", "NVcvt2sfxQ", "SimdCvtOp", ("float",),
             4, vcvt2sfxCode, toInt = True)
 
     vcvtu2fpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         VfpSavedState state = prepFpState(VfpRoundNearest);
         __asm__ __volatile__("" : "=m" (srcReg1) : "m" (srcReg1));
-        destElem = vfpUFixedToFpS(true, true, srcReg1, false, imm);
+        destElem = vfpUFixedToFpS(true, true, srcReg1, 32, imm);
         __asm__ __volatile__("" :: "m" (destElem));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegShiftInst("vcvt", "NVcvtu2fpD", ("float",),
+    twoRegShiftInst("vcvt", "NVcvtu2fpD", "SimdCvtOp", ("float",),
             2, vcvtu2fpCode, fromInt = True)
-    twoRegShiftInst("vcvt", "NVcvtu2fpQ", ("float",),
+    twoRegShiftInst("vcvt", "NVcvtu2fpQ", "SimdCvtOp", ("float",),
             4, vcvtu2fpCode, fromInt = True)
 
     vcvts2fpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         VfpSavedState state = prepFpState(VfpRoundNearest);
         __asm__ __volatile__("" : "=m" (srcReg1) : "m" (srcReg1));
-        destElem = vfpSFixedToFpS(true, true, srcReg1, false, imm);
+        destElem = vfpSFixedToFpS(true, true, srcReg1, 32, imm);
         __asm__ __volatile__("" :: "m" (destElem));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegShiftInst("vcvt", "NVcvts2fpD", ("float",),
+    twoRegShiftInst("vcvt", "NVcvts2fpD", "SimdCvtOp", ("float",),
             2, vcvts2fpCode, fromInt = True)
-    twoRegShiftInst("vcvt", "NVcvts2fpQ", ("float",),
+    twoRegShiftInst("vcvt", "NVcvts2fpQ", "SimdCvtOp", ("float",),
             4, vcvts2fpCode, fromInt = True)
 
     vcvts2hCode = '''
-        FPSCR fpscr = Fpscr;
+        destElem = 0;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float srcFp1 = bitsToFp(srcElem1, (float)0.0);
         if (flushToZero(srcFp1))
             fpscr.idc = 1;
@@ -2814,53 +3338,54 @@ let {{
                               fpscr.ahp, srcFp1);
         __asm__ __volatile__("" :: "m" (destElem));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegNarrowMiscInst("vcvt", "NVcvts2h", ("uint16_t",), vcvts2hCode)
+    twoRegNarrowMiscInst("vcvt", "NVcvts2h", "SimdCvtOp", ("uint16_t",), vcvts2hCode)
 
     vcvth2sCode = '''
-        FPSCR fpscr = Fpscr;
+        destElem = 0;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         VfpSavedState state = prepFpState(VfpRoundNearest);
         __asm__ __volatile__("" : "=m" (srcElem1), "=m" (destElem)
                                 : "m" (srcElem1), "m" (destElem));
         destElem = fpToBits(vcvtFpHFpS(fpscr, true, fpscr.ahp, srcElem1));
         __asm__ __volatile__("" :: "m" (destElem));
         finishVfp(fpscr, state, true);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegLongMiscInst("vcvt", "NVcvth2s", ("uint16_t",), vcvth2sCode)
+    twoRegLongMiscInst("vcvt", "NVcvth2s", "SimdCvtOp", ("uint16_t",), vcvth2sCode)
 
     vrsqrteCode = '''
         destElem = unsignedRSqrtEstimate(srcElem1);
     '''
-    twoRegMiscInst("vrsqrte", "NVrsqrteD", ("uint32_t",), 2, vrsqrteCode)
-    twoRegMiscInst("vrsqrte", "NVrsqrteQ", ("uint32_t",), 4, vrsqrteCode)
+    twoRegMiscInst("vrsqrte", "NVrsqrteD", "SimdSqrtOp", ("uint32_t",), 2, vrsqrteCode)
+    twoRegMiscInst("vrsqrte", "NVrsqrteQ", "SimdSqrtOp", ("uint32_t",), 4, vrsqrteCode)
 
     vrsqrtefpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         if (flushToZero(srcReg1))
             fpscr.idc = 1;
         destReg = fprSqrtEstimate(fpscr, srcReg1);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vrsqrte", "NVrsqrteDFp", ("float",), 2, vrsqrtefpCode)
-    twoRegMiscInstFp("vrsqrte", "NVrsqrteQFp", ("float",), 4, vrsqrtefpCode)
+    twoRegMiscInstFp("vrsqrte", "NVrsqrteDFp", "SimdFloatSqrtOp", ("float",), 2, vrsqrtefpCode)
+    twoRegMiscInstFp("vrsqrte", "NVrsqrteQFp", "SimdFloatSqrtOp", ("float",), 4, vrsqrtefpCode)
 
     vrecpeCode = '''
         destElem = unsignedRecipEstimate(srcElem1);
     '''
-    twoRegMiscInst("vrecpe", "NVrecpeD", ("uint32_t",), 2, vrecpeCode)
-    twoRegMiscInst("vrecpe", "NVrecpeQ", ("uint32_t",), 4, vrecpeCode)
+    twoRegMiscInst("vrecpe", "NVrecpeD", "SimdMultAccOp", ("uint32_t",), 2, vrecpeCode)
+    twoRegMiscInst("vrecpe", "NVrecpeQ", "SimdMultAccOp", ("uint32_t",), 4, vrecpeCode)
 
     vrecpefpCode = '''
-        FPSCR fpscr = Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         if (flushToZero(srcReg1))
             fpscr.idc = 1;
         destReg = fpRecipEstimate(fpscr, srcReg1);
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vrecpe", "NVrecpeDFp", ("float",), 2, vrecpefpCode)
-    twoRegMiscInstFp("vrecpe", "NVrecpeQFp", ("float",), 4, vrecpefpCode)
+    twoRegMiscInstFp("vrecpe", "NVrecpeDFp", "SimdFloatMultAccOp", ("float",), 2, vrecpefpCode)
+    twoRegMiscInstFp("vrecpe", "NVrecpeQFp", "SimdFloatMultAccOp", ("float",), 4, vrecpefpCode)
 
     vrev16Code = '''
         destElem = srcElem1;
@@ -2868,8 +3393,8 @@ let {{
         unsigned reverseMask = (groupSize - 1);
         j = i ^ reverseMask;
     '''
-    twoRegMiscInst("vrev16", "NVrev16D", ("uint8_t",), 2, vrev16Code)
-    twoRegMiscInst("vrev16", "NVrev16Q", ("uint8_t",), 4, vrev16Code)
+    twoRegMiscInst("vrev16", "NVrev16D", "SimdAluOp", ("uint8_t",), 2, vrev16Code)
+    twoRegMiscInst("vrev16", "NVrev16Q", "SimdAluOp", ("uint8_t",), 4, vrev16Code)
     vrev32Code = '''
         destElem = srcElem1;
         unsigned groupSize = ((1 << 2) / sizeof(Element));
@@ -2877,29 +3402,29 @@ let {{
         j = i ^ reverseMask;
     '''
     twoRegMiscInst("vrev32", "NVrev32D",
-            ("uint8_t", "uint16_t"), 2, vrev32Code)
+            "SimdAluOp", ("uint8_t", "uint16_t"), 2, vrev32Code)
     twoRegMiscInst("vrev32", "NVrev32Q",
-            ("uint8_t", "uint16_t"), 4, vrev32Code)
+            "SimdAluOp", ("uint8_t", "uint16_t"), 4, vrev32Code)
     vrev64Code = '''
         destElem = srcElem1;
         unsigned groupSize = ((1 << 3) / sizeof(Element));
         unsigned reverseMask = (groupSize - 1);
         j = i ^ reverseMask;
     '''
-    twoRegMiscInst("vrev64", "NVrev64D", smallUnsignedTypes, 2, vrev64Code)
-    twoRegMiscInst("vrev64", "NVrev64Q", smallUnsignedTypes, 4, vrev64Code)
+    twoRegMiscInst("vrev64", "NVrev64D", "SimdAluOp", smallUnsignedTypes, 2, vrev64Code)
+    twoRegMiscInst("vrev64", "NVrev64Q", "SimdAluOp", smallUnsignedTypes, 4, vrev64Code)
 
     vpaddlCode = '''
         destElem = (BigElement)srcElem1 + (BigElement)srcElem2;
     '''
-    twoRegCondenseInst("vpaddl", "NVpaddlD", smallTypes, 2, vpaddlCode)
-    twoRegCondenseInst("vpaddl", "NVpaddlQ", smallTypes, 4, vpaddlCode)
+    twoRegCondenseInst("vpaddl", "NVpaddlD", "SimdAddOp", smallTypes, 2, vpaddlCode)
+    twoRegCondenseInst("vpaddl", "NVpaddlQ", "SimdAddOp", smallTypes, 4, vpaddlCode)
 
     vpadalCode = '''
         destElem += (BigElement)srcElem1 + (BigElement)srcElem2;
     '''
-    twoRegCondenseInst("vpadal", "NVpadalD", smallTypes, 2, vpadalCode, True)
-    twoRegCondenseInst("vpadal", "NVpadalQ", smallTypes, 4, vpadalCode, True)
+    twoRegCondenseInst("vpadal", "NVpadalD", "SimdAddAccOp", smallTypes, 2, vpadalCode, True)
+    twoRegCondenseInst("vpadal", "NVpadalQ", "SimdAddAccOp", smallTypes, 4, vpadalCode, True)
 
     vclsCode = '''
         unsigned count = 0;
@@ -2918,8 +3443,8 @@ let {{
         }
         destElem = count;
     '''
-    twoRegMiscInst("vcls", "NVclsD", signedTypes, 2, vclsCode)
-    twoRegMiscInst("vcls", "NVclsQ", signedTypes, 4, vclsCode)
+    twoRegMiscInst("vcls", "NVclsD", "SimdAluOp", signedTypes, 2, vclsCode)
+    twoRegMiscInst("vcls", "NVclsQ", "SimdAluOp", signedTypes, 4, vclsCode)
 
     vclzCode = '''
         unsigned count = 0;
@@ -2929,8 +3454,8 @@ let {{
         }
         destElem = count;
     '''
-    twoRegMiscInst("vclz", "NVclzD", signedTypes, 2, vclzCode)
-    twoRegMiscInst("vclz", "NVclzQ", signedTypes, 4, vclzCode)
+    twoRegMiscInst("vclz", "NVclzD", "SimdAluOp", signedTypes, 2, vclzCode)
+    twoRegMiscInst("vclz", "NVclzQ", "SimdAluOp", signedTypes, 4, vclzCode)
 
     vcntCode = '''
         unsigned count = 0;
@@ -2940,17 +3465,18 @@ let {{
         }
         destElem = count;
     '''
-    twoRegMiscInst("vcnt", "NVcntD", unsignedTypes, 2, vcntCode)
-    twoRegMiscInst("vcnt", "NVcntQ", unsignedTypes, 4, vcntCode)
+
+    twoRegMiscInst("vcnt", "NVcntD", "SimdAluOp", unsignedTypes, 2, vcntCode)
+    twoRegMiscInst("vcnt", "NVcntQ", "SimdAluOp", unsignedTypes, 4, vcntCode)
 
     vmvnCode = '''
         destElem = ~srcElem1;
     '''
-    twoRegMiscInst("vmvn", "NVmvnD", ("uint64_t",), 2, vmvnCode)
-    twoRegMiscInst("vmvn", "NVmvnQ", ("uint64_t",), 4, vmvnCode)
+    twoRegMiscInst("vmvn", "NVmvnD", "SimdAluOp", ("uint64_t",), 2, vmvnCode)
+    twoRegMiscInst("vmvn", "NVmvnQ", "SimdAluOp", ("uint64_t",), 4, vmvnCode)
 
     vqabsCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
@@ -2959,23 +3485,23 @@ let {{
         } else {
             destElem = srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegMiscInst("vqabs", "NVqabsD", signedTypes, 2, vqabsCode)
-    twoRegMiscInst("vqabs", "NVqabsQ", signedTypes, 4, vqabsCode)
+    twoRegMiscInst("vqabs", "NVqabsD", "SimdAluOp", signedTypes, 2, vqabsCode)
+    twoRegMiscInst("vqabs", "NVqabsQ", "SimdAluOp", signedTypes, 4, vqabsCode)
 
     vqnegCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrQc;
         if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
         } else {
             destElem = -srcElem1;
         }
-        Fpscr = fpscr;
+        FpscrQc = fpscr;
     '''
-    twoRegMiscInst("vqneg", "NVqnegD", signedTypes, 2, vqnegCode)
-    twoRegMiscInst("vqneg", "NVqnegQ", signedTypes, 4, vqnegCode)
+    twoRegMiscInst("vqneg", "NVqnegD", "SimdAluOp", signedTypes, 2, vqnegCode)
+    twoRegMiscInst("vqneg", "NVqnegQ", "SimdAluOp", signedTypes, 4, vqnegCode)
 
     vabsCode = '''
         if (srcElem1 < 0) {
@@ -2984,8 +3510,9 @@ let {{
             destElem = srcElem1;
         }
     '''
-    twoRegMiscInst("vabs", "NVabsD", signedTypes, 2, vabsCode)
-    twoRegMiscInst("vabs", "NVabsQ", signedTypes, 4, vabsCode)
+
+    twoRegMiscInst("vabs", "NVabsD", "SimdAluOp", signedTypes, 2, vabsCode)
+    twoRegMiscInst("vabs", "NVabsQ", "SimdAluOp", signedTypes, 4, vabsCode)
     vabsfpCode = '''
         union
         {
@@ -2996,103 +3523,103 @@ let {{
         cStruct.i &= mask(sizeof(Element) * 8 - 1);
         destReg = cStruct.f;
     '''
-    twoRegMiscInstFp("vabs", "NVabsDFp", ("float",), 2, vabsfpCode)
-    twoRegMiscInstFp("vabs", "NVabsQFp", ("float",), 4, vabsfpCode)
+    twoRegMiscInstFp("vabs", "NVabsDFp", "SimdFloatAluOp", ("float",), 2, vabsfpCode)
+    twoRegMiscInstFp("vabs", "NVabsQFp", "SimdFloatAluOp", ("float",), 4, vabsfpCode)
 
     vnegCode = '''
         destElem = -srcElem1;
     '''
-    twoRegMiscInst("vneg", "NVnegD", signedTypes, 2, vnegCode)
-    twoRegMiscInst("vneg", "NVnegQ", signedTypes, 4, vnegCode)
+    twoRegMiscInst("vneg", "NVnegD", "SimdAluOp", signedTypes, 2, vnegCode)
+    twoRegMiscInst("vneg", "NVnegQ", "SimdAluOp", signedTypes, 4, vnegCode)
     vnegfpCode = '''
         destReg = -srcReg1;
     '''
-    twoRegMiscInstFp("vneg", "NVnegDFp", ("float",), 2, vnegfpCode)
-    twoRegMiscInstFp("vneg", "NVnegQFp", ("float",), 4, vnegfpCode)
+    twoRegMiscInstFp("vneg", "NVnegDFp", "SimdFloatAluOp", ("float",), 2, vnegfpCode)
+    twoRegMiscInstFp("vneg", "NVnegQFp", "SimdFloatAluOp", ("float",), 4, vnegfpCode)
 
     vcgtCode = 'destElem = (srcElem1 > 0) ? mask(sizeof(Element) * 8) : 0;'
-    twoRegMiscInst("vcgt", "NVcgtD", signedTypes, 2, vcgtCode)
-    twoRegMiscInst("vcgt", "NVcgtQ", signedTypes, 4, vcgtCode)
+    twoRegMiscInst("vcgt", "NVcgtD", "SimdCmpOp", signedTypes, 2, vcgtCode)
+    twoRegMiscInst("vcgt", "NVcgtQ", "SimdCmpOp", signedTypes, 4, vcgtCode)
     vcgtfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, (FloatReg)0.0, vcgtFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vcgt", "NVcgtDFp", ("float",),
+    twoRegMiscInstFp("vcgt", "NVcgtDFp", "SimdFloatCmpOp", ("float",),
             2, vcgtfpCode, toInt = True)
-    twoRegMiscInstFp("vcgt", "NVcgtQFp", ("float",),
+    twoRegMiscInstFp("vcgt", "NVcgtQFp", "SimdFloatCmpOp", ("float",),
             4, vcgtfpCode, toInt = True)
 
     vcgeCode = 'destElem = (srcElem1 >= 0) ? mask(sizeof(Element) * 8) : 0;'
-    twoRegMiscInst("vcge", "NVcgeD", signedTypes, 2, vcgeCode)
-    twoRegMiscInst("vcge", "NVcgeQ", signedTypes, 4, vcgeCode)
+    twoRegMiscInst("vcge", "NVcgeD", "SimdCmpOp", signedTypes, 2, vcgeCode)
+    twoRegMiscInst("vcge", "NVcgeQ", "SimdCmpOp", signedTypes, 4, vcgeCode)
     vcgefpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, (FloatReg)0.0, vcgeFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vcge", "NVcgeDFp", ("float",),
+    twoRegMiscInstFp("vcge", "NVcgeDFp", "SimdFloatCmpOp", ("float",),
             2, vcgefpCode, toInt = True)
-    twoRegMiscInstFp("vcge", "NVcgeQFp", ("float",),
+    twoRegMiscInstFp("vcge", "NVcgeQFp", "SimdFloatCmpOp", ("float",),
             4, vcgefpCode, toInt = True)
 
     vceqCode = 'destElem = (srcElem1 == 0) ? mask(sizeof(Element) * 8) : 0;'
-    twoRegMiscInst("vceq", "NVceqD", signedTypes, 2, vceqCode)
-    twoRegMiscInst("vceq", "NVceqQ", signedTypes, 4, vceqCode)
+    twoRegMiscInst("vceq", "NVceqD", "SimdCmpOp", signedTypes, 2, vceqCode)
+    twoRegMiscInst("vceq", "NVceqQ", "SimdCmpOp", signedTypes, 4, vceqCode)
     vceqfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, (FloatReg)0.0, vceqFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vceq", "NVceqDFp", ("float",),
+    twoRegMiscInstFp("vceq", "NVceqDFp", "SimdFloatCmpOp", ("float",),
             2, vceqfpCode, toInt = True)
-    twoRegMiscInstFp("vceq", "NVceqQFp", ("float",),
+    twoRegMiscInstFp("vceq", "NVceqQFp", "SimdFloatCmpOp", ("float",),
             4, vceqfpCode, toInt = True)
 
     vcleCode = 'destElem = (srcElem1 <= 0) ? mask(sizeof(Element) * 8) : 0;'
-    twoRegMiscInst("vcle", "NVcleD", signedTypes, 2, vcleCode)
-    twoRegMiscInst("vcle", "NVcleQ", signedTypes, 4, vcleCode)
+    twoRegMiscInst("vcle", "NVcleD", "SimdCmpOp", signedTypes, 2, vcleCode)
+    twoRegMiscInst("vcle", "NVcleQ", "SimdCmpOp", signedTypes, 4, vcleCode)
     vclefpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, (FloatReg)0.0, vcleFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vcle", "NVcleDFp", ("float",),
+    twoRegMiscInstFp("vcle", "NVcleDFp", "SimdFloatCmpOp", ("float",),
             2, vclefpCode, toInt = True)
-    twoRegMiscInstFp("vcle", "NVcleQFp", ("float",),
+    twoRegMiscInstFp("vcle", "NVcleQFp", "SimdFloatCmpOp", ("float",),
             4, vclefpCode, toInt = True)
 
     vcltCode = 'destElem = (srcElem1 < 0) ? mask(sizeof(Element) * 8) : 0;'
-    twoRegMiscInst("vclt", "NVcltD", signedTypes, 2, vcltCode)
-    twoRegMiscInst("vclt", "NVcltQ", signedTypes, 4, vcltCode)
+    twoRegMiscInst("vclt", "NVcltD", "SimdCmpOp", signedTypes, 2, vcltCode)
+    twoRegMiscInst("vclt", "NVcltQ", "SimdCmpOp", signedTypes, 4, vcltCode)
     vcltfpCode = '''
-        FPSCR fpscr = (FPSCR)Fpscr;
+        FPSCR fpscr = (FPSCR) FpscrExc;
         float res = binaryOp(fpscr, srcReg1, (FloatReg)0.0, vcltFunc,
                              true, true, VfpRoundNearest);
         destReg = (res == 0) ? -1 : 0;
         if (res == 2.0)
             fpscr.ioc = 1;
-        Fpscr = fpscr;
+        FpscrExc = fpscr;
     '''
-    twoRegMiscInstFp("vclt", "NVcltDFp", ("float",),
+    twoRegMiscInstFp("vclt", "NVcltDFp", "SimdFloatCmpOp", ("float",),
             2, vcltfpCode, toInt = True)
-    twoRegMiscInstFp("vclt", "NVcltQFp", ("float",),
+    twoRegMiscInstFp("vclt", "NVcltQFp", "SimdFloatCmpOp", ("float",),
             4, vcltfpCode, toInt = True)
 
     vswpCode = '''
@@ -3103,8 +3630,8 @@ let {{
             destReg.regs[r] = mid;
         }
     '''
-    twoRegMiscScramble("vswp", "NVswpD", ("uint64_t",), 2, vswpCode)
-    twoRegMiscScramble("vswp", "NVswpQ", ("uint64_t",), 4, vswpCode)
+    twoRegMiscScramble("vswp", "NVswpD", "SimdAluOp", ("uint64_t",), 2, vswpCode)
+    twoRegMiscScramble("vswp", "NVswpQ", "SimdAluOp", ("uint64_t",), 4, vswpCode)
 
     vtrnCode = '''
         Element mid;
@@ -3114,8 +3641,10 @@ let {{
             destReg.elements[i + 1] = mid;
         }
     '''
-    twoRegMiscScramble("vtrn", "NVtrnD", unsignedTypes, 2, vtrnCode)
-    twoRegMiscScramble("vtrn", "NVtrnQ", unsignedTypes, 4, vtrnCode)
+    twoRegMiscScramble("vtrn", "NVtrnD", "SimdAluOp",
+            smallUnsignedTypes, 2, vtrnCode)
+    twoRegMiscScramble("vtrn", "NVtrnQ", "SimdAluOp",
+            smallUnsignedTypes, 4, vtrnCode)
 
     vuzpCode = '''
         Element mid[eCount];
@@ -3129,8 +3658,8 @@ let {{
             destReg.elements[eCount / 2 + i] = mid[2 * i];
         }
     '''
-    twoRegMiscScramble("vuzp", "NVuzpD", unsignedTypes, 2, vuzpCode)
-    twoRegMiscScramble("vuzp", "NVuzpQ", unsignedTypes, 4, vuzpCode)
+    twoRegMiscScramble("vuzp", "NVuzpD", "SimdAluOp", unsignedTypes, 2, vuzpCode)
+    twoRegMiscScramble("vuzp", "NVuzpQ", "SimdAluOp", unsignedTypes, 4, vuzpCode)
 
     vzipCode = '''
         Element mid[eCount];
@@ -3144,17 +3673,17 @@ let {{
             srcReg1.elements[2 * i + 1] = srcReg1.elements[eCount / 2 + i];
         }
     '''
-    twoRegMiscScramble("vzip", "NVzipD", unsignedTypes, 2, vzipCode)
-    twoRegMiscScramble("vzip", "NVzipQ", unsignedTypes, 4, vzipCode)
+    twoRegMiscScramble("vzip", "NVzipD", "SimdAluOp", unsignedTypes, 2, vzipCode)
+    twoRegMiscScramble("vzip", "NVzipQ", "SimdAluOp", unsignedTypes, 4, vzipCode)
 
     vmovnCode = 'destElem = srcElem1;'
-    twoRegNarrowMiscInst("vmovn", "NVmovn", smallUnsignedTypes, vmovnCode)
+    twoRegNarrowMiscInst("vmovn", "NVmovn", "SimdMiscOp", smallUnsignedTypes, vmovnCode)
 
     vdupCode = 'destElem = srcElem1;'
-    twoRegMiscScInst("vdup", "NVdupD", smallUnsignedTypes, 2, vdupCode)
-    twoRegMiscScInst("vdup", "NVdupQ", smallUnsignedTypes, 4, vdupCode)
+    twoRegMiscScInst("vdup", "NVdupD", "SimdAluOp", smallUnsignedTypes, 2, vdupCode)
+    twoRegMiscScInst("vdup", "NVdupQ", "SimdAluOp", smallUnsignedTypes, 4, vdupCode)
 
-    def vdupGprInst(name, Name, types, rCount):
+    def vdupGprInst(name, Name, opClass, types, rCount):
         global header_output, exec_output
         eWalkCode = '''
         RegVect destReg;
@@ -3164,40 +3693,41 @@ let {{
         '''
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
             substDict = { "targs" : type,
                           "class_name" : Name }
             exec_output += NeonExecDeclare.subst(substDict)
-    vdupGprInst("vdup", "NVdupDGpr", smallUnsignedTypes, 2)
-    vdupGprInst("vdup", "NVdupQGpr", smallUnsignedTypes, 4)
+    vdupGprInst("vdup", "NVdupDGpr", "SimdMiscOp", smallUnsignedTypes, 2)
+    vdupGprInst("vdup", "NVdupQGpr", "SimdMiscOp", smallUnsignedTypes, 4)
 
     vmovCode = 'destElem = imm;'
-    oneRegImmInst("vmov", "NVmoviD", ("uint64_t",), 2, vmovCode)
-    oneRegImmInst("vmov", "NVmoviQ", ("uint64_t",), 4, vmovCode)
+    oneRegImmInst("vmov", "NVmoviD", "SimdMiscOp", ("uint64_t",), 2, vmovCode)
+    oneRegImmInst("vmov", "NVmoviQ", "SimdMiscOp", ("uint64_t",), 4, vmovCode)
 
     vorrCode = 'destElem |= imm;'
-    oneRegImmInst("vorr", "NVorriD", ("uint64_t",), 2, vorrCode, True)
-    oneRegImmInst("vorr", "NVorriQ", ("uint64_t",), 4, vorrCode, True)
+    oneRegImmInst("vorr", "NVorriD", "SimdAluOp", ("uint64_t",), 2, vorrCode, True)
+    oneRegImmInst("vorr", "NVorriQ", "SimdAluOp", ("uint64_t",), 4, vorrCode, True)
 
     vmvnCode = 'destElem = ~imm;'
-    oneRegImmInst("vmvn", "NVmvniD", ("uint64_t",), 2, vmvnCode)
-    oneRegImmInst("vmvn", "NVmvniQ", ("uint64_t",), 4, vmvnCode)
+    oneRegImmInst("vmvn", "NVmvniD", "SimdAluOp", ("uint64_t",), 2, vmvnCode)
+    oneRegImmInst("vmvn", "NVmvniQ", "SimdAluOp", ("uint64_t",), 4, vmvnCode)
 
     vbicCode = 'destElem &= ~imm;'
-    oneRegImmInst("vbic", "NVbiciD", ("uint64_t",), 2, vbicCode, True)
-    oneRegImmInst("vbic", "NVbiciQ", ("uint64_t",), 4, vbicCode, True)
+    oneRegImmInst("vbic", "NVbiciD", "SimdAluOp", ("uint64_t",), 2, vbicCode, True)
+    oneRegImmInst("vbic", "NVbiciQ", "SimdAluOp", ("uint64_t",), 4, vbicCode, True)
 
     vqmovnCode = '''
-    FPSCR fpscr = (FPSCR)Fpscr;
+    FPSCR fpscr = (FPSCR) FpscrQc;
     destElem = srcElem1;
     if ((BigElement)destElem != srcElem1) {
         fpscr.qc = 1;
@@ -3205,24 +3735,24 @@ let {{
         if (srcElem1 < 0)
             destElem = ~destElem;
     }
-    Fpscr = fpscr;
+    FpscrQc = fpscr;
     '''
-    twoRegNarrowMiscInst("vqmovn", "NVqmovn", smallSignedTypes, vqmovnCode)
+    twoRegNarrowMiscInst("vqmovn", "NVqmovn", "SimdMiscOp", smallSignedTypes, vqmovnCode)
 
     vqmovunCode = '''
-    FPSCR fpscr = (FPSCR)Fpscr;
+    FPSCR fpscr = (FPSCR) FpscrQc;
     destElem = srcElem1;
     if ((BigElement)destElem != srcElem1) {
         fpscr.qc = 1;
         destElem = mask(sizeof(Element) * 8);
     }
-    Fpscr = fpscr;
+    FpscrQc = fpscr;
     '''
     twoRegNarrowMiscInst("vqmovun", "NVqmovun",
-            smallUnsignedTypes, vqmovunCode)
+            "SimdMiscOp", smallUnsignedTypes, vqmovunCode)
 
     vqmovunsCode = '''
-    FPSCR fpscr = (FPSCR)Fpscr;
+    FPSCR fpscr = (FPSCR) FpscrQc;
     destElem = srcElem1;
     if (srcElem1 < 0 ||
             ((BigElement)destElem & mask(sizeof(Element) * 8)) != srcElem1) {
@@ -3231,31 +3761,32 @@ let {{
         if (srcElem1 < 0)
             destElem = ~destElem;
     }
-    Fpscr = fpscr;
+    FpscrQc = fpscr;
     '''
     twoRegNarrowMiscInst("vqmovun", "NVqmovuns",
-            smallSignedTypes, vqmovunsCode)
+            "SimdMiscOp", smallSignedTypes, vqmovunsCode)
 
-    def buildVext(name, Name, types, rCount, op):
+    def buildVext(name, Name, opClass, types, rCount, op):
         global header_output, exec_output
         eWalkCode = '''
         RegVect srcReg1, srcReg2, destReg;
         '''
         for reg in range(rCount):
-            eWalkCode += '''
-                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
-                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
+            eWalkCode += simdEnabledCheckCode + '''
+                srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);
+                srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw);
             ''' % { "reg" : reg }
         eWalkCode += op
         for reg in range(rCount):
             eWalkCode += '''
-            FpDestP%(reg)d.uw = gtoh(destReg.regs[%(reg)d]);
+            FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
             ''' % { "reg" : reg }
         iop = InstObjParams(name, Name,
                             "RegRegRegImmOp",
                             { "code": eWalkCode,
                               "r_count": rCount,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += NeonRegRegRegImmOpDeclare.subst(iop)
         exec_output += NeonEqualRegExecute.subst(iop)
         for type in types:
@@ -3270,15 +3801,18 @@ let {{
                 destReg.elements[i] = srcReg1.elements[index];
             } else {
                 index -= eCount;
-                assert(index < eCount);
-                destReg.elements[i] = srcReg2.elements[index];
+                if (index >= eCount) {
+                    fault = new UndefinedInstruction(machInst, false, mnemonic);
+                } else {
+                    destReg.elements[i] = srcReg2.elements[index];
+                }
             }
         }
     '''
-    buildVext("vext", "NVextD", ("uint8_t",), 2, vextCode)
-    buildVext("vext", "NVextQ", ("uint8_t",), 4, vextCode)
+    buildVext("vext", "NVextD", "SimdMiscOp", ("uint8_t",), 2, vextCode)
+    buildVext("vext", "NVextQ", "SimdMiscOp", ("uint8_t",), 4, vextCode)
 
-    def buildVtbxl(name, Name, length, isVtbl):
+    def buildVtbxl(name, Name, opClass, length, isVtbl):
         global header_output, decoder_output, exec_output
         code = '''
             union
@@ -3296,15 +3830,15 @@ let {{
             const unsigned length = %(length)d;
             const bool isVtbl = %(isVtbl)s;
 
-            srcReg2.regs[0] = htog(FpOp2P0.uw);
-            srcReg2.regs[1] = htog(FpOp2P1.uw);
+            srcReg2.regs[0] = htog(FpOp2P0_uw);
+            srcReg2.regs[1] = htog(FpOp2P1_uw);
 
-            destReg.regs[0] = htog(FpDestP0.uw);
-            destReg.regs[1] = htog(FpDestP1.uw);
+            destReg.regs[0] = htog(FpDestP0_uw);
+            destReg.regs[1] = htog(FpDestP1_uw);
         ''' % { "length" : length, "isVtbl" : isVtbl }
         for reg in range(8):
             if reg < length * 2:
-                code += 'table.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);\n' % \
+                code += 'table.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw);\n' % \
                         { "reg" : reg }
             else:
                 code += 'table.regs[%(reg)d] = 0;\n' % { "reg" : reg }
@@ -3320,24 +3854,25 @@ let {{
             }
         }
 
-        FpDestP0.uw = gtoh(destReg.regs[0]);
-        FpDestP1.uw = gtoh(destReg.regs[1]);
+        FpDestP0_uw = gtoh(destReg.regs[0]);
+        FpDestP1_uw = gtoh(destReg.regs[1]);
         '''
         iop = InstObjParams(name, Name,
                             "RegRegRegOp",
                             { "code": code,
-                              "predicate_test": predicateTest }, [])
+                              "predicate_test": predicateTest,
+                              "op_class": opClass }, [])
         header_output += RegRegRegOpDeclare.subst(iop)
         decoder_output += RegRegRegOpConstructor.subst(iop)
         exec_output += PredOpExecute.subst(iop)
 
-    buildVtbxl("vtbl", "NVtbl1", 1, "true")
-    buildVtbxl("vtbl", "NVtbl2", 2, "true")
-    buildVtbxl("vtbl", "NVtbl3", 3, "true")
-    buildVtbxl("vtbl", "NVtbl4", 4, "true")
+    buildVtbxl("vtbl", "NVtbl1", "SimdMiscOp", 1, "true")
+    buildVtbxl("vtbl", "NVtbl2", "SimdMiscOp", 2, "true")
+    buildVtbxl("vtbl", "NVtbl3", "SimdMiscOp", 3, "true")
+    buildVtbxl("vtbl", "NVtbl4", "SimdMiscOp", 4, "true")
 
-    buildVtbxl("vtbx", "NVtbx1", 1, "false")
-    buildVtbxl("vtbx", "NVtbx2", 2, "false")
-    buildVtbxl("vtbx", "NVtbx3", 3, "false")
-    buildVtbxl("vtbx", "NVtbx4", 4, "false")
+    buildVtbxl("vtbx", "NVtbx1", "SimdMiscOp", 1, "false")
+    buildVtbxl("vtbx", "NVtbx2", "SimdMiscOp", 2, "false")
+    buildVtbxl("vtbx", "NVtbx3", "SimdMiscOp", 3, "false")
+    buildVtbxl("vtbx", "NVtbx4", "SimdMiscOp", 4, "false")
 }};