ARM64: Just some disasm improvements

This commit is contained in:
Henrik Rydgard 2015-03-25 22:59:12 +01:00
parent ad3d539451
commit 7d918c0ad8
2 changed files with 35 additions and 4 deletions

View file

@ -82,6 +82,15 @@ int HighestSetBit(int value) {
return highest;
}
int LowestSetBit(int value, int maximum = 32) {
int lowest = 0;
for (int i = 0; i < maximum; i++) {
if (value & (1 << i))
return i;
}
return maximum;
}
static uint64_t Ones(int len) {
if (len == 0x40) {
return 0xFFFFFFFFFFFFFFFF;
@ -354,6 +363,9 @@ static void DataProcessingRegister(uint32_t w, uint64_t addr, Instruction *instr
if (Rd == 31 && opc == 3) {
// It's a CMP
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d", "cmp", r, Rn, r, Rm);
} else if (Rn == 31 && opc == 2) {
// It's a NEG
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d", "neg", r, Rd, r, Rm);
} else {
snprintf(instr->text, sizeof(instr->text), "%s %c%d, %c%d, %c%d", opnames[opc], r, Rd, r, Rn, r, Rm);
}
@ -413,6 +425,7 @@ const char *GetArrangement(bool Q, bool sz) {
else if (Q == 1 && sz == 1) return "2d";
else return "ERROR";
}
// (w >> 25) & 0xF == 7
static void FPandASIMD1(uint32_t w, uint64_t addr, Instruction *instr) {
int Rd = w & 0x1f;
@ -438,7 +451,20 @@ static void FPandASIMD1(uint32_t w, uint64_t addr, Instruction *instr) {
}
} else if (((w >> 21) & 0x4F9) == 0x70) {
if (((w >> 10) & 0x21) == 1) {
snprintf(instr->text, sizeof(instr->text), "(asimd copy %08x)", w);
if (((w >> 11) & 3) == 3) {
// From GPR
snprintf(instr->text, sizeof(instr->text), "(asimd copy gpr %08x)", w);
} else {
int imm5 = (w >> 16) & 0x1F;
int size = LowestSetBit(imm5, 5);
int imm4 = (w >> 11) & 0xF;
int dst_index = imm5 >> (size + 1);
int src_index = imm4 >> size;
int idxdsize = (imm4 & 8) ? 128 : 64;
char s = "bhdx"[size];
char r = "dq"[idxdsize == 128];
snprintf(instr->text, sizeof(instr->text), "ins %c%d.%c[%d], %c%d.%c[%d]", r, Rd, s, dst_index, r, Rn, s, src_index);
}
}
} else if (((w >> 21) & 0x4F8) == 0x78) {
if ((w >> 10) & 1) {

View file

@ -39,15 +39,20 @@ bool TestArm64Emitter() {
ARM64XEmitter emitter((u8 *)code);
ARM64FloatEmitter fp(&emitter);
fp.INS(32, Q3, 1, Q12, 3);
RET(CheckLast(emitter, "6e0c6583 ins q3.d[1], q12.d[3]"));
fp.INS(8, D4, 5, D11, 2);
RET(CheckLast(emitter, "6e0b1564 ins d4.b[5], d11.b[2]"));
emitter.NEG(X1, X2);
RET(CheckLast(emitter, "8b030c41 neg x1, x2")); // A real disasm says fmla v0.2s, v1.2s, v2.s[1] but I think our way is more readable
RET(CheckLast(emitter, "cb0203e1 neg x1, x2"));
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
RET(CheckLast(emitter, "8b030c41 add x1, x2, x3, lsl #3"));
//emitter.EXTR(W1, W3, 0, 7);
//RET(CheckLast(emitter, "53033061 extr w1, w3, w7"));
//fp.FCVTL(32, Q6, D25);
//RET(CheckLast(emitter, "4fa29820 fcvtl q6, d25")); // A real disasm says fmla v0.2s, v1.2s, v2.s[1] but I think our way is more readable
//RET(CheckLast(emitter, "4fa29820 fcvtl q6, d25"));
fp.FMUL(32, Q0, Q1, Q2, 3);
RET(CheckLast(emitter, "4fa29820 fmul q0, q1, q2.4s[3]")); // A real disasm says fmla v0.2s, v1.2s, v2.s[1] but I think our way is more readable
fp.FMLA(32, D0, D1, D2, 1);