16CHAR8 *gCondition[] = {
35#define COND(_a) gCondition[((_a) >> 28)]
70#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
72#define SIGN(_U) ((_U) ? "" : "-")
73#define WRITE(_Write) ((_Write) ? "!" : "")
74#define BYTE(_B) ((_B) ? "B":"")
75#define USER(_B) ((_B) ? "^" : "")
77CHAR8 mMregListStr[4*15 + 1];
84 UINTN Index, Start, End;
87 mMregListStr[0] =
'\0';
89 for (Index = 0, First =
TRUE; Index <= 15; Index++) {
90 if ((OpCode & (1 << Index)) != 0) {
92 for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {
103 AsciiStrCatS (mMregListStr,
sizeof mMregListStr, gReg[Start]);
106 AsciiStrCatS (mMregListStr,
sizeof mMregListStr, gReg[Start]);
108 AsciiStrCatS (mMregListStr,
sizeof mMregListStr, gReg[End]);
114 AsciiStrCatS (mMregListStr,
sizeof mMregListStr,
"ERROR");
137 return (Op >> Shift) | (Op << (32 - Shift));
155 IN UINT32 **OpCodePtr,
164 BOOLEAN Imm, Pre, Up, WriteBack, Write, Load, Sign, Half;
166 UINT32 IMod, Offset8, Offset12;
168 UINT32 ShiftImm, Shift;
170 OpCode = **OpCodePtr;
172 Imm = (OpCode & BIT25) == BIT25;
173 Pre = (OpCode & BIT24) == BIT24;
174 Up = (OpCode & BIT23) == BIT23;
175 WriteBack = (OpCode & BIT22) == BIT22;
176 Write = (OpCode & BIT21) == BIT21;
177 Load = (OpCode & BIT20) == BIT20;
178 Sign = (OpCode & BIT6) == BIT6;
179 Half = (OpCode & BIT5) == BIT5;
180 Rn = (OpCode >> 16) & 0xf;
181 Rd = (OpCode >> 12) & 0xf;
185 Index =
AsciiSPrint (Buf, Size,
"0x%08x ", OpCode);
191 if ((OpCode & 0x0fe000f0) == 0x01800090) {
194 AsciiSPrint (Buf, Size,
"LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);
197 AsciiSPrint (Buf, Size,
"STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);
204 if ((OpCode & 0x0e000000) == 0x08000000) {
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));
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));
220 if (((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000) == 0xf550f000)) {
221 Offset12 = OpCode & 0xfff;
222 if ((OpCode & 0xfd70f000) == 0xf550f000) {
225 Index =
AsciiSPrint (Buf, Size,
"%a%a%a%a %a, ", Load ?
"LDR" :
"STR", COND (OpCode), BYTE (WriteBack), (!(Pre) && Write) ?
"T" :
"", gReg[Rd]);
232 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a0x%x]%a", gReg[Rn], SIGN (Up), Offset12, WRITE (Write));
233 }
else if ((OpCode & 0x03000ff0) == 0x03000000) {
236 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a%a]%a", gReg[Rn], SIGN (Up), WRITE (Write));
240 ShiftImm = (OpCode >> 7) & 0x1f;
241 Shift = (OpCode >> 5) & 0x3;
244 }
else if (Shift == 0x1) {
249 }
else if (Shift == 0x2) {
251 }
else if (ShiftImm == 0) {
252 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
258 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm, WRITE (Write));
264 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a0x%x", gReg[Rn], SIGN (Up), Offset12);
265 }
else if ((OpCode & 0x03000ff0) == 0x03000000) {
267 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
270 ShiftImm = (OpCode >> 7) & 0x1f;
271 Shift = (OpCode >> 5) & 0x3;
275 }
else if (Shift == 0x1) {
280 }
else if (Shift == 0x2) {
282 }
else if (ShiftImm == 0) {
283 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (Up), gReg[Rm]);
290 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm);
297 if ((OpCode & 0x0e000000) == 0x00000000) {
302 Root =
"LDR%aH %a, ";
304 Root =
"LDR%aSB %a, ";
306 Root =
"LDR%aSH %a, ";
318 Index =
AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);
320 Sign = (OpCode & BIT6) == BIT6;
321 Half = (OpCode & BIT5) == BIT5;
322 Offset8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;
328 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a%d]%a", gReg[Rn], SIGN (Up), Offset8, WRITE (Write));
332 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a%]a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
338 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a%d", gReg[Rn], SIGN (Up), Offset8);
341 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
348 if ((OpCode & 0x0fb000f0) == 0x01000050) {
351 AsciiSPrint (Buf, Size,
"SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (WriteBack), gReg[Rd], gReg[Rm], gReg[Rn]);
355 if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {
357 AsciiSPrint (Buf, Size,
"SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (Write));
361 if ((OpCode & 0xfe500f00) == 0xf8100500) {
363 AsciiSPrint (Buf, Size,
"RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (Write));
367 if ((OpCode & 0xfff000f0) == 0xe1200070) {
369 AsciiSPrint (Buf, Size,
"BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);
373 if ((OpCode & 0xfff10020) == 0xf1000000) {
375 if (((OpCode >> 6) & 0x7) == 0) {
376 AsciiSPrint (Buf, Size,
"CPS #0x%x", (OpCode & 0x2f));
378 IMod = (OpCode >> 18) & 0x3;
383 (IMod == 3) ?
"ID" :
"IE",
384 ((OpCode & BIT8) != 0) ?
"A" :
"",
385 ((OpCode & BIT7) != 0) ?
"I" :
"",
386 ((OpCode & BIT6) != 0) ?
"F" :
""
388 if ((OpCode & BIT17) != 0) {
389 AsciiSPrint (&Buf[Index], Size - Index,
", #0x%x", OpCode & 0x1f);
396 if ((OpCode & 0x0f000000) == 0x0f000000) {
398 AsciiSPrint (Buf, Size,
"SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);
402 if ((OpCode & 0x0fb00000) == 0x01000000) {
404 AsciiSPrint (Buf, Size,
"MRS%a %a, %a", COND (OpCode), gReg[Rd], WriteBack ?
"SPSR" :
"CPSR");
408 if ((OpCode & 0x0db00000) == 0x01200000) {
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));
415 AsciiSPrint (Buf, Size,
"MRS%a %a_%a, %a", COND (OpCode), WriteBack ?
"SPSR" :
"CPSR", gReg[Rd]);
421 if ((OpCode & 0xff000010) == 0xfe000000) {
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);
427 if ((OpCode & 0x0e000000) == 0x0c000000) {
429 if ((OpCode & 0xf0000000) == 0xf0000000) {
430 Index =
AsciiSPrint (Buf, Size,
"%a2 0x%x, CR%d, ", Load ?
"LDC" :
"SDC", (OpCode >> 8) & 0xf, Rd);
432 Index =
AsciiSPrint (Buf, Size,
"%a%a 0x%x, CR%d, ", Load ?
"LDC" :
"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);
438 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], {0x%x}", gReg[Rn], OpCode & 0xff);
441 AsciiSPrint (&Buf[Index], Size - Index,
"[%a], #%a0x%x*4", gReg[Rn], SIGN (Up), OpCode & 0xff);
445 AsciiSPrint (&Buf[Index], Size - Index,
"[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (Up), OpCode & 0xff, WRITE (Write));
449 if ((OpCode & 0x0f000010) == 0x0e000010) {
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);
455 if ((OpCode & 0x0ff00000) == 0x0c400000) {
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);
461 AsciiSPrint (Buf, Size,
"Faulting OpCode 0x%08x", OpCode);
VOID DisassembleArmInstruction(IN UINT32 **OpCodePtr, OUT CHAR8 *Buf, OUT UINTN Size, IN BOOLEAN Extended)
RETURN_STATUS EFIAPI AsciiStrCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)