mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-10 00:05:07 +00:00
ARM64: Add a few aliases to emitter. Disasm fixes.
This commit is contained in:
parent
acf08eefa8
commit
4618275f99
@ -1901,6 +1901,22 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
|
||||
}
|
||||
}
|
||||
|
||||
void ARM64XEmitter::PUSH(ARM64Reg Rd) {
|
||||
STR(INDEX_PRE, Rd, SP, -16);
|
||||
}
|
||||
|
||||
void ARM64XEmitter::POP(ARM64Reg Rd) {
|
||||
LDR(INDEX_POST, Rd, SP, 16);
|
||||
}
|
||||
|
||||
void ARM64XEmitter::PUSH2(ARM64Reg Rd, ARM64Reg Rn) {
|
||||
STP(INDEX_PRE, Rd, Rn, SP, -16);
|
||||
}
|
||||
void ARM64XEmitter::POP2(ARM64Reg Rd, ARM64Reg Rn) {
|
||||
LDP(INDEX_POST, Rd, Rn, SP, 16);
|
||||
}
|
||||
|
||||
|
||||
void ARM64XEmitter::ABI_PushRegisters(BitSet32 registers)
|
||||
{
|
||||
int num_regs = registers.Count();
|
||||
|
@ -496,6 +496,9 @@ public:
|
||||
ARM64Reg zr = Is64Bit(Rd) ? ZR : WZR;
|
||||
CSINC(Rd, zr, zr, (CCFlags)((u32)cond ^ 1));
|
||||
}
|
||||
void NEG(ARM64Reg Rd, ARM64Reg Rs) {
|
||||
SUB(Rd, Is64Bit(Rd) ? ZR : WZR, Rs);
|
||||
}
|
||||
|
||||
// Data-Processing 1 source
|
||||
void RBIT(ARM64Reg Rd, ARM64Reg Rn);
|
||||
@ -711,6 +714,14 @@ public:
|
||||
void ABI_PushRegisters(BitSet32 registers);
|
||||
void ABI_PopRegisters(BitSet32 registers, BitSet32 ignore_mask = BitSet32(0));
|
||||
|
||||
// Pseudo-instruction for convenience. PUSH pushes 16 bytes even though we only push a single register.
|
||||
// This is so the stack pointer is always 16-byte aligned, which is checked by hardware!
|
||||
void PUSH(ARM64Reg Rd);
|
||||
void POP(ARM64Reg Rd);
|
||||
void PUSH2(ARM64Reg Rd, ARM64Reg Rn);
|
||||
void POP2(ARM64Reg Rd, ARM64Reg Rn);
|
||||
|
||||
|
||||
// Utility to generate a call to a std::function object.
|
||||
//
|
||||
// Unfortunately, calling operator() directly is undefined behavior in C++
|
||||
|
@ -141,7 +141,7 @@ static void DataProcessingImmediate(uint32_t w, uint64_t addr, Instruction *inst
|
||||
} else if (((w >> 24) & 0x1F) == 0x10) {
|
||||
// Address generation relative to PC
|
||||
int op = w >> 31;
|
||||
int imm = SignExtend19(w >> 5);
|
||||
int imm = (SignExtend19(w >> 5) << 2) | ((w >> 29) & 3);
|
||||
if (op & 1) imm <<= 12;
|
||||
u64 daddr = addr + imm;
|
||||
snprintf(instr->text, sizeof(instr->text), "%s x%d, #0x%04x%08x", op ? "adrp" : "adr", Rd, daddr >> 32, daddr & 0xFFFFFFFF);
|
||||
@ -358,7 +358,7 @@ static void DataProcessingRegister(uint32_t w, uint64_t addr, Instruction *instr
|
||||
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d, %c%d", opnames[opc], r, Rd, r, Rn, r, Rm);
|
||||
}
|
||||
} else {
|
||||
snprintf(instr->text, sizeof(instr->text), "(logical-shifted-register %08x", w);
|
||||
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 >> 21) & 0xFF) == 0x59) {
|
||||
// Add/sub (extended register)
|
||||
|
@ -26,6 +26,8 @@ static void DisassembleARMBetween(const u8 *start, const u8 *end) {
|
||||
}
|
||||
}
|
||||
|
||||
#undef ADD
|
||||
|
||||
bool TestArm64Emitter() {
|
||||
using namespace Arm64Gen;
|
||||
|
||||
@ -37,6 +39,8 @@ bool TestArm64Emitter() {
|
||||
ARM64XEmitter emitter((u8 *)code);
|
||||
ARM64FloatEmitter fp(&emitter);
|
||||
|
||||
emitter.ADD(X1, X2, X3, ArithOption(X1, ST_LSL, 3));
|
||||
RET(CheckLast(emitter, "8b030c41 add x1, x2, x3, lsl #3")); // A real disasm says fmla v0.2s, v1.2s, v2.s[1] but I think our way is more readable
|
||||
//emitter.EXTR(W1, W3, 0, 7);
|
||||
//RET(CheckLast(emitter, "53033061 extr w1, w3, w7"));
|
||||
//fp.FCVTL(32, Q6, D25);
|
||||
|
Loading…
x
Reference in New Issue
Block a user