diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff new file mode 100644 index 0000000..0417410 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff @@ -0,0 +1,142 @@ +Pull in r199781 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Add support for inline assembly constraint 'I'. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: test/CodeGen/SPARC/inlineasm.ll +=================================================================== +--- test/CodeGen/SPARC/inlineasm.ll ++++ test/CodeGen/SPARC/inlineasm.ll +@@ -0,0 +1,35 @@ ++; RUN: llc -march=sparc <%s | FileCheck %s ++ ++; CHECK-LABEL: test_constraint_r ++; CHECK: add %o1, %o0, %o0 ++define i32 @test_constraint_r(i32 %a, i32 %b) { ++entry: ++ %0 = tail call i32 asm sideeffect "add $2, $1, $0", "=r,r,r"(i32 %a, i32 %b) ++ ret i32 %0 ++} ++ ++; CHECK-LABEL: test_constraint_I ++; CHECK: add %o0, 1023, %o0 ++define i32 @test_constraint_I(i32 %a) { ++entry: ++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 1023) ++ ret i32 %0 ++} ++ ++; CHECK-LABEL: test_constraint_I_neg ++; CHECK: add %o0, -4096, %o0 ++define i32 @test_constraint_I_neg(i32 %a) { ++entry: ++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 -4096) ++ ret i32 %0 ++} ++ ++; CHECK-LABEL: test_constraint_I_largeimm ++; CHECK: sethi 9, [[R0:%[gilo][0-7]]] ++; CHECK: or [[R0]], 784, [[R1:%[gilo][0-7]]] ++; CHECK: add %o0, [[R1]], %o0 ++define i32 @test_constraint_I_largeimm(i32 %a) { ++entry: ++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000) ++ ret i32 %0 ++} +Index: lib/Target/Sparc/SparcISelLowering.h +=================================================================== +--- lib/Target/Sparc/SparcISelLowering.h ++++ 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; + +Index: lib/Target/Sparc/SparcISelLowering.cpp +=================================================================== +--- lib/Target/Sparc/SparcISelLowering.cpp ++++ lib/Target/Sparc/SparcISelLowering.cpp +@@ -2918,6 +2918,8 @@ SparcTargetLowering::getConstraintType(const std:: + switch (Constraint[0]) { + default: break; + case 'r': return C_RegisterClass; ++ case 'I': // SIMM13 ++ return C_Other; + } + } + +@@ -2924,6 +2926,64 @@ SparcTargetLowering::getConstraintType(const std:: + 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 { |