diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -96,11 +96,6 @@ // 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 @@ {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 @@ // 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 @@ {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. + }; + + if (Subtarget.is64BitELFABI()) { + NumEntries = array_lengthof(ELFOffsets64); + return ELFOffsets64; + } - return Offsets; + 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::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 &CSI = MFI.getCalleeSavedInfo(); diff --git a/llvm/test/CodeGen/PowerPC/aix-calleesavedregs.ll b/llvm/test/CodeGen/PowerPC/aix-calleesavedregs.ll --- a/llvm/test/CodeGen/PowerPC/aix-calleesavedregs.ll +++ b/llvm/test/CodeGen/PowerPC/aix-calleesavedregs.ll @@ -7,5 +7,5 @@ ret void } -; CHECK: stw 13, -4(1) -; CHECK: lwz 13, -4(1) +; CHECK: stw 13, -76(1) +; CHECK: lwz 13, -76(1) diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll --- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll @@ -2337,7 +2337,7 @@ ; 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) diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll b/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll --- a/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll @@ -203,7 +203,7 @@ ; 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 @@ ; 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 @@ ; 32BIT-NEXT: BL_NOP , 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 @@ ; 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 @@ ; 64BIT-NEXT: BL8_NOP , 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 @@ ; 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: diff --git a/llvm/test/CodeGen/PowerPC/aix-csr.ll b/llvm/test/CodeGen/PowerPC/aix-csr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-csr.ll @@ -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 diff --git a/llvm/test/CodeGen/PowerPC/aix32-crsave.mir b/llvm/test/CodeGen/PowerPC/aix32-crsave.mir --- a/llvm/test/CodeGen/PowerPC/aix32-crsave.mir +++ b/llvm/test/CodeGen/PowerPC/aix32-crsave.mir @@ -17,20 +17,25 @@ 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 @@ 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 @@ ; 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 diff --git a/llvm/test/CodeGen/PowerPC/ppc64-crsave.mir b/llvm/test/CodeGen/PowerPC/ppc64-crsave.mir --- a/llvm/test/CodeGen/PowerPC/ppc64-crsave.mir +++ b/llvm/test/CodeGen/PowerPC/ppc64-crsave.mir @@ -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 @@ 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 @@ ; 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 @@ ; 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