mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
LLVM-1163: AAPCS-VFP violation when CPRC allocated to stack
According to the AAPCS, when a CPRC is allocated to the stack, all other VFP registers should be marked as unavailable. I have also modified the rules for allocating non-CPRCs to the stack, to make it more explicit that all GPRs must be made unavailable. I cannot think of a case where the old version would produce incorrect answers, so there is no test for this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200970 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fba9c104b9
commit
c8f5d43820
@ -348,6 +348,15 @@ public:
|
|||||||
return AllocateStack(Size, Align);
|
return AllocateStack(Size, Align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Version of AllocateStack with list of extra registers to be shadowed.
|
||||||
|
/// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
|
||||||
|
unsigned AllocateStack(unsigned Size, unsigned Align,
|
||||||
|
const uint16_t *ShadowRegs, unsigned NumShadowRegs) {
|
||||||
|
for (unsigned i = 0; i < NumShadowRegs; ++i)
|
||||||
|
MarkAllocated(ShadowRegs[i]);
|
||||||
|
return AllocateStack(Size, Align);
|
||||||
|
}
|
||||||
|
|
||||||
// HandleByVal - Allocate a stack slot large enough to pass an argument by
|
// HandleByVal - Allocate a stack slot large enough to pass an argument by
|
||||||
// value. The size and alignment information of the argument is encoded in its
|
// value. The size and alignment information of the argument is encoded in its
|
||||||
// parameter attribute.
|
// parameter attribute.
|
||||||
|
@ -89,11 +89,15 @@ class CCAssignToStack<int size, int align> : CCAction {
|
|||||||
int Align = align;
|
int Align = align;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a register
|
/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of
|
||||||
/// to be shadowed.
|
/// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this
|
||||||
class CCAssignToStackWithShadow<int size, int align, Register reg> :
|
/// shadows ALL of the registers in shadowList.
|
||||||
CCAssignToStack<size, align> {
|
class CCAssignToStackWithShadow<int size,
|
||||||
Register ShadowReg = reg;
|
int align,
|
||||||
|
list<Register> shadowList> : CCAction {
|
||||||
|
int Size = size;
|
||||||
|
int Align = align;
|
||||||
|
list<Register> ShadowRegList = shadowList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CCPassByVal - This action always matches: it assigns the value to a stack
|
/// CCPassByVal - This action always matches: it assigns the value to a stack
|
||||||
|
@ -114,10 +114,11 @@ def CC_ARM_AAPCS_Common : CallingConv<[
|
|||||||
CCIfType<[i32], CCIf<"ArgFlags.getOrigAlign() != 8",
|
CCIfType<[i32], CCIf<"ArgFlags.getOrigAlign() != 8",
|
||||||
CCAssignToReg<[R0, R1, R2, R3]>>>,
|
CCAssignToReg<[R0, R1, R2, R3]>>>,
|
||||||
|
|
||||||
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, R3>>>,
|
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, [R0, R1, R2, R3]>>>,
|
||||||
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
|
CCIfType<[i32], CCAssignToStackWithShadow<4, 4, [R0, R1, R2, R3]>>,
|
||||||
CCIfType<[f64], CCAssignToStack<8, 8>>,
|
CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
||||||
CCIfType<[v2f64], CCAssignToStack<16, 8>>
|
CCIfType<[f64], CCAssignToStackWithShadow<8, 8, [Q0, Q1, Q2, Q3]>>,
|
||||||
|
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 8, [Q0, Q1, Q2, Q3]>>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def RetCC_ARM_AAPCS_Common : CallingConv<[
|
def RetCC_ARM_AAPCS_Common : CallingConv<[
|
||||||
|
22
test/CodeGen/ARM/2014-02-05-vfp-regs-after-stack.ll
Normal file
22
test/CodeGen/ARM/2014-02-05-vfp-regs-after-stack.ll
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
; RUN: llc < %s -o - -filetype=asm | FileCheck %s
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
|
||||||
|
target triple = "armv8-none--eabi"
|
||||||
|
|
||||||
|
; CHECK-LABEL: fn1:
|
||||||
|
define arm_aapcs_vfpcc float @fn1(double %a, double %b, double %c, double %d, double %e, double %f, double %g, float %h, double %i, float %j) {
|
||||||
|
ret float %j
|
||||||
|
; CHECK: vldr s0, [sp, #8]
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: fn2:
|
||||||
|
define arm_aapcs_vfpcc float @fn2(double %a, double %b, double %c, double %d, double %e, double %f, float %h, <4 x float> %i, float %j) {
|
||||||
|
ret float %j
|
||||||
|
; CHECK: vldr s0, [sp, #16]
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: fn3:
|
||||||
|
define arm_aapcs_vfpcc float @fn3(float %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, float %j) #0 {
|
||||||
|
ret float %j
|
||||||
|
; CHECK: vldr s0, [sp, #8]
|
||||||
|
}
|
@ -185,12 +185,34 @@ void CallingConvEmitter::EmitAction(Record *Action,
|
|||||||
else
|
else
|
||||||
O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
|
O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
|
||||||
"->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
|
"->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
|
||||||
if (Action->isSubClassOf("CCAssignToStackWithShadow"))
|
|
||||||
O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
|
|
||||||
O << ");\n" << IndentStr
|
O << ");\n" << IndentStr
|
||||||
<< "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
|
<< "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
|
||||||
<< Counter << ", LocVT, LocInfo));\n";
|
<< Counter << ", LocVT, LocInfo));\n";
|
||||||
O << IndentStr << "return false;\n";
|
O << IndentStr << "return false;\n";
|
||||||
|
} else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
|
||||||
|
int Size = Action->getValueAsInt("Size");
|
||||||
|
int Align = Action->getValueAsInt("Align");
|
||||||
|
ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
|
||||||
|
|
||||||
|
unsigned ShadowRegListNumber = ++Counter;
|
||||||
|
|
||||||
|
O << IndentStr << "static const uint16_t ShadowRegList"
|
||||||
|
<< ShadowRegListNumber << "[] = {\n";
|
||||||
|
O << IndentStr << " ";
|
||||||
|
for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
|
||||||
|
if (i != 0) O << ", ";
|
||||||
|
O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
|
||||||
|
}
|
||||||
|
O << "\n" << IndentStr << "};\n";
|
||||||
|
|
||||||
|
O << IndentStr << "unsigned Offset" << ++Counter
|
||||||
|
<< " = State.AllocateStack("
|
||||||
|
<< Size << ", " << Align << ", "
|
||||||
|
<< "ShadowRegList" << ShadowRegListNumber << ", "
|
||||||
|
<< ShadowRegList->getSize() << ");\n";
|
||||||
|
O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
|
||||||
|
<< Counter << ", LocVT, LocInfo));\n";
|
||||||
|
O << IndentStr << "return false;\n";
|
||||||
} else if (Action->isSubClassOf("CCPromoteToType")) {
|
} else if (Action->isSubClassOf("CCPromoteToType")) {
|
||||||
Record *DestTy = Action->getValueAsDef("DestTy");
|
Record *DestTy = Action->getValueAsDef("DestTy");
|
||||||
MVT::SimpleValueType DestVT = getValueType(DestTy);
|
MVT::SimpleValueType DestVT = getValueType(DestTy);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user