1 Pull in r199781 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Add support for inline assembly constraint 'I'.
5 Introduced here: http://svn.freebsd.org/changeset/base/262261
7 Index: test/CodeGen/SPARC/inlineasm.ll
8 ===================================================================
9 --- test/CodeGen/SPARC/inlineasm.ll
10 +++ test/CodeGen/SPARC/inlineasm.ll
12 +; RUN: llc -march=sparc <%s | FileCheck %s
14 +; CHECK-LABEL: test_constraint_r
15 +; CHECK: add %o1, %o0, %o0
16 +define i32 @test_constraint_r(i32 %a, i32 %b) {
18 + %0 = tail call i32 asm sideeffect "add $2, $1, $0", "=r,r,r"(i32 %a, i32 %b)
22 +; CHECK-LABEL: test_constraint_I
23 +; CHECK: add %o0, 1023, %o0
24 +define i32 @test_constraint_I(i32 %a) {
26 + %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 1023)
30 +; CHECK-LABEL: test_constraint_I_neg
31 +; CHECK: add %o0, -4096, %o0
32 +define i32 @test_constraint_I_neg(i32 %a) {
34 + %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 -4096)
38 +; CHECK-LABEL: test_constraint_I_largeimm
39 +; CHECK: sethi 9, [[R0:%[gilo][0-7]]]
40 +; CHECK: or [[R0]], 784, [[R1:%[gilo][0-7]]]
41 +; CHECK: add %o0, [[R1]], %o0
42 +define i32 @test_constraint_I_largeimm(i32 %a) {
44 + %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000)
47 Index: lib/Target/Sparc/SparcISelLowering.h
48 ===================================================================
49 --- lib/Target/Sparc/SparcISelLowering.h
50 +++ lib/Target/Sparc/SparcISelLowering.h
51 @@ -73,6 +73,13 @@ namespace llvm {
52 virtual const char *getTargetNodeName(unsigned Opcode) const;
54 ConstraintType getConstraintType(const std::string &Constraint) const;
56 + getSingleConstraintMatchWeight(AsmOperandInfo &info,
57 + const char *constraint) const;
58 + void LowerAsmOperandForConstraint(SDValue Op,
59 + std::string &Constraint,
60 + std::vector<SDValue> &Ops,
61 + SelectionDAG &DAG) const;
62 std::pair<unsigned, const TargetRegisterClass*>
63 getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
65 Index: lib/Target/Sparc/SparcISelLowering.cpp
66 ===================================================================
67 --- lib/Target/Sparc/SparcISelLowering.cpp
68 +++ lib/Target/Sparc/SparcISelLowering.cpp
69 @@ -2918,6 +2918,8 @@ SparcTargetLowering::getConstraintType(const std::
70 switch (Constraint[0]) {
72 case 'r': return C_RegisterClass;
78 @@ -2924,6 +2926,64 @@ SparcTargetLowering::getConstraintType(const std::
79 return TargetLowering::getConstraintType(Constraint);
82 +TargetLowering::ConstraintWeight SparcTargetLowering::
83 +getSingleConstraintMatchWeight(AsmOperandInfo &info,
84 + const char *constraint) const {
85 + ConstraintWeight weight = CW_Invalid;
86 + Value *CallOperandVal = info.CallOperandVal;
87 + // If we don't have a value, we can't do a match,
88 + // but allow it at the lowest weight.
89 + if (CallOperandVal == NULL)
92 + // Look at the constraint type.
93 + switch (*constraint) {
95 + weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
98 + if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
99 + if (isInt<13>(C->getSExtValue()))
100 + weight = CW_Constant;
107 +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
108 +/// vector. If it is invalid, don't add anything to Ops.
109 +void SparcTargetLowering::
110 +LowerAsmOperandForConstraint(SDValue Op,
111 + std::string &Constraint,
112 + std::vector<SDValue> &Ops,
113 + SelectionDAG &DAG) const {
114 + SDValue Result(0, 0);
116 + // Only support length 1 constraints for now.
117 + if (Constraint.length() > 1)
120 + char ConstraintLetter = Constraint[0];
121 + switch (ConstraintLetter) {
124 + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
125 + if (isInt<13>(C->getSExtValue())) {
126 + Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType());
133 + if (Result.getNode()) {
134 + Ops.push_back(Result);
137 + TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
140 std::pair<unsigned, const TargetRegisterClass*>
141 SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,