From 407e442245b5515c5f110f81b7c1e3f90c40c68c Mon Sep 17 00:00:00 2001 From: Venkatraman Govindaraju Date: Wed, 22 Jan 2014 01:29:51 +0000 Subject: [Sparc] Add support for inline assembly constraint 'I'. llvm-svn: 199781 --- llvm/lib/Target/Sparc/SparcISelLowering.cpp | 60 +++++++++++++++++++++++++++++ llvm/lib/Target/Sparc/SparcISelLowering.h | 7 ++++ 2 files changed, 67 insertions(+) (limited to 'llvm/lib') diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 3abccdef6ef..6dae29c45c0 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/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(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 &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(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 SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index 2659fc89501..36d569e3b69 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/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 &Ops, + SelectionDAG &DAG) const; std::pair getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const; -- cgit v1.2.3