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