Skip to content

Commit 407e442

Browse files
committed
[Sparc] Add support for inline assembly constraint 'I'.
llvm-svn: 199781
1 parent bbf322b commit 407e442

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

llvm/lib/Target/Sparc/SparcISelLowering.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2923,12 +2923,72 @@ SparcTargetLowering::getConstraintType(const std::string &Constraint) const {
29232923
switch (Constraint[0]) {
29242924
default: break;
29252925
case 'r': return C_RegisterClass;
2926+
case 'I': // SIMM13
2927+
return C_Other;
29262928
}
29272929
}
29282930

29292931
return TargetLowering::getConstraintType(Constraint);
29302932
}
29312933

2934+
TargetLowering::ConstraintWeight SparcTargetLowering::
2935+
getSingleConstraintMatchWeight(AsmOperandInfo &info,
2936+
const char *constraint) const {
2937+
ConstraintWeight weight = CW_Invalid;
2938+
Value *CallOperandVal = info.CallOperandVal;
2939+
// If we don't have a value, we can't do a match,
2940+
// but allow it at the lowest weight.
2941+
if (CallOperandVal == NULL)
2942+
return CW_Default;
2943+
2944+
// Look at the constraint type.
2945+
switch (*constraint) {
2946+
default:
2947+
weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
2948+
break;
2949+
case 'I': // SIMM13
2950+
if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
2951+
if (isInt<13>(C->getSExtValue()))
2952+
weight = CW_Constant;
2953+
}
2954+
break;
2955+
}
2956+
return weight;
2957+
}
2958+
2959+
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
2960+
/// vector. If it is invalid, don't add anything to Ops.
2961+
void SparcTargetLowering::
2962+
LowerAsmOperandForConstraint(SDValue Op,
2963+
std::string &Constraint,
2964+
std::vector<SDValue> &Ops,
2965+
SelectionDAG &DAG) const {
2966+
SDValue Result(0, 0);
2967+
2968+
// Only support length 1 constraints for now.
2969+
if (Constraint.length() > 1)
2970+
return;
2971+
2972+
char ConstraintLetter = Constraint[0];
2973+
switch (ConstraintLetter) {
2974+
default: break;
2975+
case 'I':
2976+
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
2977+
if (isInt<13>(C->getSExtValue())) {
2978+
Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType());
2979+
break;
2980+
}
2981+
return;
2982+
}
2983+
}
2984+
2985+
if (Result.getNode()) {
2986+
Ops.push_back(Result);
2987+
return;
2988+
}
2989+
TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
2990+
}
2991+
29322992
std::pair<unsigned, const TargetRegisterClass*>
29332993
SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
29342994
MVT VT) const {

llvm/lib/Target/Sparc/SparcISelLowering.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ namespace llvm {
7373
virtual const char *getTargetNodeName(unsigned Opcode) const;
7474

7575
ConstraintType getConstraintType(const std::string &Constraint) const;
76+
ConstraintWeight
77+
getSingleConstraintMatchWeight(AsmOperandInfo &info,
78+
const char *constraint) const;
79+
void LowerAsmOperandForConstraint(SDValue Op,
80+
std::string &Constraint,
81+
std::vector<SDValue> &Ops,
82+
SelectionDAG &DAG) const;
7683
std::pair<unsigned, const TargetRegisterClass*>
7784
getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
7885

llvm/test/CodeGen/SPARC/inlineasm.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llc -march=sparc <%s | FileCheck %s
2+
3+
; CHECK-LABEL: test_constraint_r
4+
; CHECK: add %o1, %o0, %o0
5+
define i32 @test_constraint_r(i32 %a, i32 %b) {
6+
entry:
7+
%0 = tail call i32 asm sideeffect "add $2, $1, $0", "=r,r,r"(i32 %a, i32 %b)
8+
ret i32 %0
9+
}
10+
11+
; CHECK-LABEL: test_constraint_I
12+
; CHECK: add %o0, 1023, %o0
13+
define i32 @test_constraint_I(i32 %a) {
14+
entry:
15+
%0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 1023)
16+
ret i32 %0
17+
}
18+
19+
; CHECK-LABEL: test_constraint_I_neg
20+
; CHECK: add %o0, -4096, %o0
21+
define i32 @test_constraint_I_neg(i32 %a) {
22+
entry:
23+
%0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 -4096)
24+
ret i32 %0
25+
}
26+
27+
; CHECK-LABEL: test_constraint_I_largeimm
28+
; CHECK: sethi 9, [[R0:%[gilo][0-7]]]
29+
; CHECK: or [[R0]], 784, [[R1:%[gilo][0-7]]]
30+
; CHECK: add %o0, [[R1]], %o0
31+
define i32 @test_constraint_I_largeimm(i32 %a) {
32+
entry:
33+
%0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000)
34+
ret i32 %0
35+
}

0 commit comments

Comments
 (0)