From 48884cd80b52be1528618f2e9b3425ac24e7b5ca Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 25 Aug 2007 00:47:38 +0000 Subject: [PATCH] rename isOperandValidForConstraint to LowerAsmOperandForConstraint, changing the interface to allow for future changes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41384 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 11 ++--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 12 ++--- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 24 ++++----- lib/Target/PowerPC/PPCISelLowering.cpp | 32 +++++++----- lib/Target/PowerPC/PPCISelLowering.h | 9 +++- lib/Target/X86/X86ISelLowering.cpp | 49 ++++++++++++------- lib/Target/X86/X86ISelLowering.h | 12 +++-- 7 files changed, 90 insertions(+), 59 deletions(-) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 510dd6e91fe..f566038e4c4 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -907,12 +907,11 @@ public: 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. - virtual SDOperand - isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, - SelectionDAG &DAG); + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); //===--------------------------------------------------------------------===// // Scheduler hooks diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 1dde705bf59..7439e617d3e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3623,20 +3623,20 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { assert(!OpInfo.isIndirect && "Don't know how to handle indirect other inputs yet!"); - InOperandVal = TLI.isOperandValidForConstraint(InOperandVal, - OpInfo.ConstraintCode[0], - DAG); - if (!InOperandVal.Val) { + std::vector Ops; + TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0], + Ops, DAG); + if (Ops.empty()) { cerr << "Invalid operand for inline asm constraint '" << OpInfo.ConstraintCode << "'!\n"; exit(1); } // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = 3 /*IMM*/ | (1 << 3); + unsigned ResOpType = 3 /*IMM*/ | (Ops.size() << 3); AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, TLI.getPointerTy())); - AsmNodeOperands.push_back(InOperandVal); + AsmNodeOperands.insert(AsmNodeOperands.end(), Ops.begin(), Ops.end()); break; } else if (OpInfo.ConstraintType == TargetLowering::C_Memory) { assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!"); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 2e91359b430..9597696d2dc 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1354,12 +1354,12 @@ TargetLowering::getConstraintType(const std::string &Constraint) const { return C_Unknown; } -/// isOperandValidForConstraint - Return the specified operand (possibly -/// modified) if the specified SDOperand is valid for the specified target -/// constraint letter, otherwise return null. -SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op, - char ConstraintLetter, - SelectionDAG &DAG) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG) { switch (ConstraintLetter) { default: break; case 'i': // Simple Integer or Relocatable Constant @@ -1390,19 +1390,21 @@ SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op, if (ConstraintLetter != 'n') { int64_t Offs = GA->getOffset(); if (C) Offs += C->getValue(); - return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(), - Offs); + Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), + Op.getValueType(), Offs)); + return; } } if (C) { // just C, no GV. // Simple constants are not allowed for 's'. - if (ConstraintLetter != 's') - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (ConstraintLetter != 's') { + Ops.push_back(DAG.getTargetConstant(C->getValue(), Op.getValueType())); + return; + } } break; } } - return SDOperand(0,0); } std::vector TargetLowering:: diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 6f4d923cff9..5b738a5085e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3338,9 +3338,12 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, } -// isOperandValidForConstraint -SDOperand PPCTargetLowering:: -isOperandValidForConstraint(SDOperand Op, char Letter, SelectionDAG &DAG) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void PPCTargetLowering::LowerAsmOperandForConstraint(SDOperand Op, char Letter, + std::vector&Ops, + SelectionDAG &DAG) { + SDOperand Result(0,0); switch (Letter) { default: break; case 'I': @@ -3352,46 +3355,51 @@ isOperandValidForConstraint(SDOperand Op, char Letter, SelectionDAG &DAG) { case 'O': case 'P': { ConstantSDNode *CST = dyn_cast(Op); - if (!CST) return SDOperand(0, 0); // Must be an immediate to match. + if (!CST) return; // Must be an immediate to match. unsigned Value = CST->getValue(); switch (Letter) { default: assert(0 && "Unknown constraint letter!"); case 'I': // "I" is a signed 16-bit constant. if ((short)Value == (int)Value) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'J': // "J" is a constant with only the high-order 16 bits nonzero. case 'L': // "L" is a signed 16-bit constant shifted left 16 bits. if ((short)Value == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'K': // "K" is a constant with only the low-order 16 bits nonzero. if ((Value >> 16) == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'M': // "M" is a constant that is greater than 31. if (Value > 31) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'N': // "N" is a positive constant that is an exact power of two. if ((int)Value > 0 && isPowerOf2_32(Value)) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'O': // "O" is the constant zero. if (Value == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'P': // "P" is a constant whose negation is a signed 16-bit constant. if ((short)-Value == (int)-Value) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; } break; } } + if (Result.Val) { + Ops.push_back(Result); + return; + } + // Handle standard constraint letters. - return TargetLowering::isOperandValidForConstraint(Op, Letter, DAG); + TargetLowering::LowerAsmOperandForConstraint(Op, Letter, Ops, DAG); } // isLegalAddressingMode - Return true if the addressing mode represented diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index b6b52ef31e1..33f63814bc0 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -244,9 +244,14 @@ namespace llvm { std::pair getRegForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; - SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, - SelectionDAG &DAG); + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); + /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index f32e6f6ead2..6673c5f6399 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5002,29 +5002,38 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const { return TargetLowering::getConstraintType(Constraint); } -/// 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) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, + char Constraint, + std::vector&Ops, + SelectionDAG &DAG) { + SDOperand Result(0, 0); + switch (Constraint) { default: break; case 'I': if (ConstantSDNode *C = dyn_cast(Op)) { - if (C->getValue() <= 31) - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (C->getValue() <= 31) { + Result = DAG.getTargetConstant(C->getValue(), Op.getValueType()); + break; + } } - return SDOperand(0,0); + return; case 'N': if (ConstantSDNode *C = dyn_cast(Op)) { - if (C->getValue() <= 255) - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (C->getValue() <= 255) { + Result = DAG.getTargetConstant(C->getValue(), Op.getValueType()); + break; + } } - return SDOperand(0,0); + return; case 'i': { // Literal immediates are always ok. - if (ConstantSDNode *CST = dyn_cast(Op)) - return DAG.getTargetConstant(CST->getValue(), Op.getValueType()); + if (ConstantSDNode *CST = dyn_cast(Op)) { + Result = DAG.getTargetConstant(CST->getValue(), Op.getValueType()); + break; + } // If we are in non-pic codegen mode, we allow the address of a global (with // an optional displacement) to be used with 'i'. @@ -5054,18 +5063,24 @@ isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) { // match. if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(), getTargetMachine(), false)) - return SDOperand(0, 0); + return; Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), Offset); - return Op; + Result = Op; + break; } // Otherwise, not valid for this mode. - return SDOperand(0, 0); + return; } } - return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG); + + if (Result.Val) { + Ops.push_back(Result); + return; + } + return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } std::vector X86TargetLowering:: diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 022005d0027..24ca1ea44bf 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -330,11 +330,13 @@ 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); + + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); /// getRegForInlineAsmConstraint - Given a physical register constraint /// (e.g. {edx}), return the register number and the register class for the