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;
 | 
						|
}
 |