123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- /*
- * Startup code for programs linked with GNU libc, PowerPC64
- * version.
- *
- * Adapted from the glibc-sources (2.3.5) in the file
- *
- * sysdeps/powerpc/powerpc64/elf/start.S
- *
- * Original header follows.
- */
- /* Startup code for programs linked with GNU libc. PowerPC64 version.
- Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA. */
- /* some macros which simplify the startup code */
- /* load the 64 bit value "value" into register ra */
- .macro LOAD_64BIT_VAL ra, value
- lis \ra,\value@highest
- ori \ra,\ra,\value@higher
- sldi \ra,\ra,32
- oris \ra,\ra,\value@h
- ori \ra,\ra,\value@l
- .endm
- /* create function prolog for symbol "fn" */
- .macro FUNCTION_PROLOG fn
- .section ".text"
- .align 2
- .globl \fn
- .section ".opd", "aw"
- .align 3
- \fn:
- .quad .\fn, .TOC.@tocbase, 0
- .previous
- .size \fn, 24
- .type \fn, @function
- .globl .\fn
- .\fn:
- .endm
- /*
- * "ptrgl" glue code for calls via pointer. This function
- * sequence loads the data from the function descriptor
- * referenced by R11 into the CTR register (function address),
- * R2 (GOT/TOC pointer), and R11 (the outer frame pointer).
- *
- * On entry, R11 must be set to point to the function descriptor.
- *
- * See also the 64-bit PowerPC ABI specification for more
- * information, chapter 3.5.11 (in v1.7).
- */
- .section ".text"
- .align 3
- .globl .ptrgl
- .ptrgl:
- ld 0, 0(11)
- std 2, 40(1)
- mtctr 0
- ld 2, 8(11)
- ld 11, 8(11)
- bctr
- .long 0
- .byte 0, 12, 128, 0, 0, 0, 0, 0
- .type .ptrgl, @function
- .size .ptrgl, . - .ptrgl
- /*
- * Function prolog/epilog helpers, which are part of the 64-bit
- * PowerPC ABI.
- *
- * See also the 64-bit PowerPC ABI specification for more
- * information, chapter 3.5.5, "Register saving and restoring
- * function" (in v1.7).
- */
- /* Each _savegpr0_N routine saves the general registers from rN to r31,
- * inclusive. When the routine is called, r1 must point to the start
- * of the general register save area. R0 must contain the old LR on
- * entry.
- */
- _savegpr0_14: std 14,-144(1)
- _savegpr0_15: std 15,-136(1)
- _savegpr0_16: std 16,-128(1)
- _savegpr0_17: std 17,-120(1)
- _savegpr0_18: std 18,-112(1)
- _savegpr0_19: std 19,-104(1)
- _savegpr0_20: std 20,-96(1)
- _savegpr0_21: std 21,-88(1)
- _savegpr0_22: std 22,-80(1)
- _savegpr0_23: std 23,-72(1)
- _savegpr0_24: std 24,-64(1)
- _savegpr0_25: std 25,-56(1)
- _savegpr0_26: std 26,-48(1)
- _savegpr0_27: std 27,-40(1)
- _savegpr0_28: std 28,-32(1)
- _savegpr0_29: std 29,-24(1)
- _savegpr0_30: std 30,-16(1)
- _savegpr0_31:
- std 31,-8(1)
- std 0, 16(1)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* Each _restgpr0_N routine restores the general registers from rN to r31,
- * inclusive. When the routine is called, r1 must point to the start
- * of the general register save area.
- */
- _restgpr0_14: ld 14,-144(1)
- _restgpr0_15: ld 15,-136(1)
- _restgpr0_16: ld 16,-128(1)
- _restgpr0_17: ld 17,-120(1)
- _restgpr0_18: ld 18,-112(1)
- _restgpr0_19: ld 19,-104(1)
- _restgpr0_20: ld 20,-96(1)
- _restgpr0_21: ld 21,-88(1)
- _restgpr0_22: ld 22,-80(1)
- _restgpr0_23: ld 23,-72(1)
- _restgpr0_24: ld 24,-64(1)
- _restgpr0_25: ld 25,-56(1)
- _restgpr0_26: ld 26,-48(1)
- _restgpr0_27: ld 27,-40(1)
- _restgpr0_28: ld 28,-32(1)
- _restgpr0_29:
- ld 0, 16(1)
- ld 29,-24(1)
- mtlr 0
- ld 30,-16(1)
- ld 31,-8(1)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- _restgpr0_30: ld 30,-16(1)
- _restgpr0_31: ld 0, 16(1)
- ld 31,-8(1)
- mtlr 0
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* Each _savegpr1_N routine saves the general registers from rN to r31,
- * inclusive. When the routine is called, r12
- * must point to the start of the general register save area.
- */
- _savegpr1_14: std 14,-144(12)
- _savegpr1_15: std 15,-136(12)
- _savegpr1_16: std 16,-128(12)
- _savegpr1_17: std 17,-120(12)
- _savegpr1_18: std 18,-112(12)
- _savegpr1_19: std 19,-104(12)
- _savegpr1_20: std 20,-96(12)
- _savegpr1_21: std 21,-88(12)
- _savegpr1_22: std 22,-80(12)
- _savegpr1_23: std 23,-72(12)
- _savegpr1_24: std 24,-64(12)
- _savegpr1_25: std 25,-56(12)
- _savegpr1_26: std 26,-48(12)
- _savegpr1_27: std 27,-40(12)
- _savegpr1_28: std 28,-32(12)
- _savegpr1_29: std 29,-24(12)
- _savegpr1_30: std 30,-16(12)
- _savegpr1_31: std 31,-8(12)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* The _restgpr1_N routines restore the general registers from rN to r31.
- * When the routine is called, r12 must point to the start of the general
- * register save area.
- */
- _restgpr1_14: ld 14,-144(12)
- _restgpr1_15: ld 15,-136(12)
- _restgpr1_16: ld 16,-128(12)
- _restgpr1_17: ld 17,-120(12)
- _restgpr1_18: ld 18,-112(12)
- _restgpr1_19: ld 19,-104(12)
- _restgpr1_20: ld 20,-96(12)
- _restgpr1_21: ld 21,-88(12)
- _restgpr1_22: ld 22,-80(12)
- _restgpr1_23: ld 23,-72(12)
- _restgpr1_24: ld 24,-64(12)
- _restgpr1_25: ld 25,-56(12)
- _restgpr1_26: ld 26,-48(12)
- _restgpr1_27: ld 27,-40(12)
- _restgpr1_28: ld 28,-32(12)
- _restgpr1_29: ld 29,-24(12)
- _restgpr1_30: ld 30,-16(12)
- _restgpr1_31: ld 31,-8(12)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* Each _savefpr_M routine saves the floating point registers from fM to f31,
- * inclusive. When the routine is called, r1 must point to the start of the
- * floating point register save area, and r0 must contain the value of LR on
- * function entry.
- */
- _savefpr_14: stfd 14,-144(1)
- _savefpr_15: stfd 15,-136(1)
- _savefpr_16: stfd 16,-128(1)
- _savefpr_17: stfd 17,-120(1)
- _savefpr_18: stfd 18,-112(1)
- _savefpr_19: stfd 19,-104(1)
- _savefpr_20: stfd 20,-96(1)
- _savefpr_21: stfd 21,-88(1)
- _savefpr_22: stfd 22,-80(1)
- _savefpr_23: stfd 23,-72(1)
- _savefpr_24: stfd 24,-64(1)
- _savefpr_25: stfd 25,-56(1)
- _savefpr_26: stfd 26,-48(1)
- _savefpr_27: stfd 27,-40(1)
- _savefpr_28: stfd 28,-32(1)
- _savefpr_29: stfd 29,-24(1)
- _savefpr_30: stfd 30,-16(1)
- _savefpr_31: stfd 31,-8(1)
- std 0, 16(1)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* The _restfpr_M routines restore the floating point registers from fM to f31.
- * When the routine is called, r1 must point to the start of the floating point
- * register save area.
- */
- _restfpr_14: lfd 14,-144(1)
- _restfpr_15: lfd 15,-136(1)
- _restfpr_16: lfd 16,-128(1)
- _restfpr_17: lfd 17,-120(1)
- _restfpr_18: lfd 18,-112(1)
- _restfpr_19: lfd 19,-104(1)
- _restfpr_20: lfd 20,-96(1)
- _restfpr_21: lfd 21,-88(1)
- _restfpr_22: lfd 22,-80(1)
- _restfpr_23: lfd 23,-72(1)
- _restfpr_24: lfd 24,-64(1)
- _restfpr_25: lfd 25,-56(1)
- _restfpr_26: lfd 26,-48(1)
- _restfpr_27: lfd 27,-40(1)
- _restfpr_28: lfd 28,-32(1)
- _restfpr_29:
- ld 0, 16(1)
- lfd 29,-24(1)
- mtlr 0
- lfd 30,-16(1)
- lfd 31,-8(1)
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- _restfpr_30: lfd 30,-16(1)
- _restfpr_31:
- ld 0, 16(1)
- lfd 31,-8(1)
- mtlr 0
- blr
- .long 0
- .byte 0, 12, 64, 0, 0, 0, 0, 0
- /* Each _savevr_M routine saves the vector registers from vM to v31, inclusive.
- * When the routine is called, r0 must point to the word just beyound the end
- * of the vector register save area. On return the value of r0 is unchanged
- * while r12 may be modified.
- */
- /* commented out for now, unused
- _savevr_20: addi r12,r0,-192
- stvx v20,r12,r0
- _savevr_21: addi r12,r0,-176
- stvx v21,r12,r0
- _savevr_22: addi r12,r0,-160
- stvx v22,r12,r0
- _savevr_23: addi r12,r0,-144
- stvx v23,r12,r0
- _savevr_24: addi r12,r0,-128
- stvx v24,r12,r0
- _savevr_25: addi r12,r0,-112
- stvx v25,r12,r0
- _savevr_26: addi r12,r0,-96
- stvx v26,r12,r0
- _savevr_27: addi r12,r0,-80
- stvx v27,r12,r0
- _savevr_28: addi r12,r0,-64
- stvx v28,r12,r0
- _savevr_29: addi r12,r0,-48
- stvx v29,r12,r0
- _savevr_30: addi r12,r0,-32
- stvx v30,r12,r0
- _savevr_31: addi r12,r0,-16
- stvx v31,r12,r0
- blr
- */
- /* The _restvr_M routines restore the vector registers from vM to v31. When the
- * routine is called, r0 must point to the word just beyound the end of the
- * vector register save area. On return the value of r0 is unchanged while r12
- * may be modified.
- */
- /* commented out for now, unused
- _restvr_20: addi r12,r0,-192
- lvx v20,r12,r0
- _restvr_21: addi r12,r0,-176
- lvx v21,r12,r0
- _restvr_22: addi r12,r0,-160
- lvx v22,r12,r0
- _restvr_23: addi r12,r0,-144
- lvx v23,r12,r0
- _restvr_24: addi r12,r0,-128
- lvx v24,r12,r0
- _restvr_25: addi r12,r0,-112
- lvx v25,r12,r0
- _restvr_26: addi r12,r0,-96
- lvx v26,r12,r0
- _restvr_27: addi r12,r0,-80
- lvx v27,r12,r0
- _restvr_28: addi r12,r0,-64
- lvx v28,r12,r0
- _restvr_29: addi r12,r0,-48
- lvx v29,r12,r0
- _restvr_30: addi r12,r0,-32
- lvx v30,r12,r0
- _restvr_31: addi r12,r0,-16
- lvx v31,r12,r0
- blr
- */
- /*
- * start_addresses is a structure containing the real
- * entry point (next to other things not interesting to
- * us here).
- *
- * All references in the struct are function descriptors
- *
- */
- .section ".rodata"
- .align 3
- start_addresses:
- .quad 0 /* was _SDA_BASE_ but not in 64-bit ABI*/
- .quad main_stub
- .quad __libc_csu_init
- .quad __libc_csu_fini
- .size start_adresses, .-start_addresses
- /*
- * the real entry point for the program
- */
- FUNCTION_PROLOG _start
- mr 9,1 /* save the stack pointer */
- /* Set up an initial stack frame, and clear the LR. */
- clrrdi 1,1,4
- li 0,0
- stdu 1,-128(1)
- mtlr 0
- std 0,0(1)
- /* put the address of start_addresses in r8... */
- /* PPC64 ABI uses R13 for thread local, so we leave it alone */
- LOAD_64BIT_VAL 8, start_addresses
- bl __libc_start_main
- nop /* a NOP for the linker */
- /*
- * This is our FreePascal main procedure which is called by
- * libc after initializing.
- */
- FUNCTION_PROLOG main_stub
- mflr 0
- std 0,16(1)
- stdu 1,-128(1)
- LOAD_64BIT_VAL 8, operatingsystem_parameter_argc
- stw 3,0(8)
- LOAD_64BIT_VAL 8, operatingsystem_parameter_argv
- std 4,0(8)
- LOAD_64BIT_VAL 8, operatingsystem_parameter_envp
- std 5,0(8)
- LOAD_64BIT_VAL 8, __stkptr
- std 1,0(8)
- LOAD_64BIT_VAL 8, ___fpc_ret
- std 1,0(8)
- bl PASCALMAIN
- nop
- b ._haltproc
- FUNCTION_PROLOG _haltproc
- LOAD_64BIT_VAL 8, ___fpc_ret
- ld 1, 0(8)
- addi 1, 1, 128
- ld 0, 16(1)
- mtlr 0
- blr
- /* Define a symbol for the first piece of initialized data. */
- .section ".data"
- .globl __data_start
- __data_start:
- data_start:
- ___fpc_ret: /* return address to libc */
- .quad 0
- .section ".bss"
- .type __stkptr, @object
- .size __stkptr, 8
- .global __stkptr
- __stkptr:
- .skip 8
- .type operatingsystem_parameters, @object
- .size operatingsystem_parameters, 24
- operatingsystem_parameters:
- .skip 3 * 8
- .global operatingsystem_parameter_argc
- .global operatingsystem_parameter_argv
- .global operatingsystem_parameter_envp
- .set operatingsystem_parameter_argc, operatingsystem_parameters+0
- .set operatingsystem_parameter_argv, operatingsystem_parameters+8
- .set operatingsystem_parameter_envp, operatingsystem_parameters+16
- .section .note.GNU-stack,"",%progbits
|