From 47155af5eba79a0b23f46fb8da20fd34fd678723 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Thu, 6 Mar 2014 16:37:48 +0000 Subject: [PATCH] [XCore] Add support for the "m" inline asm constraint. Summary: This provides support for CP and DP relative global accesses in inline asm. Reviewers: robertlytton Reviewed By: robertlytton Differential Revision: http://llvm-reviews.chandlerc.com/D2943 llvm-svn: 203129 --- llvm/lib/Target/XCore/XCoreAsmPrinter.cpp | 17 +++++++++++++ llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp | 27 ++++++++++++++++++++- llvm/test/CodeGen/XCore/inline-asm.ll | 21 ++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp index ea4f1964a782..21acedf7be29 100644 --- a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -71,6 +71,9 @@ namespace { bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); virtual void EmitGlobalVariable(const GlobalVariable *GV); @@ -248,6 +251,20 @@ bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); } +bool XCoreAsmPrinter:: +PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) { + if (ExtraCode && ExtraCode[0]) { + return true; // Unknown modifier. + } + printOperand(MI, OpNum, O); + O << '['; + printOperand(MI, OpNum + 1, O); + O << ']'; + return false; +} + void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { SmallString<128> Str; raw_svector_ostream O(Str); diff --git a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp index e28f84fec2a9..5b0fcfa15e4d 100644 --- a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -66,7 +66,10 @@ namespace { // Complex Pattern Selectors. bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset); - + + bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector &OutOps) override; + virtual const char *getPassName() const { return "XCore DAG->DAG Pattern Instruction Selection"; } @@ -106,6 +109,28 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, return false; } +bool XCoreDAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector &OutOps) { + SDValue Reg; + switch (ConstraintCode) { + default: return true; + case 'm': // Memory. + switch (Op.getOpcode()) { + default: return true; + case XCoreISD::CPRelativeWrapper: + Reg = CurDAG->getRegister(XCore::CP, MVT::i32); + break; + case XCoreISD::DPRelativeWrapper: + Reg = CurDAG->getRegister(XCore::DP, MVT::i32); + break; + } + } + OutOps.push_back(Reg); + OutOps.push_back(Op.getOperand(0)); + return false; +} + SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { SDLoc dl(N); switch (N->getOpcode()) { diff --git a/llvm/test/CodeGen/XCore/inline-asm.ll b/llvm/test/CodeGen/XCore/inline-asm.ll index af3edd1544a2..e9f5b5769997 100644 --- a/llvm/test/CodeGen/XCore/inline-asm.ll +++ b/llvm/test/CodeGen/XCore/inline-asm.ll @@ -30,3 +30,24 @@ entry: tail call void asm sideeffect "foo ${0:n}", "i"(i32 99) nounwind ret void } + +@x = external global i32 +@y = external global i32, section ".cp.rodata" + +; CHECK-LABEL: f5: +; CHECK: ldw r0, dp[x] +; CHECK: retsp 0 +define i32 @f5() nounwind { +entry: + %asmtmp = call i32 asm "ldw $0, $1", "=r,*m"(i32* @x) nounwind + ret i32 %asmtmp +} + +; CHECK-LABEL: f6: +; CHECK: ldw r0, cp[y] +; CHECK: retsp 0 +define i32 @f6() nounwind { +entry: + %asmtmp = call i32 asm "ldw $0, $1", "=r,*m"(i32* @y) nounwind + ret i32 %asmtmp +}