mirror of
https://github.com/libretro/ppsspp.git
synced 2025-03-03 14:09:45 +00:00
ARM64: Disassemble csel and multiply instructions
This commit is contained in:
parent
a8be978154
commit
120e0bba3c
@ -35,6 +35,23 @@ struct Instruction {
|
||||
|
||||
static const char * const shiftnames[4] = { "lsl", "lsr", "asr", "ror" };
|
||||
static const char * const extendnames[8] = { "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx" };
|
||||
static const char * const condnames[16] = {
|
||||
"eq", // Equal
|
||||
"ne", // Not equal
|
||||
"cs", // Carry Set "HS"
|
||||
"cc", // Carry Clear "LO"
|
||||
"mi", // Minus (Negative)
|
||||
"pl", // Plus
|
||||
"vs", // Overflow
|
||||
"vc", // No Overflow
|
||||
"hi", // Unsigned higher
|
||||
"ls", // Unsigned lower or same
|
||||
"ge", // Signed greater than or equal
|
||||
"lt", // Signed less than
|
||||
"gt", // Signed greater than
|
||||
"le", // Signed less than or equal
|
||||
"al", // Always (unconditional) 14
|
||||
};
|
||||
|
||||
int SignExtend26(int x) {
|
||||
return (x & 0x02000000) ? (0xFC000000 | x) : (x & 0x3FFFFFF);
|
||||
@ -110,24 +127,6 @@ void DecodeBitMasks(int immN, int imms, int immr, uint64_t *tmask, uint64_t *wma
|
||||
}
|
||||
}
|
||||
|
||||
static const char *conds[16] = {
|
||||
"eq", // Equal
|
||||
"ne", // Not equal
|
||||
"cs", // Carry Set "HS"
|
||||
"cc", // Carry Clear "LO"
|
||||
"mi", // Minus (Negative)
|
||||
"pl", // Plus
|
||||
"vs", // Overflow
|
||||
"vc", // No Overflow
|
||||
"hi", // Unsigned higher
|
||||
"ls", // Unsigned lower or same
|
||||
"ge", // Signed greater than or equal
|
||||
"lt", // Signed less than
|
||||
"gt", // Signed greater than
|
||||
"le", // Signed less than or equal
|
||||
"al", // Always (unconditional) 14
|
||||
};
|
||||
|
||||
static void DataProcessingImmediate(uint32_t w, uint64_t addr, Instruction *instr) {
|
||||
int Rd = w & 0x1f;
|
||||
int Rn = (w >> 5) & 0x1f;
|
||||
@ -194,9 +193,14 @@ static void BranchExceptionAndSystem(uint32_t w, uint64_t addr, Instruction *ins
|
||||
int offset = SignExtend19(w >> 5) << 2;
|
||||
uint64_t target = addr + offset;
|
||||
int cond = w & 0xF;
|
||||
snprintf(instr->text, sizeof(instr->text), "b.%s %04x%08x", conds[cond], (target >> 32), (target & 0xFFFFFFFF));
|
||||
snprintf(instr->text, sizeof(instr->text), "b.%s %04x%08x", condnames[cond], (target >> 32), (target & 0xFFFFFFFF));
|
||||
} else if ((w >> 24) == 0xD4) {
|
||||
snprintf(instr->text, sizeof(instr->text), "(exception-gen %08x)", w);
|
||||
if (((w >> 21) & 0x7) == 1 && Rt == 0) {
|
||||
int imm = (w >> 5) & 0xFFFF;
|
||||
snprintf(instr->text, sizeof(instr->text), "brk #%d", imm);
|
||||
} else {
|
||||
snprintf(instr->text, sizeof(instr->text), "(exception-gen %08x)", w);
|
||||
}
|
||||
} else if (((w >> 20) & 0xFFC) == 0xD50) {
|
||||
snprintf(instr->text, sizeof(instr->text), "(system-reg %08x)", w);
|
||||
} else if (((w >> 25) & 0x7F) == 0x6B) {
|
||||
@ -219,7 +223,7 @@ static void LoadStore(uint32_t w, uint64_t addr, Instruction *instr) {
|
||||
int opc = (w >> 22) & 0x3;
|
||||
char r = size == 3 ? 'x' : 'w';
|
||||
const char *opname[4] = { "str", "ldr", "str", "ldr" };
|
||||
const char *sizeSuffix[4] = { "b", "w", "", "" };
|
||||
const char *sizeSuffix[4] = { "b", "h", "", "" };
|
||||
|
||||
if (((w >> 27) & 7) == 7) {
|
||||
int V = (w >> 26) & 1;
|
||||
@ -323,8 +327,8 @@ static void DataProcessingRegister(uint32_t w, uint64_t addr, Instruction *instr
|
||||
} else {
|
||||
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d, %c%d, %s #%d", opnames[opc], r, Rd, r, Rn, r, Rm, shiftnames[shift], imm6);
|
||||
}
|
||||
} else if (((w >> 24) & 0x1f) == 0xB) {
|
||||
// Arithmetic (shifted register)
|
||||
} else if (((w >> 21) & 0xf9) == 0x58) {
|
||||
// Add/sub/cmp (shifted register)
|
||||
bool S = (w >> 29) & 1;
|
||||
int shift = (w >> 22) & 0x3;
|
||||
int imm6 = (w >> 10) & 0x3f;
|
||||
@ -340,7 +344,7 @@ static void DataProcessingRegister(uint32_t w, uint64_t addr, Instruction *instr
|
||||
} else {
|
||||
snprintf(instr->text, sizeof(instr->text), "(logical-shifted-register %08x", w);
|
||||
}
|
||||
} else if (((w >> 21) & 0xF) == 9) {
|
||||
} else if (((w >> 21) & 0xFF) == 0x59) {
|
||||
// Add/sub (extended register)
|
||||
bool S = (w >> 29) & 1;
|
||||
bool sub = (w >> 30) & 1;
|
||||
@ -356,6 +360,29 @@ static void DataProcessingRegister(uint32_t w, uint64_t addr, Instruction *instr
|
||||
// Variable shifts
|
||||
int opc = (w >> 10) & 3;
|
||||
snprintf(instr->text, sizeof(instr->text), "%sv %c%d, %c%d, %c%d", shiftnames[opc], r, Rd, r, Rn, r, Rm);
|
||||
} else if (((w >> 21) & 0xFF) == 0xD4) {
|
||||
// Conditional select
|
||||
int op = (w >> 30) & 1;
|
||||
int op2 = (w >> 10) & 3;
|
||||
int cond = (w >> 12) & 0xf;
|
||||
const char *opnames[4] = { "csel", "csinc", "csinv", "csneg" };
|
||||
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d, %c%d, %s", opnames[(op << 1) | op2], r, Rd, r, Rn, r, Rm, condnames[cond]);
|
||||
} else if (((w >> 24) & 0x1f) == 0x1b) {
|
||||
// Data processing - 3 source
|
||||
int op31 = (w >> 21) & 0x7;
|
||||
int o0 = (w >> 15) & 1;
|
||||
int Ra = (w >> 10) & 0x1f;
|
||||
const char *opnames[8] = { 0, 0, "maddl", "msubl", "smulh", 0, 0, 0 };
|
||||
|
||||
if (op31 == 0) {
|
||||
// madd/msub supports both 32-bit and 64-bit modes
|
||||
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d, %c%d, %c%d", o0 ? "msub" : "madd", r, Rd, r, Rn, r, Rm, r, Ra);
|
||||
} else {
|
||||
// The rest are 64-bit accumulator, 32-bit operands
|
||||
char sign = (op31 >> 2) ? 'u' : 's';
|
||||
int opn = (op31 & 0x3) << 1 | o0;
|
||||
snprintf(instr->text, sizeof(instr->text), "%c%s x%d, x%d, w%d, w%d", sign, opnames[opn], Rd, Rn, Rm, Ra);
|
||||
}
|
||||
} else {
|
||||
// Logical (extended register)
|
||||
snprintf(instr->text, sizeof(instr->text), "(DPR %08x)", w);
|
||||
|
@ -39,6 +39,16 @@ bool TestArm64Emitter() {
|
||||
//RET(CheckLast(emitter, "aa023be1 fmov s1, w3"));
|
||||
//fp.FMOV(32, false, X1, S3);
|
||||
//RET(CheckLast(emitter, "aa023be1 fmov x1, s3"));
|
||||
//fp.UCVTF(S12, X3, 8);
|
||||
//RET(CheckLast(emitter, "b86c6877 ucvtf s12, x3, #8"));
|
||||
emitter.MADD(W3, W7, W1, W8);
|
||||
RET(CheckLast(emitter, "1b0120e3 madd w3, w7, w1, w8"));
|
||||
emitter.SMADDL(X3, X6, W1, W8);
|
||||
RET(CheckLast(emitter, "9b2120c3 smaddl x3, x6, w1, w8"));
|
||||
emitter.BRK(3);
|
||||
RET(CheckLast(emitter, "d4200060 brk #3"));
|
||||
emitter.CSEL(X3, X5, X7, CC_GT);
|
||||
RET(CheckLast(emitter, "9a87c0a3 csel x3, x5, x7, gt"));
|
||||
emitter.LDR(W23, X3, X12);
|
||||
RET(CheckLast(emitter, "b86c6877 ldr w23, [x3 + x12]"));
|
||||
emitter.LDP(INDEX_SIGNED, W23, W5, X3, 36);
|
||||
|
Loading…
x
Reference in New Issue
Block a user