summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 250f973)
raw | patch | inline | side by side (parent: 250f973)
author | Bradley Smith <bradley.smith@arm.com> | |
Wed, 9 Apr 2014 14:44:18 +0000 (14:44 +0000) | ||
committer | Bradley Smith <bradley.smith@arm.com> | |
Wed, 9 Apr 2014 14:44:18 +0000 (14:44 +0000) |
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205889 91177308-0d34-0410-b5e6-96231b3b80d8
index 35a73f923c88e975b43594e7b03b6ef0d53871de..241ada9ca2d0b0eeecec634bb7f0c73dc65876e7 100644 (file)
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",
diff --git a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
index ee985772878418d38dc82181661d1f77d5c74a7d..e50057960581f8b8f41b2b29cf42d1bf5ca8d245 100644 (file)
}
}
-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] =
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:
// 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())) {
// 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") {
diff --git a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
index 7d1dd50b720bb5bd5597cd8996a99b57a1c3ce4b..f702522ef33394d0ca25319d501a2ead4c368d17 100644 (file)
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();
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);
diff --git a/test/MC/Disassembler/ARM64/canonical-form.txt b/test/MC/Disassembler/ARM64/canonical-form.txt
index 3172fd2521faaf5b163b99d05891102dc9e8e378..80c032d71a9019694e31ecf69504310eac5029db 100644 (file)
0x08 0x20 0x21 0x1e
# CHECK: fcmp s0, #0.0
+
+0x1f 0x00 0x00 0x11
+
+# CHECK: mov wsp, w0