]>
Commit | Line | Data |
---|---|---|
6f72e28d | 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 | |
6f72e28d | 18 | #include <Library/PrintLib.h>\r |
097bd461 | 19 | #include <Library/ArmDisassemblerLib.h>\r |
6f72e28d | 20 | \r |
21 | CHAR8 *gCondition[] = {\r | |
22 | "EQ",\r | |
23 | "NE",\r | |
24 | "CS",\r | |
25 | "CC",\r | |
26 | "MI",\r | |
27 | "PL",\r | |
28 | "VS",\r | |
29 | "VC",\r | |
30 | "HI",\r | |
31 | "LS",\r | |
32 | "GE",\r | |
33 | "LT",\r | |
34 | "GT",\r | |
35 | "LE",\r | |
36 | "",\r | |
37 | "2"\r | |
38 | };\r | |
39 | \r | |
40 | #define COND(_a) gCondition[(_a) >> 28]\r | |
41 | \r | |
42 | CHAR8 *gReg[] = {\r | |
43 | "r0",\r | |
44 | "r1",\r | |
45 | "r2",\r | |
46 | "r3",\r | |
47 | "r4",\r | |
48 | "r5",\r | |
49 | "r6",\r | |
50 | "r7",\r | |
51 | "r8",\r | |
52 | "r9",\r | |
53 | "r10",\r | |
54 | "r11",\r | |
55 | "r12",\r | |
56 | "sp",\r | |
57 | "lr",\r | |
58 | "pc"\r | |
59 | };\r | |
60 | \r | |
61 | CHAR8 *gLdmAdr[] = {\r | |
62 | "DA",\r | |
63 | "IA",\r | |
64 | "DB",\r | |
65 | "IB"\r | |
66 | };\r | |
67 | \r | |
68 | CHAR8 *gLdmStack[] = {\r | |
69 | "FA",\r | |
70 | "FD",\r | |
71 | "EA",\r | |
72 | "ED"\r | |
73 | };\r | |
74 | \r | |
75 | #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])\r | |
76 | \r | |
77 | \r | |
78 | #define SIGN(_U) ((_U) ? "" : "-")\r | |
79 | #define WRITE(_W) ((_W) ? "!" : "")\r | |
80 | #define BYTE(_B) ((_B) ? "B":"")\r | |
81 | #define USER(_B) ((_B) ? "^" : "")\r | |
82 | \r | |
83 | CHAR8 mMregListStr[4*15 + 1];\r | |
84 | \r | |
85 | CHAR8 *\r | |
86 | MRegList (\r | |
87 | UINT32 OpCode\r | |
88 | )\r | |
89 | {\r | |
90 | UINTN Index, Start, End;\r | |
91 | CHAR8 *Str;\r | |
92 | BOOLEAN First;\r | |
93 | \r | |
94 | Str = mMregListStr;\r | |
95 | *Str = '\0';\r | |
96 | AsciiStrCat (Str, "{");\r | |
97 | for (Index = 0, First = TRUE; Index <= 15; Index++) {\r | |
98 | if ((OpCode & (1 << Index)) != 0) {\r | |
99 | Start = End = Index;\r | |
100 | for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {\r | |
101 | End = Index;\r | |
102 | }\r | |
103 | \r | |
104 | if (!First) {\r | |
105 | AsciiStrCat (Str, ",");\r | |
106 | } else {\r | |
107 | First = FALSE;\r | |
108 | }\r | |
109 | \r | |
110 | if (Start == End) {\r | |
111 | AsciiStrCat (Str, gReg[Start]);\r | |
112 | AsciiStrCat (Str, ", ");\r | |
113 | } else {\r | |
114 | AsciiStrCat (Str, gReg[Start]);\r | |
115 | AsciiStrCat (Str, "-");\r | |
116 | AsciiStrCat (Str, gReg[End]);\r | |
117 | }\r | |
118 | }\r | |
119 | }\r | |
120 | if (First) {\r | |
121 | AsciiStrCat (Str, "ERROR");\r | |
122 | }\r | |
123 | AsciiStrCat (Str, "}");\r | |
124 | \r | |
125 | // BugBug: Make caller pass in buffer it is cleaner\r | |
126 | return mMregListStr;\r | |
127 | }\r | |
128 | \r | |
129 | CHAR8 *\r | |
130 | FieldMask (\r | |
131 | IN UINT32 Mask\r | |
132 | )\r | |
133 | {\r | |
134 | return "";\r | |
135 | }\r | |
136 | \r | |
137 | UINT32\r | |
138 | RotateRight (\r | |
139 | IN UINT32 Op,\r | |
140 | IN UINT32 Shift\r | |
141 | )\r | |
142 | {\r | |
143 | return (Op >> Shift) | (Op << (32 - Shift));\r | |
144 | }\r | |
145 | \r | |
146 | \r | |
147 | /**\r | |
097bd461 | 148 | Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r |
149 | point to next instructin. \r | |
150 | \r | |
151 | We cheat and only decode instructions that access \r | |
6f72e28d | 152 | memory. If the instruction is not found we dump the instruction in hex.\r |
153 | \r | |
097bd461 | 154 | @param OpCodePtr Pointer to pointer of ARM instruction to disassemble. \r |
155 | @param Buf Buffer to sprintf disassembly into.\r | |
156 | @param Size Size of Buf in bytes. \r | |
f9f937d2 | 157 | @param Extended TRUE dump hex for instruction too.\r |
6f72e28d | 158 | \r |
159 | **/\r | |
160 | VOID\r | |
161 | DisassembleArmInstruction (\r | |
097bd461 | 162 | IN UINT32 **OpCodePtr,\r |
6f72e28d | 163 | OUT CHAR8 *Buf,\r |
f9f937d2 | 164 | OUT UINTN Size,\r |
165 | IN BOOLEAN Extended\r | |
6f72e28d | 166 | )\r |
167 | {\r | |
097bd461 | 168 | UINT32 OpCode = **OpCodePtr;\r |
6f72e28d | 169 | CHAR8 *Type, *Root;\r |
170 | BOOLEAN I, P, U, B, W, L, S, H;\r | |
171 | UINT32 Rn, Rd, Rm;\r | |
172 | UINT32 imode, offset_8, offset_12;\r | |
173 | UINT32 Index;\r | |
174 | UINT32 shift_imm, shift;\r | |
175 | \r | |
176 | I = (OpCode & BIT25) == BIT25;\r | |
177 | P = (OpCode & BIT24) == BIT24;\r | |
178 | U = (OpCode & BIT23) == BIT23;\r | |
179 | B = (OpCode & BIT22) == BIT22; // Also called S\r | |
180 | W = (OpCode & BIT21) == BIT21; \r | |
181 | L = (OpCode & BIT20) == BIT20;\r | |
182 | S = (OpCode & BIT6) == BIT6;\r | |
183 | H = (OpCode & BIT5) == BIT5;\r | |
184 | Rn = (OpCode >> 16) & 0xf;\r | |
185 | Rd = (OpCode >> 12) & 0xf;\r | |
186 | Rm = (OpCode & 0xf);\r | |
187 | \r | |
f9f937d2 | 188 | \r |
189 | if (Extended) {\r | |
190 | Index = AsciiSPrint (Buf, Size, "0x%08x ", OpCode);\r | |
191 | Buf += Index;\r | |
192 | Size -= Index;\r | |
193 | }\r | |
194 | \r | |
6f72e28d | 195 | // LDREX, STREX\r |
196 | if ((OpCode & 0x0fe000f0) == 0x01800090) {\r | |
197 | if (L) {\r | |
198 | // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>] \r | |
199 | AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]); \r | |
200 | } else {\r | |
201 | // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]\r | |
202 | AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]); \r | |
203 | } \r | |
204 | return;\r | |
205 | }\r | |
206 | \r | |
207 | // LDM/STM\r | |
208 | if ((OpCode & 0x0e000000) == 0x08000000) {\r | |
209 | if (L) {\r | |
210 | // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r | |
211 | // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^\r | |
212 | // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^\r | |
213 | AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B)); \r | |
214 | } else {\r | |
215 | // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r | |
216 | // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^\r | |
217 | AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B)); \r | |
218 | } \r | |
219 | return;\r | |
220 | }\r | |
221 | \r | |
222 | // LDR/STR Address Mode 2\r | |
223 | if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {\r | |
224 | offset_12 = OpCode & 0xfff;\r | |
225 | if ((OpCode & 0xfd70f000 ) == 0xf550f000) {\r | |
226 | Index = AsciiSPrint (Buf, Size, "PLD");\r | |
227 | } else {\r | |
228 | Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!P & W) ? "T":"", gReg[Rd]); \r | |
229 | }\r | |
230 | if (P) {\r | |
231 | if (!I) {\r | |
232 | // A5.2.2 [<Rn>, #+/-<offset_12>]\r | |
233 | // A5.2.5 [<Rn>, #+/-<offset_12>]\r | |
234 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));\r | |
235 | } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r | |
236 | // A5.2.3 [<Rn>, +/-<Rm>]\r | |
237 | // A5.2.6 [<Rn>, +/-<Rm>]!\r | |
238 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));\r | |
239 | } else {\r | |
240 | // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]\r | |
241 | // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!\r | |
242 | shift_imm = (OpCode >> 7) & 0x1f;\r | |
243 | shift = (OpCode >> 5) & 0x3;\r | |
244 | if (shift == 0x0) {\r | |
245 | Type = "LSL";\r | |
246 | } else if (shift == 0x1) {\r | |
247 | Type = "LSR";\r | |
248 | if (shift_imm == 0) {\r | |
249 | shift_imm = 32;\r | |
250 | }\r | |
251 | } else if (shift == 0x12) {\r | |
252 | Type = "ASR";\r | |
253 | } else if (shift_imm == 0) {\r | |
254 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r | |
255 | return;\r | |
256 | } else {\r | |
257 | Type = "ROR";\r | |
258 | }\r | |
259 | \r | |
260 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));\r | |
261 | }\r | |
262 | } else { // !P\r | |
263 | if (!I) {\r | |
264 | // A5.2.8 [<Rn>], #+/-<offset_12>\r | |
265 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);\r | |
266 | } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r | |
267 | // A5.2.9 [<Rn>], +/-<Rm>\r | |
268 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r | |
269 | } else {\r | |
270 | // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>\r | |
271 | shift_imm = (OpCode >> 7) & 0x1f;\r | |
272 | shift = (OpCode >> 5) & 0x3;\r | |
273 | \r | |
274 | if (shift == 0x0) {\r | |
275 | Type = "LSL";\r | |
276 | } else if (shift == 0x1) {\r | |
277 | Type = "LSR";\r | |
278 | if (shift_imm == 0) {\r | |
279 | shift_imm = 32;\r | |
280 | }\r | |
281 | } else if (shift == 0x12) {\r | |
282 | Type = "ASR";\r | |
283 | } else if (shift_imm == 0) {\r | |
284 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);\r | |
285 | // FIx me\r | |
286 | return;\r | |
287 | } else {\r | |
288 | Type = "ROR";\r | |
289 | }\r | |
290 | \r | |
291 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);\r | |
292 | }\r | |
293 | }\r | |
294 | return; \r | |
295 | }\r | |
296 | \r | |
297 | if ((OpCode & 0x0e000000) == 0x00000000) {\r | |
298 | // LDR/STR address mode 3\r | |
299 | // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>\r | |
300 | if (L) {\r | |
301 | if (!S) {\r | |
302 | Root = "LDR%aH %a, ";\r | |
303 | } else if (!H) {\r | |
304 | Root = "LDR%aSB %a, ";\r | |
305 | } else {\r | |
306 | Root = "LDR%aSH %a, ";\r | |
307 | }\r | |
308 | } else {\r | |
309 | if (!S) {\r | |
310 | Root = "STR%aH %a ";\r | |
311 | } else if (!H) {\r | |
312 | Root = "LDR%aD %a ";\r | |
313 | } else {\r | |
314 | Root = "STR%aD %a ";\r | |
315 | }\r | |
316 | }\r | |
317 | \r | |
318 | Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]); \r | |
319 | \r | |
320 | S = (OpCode & BIT6) == BIT6;\r | |
321 | H = (OpCode & BIT5) == BIT5;\r | |
322 | offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;\r | |
323 | if (P & !W) {\r | |
324 | // Immediate offset/index\r | |
325 | if (B) {\r | |
326 | // A5.3.2 [<Rn>, #+/-<offset_8>]\r | |
327 | // A5.3.4 [<Rn>, #+/-<offset_8>]!\r | |
328 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));\r | |
329 | } else {\r | |
330 | // A5.3.3 [<Rn>, +/-<Rm>]\r | |
331 | // A5.3.5 [<Rn>, +/-<Rm>]!\r | |
332 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r | |
333 | }\r | |
334 | } else {\r | |
335 | // Register offset/index\r | |
336 | if (B) {\r | |
337 | // A5.3.6 [<Rn>], #+/-<offset_8>\r | |
338 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);\r | |
339 | } else {\r | |
340 | // A5.3.7 [<Rn>], +/-<Rm>\r | |
341 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r | |
342 | }\r | |
343 | }\r | |
344 | return;\r | |
345 | }\r | |
346 | \r | |
347 | if ((OpCode & 0x0fb000f0) == 0x01000050) {\r | |
348 | // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r | |
349 | // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r | |
350 | AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);\r | |
351 | return;\r | |
352 | }\r | |
353 | \r | |
354 | if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {\r | |
355 | // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}\r | |
356 | AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));\r | |
357 | return;\r | |
358 | }\r | |
359 | \r | |
360 | if ((OpCode & 0xfe500f00) == 0xf8100500) {\r | |
361 | // A4.1.59 RFE<addressing_mode> <Rn>{!}\r | |
362 | AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));\r | |
363 | return;\r | |
364 | }\r | |
365 | \r | |
366 | if ((OpCode & 0xfff000f0) == 0xe1200070) {\r | |
367 | // A4.1.7 BKPT <immed_16>\r | |
368 | AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);\r | |
369 | return;\r | |
370 | } \r | |
371 | \r | |
372 | if ((OpCode & 0xfff10020) == 0xf1000000) {\r | |
373 | // A4.1.16 CPS<effect> <iflags> {, #<mode>}\r | |
374 | if (((OpCode >> 6) & 0x7) == 0) {\r | |
375 | AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));\r | |
376 | } else {\r | |
377 | imode = (OpCode >> 18) & 0x3;\r | |
378 | Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");\r | |
379 | if ((OpCode & BIT17) != 0) {\r | |
380 | AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);\r | |
381 | }\r | |
382 | }\r | |
383 | return;\r | |
384 | } \r | |
385 | \r | |
386 | if ((OpCode & 0x0f000000) == 0x0f000000) {\r | |
387 | // A4.1.107 SWI{<cond>} <immed_24>\r | |
388 | AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);\r | |
389 | return;\r | |
390 | } \r | |
391 | \r | |
392 | if ((OpCode & 0x0fb00000) == 0x01000000) {\r | |
393 | // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR\r | |
394 | AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");\r | |
395 | return;\r | |
396 | } \r | |
397 | \r | |
398 | \r | |
399 | if ((OpCode & 0x0db00000) == 0x03200000) {\r | |
400 | // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>\r | |
401 | if (I) {\r | |
402 | // MSR{<cond>} CPSR_<fields>, #<immediate>\r | |
403 | AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode), B ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));\r | |
404 | } else {\r | |
405 | // MSR{<cond>} CPSR_<fields>, <Rm>\r | |
406 | AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);\r | |
407 | }\r | |
408 | return;\r | |
409 | } \r | |
410 | \r | |
411 | if ((OpCode & 0xff000010) == 0xfe000000) {\r | |
412 | // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>\r | |
413 | AsciiSPrint (Buf, Size, "CDP%a 0x%x, 0x%x, CR%d, CR%d, CR%d, 0x%x", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, Rn, Rd, Rm, (OpCode >> 5) &0x7);\r | |
414 | return;\r | |
415 | }\r | |
416 | \r | |
417 | if ((OpCode & 0x0e000000) == 0x0c000000) {\r | |
418 | // A4.1.19 LDC and A4.1.96 SDC\r | |
419 | if ((OpCode & 0xf0000000) == 0xf0000000) {\r | |
420 | Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);\r | |
421 | } else {\r | |
422 | Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);\r | |
423 | }\r | |
424 | \r | |
425 | if (!P) {\r | |
426 | if (!W) { \r | |
427 | // A5.5.5.5 [<Rn>], <option>\r | |
428 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff); \r | |
429 | } else {\r | |
430 | // A.5.5.4 [<Rn>], #+/-<offset_8>*4\r | |
431 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff); \r | |
432 | }\r | |
433 | } else {\r | |
434 | // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!\r | |
435 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W)); \r | |
436 | }\r | |
437 | \r | |
438 | }\r | |
439 | \r | |
440 | if ((OpCode & 0x0f000010) == 0x0e000010) {\r | |
441 | // A4.1.32 MRC2, MCR2 \r | |
442 | AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", L ? "MRC":"MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);\r | |
443 | return; \r | |
444 | }\r | |
445 | \r | |
446 | if ((OpCode & 0x0ff00000) == 0x0c400000) {\r | |
447 | // A4.1.33 MRRC2, MCRR2 \r | |
448 | AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", L ? "MRRC":"MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);\r | |
449 | return; \r | |
450 | }\r | |
451 | \r | |
452 | AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);\r | |
097bd461 | 453 | \r |
454 | *OpCodePtr += 1;\r | |
6f72e28d | 455 | return;\r |
456 | }\r | |
457 | \r |