ARM: Decode the neon instruction space.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:18 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:18 +0000 (12:58 -0500)
src/arch/arm/isa/decoder/thumb.isa
src/arch/arm/isa/formats/fp.isa
src/arch/arm/isa/formats/uncond.isa

index 3799bdf1fe5d5acc02607fd26ffe5f0a80315441..65ea7e30cfbe4ae2ab5309bc58145e7761f16cd1 100644 (file)
@@ -119,7 +119,7 @@ decode BIGTHUMB {
             0x0: decode HTOPCODE_4 {
                 0x0: decode HTOPCODE_8 {
                     0x0: Thumb32StoreSingle::thumb32StoreSingle();
-                    0x1: WarnUnimpl::Advanced_SIMD_or_structure_load_store();
+                    0x1: ThumbNeonMem::thumbNeonMem();
                 }
                 0x1: decode HTOPCODE_6_5 {
                     0x0: LoadByteMemoryHints::loadByteMemoryHints();
@@ -144,7 +144,7 @@ decode BIGTHUMB {
                         0xf: McrMrc15::mcrMrc15();
                     }
                 }
-                0x3: WarnUnimpl::Advanced_SIMD();
+                0x3: ThumbNeonData::thumbNeonData();
                 default: decode LTCOPROC {
                     0xa, 0xb: ExtensionRegLoadStore::extensionRegLoadStre();
                     0xf: decode HTOPCODE_9_4 {
index 1bb15fd5ba79cc5a1d98811ee7f69c5d7f0e8e3f..22207d4e7ae698bba36991d6ec2650244965fad0 100644 (file)
 // Floating Point operate instructions
 //
 
+let {{
+    header_output = '''
+    StaticInstPtr
+    decodeNeonMem(ExtMachInst machInst);
+
+    StaticInstPtr
+    decodeNeonData(ExtMachInst machInst);
+    '''
+
+    decoder_output = '''
+    StaticInstPtr
+    decodeNeonMem(ExtMachInst machInst)
+    {
+        const uint32_t b = bits(machInst, 11, 8);
+        const bool a = bits(machInst, 23);
+        const bool l = bits(machInst, 21);
+
+        if (l) {
+            // Load instructions.
+            if (a) {
+                switch (b) {
+                }
+                // Single.
+            } else {
+                switch (b) {
+                }
+                // Multiple.
+            }
+        } else {
+            // Store instructions.
+            if (a) {
+                switch (b) {
+                }
+                // Single.
+            } else {
+                switch (b) {
+                }
+                // Multiple.
+            }
+        }
+        return new WarnUnimplemented("neon memory", machInst);
+    }
+    '''
+
+    decoder_output += '''
+    static StaticInstPtr
+    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
+    {
+        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
+        const uint32_t a = bits(machInst, 11, 8);
+        const bool b = bits(machInst, 4);
+        const uint32_t c = bits(machInst, 21, 20);
+        switch (a) {
+          case 0x0:
+            if (b) {
+                if (bits(machInst, 9) == 0) {
+                    return new WarnUnimplemented("vhadd", machInst);
+                } else {
+                    return new WarnUnimplemented("vhsub", machInst);
+                }
+            } else {
+                return new WarnUnimplemented("vqadd", machInst);
+            }
+          case 0x1:
+            if (!b) {
+                return new WarnUnimplemented("vrhadd", machInst);
+            } else {
+                if (u) {
+                    switch (c) {
+                      case 0:
+                        return new WarnUnimplemented("veor", machInst);
+                      case 1:
+                        return new WarnUnimplemented("vbsl", machInst);
+                      case 2:
+                        return new WarnUnimplemented("vbit", machInst);
+                      case 3:
+                        return new WarnUnimplemented("vbif", machInst);
+                    }
+                } else {
+                    switch (c) {
+                      case 0:
+                        return new WarnUnimplemented("vand (reg)", machInst);
+                      case 1:
+                        return new WarnUnimplemented("vbic (reg)", machInst);
+                      case 2:
+                        {
+                            const IntRegIndex n = (IntRegIndex)(
+                                    (uint32_t)bits(machInst, 19, 16) |
+                                    (uint32_t)(bits(machInst, 7) << 4));
+                            const IntRegIndex m = (IntRegIndex)(
+                                    (uint32_t)bits(machInst, 3, 0) |
+                                    (uint32_t)(bits(machInst, 5) << 4));
+                            if (n == m) {
+                                return new WarnUnimplemented("vmov (reg)",
+                                        machInst);
+                            } else {
+                                return new WarnUnimplemented("vorr (reg)",
+                                        machInst);
+                            }
+                        }
+                      case 3:
+                        return new WarnUnimplemented("vorn (reg)", machInst);
+                    }
+                }
+            }
+          case 0x2:
+            if (b) {
+                return new WarnUnimplemented("vqsub", machInst);
+            } else {
+                if (bits(machInst, 9) == 0) {
+                    return new WarnUnimplemented("vhadd", machInst);
+                } else {
+                    return new WarnUnimplemented("vhsub", machInst);
+                }
+            }
+          case 0x3:
+            if (b) {
+                return new WarnUnimplemented("vcge (reg)", machInst);
+            } else {
+                return new WarnUnimplemented("vcgt (reg)", machInst);
+            }
+          case 0x4:
+            if (b) {
+                return new WarnUnimplemented("vqshl (reg)", machInst);
+            } else {
+                return new WarnUnimplemented("vshl (reg)", machInst);
+            }
+          case 0x5:
+            if (b) {
+                return new WarnUnimplemented("vqrshl", machInst);
+            } else {
+                return new WarnUnimplemented("vrshl", machInst);
+            }
+          case 0x6:
+            if (b) {
+                return new WarnUnimplemented("vmin (int)", machInst);
+            } else {
+                return new WarnUnimplemented("vmax (int)", machInst);
+            }
+          case 0x7:
+            if (b) {
+                return new WarnUnimplemented("vaba", machInst);
+            } else {
+                if (bits(machInst, 23) == 1) {
+                    if (bits(machInst, 6) == 1) {
+                        return new Unknown(machInst);
+                    } else {
+                        return new WarnUnimplemented("vabdl (int)", machInst);
+                    }
+                } else {
+                    return new WarnUnimplemented("vabd (int)", machInst);
+                }
+            }
+          case 0x8:
+            if (b) {
+                if (u) {
+                    return new WarnUnimplemented("vceq (reg)", machInst);
+                } else {
+                    return new WarnUnimplemented("vtst", machInst);
+                }
+            } else {
+                if (u) {
+                    return new WarnUnimplemented("vsub (int)", machInst);
+                } else {
+                    return new WarnUnimplemented("vadd (int)", machInst);
+                }
+            }
+          case 0x9:
+            if (b) {
+                if (u) {
+                    return new WarnUnimplemented("vmul (poly)", machInst);
+                } else {
+                    return new WarnUnimplemented("vmul (int)", machInst);
+                }
+            } else {
+                if (u) {
+                    return new WarnUnimplemented("vmls (int)", machInst);
+                } else {
+                    return new WarnUnimplemented("vmla (int)", machInst);
+                }
+            }
+          case 0xa:
+            if (b) {
+                return new WarnUnimplemented("vpmin (int)", machInst);
+            } else {
+                return new WarnUnimplemented("vpmax (int)", machInst);
+            }
+          case 0xb:
+            if (b) {
+                if (u) {
+                    return new Unknown(machInst);
+                } else {
+                    return new WarnUnimplemented("vpadd (int)", machInst);
+                }
+            } else {
+                if (u) {
+                    return new WarnUnimplemented("vqrdmulh", machInst);
+                } else {
+                    return new WarnUnimplemented("vqdmulh", machInst);
+                }
+            }
+          case 0xc:
+            return new Unknown(machInst);
+          case 0xd:
+            if (b) {
+                if (u) {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vmul (fp)", machInst);
+                    } else {
+                        return new Unknown(machInst);
+                    }
+                } else {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vmla (fp)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vmls (fp)", machInst);
+                    }
+                }
+            } else {
+                if (u) {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vpadd (fp)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vabd (fp)", machInst);
+                    }
+                } else {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vadd (fp)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vsub (fp)", machInst);
+                    }
+                }
+            }
+          case 0xe:
+            if (b) {
+                if (u) {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vacge", machInst);
+                    } else {
+                        return new WarnUnimplemented("vacgt", machInst);
+                    }
+                } else {
+                    return new Unknown(machInst);
+                }
+            } else {
+                if (u) {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vcge (reg)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vcgt (reg)", machInst);
+                    }
+                } else {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vceq (reg)", machInst);
+                    } else {
+                        return new Unknown(machInst);
+                    }
+                }
+            }
+          case 0xf:
+            if (b) {
+                if (u) {
+                    return new Unknown(machInst);
+                } else {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vrecps", machInst);
+                    } else {
+                        return new WarnUnimplemented("vrsqrts", machInst);
+                    }
+                }
+            } else {
+                if (u) {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vpmax (fp)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vpmin (fp)", machInst);
+                    }
+                } else {
+                    if (bits(c, 1) == 0) {
+                        return new WarnUnimplemented("vmax (fp)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vmin (fp)", machInst);
+                    }
+                }
+            }
+        }
+        return new Unknown(machInst);
+    }
+
+    static StaticInstPtr
+    decodeNeonOneRegModImm(ExtMachInst machInst)
+    {
+        const bool op = bits(machInst, 5);
+        const uint32_t cmode = bits(machInst, 11, 8);
+        if (op) {
+            if (bits(cmode, 3) == 0) {
+                if (bits(cmode, 0) == 0) {
+                    return new WarnUnimplemented("vmov (imm)", machInst);
+                } else {
+                    return new WarnUnimplemented("vorr (imm)", machInst);
+                }
+            } else {
+                if (bits(cmode, 2) == 1) {
+                    return new WarnUnimplemented("vmov (imm)", machInst);
+                } else {
+                    if (bits(cmode, 0) == 0) {
+                        return new WarnUnimplemented("vmov (imm)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vorr (imm)", machInst);
+                    }
+                }
+            }
+        } else {
+            if (bits(cmode, 3) == 0) {
+                if (bits(cmode, 0) == 0) {
+                    return new WarnUnimplemented("vmvn (imm)", machInst);
+                } else {
+                    return new WarnUnimplemented("vbic (imm)", machInst);
+                }
+            } else {
+                if (bits(cmode, 2) == 1) {
+                    switch (bits(cmode, 1, 0)) {
+                      case 0:
+                      case 1:
+                        return new WarnUnimplemented("vmvn (imm)", machInst);
+                      case 2:
+                        return new WarnUnimplemented("vmov (imm)", machInst);
+                      case 3:
+                        return new Unknown(machInst);
+                    }
+                    return new WarnUnimplemented("vmov (imm)", machInst);
+                } else {
+                    if (bits(cmode, 0) == 0) {
+                        return new WarnUnimplemented("vmvn (imm)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vbic (imm)", machInst);
+                    }
+                }
+            }
+        }
+        return new Unknown(machInst);
+    }
+
+    static StaticInstPtr
+    decodeNeonTwoRegAndShift(ExtMachInst machInst)
+    {
+        const uint32_t a = bits(machInst, 11, 8);
+        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
+        const bool b = bits(machInst, 6);
+        const bool l = bits(machInst, 7);
+
+        switch (a) {
+          case 0x0:
+            return new WarnUnimplemented("vshr", machInst);
+          case 0x1:
+            return new WarnUnimplemented("vsra", machInst);
+          case 0x2:
+            return new WarnUnimplemented("vrshr", machInst);
+          case 0x3:
+            return new WarnUnimplemented("vrsra", machInst);
+          case 0x4:
+            if (u) {
+                return new WarnUnimplemented("vsri", machInst);
+            } else {
+                return new Unknown(machInst);
+            }
+          case 0x5:
+            if (u) {
+                return new WarnUnimplemented("vsli", machInst);
+            } else {
+                return new WarnUnimplemented("vshl (imm)", machInst);
+            }
+          case 0x6:
+          case 0x7:
+            return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
+          case 0x8:
+            if (l) {
+                return new Unknown(machInst);
+            } else if (u) {
+                if (b) {
+                    return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
+                } else {
+                    return new WarnUnimplemented("vqshrn, vqshrun", machInst);
+                }
+            } else {
+                if (b) {
+                    return new WarnUnimplemented("vrshrn", machInst);
+                } else {
+                    return new WarnUnimplemented("vshrn", machInst);
+                }
+            }
+          case 0x9:
+            if (l) {
+                return new Unknown(machInst);
+            } else if (b) {
+                return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
+            } else {
+                return new WarnUnimplemented("vqshrn, vqshrun", machInst);
+            }
+          case 0xa:
+            if (l || b) {
+                return new Unknown(machInst);
+            } else {
+                // If the shift amount is zero, it's vmovl.
+                return new WarnUnimplemented("vshll, vmovl", machInst);
+            }
+          case 0xe:
+          case 0xf:
+            if (l) {
+                return new Unknown(machInst);
+            } else if (a == 0xe) {
+                return new WarnUnimplemented("vcvt (fixed to fp)", machInst);
+            } else if (a == 0xf) {
+                return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
+            }
+        }
+        return new Unknown(machInst);
+    }
+
+    static StaticInstPtr
+    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
+    {
+        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
+        const uint32_t a = bits(machInst, 11, 8);
+
+        switch (a) {
+          case 0x0:
+            return new WarnUnimplemented("vaddl", machInst);
+          case 0x1:
+            return new WarnUnimplemented("vaddw", machInst);
+          case 0x2:
+            return new WarnUnimplemented("vsubl", machInst);
+          case 0x3:
+            return new WarnUnimplemented("vsubw", machInst);
+          case 0x4:
+            if (u) {
+                return new WarnUnimplemented("vraddhn", machInst);
+            } else {
+                return new WarnUnimplemented("vaddhn", machInst);
+            }
+          case 0x5:
+            return new WarnUnimplemented("vabal", machInst);
+          case 0x6:
+            if (u) {
+                return new WarnUnimplemented("vrsubhn", machInst);
+            } else {
+                return new WarnUnimplemented("vsubhn", machInst);
+            }
+          case 0x7:
+            if (bits(machInst, 23)) {
+                return new WarnUnimplemented("vabdl (int)", machInst);
+            } else {
+                return new WarnUnimplemented("vabd (int)", machInst);
+            }
+          case 0x8:
+            return new WarnUnimplemented("vmlal (int)", machInst);
+          case 0xa:
+            return new WarnUnimplemented("vmlsl (int)", machInst);
+          case 0x9:
+            if (bits(machInst, 23) == 0) {
+                if (bits(machInst, 4) == 0) {
+                    if (u) {
+                        return new WarnUnimplemented("vmls (int)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vmla (int)", machInst);
+                    }
+                } else {
+                    if (u) {
+                        return new WarnUnimplemented("vmul (poly)", machInst);
+                    } else {
+                        return new WarnUnimplemented("vmul (int)", machInst);
+                    }
+                }
+            } else {
+                return new WarnUnimplemented("vqdmlal", machInst);
+            }
+          case 0xb:
+            if (!u) {
+                return new Unknown(machInst);
+            } else {
+                return new WarnUnimplemented("vqdmlsl", machInst);
+            }
+          case 0xc:
+            return new WarnUnimplemented("vmull (int)", machInst);
+          case 0xd:
+            if (!u) {
+                return new Unknown(machInst);
+            } else {
+                return new WarnUnimplemented("vqdmull", machInst);
+            }
+          case 0xe:
+            return new WarnUnimplemented("vmull (poly)", machInst);
+        }
+        return new Unknown(machInst);
+    }
+
+    static StaticInstPtr
+    decodeNeonTwoRegScalar(ExtMachInst machInst)
+    {
+        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
+        const uint32_t a = bits(machInst, 11, 8);
+
+        switch (a) {
+          case 0x0:
+            return new WarnUnimplemented("vmla (int scalar)", machInst);
+          case 0x1:
+            return new WarnUnimplemented("vmla (fp scalar)", machInst);
+          case 0x4:
+            return new WarnUnimplemented("vmls (int scalar)", machInst);
+          case 0x5:
+            return new WarnUnimplemented("vmls (fp scalar)", machInst);
+          case 0x2:
+            return new WarnUnimplemented("vmlal (scalar)", machInst);
+          case 0x6:
+            return new WarnUnimplemented("vmlsl (scalar)", machInst);
+          case 0x3:
+            if (u) {
+                return new Unknown(machInst);
+            } else {
+                return new WarnUnimplemented("vqdmlal", machInst);
+            }
+          case 0x7:
+            if (u) {
+                return new Unknown(machInst);
+            } else {
+                return new WarnUnimplemented("vqdmlsl", machInst);
+            }
+          case 0x8:
+            return new WarnUnimplemented("vmul (int scalar)", machInst);
+          case 0x9:
+            return new WarnUnimplemented("vmul (fp scalar)", machInst);
+          case 0xa:
+            return new WarnUnimplemented("vmull (scalar)", machInst);
+          case 0xb:
+            if (u) {
+                return new Unknown(machInst);
+            } else {
+                return new WarnUnimplemented("vqdmull", machInst);
+            }
+          case 0xc:
+            return new WarnUnimplemented("vqdmulh", machInst);
+          case 0xd:
+            return new WarnUnimplemented("vqrdmulh", machInst);
+        }
+        return new Unknown(machInst);
+    }
+
+    static StaticInstPtr
+    decodeNeonTwoRegMisc(ExtMachInst machInst)
+    {
+        const uint32_t a = bits(machInst, 17, 16);
+        const uint32_t b = bits(machInst, 10, 6);
+        switch (a) {
+          case 0x0:
+            switch (bits(b, 4, 1)) {
+              case 0x0:
+                return new WarnUnimplemented("vrev64", machInst);
+              case 0x1:
+                return new WarnUnimplemented("vrev32", machInst);
+              case 0x2:
+                return new WarnUnimplemented("vrev16", machInst);
+              case 0x4:
+              case 0x5:
+                return new WarnUnimplemented("vpaddl", machInst);
+              case 0x8:
+                return new WarnUnimplemented("vcls", machInst);
+              case 0x9:
+                return new WarnUnimplemented("vclz", machInst);
+              case 0xa:
+                return new WarnUnimplemented("vcnt", machInst);
+              case 0xb:
+                return new WarnUnimplemented("vmvn (reg)", machInst);
+              case 0xc:
+              case 0xd:
+                return new WarnUnimplemented("vpadal", machInst);
+              case 0xe:
+                return new WarnUnimplemented("vqabs", machInst);
+              case 0xf:
+                return new WarnUnimplemented("vqneg", machInst);
+              default:
+                return new Unknown(machInst);
+            }
+          case 0x1:
+            switch (bits(b, 3, 1)) {
+              case 0x0:
+                return new WarnUnimplemented("vcgt (imm #0)", machInst);
+              case 0x1:
+                return new WarnUnimplemented("vcge (imm #0)", machInst);
+              case 0x2:
+                return new WarnUnimplemented("vceq (imm #0)", machInst);
+              case 0x3:
+                return new WarnUnimplemented("vcle (imm #0)", machInst);
+              case 0x4:
+                return new WarnUnimplemented("vclt (imm #0)", machInst);
+              case 0x6:
+                return new WarnUnimplemented("vabs (imm #0)", machInst);
+              case 0x7:
+                return new WarnUnimplemented("vneg (imm #0)", machInst);
+            }
+          case 0x2:
+            switch (bits(b, 4, 1)) {
+              case 0x0:
+                return new WarnUnimplemented("vswp", machInst);
+              case 0x1:
+                return new WarnUnimplemented("vtrn", machInst);
+              case 0x2:
+                return new WarnUnimplemented("vuzp", machInst);
+              case 0x3:
+                return new WarnUnimplemented("vzip", machInst);
+              case 0x4:
+                if (b == 0x8) {
+                    return new WarnUnimplemented("vmovn", machInst);
+                } else {
+                    return new WarnUnimplemented("vqmovun", machInst);
+                }
+              case 0x5:
+                return new WarnUnimplemented("vqmovn", machInst);
+              case 0x6:
+                if (b == 0xc) {
+                    return new WarnUnimplemented("vshll", machInst);
+                } else {
+                    return new Unknown(machInst);
+                }
+              case 0xc:
+              case 0xe:
+                if (b == 0x18) {
+                    return new WarnUnimplemented("vcvt (single to half)",
+                            machInst);
+                } else if (b == 0x1c) {
+                    return new WarnUnimplemented("vcvt (half to single)",
+                            machInst);
+                } else {
+                    return new Unknown(machInst);
+                }
+              default:
+                return new Unknown(machInst);
+            }
+          case 0x3:
+            if (bits(b, 4, 3) == 0x3) {
+                return new WarnUnimplemented("vcvt (fp and int)", machInst);
+            } else if ((b & 0x1a) == 0x10) {
+                return new WarnUnimplemented("vrecpe", machInst);
+            } else if ((b & 0x1a) == 0x12) {
+                return new WarnUnimplemented("vrsqrte", machInst);
+            } else {
+                return new Unknown(machInst);
+            }
+        }
+        return new Unknown(machInst);
+    }
+
+    StaticInstPtr
+    decodeNeonData(ExtMachInst machInst)
+    {
+        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
+        const uint32_t a = bits(machInst, 23, 19);
+        const uint32_t b = bits(machInst, 11, 8);
+        const uint32_t c = bits(machInst, 7, 4);
+        if (bits(a, 4) == 0) {
+            return decodeNeonThreeRegistersSameLength(machInst);
+        } else if ((c & 0x9) == 1) {
+            if ((a & 0x7) == 0) {
+                return decodeNeonOneRegModImm(machInst);
+            } else {
+                return decodeNeonTwoRegAndShift(machInst);
+            }
+        } else if ((c & 0x9) == 9) {
+            return decodeNeonTwoRegAndShift(machInst);
+        } else if ((c & 0x5) == 0) {
+            if (bits(a, 3, 2) != 0x3) {
+                return decodeNeonThreeRegDiffLengths(machInst);
+            }
+        } else if ((c & 0x5) == 4) {
+            if (bits(a, 3, 2) != 0x3) {
+                return decodeNeonTwoRegScalar(machInst);
+            }
+        } else if ((a & 0x16) == 0x16) {
+            if (!u) {
+                if (bits(c, 0) == 0) {
+                    return new WarnUnimplemented("vext", machInst);
+                }
+            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
+                return decodeNeonTwoRegMisc(machInst);
+            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
+                if (bits(machInst, 6) == 0) {
+                    return new WarnUnimplemented("vtbl", machInst);
+                } else {
+                    return new WarnUnimplemented("vtbx", machInst);
+                }
+            } else if (b == 0xc && (c & 0x9) == 0) {
+                return new WarnUnimplemented("vdup (scalar)", machInst);
+            }
+        }
+        return new Unknown(machInst);
+    }
+    '''
+}};
+
+def format ThumbNeonMem() {{
+    decode_block = '''
+    return decodeNeonMem(machInst);
+    '''
+}};
+
+def format ThumbNeonData() {{
+    decode_block = '''
+    return decodeNeonMem(machInst);
+    '''
+}};
+
 let {{
     header_output = '''
     StaticInstPtr
index 8aa460081f4929be4e285d9afee3f23fef002e97..f4cc16262a8ac43d84dfa8c2ca1f7b9f93e8f542 100644 (file)
@@ -54,13 +54,10 @@ def format ArmUnconditional() {{
                     return new Cps(machInst, mods);
                 }
             } else if (bits(op1, 6, 5) == 0x1) {
-                return new WarnUnimplemented(
-                        "Advanced SIMD data-processing", machInst);
+                return decodeNeonData(machInst);
             } else if (bits(op1, 6, 4) == 0x4) {
                 if (bits(op1, 0) == 0) {
-                    return new WarnUnimplemented(
-                            "Advanced SIMD element or structure load/store",
-                            machInst);
+                    return decodeNeonMem(machInst);
                 } else if (bits(op1, 2, 0) == 1) {
                     // Unallocated memory hint
                     return new NopInst(machInst);