| # REQUIRES: ppc |
| # RUN: split-file %s %t |
| |
| # RUN: llvm-mc -filetype=obj -triple=powerpc64le %t/callees.s -o %t-callees.o |
| # RUN: llvm-mc -filetype=obj -triple=powerpc64le %t/callertoc.s -o %t-callertoc.o |
| # RUN: llvm-mc -filetype=obj -triple=powerpc64le %t/callernotoc.s -o %t-callernotoc.o |
| # RUN: ld.lld -T %t/lds %t-callees.o %t-callernotoc.o %t-callertoc.o -o %t-r12setup |
| # RUN: ld.lld -T %t/ldsswap %t-callees.o %t-callernotoc.o %t-callertoc.o -o %t-r2save |
| |
| # RUN: llvm-objdump -d --no-show-raw-insn --mcpu=pwr10 %t-r12setup | \ |
| # RUN: FileCheck %s --check-prefix=NOSWAP |
| # RUN: llvm-objdump -d --no-show-raw-insn --mcpu=pwr10 %t-r2save | \ |
| # RUN: FileCheck %s --check-prefix=SWAP |
| |
| ## This test checks that it is possible to mix TOC and NOTOC functions and have |
| ## the correct thunks for all of the calls. |
| |
| # NOSWAP-LABEL: 01001000 <func>: |
| # NOSWAP-NEXT: blr |
| # NOSWAP-LABEL: 01002000 <callee_toc>: |
| # NOSWAP: bl 0x1001000 |
| # NOSWAP: blr |
| # NOSWAP-LABEL: 01002018 <callee_notoc>: |
| # NOSWAP: bl 0x1001000 |
| # NOSWAP: blr |
| # NOSWAP-LABEL: 10030000 <caller_notoc>: |
| # NOSWAP-NEXT: bl 0x10030010 |
| # NOSWAP-NEXT: bl 0x10030030 |
| # NOSWAP-NEXT: blr |
| # NOSWAP-LABEL: 10030010 <__gep_setup_callee_toc>: |
| # NOSWAP: bctr |
| # NOSWAP-LABEL: 10030030 <__long_branch_pcrel_callee_notoc>: |
| # NOSWAP: bctr |
| # NOSWAP-LABEL: 10040000 <caller_toc>: |
| # NOSWAP: bl 0x10040020 |
| # NOSWAP-NEXT: nop |
| # NOSWAP-NEXT: bl 0x10040040 |
| # NOSWAP-NEXT: ld 2, 24(1) |
| # NOSWAP-NEXT: blr |
| # NOSWAP-LABEL: 10040020 <__long_branch_callee_toc>: |
| # NOSWAP: bctr |
| # NOSWAP-LABEL: 10040040 <__toc_save_callee_notoc>: |
| # NOSWAP-NEXT: std 2, 24(1) |
| # NOSWAP: bctr |
| |
| # SWAP-LABEL: 01001000 <func>: |
| # SWAP-NEXT: blr |
| # SWAP-LABEL: 01002000 <callee_toc>: |
| # SWAP: bl 0x1001000 |
| # SWAP: blr |
| # SWAP-LABEL: 01002018 <callee_notoc>: |
| # SWAP: bl 0x1001000 |
| # SWAP: blr |
| # SWAP-LABEL: 10030000 <caller_toc>: |
| # SWAP: bl 0x10030020 |
| # SWAP-NEXT: nop |
| # SWAP-NEXT: bl 0x10030040 |
| # SWAP-NEXT: ld 2, 24(1) |
| # SWAP-NEXT: blr |
| # SWAP-LABEL: 10030020 <__long_branch_callee_toc>: |
| # SWAP: bctr |
| # SWAP-LABEL: 10030040 <__toc_save_callee_notoc>: |
| # SWAP-NEXT: std 2, 24(1) |
| # SWAP: bctr |
| # SWAP-LABEL: 10040000 <caller_notoc>: |
| # SWAP-NEXT: bl 0x10040010 |
| # SWAP-NEXT: bl 0x10040030 |
| # SWAP-NEXT: blr |
| # SWAP-LABEL: 10040010 <__gep_setup_callee_toc>: |
| # SWAP: bctr |
| # SWAP-LABEL: 10040030 <__long_branch_pcrel_callee_notoc>: |
| # SWAP: bctr |
| |
| #--- lds |
| SECTIONS { |
| .text_func 0x1001000 : { *(.text_func) } |
| .text_callee 0x1002000 : { *(.text_callee) } |
| .text_caller_notoc 0x10030000 : { *(.text_caller_notoc) } |
| .text_caller_toc 0x10040000 : { *(.text_caller_toc) } |
| } |
| |
| #--- ldsswap |
| SECTIONS { |
| .text_func 0x1001000 : { *(.text_func) } |
| .text_callee 0x1002000 : { *(.text_callee) } |
| .text_caller_toc 0x10030000 : { *(.text_caller_toc) } |
| .text_caller_notoc 0x10040000 : { *(.text_caller_notoc) } |
| } |
| |
| #--- callees.s |
| .section .text_func, "ax", %progbits |
| func: |
| blr |
| |
| .globl callee_toc |
| .section .text_callee, "ax", %progbits |
| callee_toc: |
| .Lfunc_gep1: |
| addis 2, 12, .TOC.-.Lfunc_gep1@ha |
| addi 2, 2, .TOC.-.Lfunc_gep1@l |
| .Lfunc_lep1: |
| .localentry callee_toc, .Lfunc_lep1-.Lfunc_gep1 |
| bl func |
| addis 4, 2, global@toc@ha |
| lwz 4, global@toc@l(4) |
| blr |
| |
| .globl callee_notoc |
| callee_notoc: |
| .localentry callee_notoc, 1 |
| bl func |
| plwz 4, global@pcrel(0), 1 |
| blr |
| |
| ## .globl global |
| global: |
| .long 0 |
| .size global, 4 |
| |
| #--- callernotoc.s |
| .section .text_caller_notoc, "ax", %progbits |
| caller_notoc: |
| .localentry caller, 1 |
| bl callee_toc@notoc |
| bl callee_notoc@notoc |
| blr |
| |
| #--- callertoc.s |
| .section .text_caller_toc, "ax", %progbits |
| caller_toc: |
| .Lfunc_gep2: |
| addis 2, 12, .TOC.-.Lfunc_gep2@ha |
| addi 2, 2, .TOC.-.Lfunc_gep2@l |
| .Lfunc_lep2: |
| .localentry caller_toc, .Lfunc_lep2-.Lfunc_gep2 |
| bl callee_toc |
| nop |
| bl callee_notoc |
| nop |
| blr |