ARM: Hook the new multiply instructions into all the decoders.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:03 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:03 +0000 (12:58 -0500)
src/arch/arm/isa/bitfields.isa
src/arch/arm/isa/decoder/arm.isa
src/arch/arm/isa/decoder/thumb.isa
src/arch/arm/isa/formats/data.isa
src/arch/arm/isa/formats/formats.isa
src/arch/arm/isa/formats/mult.isa [new file with mode: 0644]
src/arch/arm/types.hh

index 29f3e746ef5692e46cdfd3a25b94043583b1642d..abaedd0242ef01bdf3dd6b1ece413040169c9e76 100644 (file)
@@ -52,6 +52,7 @@ def bitfield MEDIA_OPCODE  mediaOpcode;
 def bitfield MEDIA_OPCODE2 mediaOpcode2;
 def bitfield USEIMM        useImm;
 def bitfield OPCODE_24     opcode24;
+def bitfield OPCODE_24_23  opcode24_23;
 def bitfield OPCODE_23_20  opcode23_20;
 def bitfield OPCODE_23_21  opcode23_21;
 def bitfield OPCODE_22     opcode22;
index 06f5407178bb434913bd814ecabc6f1a4839ed43..d84a6a5dc4f30071fe3035a4eb929fa4558fa720 100644 (file)
@@ -55,34 +55,7 @@ format DataOp {
     0x0: decode SEVEN_AND_FOUR {
         1: decode MISC_OPCODE {
             0x9: decode PREPOST {
-                0: decode OPCODE {
-                    0x0: mul({{ Rn = resTemp = Rm * Rs; }}, none);
-                    0x1: mla({{ Rn = resTemp = (Rm * Rs) + Rd; }}, none);
-                    0x2: WarnUnimpl::umall();
-                    0x4: umull({{
-                        resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
-                        Rd = (uint32_t)(resTemp & 0xffffffff);
-                        Rn = (uint32_t)(resTemp >> 32);
-                    }}, llbit);
-                    0x5: smlal({{
-                        resTemp = ((int64_t)Rm) * ((int64_t)Rs);
-                        resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd);
-                        Rd = (uint32_t)(resTemp & 0xffffffff);
-                        Rn = (uint32_t)(resTemp >> 32);
-                    }}, llbit);
-                    0x6: smull({{
-                        resTemp = ((int64_t)(int32_t)Rm)*
-                                  ((int64_t)(int32_t)Rs);
-                        Rd = (int32_t)(resTemp & 0xffffffff);
-                        Rn = (int32_t)(resTemp >> 32);
-                    }}, llbit);
-                    0x7: umlal({{
-                        resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
-                        resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
-                        Rd = (uint32_t)(resTemp & 0xffffffff);
-                        Rn = (uint32_t)(resTemp >> 32);
-                    }}, llbit);
-                }
+                0: ArmMultAndMultAcc::armMultAndMultAcc();
                 1: decode PUBWL {
                     0x10: WarnUnimpl::swp();
                     0x14: WarnUnimpl::swpb();
@@ -94,86 +67,61 @@ format DataOp {
         }
         0: decode IS_MISC {
             0: ArmDataProcReg::armDataProcReg();
-            1: decode MISC_OPCODE {
-                0x0: decode OPCODE {
-                    0x8: PredOp::mrs_cpsr({{
-                        Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
-                    }});
-                    0x9: decode USEIMM {
-                        // The mask field is the same as the RN index.
-                        0: PredOp::msr_cpsr_reg({{
-                            uint32_t newCpsr =
-                                cpsrWriteByInstr(Cpsr | CondCodes,
-                                                 Rm, RN, false);
-                            Cpsr = ~CondCodesMask & newCpsr;
-                            CondCodes = CondCodesMask & newCpsr;
-                        }});
-                        1: PredImmOp::msr_cpsr_imm({{
-                            uint32_t newCpsr =
-                                cpsrWriteByInstr(Cpsr | CondCodes,
-                                                 rotated_imm, RN, false);
-                            Cpsr = ~CondCodesMask & newCpsr;
-                            CondCodes = CondCodesMask & newCpsr;
+            1: decode OPCODE_7 {
+                0x0: decode MISC_OPCODE {
+                    0x0: decode OPCODE {
+                        0x8: PredOp::mrs_cpsr({{
+                            Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
                         }});
+                        0x9: decode USEIMM {
+                            // The mask field is the same as the RN index.
+                            0: PredOp::msr_cpsr_reg({{
+                                uint32_t newCpsr =
+                                    cpsrWriteByInstr(Cpsr | CondCodes,
+                                                     Rm, RN, false);
+                                Cpsr = ~CondCodesMask & newCpsr;
+                                CondCodes = CondCodesMask & newCpsr;
+                            }});
+                            1: PredImmOp::msr_cpsr_imm({{
+                                uint32_t newCpsr =
+                                    cpsrWriteByInstr(Cpsr | CondCodes,
+                                                     rotated_imm, RN, false);
+                                Cpsr = ~CondCodesMask & newCpsr;
+                                CondCodes = CondCodesMask & newCpsr;
+                            }});
+                        }
+                        0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
+                        0xb: decode USEIMM {
+                            // The mask field is the same as the RN index.
+                            0: PredOp::msr_spsr_reg({{
+                                Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
+                            }});
+                            1: PredImmOp::msr_spsr_imm({{
+                                Spsr = spsrWriteByInstr(Spsr, rotated_imm,
+                                                        RN, false);
+                            }});
+                        }
                     }
-                    0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
-                    0xb: decode USEIMM {
-                        // The mask field is the same as the RN index.
-                        0: PredOp::msr_spsr_reg({{
-                            Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
-                        }});
-                        1: PredImmOp::msr_spsr_imm({{
-                            Spsr = spsrWriteByInstr(Spsr, rotated_imm,
-                                                    RN, false);
+                    0x1: decode OPCODE {
+                        0x9: ArmBx::armBx();
+                        0xb: PredOp::clz({{
+                            Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm)));
                         }});
                     }
+                    0x2: decode OPCODE {
+                        0x9: WarnUnimpl::bxj();
+                    }
+                    0x3: decode OPCODE {
+                        0x9: ArmBlxReg::armBlxReg();
+                    }
+                    0x5: decode OPCODE {
+                        0x8: WarnUnimpl::qadd();
+                        0x9: WarnUnimpl::qsub();
+                        0xa: WarnUnimpl::qdadd();
+                        0xb: WarnUnimpl::qdsub();
+                    }
                 }
-                0x1: decode OPCODE {
-                    0x9: ArmBx::armBx();
-                    0xb: PredOp::clz({{
-                        Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm)));
-                    }});
-                }
-                0x2: decode OPCODE {
-                    0x9: WarnUnimpl::bxj();
-                }
-                0x3: decode OPCODE {
-                    0x9: ArmBlxReg::armBlxReg();
-                }
-                0x5: decode OPCODE {
-                    0x8: WarnUnimpl::qadd();
-                    0x9: WarnUnimpl::qsub();
-                    0xa: WarnUnimpl::qdadd();
-                    0xb: WarnUnimpl::qdsub();
-                }
-                0x8: decode OPCODE {
-                    0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
-                    0x9: WarnUnimpl::smlalbb();
-                    0xa: WarnUnimpl::smlawb();
-                    0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
-                }
-                0xa: decode OPCODE {
-                    0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
-                    0x9: smulwb({{
-                        Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16);
-                    }}, none);
-                    0xa: WarnUnimpl::smlaltb();
-                    0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
-                }
-                0xc: decode OPCODE {
-                    0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
-                    0x9: WarnUnimpl::smlawt();
-                    0xa: WarnUnimpl::smlalbt();
-                    0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
-                }
-                0xe: decode OPCODE {
-                    0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
-                    0x9: smulwt({{
-                        Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16);
-                    }}, none);
-                    0xa: WarnUnimpl::smlaltt();
-                    0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
-                }
+                0x1: ArmHalfWordMultAndMultAcc::armHalfWordMultAndMultAcc();
             }
         }
     }
@@ -207,58 +155,31 @@ format DataOp {
     0x2: AddrMode2::addrMode2(True);
     0x3: decode OPCODE_4 {
         0: AddrMode2::addrMode2(False);
-        1: decode MEDIA_OPCODE {
-            0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions();
-            0x8: decode MISC_OPCODE {
-                0x1, 0x9: WarnUnimpl::pkhbt();
-                0x7: WarnUnimpl::sxtab16();
-                0xb: WarnUnimpl::sel();
-                0x5, 0xd: WarnUnimpl::pkhtb();
-                0x3: WarnUnimpl::sign_zero_extend_add();
-            }
-            0xa, 0xb: decode SHIFT {
-                0x0, 0x2: WarnUnimpl::ssat();
-                0x1: WarnUnimpl::ssat16();
-            }
-            0xe, 0xf: decode SHIFT {
-                0x0, 0x2: WarnUnimpl::usat();
-                0x1: WarnUnimpl::usat16();
-            }
-            0x10: decode RN {
-                0xf: decode MISC_OPCODE {
-                    0x1: WarnUnimpl::smuad();
-                    0x3: WarnUnimpl::smuadx();
-                    0x5: WarnUnimpl::smusd();
-                    0x7: WarnUnimpl::smusdx();
+        1: decode OPCODE_24_23 {
+            0x0: WarnUnimpl::parallel_add_subtract_instructions();
+            0x1: decode MEDIA_OPCODE {
+                0x8: decode MISC_OPCODE {
+                    0x1, 0x9: WarnUnimpl::pkhbt();
+                    0x7: WarnUnimpl::sxtab16();
+                    0xb: WarnUnimpl::sel();
+                    0x5, 0xd: WarnUnimpl::pkhtb();
+                    0x3: WarnUnimpl::sign_zero_extend_add();
                 }
-                default: decode MISC_OPCODE {
-                    0x1: WarnUnimpl::smlad();
-                    0x3: WarnUnimpl::smladx();
-                    0x5: WarnUnimpl::smlsd();
-                    0x7: WarnUnimpl::smlsdx();
+                0xa, 0xb: decode SHIFT {
+                    0x0, 0x2: WarnUnimpl::ssat();
+                    0x1: WarnUnimpl::ssat16();
                 }
-            }
-            0x14: decode MISC_OPCODE {
-                0x1: WarnUnimpl::smlald();
-                0x3: WarnUnimpl::smlaldx();
-                0x5: WarnUnimpl::smlsld();
-                0x7: WarnUnimpl::smlsldx();
-            }
-            0x15: decode RN {
-                0xf: decode MISC_OPCODE {
-                    0x1: WarnUnimpl::smmul();
-                    0x3: WarnUnimpl::smmulr();
-                }
-                default: decode MISC_OPCODE {
-                    0x1: WarnUnimpl::smmla();
-                    0x3: WarnUnimpl::smmlar();
-                    0xd: WarnUnimpl::smmls();
-                    0xf: WarnUnimpl::smmlsr();
+                0xe, 0xf: decode SHIFT {
+                    0x0, 0x2: WarnUnimpl::usat();
+                    0x1: WarnUnimpl::usat16();
                 }
             }
-            0x18: decode RN {
-                0xf: WarnUnimpl::usada8();
-                default: WarnUnimpl::usad8();
+            0x2: ArmSignedMultiplies::armSignedMultiplies();
+            0x3: decode MEDIA_OPCODE {
+                0x18: decode RN {
+                    0xf: WarnUnimpl::usada8();
+                    default: WarnUnimpl::usad8();
+                }
             }
         }
     }
index 9a09a57d4034e59419c92196220d90b282acfed5..781e467cfde9a41bd4aa0df24304e8306c8f4b45 100644 (file)
                 }
             }
             0x1: decode HTOPCODE_8_7 {
-                0x2: WarnUnimpl::Multiply_multiply_accumulate_and_absolute_difference();
-                0x3: WarnUnimpl::Long_multiply_long_multiply_accumulate_and_divide();
+                0x2: Thumb32MulMulAccAndAbsDiff::thumb32MulMulAccAndAbsDiff();
+                0x3: Thumb32LongMulMulAccAndDiv::thumb32LongMulMulAccAndDiv();
                 default: WarnUnimpl::Data_processing_register();
             }
             default: decode HTOPCODE_9_8 {
index 6707e23c2c525c335ebf64881a76209352cc968b..e866ee04be827a426f045f5d0f071bae26d8b323 100644 (file)
@@ -230,8 +230,7 @@ def format Thumb16DataProcessing() {{
           case 0xc:
             return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
           case 0xd:
-            //XXX Implement me!
-            return new WarnUnimplemented("mul", machInst);
+            return new NewMul(machInst, rdn, rm, rdn);
           case 0xe:
             return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
           case 0xf:
index 87383c26cf8b811ec7cd3a3d5977e693eda3680a..b55b821100cb1767e99d1718e0fe0dd2d6329bd5 100644 (file)
@@ -70,3 +70,6 @@
 
 //Include the formats for data processing instructions
 ##include "data.isa"
+
+//Include the formats for multiply instructions
+##include "mult.isa"
diff --git a/src/arch/arm/isa/formats/mult.isa b/src/arch/arm/isa/formats/mult.isa
new file mode 100644 (file)
index 0000000..a0cdfbc
--- /dev/null
@@ -0,0 +1,440 @@
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Gabe Black
+
+def format ArmMultAndMultAcc() {{
+    decode_block = '''
+    {
+        // The manual defines this field as 23-20, but bit 20 is usually
+        // ignored.
+        const uint32_t op = bits(machInst, 23, 21);
+        const bool s = bits(machInst, 20);
+        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
+        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+        switch (op) {
+            case 0x0:
+              if (s) {
+                  return new NewMulCc(machInst, rd, rm, rn);
+              } else {
+                  return new NewMul(machInst, rd, rm, rn);
+              }
+            case 0x1:
+              if (s) {
+                  return new NewMlaCc(machInst, rd, rn, rm, ra);
+              } else {
+                  return new NewMla(machInst, rd, rn, rm, ra);
+              }
+            case 0x2:
+              return new NewUmaal(machInst, ra, rd, rn, rm);
+            case 0x3:
+              return new NewMls(machInst, rd, rn, rm, ra);
+            case 0x4:
+              if (s) {
+                  return new NewUmullCc(machInst, ra, rd, rn, rm);
+              } else {
+                  return new NewUmull(machInst, ra, rd, rn, rm);
+              }
+            case 0x5:
+              if (s) {
+                  return new NewUmlalCc(machInst, ra, rd, rn, rm);
+              } else {
+                  return new NewUmlal(machInst, ra, rd, rn, rm);
+              }
+            case 0x6:
+              if (s) {
+                  return new NewSmullCc(machInst, ra, rd, rn, rm);
+              } else {
+                  return new NewSmull(machInst, ra, rd, rn, rm);
+              }
+            case 0x7:
+              if (s) {
+                  return new NewSmlalCc(machInst, ra, rd, rn, rm);
+              } else {
+                  return new NewSmlal(machInst, ra, rd, rn, rm);
+              }
+        }
+    }
+    '''
+}};
+
+def format ArmHalfWordMultAndMultAcc() {{
+    decode_block = '''
+    {
+        const uint32_t op1 = bits(machInst, 22, 21);
+        const bool op = bits(machInst, 5);
+        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
+        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+        switch (op1) {
+          case 0x0:
+            switch (bits(machInst, 6, 5)) {
+              case 0x0:
+                return new NewSmlabbCc(machInst, rd, rn, rm, ra);
+              case 0x1:
+                return new NewSmlatbCc(machInst, rd, rn, rm, ra);
+              case 0x2:
+                return new NewSmlabtCc(machInst, rd, rn, rm, ra);
+              case 0x3:
+                return new NewSmlattCc(machInst, rd, rn, rm, ra);
+            }
+          case 0x1:
+            if (op) {
+                if (bits(machInst, 6)) {
+                    return new NewSmulwt(machInst, rd, rn, rm);
+                } else {
+                    return new NewSmulwb(machInst, rd, rn, rm);
+                }
+            } else {
+                if (bits(machInst, 6)) {
+                    return new NewSmlawtCc(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmlawbCc(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x2:
+            switch (bits(machInst, 6, 5)) {
+              case 0x0:
+                return new NewSmlalbb(machInst, ra, rd, rn, rm);
+              case 0x1:
+                return new NewSmlaltb(machInst, ra, rd, rn, rm);
+              case 0x2:
+                return new NewSmlalbt(machInst, ra, rd, rn, rm);
+              case 0x3:
+                return new NewSmlaltt(machInst, ra, rd, rn, rm);
+            }
+          case 0x3:
+            switch (bits(machInst, 6, 5)) {
+              case 0x0:
+                return new NewSmulbb(machInst, rd, rn, rm);
+              case 0x1:
+                return new NewSmultb(machInst, rd, rn, rm);
+              case 0x2:
+                return new NewSmulbt(machInst, rd, rn, rm);
+              case 0x3:
+                return new NewSmultt(machInst, rd, rn, rm);
+            }
+        }
+    }
+    '''
+}};
+
+def format Thumb32MulMulAccAndAbsDiff() {{
+    decode_block = '''
+    {
+        const uint32_t op1 = bits(machInst, 22, 20);
+        const uint32_t op2 = bits(machInst, 5, 4);
+        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
+        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+        if (op1 != 0x1 && bits(op2, 1) != 0) {
+            return new Unknown(machInst);
+        }
+        switch (op1) {
+          case 0x0:
+            if (op2 == 0) {
+                if (ra == 0xf) {
+                    return new NewMul(machInst, rd, rn, rm);
+                } else {
+                    return new NewMla(machInst, rd, rn, rm, ra);
+                }
+            } else {
+                return new NewMls(machInst, rd, rn, rm, ra);
+            }
+          case 0x1:
+            if (ra == 0xf) {
+                switch (bits(machInst, 5, 4)) {
+                  case 0x0:
+                    return new NewSmulbb(machInst, rd, rn, rm);
+                  case 0x1:
+                    return new NewSmulbt(machInst, rd, rn, rm);
+                  case 0x2:
+                    return new NewSmultb(machInst, rd, rn, rm);
+                  case 0x3:
+                    return new NewSmultt(machInst, rd, rn, rm);
+                }
+            } else {
+                switch (bits(machInst, 5, 4)) {
+                  case 0x0:
+                    return new NewSmlabbCc(machInst, rd, rn, rm, ra);
+                  case 0x1:
+                    return new NewSmlabtCc(machInst, rd, rn, rm, ra);
+                  case 0x2:
+                    return new NewSmlatbCc(machInst, rd, rn, rm, ra);
+                  case 0x3:
+                    return new NewSmlattCc(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x2:
+            if (ra == 0xf) {
+                if (bits(machInst, 4)) {
+                    return new NewSmuadxCc(machInst, rd, rn, rm);
+                } else {
+                    return new NewSmuadCc(machInst, rd, rn, rm);
+                }
+            } else {
+                if (bits(machInst, 4)) {
+                    return new NewSmladxCc(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmladCc(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x3:
+            if (ra == 0xf) {
+                if (bits(machInst, 4)) {
+                    return new NewSmulwt(machInst, rd, rn, rm);
+                } else {
+                    return new NewSmulwb(machInst, rd, rn, rm);
+                }
+            } else {
+                if (bits(machInst, 4)) {
+                    return new NewSmlawtCc(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmlawbCc(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x4:
+            if (ra == 0xf) {
+                if (bits(machInst, 4)) {
+                    return new NewSmusdx(machInst, rd, rn, rm);
+                } else {
+                    return new NewSmusd(machInst, rd, rn, rm);
+                }
+            } else {
+                if (bits(machInst, 4)) {
+                    return new NewSmlsdxCc(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmlsdCc(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x5:
+            if (ra == 0xf) {
+                if (bits(machInst, 4)) {
+                    return new NewSmmulr(machInst, rd, rn, rm);
+                } else {
+                    return new NewSmmul(machInst, rd, rn, rm);
+                }
+            } else {
+                if (bits(machInst, 4)) {
+                    return new NewSmmlar(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmmla(machInst, rd, rn, rm, ra);
+                }
+            }
+          case 0x6:
+            if (bits(machInst, 4)) {
+                return new NewSmmlsr(machInst, rd, rn, rm, ra);
+            } else {
+                return new NewSmmls(machInst, rd, rn, rm, ra);
+            }
+          case 0x7:
+            if (op2 != 0x0) {
+                return new Unknown(machInst);
+            } else if (ra == 0xf) {
+                return new WarnUnimplemented("usada8", machInst);
+            } else {
+                return new WarnUnimplemented("usad8", machInst);
+            }
+        }
+    }
+    '''
+}};
+
+def format Thumb32LongMulMulAccAndDiv() {{
+    decode_block = '''
+    {
+        const uint32_t op1 = bits(machInst, 22, 20);
+        const uint32_t op2 = bits(machInst, 7, 4);
+        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+        const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+        const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
+        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+        switch (op1) {
+          case 0x0:
+            if (op2 == 0x0) {
+                return new NewSmull(machInst, rdlo, rdhi, rn, rm);
+            }
+            break;
+          case 0x1:
+            if (op2 == 0xf) {
+                return new WarnUnimplemented("sdiv", machInst);
+            }
+            break;
+          case 0x2:
+            if (op2 == 0x0) {
+                return new NewUmull(machInst, rdlo, rdhi, rn, rm);
+            }
+            break;
+          case 0x3:
+            if (op2 == 0xf) {
+                return new WarnUnimplemented("udiv", machInst);
+            }
+            break;
+          case 0x4:
+            if (op2 == 0) {
+                return new NewSmlal(machInst, rdlo, rdhi, rn, rm);
+            } else if (bits(op2, 3, 2) == 0x2) {
+                switch (bits(machInst, 5, 4)) {
+                  case 0x0:
+                    return new NewSmlalbb(machInst, rdlo, rdhi, rn, rm);
+                  case 0x1:
+                    return new NewSmlalbt(machInst, rdlo, rdhi, rn, rm);
+                  case 0x2:
+                    return new NewSmlaltb(machInst, rdlo, rdhi, rn, rm);
+                  case 0x3:
+                    return new NewSmlaltt(machInst, rdlo, rdhi, rn, rm);
+                }
+            } else if (bits(op2, 3, 1) == 0x6) {
+                if (bits(machInst, 4)) {
+                    return new NewSmlaldx(machInst, rdlo, rdhi, rn, rm);
+                } else {
+                    return new NewSmlald(machInst, rdlo, rdhi, rn, rm);
+                }
+            }
+            break;
+          case 0x5:
+            if (bits(op2, 3, 1) == 0x6) {
+                if (bits(machInst, 4)) {
+                    return new NewSmlsldx(machInst, rdlo, rdhi, rn, rm);
+                } else {
+                    return new NewSmlsld(machInst, rdlo, rdhi, rn, rm);
+                }
+            }
+          case 0x6:
+            if (op2 == 0) {
+                return new NewUmlal(machInst, rdlo, rdhi, rn, rm);
+            } else if (op2 == 0x6) {
+                return new NewUmaal(machInst, rdlo, rdhi, rn, rm);
+            }
+            break;
+        }
+        return new Unknown(machInst);
+    }
+    '''
+}};
+
+def format ArmSignedMultiplies() {{
+    decode_block = '''
+    {
+        const uint32_t op1 = bits(machInst, 22, 20);
+        // This is 7-5 in the manual, but bit 5 is always ignored.
+        const uint32_t op2 = bits(machInst, 7, 6);
+        const bool aIsF = (bits(machInst, 15, 12) == 0xf);
+        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
+        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+        const bool m = bits(machInst, 5);
+        switch (op1) {
+          case 0x0:
+            if (op2 == 0) {
+                if (aIsF) {
+                    if (m) {
+                        return new NewSmuadxCc(machInst, rd, rn, rm);
+                    } else {
+                        return new NewSmuadCc(machInst, rd, rn, rm);
+                    }
+                } else {
+                    if (m) {
+                        return new NewSmladxCc(machInst, rd, rn, rm, ra);
+                    } else {
+                        return new NewSmladCc(machInst, rd, rn, rm, ra);
+                    }
+                }
+            } else if (op2 == 1) {
+                if (aIsF) {
+                    if (m) {
+                        return new NewSmusdx(machInst, rd, rn, rm);
+                    } else {
+                        return new NewSmusd(machInst, rd, rn, rm);
+                    }
+                } else {
+                    if (m) {
+                        return new NewSmlsdxCc(machInst, rd, rn, rm, ra);
+                    } else {
+                        return new NewSmlsdCc(machInst, rd, rn, rm, ra);
+                    }
+                }
+            }
+            break;
+          case 0x4:
+            if (op2 == 0) {
+                if (m) {
+                    return new NewSmlaldx(machInst, ra, rd, rn, rm);
+                } else {
+                    return new NewSmlald(machInst, ra, rd, rn, rm);
+                }
+            } else if (op2 == 1) {
+                if (m) {
+                    return new NewSmlsldx(machInst, ra, rd, rn, rm);
+                } else {
+                    return new NewSmlsld(machInst, ra, rd, rn, rm);
+                }
+            }
+            break;
+          case 0x5:
+            if (op2 == 0) {
+                if (aIsF) {
+                    if (m) {
+                        return new NewSmmulr(machInst, rd, rn, rm);
+                    } else {
+                        return new NewSmmul(machInst, rd, rn, rm);
+                    }
+                } else {
+                    if (m) {
+                        return new NewSmmlar(machInst, rd, rn, rm, ra);
+                    } else {
+                        return new NewSmmla(machInst, rd, rn, rm, ra);
+                    }
+                }
+            } else if (op2 == 0x3) {
+                if (m) {
+                    return new NewSmmlsr(machInst, rd, rn, rm, ra);
+                } else {
+                    return new NewSmmls(machInst, rd, rn, rm, ra);
+                }
+            }
+            break;
+          default:
+            break;
+        }
+        return new Unknown(machInst);
+    }
+    '''
+}};
index 62547d53c5ea27d88d7c9811b4f8c74778046585..7c961daa48b68809436e51469dd0b0b269dc8e19 100644 (file)
@@ -67,6 +67,7 @@ namespace ArmISA
         Bitfield<24, 21> opcode;
         Bitfield<24, 20> mediaOpcode;
         Bitfield<24>     opcode24;
+        Bitfield<24, 23> opcode24_23;
         Bitfield<23, 20> opcode23_20;
         Bitfield<23, 21> opcode23_21;
         Bitfield<20>     opcode20;