forked from OSchip/llvm-project
[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:
parent
28bfb48fd0
commit
47155af5eb
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue