diff options
author | Chris Lattner <sabre@nondot.org> | 2006-10-31 20:13:11 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-10-31 20:13:11 +0000 |
commit | 22aaf1d61c6a752d66f7ee10a7a5d99c7160e007 (patch) | |
tree | 8d29fb829541043690684b406bc9840c00397c98 | |
parent | 0d924994556f5332216b41e3b1d3b8acc97d2099 (diff) |
allow the address of a global to be used with the "i" constraint when in
-static mode. This implements PR882.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31326 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 30 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 7 |
2 files changed, 36 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 83bf280733..92bec9174e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5466,6 +5466,36 @@ X86TargetLowering::getConstraintType(char ConstraintLetter) const { } } +/// isOperandValidForConstraint - Return the specified operand (possibly +/// modified) if the specified SDOperand is valid for the specified target +/// constraint letter, otherwise return null. +SDOperand X86TargetLowering:: +isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) { + switch (Constraint) { + default: break; + case 'i': + // Literal immediates are always ok. + if (isa<ConstantSDNode>(Op)) return Op; + + // If we are in non-pic codegen mode, we allow the address of a global to + // be used with 'i'. + if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) + return SDOperand(0, 0); + + if (GA->getOpcode() != ISD::TargetGlobalAddress) + Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), + GA->getOffset()); + return Op; + } + + // Otherwise, not valid for this mode. + return SDOperand(0, 0); + } + return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG); +} + + std::vector<unsigned> X86TargetLowering:: getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const { diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 6de2964ec7..dde123c02f 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -300,7 +300,12 @@ namespace llvm { std::vector<unsigned> getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; - + /// isOperandValidForConstraint - Return the specified operand (possibly + /// modified) if the specified SDOperand is valid for the specified target + /// constraint letter, otherwise return null. + SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, + SelectionDAG &DAG); + /// getRegForInlineAsmConstraint - Given a physical register constraint /// (e.g. {edx}), return the register number and the register class for the /// register. This should only be used for C_Register constraints. On |