ARM64: Add a few aliases to emitter. Disasm fixes.

This commit is contained in:
Henrik Rydgard 2015-03-24 00:29:12 +01:00
parent acf08eefa8
commit 4618275f99
4 changed files with 33 additions and 2 deletions

View File

@ -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();

View File

@ -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++

View File

@ -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)

View File

@ -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);