REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ArmPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			466 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			466 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Default exception handler
 | |
| 
 | |
|   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
 | |
|   Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Base.h>
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/PrintLib.h>
 | |
| #include <Library/ArmDisassemblerLib.h>
 | |
| 
 | |
| CHAR8  *gCondition[] = {
 | |
|   "EQ",
 | |
|   "NE",
 | |
|   "CS",
 | |
|   "CC",
 | |
|   "MI",
 | |
|   "PL",
 | |
|   "VS",
 | |
|   "VC",
 | |
|   "HI",
 | |
|   "LS",
 | |
|   "GE",
 | |
|   "LT",
 | |
|   "GT",
 | |
|   "LE",
 | |
|   "",
 | |
|   "2"
 | |
| };
 | |
| 
 | |
| #define COND(_a)  gCondition[((_a) >> 28)]
 | |
| 
 | |
| CHAR8  *gReg[] = {
 | |
|   "r0",
 | |
|   "r1",
 | |
|   "r2",
 | |
|   "r3",
 | |
|   "r4",
 | |
|   "r5",
 | |
|   "r6",
 | |
|   "r7",
 | |
|   "r8",
 | |
|   "r9",
 | |
|   "r10",
 | |
|   "r11",
 | |
|   "r12",
 | |
|   "sp",
 | |
|   "lr",
 | |
|   "pc"
 | |
| };
 | |
| 
 | |
| CHAR8  *gLdmAdr[] = {
 | |
|   "DA",
 | |
|   "IA",
 | |
|   "DB",
 | |
|   "IB"
 | |
| };
 | |
| 
 | |
| CHAR8  *gLdmStack[] = {
 | |
|   "FA",
 | |
|   "FD",
 | |
|   "EA",
 | |
|   "ED"
 | |
| };
 | |
| 
 | |
| #define LDM_EXT(_reg, _off)  ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
 | |
| 
 | |
| #define SIGN(_U)       ((_U) ? "" : "-")
 | |
| #define WRITE(_Write)  ((_Write) ? "!" : "")
 | |
| #define BYTE(_B)       ((_B) ? "B":"")
 | |
| #define USER(_B)       ((_B) ? "^" : "")
 | |
| 
 | |
| CHAR8  mMregListStr[4*15 + 1];
 | |
| 
 | |
| CHAR8 *
 | |
| MRegList (
 | |
|   UINT32  OpCode
 | |
|   )
 | |
| {
 | |
|   UINTN    Index, Start, End;
 | |
|   BOOLEAN  First;
 | |
| 
 | |
|   mMregListStr[0] = '\0';
 | |
|   AsciiStrCatS (mMregListStr, sizeof mMregListStr, "{");
 | |
|   for (Index = 0, First = TRUE; Index <= 15; Index++) {
 | |
|     if ((OpCode & (1 << Index)) != 0) {
 | |
|       Start = End = Index;
 | |
|       for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {
 | |
|         End = Index;
 | |
|       }
 | |
| 
 | |
|       if (!First) {
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, ",");
 | |
|       } else {
 | |
|         First = FALSE;
 | |
|       }
 | |
| 
 | |
|       if (Start == End) {
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[Start]);
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, ", ");
 | |
|       } else {
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[Start]);
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, "-");
 | |
|         AsciiStrCatS (mMregListStr, sizeof mMregListStr, gReg[End]);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (First) {
 | |
|     AsciiStrCatS (mMregListStr, sizeof mMregListStr, "ERROR");
 | |
|   }
 | |
| 
 | |
|   AsciiStrCatS (mMregListStr, sizeof mMregListStr, "}");
 | |
| 
 | |
|   // BugBug: Make caller pass in buffer it is cleaner
 | |
|   return mMregListStr;
 | |
| }
 | |
| 
 | |
| CHAR8 *
 | |
| FieldMask (
 | |
|   IN  UINT32  Mask
 | |
|   )
 | |
| {
 | |
|   return "";
 | |
| }
 | |
| 
 | |
| UINT32
 | |
| RotateRight (
 | |
|   IN UINT32  Op,
 | |
|   IN UINT32  Shift
 | |
|   )
 | |
| {
 | |
|   return (Op >> Shift) | (Op << (32 - Shift));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Place a disassembly of **OpCodePtr into buffer, and update OpCodePtr to
 | |
|   point to next instruction.
 | |
| 
 | |
|   We cheat and only decode instructions that access
 | |
|   memory. If the instruction is not found we dump the instruction in hex.
 | |
| 
 | |
|   @param  OpCodePtr   Pointer to pointer of ARM instruction to disassemble.
 | |
|   @param  Buf         Buffer to sprintf disassembly into.
 | |
|   @param  Size        Size of Buf in bytes.
 | |
|   @param  Extended    TRUE dump hex for instruction too.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DisassembleArmInstruction (
 | |
|   IN  UINT32   **OpCodePtr,
 | |
|   OUT CHAR8    *Buf,
 | |
|   OUT UINTN    Size,
 | |
|   IN  BOOLEAN  Extended
 | |
|   )
 | |
| {
 | |
|   UINT32   OpCode;
 | |
|   CHAR8    *Type;
 | |
|   CHAR8    *Root;
 | |
|   BOOLEAN  Imm, Pre, Up, WriteBack, Write, Load, Sign, Half;
 | |
|   UINT32   Rn, Rd, Rm;
 | |
|   UINT32   IMod, Offset8, Offset12;
 | |
|   UINT32   Index;
 | |
|   UINT32   ShiftImm, Shift;
 | |
| 
 | |
|   OpCode = **OpCodePtr;
 | |
| 
 | |
|   Imm       = (OpCode & BIT25) == BIT25; // I
 | |
|   Pre       = (OpCode & BIT24) == BIT24; // P
 | |
|   Up        = (OpCode & BIT23) == BIT23; // U
 | |
|   WriteBack = (OpCode & BIT22) == BIT22; // B, also called S
 | |
|   Write     = (OpCode & BIT21) == BIT21; // W
 | |
|   Load      = (OpCode & BIT20) == BIT20; // L
 | |
|   Sign      = (OpCode & BIT6) == BIT6;   // S
 | |
|   Half      = (OpCode & BIT5) == BIT5;   // H
 | |
|   Rn        = (OpCode >> 16) & 0xf;
 | |
|   Rd        = (OpCode >> 12) & 0xf;
 | |
|   Rm        = (OpCode & 0xf);
 | |
| 
 | |
|   if (Extended) {
 | |
|     Index = AsciiSPrint (Buf, Size, "0x%08x   ", OpCode);
 | |
|     Buf  += Index;
 | |
|     Size -= Index;
 | |
|   }
 | |
| 
 | |
|   // LDREX, STREX
 | |
|   if ((OpCode  & 0x0fe000f0) == 0x01800090) {
 | |
|     if (Load) {
 | |
|       // A4.1.27  LDREX{<cond>} <Rd>, [<Rn>]
 | |
|       AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);
 | |
|     } else {
 | |
|       // A4.1.103  STREX{<cond>} <Rd>, <Rm>, [<Rn>]
 | |
|       AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // LDM/STM
 | |
|   if ((OpCode  & 0x0e000000) == 0x08000000) {
 | |
|     if (Load) {
 | |
|       // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
 | |
|       // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
 | |
|       // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
 | |
|       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));
 | |
|     } else {
 | |
|       // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
 | |
|       // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
 | |
|       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));
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // LDR/STR Address Mode 2
 | |
|   if (((OpCode  & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000) == 0xf550f000)) {
 | |
|     Offset12 = OpCode & 0xfff;
 | |
|     if ((OpCode & 0xfd70f000) == 0xf550f000) {
 | |
|       Index = AsciiSPrint (Buf, Size, "PLD");
 | |
|     } else {
 | |
|       Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", Load ? "LDR" : "STR", COND (OpCode), BYTE (WriteBack), (!(Pre) && Write) ? "T" : "", gReg[Rd]);
 | |
|     }
 | |
| 
 | |
|     if (Pre) {
 | |
|       if (!Imm) {
 | |
|         // A5.2.2 [<Rn>, #+/-<offset_12>]
 | |
|         // A5.2.5 [<Rn>, #+/-<offset_12>]
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (Up), Offset12, WRITE (Write));
 | |
|       } else if ((OpCode & 0x03000ff0) == 0x03000000) {
 | |
|         // A5.2.3 [<Rn>, +/-<Rm>]
 | |
|         // A5.2.6 [<Rn>, +/-<Rm>]!
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (Up), WRITE (Write));
 | |
|       } else {
 | |
|         // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
 | |
|         // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
 | |
|         ShiftImm = (OpCode >> 7) & 0x1f;
 | |
|         Shift    = (OpCode >> 5) & 0x3;
 | |
|         if (Shift == 0x0) {
 | |
|           Type = "LSL";
 | |
|         } else if (Shift == 0x1) {
 | |
|           Type = "LSR";
 | |
|           if (ShiftImm == 0) {
 | |
|             ShiftImm = 32;
 | |
|           }
 | |
|         } else if (Shift == 0x2) {
 | |
|           Type = "ASR";
 | |
|         } else if (ShiftImm == 0) {
 | |
|           AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
 | |
|           return;
 | |
|         } else {
 | |
|           Type = "ROR";
 | |
|         }
 | |
| 
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm, WRITE (Write));
 | |
|       }
 | |
|     } else {
 | |
|       // !Pre
 | |
|       if (!Imm) {
 | |
|         // A5.2.8  [<Rn>], #+/-<offset_12>
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (Up), Offset12);
 | |
|       } else if ((OpCode & 0x03000ff0) == 0x03000000) {
 | |
|         // A5.2.9  [<Rn>], +/-<Rm>
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
 | |
|       } else {
 | |
|         // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
 | |
|         ShiftImm = (OpCode >> 7) & 0x1f;
 | |
|         Shift    = (OpCode >> 5) & 0x3;
 | |
| 
 | |
|         if (Shift == 0x0) {
 | |
|           Type = "LSL";
 | |
|         } else if (Shift == 0x1) {
 | |
|           Type = "LSR";
 | |
|           if (ShiftImm == 0) {
 | |
|             ShiftImm = 32;
 | |
|           }
 | |
|         } else if (Shift == 0x2) {
 | |
|           Type = "ASR";
 | |
|         } else if (ShiftImm == 0) {
 | |
|           AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (Up), gReg[Rm]);
 | |
|           // FIx me
 | |
|           return;
 | |
|         } else {
 | |
|           Type = "ROR";
 | |
|         }
 | |
| 
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0e000000) == 0x00000000) {
 | |
|     // LDR/STR address mode 3
 | |
|     // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
 | |
|     if (Load) {
 | |
|       if (!Sign) {
 | |
|         Root = "LDR%aH %a, ";
 | |
|       } else if (!Half) {
 | |
|         Root = "LDR%aSB %a, ";
 | |
|       } else {
 | |
|         Root = "LDR%aSH %a, ";
 | |
|       }
 | |
|     } else {
 | |
|       if (!Sign) {
 | |
|         Root = "STR%aH %a ";
 | |
|       } else if (!Half) {
 | |
|         Root = "LDR%aD %a ";
 | |
|       } else {
 | |
|         Root = "STR%aD %a ";
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);
 | |
| 
 | |
|     Sign    = (OpCode & BIT6) == BIT6;
 | |
|     Half    = (OpCode & BIT5) == BIT5;
 | |
|     Offset8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;
 | |
|     if (Pre & !Write) {
 | |
|       // Immediate offset/index
 | |
|       if (WriteBack) {
 | |
|         // A5.3.2  [<Rn>, #+/-<offset_8>]
 | |
|         // A5.3.4  [<Rn>, #+/-<offset_8>]!
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (Up), Offset8, WRITE (Write));
 | |
|       } else {
 | |
|         // A5.3.3  [<Rn>, +/-<Rm>]
 | |
|         // A5.3.5  [<Rn>, +/-<Rm>]!
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
 | |
|       }
 | |
|     } else {
 | |
|       // Register offset/index
 | |
|       if (WriteBack) {
 | |
|         // A5.3.6 [<Rn>], #+/-<offset_8>
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (Up), Offset8);
 | |
|       } else {
 | |
|         // A5.3.7 [<Rn>], +/-<Rm>
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0fb000f0) == 0x01000050) {
 | |
|     // A4.1.108  SWP   SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
 | |
|     // A4.1.109  SWPB  SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
 | |
|     AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (WriteBack), gReg[Rd], gReg[Rm], gReg[Rn]);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0xfe5f0f00) == 0xf84d0500) {
 | |
|     // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
 | |
|     AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (Write));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0xfe500f00) == 0xf8100500) {
 | |
|     // A4.1.59 RFE<addressing_mode> <Rn>{!}
 | |
|     AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (Write));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0xfff000f0) == 0xe1200070) {
 | |
|     // A4.1.7 BKPT <immed_16>
 | |
|     AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0xfff10020) == 0xf1000000) {
 | |
|     // A4.1.16 CPS<effect> <iflags> {, #<mode>}
 | |
|     if (((OpCode >> 6) & 0x7) == 0) {
 | |
|       AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));
 | |
|     } else {
 | |
|       IMod  = (OpCode >> 18) & 0x3;
 | |
|       Index = AsciiSPrint (
 | |
|                 Buf,
 | |
|                 Size,
 | |
|                 "CPS%a %a%a%a",
 | |
|                 (IMod == 3) ? "ID" : "IE",
 | |
|                 ((OpCode & BIT8) != 0) ? "A" : "",
 | |
|                 ((OpCode & BIT7) != 0) ? "I" : "",
 | |
|                 ((OpCode & BIT6) != 0) ? "F" : ""
 | |
|                 );
 | |
|       if ((OpCode & BIT17) != 0) {
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0f000000) == 0x0f000000) {
 | |
|     // A4.1.107 SWI{<cond>} <immed_24>
 | |
|     AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0fb00000) == 0x01000000) {
 | |
|     // A4.1.38 MRS{<cond>} <Rd>, CPSR  MRS{<cond>} <Rd>, SPSR
 | |
|     AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], WriteBack ? "SPSR" : "CPSR");
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0db00000) == 0x01200000) {
 | |
|     // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
 | |
|     if (Imm) {
 | |
|       // MSR{<cond>} CPSR_<fields>, #<immediate>
 | |
|       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));
 | |
|     } else {
 | |
|       // MSR{<cond>} CPSR_<fields>, <Rm>
 | |
|       AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), WriteBack ? "SPSR" : "CPSR", gReg[Rd]);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0xff000010) == 0xfe000000) {
 | |
|     // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
 | |
|     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);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0e000000) == 0x0c000000) {
 | |
|     // A4.1.19 LDC and A4.1.96 SDC
 | |
|     if ((OpCode & 0xf0000000) == 0xf0000000) {
 | |
|       Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", Load ? "LDC" : "SDC", (OpCode >> 8) & 0xf, Rd);
 | |
|     } else {
 | |
|       Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", Load ? "LDC" : "SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);
 | |
|     }
 | |
| 
 | |
|     if (!Pre) {
 | |
|       if (!Write) {
 | |
|         // A5.5.5.5 [<Rn>], <option>
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);
 | |
|       } else {
 | |
|         // A.5.5.4  [<Rn>], #+/-<offset_8>*4
 | |
|         AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (Up), OpCode & 0xff);
 | |
|       }
 | |
|     } else {
 | |
|       // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
 | |
|       AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (Up), OpCode & 0xff, WRITE (Write));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0f000010) == 0x0e000010) {
 | |
|     // A4.1.32 MRC2, MCR2
 | |
|     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);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if ((OpCode  & 0x0ff00000) == 0x0c400000) {
 | |
|     // A4.1.33 MRRC2, MCRR2
 | |
|     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);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);
 | |
| 
 | |
|   *OpCodePtr += 1;
 | |
|   return;
 | |
| }
 |