More updated
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Feb 2010 04:14:39 +0000 (04:14 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Feb 2010 04:14:39 +0000 (04:14 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9926 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c

index 74154fc2197e3637e24335ebf35a0b4f7ffe4bc6..f9c84bb890f92a02989973b0672d3d5a6eea1fcc 100644 (file)
@@ -81,6 +81,16 @@ extern CHAR8 *gReg[];
 #define ADD_IMM5                    219\r
 #define ADR_THUMB2                  220\r
 #define CMN_THUMB2                  221\r
+#define ASR_IMM5                    222\r
+#define ASR_3REG                    223\r
+#define BFC_THUMB2                  224\r
+#define CDP_THUMB2                  225\r
+#define THUMB2_NO_ARGS              226\r
+#define THUMB2_2REGS                227\r
+#define ADD_IMM5_2REG               228\r
+#define CPD_THUMB2                  229\r
+#define THUMB2_4REGS                230\r
+\r
 \r
 typedef struct {\r
   CHAR8   *Start;\r
@@ -143,6 +153,7 @@ THUMB_INSTRUCTIONS gOpThumb[] = {
   { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r
   { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r
   { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r
+  { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 },  // LSRS <Rd>, <Rm>, #<imm5>\r
 \r
   { "MOVS", 0x2000, 0xf800, DATA_FORMAT3 },\r
   { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r
@@ -190,8 +201,14 @@ THUMB_INSTRUCTIONS gOpThumb[] = {
 THUMB_INSTRUCTIONS gOpThumb2[] = {\r
 //Instruct  OpCode      OpCode Mask  Addressig Mode\r
   \r
-  { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2 },  // ADDR <Rd>, <label> ;Needs to go before ADDW \r
-  { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2 },  // CMN <Rn>, <Rm>, {,<shift> #<const>} ;Needs to go before ADD\r
+  { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2    },  // ADDR <Rd>, <label> ;Needs to go before ADDW \r
+  { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2    },  // CMN <Rn>, #<const> ;Needs to go before ADD\r
+  { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG },  // CMN <Rn>, <Rm> {,<shift> #<const>}\r
+  { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>\r
+  { "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>\r
+  { "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG },  // CMN <Rn>, <Rm> {,<shift> #<const>}\r
+  { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>\r
+  { "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG },  // TST <Rn>, <Rm> {,<shift> #<const>}\r
 \r
   { "ADC",  0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S}  <Rd>, <Rn>, #<const>\r
   { "ADC",  0xeb400000, 0xffe08000, ADD_IMM5  }, // ADC{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
@@ -215,6 +232,54 @@ THUMB_INSTRUCTIONS gOpThumb2[] = {
   { "SUB",  0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S}  <Rd>, <Rn>, #<const>\r
   { "SUB",  0xeba00000, 0xffe08000, ADD_IMM5  }, // SUB{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
 \r
+  { "ASR",  0xea4f0020, 0xffef8030, ASR_IMM5 },  // ARS  <Rd>, <Rm> #<const>} imm3:imm2\r
+  { "ASR",  0xfa40f000, 0xffe0f0f0, ASR_3REG },  // ARS  <Rd>, <Rn>, <Rm> \r
+  { "LSR",  0xea4f0010, 0xffef8030, ASR_IMM5 },  // LSR  <Rd>, <Rm> #<const>} imm3:imm2\r
+  { "LSR",  0xfa20f000, 0xffe0f0f0, ASR_3REG },  // LSR  <Rd>, <Rn>, <Rm> \r
+  { "ROR",  0xea4f0030, 0xffef8030, ASR_IMM5 },  // ROR  <Rd>, <Rm> #<const>} imm3:imm2\r
+  { "ROR",  0xfa60f000, 0xffe0f0f0, ASR_3REG },  // ROR  <Rd>, <Rn>, <Rm> \r
+\r
+  { "BFC",  0xf36f0000, 0xffff8010, BFC_THUMB2 },   // BFC  <Rd>, #<lsb>, #<width>\r
+  { "BIC",  0xf3600000, 0xfff08010, BFC_THUMB2 },   // BIC  <Rn>, <Rd>, #<lsb>, #<width>\r
+  { "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 },   // SBFX <Rn>, <Rd>, #<lsb>, #<width>\r
+  { "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 },   // UBFX <Rn>, <Rd>, #<lsb>, #<width>\r
+\r
+  { "CPD",  0xee000000, 0xff000010, CPD_THUMB2 },  // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
+  { "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 },  // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
+\r
+  { "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX\r
+\r
+  { "CLZ",   0xfab0f080, 0xfff0f0f0, THUMB2_2REGS },  // CLZ    <Rd>,<Rm>\r
+  { "MOV",   0xec4f0000, 0xfff0f0f0, THUMB2_2REGS },  // MOV    <Rd>,<Rm>\r
+  { "MOVS",  0xec5f0000, 0xfff0f0f0, THUMB2_2REGS },  // MOVS   <Rd>,<Rm>\r
+  { "RBIT",  0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS },  // RBIT   <Rd>,<Rm>\r
+  { "REV",   0xfb90f080, 0xfff0f0f0, THUMB2_2REGS },  // REV    <Rd>,<Rm>\r
+  { "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS },  // REV16  <Rd>,<Rm>\r
+  { "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS },  // REVSH  <Rd>,<Rm>\r
+  { "RRX",   0xea4f0030, 0xfffff0f0, THUMB2_2REGS },  // RRX    <Rd>,<Rm>\r
+  { "RRXS",  0xea5f0030, 0xfffff0f0, THUMB2_2REGS },  // RRXS   <Rd>,<Rm>\r
+\r
+  { "MLA",   0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "MLS",   0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>\r
+\r
+\r
+  { "SMLABB",  0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLABT",  0xfb100010, 0xfff000f0, THUMB2_4REGS }, // SMLABT   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLABB",  0xfb100020, 0xfff000f0, THUMB2_4REGS }, // SMLATB   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLATT",  0xfb100030, 0xfff000f0, THUMB2_4REGS }, // SMLATT   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLAWB",  0xfb300000, 0xfff000f0, THUMB2_4REGS },// SMLAWB   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLAWT",  0xfb300010, 0xfff000f0, THUMB2_4REGS },// SMLAWT   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLSD",   0xfb400000, 0xfff000f0, THUMB2_4REGS },// SMLSD    <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLSDX",  0xfb400010, 0xfff000f0, THUMB2_4REGS },// SMLSDX   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMMLA",   0xfb500000, 0xfff000f0, THUMB2_4REGS },// SMMLA    <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMMLAR",  0xfb500010, 0xfff000f0, THUMB2_4REGS },// SMMLAR   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMMLS",   0xfb600000, 0xfff000f0, THUMB2_4REGS },// SMMLS    <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMMLSR",  0xfb600010, 0xfff000f0, THUMB2_4REGS },// SMMLSR   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "USADA8",  0xfb700000, 0xfff000f0, THUMB2_4REGS },// USADA8   <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLAD",   0xfb200000, 0xfff000f0, THUMB2_4REGS },// SMLAD    <Rd>, <Rn>, <Rm>, <Ra>\r
+  { "SMLADX",  0xfb200010, 0xfff000f0, THUMB2_4REGS },// SMLADX   <Rd>, <Rn>, <Rm>, <Ra>\r
+\r
+\r
   { "B",    0xf0008000, 0xf800d000, B_T3  },             // B<c> <label>\r
   { "B",    0xf0009000, 0xf800d000, B_T4  },             // B<c> <label>\r
   { "BL",   0xf000d000, 0xf800d000, B_T4  },             // BL<c> <label>\r
@@ -405,9 +470,10 @@ DisassembleThumbInstruction (
   UINT32  Offset;\r
   UINT16  Rd, Rn, Rm, Rt, Rt2;\r
   BOOLEAN H1, H2, imod;\r
-  UINT32  PC, Target;\r
+  UINT32  PC, Target, msbit, lsbit;\r
   CHAR8   *Cond;\r
   BOOLEAN S, J1, J2, P, U, W;\r
+  UINT32  coproc, opc1, opc2, CRd, CRn, CRm; \r
 \r
   OpCodePtr = *OpCodePtrPtr;\r
   OpCode = **OpCodePtrPtr;\r
@@ -441,7 +507,7 @@ DisassembleThumbInstruction (
         return;\r
       case LOAD_STORE_FORMAT1_H:\r
         // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]\r
-        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3f);   \r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3e);   \r
         return;\r
       case LOAD_STORE_FORMAT1_B:\r
         // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]\r
@@ -739,21 +805,47 @@ DisassembleThumbInstruction (
           Buf[Offset - 3] = 'S';  // assume %-6a\r
         }\r
         Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
-        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, #0x%x", gReg[Rd], gReg[Rn], Target); \r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #0x%x", gReg[Rd], gReg[Rn], Target); \r
         return;\r
 \r
       case ADD_IMM5:\r
-        // ADC  <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2\r
+        // ADC{S}  <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2\r
         if ((OpCode32 & BIT20) == BIT20) {\r
           Buf[Offset - 3] = 'S';  // assume %-6a\r
         }\r
         Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
-        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, %a", gReg[Rd], gReg[Rn], gReg[Rm]); \r
+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm]); \r
         if (Target != 0) {\r
           AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); \r
         }\r
         return;\r
 \r
+      case ADD_IMM5_2REG:\r
+        // CMP  <Rn>, <Rm> {,LSL #<const>} imm3:imm2\r
+        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rn], gReg[Rm]); \r
+        if (Target != 0) {\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); \r
+        }\r
+\r
+\r
+      case ASR_IMM5:\r
+        // ARS  <Rd>, <Rm> #<const>} imm3:imm2\r
+        if ((OpCode32 & BIT20) == BIT20) {\r
+          Buf[Offset - 3] = 'S';  // assume %-6a\r
+        }\r
+        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a #%d", gReg[Rd], gReg[Rm], Target); \r
+        return;\r
+\r
+      case ASR_3REG:\r
+        // ARS  <Rd>, <Rn>, <Rm>\r
+        if ((OpCode32 & BIT20) == BIT20) {\r
+          Buf[Offset - 3] = 'S';  // assume %-6a\r
+        }\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a %a", gReg[Rd], gReg[Rn], gReg[Rm]); \r
+        return;\r
+\r
       case ADR_THUMB2:\r
         // ADDR <Rd>, <label>\r
         Target = (OpCode32 & 0xff) | ((OpCode32 >> 8) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
@@ -766,16 +858,52 @@ DisassembleThumbInstruction (
         return;\r
 \r
       case CMN_THUMB2:\r
-        // CMN <Rn>, <Rm>, {,<shift> #<const>}\r
-        if ((OpCode32 & BIT20) == BIT20) {\r
-          Buf[Offset - 3] = 'S';  // assume %-6a\r
+        // CMN <Rn>, #<const>}\r
+        Target = (OpCode32 & 0xff) | ((OpCode >> 4) && 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rn], Target); \r
+        return;\r
+\r
+      case BFC_THUMB2:\r
+        // BFI <Rd>, <Rn>, #<lsb>, #<width>\r
+        msbit = OpCode32 & 0x1f;\r
+        lsbit = ((OpCode32 >> 6) & 3) | ((OpCode >> 10) &  0x1c);\r
+        if ((Rn == 0xf) & (AsciiStrCmp (gOpThumb2[Index].Start, "BFC") == 0)){\r
+          // BFC <Rd>, #<lsb>, #<width>\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #%d, #%d", gReg[Rd], lsbit, msbit - lsbit + 1); \r
+        } else if (AsciiStrCmp (gOpThumb2[Index].Start, "BFI") == 0) {\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit - lsbit + 1); \r
+        } else {\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit + 1); \r
         }\r
-        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
-        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a", gReg[Rn], gReg[Rm]); \r
-        if (Target != 0) {\r
-          AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); \r
+        return;\r
+\r
+      case CPD_THUMB2:\r
+        // <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
+        coproc = (OpCode32 >> 8)  & 0xf;\r
+        opc1   = (OpCode32 >> 20) & 0xf;\r
+        opc2   = (OpCode32 >> 5)  & 0x7;\r
+        CRd    = (OpCode32 >> 12) & 0xf;\r
+        CRn    = (OpCode32 >> 16) & 0xf;\r
+        CRm    = OpCode32 & 0xf;\r
+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,c%d,c%d,c%d", coproc, opc1, CRd, CRn, CRm);\r
+        if (opc2 != 0) {\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);\r
         }\r
         return;\r
+\r
+      case THUMB2_2REGS:\r
+        // <Rd>, <Rm>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd], gReg[Rm]);\r
+        return;\r
+\r
+      case THUMB2_4REGS:\r
+        // <Rd>, <Rn>, <Rm>, <Ra>\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm], gReg[Rt]);\r
+        return;\r
+\r
+      case THUMB2_NO_ARGS:\r
+      default:\r
+        break;\r
       }\r
     }\r
   }\r