mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-11 06:56:12 +00:00
[ARM64] Fix canonicalisation of MOVs. MOV is too complex to be modelled by a dumb alias.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205889 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
250f973d7f
commit
7b5940c0c0
@ -604,13 +604,6 @@ defm ORN : LogicalReg<0b01, 1, "orn",
|
||||
BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
||||
defm ORR : LogicalReg<0b01, 0, "orr", or>;
|
||||
|
||||
def : InstAlias<"mov $dst, $src", (ORRWrs GPR32:$dst, WZR, GPR32:$src, 0)>;
|
||||
def : InstAlias<"mov $dst, $src",
|
||||
(ADDWri GPR32sp:$dst, GPR32sp:$src, 0, 0)>;
|
||||
def : InstAlias<"mov $dst, $src", (ORRXrs GPR64:$dst, XZR, GPR64:$src, 0)>;
|
||||
def : InstAlias<"mov $dst, $src",
|
||||
(ADDXri GPR64sp:$dst, GPR64sp:$src, 0, 0)>;
|
||||
|
||||
def : InstAlias<"tst $src1, $src2",
|
||||
(ANDSWri WZR, GPR32:$src1, logical_imm32:$src2)>;
|
||||
def : InstAlias<"tst $src1, $src2",
|
||||
|
@ -3732,9 +3732,9 @@ bool ARM64AsmParser::validateInstruction(MCInst &Inst,
|
||||
}
|
||||
}
|
||||
|
||||
static void rewriteMOV(ARM64AsmParser::OperandVector &Operands,
|
||||
StringRef mnemonic, uint64_t imm, unsigned shift,
|
||||
MCContext &Context) {
|
||||
static void rewriteMOVI(ARM64AsmParser::OperandVector &Operands,
|
||||
StringRef mnemonic, uint64_t imm, unsigned shift,
|
||||
MCContext &Context) {
|
||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
|
||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
||||
Operands[0] =
|
||||
@ -3750,6 +3750,43 @@ static void rewriteMOV(ARM64AsmParser::OperandVector &Operands,
|
||||
delete Op;
|
||||
}
|
||||
|
||||
static void rewriteMOVRSP(ARM64AsmParser::OperandVector &Operands,
|
||||
MCContext &Context) {
|
||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
|
||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
||||
Operands[0] =
|
||||
ARM64Operand::CreateToken("add", false, Op->getStartLoc(), Context);
|
||||
|
||||
const MCExpr *Imm = MCConstantExpr::Create(0, Context);
|
||||
Operands.push_back(ARM64Operand::CreateImm(Imm, Op2->getStartLoc(),
|
||||
Op2->getEndLoc(), Context));
|
||||
Operands.push_back(ARM64Operand::CreateShifter(
|
||||
ARM64_AM::LSL, 0, Op2->getStartLoc(), Op2->getEndLoc(), Context));
|
||||
|
||||
delete Op;
|
||||
}
|
||||
|
||||
static void rewriteMOVR(ARM64AsmParser::OperandVector &Operands,
|
||||
MCContext &Context) {
|
||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
|
||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
||||
Operands[0] =
|
||||
ARM64Operand::CreateToken("orr", false, Op->getStartLoc(), Context);
|
||||
|
||||
// Operands[2] becomes Operands[3].
|
||||
Operands.push_back(Operands[2]);
|
||||
// And Operands[2] becomes ZR.
|
||||
unsigned ZeroReg = ARM64::XZR;
|
||||
if (isGPR32Register(Operands[2]->getReg()))
|
||||
ZeroReg = ARM64::WZR;
|
||||
|
||||
Operands[2] =
|
||||
ARM64Operand::CreateReg(ZeroReg, false, Op2->getStartLoc(),
|
||||
Op2->getEndLoc(), Context);
|
||||
|
||||
delete Op;
|
||||
}
|
||||
|
||||
bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
||||
switch (ErrCode) {
|
||||
case Match_MissingFeature:
|
||||
@ -3840,6 +3877,7 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
// FIXME: Catching this here is a total hack, and we should use tblgen
|
||||
// support to implement this instead as soon as it is available.
|
||||
|
||||
ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
|
||||
ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
|
||||
if (Op2->isImm()) {
|
||||
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op2->getImm())) {
|
||||
@ -3856,36 +3894,47 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
|
||||
// MOVK Rd, imm << 0
|
||||
if ((Val & 0xFFFF) == Val)
|
||||
rewriteMOV(Operands, "movz", Val, 0, getContext());
|
||||
rewriteMOVI(Operands, "movz", Val, 0, getContext());
|
||||
|
||||
// MOVK Rd, imm << 16
|
||||
else if ((Val & 0xFFFF0000ULL) == Val)
|
||||
rewriteMOV(Operands, "movz", Val, 16, getContext());
|
||||
rewriteMOVI(Operands, "movz", Val, 16, getContext());
|
||||
|
||||
// MOVK Rd, imm << 32
|
||||
else if ((Val & 0xFFFF00000000ULL) == Val)
|
||||
rewriteMOV(Operands, "movz", Val, 32, getContext());
|
||||
rewriteMOVI(Operands, "movz", Val, 32, getContext());
|
||||
|
||||
// MOVK Rd, imm << 48
|
||||
else if ((Val & 0xFFFF000000000000ULL) == Val)
|
||||
rewriteMOV(Operands, "movz", Val, 48, getContext());
|
||||
rewriteMOVI(Operands, "movz", Val, 48, getContext());
|
||||
|
||||
// MOVN Rd, (~imm << 0)
|
||||
else if ((NVal & 0xFFFFULL) == NVal)
|
||||
rewriteMOV(Operands, "movn", NVal, 0, getContext());
|
||||
rewriteMOVI(Operands, "movn", NVal, 0, getContext());
|
||||
|
||||
// MOVN Rd, ~(imm << 16)
|
||||
else if ((NVal & 0xFFFF0000ULL) == NVal)
|
||||
rewriteMOV(Operands, "movn", NVal, 16, getContext());
|
||||
rewriteMOVI(Operands, "movn", NVal, 16, getContext());
|
||||
|
||||
// MOVN Rd, ~(imm << 32)
|
||||
else if ((NVal & 0xFFFF00000000ULL) == NVal)
|
||||
rewriteMOV(Operands, "movn", NVal, 32, getContext());
|
||||
rewriteMOVI(Operands, "movn", NVal, 32, getContext());
|
||||
|
||||
// MOVN Rd, ~(imm << 48)
|
||||
else if ((NVal & 0xFFFF000000000000ULL) == NVal)
|
||||
rewriteMOV(Operands, "movn", NVal, 48, getContext());
|
||||
rewriteMOVI(Operands, "movn", NVal, 48, getContext());
|
||||
}
|
||||
} else if (Op1->isReg() && Op2->isReg()) {
|
||||
// reg->reg move.
|
||||
unsigned Reg1 = Op1->getReg();
|
||||
unsigned Reg2 = Op2->getReg();
|
||||
if ((Reg1 == ARM64::SP && isGPR64Reg(Reg2)) ||
|
||||
(Reg2 == ARM64::SP && isGPR64Reg(Reg1)) ||
|
||||
(Reg1 == ARM64::WSP && isGPR32Register(Reg2)) ||
|
||||
(Reg2 == ARM64::WSP && isGPR32Register(Reg1)))
|
||||
rewriteMOVRSP(Operands, getContext());
|
||||
else
|
||||
rewriteMOVR(Operands, getContext());
|
||||
}
|
||||
} else if (NumOperands == 4) {
|
||||
if (Tok == "add" || Tok == "adds" || Tok == "sub" || Tok == "subs") {
|
||||
|
@ -52,7 +52,7 @@ void ARM64InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
|
||||
|
||||
void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
StringRef Annot) {
|
||||
// Check for special encodings and print the cannonical alias instead.
|
||||
// Check for special encodings and print the canonical alias instead.
|
||||
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
|
||||
@ -250,6 +250,38 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
printExtend(MI, 3, O);
|
||||
return;
|
||||
}
|
||||
// ADD WSP, Wn, #0 ==> MOV WSP, Wn
|
||||
if (Opcode == ARM64::ADDWri && (MI->getOperand(0).getReg() == ARM64::WSP ||
|
||||
MI->getOperand(1).getReg() == ARM64::WSP) &&
|
||||
MI->getOperand(2).getImm() == 0 &&
|
||||
ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
|
||||
O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
|
||||
<< ", " << getRegisterName(MI->getOperand(1).getReg());
|
||||
return;
|
||||
}
|
||||
// ADD XSP, Wn, #0 ==> MOV XSP, Wn
|
||||
if (Opcode == ARM64::ADDXri && (MI->getOperand(0).getReg() == ARM64::SP ||
|
||||
MI->getOperand(1).getReg() == ARM64::SP) &&
|
||||
MI->getOperand(2).getImm() == 0 &&
|
||||
ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
|
||||
O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
|
||||
<< ", " << getRegisterName(MI->getOperand(1).getReg());
|
||||
return;
|
||||
}
|
||||
// ORR Wn, WZR, Wm ==> MOV Wn, Wm
|
||||
if (Opcode == ARM64::ORRWrs && MI->getOperand(1).getReg() == ARM64::WZR &&
|
||||
MI->getOperand(3).getImm() == 0) {
|
||||
O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
|
||||
<< ", " << getRegisterName(MI->getOperand(2).getReg());
|
||||
return;
|
||||
}
|
||||
// ORR Xn, XZR, Xm ==> MOV Xn, Xm
|
||||
if (Opcode == ARM64::ORRXrs && MI->getOperand(1).getReg() == ARM64::XZR &&
|
||||
MI->getOperand(3).getImm() == 0) {
|
||||
O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
|
||||
<< ", " << getRegisterName(MI->getOperand(2).getReg());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!printAliasInstr(MI, O))
|
||||
printInstruction(MI, O);
|
||||
|
@ -11,3 +11,7 @@
|
||||
0x08 0x20 0x21 0x1e
|
||||
|
||||
# CHECK: fcmp s0, #0.0
|
||||
|
||||
0x1f 0x00 0x00 0x11
|
||||
|
||||
# CHECK: mov wsp, w0
|
||||
|
Loading…
x
Reference in New Issue
Block a user