[llvm] r205889 - [ARM64] Fix canonicalisation of MOVs. MOV is too complex to be modelled by a dumb alias.
Bradley Smith
bradley.smith at arm.com
Wed Apr 9 07:44:18 PDT 2014
Author: brasmi01
Date: Wed Apr 9 09:44:18 2014
New Revision: 205889
URL: http://llvm.org/viewvc/llvm-project?rev=205889&view=rev
Log:
[ARM64] Fix canonicalisation of MOVs. MOV is too complex to be modelled by a dumb alias.
Modified:
llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt
Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td Wed Apr 9 09:44:18 2014
@@ -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",
Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Wed Apr 9 09:44:18 2014
@@ -3732,9 +3732,9 @@ bool ARM64AsmParser::validateInstruction
}
}
-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::O
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::MatchAndEmitInstruc
// 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::MatchAndEmitInstruc
// 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") {
Modified: llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp Wed Apr 9 09:44:18 2014
@@ -52,7 +52,7 @@ void ARM64InstPrinter::printRegName(raw_
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 M
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);
Modified: llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt Wed Apr 9 09:44:18 2014
@@ -11,3 +11,7 @@
0x08 0x20 0x21 0x1e
# CHECK: fcmp s0, #0.0
+
+0x1f 0x00 0x00 0x11
+
+# CHECK: mov wsp, w0
More information about the llvm-commits
mailing list