]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
ArmPkg/ArmDisassemblerLib: Comment out unused variable
[mirror_edk2.git] / ArmPkg / Library / ArmDisassemblerLib / ThumbDisassembler.c
index 0f4139d5852d6b7ac0a101dc5497352aa18423f9..dfab4cc2e4701c7466dbd636bc4a74740943ce49 100644 (file)
@@ -8,9 +8,9 @@
   statements to print everything out. If you are adding instructions\r
   try to reuse existing case entries if possible.\r
 \r
-  Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
   \r
-  All rights reserved. This program and the accompanying materials\r
+  This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
   http://opensource.org/licenses/bsd-license.php\r
@@ -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
@@ -81,6 +82,24 @@ 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
+#define ADD_IMM12_1REG              231\r
+#define THUMB2_IMM16                232\r
+#define MRC_THUMB2                  233 \r
+#define MRRC_THUMB2                 234 \r
+#define THUMB2_MRS                  235\r
+#define THUMB2_MSR                  236\r
+\r
+\r
+\r
 \r
 typedef struct {\r
   CHAR8   *Start;\r
@@ -92,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
@@ -127,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
@@ -143,6 +162,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
@@ -151,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
@@ -164,35 +184,48 @@ 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
 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
-\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
+  { "MOV",  0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV  <Rd>, #<const>\r
+  { "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 },   // MOVW <Rd>, #<const>\r
+  { "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 },   // MOVT <Rd>, #<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
   { "ADD",  0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S}  <Rd>, <Rn>, #<const>\r
@@ -215,6 +248,62 @@ 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
+  { "MRC",   0xee100000, 0xff100000, MRC_THUMB2 },  // MRC  <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
+  { "MRC2",  0xfe100000, 0xff100000, MRC_THUMB2 },  // MRC2 <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
+  { "MRRC",  0xec500000, 0xfff00000, MRRC_THUMB2 },  // MRRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>\r
+  { "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 },  // MRR2 <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>\r
+\r
+  { "MRS",   0xf3ef8000, 0xfffff0ff, THUMB2_MRS  }, // MRS  <Rd>, CPSR\r
+  { "MSR",   0xf3808000, 0xfff0fcff, THUMB2_MSR  }, // MSR  CPSR_fs, <Rn>\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
@@ -250,7 +339,7 @@ THUMB_INSTRUCTIONS gOpThumb2[] = {
   { "LDR",   0xf8500800, 0xfff00800,  LDM_REG_IMM8 },           // LDR    <rt>, [<rn>, {, #<imm8>]}\r
   { "LDRBT", 0xf8100e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRBT  <rt>, [<rn>, {, #<imm8>]}\r
   { "LDRHT", 0xf8300e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRHT  <rt>, [<rn>, {, #<imm8>]}\r
-  { "LDRSB", 0xf9900800, 0xfff00800,  LDM_REG_IMM8 },           // LDRHT  <rt>, [<rn>, {, #<imm8>]}  {!} form? \r
+  { "LDRSB", 0xf9100800, 0xfff00800,  LDM_REG_IMM8 },           // LDRHT  <rt>, [<rn>, {, #<imm8>]}  {!} form? \r
   { "LDRSBT",0xf9100e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRHBT <rt>, [<rn>, {, #<imm8>]}  {!} form? \r
   { "LDRSH" ,0xf9300800, 0xfff00800,  LDM_REG_IMM8 },           // LDRSH  <rt>, [<rn>, {, #<imm8>]}  \r
   { "LDRSHT",0xf9300e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRSHT <rt>, [<rn>, {, #<imm8>]}   \r
@@ -369,6 +458,7 @@ SignExtend32 (
 // The PC is after the instruction that is excuting. So you pass\r
 // in the instruction address and you get back the aligned answer\r
 //\r
+UINT32\r
 PCAlign4 (\r
   IN  UINT32  Data\r
   )\r
@@ -394,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
@@ -404,9 +495,12 @@ DisassembleThumbInstruction (
   UINT32  Offset;\r
   UINT16  Rd, Rn, Rm, Rt, Rt2;\r
   BOOLEAN H1, H2, imod;\r
-  UINT32  PC, Target;\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
@@ -426,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
@@ -440,7 +542,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
@@ -559,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
@@ -664,7 +791,6 @@ DisassembleThumbInstruction (
         return;\r
 \r
       case LDM_REG_IMM8:\r
-        ASSERT (FALSE);\r
         // <rt>, [<rn>, {, #<imm8>}]{!}\r
         W = (OpCode32 & BIT8) == BIT8;\r
         U = (OpCode32 & BIT9) == BIT9;\r
@@ -674,10 +800,10 @@ DisassembleThumbInstruction (
           if ((OpCode32 && 0xff) == 0) {\r
             AsciiSPrint (&Buf[Offset], Size - Offset, "]%a", W?"!":"");\r
           } else {\r
-            AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", OpCode32 & 0xff, U?"":"-" , W?"!":"");\r
+            AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-" , OpCode32 & 0xff, W?"!":"");\r
           }\r
         } else {\r
-          AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x]", OpCode32 & 0xff, U?"":"-");\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x", U?"":"-", OpCode32 & 0xff);\r
         }\r
         return;\r
 \r
@@ -728,6 +854,7 @@ DisassembleThumbInstruction (
 \r
       case RFE_FORMAT:\r
         // <Rn>{!}\r
+        W = (OpCode32 & BIT21) == BIT21;\r
         AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, #0x%x", gReg[Rn], W?"!":"");\r
         return;\r
       \r
@@ -737,19 +864,61 @@ 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_IMM12_1REG:\r
+        // MOV{S} <Rd>, #<const>   i:imm3:imm8\r
+        if ((OpCode32 & BIT20) == BIT20) {\r
+          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, #0x%x", gReg[Rd], Target); \r
+        return;\r
+\r
+      case THUMB2_IMM16:\r
+        // MOVW <Rd>, #<const>   i:imm3:imm8\r
+        Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
+        Target |= ((OpCode32 >> 4) & 0xf0000);\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], 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
@@ -764,16 +933,85 @@ 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 MRC_THUMB2:\r
+        // MRC  <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
+        coproc = (OpCode32 >> 8)  & 0xf;\r
+        opc1   = (OpCode32 >> 20) & 0xf;\r
+        opc2   = (OpCode32 >> 5)  & 0x7;\r
+        CRn    = (OpCode32 >> 16) & 0xf;\r
+        CRm    = OpCode32 & 0xf;\r
+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,c%d,c%d", coproc, opc1, gReg[Rt], CRn, CRm);\r
+        if (opc2 != 0) {\r
+          AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);\r
+        }\r
+        return;  \r
+\r
+      case MRRC_THUMB2:\r
+        // MRC  <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>,<opc2>\r
+        coproc = (OpCode32 >> 8)  & 0xf;\r
+        opc1   = (OpCode32 >> 20) & 0xf;\r
+        CRn    = (OpCode32 >> 16) & 0xf;\r
+        CRm    = OpCode32 & 0xf;\r
+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,%a,c%d", coproc, opc1, gReg[Rt], gReg[Rt2], CRm);\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_MRS:\r
+        // MRS <Rd>, CPSR\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, CPSR", gReg[Rd]);\r
+        return;\r
+        \r
+      case THUMB2_MSR:\r
+        // MRS CPSR_<fields>, <Rd>\r
+        Target = (OpCode32 >> 10) & 3;\r
+        AsciiSPrint (&Buf[Offset], Size - Offset, " CPSR_%a%a, %a", (Target & 2) == 0 ? "":"f", (Target & 1) == 0 ? "":"s", gReg[Rd]);\r
+        return;\r
+\r
+      case THUMB2_NO_ARGS:\r
+      default:\r
+        break;\r
       }\r
     }\r
   }\r
@@ -802,6 +1040,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
@@ -811,12 +1050,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