]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
Update input of disasmembler to support IfThen construct. Add prototype dos script...
[mirror_edk2.git] / ArmPkg / Library / ArmDisassemblerLib / ThumbDisassembler.c
index c2df0d4c726af5b20e3be7618c8c577570f0392a..75d0f1c687a9e483e3e3a7eec895043aa835f916 100644 (file)
@@ -57,6 +57,7 @@ extern CHAR8 *gReg[];
 #define ENDIAN_FORMAT                21\r
 #define DATA_CBZ                     22\r
 #define ADR_FORMAT                   23\r
+#define IT_BLOCK                     24\r
 \r
 // Thumb2 address modes\r
 #define B_T3                        200\r
@@ -110,7 +111,7 @@ typedef struct {
 THUMB_INSTRUCTIONS gOpThumb[] = {\r
 // Thumb 16-bit instrucitons\r
 //          Op       Mask   Format\r
-  { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r
+  { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },  // ADC <Rndn>, <Rm>\r
   { "ADR",  0xa000, 0xf800, ADR_FORMAT   },  // ADR <Rd>, <label>\r
   { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r
   { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r
@@ -145,15 +146,15 @@ THUMB_INSTRUCTIONS gOpThumb[] = {
   { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r
 \r
   { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
-  { "LDR"   , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r
-  { "LDR"   , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDR"   , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },  // LDR <Rt>, [<Rn> {,#<imm>}]\r
+  { "LDR"   , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]\r
   { "LDR"   , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r
-  { "LDR"   , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r
+  { "LDR"   , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },  // LDR <Rt>, [SP, #<imm>]\r
   { "LDRB"  , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B },\r
-  { "LDRB"  , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDRB"  , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]\r
   { "LDRH"  , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H },\r
   { "LDRH"  , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r
-  { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]\r
   { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r
  \r
   { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 },   // LSL with imm5 == 0 is a MOVS, so this must go before LSL\r
@@ -170,7 +171,7 @@ THUMB_INSTRUCTIONS gOpThumb[] = {
   { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r
   { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
   { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r
-  { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+  { "ORR" , 0x4300, 0xffc0, DATA_FORMAT5 },\r
   { "POP" , 0xbc00, 0xfe00, POP_FORMAT },\r
   { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT },\r
 \r
@@ -183,26 +184,29 @@ THUMB_INSTRUCTIONS gOpThumb[] = {
   { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },\r
 \r
   { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
-  { "STR"   , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r
-  { "STR"   , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r
-  { "STR"   , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r
-  { "STR"   , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r
-  { "STRB"  , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B },\r
-  { "STRB"  , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
-  { "STRH"  , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H },\r
-  { "STRH"  , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r
+  { "STR"   , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },   // STR  <Rt>, [<Rn> {,#<imm>}]\r
+  { "STR"   , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },   // STR  <Rt>, [<Rn>, <Rm>]\r
+  { "STR"   , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },   // STR  <Rt>, [SP, #<imm>]\r
+  { "STRB"  , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B }, // STRB <Rt>, [<Rn>, #<imm5>]\r
+  { "STRB"  , 0x5400, 0xfe00, LOAD_STORE_FORMAT2 },   // STRB <Rt>, [<Rn>, <Rm>]\r
+  { "STRH"  , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H }, // STRH <Rt>, [<Rn>{,#<imm>}]\r
+  { "STRH"  , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },   // STRH <Rt>, [<Rn>, <Rm>]\r
 \r
   { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r
   { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r
   { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r
   { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r
 \r
+  { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+\r
   { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r
   { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r
   { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r
   { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r
   { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r
-  { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r
+  { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 },\r
+\r
+  { "IT",   0xbf00, 0xff00, IT_BLOCK }\r
 \r
 };\r
 \r
@@ -480,6 +484,7 @@ DisassembleThumbInstruction (
   IN  UINT16    **OpCodePtrPtr,\r
   OUT CHAR8     *Buf,\r
   OUT UINTN     Size,\r
+  OUT UINT32    *ItBlock,\r
   IN  BOOLEAN   Extended\r
   )\r
 {\r
@@ -490,10 +495,12 @@ DisassembleThumbInstruction (
   UINT32  Offset;\r
   UINT16  Rd, Rn, Rm, Rt, Rt2;\r
   BOOLEAN H1, H2, imod;\r
+  BOOLEAN ItFlag;\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
+  UINT32  Mask;\r
 \r
   OpCodePtr = *OpCodePtrPtr;\r
   OpCode = **OpCodePtrPtr;\r
@@ -513,6 +520,14 @@ DisassembleThumbInstruction (
   // Increment by the minimum instruction size, Thumb2 could be bigger\r
   *OpCodePtrPtr += 1;\r
   \r
+  // Manage IT Block ItFlag TRUE means we are in an IT block\r
+  if (*ItBlock != 0) {\r
+    ItFlag = TRUE;\r
+    *ItBlock -= 1;\r
+  } else {\r
+    ItFlag = FALSE;\r
+  }\r
+\r
   for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
     if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {\r
       if (Extended) {\r
@@ -646,6 +661,31 @@ DisassembleThumbInstruction (
         Target = (OpCode & 0xff) << 2;\r
         AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[(OpCode >> 8) & 7], PCAlign4 (PC) + Target); \r
         return;\r
+\r
+      case IT_BLOCK:\r
+        // ITSTATE = cond:mask   OpCode[7:4]:OpCode[3:0]\r
+        // ITSTATE[7:5] == cond[3:1]\r
+        // ITSTATE[4] == 1st Instruction cond[0]  \r
+        // ITSTATE[3] == 2st Instruction cond[0]  \r
+        // ITSTATE[2] == 3st Instruction cond[0]  \r
+        // ITSTATE[1] == 4st Instruction cond[0]\r
+        // ITSTATE[0] == 1 4 instruction IT block. 0 means 0,1,2 or 3 instructions\r
+        // 1st one  in ITSTATE low bits defines the number of instructions\r
+        Mask = (OpCode & 0xf);\r
+        if ((Mask & 0x1) == 0x1) {\r
+          *ItBlock = 4;\r
+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E", (Mask & BIT1)?"T":"E");\r
+        } else if ((OpCode & 0x3) == 0x2) {\r
+          *ItBlock = 3;\r
+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E");\r
+        } else if ((OpCode & 0x7) == 0x4) {\r
+          *ItBlock = 2;\r
+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a", (Mask & BIT3)?"T":"E");\r
+        } else if ((OpCode & 0xf) == 0x8) {\r
+          *ItBlock = 1;\r
+        }\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gCondition[(OpCode >> 4) & 0xf]); \r
+        return;\r
       }\r
     }\r
   }\r
@@ -1001,6 +1041,7 @@ DisassembleArmInstruction (
   @param  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.  \r
   @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream\r
   @param  Extended      TRUE dump hex for instruction too.\r
+  @param  ItBlock       Size of IT Block\r
   @param  Buf           Buffer to sprintf disassembly into.\r
   @param  Size          Size of Buf in bytes. \r
   \r
@@ -1010,12 +1051,13 @@ DisassembleInstruction (
   IN  UINT8     **OpCodePtr,\r
   IN  BOOLEAN   Thumb,\r
   IN  BOOLEAN   Extended,\r
+  IN OUT UINT32 *ItBlock,\r
   OUT CHAR8     *Buf,\r
   OUT UINTN     Size\r
   )\r
 {\r
   if (Thumb) {\r
-    DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, Extended);\r
+    DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, &ItBlock, Extended);\r
   } else {\r
     DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended);\r
   }\r