mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
[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
This commit is contained in:
parent
825fc31bd3
commit
29b1a24a42
@ -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<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 {
|
||||
|
@ -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;
|
||||
|
||||
|
35
test/CodeGen/SPARC/inlineasm.ll
Normal file
35
test/CodeGen/SPARC/inlineasm.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user