llvm.org GIT mirror llvm / 29b1a24
[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 Venkatraman Govindaraju 6 years ago
3 changed file(s) with 102 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
29222922 switch (Constraint[0]) {
29232923 default: break;
29242924 case 'r': return C_RegisterClass;
2925 case 'I': // SIMM13
2926 return C_Other;
29252927 }
29262928 }
29272929
29282930 return TargetLowering::getConstraintType(Constraint);
2931 }
2932
2933 TargetLowering::ConstraintWeight SparcTargetLowering::
2934 getSingleConstraintMatchWeight(AsmOperandInfo &info,
2935 const char *constraint) const {
2936 ConstraintWeight weight = CW_Invalid;
2937 Value *CallOperandVal = info.CallOperandVal;
2938 // If we don't have a value, we can't do a match,
2939 // but allow it at the lowest weight.
2940 if (CallOperandVal == NULL)
2941 return CW_Default;
2942
2943 // Look at the constraint type.
2944 switch (*constraint) {
2945 default:
2946 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
2947 break;
2948 case 'I': // SIMM13
2949 if (ConstantInt *C = dyn_cast(info.CallOperandVal)) {
2950 if (isInt<13>(C->getSExtValue()))
2951 weight = CW_Constant;
2952 }
2953 break;
2954 }
2955 return weight;
2956 }
2957
2958 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
2959 /// vector. If it is invalid, don't add anything to Ops.
2960 void SparcTargetLowering::
2961 LowerAsmOperandForConstraint(SDValue Op,
2962 std::string &Constraint,
2963 std::vector &Ops,
2964 SelectionDAG &DAG) const {
2965 SDValue Result(0, 0);
2966
2967 // Only support length 1 constraints for now.
2968 if (Constraint.length() > 1)
2969 return;
2970
2971 char ConstraintLetter = Constraint[0];
2972 switch (ConstraintLetter) {
2973 default: break;
2974 case 'I':
2975 if (ConstantSDNode *C = dyn_cast(Op)) {
2976 if (isInt<13>(C->getSExtValue())) {
2977 Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType());
2978 break;
2979 }
2980 return;
2981 }
2982 }
2983
2984 if (Result.getNode()) {
2985 Ops.push_back(Result);
2986 return;
2987 }
2988 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
29292989 }
29302990
29312991 std::pair
7272 virtual const char *getTargetNodeName(unsigned Opcode) const;
7373
7474 ConstraintType getConstraintType(const std::string &Constraint) const;
75 ConstraintWeight
76 getSingleConstraintMatchWeight(AsmOperandInfo &info,
77 const char *constraint) const;
78 void LowerAsmOperandForConstraint(SDValue Op,
79 std::string &Constraint,
80 std::vector &Ops,
81 SelectionDAG &DAG) const;
7582 std::pair
7683 getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
7784
0 ; RUN: llc -march=sparc <%s | FileCheck %s
1
2 ; CHECK-LABEL: test_constraint_r
3 ; CHECK: add %o1, %o0, %o0
4 define i32 @test_constraint_r(i32 %a, i32 %b) {
5 entry:
6 %0 = tail call i32 asm sideeffect "add $2, $1, $0", "=r,r,r"(i32 %a, i32 %b)
7 ret i32 %0
8 }
9
10 ; CHECK-LABEL: test_constraint_I
11 ; CHECK: add %o0, 1023, %o0
12 define i32 @test_constraint_I(i32 %a) {
13 entry:
14 %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 1023)
15 ret i32 %0
16 }
17
18 ; CHECK-LABEL: test_constraint_I_neg
19 ; CHECK: add %o0, -4096, %o0
20 define i32 @test_constraint_I_neg(i32 %a) {
21 entry:
22 %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 -4096)
23 ret i32 %0
24 }
25
26 ; CHECK-LABEL: test_constraint_I_largeimm
27 ; CHECK: sethi 9, [[R0:%[gilo][0-7]]]
28 ; CHECK: or [[R0]], 784, [[R1:%[gilo][0-7]]]
29 ; CHECK: add %o0, [[R1]], %o0
30 define i32 @test_constraint_I_largeimm(i32 %a) {
31 entry:
32 %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000)
33 ret i32 %0
34 }