]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
More disasm work.
[mirror_edk2.git] / ArmPkg / Library / ArmDisassemblerLib / ThumbDisassembler.c
CommitLineData
6f72e28d 1/** @file\r
b32fecd2 2 Thumb Dissassembler. Still a work in progress.\r
3\r
4 Wrong output is a bug, so please fix it. \r
5 Hex output means there is not yet an entry or a decode bug.\r
6 gOpThumb[] are Thumb 16-bit, and gOpThumb2[] work on the 32-bit \r
7 16-bit stream of Thumb2 instruction. Then there are big case \r
8 statements to print everything out. If you are adding instructions\r
9 try to reuse existing case entries if possible.\r
6f72e28d 10\r
11 Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
12 \r
13 All rights reserved. This program and the accompanying materials\r
14 are licensed and made available under the terms and conditions of the BSD License\r
15 which accompanies this distribution. The full text of the license may be found at\r
16 http://opensource.org/licenses/bsd-license.php\r
17\r
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
20\r
21**/\r
22\r
23#include <Base.h>\r
24#include <Library/BaseLib.h>\r
eeb78924 25#include <Library/DebugLib.h>\r
6f72e28d 26#include <Library/PrintLib.h>\r
27\r
7c34497d 28extern CHAR8 *gCondition[];\r
29\r
6f72e28d 30extern CHAR8 *gReg[];\r
31\r
b32fecd2 32// Thumb address modes\r
6f72e28d 33#define LOAD_STORE_FORMAT1 1\r
eeb78924 34#define LOAD_STORE_FORMAT1_H 101\r
35#define LOAD_STORE_FORMAT1_B 111 \r
6f72e28d 36#define LOAD_STORE_FORMAT2 2\r
37#define LOAD_STORE_FORMAT3 3\r
38#define LOAD_STORE_FORMAT4 4\r
39#define LOAD_STORE_MULTIPLE_FORMAT1 5 \r
7c34497d 40#define PUSH_FORMAT 6 \r
41#define POP_FORMAT 106 \r
6f72e28d 42#define IMMED_8 7\r
43#define CONDITIONAL_BRANCH 8\r
44#define UNCONDITIONAL_BRANCH 9\r
45#define UNCONDITIONAL_BRANCH_SHORT 109\r
46#define BRANCH_EXCHANGE 10\r
47#define DATA_FORMAT1 11\r
48#define DATA_FORMAT2 12\r
49#define DATA_FORMAT3 13\r
50#define DATA_FORMAT4 14\r
51#define DATA_FORMAT5 15\r
52#define DATA_FORMAT6_SP 16\r
53#define DATA_FORMAT6_PC 116\r
54#define DATA_FORMAT7 17\r
55#define DATA_FORMAT8 19\r
56#define CPS_FORMAT 20\r
57#define ENDIAN_FORMAT 21\r
b32fecd2 58#define DATA_CBZ 22\r
59#define ADR_FORMAT 23\r
60\r
61// Thumb2 address modes\r
7c34497d 62#define B_T3 200\r
63#define B_T4 201\r
64#define BL_T2 202\r
b32fecd2 65#define POP_T2 203\r
66#define POP_T3 204\r
67#define STM_FORMAT 205\r
68#define LDM_REG_IMM12_SIGNED 206\r
69#define LDM_REG_IMM12_LSL 207\r
70#define LDM_REG_IMM8 208\r
71#define LDM_REG_IMM12 209\r
72#define LDM_REG_INDIRECT_LSL 210\r
73#define LDM_REG_IMM8_SIGNED 211\r
74#define LDRD_REG_IMM8 212\r
75#define LDREXB 213\r
76#define LDREXD 214\r
77#define SRS_FORMAT 215\r
78#define RFE_FORMAT 216\r
79#define LDRD_REG_IMM8_SIGNED 217\r
eeb78924 80#define ADD_IMM12 218\r
81#define ADD_IMM5 219\r
82#define ADR_THUMB2 220\r
83#define CMN_THUMB2 221\r
c5c902da 84#define ASR_IMM5 222\r
85#define ASR_3REG 223\r
86#define BFC_THUMB2 224\r
87#define CDP_THUMB2 225\r
88#define THUMB2_NO_ARGS 226\r
89#define THUMB2_2REGS 227\r
90#define ADD_IMM5_2REG 228\r
91#define CPD_THUMB2 229\r
92#define THUMB2_4REGS 230\r
fef52726 93#define ADD_IMM12_1REG 231\r
94#define THUMB2_IMM16 232\r
95#define MRC_THUMB2 233 \r
96#define MRRC_THUMB2 234 \r
97#define THUMB2_MRS 235\r
98#define THUMB2_MSR 236\r
99\r
100\r
c5c902da 101\r
6f72e28d 102\r
103typedef struct {\r
104 CHAR8 *Start;\r
105 UINT32 OpCode;\r
106 UINT32 Mask;\r
107 UINT32 AddressMode;\r
108} THUMB_INSTRUCTIONS;\r
109\r
097bd461 110THUMB_INSTRUCTIONS gOpThumb[] = {\r
6f72e28d 111// Thumb 16-bit instrucitons\r
b32fecd2 112// Op Mask Format\r
6f72e28d 113 { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r
b32fecd2 114 { "ADR", 0xa000, 0xf800, ADR_FORMAT }, // ADR <Rd>, <label>\r
6f72e28d 115 { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r
116 { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r
117 { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },\r
118 { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9\r
119 { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },\r
7c34497d 120 { "ADD" , 0xa800, 0xf800, DATA_FORMAT6_SP }, \r
121 { "ADD" , 0xb000, 0xff80, DATA_FORMAT7 },\r
6f72e28d 122\r
123 { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },\r
124\r
125 { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },\r
126 { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },\r
127\r
128 { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH },\r
7c34497d 129 { "B" , 0xe000, 0xf800, UNCONDITIONAL_BRANCH_SHORT },\r
6f72e28d 130 { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },\r
7c34497d 131 { "BX" , 0x4700, 0xff87, BRANCH_EXCHANGE },\r
6f72e28d 132\r
133 { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },\r
134 { "BKPT", 0xdf00, 0xff00, IMMED_8 },\r
b32fecd2 135 { "CBZ", 0xb100, 0xfd00, DATA_CBZ },\r
136 { "CBNZ", 0xb900, 0xfd00, DATA_CBZ },\r
6f72e28d 137 { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },\r
138\r
7c34497d 139 { "CMP" , 0x2800, 0xf800, DATA_FORMAT3 },\r
6f72e28d 140 { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },\r
141 { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },\r
142\r
143 { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },\r
7c34497d 144 { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r
6f72e28d 145 { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r
146\r
147 { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
148 { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r
149 { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
150 { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r
151 { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r
eeb78924 152 { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B },\r
6f72e28d 153 { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r
eeb78924 154 { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H },\r
6f72e28d 155 { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r
156 { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r
157 { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r
158 \r
7c34497d 159 { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 }, // LSL with imm5 == 0 is a MOVS, so this must go before LSL\r
6f72e28d 160 { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },\r
161 { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r
162 { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r
163 { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r
c5c902da 164 { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 }, // LSRS <Rd>, <Rm>, #<imm5>\r
6f72e28d 165\r
7c34497d 166 { "MOVS", 0x2000, 0xf800, DATA_FORMAT3 },\r
6f72e28d 167 { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r
168 { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r
169\r
170 { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r
171 { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
172 { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r
173 { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
7c34497d 174 { "POP" , 0xbc00, 0xfe00, POP_FORMAT },\r
175 { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT },\r
176\r
6f72e28d 177 { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 },\r
178 { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },\r
179 { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },\r
180\r
7c34497d 181 { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
182 { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
183 { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },\r
6f72e28d 184\r
185 { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
186 { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r
187 { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r
188 { "STR" , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r
189 { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r
eeb78924 190 { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B },\r
6f72e28d 191 { "STRB" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
eeb78924 192 { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H },\r
6f72e28d 193 { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r
194\r
195 { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r
196 { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r
197 { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r
198 { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r
199\r
200 { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r
201 { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r
202 { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r
203 { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r
204 { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r
205 { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r
b32fecd2 206\r
097bd461 207};\r
208\r
097bd461 209THUMB_INSTRUCTIONS gOpThumb2[] = {\r
b32fecd2 210//Instruct OpCode OpCode Mask Addressig Mode\r
eeb78924 211 \r
c5c902da 212 { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2 }, // ADDR <Rd>, <label> ;Needs to go before ADDW \r
213 { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2 }, // CMN <Rn>, #<const> ;Needs to go before ADD\r
214 { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>}\r
215 { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>\r
216 { "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>\r
217 { "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>}\r
218 { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>\r
219 { "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG }, // TST <Rn>, <Rm> {,<shift> #<const>}\r
eeb78924 220\r
fef52726 221 { "MOV", 0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV <Rd>, #<const>\r
222 { "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 }, // MOVW <Rd>, #<const>\r
223 { "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 }, // MOVT <Rd>, #<const>\r
224 \r
eeb78924 225 { "ADC", 0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S} <Rd>, <Rn>, #<const>\r
226 { "ADC", 0xeb400000, 0xffe08000, ADD_IMM5 }, // ADC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
227 { "ADD", 0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S} <Rd>, <Rn>, #<const>\r
228 { "ADD", 0xeb000000, 0xffe08000, ADD_IMM5 }, // ADD{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
229 { "ADDW", 0xf2000000, 0xfbe08000, ADD_IMM12 }, // ADDW{S} <Rd>, <Rn>, #<const>\r
230 { "AND", 0xf0000000, 0xfbe08000, ADD_IMM12 }, // AND{S} <Rd>, <Rn>, #<const>\r
231 { "AND", 0xea000000, 0xffe08000, ADD_IMM5 }, // AND{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
232 { "BIC", 0xf0200000, 0xfbe08000, ADD_IMM12 }, // BIC{S} <Rd>, <Rn>, #<const>\r
233 { "BIC", 0xea200000, 0xffe08000, ADD_IMM5 }, // BIC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
234 { "EOR", 0xf0800000, 0xfbe08000, ADD_IMM12 }, // EOR{S} <Rd>, <Rn>, #<const>\r
235 { "EOR", 0xea800000, 0xffe08000, ADD_IMM5 }, // EOR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
236 { "ORN", 0xf0600000, 0xfbe08000, ADD_IMM12 }, // ORN{S} <Rd>, <Rn>, #<const>\r
237 { "ORN", 0xea600000, 0xffe08000, ADD_IMM5 }, // ORN{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
238 { "ORR", 0xf0400000, 0xfbe08000, ADD_IMM12 }, // ORR{S} <Rd>, <Rn>, #<const>\r
239 { "ORR", 0xea400000, 0xffe08000, ADD_IMM5 }, // ORR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
240 { "RSB", 0xf1c00000, 0xfbe08000, ADD_IMM12 }, // RSB{S} <Rd>, <Rn>, #<const>\r
241 { "RSB", 0xebc00000, 0xffe08000, ADD_IMM5 }, // RSB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
242 { "SBC", 0xf1600000, 0xfbe08000, ADD_IMM12 }, // SBC{S} <Rd>, <Rn>, #<const>\r
243 { "SBC", 0xeb600000, 0xffe08000, ADD_IMM5 }, // SBC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
244 { "SUB", 0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S} <Rd>, <Rn>, #<const>\r
245 { "SUB", 0xeba00000, 0xffe08000, ADD_IMM5 }, // SUB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}\r
246\r
c5c902da 247 { "ASR", 0xea4f0020, 0xffef8030, ASR_IMM5 }, // ARS <Rd>, <Rm> #<const>} imm3:imm2\r
248 { "ASR", 0xfa40f000, 0xffe0f0f0, ASR_3REG }, // ARS <Rd>, <Rn>, <Rm> \r
249 { "LSR", 0xea4f0010, 0xffef8030, ASR_IMM5 }, // LSR <Rd>, <Rm> #<const>} imm3:imm2\r
250 { "LSR", 0xfa20f000, 0xffe0f0f0, ASR_3REG }, // LSR <Rd>, <Rn>, <Rm> \r
251 { "ROR", 0xea4f0030, 0xffef8030, ASR_IMM5 }, // ROR <Rd>, <Rm> #<const>} imm3:imm2\r
252 { "ROR", 0xfa60f000, 0xffe0f0f0, ASR_3REG }, // ROR <Rd>, <Rn>, <Rm> \r
253\r
254 { "BFC", 0xf36f0000, 0xffff8010, BFC_THUMB2 }, // BFC <Rd>, #<lsb>, #<width>\r
255 { "BIC", 0xf3600000, 0xfff08010, BFC_THUMB2 }, // BIC <Rn>, <Rd>, #<lsb>, #<width>\r
256 { "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 }, // SBFX <Rn>, <Rd>, #<lsb>, #<width>\r
257 { "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 }, // UBFX <Rn>, <Rd>, #<lsb>, #<width>\r
258\r
259 { "CPD", 0xee000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
260 { "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
261\r
fef52726 262 { "MRC", 0xee100000, 0xff100000, MRC_THUMB2 }, // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
263 { "MRC2", 0xfe100000, 0xff100000, MRC_THUMB2 }, // MRC2 <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
264 { "MRRC", 0xec500000, 0xfff00000, MRRC_THUMB2 }, // MRRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>\r
265 { "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 }, // MRR2 <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>\r
266\r
267 { "MRS", 0xf3ef8000, 0xfffff0ff, THUMB2_MRS }, // MRS <Rd>, CPSR\r
268 { "MSR", 0xf3808000, 0xfff0fcff, THUMB2_MSR }, // MSR CPSR_fs, <Rn>\r
269\r
c5c902da 270 { "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX\r
271\r
272 { "CLZ", 0xfab0f080, 0xfff0f0f0, THUMB2_2REGS }, // CLZ <Rd>,<Rm>\r
273 { "MOV", 0xec4f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOV <Rd>,<Rm>\r
274 { "MOVS", 0xec5f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOVS <Rd>,<Rm>\r
275 { "RBIT", 0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS }, // RBIT <Rd>,<Rm>\r
276 { "REV", 0xfb90f080, 0xfff0f0f0, THUMB2_2REGS }, // REV <Rd>,<Rm>\r
277 { "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS }, // REV16 <Rd>,<Rm>\r
278 { "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS }, // REVSH <Rd>,<Rm>\r
279 { "RRX", 0xea4f0030, 0xfffff0f0, THUMB2_2REGS }, // RRX <Rd>,<Rm>\r
280 { "RRXS", 0xea5f0030, 0xfffff0f0, THUMB2_2REGS }, // RRXS <Rd>,<Rm>\r
281\r
282 { "MLA", 0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>\r
283 { "MLS", 0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>\r
284\r
285\r
286 { "SMLABB", 0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB <Rd>, <Rn>, <Rm>, <Ra>\r
287 { "SMLABT", 0xfb100010, 0xfff000f0, THUMB2_4REGS }, // SMLABT <Rd>, <Rn>, <Rm>, <Ra>\r
288 { "SMLABB", 0xfb100020, 0xfff000f0, THUMB2_4REGS }, // SMLATB <Rd>, <Rn>, <Rm>, <Ra>\r
289 { "SMLATT", 0xfb100030, 0xfff000f0, THUMB2_4REGS }, // SMLATT <Rd>, <Rn>, <Rm>, <Ra>\r
fef52726 290 { "SMLAWB", 0xfb300000, 0xfff000f0, THUMB2_4REGS }, // SMLAWB <Rd>, <Rn>, <Rm>, <Ra>\r
291 { "SMLAWT", 0xfb300010, 0xfff000f0, THUMB2_4REGS }, // SMLAWT <Rd>, <Rn>, <Rm>, <Ra>\r
292 { "SMLSD", 0xfb400000, 0xfff000f0, THUMB2_4REGS }, // SMLSD <Rd>, <Rn>, <Rm>, <Ra>\r
293 { "SMLSDX", 0xfb400010, 0xfff000f0, THUMB2_4REGS }, // SMLSDX <Rd>, <Rn>, <Rm>, <Ra>\r
294 { "SMMLA", 0xfb500000, 0xfff000f0, THUMB2_4REGS }, // SMMLA <Rd>, <Rn>, <Rm>, <Ra>\r
295 { "SMMLAR", 0xfb500010, 0xfff000f0, THUMB2_4REGS }, // SMMLAR <Rd>, <Rn>, <Rm>, <Ra>\r
296 { "SMMLS", 0xfb600000, 0xfff000f0, THUMB2_4REGS }, // SMMLS <Rd>, <Rn>, <Rm>, <Ra>\r
297 { "SMMLSR", 0xfb600010, 0xfff000f0, THUMB2_4REGS }, // SMMLSR <Rd>, <Rn>, <Rm>, <Ra>\r
298 { "USADA8", 0xfb700000, 0xfff000f0, THUMB2_4REGS }, // USADA8 <Rd>, <Rn>, <Rm>, <Ra>\r
299 { "SMLAD", 0xfb200000, 0xfff000f0, THUMB2_4REGS }, // SMLAD <Rd>, <Rn>, <Rm>, <Ra>\r
300 { "SMLADX", 0xfb200010, 0xfff000f0, THUMB2_4REGS }, // SMLADX <Rd>, <Rn>, <Rm>, <Ra>\r
c5c902da 301\r
302\r
b32fecd2 303 { "B", 0xf0008000, 0xf800d000, B_T3 }, // B<c> <label>\r
304 { "B", 0xf0009000, 0xf800d000, B_T4 }, // B<c> <label>\r
305 { "BL", 0xf000d000, 0xf800d000, B_T4 }, // BL<c> <label>\r
306 { "BLX", 0xf000c000, 0xf800d000, BL_T2 }, // BLX<c> <label>\r
307\r
308 { "POP", 0xe8bd0000, 0xffff2000, POP_T2 }, // POP <registers>\r
309 { "POP", 0xf85d0b04, 0xffff0fff, POP_T3 }, // POP <register>\r
310 { "PUSH", 0xe8ad0000, 0xffffa000, POP_T2 }, // PUSH <registers>\r
311 { "PUSH", 0xf84d0d04, 0xffff0fff, POP_T3 }, // PUSH <register>\r
312 { "STM" , 0xe8800000, 0xffd0a000, STM_FORMAT }, // STM <Rn>{!},<registers>\r
313 { "STMDB", 0xe9800000, 0xffd0a000, STM_FORMAT }, // STMDB <Rn>{!},<registers>\r
314 { "LDM" , 0xe8900000, 0xffd02000, STM_FORMAT }, // LDM <Rn>{!},<registers>\r
315 { "LDMDB", 0xe9100000, 0xffd02000, STM_FORMAT }, // LDMDB <Rn>{!},<registers>\r
6f72e28d 316 \r
b32fecd2 317 { "LDR", 0xf8d00000, 0xfff00000, LDM_REG_IMM12 }, // LDR <rt>, [<rn>, {, #<imm12>]}\r
318 { "LDRB", 0xf8900000, 0xfff00000, LDM_REG_IMM12 }, // LDRB <rt>, [<rn>, {, #<imm12>]}\r
319 { "LDRH", 0xf8b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRH <rt>, [<rn>, {, #<imm12>]}\r
320 { "LDRSB", 0xf9900000, 0xfff00000, LDM_REG_IMM12 }, // LDRSB <rt>, [<rn>, {, #<imm12>]}\r
321 { "LDRSH", 0xf9b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRSH <rt>, [<rn>, {, #<imm12>]}\r
322\r
323 { "LDR", 0xf85f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDR <Rt>, <label> \r
324 { "LDRB", 0xf81f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRB <Rt>, <label> \r
325 { "LDRH", 0xf83f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRH <Rt>, <label> \r
326 { "LDRSB", 0xf91f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label> \r
327 { "LDRSH", 0xf93f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label> \r
6f72e28d 328 \r
b32fecd2 329 { "LDR", 0xf8500000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDR <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
330 { "LDRB", 0xf8100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRB <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
331 { "LDRH", 0xf8300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRH <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
332 { "LDRSB", 0xf9100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSB <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
333 { "LDRSH", 0xf9300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSH <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
334\r
335 { "LDR", 0xf8500800, 0xfff00800, LDM_REG_IMM8 }, // LDR <rt>, [<rn>, {, #<imm8>]}\r
336 { "LDRBT", 0xf8100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRBT <rt>, [<rn>, {, #<imm8>]}\r
337 { "LDRHT", 0xf8300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]}\r
338 { "LDRSB", 0xf9900800, 0xfff00800, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]} {!} form? \r
339 { "LDRSBT",0xf9100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHBT <rt>, [<rn>, {, #<imm8>]} {!} form? \r
340 { "LDRSH" ,0xf9300800, 0xfff00800, LDM_REG_IMM8 }, // LDRSH <rt>, [<rn>, {, #<imm8>]} \r
341 { "LDRSHT",0xf9300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRSHT <rt>, [<rn>, {, #<imm8>]} \r
342 { "LDRT", 0xf8500e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRT <rt>, [<rn>, {, #<imm8>]} \r
343\r
344 { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}\r
345 { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8 }, // LDRD <rt>, <rt2>, <label>\r
346 \r
347 { "LDREX", 0xe8500f00, 0xfff00f00, LDM_REG_IMM8 }, // LDREX <Rt>, [Rn, {#imm8}]] \r
348 { "LDREXB", 0xe8d00f4f, 0xfff00fff, LDREXB }, // LDREXB <Rt>, [<Rn>] \r
349 { "LDREXH", 0xe8d00f5f, 0xfff00fff, LDREXB }, // LDREXH <Rt>, [<Rn>] \r
350 \r
351 { "LDREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // LDREXD <Rt>, <Rt2>, [<Rn>] \r
6f72e28d 352\r
b32fecd2 353 { "STR", 0xf8c00000, 0xfff00000, LDM_REG_IMM12 }, // STR <rt>, [<rn>, {, #<imm12>]} \r
354 { "STRB", 0xf8800000, 0xfff00000, LDM_REG_IMM12 }, // STRB <rt>, [<rn>, {, #<imm12>]}\r
355 { "STRH", 0xf8a00000, 0xfff00000, LDM_REG_IMM12 }, // STRH <rt>, [<rn>, {, #<imm12>]}\r
356 \r
357 { "STR", 0xf8400000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STR <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
358 { "STRB", 0xf8000000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRB <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
359 { "STRH", 0xf8200000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRH <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
6f72e28d 360\r
b32fecd2 361 { "STR", 0xf8400800, 0xfff00800, LDM_REG_IMM8 }, // STR <rt>, [<rn>, {, #<imm8>]}\r
362 { "STRH", 0xf8200800, 0xfff00800, LDM_REG_IMM8 }, // STRH <rt>, [<rn>, {, #<imm8>]}\r
363 { "STRBT", 0xf8000e00, 0xfff00f00, LDM_REG_IMM8 }, // STRBT <rt>, [<rn>, {, #<imm8>]}\r
364 { "STRHT", 0xf8200e00, 0xfff00f00, LDM_REG_IMM8 }, // STRHT <rt>, [<rn>, {, #<imm8>]}\r
365 { "STRT", 0xf8400e00, 0xfff00f00, LDM_REG_IMM8 }, // STRT <rt>, [<rn>, {, #<imm8>]} \r
6f72e28d 366\r
b32fecd2 367 { "STRD", 0xe8400000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // STRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}\r
6f72e28d 368\r
b32fecd2 369 { "STREX", 0xe8400f00, 0xfff00f00, LDM_REG_IMM8 }, // STREX <Rt>, [Rn, {#imm8}]] \r
370 { "STREXB", 0xe8c00f4f, 0xfff00fff, LDREXB }, // STREXB <Rd>, <Rt>, [<Rn>] \r
371 { "STREXH", 0xe8c00f5f, 0xfff00fff, LDREXB }, // STREXH <Rd>, <Rt>, [<Rn>] \r
372 \r
373 { "STREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // STREXD <Rd>, <Rt>, <Rt2>, [<Rn>] \r
6f72e28d 374\r
b32fecd2 375 { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode>\r
376 { "SRS" , 0xe98dc000, 0xffdffff0, SRS_FORMAT }, // SRS{IA}<c> SP{!},#<mode>\r
377 { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!}\r
378 { "RFE" , 0xe990c000, 0xffd0ffff, RFE_FORMAT } // RFE{IA}<c> <Rn>{!}\r
7c34497d 379};\r
6f72e28d 380\r
eeb78924 381CHAR8 *gShiftType[] = {\r
382 "LSL",\r
383 "LSR",\r
384 "ASR",\r
385 "ROR"\r
386};\r
387\r
6f72e28d 388CHAR8 mThumbMregListStr[4*15 + 1];\r
389\r
390CHAR8 *\r
391ThumbMRegList (\r
7c34497d 392 UINT32 RegBitMask\r
6f72e28d 393 )\r
394{\r
395 UINTN Index, Start, End;\r
396 CHAR8 *Str;\r
397 BOOLEAN First;\r
398 \r
399 Str = mThumbMregListStr;\r
400 *Str = '\0';\r
401 AsciiStrCat (Str, "{");\r
eeb78924 402 \r
7c34497d 403 for (Index = 0, First = TRUE; Index <= 15; Index++) {\r
404 if ((RegBitMask & (1 << Index)) != 0) {\r
6f72e28d 405 Start = End = Index;\r
7c34497d 406 for (Index++; ((RegBitMask & (1 << Index)) != 0) && (Index <= 9); Index++) {\r
6f72e28d 407 End = Index;\r
408 }\r
409 \r
410 if (!First) {\r
411 AsciiStrCat (Str, ",");\r
412 } else {\r
413 First = FALSE;\r
414 }\r
415 \r
416 if (Start == End) {\r
7c34497d 417 AsciiStrCat (Str, gReg[Start]);\r
6f72e28d 418 } else {\r
419 AsciiStrCat (Str, gReg[Start]);\r
420 AsciiStrCat (Str, "-");\r
7c34497d 421 AsciiStrCat (Str, gReg[End]);\r
6f72e28d 422 }\r
423 }\r
424 }\r
425 if (First) {\r
426 AsciiStrCat (Str, "ERROR");\r
427 }\r
428 AsciiStrCat (Str, "}");\r
429 \r
430 // BugBug: Make caller pass in buffer it is cleaner\r
431 return mThumbMregListStr;\r
432}\r
433\r
434UINT32\r
7c34497d 435SignExtend32 (\r
436 IN UINT32 Data,\r
437 IN UINT32 TopBit\r
6f72e28d 438 )\r
439{\r
7c34497d 440 if (((Data & TopBit) == 0) || (TopBit == BIT31)) {\r
441 return Data;\r
442 }\r
443 \r
444 do {\r
445 TopBit <<= 1;\r
446 Data |= TopBit; \r
447 } while ((TopBit & BIT31) != BIT31);\r
448\r
449 return Data;\r
6f72e28d 450}\r
451\r
eeb78924 452//\r
453// Some instructions specify the PC is always considered aligned \r
454// The PC is after the instruction that is excuting. So you pass\r
455// in the instruction address and you get back the aligned answer\r
456//\r
c639c2de 457UINT32\r
eeb78924 458PCAlign4 (\r
459 IN UINT32 Data\r
460 )\r
461{\r
462 return (Data + 4) & 0xfffffffc;\r
463}\r
464\r
6f72e28d 465/**\r
097bd461 466 Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
467 point to next instructin. \r
468 \r
469 We cheat and only decode instructions that access \r
6f72e28d 470 memory. If the instruction is not found we dump the instruction in hex.\r
471 \r
097bd461 472 @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. \r
473 @param Buf Buffer to sprintf disassembly into.\r
474 @param Size Size of Buf in bytes. \r
f9f937d2 475 @param Extended TRUE dump hex for instruction too.\r
6f72e28d 476 \r
477**/\r
478VOID\r
479DisassembleThumbInstruction (\r
097bd461 480 IN UINT16 **OpCodePtrPtr,\r
6f72e28d 481 OUT CHAR8 *Buf,\r
f9f937d2 482 OUT UINTN Size,\r
483 IN BOOLEAN Extended\r
6f72e28d 484 )\r
485{\r
097bd461 486 UINT16 *OpCodePtr;\r
487 UINT16 OpCode;\r
7c34497d 488 UINT32 OpCode32;\r
6f72e28d 489 UINT32 Index;\r
490 UINT32 Offset;\r
b32fecd2 491 UINT16 Rd, Rn, Rm, Rt, Rt2;\r
6f72e28d 492 BOOLEAN H1, H2, imod;\r
c5c902da 493 UINT32 PC, Target, msbit, lsbit;\r
7c34497d 494 CHAR8 *Cond;\r
b32fecd2 495 BOOLEAN S, J1, J2, P, U, W;\r
c5c902da 496 UINT32 coproc, opc1, opc2, CRd, CRn, CRm; \r
6f72e28d 497\r
097bd461 498 OpCodePtr = *OpCodePtrPtr;\r
499 OpCode = **OpCodePtrPtr;\r
500 \r
501 // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.\r
7c34497d 502 OpCode32 = (((UINT32)OpCode) << 16) | *(OpCodePtr + 1);\r
097bd461 503\r
6f72e28d 504 // These register names match branch form, but not others\r
505 Rd = OpCode & 0x7;\r
506 Rn = (OpCode >> 3) & 0x7;\r
507 Rm = (OpCode >> 6) & 0x7;\r
508 H1 = (OpCode & BIT7) != 0;\r
509 H2 = (OpCode & BIT6) != 0;\r
510 imod = (OpCode & BIT4) != 0;\r
7c34497d 511 PC = (UINT32)(UINTN)OpCodePtr;\r
6f72e28d 512\r
097bd461 513 // Increment by the minimum instruction size, Thumb2 could be bigger\r
514 *OpCodePtrPtr += 1;\r
515 \r
516 for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
517 if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {\r
f9f937d2 518 if (Extended) {\r
7c34497d 519 Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode, gOpThumb[Index].Start); \r
f9f937d2 520 } else {\r
7c34497d 521 Offset = AsciiSPrint (Buf, Size, "%-6a", gOpThumb[Index].Start); \r
f9f937d2 522 }\r
097bd461 523 switch (gOpThumb[Index].AddressMode) {\r
6f72e28d 524 case LOAD_STORE_FORMAT1:\r
525 // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r
7c34497d 526 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 4) & 0x7c); \r
527 return;\r
eeb78924 528 case LOAD_STORE_FORMAT1_H:\r
529 // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r
c5c902da 530 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3e); \r
eeb78924 531 return;\r
532 case LOAD_STORE_FORMAT1_B:\r
533 // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r
534 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 6) & 0x1f); \r
535 return;\r
536\r
6f72e28d 537 case LOAD_STORE_FORMAT2:\r
538 // A6.5.1 <Rd>, [<Rn>, <Rm>]\r
7c34497d 539 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, Rn, Rm); \r
540 return;\r
6f72e28d 541 case LOAD_STORE_FORMAT3:\r
542 // A6.5.1 <Rd>, [PC, #<8_bit_offset>]\r
7c34497d 543 Target = (OpCode & 0xff) << 2;\r
eeb78924 544 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x] ;0x%08x", (OpCode >> 8) & 7, Target, PCAlign4 (PC) + Target); \r
7c34497d 545 return;\r
6f72e28d 546 case LOAD_STORE_FORMAT4:\r
7c34497d 547 // Rt, [SP, #imm8]\r
548 Target = (OpCode & 0xff) << 2;\r
eeb78924 549 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, Target); \r
7c34497d 550 return;\r
6f72e28d 551 \r
552 case LOAD_STORE_MULTIPLE_FORMAT1:\r
7c34497d 553 // <Rn>!, {r0-r7}\r
554 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode & 0xff)); \r
555 return;\r
556 \r
557 case POP_FORMAT:\r
558 // POP {r0-r7,pc}\r
559 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT15 : 0))); \r
560 return;\r
561\r
562 case PUSH_FORMAT:\r
563 // PUSH {r0-r7,lr}\r
564 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT14 : 0))); \r
565 return;\r
566\r
6f72e28d 567 \r
568 case IMMED_8:\r
569 // A6.7 <immed_8>\r
570 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff); \r
7c34497d 571 return;\r
6f72e28d 572\r
573 case CONDITIONAL_BRANCH:\r
574 // A6.3.1 B<cond> <target_address>\r
7c34497d 575 // Patch in the condition code. A little hack but based on "%-6a"\r
576 Cond = gCondition[(OpCode >> 8) & 0xf];\r
577 Buf[Offset-5] = *Cond++;\r
578 Buf[Offset-4] = *Cond;\r
579 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0xff) << 1, BIT8)); \r
580 return;\r
6f72e28d 581 case UNCONDITIONAL_BRANCH_SHORT:\r
582 // A6.3.2 B <target_address>\r
7c34497d 583 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0x3ff) << 1, BIT11)); \r
584 return;\r
585 \r
6f72e28d 586 case BRANCH_EXCHANGE:\r
587 // A6.3.3 BX|BLX <Rm>\r
7c34497d 588 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[Rn | (H2 ? 8:0)]); \r
589 return;\r
6f72e28d 590\r
591 case DATA_FORMAT1:\r
592 // A6.4.3 <Rd>, <Rn>, <Rm>\r
593 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm); \r
7c34497d 594 return;\r
6f72e28d 595 case DATA_FORMAT2:\r
596 // A6.4.3 <Rd>, <Rn>, #3_bit_immed\r
597 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm); \r
7c34497d 598 return;\r
6f72e28d 599 case DATA_FORMAT3:\r
7c34497d 600 // A6.4.3 <Rd>|<Rn>, #imm8\r
601 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, #0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r
602 return;\r
6f72e28d 603 case DATA_FORMAT4:\r
604 // A6.4.3 <Rd>|<Rm>, #immed_5\r
605 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f); \r
7c34497d 606 return;\r
6f72e28d 607 case DATA_FORMAT5:\r
608 // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs>\r
609 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn); \r
7c34497d 610 return;\r
6f72e28d 611 case DATA_FORMAT6_SP:\r
612 // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
7c34497d 613 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2); \r
614 return;\r
6f72e28d 615 case DATA_FORMAT6_PC:\r
616 // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
7c34497d 617 AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2); \r
618 return;\r
6f72e28d 619 case DATA_FORMAT7:\r
620 // A6.4.3 SP, SP, #<7_Bit_immed>\r
7c34497d 621 AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp, 0x%x", (OpCode & 0x7f)*4); \r
622 return;\r
6f72e28d 623 case DATA_FORMAT8:\r
624 // A6.4.3 <Rd>|<Rn>, <Rm>\r
625 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]); \r
7c34497d 626 return;\r
6f72e28d 627 \r
628 case CPS_FORMAT:\r
629 // A7.1.24\r
630 AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a", ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f"); \r
7c34497d 631 return;\r
6f72e28d 632\r
633 case ENDIAN_FORMAT:\r
634 // A7.1.24\r
635 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE"); \r
7c34497d 636 return;\r
b32fecd2 637\r
638 case DATA_CBZ:\r
639 // CB{N}Z <Rn>, <Lable>\r
640 Target = ((OpCode >> 2) & 0x3e) | (((OpCode & BIT9) == BIT9) ? BIT6 : 0);\r
641 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[Rd], PC + 4 + Target); \r
642 return;\r
643\r
644 case ADR_FORMAT:\r
645 // ADR <Rd>, <Label>\r
646 Target = (OpCode & 0xff) << 2;\r
eeb78924 647 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[(OpCode >> 8) & 7], PCAlign4 (PC) + Target); \r
b32fecd2 648 return;\r
6f72e28d 649 }\r
650 }\r
651 }\r
7c34497d 652\r
653 \r
097bd461 654 // Thumb2 are 32-bit instructions\r
655 *OpCodePtrPtr += 1;\r
b32fecd2 656 Rt = (OpCode32 >> 12) & 0xf;\r
657 Rt2 = (OpCode32 >> 8) & 0xf;\r
eeb78924 658 Rd = (OpCode32 >> 8) & 0xf;\r
b32fecd2 659 Rm = (OpCode32 & 0xf);\r
660 Rn = (OpCode32 >> 16) & 0xf;\r
097bd461 661 for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
662 if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {\r
f9f937d2 663 if (Extended) {\r
c7ed09e3 664 Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode32, gOpThumb2[Index].Start); \r
f9f937d2 665 } else {\r
c7ed09e3 666 Offset = AsciiSPrint (Buf, Size, " %-6a", gOpThumb2[Index].Start); \r
f9f937d2 667 }\r
668 switch (gOpThumb2[Index].AddressMode) {\r
7c34497d 669 case B_T3:\r
670 Cond = gCondition[(OpCode32 >> 22) & 0xf];\r
671 Buf[Offset-5] = *Cond++;\r
672 Buf[Offset-4] = *Cond;\r
673 // S:J2:J1:imm6:imm11:0\r
674 Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3f000);\r
c7ed09e3 675 Target |= ((OpCode32 & BIT11) == BIT11)? BIT19 : 0; // J2\r
676 Target |= ((OpCode32 & BIT13) == BIT13)? BIT18 : 0; // J1\r
677 Target |= ((OpCode32 & BIT26) == BIT26)? BIT20 : 0; // S\r
678 Target = SignExtend32 (Target, BIT20);\r
679 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target); \r
7c34497d 680 return;\r
681 case B_T4:\r
682 // S:I1:I2:imm10:imm11:0\r
683 Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3ff000);\r
c7ed09e3 684 S = (OpCode32 & BIT26) == BIT26;\r
685 J1 = (OpCode32 & BIT13) == BIT13;\r
686 J2 = (OpCode32 & BIT11) == BIT11;\r
687 Target |= (!(J2 ^ S) ? BIT22 : 0); // I2\r
688 Target |= (!(J1 ^ S) ? BIT23 : 0); // I1\r
689 Target |= (S ? BIT24 : 0); // S\r
690 Target = SignExtend32 (Target, BIT24);\r
691 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target); \r
7c34497d 692 return;\r
693\r
694 case BL_T2:\r
eeb78924 695 // BLX S:I1:I2:imm10:imm11:0\r
696 Target = ((OpCode32 << 1) & 0xffc) + ((OpCode32 >> 4) & 0x3ff000);\r
c7ed09e3 697 S = (OpCode32 & BIT26) == BIT26;\r
698 J1 = (OpCode32 & BIT13) == BIT13;\r
699 J2 = (OpCode32 & BIT11) == BIT11;\r
700 Target |= (!(J2 ^ S) ? BIT23 : 0); // I2\r
701 Target |= (!(J1 ^ S) ? BIT24 : 0); // I1\r
702 Target |= (S ? BIT25 : 0); // S\r
703 Target = SignExtend32 (Target, BIT25);\r
eeb78924 704 AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PCAlign4 (PC) + Target); \r
7c34497d 705 return;\r
b32fecd2 706\r
707 case POP_T2:\r
708 // <reglist> some must be zero, handled in table\r
709 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList (OpCode32 & 0xffff));\r
710 return;\r
711\r
712 case POP_T3:\r
713 // <register> \r
714 AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[(OpCode32 >> 12) & 0xf]);\r
715 return;\r
716\r
717 case STM_FORMAT:\r
718 // <Rn>{!}, <registers>\r
719 W = (OpCode32 & BIT21) == BIT21;\r
eeb78924 720 AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, %a", gReg[(OpCode32 >> 16) & 0xf], W ? "!":"", ThumbMRegList (OpCode32 & 0xffff));\r
b32fecd2 721 return;\r
722\r
723 case LDM_REG_IMM12_SIGNED:\r
724 // <rt>, <label>\r
725 Target = OpCode32 & 0xfff; \r
726 if ((OpCode32 & BIT23) == 0) {\r
727 // U == 0 means subtrack, U == 1 means add\r
728 Target = -Target;\r
729 }\r
eeb78924 730 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[(OpCode32 >> 12) & 0xf], PCAlign4 (PC) + Target);\r
b32fecd2 731 return;\r
732\r
733 case LDM_REG_INDIRECT_LSL:\r
734 // <rt>, [<rn>, <rm> {, LSL #<imm2>]}\r
735 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a, %a", gReg[Rt], gReg[Rn], gReg[Rm]);\r
736 if (((OpCode32 >> 4) && 3) == 0) {\r
737 AsciiSPrint (&Buf[Offset], Size - Offset, "]");\r
738 } else {\r
739 AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL #%d]", (OpCode32 >> 4) && 3);\r
740 }\r
741 return;\r
742 \r
743 case LDM_REG_IMM12:\r
744 // <rt>, [<rn>, {, #<imm12>]}\r
745 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);\r
746 if ((OpCode32 && 0xfff) == 0) {\r
747 AsciiSPrint (&Buf[Offset], Size - Offset, "]");\r
748 } else {\r
749 AsciiSPrint (&Buf[Offset], Size - Offset, ", #0x%x]", OpCode32 & 0xfff);\r
750 }\r
751 return;\r
752\r
753 case LDM_REG_IMM8:\r
eeb78924 754 ASSERT (FALSE);\r
b32fecd2 755 // <rt>, [<rn>, {, #<imm8>}]{!}\r
756 W = (OpCode32 & BIT8) == BIT8;\r
757 U = (OpCode32 & BIT9) == BIT9;\r
758 P = (OpCode32 & BIT10) == BIT10;\r
759 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);\r
760 if (P) {\r
761 if ((OpCode32 && 0xff) == 0) {\r
762 AsciiSPrint (&Buf[Offset], Size - Offset, "]%a", W?"!":"");\r
763 } else {\r
eeb78924 764 AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", OpCode32 & 0xff, U?"":"-" , W?"!":"");\r
b32fecd2 765 }\r
766 } else {\r
eeb78924 767 AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x]", OpCode32 & 0xff, U?"":"-");\r
b32fecd2 768 }\r
769 return;\r
770\r
771 case LDRD_REG_IMM8_SIGNED:\r
772 // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}\r
773 P = (OpCode32 & BIT24) == BIT24; // index = P\r
774 U = (OpCode32 & BIT23) == BIT23; \r
775 W = (OpCode32 & BIT21) == BIT21;\r
776 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, [%a", gReg[Rt], gReg[Rt2], gReg[Rn]);\r
777 if (P) {\r
778 if ((OpCode32 && 0xff) == 0) {\r
779 AsciiSPrint (&Buf[Offset], Size - Offset, "]");\r
780 } else {\r
781 AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-", (OpCode32 & 0xff) << 2, W?"!":"");\r
782 }\r
783 } else {\r
784 if ((OpCode32 && 0xff) != 0) {\r
785 AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x", U?"":"-", (OpCode32 & 0xff) << 2);\r
786 }\r
787 }\r
788 return;\r
789\r
790 case LDRD_REG_IMM8: \r
791 // LDRD <rt>, <rt2>, <label> \r
792 Target = (OpCode32 & 0xff) << 2; \r
793 if ((OpCode32 & BIT23) == 0) {\r
794 // U == 0 means subtrack, U == 1 means add\r
795 Target = -Target;\r
796 }\r
797 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rt], gReg[Rt2], PC + 4 + Target);\r
798 return;\r
799\r
800 case LDREXB:\r
801 // LDREXB <Rt>, [Rn]\r
802 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a]", gReg[Rt], gReg[Rn]);\r
803 return;\r
804\r
805 case LDREXD:\r
806 // LDREXD <Rt>, <Rt2>, [<Rn>]\r
807 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, [%a]", gReg[Rt], gReg[Rt2], gReg[Rn]);\r
808 return;\r
809 \r
810 case SRS_FORMAT:\r
811 // SP{!}, #<mode>\r
812 W = (OpCode32 & BIT21) == BIT21;\r
813 AsciiSPrint (&Buf[Offset], Size - Offset, " SP%a, #0x%x", W?"!":"", OpCode32 & 0x1f);\r
814 return;\r
815\r
816 case RFE_FORMAT:\r
817 // <Rn>{!}\r
c639c2de 818 W = (OpCode32 & BIT21) == BIT21;\r
b32fecd2 819 AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, #0x%x", gReg[Rn], W?"!":"");\r
820 return;\r
eeb78924 821 \r
822 case ADD_IMM12:\r
823 // ADD{S} <Rd>, <Rn>, #<const> i:imm3:imm8\r
824 if ((OpCode32 & BIT20) == BIT20) {\r
825 Buf[Offset - 3] = 'S'; // assume %-6a\r
826 }\r
827 Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
c5c902da 828 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #0x%x", gReg[Rd], gReg[Rn], Target); \r
eeb78924 829 return;\r
830\r
fef52726 831 case ADD_IMM12_1REG:\r
832 // MOV{S} <Rd>, #<const> i:imm3:imm8\r
833 if ((OpCode32 & BIT20) == BIT20) {\r
834 Buf[Offset - 3] = 'S'; // assume %-6a\r
835 }\r
836 Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
837 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target); \r
838 return;\r
839\r
840 case THUMB2_IMM16:\r
841 // MOVW <Rd>, #<const> i:imm3:imm8\r
842 Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
843 Target |= ((OpCode32 >> 4) & 0xf0000);\r
844 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target); \r
845 return;\r
846\r
eeb78924 847 case ADD_IMM5:\r
c5c902da 848 // ADC{S} <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2\r
eeb78924 849 if ((OpCode32 & BIT20) == BIT20) {\r
850 Buf[Offset - 3] = 'S'; // assume %-6a\r
851 }\r
852 Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
c5c902da 853 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm]); \r
eeb78924 854 if (Target != 0) {\r
855 AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); \r
856 }\r
857 return;\r
858\r
c5c902da 859 case ADD_IMM5_2REG:\r
860 // CMP <Rn>, <Rm> {,LSL #<const>} imm3:imm2\r
861 Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
862 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rn], gReg[Rm]); \r
863 if (Target != 0) {\r
864 AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); \r
865 }\r
866\r
867\r
868 case ASR_IMM5:\r
869 // ARS <Rd>, <Rm> #<const>} imm3:imm2\r
870 if ((OpCode32 & BIT20) == BIT20) {\r
871 Buf[Offset - 3] = 'S'; // assume %-6a\r
872 }\r
873 Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);\r
874 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a #%d", gReg[Rd], gReg[Rm], Target); \r
875 return;\r
876\r
877 case ASR_3REG:\r
878 // ARS <Rd>, <Rn>, <Rm>\r
879 if ((OpCode32 & BIT20) == BIT20) {\r
880 Buf[Offset - 3] = 'S'; // assume %-6a\r
881 }\r
882 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a %a", gReg[Rd], gReg[Rn], gReg[Rm]); \r
883 return;\r
884\r
eeb78924 885 case ADR_THUMB2:\r
886 // ADDR <Rd>, <label>\r
887 Target = (OpCode32 & 0xff) | ((OpCode32 >> 8) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
888 if ((OpCode & (BIT23 | BIT21)) == (BIT23 | BIT21)) {\r
889 Target = PCAlign4 (PC) - Target;\r
890 } else {\r
891 Target = PCAlign4 (PC) + Target;\r
892 }\r
893 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, 0x%08x", gReg[Rd], Target); \r
894 return;\r
b32fecd2 895\r
eeb78924 896 case CMN_THUMB2:\r
c5c902da 897 // CMN <Rn>, #<const>}\r
898 Target = (OpCode32 & 0xff) | ((OpCode >> 4) && 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);\r
899 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rn], Target); \r
900 return;\r
901\r
902 case BFC_THUMB2:\r
903 // BFI <Rd>, <Rn>, #<lsb>, #<width>\r
904 msbit = OpCode32 & 0x1f;\r
905 lsbit = ((OpCode32 >> 6) & 3) | ((OpCode >> 10) & 0x1c);\r
906 if ((Rn == 0xf) & (AsciiStrCmp (gOpThumb2[Index].Start, "BFC") == 0)){\r
907 // BFC <Rd>, #<lsb>, #<width>\r
908 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #%d, #%d", gReg[Rd], lsbit, msbit - lsbit + 1); \r
909 } else if (AsciiStrCmp (gOpThumb2[Index].Start, "BFI") == 0) {\r
910 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit - lsbit + 1); \r
911 } else {\r
912 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit + 1); \r
eeb78924 913 }\r
c5c902da 914 return;\r
915\r
916 case CPD_THUMB2:\r
917 // <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>\r
918 coproc = (OpCode32 >> 8) & 0xf;\r
919 opc1 = (OpCode32 >> 20) & 0xf;\r
920 opc2 = (OpCode32 >> 5) & 0x7;\r
921 CRd = (OpCode32 >> 12) & 0xf;\r
922 CRn = (OpCode32 >> 16) & 0xf;\r
923 CRm = OpCode32 & 0xf;\r
924 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,c%d,c%d,c%d", coproc, opc1, CRd, CRn, CRm);\r
925 if (opc2 != 0) {\r
926 AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);\r
eeb78924 927 }\r
928 return;\r
c5c902da 929\r
fef52726 930 case MRC_THUMB2:\r
931 // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>\r
932 coproc = (OpCode32 >> 8) & 0xf;\r
933 opc1 = (OpCode32 >> 20) & 0xf;\r
934 opc2 = (OpCode32 >> 5) & 0x7;\r
935 CRn = (OpCode32 >> 16) & 0xf;\r
936 CRm = OpCode32 & 0xf;\r
937 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,c%d,c%d", coproc, opc1, gReg[Rt], CRn, CRm);\r
938 if (opc2 != 0) {\r
939 AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);\r
940 }\r
941 return; \r
942\r
943 case MRRC_THUMB2:\r
944 // MRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>,<opc2>\r
945 coproc = (OpCode32 >> 8) & 0xf;\r
946 opc1 = (OpCode32 >> 20) & 0xf;\r
947 CRn = (OpCode32 >> 16) & 0xf;\r
948 CRm = OpCode32 & 0xf;\r
949 Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,%a,c%d", coproc, opc1, gReg[Rt], gReg[Rt2], CRm);\r
950 return; \r
951\r
c5c902da 952 case THUMB2_2REGS:\r
953 // <Rd>, <Rm>\r
954 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd], gReg[Rm]);\r
955 return;\r
956\r
957 case THUMB2_4REGS:\r
958 // <Rd>, <Rn>, <Rm>, <Ra>\r
959 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm], gReg[Rt]);\r
960 return;\r
961\r
fef52726 962 case THUMB2_MRS:\r
963 // MRS <Rd>, CPSR\r
964 AsciiSPrint (&Buf[Offset], Size - Offset, " %a, CPSR", gReg[Rd]);\r
965 return;\r
966 \r
967 case THUMB2_MSR:\r
968 // MRS CPSR_<fields>, <Rd>\r
969 Target = (OpCode32 >> 10) & 3;\r
970 AsciiSPrint (&Buf[Offset], Size - Offset, " CPSR_%a%a, %a", (Target & 2) == 0 ? "":"f", (Target & 1) == 0 ? "":"s", gReg[Rd]);\r
971 return;\r
972\r
c5c902da 973 case THUMB2_NO_ARGS:\r
974 default:\r
975 break;\r
f9f937d2 976 }\r
097bd461 977 }\r
978 }\r
7c34497d 979\r
980 AsciiSPrint (Buf, Size, "0x%08x", OpCode32);\r
6f72e28d 981}\r
982\r
097bd461 983\r
984\r
985VOID\r
986DisassembleArmInstruction (\r
987 IN UINT32 **OpCodePtr,\r
988 OUT CHAR8 *Buf,\r
f9f937d2 989 OUT UINTN Size,\r
990 IN BOOLEAN Extended\r
097bd461 991 );\r
992\r
993\r
994/**\r
995 Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
996 point to next instructin. \r
997 \r
998 We cheat and only decode instructions that access \r
999 memory. If the instruction is not found we dump the instruction in hex.\r
1000 \r
1001 @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. \r
1002 @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream\r
f9f937d2 1003 @param Extended TRUE dump hex for instruction too.\r
097bd461 1004 @param Buf Buffer to sprintf disassembly into.\r
1005 @param Size Size of Buf in bytes. \r
1006 \r
1007**/\r
1008VOID\r
1009DisassembleInstruction (\r
1010 IN UINT8 **OpCodePtr,\r
1011 IN BOOLEAN Thumb,\r
f9f937d2 1012 IN BOOLEAN Extended,\r
097bd461 1013 OUT CHAR8 *Buf,\r
1014 OUT UINTN Size\r
1015 )\r
1016{\r
1017 if (Thumb) {\r
f9f937d2 1018 DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, Extended);\r
097bd461 1019 } else {\r
f9f937d2 1020 DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended);\r
097bd461 1021 }\r
1022}\r
6f72e28d 1023 \r