[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
This commit is contained in:
Richard Osborne 2014-03-06 16:37:48 +00:00
parent 28bfb48fd0
commit 47155af5eb
3 changed files with 64 additions and 1 deletions

View File

@ -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);

View File

@ -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<SDValue> &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<SDValue> &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()) {

View File

@ -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
}