diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 83bf2807333..92bec9174e1 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(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(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 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 6de2964ec78..dde123c02f0 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -300,7 +300,12 @@ namespace llvm { std::vector 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