diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-01-22 01:29:51 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-01-22 01:29:51 +0000 |
commit | 29b1a24a4297f6fb5ab193e3cd5ab2a37a1e704f (patch) | |
tree | d93b2b36df14273ccb8a521c4b7929b733dbee46 /lib | |
parent | 825fc31bd3a6e7604c4b69f28f32e90b5a882289 (diff) | |
download | llvm-29b1a24a4297f6fb5ab193e3cd5ab2a37a1e704f.tar.gz llvm-29b1a24a4297f6fb5ab193e3cd5ab2a37a1e704f.tar.bz2 llvm-29b1a24a4297f6fb5ab193e3cd5ab2a37a1e704f.tar.xz |
[Sparc] Add support for inline assembly constraint 'I'.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199781 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.cpp | 60 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.h | 7 |
2 files changed, 67 insertions, 0 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 3abccdef6e..6dae29c45c 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -2923,12 +2923,72 @@ SparcTargetLowering::getConstraintType(const std::string &Constraint) const { switch (Constraint[0]) { default: break; case 'r': return C_RegisterClass; + case 'I': // SIMM13 + return C_Other; } } return TargetLowering::getConstraintType(Constraint); } +TargetLowering::ConstraintWeight SparcTargetLowering:: +getSingleConstraintMatchWeight(AsmOperandInfo &info, + const char *constraint) const { + ConstraintWeight weight = CW_Invalid; + Value *CallOperandVal = info.CallOperandVal; + // If we don't have a value, we can't do a match, + // but allow it at the lowest weight. + if (CallOperandVal == NULL) + return CW_Default; + + // Look at the constraint type. + switch (*constraint) { + default: + weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); + break; + case 'I': // SIMM13 + if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) { + if (isInt<13>(C->getSExtValue())) + weight = CW_Constant; + } + break; + } + return weight; +} + +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void SparcTargetLowering:: +LowerAsmOperandForConstraint(SDValue Op, + std::string &Constraint, + std::vector<SDValue> &Ops, + SelectionDAG &DAG) const { + SDValue Result(0, 0); + + // Only support length 1 constraints for now. + if (Constraint.length() > 1) + return; + + char ConstraintLetter = Constraint[0]; + switch (ConstraintLetter) { + default: break; + case 'I': + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { + if (isInt<13>(C->getSExtValue())) { + Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType()); + break; + } + return; + } + } + + if (Result.getNode()) { + Ops.push_back(Result); + return; + } + TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); +} + std::pair<unsigned, const TargetRegisterClass*> SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 2659fc8950..36d569e3b6 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/lib/Target/Sparc/SparcISelLowering.h @@ -73,6 +73,13 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; ConstraintType getConstraintType(const std::string &Constraint) const; + ConstraintWeight + getSingleConstraintMatchWeight(AsmOperandInfo &info, + const char *constraint) const; + void LowerAsmOperandForConstraint(SDValue Op, + std::string &Constraint, + std::vector<SDValue> &Ops, + SelectionDAG &DAG) const; std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const; |