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