mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +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);
|
||||
}
|
||||
|
||||
/// 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
|
||||
// value. The size and alignment information of the argument is encoded in its
|
||||
// parameter attribute.
|
||||
|
@ -89,11 +89,15 @@ class CCAssignToStack<int size, int align> : CCAction {
|
||||
int Align = align;
|
||||
}
|
||||
|
||||
/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a register
|
||||
/// to be shadowed.
|
||||
class CCAssignToStackWithShadow<int size, int align, Register reg> :
|
||||
CCAssignToStack<size, align> {
|
||||
Register ShadowReg = reg;
|
||||
/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of
|
||||
/// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this
|
||||
/// shadows ALL of the registers in shadowList.
|
||||
class CCAssignToStackWithShadow<int size,
|
||||
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
|
||||
|
@ -114,10 +114,11 @@ def CC_ARM_AAPCS_Common : CallingConv<[
|
||||
CCIfType<[i32], CCIf<"ArgFlags.getOrigAlign() != 8",
|
||||
CCAssignToReg<[R0, R1, R2, R3]>>>,
|
||||
|
||||
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, R3>>>,
|
||||
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
|
||||
CCIfType<[f64], CCAssignToStack<8, 8>>,
|
||||
CCIfType<[v2f64], CCAssignToStack<16, 8>>
|
||||
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, [R0, R1, R2, R3]>>>,
|
||||
CCIfType<[i32], CCAssignToStackWithShadow<4, 4, [R0, R1, R2, R3]>>,
|
||||
CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[f64], CCAssignToStackWithShadow<8, 8, [Q0, Q1, Q2, Q3]>>,
|
||||
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 8, [Q0, Q1, Q2, Q3]>>
|
||||
]>;
|
||||
|
||||
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
|
||||
O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
|
||||
"->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
|
||||
if (Action->isSubClassOf("CCAssignToStackWithShadow"))
|
||||
O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
|
||||
O << ");\n" << IndentStr
|
||||
<< "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
|
||||
<< Counter << ", LocVT, LocInfo));\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")) {
|
||||
Record *DestTy = Action->getValueAsDef("DestTy");
|
||||
MVT::SimpleValueType DestVT = getValueType(DestTy);
|
||||
|
Loading…
Reference in New Issue
Block a user