1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[PowerPC][AIX] Spill CSRs to the ABI specified stack offsets.

Extend the CSR save/restore insertion code to support both 32-bit and
64-bit AIX.

Differential Revision: https://reviews.llvm.org/D79252
This commit is contained in:
Sean Fertile 2020-05-26 10:37:51 -04:00
parent bd4b8dd3ba
commit ae425e7b58
7 changed files with 350 additions and 56 deletions

View File

@ -96,11 +96,6 @@ PPCFrameLowering::PPCFrameLowering(const PPCSubtarget &STI)
// With the SVR4 ABI, callee-saved registers have fixed offsets on the stack.
const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
unsigned &NumEntries) const {
// Early exit if not using the SVR4 ABI.
if (!Subtarget.isSVR4ABI()) {
NumEntries = 0;
return nullptr;
}
// Floating-point register save area offsets.
#define CALLEE_SAVED_FPRS \
@ -123,7 +118,8 @@ const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
{PPC::F15, -136}, \
{PPC::F14, -144}
// 32-bit general purpose register save area offsets.
// 32-bit general purpose register save area offsets shared by ELF and
// AIX. AIX has an extra CSR with r13.
#define CALLEE_SAVED_GPRS32 \
{PPC::R31, -4}, \
{PPC::R30, -8}, \
@ -183,7 +179,7 @@ const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
// Note that the offsets here overlap, but this is fixed up in
// processFunctionBeforeFrameFinalized.
static const SpillSlot Offsets[] = {
static const SpillSlot ELFOffsets32[] = {
CALLEE_SAVED_FPRS,
CALLEE_SAVED_GPRS32,
@ -218,25 +214,48 @@ const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
{PPC::S15, -136},
{PPC::S14, -144}};
static const SpillSlot Offsets64[] = {
static const SpillSlot ELFOffsets64[] = {
CALLEE_SAVED_FPRS,
CALLEE_SAVED_GPRS64,
// VRSAVE save area offset.
{PPC::VRSAVE, -4},
CALLEE_SAVED_VRS
};
if (Subtarget.isPPC64()) {
NumEntries = array_lengthof(Offsets64);
static const SpillSlot AIXOffsets32[] = {
CALLEE_SAVED_FPRS,
CALLEE_SAVED_GPRS32,
// Add AIX's extra CSR.
{PPC::R13, -76},
// TODO Update when we add vector support for AIX.
};
return Offsets64;
} else {
NumEntries = array_lengthof(Offsets);
static const SpillSlot AIXOffsets64[] = {
CALLEE_SAVED_FPRS,
CALLEE_SAVED_GPRS64,
// TODO Update when we add vector support for AIX.
};
return Offsets;
if (Subtarget.is64BitELFABI()) {
NumEntries = array_lengthof(ELFOffsets64);
return ELFOffsets64;
}
if (Subtarget.is32BitELFABI()) {
NumEntries = array_lengthof(ELFOffsets32);
return ELFOffsets32;
}
assert(Subtarget.isAIXABI() && "Unexpected ABI.");
if (Subtarget.isPPC64()) {
NumEntries = array_lengthof(AIXOffsets64);
return AIXOffsets64;
}
NumEntries = array_lengthof(AIXOffsets32);
return AIXOffsets32;
}
/// RemoveVRSaveCode - We have found that this function does not need any code
@ -1805,12 +1824,6 @@ void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const {
// Early exit if not using the SVR4 ABI.
if (!Subtarget.isSVR4ABI()) {
addScavengingSpillSlot(MF, RS);
return;
}
// Get callee saved register information.
MachineFrameInfo &MFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();

View File

@ -7,5 +7,5 @@ define void @usethirteen() {
ret void
}
; CHECK: stw 13, -4(1)
; CHECK: lwz 13, -4(1)
; CHECK: stw 13, -76(1)
; CHECK: lwz 13, -76(1)

View File

@ -2337,7 +2337,7 @@ define void @caller_mix() {
; ASM64PWR4: mflr 0
; ASM64PWR4-DAG: std 0, 16(1)
; ASM64PWR4-DAG: stdu 1, -240(1)
; ASM64PWR4-DAG: stdu 1, -256(1)
; ASM64PWR4-DAG: std [[REG:[0-9]+]], 112(1)
; ASM64PWR4-DAG: std [[REG:[0-9]+]], 120(1)
; ASM64PWR4-DAG: std [[REG:[0-9]+]], 128(1)

View File

@ -203,7 +203,7 @@ entry:
; CHECKASM-LABEL: .call_test_byval_mem3:
; ASM32BIT: stwu 1, -96(1)
; ASM32BIT: stwu 1, -112(1)
; ASM32BIT-DAG: lwz [[REG:[0-9]+]], LC{{[0-9]+}}(2)
; ASM32BIT-DAG: addi 3, 1, 56
; ASM32BIT-DAG: addi 4, [[REG]], 24
@ -216,7 +216,7 @@ entry:
; ASM32BIT-DAG: lwz 9, 16([[REG]])
; ASM32BIT-DAG: lwz 10, 20([[REG]])
; ASM32BIT: bl .test_byval_mem3
; ASM32BIT: addi 1, 1, 96
; ASM32BIT: addi 1, 1, 112
; The memcpy call was inlined in 64-bit so MIR test is redundant and omitted.
; ASM64BIT: stdu 1, -128(1)
@ -319,7 +319,7 @@ entry:
; 32BIT-NEXT: BL_NOP <mcsymbol .test_byval_mem4>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1
; 32BIT-NEXT: ADJCALLSTACKUP 316, 0, implicit-def dead $r1, implicit $r1
; ASM32BIT: stwu 1, -320(1)
; ASM32BIT: stwu 1, -336(1)
; ASM32BIT-NEXT: stw [[REG1:[0-9]+]], {{[0-9]+}}(1)
; ASM32BIT: lwz [[REG1]], LC{{[0-9]+}}(2)
; ASM32BIT-DAG: lhz [[REG2:[0-9]+]], 28([[REG1]])
@ -338,7 +338,7 @@ entry:
; ASM32BIT-DAG: lwz 9, 20([[REG1]])
; ASM32BIT-DAG: lwz 10, 24([[REG1]])
; ASM32BIT: bl .test_byval_mem4
; ASM32BIT: addi 1, 1, 320
; ASM32BIT: addi 1, 1, 336
; Confirm the expected memcpy call is independent of the call to test_byval_mem4.
; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
@ -363,7 +363,7 @@ entry:
; 64BIT-NEXT: BL8_NOP <mcsymbol .test_byval_mem4>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1
; 64BIT-NEXT: ADJCALLSTACKUP 344, 0, implicit-def dead $r1, implicit $r1
; ASM64BIT: stdu 1, -352(1)
; ASM64BIT: stdu 1, -368(1)
; ASM64BIT-DAG: ld [[REG1:[0-9]+]], LC{{[0-9]+}}(2)
; ASM64BIT-DAG: addi 3, 1, 112
; ASM64BIT-DAG: addi 4, [[REG1]], 24
@ -383,7 +383,7 @@ entry:
; ASM64BIT-DAG: ld 9, 8([[REG1]])
; ASM64BIT-DAG: ld 10, 16([[REG1]])
; ASM64BIT: bl .test_byval_mem4
; ASM64BIT: addi 1, 1, 352
; ASM64BIT: addi 1, 1, 368
define void @test_byval_mem4(i32, %struct_S31* byval(%struct_S31) align 1, %struct_S256* byval(%struct_S256) align 1 %s) {
entry:

View File

@ -0,0 +1,270 @@
; RUN: llc -mtriple=powerpc64-unknown-aix-xcoff -verify-machineinstrs \
; RUN: -mcpu=pwr4 -mattr=-altivec -stop-after=prologepilog < %s | \
; RUN: FileCheck --check-prefix=MIR64 %s
; RUN: llc -mtriple=powerpc64-unknown-aix-xcoff -verify-machineinstrs \
; RUN: -mcpu=pwr4 -mattr=-altivec < %s | FileCheck --check-prefix=ASM64 %s
; RUN: llc -mtriple=powerpc-unknown-aix-xcoff -verify-machineinstrs \
; RUN: -mcpu=pwr4 -mattr=-altivec -stop-after=prologepilog < %s | \
; RUN: FileCheck --check-prefix=MIR32 %s
; RUN: llc -mtriple=powerpc-unknown-aix-xcoff -verify-machineinstrs \
; RUN: -mcpu=pwr4 -mattr=-altivec < %s | FileCheck --check-prefix=ASM32 %s
define dso_local signext i32 @gprs_only(i32 signext %i) {
entry:
call void asm sideeffect "", "~{r16},~{r22},~{r30}"()
ret i32 %i
}
; MIR64: name: gprs_only
; MIR64-LABEL: fixedStack:
; MIR64-NEXT: - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x30', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 1, type: spill-slot, offset: -80, size: 8, alignment: 16, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x22', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 2, type: spill-slot, offset: -128, size: 8, alignment: 16, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x16', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: stack: []
; MIR32: name: gprs_only
; MIR32-LABEL: fixedStack:
; MIR32: - { id: 0, type: spill-slot, offset: -8, size: 4, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r30', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 1, type: spill-slot, offset: -40, size: 4, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r22', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 2, type: spill-slot, offset: -64, size: 4, alignment: 16, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r16', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: stack: []
; MIR64: liveins: $x3, $x16, $x22, $x30
; MIR64-DAG: STD killed $x16, -128, $x1 :: (store 8 into %fixed-stack.2, align 16)
; MIR64-DAG: STD killed $x22, -80, $x1 :: (store 8 into %fixed-stack.1, align 16)
; MIR64-DAG: STD killed $x30, -16, $x1 :: (store 8 into %fixed-stack.0, align 16)
; MIR64: INLINEASM
; MIR64-DAG: $x30 = LD -16, $x1 :: (load 8 from %fixed-stack.0, align 16)
; MIR64-DAG: $x22 = LD -80, $x1 :: (load 8 from %fixed-stack.1, align 16)
; MIR64-DAG: $x16 = LD -128, $x1 :: (load 8 from %fixed-stack.2, align 16)
; MIR64: BLR8 implicit $lr8, implicit $rm, implicit $x3
; MIR32: liveins: $r3, $r16, $r22, $r30
; MIR32-DAG: STW killed $r16, -64, $r1 :: (store 4 into %fixed-stack.2, align 16)
; MIR32-DAG: STW killed $r22, -40, $r1 :: (store 4 into %fixed-stack.1, align 8)
; MIR32-DAG: STW killed $r30, -8, $r1 :: (store 4 into %fixed-stack.0, align 8)
; MIR32: INLINEASM
; MIR32-DAG: $r30 = LWZ -8, $r1 :: (load 4 from %fixed-stack.0, align 8)
; MIR32-DAG: $r22 = LWZ -40, $r1 :: (load 4 from %fixed-stack.1, align 8)
; MIR32-DAG: $r16 = LWZ -64, $r1 :: (load 4 from %fixed-stack.2, align 16)
; MIR32: BLR implicit $lr, implicit $rm, implicit $r3
; ASM64-LABEL: .gprs_only:
; ASM64-DAG: std 16, -128(1) # 8-byte Folded Spill
; ASM64-DAG: std 22, -80(1) # 8-byte Folded Spill
; ASM64-DAG: std 30, -16(1) # 8-byte Folded Spill
; ASM64: #APP
; ASM64-DAG: ld 30, -16(1) # 8-byte Folded Reload
; ASM64-DAG: ld 22, -80(1) # 8-byte Folded Reload
; ASM64-DAG: ld 16, -128(1) # 8-byte Folded Reload
; ASM64: blr
; ASM32-LABEl: .gprs_only:
; ASM32-DAG: stw 16, -64(1) # 4-byte Folded Spill
; ASM32-DAG: stw 22, -40(1) # 4-byte Folded Spill
; ASM32-DAG: stw 30, -8(1) # 4-byte Folded Spill
; ASM32: #APP
; ASM32-DAG: lwz 30, -8(1) # 4-byte Folded Reload
; ASM32-DAG: lwz 22, -40(1) # 4-byte Folded Reload
; ASM32-DAG: lwz 16, -64(1) # 4-byte Folded Reload
; ASM32-DAG: blr
declare double @dummy(i32 signext);
define dso_local double @fprs_and_gprs(i32 signext %i) {
call void asm sideeffect "", "~{r13},~{r14},~{r25},~{r31},~{f14},~{f19},~{f21},~{f31}"()
%result = call double @dummy(i32 signext %i)
ret double %result
}
; MIR64: name: fprs_and_gprs
; MIR64-LABEL: fixedStack:
; MIR64-NEXT: - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$f31', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 1, type: spill-slot, offset: -88, size: 8, alignment: 8, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$f21', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 2, type: spill-slot, offset: -104, size: 8, alignment: 8, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$f19', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 3, type: spill-slot, offset: -144, size: 8, alignment: 16, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$f14', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 4, type: spill-slot, offset: -152, size: 8, alignment: 8, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x31', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 5, type: spill-slot, offset: -200, size: 8, alignment: 8, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x25', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: - { id: 6, type: spill-slot, offset: -288, size: 8, alignment: 16, stack-id: default,
; MIR64-NEXT: callee-saved-register: '$x14', callee-saved-restored: true, debug-info-variable: '',
; MIR64-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR64-NEXT: stack: []
; MIR32: name: fprs_and_gprs
; MIR32-LABEL: fixedStack:
; MIR32-NEXT: - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$f31', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 1, type: spill-slot, offset: -88, size: 8, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$f21', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 2, type: spill-slot, offset: -104, size: 8, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$f19', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 3, type: spill-slot, offset: -144, size: 8, alignment: 16, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$f14', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 4, type: spill-slot, offset: -148, size: 4, alignment: 4, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r31', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 5, type: spill-slot, offset: -172, size: 4, alignment: 4, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r25', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 6, type: spill-slot, offset: -216, size: 4, alignment: 8, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: - { id: 7, type: spill-slot, offset: -220, size: 4, alignment: 4, stack-id: default,
; MIR32-NEXT: callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
; MIR32-NEXT: debug-info-expression: '', debug-info-location: '' }
; MIR32-NEXT: stack: []
; MIR64: liveins: $x3, $x14, $x25, $x31, $f14, $f19, $f21, $f31
; MIR64: $x0 = MFLR8 implicit $lr8
; MIR64-NEXT: STD killed $x0, 16, $x1
; MIR64-NEXT: $x1 = STDU $x1, -400, $x1
; MIR64-DAG: STD killed $x14, 112, $x1 :: (store 8 into %fixed-stack.6, align 16)
; MIR64-DAG: STD killed $x25, 200, $x1 :: (store 8 into %fixed-stack.5)
; MIR64-DAG: STD killed $x31, 248, $x1 :: (store 8 into %fixed-stack.4)
; MIR64-DAG: STFD killed $f14, 256, $x1 :: (store 8 into %fixed-stack.3, align 16)
; MIR64-DAG: STFD killed $f19, 296, $x1 :: (store 8 into %fixed-stack.2)
; MIR64-DAG: STFD killed $f21, 312, $x1 :: (store 8 into %fixed-stack.1)
; MIR64-DAG: STFD killed $f31, 392, $x1 :: (store 8 into %fixed-stack.0)
; MIR64: INLINEASM
; MIR64-NEXT: BL8_NOP
; MIR64-DAG: $f31 = LFD 392, $x1 :: (load 8 from %fixed-stack.0)
; MIR64-DAG: $f21 = LFD 312, $x1 :: (load 8 from %fixed-stack.1)
; MIR64-DAG: $f19 = LFD 296, $x1 :: (load 8 from %fixed-stack.2)
; MIR64-DAG: $f14 = LFD 256, $x1 :: (load 8 from %fixed-stack.3, align 16)
; MIR64-DAG: $x31 = LD 248, $x1 :: (load 8 from %fixed-stack.4)
; MIR64-DAG: $x25 = LD 200, $x1 :: (load 8 from %fixed-stack.5)
; MIR64-DAG: $x14 = LD 112, $x1 :: (load 8 from %fixed-stack.6, align 16)
; MIR64: $x1 = ADDI8 $x1, 400
; MIR64-NEXT: $x0 = LD 16, $x1
; MIR64-NEXT: MTLR8 $x0, implicit-def $lr8
; MIR64-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1
; MIR32: liveins: $r3, $r13, $r14, $r25, $r31, $f14, $f19, $f21, $f31
; MIR32: $r0 = MFLR implicit $lr
; MIR32-NEXT: STW killed $r0, 8, $r1
; MIR32-NEXT: $r1 = STWU $r1, -288, $r1
; MIR32-DAG: STW killed $r13, 68, $r1 :: (store 4 into %fixed-stack.7)
; MIR32-DAG: STW killed $r14, 72, $r1 :: (store 4 into %fixed-stack.6, align 8)
; MIR32-DAG: STW killed $r25, 116, $r1 :: (store 4 into %fixed-stack.5)
; MIR32-DAG: STW killed $r31, 140, $r1 :: (store 4 into %fixed-stack.4)
; MIR32-DAG: STFD killed $f14, 144, $r1 :: (store 8 into %fixed-stack.3, align 16)
; MIR32-DAG: STFD killed $f19, 184, $r1 :: (store 8 into %fixed-stack.2)
; MIR32-DAG: STFD killed $f21, 200, $r1 :: (store 8 into %fixed-stack.1)
; MIR32-DAG: STFD killed $f31, 280, $r1 :: (store 8 into %fixed-stack.0)
; MIR32: INLINEASM
; MIR32: BL_NOP
; MIR32-DAG: $f31 = LFD 280, $r1 :: (load 8 from %fixed-stack.0)
; MIR32-DAG: $f21 = LFD 200, $r1 :: (load 8 from %fixed-stack.1)
; MIR32-DAG: $f19 = LFD 184, $r1 :: (load 8 from %fixed-stack.2)
; MIR32-DAG: $f14 = LFD 144, $r1 :: (load 8 from %fixed-stack.3, align 16)
; MIR32-DAG: $r31 = LWZ 140, $r1 :: (load 4 from %fixed-stack.4)
; MIR32-DAG: $r25 = LWZ 116, $r1 :: (load 4 from %fixed-stack.5)
; MIR32-DAG: $r14 = LWZ 72, $r1 :: (load 4 from %fixed-stack.6, align 8)
; MIR32-DAG: $r13 = LWZ 68, $r1 :: (load 4 from %fixed-stack.7)
; MIR32: $r1 = ADDI $r1, 288
; MIR32-NEXT: $r0 = LWZ 8, $r1
; MIR32-NEXT: MTLR $r0, implicit-def $lr
; MIR32-NEXT: BLR implicit $lr, implicit $rm, implicit $f1
; ASM64-LABEL: .fprs_and_gprs:
; ASM64: mflr 0
; ASM64-NEXT: std 0, 16(1)
; ASM64-NEXT: stdu 1, -400(1)
; ASM64-DAG: std 14, 112(1) # 8-byte Folded Spill
; ASM64-DAG: std 25, 200(1) # 8-byte Folded Spill
; ASM64-DAG: std 31, 248(1) # 8-byte Folded Spill
; ASM64-DAG: stfd 14, 256(1) # 8-byte Folded Spill
; ASM64-DAG: stfd 19, 296(1) # 8-byte Folded Spill
; ASM64-DAG: stfd 21, 312(1) # 8-byte Folded Spill
; ASM64-DAG: stfd 31, 392(1) # 8-byte Folded Spill
; ASM64: bl .dummy
; ASM64-DAG: lfd 31, 392(1) # 8-byte Folded Reload
; ASM64-DAG: lfd 21, 312(1) # 8-byte Folded Reload
; ASM64-DAG: lfd 19, 296(1) # 8-byte Folded Reload
; ASM64-DAG: lfd 14, 256(1) # 8-byte Folded Reload
; ASM64-DAG: ld 31, 248(1) # 8-byte Folded Reload
; ASM64-DAG: ld 25, 200(1) # 8-byte Folded Reload
; ASM64-DAG: ld 14, 112(1) # 8-byte Folded Reload
; ASM64: addi 1, 1, 400
; ASM64-NEXT: ld 0, 16(1)
; ASM64-NEXT: mtlr 0
; ASM64-NEXT: blr
; ASM32-LABEL: .fprs_and_gprs:
; ASM32: mflr 0
; ASM32-NEXT: stw 0, 8(1)
; ASM32-NEXT: stwu 1, -288(1)
; ASM32-DAG: stw 13, 68(1) # 4-byte Folded Spill
; ASM32-DAG: stw 14, 72(1) # 4-byte Folded Spill
; ASM32-DAG: stw 25, 116(1) # 4-byte Folded Spill
; ASM32-DAG: stw 31, 140(1) # 4-byte Folded Spill
; ASM32-DAG: stfd 14, 144(1) # 8-byte Folded Spill
; ASM32-DAG: stfd 19, 184(1) # 8-byte Folded Spill
; ASM32-DAG: stfd 21, 200(1) # 8-byte Folded Spill
; ASM32-DAG: stfd 31, 280(1) # 8-byte Folded Spill
; ASM32-DAG: bl .dummy
; ASM32-DAG: lfd 31, 280(1) # 8-byte Folded Reload
; ASM32-DAG: lfd 21, 200(1) # 8-byte Folded Reload
; ASM32-DAG: lfd 19, 184(1) # 8-byte Folded Reload
; ASM32-DAG: lfd 14, 144(1) # 8-byte Folded Reload
; ASM32-DAG: lwz 31, 140(1) # 4-byte Folded Reload
; ASM32-DAG: lwz 25, 116(1) # 4-byte Folded Reload
; ASM32-DAG: lwz 14, 72(1) # 4-byte Folded Reload
; ASM32-DAG: lwz 13, 68(1) # 4-byte Folded Reload
; ASM32: addi 1, 1, 288
; ASM32-NEXT: lwz 0, 8(1)
; ASM32-NEXT: mtlr 0
; ASM32-NEXT: blr

View File

@ -17,20 +17,25 @@ body: |
renamable $r3 = COPY $r29
BLR implicit $lr, implicit $rm, implicit $r3
; CHECK-LABEL: fixedStack:
; CHECK: - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '$cr4',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
; CHECK-LABEL: stack:
; CHECK-LABEL: fixedStack:
; CHECK-NEXT: - { id: 0, type: spill-slot, offset: -12, size: 4, alignment: 4, stack-id: default,
; CHECK-NEXT: callee-saved-register: '$r29', callee-saved-restored: true, debug-info-variable: '',
; CHECK-NEXT: debug-info-expression: '', debug-info-location: '' }
; CHECK-NEXT: - { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '$cr4',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
; CHECK-LABEL: stack:
; CHECK: bb.0.entry:
; CHECK-NEXT: liveins: $r3, $r29, $cr2, $cr4
; CHECK: $r12 = MFCR implicit killed $cr2, implicit killed $cr4
; CHECK-NEXT: STW killed $r12, 4, $r1
; CHECK-NEXT: STW killed $r29, -12, $r1 :: (store 4 into %fixed-stack.0)
; CHECK: $r12 = LWZ 4, $r1
; CHECK: $r29 = LWZ -12, $r1 :: (load 4 from %fixed-stack.0)
; CHECK-NEXT: $r12 = LWZ 4, $r1
; CHECK-NEXT: $cr2 = MTOCRF $r12
; CHECK-NEXT: $cr4 = MTOCRF killed $r12
@ -50,7 +55,10 @@ body: |
BLR implicit $lr, implicit $rm, implicit $r3
; CHECK-LABEL: fixedStack:
; CHECK: - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
; CHECK-NEXT: - { id: 0, type: spill-slot, offset: -72, size: 4, alignment: 8, stack-id: default,
; CHECK-NEXT: callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
; CHECK-NEXT: debug-info-expression: '', debug-info-location: '' }
; CHECK-NEXT: - { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '$cr3',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
@ -61,6 +69,8 @@ body: |
; CHECK: $r12 = MFCR implicit killed $cr3
; CHECK-NEXT: STW killed $r12, 4, $r1
; CHECK-NEXT: STW killed $r14, -72, $r1 :: (store 4 into %fixed-stack.0, align 8)
; CHECK: $r12 = LWZ 4, $r1
; CHECK: $r14 = LWZ -72, $r1 :: (load 4 from %fixed-stack.0, align 8)
; CHECK-NEXT: $r12 = LWZ 4, $r1
; CHECK-NEXT: $cr3 = MTOCRF killed $r12

View File

@ -1,19 +1,16 @@
# RUN: llc -mtriple powerpc64le-unknown-linux-gnu -x mir -mcpu=pwr8 \
# RUN: -run-pass=prologepilog --verify-machineinstrs < %s | \
# RUN: FileCheck %s --check-prefixes=CHECK,SAVEONE,ELF
# RUN: FileCheck %s --check-prefixes=CHECK,SAVEONE
# RUN: llc -mtriple powerpc64-unknown-linux-gnu -x mir -mcpu=pwr7 \
# RUN: -run-pass=prologepilog --verify-machineinstrs < %s | \
# RUN: FileCheck %s --check-prefixes=CHECK,SAVEALL,ELF
# RUN: FileCheck %s --check-prefixes=CHECK,SAVEALL
# RUN: llc -mtriple powerpc64-unknown-aix-xcoff -x mir -mcpu=pwr4 \
# RUN: -run-pass=prologepilog --verify-machineinstrs < %s | \
# RUN: FileCheck %s --check-prefixes=CHECK,SAVEALL
# TODO FIXME: We only check the save and restores of the callee saved gpr for
# ELF becuase AIX callee saved registers haven't been properly implemented yet.
---
name: CRAllSave
alignment: 16
@ -30,21 +27,23 @@ body: |
BLR8 implicit $lr8, implicit $rm, implicit $x3
; CHECK-LABEL: fixedStack:
; ELF: - { id: 1, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; AIX: - { id: 0, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; CHECK: isImmutable: true, isAliased: false, callee-saved-register: '$cr4',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
; CHECK-NEXT: - { id: 0, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
; CHECK-NEXT: callee-saved-register: '$x29', callee-saved-restored: true, debug-info-variable: '',
; CHECK-NEXT: debug-info-expression: '', debug-info-location: '' }
; CHECK-NEXT: - { id: 1, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '$cr4',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
; CHECK-LABEL: stack:
; Verify the proper live-ins have been added in the prologue.
; CHECK: liveins: $x3, $x29, $cr2, $cr4
; CHECK: $x12 = MFCR8 implicit killed $cr2, implicit killed $cr4
; ELF-DAG: STD killed $x29, -24, $x1 :: (store 8 into %fixed-stack.0)
; CHECK-DAG: STD killed $x29, -24, $x1 :: (store 8 into %fixed-stack.0)
; CHECK-DAG: STW8 killed $x12, 8, $x1
; ELF: $x29 = LD -24, $x1 :: (load 8 from %fixed-stack.0)
; CHECK: $x29 = LD -24, $x1 :: (load 8 from %fixed-stack.0)
; CHECK: $x12 = LWZ8 8, $x1
; CHECK: $cr2 = MTOCRF8 $x12
; CHECK: $cr4 = MTOCRF8 killed $x12
@ -67,9 +66,11 @@ body: |
; CHECK-LABEL: CR2Save
; CHECK-LABEL: fixedStack:
; ELF: - { id: 1, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; AIX: - { id: 0, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; CHECK: isImmutable: true, isAliased: false, callee-saved-register: '$cr2',
; CHECK-NEXT: - { id: 0, type: spill-slot, offset: -144, size: 8, alignment: 16, stack-id: default,
; CHECK-NEXT: callee-saved-register: '$x14', callee-saved-restored: true, debug-info-variable: '',
; CHECK-NEXT: debug-info-expression: '', debug-info-location: '' }
; CHECK-NEXT: - { id: 1, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '$cr2',
; CHECK-NEXT: callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
; CHECK-NEXT: debug-info-location: '' }
; CHECK-LABEL: stack:
@ -82,10 +83,10 @@ body: |
; SAVEONE: $x12 = MFOCRF8 killed $cr2
; SAVEALL: $x12 = MFCR8 implicit killed $cr2
; ELF-DAG: STD killed $x14, -144, $x1 :: (store 8 into %fixed-stack.0, align 16)
; CHECK-DAG: STD killed $x14, -144, $x1 :: (store 8 into %fixed-stack.0, align 16)
; CHECK-DAG: STW8 killed $x12, 8, $x1
; ELF: $x14 = LD -144, $x1 :: (load 8 from %fixed-stack.0, align 16)
; CHECK: $x14 = LD -144, $x1 :: (load 8 from %fixed-stack.0, align 16)
; CHECK: $x12 = LWZ8 8, $x1
; CHECK: $cr2 = MTOCRF8 killed $x12