]>
Commit | Line | Data |
---|---|---|
1 | /** @file\r | |
2 | Default exception handler\r | |
3 | \r | |
4 | Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r | |
5 | \r | |
6 | All rights reserved. This program and the accompanying materials\r | |
7 | are licensed and made available under the terms and conditions of the BSD License\r | |
8 | which accompanies this distribution. The full text of the license may be found at\r | |
9 | http://opensource.org/licenses/bsd-license.php\r | |
10 | \r | |
11 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | \r | |
14 | **/\r | |
15 | \r | |
16 | #include <Base.h>\r | |
17 | #include <Library/BaseLib.h>\r | |
18 | #include <Library/PrintLib.h>\r | |
19 | \r | |
20 | extern CHAR8 *gReg[];\r | |
21 | \r | |
22 | #define LOAD_STORE_FORMAT1 1\r | |
23 | #define LOAD_STORE_FORMAT2 2\r | |
24 | #define LOAD_STORE_FORMAT3 3\r | |
25 | #define LOAD_STORE_FORMAT4 4\r | |
26 | #define LOAD_STORE_MULTIPLE_FORMAT1 5 \r | |
27 | #define LOAD_STORE_MULTIPLE_FORMAT2 6 \r | |
28 | #define IMMED_8 7\r | |
29 | #define CONDITIONAL_BRANCH 8\r | |
30 | #define UNCONDITIONAL_BRANCH 9\r | |
31 | #define UNCONDITIONAL_BRANCH_SHORT 109\r | |
32 | #define BRANCH_EXCHANGE 10\r | |
33 | #define DATA_FORMAT1 11\r | |
34 | #define DATA_FORMAT2 12\r | |
35 | #define DATA_FORMAT3 13\r | |
36 | #define DATA_FORMAT4 14\r | |
37 | #define DATA_FORMAT5 15\r | |
38 | #define DATA_FORMAT6_SP 16\r | |
39 | #define DATA_FORMAT6_PC 116\r | |
40 | #define DATA_FORMAT7 17\r | |
41 | #define DATA_FORMAT8 19\r | |
42 | #define CPS_FORMAT 20\r | |
43 | #define ENDIAN_FORMAT 21\r | |
44 | \r | |
45 | \r | |
46 | typedef struct {\r | |
47 | CHAR8 *Start;\r | |
48 | UINT32 OpCode;\r | |
49 | UINT32 Mask;\r | |
50 | UINT32 AddressMode;\r | |
51 | } THUMB_INSTRUCTIONS;\r | |
52 | \r | |
53 | THUMB_INSTRUCTIONS gOp[] = {\r | |
54 | // Thumb 16-bit instrucitons\r | |
55 | // Op Mask Format\r | |
56 | { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r | |
57 | \r | |
58 | { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r | |
59 | { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r | |
60 | { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },\r | |
61 | { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9\r | |
62 | { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },\r | |
63 | { "ADD" , 0xa100, 0xf100, DATA_FORMAT6_SP }, \r | |
64 | { "ADD" , 0xb000, 0xff10, DATA_FORMAT7 },\r | |
65 | \r | |
66 | { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },\r | |
67 | \r | |
68 | { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },\r | |
69 | { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },\r | |
70 | \r | |
71 | { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH },\r | |
72 | { "B" , 0xe000, 0xf100, UNCONDITIONAL_BRANCH_SHORT },\r | |
73 | { "BL" , 0xf100, 0xf100, UNCONDITIONAL_BRANCH },\r | |
74 | { "BLX" , 0xe100, 0xf100, UNCONDITIONAL_BRANCH },\r | |
75 | { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },\r | |
76 | { "BX" , 0x4700, 0xff80, BRANCH_EXCHANGE },\r | |
77 | \r | |
78 | { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },\r | |
79 | { "BKPT", 0xdf00, 0xff00, IMMED_8 },\r | |
80 | { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },\r | |
81 | \r | |
82 | { "CMP" , 0x2800, 0xf100, DATA_FORMAT3 },\r | |
83 | { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },\r | |
84 | { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },\r | |
85 | \r | |
86 | { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },\r | |
87 | { "CPY" , 0x4600, 0xff00, DATA_FORMAT8 },\r | |
88 | { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r | |
89 | \r | |
90 | { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r | |
91 | { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r | |
92 | { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
93 | { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r | |
94 | { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r | |
95 | { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1 },\r | |
96 | { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
97 | { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1 },\r | |
98 | { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
99 | { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
100 | { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
101 | \r | |
102 | { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },\r | |
103 | { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r | |
104 | { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r | |
105 | { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r | |
106 | \r | |
107 | { "MOV" , 0x2000, 0xf800, DATA_FORMAT3 },\r | |
108 | { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r | |
109 | { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r | |
110 | \r | |
111 | { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r | |
112 | { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r | |
113 | { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r | |
114 | { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r | |
115 | { "POP" , 0xbc00, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r | |
116 | { "POP" , 0xe400, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r | |
117 | \r | |
118 | { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 },\r | |
119 | { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },\r | |
120 | { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },\r | |
121 | \r | |
122 | { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r | |
123 | { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },\r | |
124 | { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },\r | |
125 | \r | |
126 | { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r | |
127 | { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r | |
128 | { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
129 | { "STR" , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r | |
130 | { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r | |
131 | { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1 },\r | |
132 | { "STRB" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
133 | { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1 },\r | |
134 | { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r | |
135 | \r | |
136 | { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r | |
137 | { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r | |
138 | { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r | |
139 | { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r | |
140 | \r | |
141 | { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r | |
142 | { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r | |
143 | { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r | |
144 | { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r | |
145 | { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r | |
146 | { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r | |
147 | \r | |
148 | #if 0 \r | |
149 | ,\r | |
150 | \r | |
151 | // 32-bit Thumb instructions op1 01\r | |
152 | \r | |
153 | // 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx Load/store multiple\r | |
154 | { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode>\r | |
155 | { "SRS" , 0xe98dc000, 0xffdffff0, SRS_IA_FORMAT }, // SRS{IA}<c> SP{!},#<mode>\r | |
156 | { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!}\r | |
157 | { "RFE" , 0xe990c000, 0xffd0ffff, RFE_IA_FORMAT }, // RFE{IA}<c> <Rn>{!}\r | |
158 | \r | |
159 | { "STM" , 0xe8800000, 0xffd00000, STM_FORMAT }, // STM<c>.W <Rn>{!},<registers>\r | |
160 | { "LDM" , 0xe8900000, 0xffd00000, STM_FORMAT }, // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r | |
161 | { "POP" , 0xe8bd0000, 0xffff2000, REGLIST_FORMAT }, // POP<c>.W <registers> >1 register\r | |
162 | { "POP" , 0xf85d0b04, 0xffff0fff, RT_FORMAT }, // POP<c>.W <registers> 1 register\r | |
163 | \r | |
164 | { "STMDB", 0xe9000000, 0xffd00000, STM_FORMAT }, // STMDB\r | |
165 | { "PUSH" , 0xe8bd0000, 0xffffa000, REGLIST_FORMAT }, // PUSH<c>.W <registers> >1 register\r | |
166 | { "PUSH" , 0xf84d0b04, 0xffff0fff, RT_FORMAT }, // PUSH<c>.W <registers> 1 register\r | |
167 | { "LDMDB", 0xe9102000, 0xffd02000, STM_FORMAT }, // LDMDB<c> <Rn>{!},<registers>\r | |
168 | \r | |
169 | // 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx Load/store dual,\r | |
170 | { "STREX" , 0xe0400000, 0xfff000f0, 3REG_IMM8_FORMAT }, // STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm>}]\r | |
171 | { "STREXB", 0xe8c00f40, 0xfff00ff0, 3REG_FORMAT }, // STREXB<c> <Rd>,<Rt>,[<Rn>]\r | |
172 | { "STREXD", 0xe8c00070, 0xfff000f0, 4REG_FORMAT }, // STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>]\r | |
173 | { "STREXH", 0xe8c00f70, 0xfff00ff0, 3REG_FORMAT }, // STREXH<c> <Rd>,<Rt>,[<Rn>]\r | |
174 | { "STRH", 0xf8c00000, 0xfff00000, 2REG_IMM8_FORMAT }, // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]\r | |
175 | { "STRH", 0xf8200000, 0xfff00000, }, // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r | |
176 | \r | |
177 | \r | |
178 | \r | |
179 | // 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx Data-processing\r | |
180 | // 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor\r | |
181 | \r | |
182 | // 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing modified immediate\r | |
183 | // 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing plain immediate\r | |
184 | // 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx Branches\r | |
185 | \r | |
186 | // 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx Store single data item\r | |
187 | // 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx SIMD or load/store\r | |
188 | // 1111 100x x001 xxxx xxxx xxxx xxxx xxxx Load byte, memory hints \r | |
189 | // 1111 100x x011 xxxx xxxx xxxx xxxx xxxx Load halfword, memory hints\r | |
190 | // 1111 100x x101 xxxx xxxx xxxx xxxx xxxx Load word \r | |
191 | \r | |
192 | // 1111 1 010 xxxx xxxx xxxx xxxx xxxx xxxx Data-processing register\r | |
193 | // 1111 1 011 0xxx xxxx xxxx xxxx xxxx xxxx Multiply\r | |
194 | // 1111 1 011 1xxx xxxx xxxx xxxx xxxx xxxx Long Multiply\r | |
195 | // 1111 1 1xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor \r | |
196 | #endif\r | |
197 | };\r | |
198 | \r | |
199 | \r | |
200 | CHAR8 mThumbMregListStr[4*15 + 1];\r | |
201 | \r | |
202 | CHAR8 *\r | |
203 | ThumbMRegList (\r | |
204 | UINT32 OpCode\r | |
205 | )\r | |
206 | {\r | |
207 | UINTN Index, Start, End;\r | |
208 | CHAR8 *Str;\r | |
209 | BOOLEAN First;\r | |
210 | \r | |
211 | Str = mThumbMregListStr;\r | |
212 | *Str = '\0';\r | |
213 | AsciiStrCat (Str, "{");\r | |
214 | // R0 - R7, PC\r | |
215 | for (Index = 0, First = TRUE; Index <= 9; Index++) {\r | |
216 | if ((OpCode & (1 << Index)) != 0) {\r | |
217 | Start = End = Index;\r | |
218 | for (Index++; ((OpCode & (1 << Index)) != 0) && (Index <= 9); Index++) {\r | |
219 | End = Index;\r | |
220 | }\r | |
221 | \r | |
222 | if (!First) {\r | |
223 | AsciiStrCat (Str, ",");\r | |
224 | } else {\r | |
225 | First = FALSE;\r | |
226 | }\r | |
227 | \r | |
228 | if (Start == End) {\r | |
229 | AsciiStrCat (Str, gReg[(Start == 9)?15:Start]);\r | |
230 | AsciiStrCat (Str, ", ");\r | |
231 | } else {\r | |
232 | AsciiStrCat (Str, gReg[Start]);\r | |
233 | AsciiStrCat (Str, "-");\r | |
234 | AsciiStrCat (Str, gReg[(End == 9)?15:End]);\r | |
235 | }\r | |
236 | }\r | |
237 | }\r | |
238 | if (First) {\r | |
239 | AsciiStrCat (Str, "ERROR");\r | |
240 | }\r | |
241 | AsciiStrCat (Str, "}");\r | |
242 | \r | |
243 | // BugBug: Make caller pass in buffer it is cleaner\r | |
244 | return mThumbMregListStr;\r | |
245 | }\r | |
246 | \r | |
247 | UINT32\r | |
248 | SignExtend (\r | |
249 | IN UINT32 Data\r | |
250 | )\r | |
251 | {\r | |
252 | return 0;\r | |
253 | }\r | |
254 | \r | |
255 | /**\r | |
256 | DEBUG print the faulting instruction. We cheat and only decode instructions that access \r | |
257 | memory. If the instruction is not found we dump the instruction in hex.\r | |
258 | \r | |
259 | @param Insturction ARM instruction to disassemble. \r | |
260 | \r | |
261 | **/\r | |
262 | VOID\r | |
263 | DisassembleThumbInstruction (\r | |
264 | IN UINT16 *OpCodePtr,\r | |
265 | OUT CHAR8 *Buf,\r | |
266 | OUT UINTN Size\r | |
267 | )\r | |
268 | {\r | |
269 | UINT16 OpCode = *OpCodePtr;\r | |
270 | UINT32 Index;\r | |
271 | UINT32 Offset;\r | |
272 | UINT16 Rd, Rn, Rm;\r | |
273 | INT32 target_addr;\r | |
274 | BOOLEAN H1, H2, imod;\r | |
275 | UINT32 PC;\r | |
276 | \r | |
277 | // These register names match branch form, but not others\r | |
278 | Rd = OpCode & 0x7;\r | |
279 | Rn = (OpCode >> 3) & 0x7;\r | |
280 | Rm = (OpCode >> 6) & 0x7;\r | |
281 | H1 = (OpCode & BIT7) != 0;\r | |
282 | H2 = (OpCode & BIT6) != 0;\r | |
283 | imod = (OpCode & BIT4) != 0;\r | |
284 | PC = (UINT32)(UINTN)*OpCodePtr;\r | |
285 | \r | |
286 | for (Index = 0; Index < sizeof (gOp)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r | |
287 | if ((OpCode & gOp[Index].Mask) == gOp[Index].OpCode) {\r | |
288 | Offset = AsciiSPrint (Buf, Size, "%a", gOp[Index].Start); \r | |
289 | switch (gOp[Index].AddressMode) {\r | |
290 | case LOAD_STORE_FORMAT1:\r | |
291 | // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r | |
292 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, (OpCode >> 7) & 7, (OpCode >> 6) & 0x1f); \r | |
293 | break;\r | |
294 | case LOAD_STORE_FORMAT2:\r | |
295 | // A6.5.1 <Rd>, [<Rn>, <Rm>]\r | |
296 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, (OpCode >> 3) & 7, Rm); \r | |
297 | break;\r | |
298 | case LOAD_STORE_FORMAT3:\r | |
299 | // A6.5.1 <Rd>, [PC, #<8_bit_offset>]\r | |
300 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r | |
301 | break;\r | |
302 | case LOAD_STORE_FORMAT4:\r | |
303 | // FIX ME!!!!!\r | |
304 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r | |
305 | break;\r | |
306 | \r | |
307 | case LOAD_STORE_MULTIPLE_FORMAT1:\r | |
308 | // <Rn>!, <registers> \r | |
309 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (!BIT8 & OpCode)); \r | |
310 | break;\r | |
311 | case LOAD_STORE_MULTIPLE_FORMAT2:\r | |
312 | // <Rn>!, <registers> \r | |
313 | // BIT8 is PC \r | |
314 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode)); \r | |
315 | break;\r | |
316 | \r | |
317 | case IMMED_8:\r | |
318 | // A6.7 <immed_8>\r | |
319 | AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff); \r | |
320 | break;\r | |
321 | \r | |
322 | case CONDITIONAL_BRANCH:\r | |
323 | // A6.3.1 B<cond> <target_address>\r | |
324 | AsciiSPrint (&Buf[Offset], Size - Offset, "%a 0x%04x", PC + 4 + SignExtend ((OpCode & 0xff) << 1)); \r | |
325 | break;\r | |
326 | case UNCONDITIONAL_BRANCH_SHORT:\r | |
327 | // A6.3.2 B <target_address>\r | |
328 | AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend ((OpCode & 0x3ff) << 1)); \r | |
329 | break;\r | |
330 | case UNCONDITIONAL_BRANCH:\r | |
331 | // A6.3.2 BL|BLX <target_address> ; Produces two 16-bit instructions \r | |
332 | target_addr = *(OpCodePtr - 1);\r | |
333 | if ((target_addr & 0xf800) == 0xf000) {\r | |
334 | target_addr = ((target_addr & 0x3ff) << 12) | (OpCode & 0x3ff);\r | |
335 | } else {\r | |
336 | target_addr = OpCode & 0x3ff;\r | |
337 | }\r | |
338 | // PC + 2 +/- target_addr\r | |
339 | AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 2 + SignExtend (target_addr)); \r | |
340 | break;\r | |
341 | case BRANCH_EXCHANGE:\r | |
342 | // A6.3.3 BX|BLX <Rm>\r | |
343 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d", gReg[Rn | (H2 ? 8:0)]); \r | |
344 | break;\r | |
345 | \r | |
346 | case DATA_FORMAT1:\r | |
347 | // A6.4.3 <Rd>, <Rn>, <Rm>\r | |
348 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm); \r | |
349 | break;\r | |
350 | case DATA_FORMAT2:\r | |
351 | // A6.4.3 <Rd>, <Rn>, #3_bit_immed\r | |
352 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm); \r | |
353 | break;\r | |
354 | case DATA_FORMAT3:\r | |
355 | // A6.4.3 <Rd>|<Rn>, #8_bit_immed\r | |
356 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", (OpCode >> 8) & 0x7, OpCode & 0xff); \r | |
357 | break;\r | |
358 | case DATA_FORMAT4:\r | |
359 | // A6.4.3 <Rd>|<Rm>, #immed_5\r | |
360 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f); \r | |
361 | break;\r | |
362 | case DATA_FORMAT5:\r | |
363 | // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs>\r | |
364 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn); \r | |
365 | break;\r | |
366 | case DATA_FORMAT6_SP:\r | |
367 | // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r | |
368 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r | |
369 | break;\r | |
370 | case DATA_FORMAT6_PC:\r | |
371 | // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r | |
372 | AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r | |
373 | break;\r | |
374 | case DATA_FORMAT7:\r | |
375 | // A6.4.3 SP, SP, #<7_Bit_immed>\r | |
376 | AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp 0x%x", (OpCode & 0x7f)*4); \r | |
377 | break;\r | |
378 | case DATA_FORMAT8:\r | |
379 | // A6.4.3 <Rd>|<Rn>, <Rm>\r | |
380 | AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]); \r | |
381 | break;\r | |
382 | \r | |
383 | case CPS_FORMAT:\r | |
384 | // A7.1.24\r | |
385 | 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 | |
386 | break;\r | |
387 | \r | |
388 | case ENDIAN_FORMAT:\r | |
389 | // A7.1.24\r | |
390 | AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE"); \r | |
391 | break;\r | |
392 | }\r | |
393 | }\r | |
394 | }\r | |
395 | \r | |
396 | \r | |
397 | }\r | |
398 | \r | |
399 | \r |