diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2014-02-07 11:19:53 +0000 |
---|---|---|
committer | Oliver Stannard <oliver.stannard@arm.com> | 2014-02-07 11:19:53 +0000 |
commit | c8f5d438208fefc4f45034ba748861cf68a5911d (patch) | |
tree | cc3664226036f477c39c57b6f85c6acf023926fc /include | |
parent | fba9c104b9f2b3bf406631ef988f94affa935718 (diff) | |
download | llvm-c8f5d438208fefc4f45034ba748861cf68a5911d.tar.gz llvm-c8f5d438208fefc4f45034ba748861cf68a5911d.tar.bz2 llvm-c8f5d438208fefc4f45034ba748861cf68a5911d.tar.xz |
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
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/CodeGen/CallingConvLower.h | 9 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.td | 14 |
2 files changed, 18 insertions, 5 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index f824e73433..4bc8cecaff 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -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. diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td index c1bef28652..9d1dc3837a 100644 --- a/include/llvm/Target/TargetCallingConv.td +++ b/include/llvm/Target/TargetCallingConv.td @@ -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 |