ARM64: LLVM buildfix, some more disasm

This commit is contained in:
Henrik Rydgård authored and Henrik Rydgard committed 2015-04-06 18:13:39 +02:00
1 parent 13c9390c53
commit 065cd97dc2
3 files changed
+86 -4

No files matched your search

+7 -2
View File
@@ -1820,6 +1820,11 @@ void ARM64XEmitter::ADRP(ARM64Reg Rd, s32 imm)
EncodeAddressInst(1, Rd, imm >> 12);
}
// LLVM is unhappy about the regular abs function, so here we go.
inline int64_t abs64(int64_t x) {
return x >= 0 ? x : -x;
}
// Wrapper around MOVZ+MOVK (and later MOVN)
void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
{
@@ -1868,11 +1873,11 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
u64 aligned_pc = (u64)GetCodePtr() & ~0xFFF;
s64 aligned_offset = (s64)imm - (s64)aligned_pc;
if (upload_part.Count() > 1 && std::abs(aligned_offset) < 0xFFFFFFFFLL)
if (upload_part.Count() > 1 && abs64(aligned_offset) < 0xFFFFFFFFLL)
{
// Immediate we are loading is within 4GB of our aligned range
// Most likely a address that we can load in one or two instructions
if (!(std::abs(aligned_offset) & 0xFFF))
if (!(abs64(aligned_offset) & 0xFFF))
{
// Aligned ADR
ADRP(Rd, (s32)aligned_offset);
+75 -2
View File
@@ -433,9 +433,82 @@ static void FPandASIMD1(uint32_t w, uint64_t addr, Instruction *instr) {
int Rm = (w >> 16) & 0x1f;
if (((w >> 21) & 0x4F9) == 0x71) {
switch ((w >> 10) & 3) {
case 1: case 3:
snprintf(instr->text, sizeof(instr->text), "(asimd three-same %08x)", w);
case 1: case 3: {
int opcode = (w >> 11) & 0x1f;
int sz = (w >> 22) & 3;
int Q = GetQ(w);
int U = GetU(w);
const char *opnames000[32] = {
"shadd", "sqadd", "srhadd", 0,
"shsub", "sqsub", "cmgt", "cmge",
"sshl", "sqshl", "srshl", "sqrshl",
"smax", "smin", "sabd", "saba",
"add", "cmtst", "mla", "mul",
"smaxp", "sminp", "sqdmulh", "addp",
"fmaxnm", "fmla", "fadd", "fmulx",
"fcmeq", 0, "fmax", "frecps",
};
const char *opnames100[32] = {
"uhadd", "uqadd", "urhadd", 0,
"uhsub", "uqsub", "cmhi", "cmhs",
"ushl", "uqshl", "urshl", "uqrshl",
"umax", "umin", "uabd", "uaba",
"sub", "cmeq", "mls", "pmul",
"umaxp", "uminp", "sqrdmulh", "addp",
"fmaxnmp", 0, "faddp", "fmul",
"fcmge", "facge", "fmaxp", "fdiv",
};
const char *opnames010[8] = {
"fminm", "fmls", "fsub", 0,
0, 0, "fmin", "frsqrts",
};
const char *opnames110[8] = {
"fminnmp", 0, "fabd", 0,
"fcmgt", "facgt", "fminp", 0,
};
char r = Q ? 'q' : 'd';
const char *opname = nullptr;
bool fp = false;
if (U == 0) {
if (opcode < 0x18) {
opname = opnames000[opcode];
} else if ((sz & 0x2) == 0) {
opname = opnames000[opcode];
fp = true;
} else if ((sz & 0x2) == 2) {
opname = opnames010[opcode - 0x18];
fp = true;
}
if (!opname && opcode == 3 && (sz & 2) == 0) {
opname = !(sz & 1) ? "and" : "bic";
} else if (!opname && opcode == 3 && (sz & 2) == 2) {
opname = !(sz & 1) ? "orr" : "orn";
}
} else if (U == 1) {
if (opcode < 0x18) {
opname = opnames100[opcode];
} else if ((sz & 0x2) == 0) {
opname = opnames100[opcode];
fp = true;
} else if ((sz & 0x2) == 2) {
opname = opnames110[opcode - 0x18];
fp = true;
}
if (!opname && opcode == 3 && (sz & 2) == 0) {
opname = !(sz & 1) ? "eor" : "bsl";
} else if (!opname && opcode == 3 && (sz & 2) == 2) {
opname = !(sz & 1) ? "bit" : "bif";
}
}
int size = (fp ? ((sz & 1) ? 64 : 32) : (sz << 3));
if (opname != nullptr) {
snprintf(instr->text, sizeof(instr->text), "%s.%d %c%d, %c%d, %c%d", opname, size, r, Rd, r, Rn, r, Rm);
} else {
snprintf(instr->text, sizeof(instr->text), "(asimd three-same %08x)", w);
}
break;
}
case 0:
snprintf(instr->text, sizeof(instr->text), "(asimd three-different %08x)", w);
break;
+4
View File
@@ -40,6 +40,10 @@ bool TestArm64Emitter() {
ARM64FloatEmitter fp(&emitter);
fp.FADD(32, Q1, Q13, Q21);
RET(CheckLast(emitter, "4e35d5a1 fadd.32 q1, q13, q21"));
fp.FMUL(32, D1, D13, D21);
RET(CheckLast(emitter, "2e35dda1 fmul.32 d1, d13, d21"));
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);