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