]>
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 |
16 | CHAR8 *gCondition[] = {\r | |
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 |
37 | CHAR8 *gReg[] = {\r | |
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 | |
56 | CHAR8 *gLdmAdr[] = {\r | |
57 | "DA",\r | |
58 | "IA",\r | |
59 | "DB",\r | |
60 | "IB"\r | |
61 | };\r | |
62 | \r | |
63 | CHAR8 *gLdmStack[] = {\r | |
64 | "FA",\r | |
65 | "FD",\r | |
66 | "EA",\r | |
67 | "ED"\r | |
68 | };\r | |
69 | \r | |
70 | #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])\r | |
71 | \r | |
72 | \r | |
73 | #define SIGN(_U) ((_U) ? "" : "-")\r | |
2f2c0a8b | 74 | #define WRITE(_Write) ((_Write) ? "!" : "")\r |
6f72e28d | 75 | #define BYTE(_B) ((_B) ? "B":"")\r |
76 | #define USER(_B) ((_B) ? "^" : "")\r | |
77 | \r | |
78 | CHAR8 mMregListStr[4*15 + 1];\r | |
79 | \r | |
80 | CHAR8 *\r | |
81 | MRegList (\r | |
82 | UINT32 OpCode\r | |
83 | )\r | |
84 | {\r | |
85 | UINTN Index, Start, End;\r | |
6f72e28d | 86 | BOOLEAN First;\r |
3402aac7 | 87 | \r |
f00ace96 LE |
88 | mMregListStr[0] = '\0';\r |
89 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, "{");\r | |
6f72e28d | 90 | for (Index = 0, First = TRUE; Index <= 15; Index++) {\r |
91 | if ((OpCode & (1 << Index)) != 0) {\r | |
92 | Start = End = Index;\r | |
93 | for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {\r | |
94 | End = Index;\r | |
95 | }\r | |
3402aac7 | 96 | \r |
6f72e28d | 97 | if (!First) {\r |
f00ace96 | 98 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, ",");\r |
6f72e28d | 99 | } else {\r |
100 | First = FALSE;\r | |
101 | }\r | |
3402aac7 | 102 | \r |
6f72e28d | 103 | if (Start == End) {\r |
f00ace96 LE |
104 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[Start]);\r |
105 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, ", ");\r | |
6f72e28d | 106 | } else {\r |
f00ace96 LE |
107 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[Start]);\r |
108 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, "-");\r | |
109 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[End]);\r | |
6f72e28d | 110 | }\r |
111 | }\r | |
112 | }\r | |
113 | if (First) {\r | |
f00ace96 | 114 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, "ERROR");\r |
6f72e28d | 115 | }\r |
f00ace96 | 116 | AsciiStrCatS (mMregListStr, sizeof mMregListStr, "}");\r |
3402aac7 | 117 | \r |
6f72e28d | 118 | // BugBug: Make caller pass in buffer it is cleaner\r |
119 | return mMregListStr;\r | |
120 | }\r | |
121 | \r | |
122 | CHAR8 *\r | |
123 | FieldMask (\r | |
124 | IN UINT32 Mask\r | |
125 | )\r | |
126 | {\r | |
127 | return "";\r | |
128 | }\r | |
129 | \r | |
130 | UINT32\r | |
131 | RotateRight (\r | |
132 | IN UINT32 Op,\r | |
133 | IN UINT32 Shift\r | |
134 | )\r | |
135 | {\r | |
136 | return (Op >> Shift) | (Op << (32 - Shift));\r | |
137 | }\r | |
138 | \r | |
139 | \r | |
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 | |
097bd461 | 155 | IN UINT32 **OpCodePtr,\r |
6f72e28d | 156 | OUT CHAR8 *Buf,\r |
f9f937d2 | 157 | OUT UINTN Size,\r |
158 | IN BOOLEAN Extended\r | |
6f72e28d | 159 | )\r |
160 | {\r | |
b9b86dc4 | 161 | UINT32 OpCode;\r |
2f2c0a8b PG |
162 | CHAR8 *Type;\r |
163 | CHAR8 *Root;\r | |
164 | BOOLEAN Imm, Pre, Up, WriteBack, Write, Load, Sign, Half;\r | |
6f72e28d | 165 | UINT32 Rn, Rd, Rm;\r |
2f2c0a8b | 166 | UINT32 IMod, Offset8, Offset12;\r |
6f72e28d | 167 | UINT32 Index;\r |
2f2c0a8b | 168 | UINT32 ShiftImm, Shift;\r |
6f72e28d | 169 | \r |
b9b86dc4 PG |
170 | OpCode = **OpCodePtr;\r |
171 | \r | |
2f2c0a8b PG |
172 | Imm = (OpCode & BIT25) == BIT25; // I\r |
173 | Pre = (OpCode & BIT24) == BIT24; // P\r | |
174 | Up = (OpCode & BIT23) == BIT23; // U\r | |
175 | WriteBack = (OpCode & BIT22) == BIT22; // B, also called S\r | |
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 | |
6f72e28d | 180 | Rn = (OpCode >> 16) & 0xf;\r |
181 | Rd = (OpCode >> 12) & 0xf;\r | |
182 | Rm = (OpCode & 0xf);\r | |
183 | \r | |
f9f937d2 | 184 | \r |
185 | if (Extended) {\r | |
186 | Index = AsciiSPrint (Buf, Size, "0x%08x ", OpCode);\r | |
187 | Buf += Index;\r | |
188 | Size -= Index;\r | |
189 | }\r | |
190 | \r | |
6f72e28d | 191 | // LDREX, STREX\r |
192 | if ((OpCode & 0x0fe000f0) == 0x01800090) {\r | |
2f2c0a8b | 193 | if (Load) {\r |
3402aac7 RC |
194 | // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]\r |
195 | AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);\r | |
6f72e28d | 196 | } else {\r |
197 | // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]\r | |
3402aac7 RC |
198 | AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);\r |
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 | |
2f2c0a8b | 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 | |
2f2c0a8b | 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 |
6f72e28d | 215 | return;\r |
216 | }\r | |
217 | \r | |
218 | // LDR/STR Address Mode 2\r | |
219 | if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {\r | |
2f2c0a8b | 220 | Offset12 = OpCode & 0xfff;\r |
6f72e28d | 221 | if ((OpCode & 0xfd70f000 ) == 0xf550f000) {\r |
222 | Index = AsciiSPrint (Buf, Size, "PLD");\r | |
223 | } else {\r | |
2f2c0a8b | 224 | Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", Load ? "LDR" : "STR", COND (OpCode), BYTE (WriteBack), (!(Pre) && Write) ? "T":"", gReg[Rd]);\r |
6f72e28d | 225 | }\r |
2f2c0a8b PG |
226 | if (Pre) {\r |
227 | if (!Imm) {\r | |
6f72e28d | 228 | // A5.2.2 [<Rn>, #+/-<offset_12>]\r |
229 | // A5.2.5 [<Rn>, #+/-<offset_12>]\r | |
2f2c0a8b | 230 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (Up), Offset12, WRITE (Write));\r |
6f72e28d | 231 | } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r |
232 | // A5.2.3 [<Rn>, +/-<Rm>]\r | |
233 | // A5.2.6 [<Rn>, +/-<Rm>]!\r | |
2f2c0a8b | 234 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (Up), WRITE (Write));\r |
6f72e28d | 235 | } else {\r |
236 | // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]\r | |
237 | // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!\r | |
2f2c0a8b PG |
238 | ShiftImm = (OpCode >> 7) & 0x1f;\r |
239 | Shift = (OpCode >> 5) & 0x3;\r | |
240 | if (Shift == 0x0) {\r | |
6f72e28d | 241 | Type = "LSL";\r |
2f2c0a8b | 242 | } else if (Shift == 0x1) {\r |
6f72e28d | 243 | Type = "LSR";\r |
2f2c0a8b PG |
244 | if (ShiftImm == 0) {\r |
245 | ShiftImm = 32;\r | |
6f72e28d | 246 | }\r |
2f2c0a8b | 247 | } else if (Shift == 0x2) {\r |
6f72e28d | 248 | Type = "ASR";\r |
2f2c0a8b PG |
249 | } else if (ShiftImm == 0) {\r |
250 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));\r | |
6f72e28d | 251 | return;\r |
252 | } else {\r | |
253 | Type = "ROR";\r | |
254 | }\r | |
3402aac7 | 255 | \r |
2f2c0a8b | 256 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm, WRITE (Write));\r |
6f72e28d | 257 | }\r |
2f2c0a8b PG |
258 | } else { // !Pre\r |
259 | if (!Imm) {\r | |
6f72e28d | 260 | // A5.2.8 [<Rn>], #+/-<offset_12>\r |
2f2c0a8b | 261 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (Up), Offset12);\r |
6f72e28d | 262 | } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r |
263 | // A5.2.9 [<Rn>], +/-<Rm>\r | |
2f2c0a8b | 264 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);\r |
6f72e28d | 265 | } else {\r |
266 | // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>\r | |
2f2c0a8b PG |
267 | ShiftImm = (OpCode >> 7) & 0x1f;\r |
268 | Shift = (OpCode >> 5) & 0x3;\r | |
6f72e28d | 269 | \r |
2f2c0a8b | 270 | if (Shift == 0x0) {\r |
6f72e28d | 271 | Type = "LSL";\r |
2f2c0a8b | 272 | } else if (Shift == 0x1) {\r |
6f72e28d | 273 | Type = "LSR";\r |
2f2c0a8b PG |
274 | if (ShiftImm == 0) {\r |
275 | ShiftImm = 32;\r | |
6f72e28d | 276 | }\r |
2f2c0a8b | 277 | } else if (Shift == 0x2) {\r |
6f72e28d | 278 | Type = "ASR";\r |
2f2c0a8b PG |
279 | } else if (ShiftImm == 0) {\r |
280 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (Up), gReg[Rm]);\r | |
6f72e28d | 281 | // FIx me\r |
282 | return;\r | |
283 | } else {\r | |
284 | Type = "ROR";\r | |
285 | }\r | |
3402aac7 | 286 | \r |
2f2c0a8b | 287 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm);\r |
6f72e28d | 288 | }\r |
289 | }\r | |
3402aac7 | 290 | return;\r |
6f72e28d | 291 | }\r |
3402aac7 | 292 | \r |
6f72e28d | 293 | if ((OpCode & 0x0e000000) == 0x00000000) {\r |
294 | // LDR/STR address mode 3\r | |
295 | // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>\r | |
2f2c0a8b PG |
296 | if (Load) {\r |
297 | if (!Sign) {\r | |
6f72e28d | 298 | Root = "LDR%aH %a, ";\r |
2f2c0a8b | 299 | } else if (!Half) {\r |
6f72e28d | 300 | Root = "LDR%aSB %a, ";\r |
301 | } else {\r | |
302 | Root = "LDR%aSH %a, ";\r | |
303 | }\r | |
304 | } else {\r | |
2f2c0a8b | 305 | if (!Sign) {\r |
6f72e28d | 306 | Root = "STR%aH %a ";\r |
2f2c0a8b | 307 | } else if (!Half) {\r |
6f72e28d | 308 | Root = "LDR%aD %a ";\r |
309 | } else {\r | |
310 | Root = "STR%aD %a ";\r | |
311 | }\r | |
312 | }\r | |
3402aac7 RC |
313 | \r |
314 | Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);\r | |
6f72e28d | 315 | \r |
2f2c0a8b PG |
316 | Sign = (OpCode & BIT6) == BIT6;\r |
317 | Half = (OpCode & BIT5) == BIT5;\r | |
318 | Offset8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;\r | |
319 | if (Pre & !Write) {\r | |
6f72e28d | 320 | // Immediate offset/index\r |
2f2c0a8b | 321 | if (WriteBack) {\r |
6f72e28d | 322 | // A5.3.2 [<Rn>, #+/-<offset_8>]\r |
323 | // A5.3.4 [<Rn>, #+/-<offset_8>]!\r | |
2f2c0a8b | 324 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (Up), Offset8, WRITE (Write));\r |
6f72e28d | 325 | } else {\r |
326 | // A5.3.3 [<Rn>, +/-<Rm>]\r | |
327 | // A5.3.5 [<Rn>, +/-<Rm>]!\r | |
2f2c0a8b | 328 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));\r |
6f72e28d | 329 | }\r |
330 | } else {\r | |
331 | // Register offset/index\r | |
2f2c0a8b | 332 | if (WriteBack) {\r |
6f72e28d | 333 | // A5.3.6 [<Rn>], #+/-<offset_8>\r |
2f2c0a8b | 334 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (Up), Offset8);\r |
6f72e28d | 335 | } else {\r |
336 | // A5.3.7 [<Rn>], +/-<Rm>\r | |
2f2c0a8b | 337 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);\r |
6f72e28d | 338 | }\r |
339 | }\r | |
340 | return;\r | |
341 | }\r | |
342 | \r | |
343 | if ((OpCode & 0x0fb000f0) == 0x01000050) {\r | |
344 | // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r | |
345 | // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r | |
2f2c0a8b | 346 | AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (WriteBack), gReg[Rd], gReg[Rm], gReg[Rn]);\r |
6f72e28d | 347 | return;\r |
348 | }\r | |
3402aac7 | 349 | \r |
6f72e28d | 350 | if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {\r |
351 | // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}\r | |
2f2c0a8b | 352 | AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (Write));\r |
6f72e28d | 353 | return;\r |
354 | }\r | |
355 | \r | |
356 | if ((OpCode & 0xfe500f00) == 0xf8100500) {\r | |
357 | // A4.1.59 RFE<addressing_mode> <Rn>{!}\r | |
2f2c0a8b | 358 | AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (Write));\r |
6f72e28d | 359 | return;\r |
360 | }\r | |
3402aac7 | 361 | \r |
6f72e28d | 362 | if ((OpCode & 0xfff000f0) == 0xe1200070) {\r |
363 | // A4.1.7 BKPT <immed_16>\r | |
364 | AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);\r | |
365 | return;\r | |
3402aac7 RC |
366 | }\r |
367 | \r | |
6f72e28d | 368 | if ((OpCode & 0xfff10020) == 0xf1000000) {\r |
369 | // A4.1.16 CPS<effect> <iflags> {, #<mode>}\r | |
370 | if (((OpCode >> 6) & 0x7) == 0) {\r | |
371 | AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));\r | |
372 | } else {\r | |
2f2c0a8b | 373 | IMod = (OpCode >> 18) & 0x3;\r |
31ea1d2e | 374 | Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a",\r |
2f2c0a8b | 375 | (IMod == 3) ? "ID":"IE",\r |
31ea1d2e PG |
376 | ((OpCode & BIT8) != 0) ? "A":"",\r |
377 | ((OpCode & BIT7) != 0) ? "I":"",\r | |
378 | ((OpCode & BIT6) != 0) ? "F":"");\r | |
6f72e28d | 379 | if ((OpCode & BIT17) != 0) {\r |
380 | AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);\r | |
381 | }\r | |
382 | }\r | |
383 | return;\r | |
3402aac7 RC |
384 | }\r |
385 | \r | |
6f72e28d | 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 | |
3402aac7 | 390 | }\r |
6f72e28d | 391 | \r |
392 | if ((OpCode & 0x0fb00000) == 0x01000000) {\r | |
393 | // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR\r | |
2f2c0a8b | 394 | AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], WriteBack ? "SPSR" : "CPSR");\r |
6f72e28d | 395 | return;\r |
3402aac7 | 396 | }\r |
6f72e28d | 397 | \r |
398 | \r | |
b2008545 | 399 | if ((OpCode & 0x0db00000) == 0x01200000) {\r |
6f72e28d | 400 | // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>\r |
2f2c0a8b | 401 | if (Imm) {\r |
6f72e28d | 402 | // MSR{<cond>} CPSR_<fields>, #<immediate>\r |
2f2c0a8b | 403 | 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 | 404 | } else {\r |
405 | // MSR{<cond>} CPSR_<fields>, <Rm>\r | |
2f2c0a8b | 406 | AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), WriteBack ? "SPSR" : "CPSR", gReg[Rd]);\r |
6f72e28d | 407 | }\r |
408 | return;\r | |
3402aac7 | 409 | }\r |
6f72e28d | 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 | |
3402aac7 | 416 | \r |
6f72e28d | 417 | if ((OpCode & 0x0e000000) == 0x0c000000) {\r |
418 | // A4.1.19 LDC and A4.1.96 SDC\r | |
419 | if ((OpCode & 0xf0000000) == 0xf0000000) {\r | |
2f2c0a8b | 420 | Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", Load ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);\r |
6f72e28d | 421 | } else {\r |
2f2c0a8b | 422 | Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", Load ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);\r |
6f72e28d | 423 | }\r |
3402aac7 | 424 | \r |
2f2c0a8b PG |
425 | if (!Pre) {\r |
426 | if (!Write) {\r | |
6f72e28d | 427 | // A5.5.5.5 [<Rn>], <option>\r |
3402aac7 | 428 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);\r |
6f72e28d | 429 | } else {\r |
430 | // A.5.5.4 [<Rn>], #+/-<offset_8>*4\r | |
2f2c0a8b | 431 | AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (Up), OpCode & 0xff);\r |
6f72e28d | 432 | }\r |
433 | } else {\r | |
434 | // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!\r | |
2f2c0a8b | 435 | AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (Up), OpCode & 0xff, WRITE (Write));\r |
6f72e28d | 436 | }\r |
3402aac7 | 437 | \r |
6f72e28d | 438 | }\r |
3402aac7 | 439 | \r |
6f72e28d | 440 | if ((OpCode & 0x0f000010) == 0x0e000010) {\r |
3402aac7 | 441 | // A4.1.32 MRC2, MCR2\r |
2f2c0a8b | 442 | 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 | 443 | return;\r |
6f72e28d | 444 | }\r |
445 | \r | |
446 | if ((OpCode & 0x0ff00000) == 0x0c400000) {\r | |
3402aac7 | 447 | // A4.1.33 MRRC2, MCRR2\r |
2f2c0a8b | 448 | 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 | 449 | return;\r |
6f72e28d | 450 | }\r |
451 | \r | |
452 | AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);\r | |
3402aac7 | 453 | \r |
097bd461 | 454 | *OpCodePtr += 1;\r |
6f72e28d | 455 | return;\r |
456 | }\r | |
457 | \r |