Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
fpc-src / usr / share / fpcsrc / 3.0.0 / rtl / linux / powerpc64 / prt0.as
Size: Mime:
/*
 * This file is part of the Free Pascal run time library.
 * Copyright (c) 2005 by Thomas Schatzl,
 * member of the Free Pascal development team.
 *
 * Startup code for normal programs, PowerPC64 version.
 *
 * See the file COPYING.FPC, included in this distribution,
 * for details about the copyright.
 *
 * This program 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.
 */

.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, 16(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
*/

/*
 * Main program entry point for dynamic executables.
 *
 * r7 contains the function pointer that needs to be registered for calling at exit.
 */
FUNCTION_PROLOG _dynamic_start
  LOAD_64BIT_VAL 11, __dl_fini
  std      7,0(11)
  LOAD_64BIT_VAL 11, _start
  /* do not bother loading the actual function address of _start. We can directly jump to it */
  /* set up GOT pointer from original start function */
  ld       2,8(11)
  /* and environment pointer */
  ld      11,16(11)
  b       _start
.long 0
.byte 0, 12, 64, 0, 0, 0, 0, 0

/*
 * Main program entry point for static executables
 *
 * The document "64-bit PowerPC ELF Application Binary Interface Supplement 1.9"
 * pg. 24f specifies that argc/argv/envp are passed in registers r3/r4/r5 respectively,
 * but that does not seem to be the case.
 *
 * However the stack layout and contents are the same as for other platforms, so
 * use this.
 */
FUNCTION_PROLOG _start
    mr     26,1            /* save stack pointer */
    /* Set up an initial stack frame, and clear the LR */
    clrrdi  1,1,5          /* align r1 */
    li      0,0
    stdu    1,-128(1)
    mtlr    0
    std     0,0(1)        /* r1 = pointer to NULL value */

    /* store argument count (= 0(r1) )*/
    ld      3,0(26)
    LOAD_64BIT_VAL 10,operatingsystem_parameter_argc
    stw     3,0(10)
    /* calculate argument vector address and store (= 8(r1) + 8 ) */
    addi    4,26,8
    LOAD_64BIT_VAL 10,operatingsystem_parameter_argv
    std     4,0(10)
    /* store environment pointer (= argv + (argc+1)* 8 ) */
    addi    5,3,1
    sldi    5,5,3
    add     5,4,5
    LOAD_64BIT_VAL 10, operatingsystem_parameter_envp
    std     5,0(10)

    LOAD_64BIT_VAL 8,__stkptr
    std     1,0(8)

    bl      PASCALMAIN
    nop

    /* we should not reach here. Crash horribly */
    trap

FUNCTION_PROLOG _haltproc
    mflr  0
    std   0,16(1)
    stdu  1,-144(1)

    LOAD_64BIT_VAL 11,__dl_fini
    ld    11,0(11)
    cmpdi 11,0
    beq .LNoCallDlFini

    bl .ptrgl
    ld      2,40(1)

.LNoCallDlFini:

    LOAD_64BIT_VAL 3, operatingsystem_result
    lwz     3,0(3)
    /* exit group call */
    li      0,234
    sc

    LOAD_64BIT_VAL 3, operatingsystem_result
    lwz     3,0(3)
    /* exit call */
    li      0,1
    sc
    /* we should not reach here. Crash horribly */
    trap
    /* do not bother cleaning up the stack frame, we should not reach here */
.long 0
.byte 0, 12, 64, 0, 0, 0, 0, 0

    /* Define a symbol for the first piece of initialized data.  */
    .section ".data"
    .globl  __data_start
__data_start:
data_start:

    .section ".bss"

    .type __stkptr, @object
    .size __stkptr, 8
    .global __stkptr
__stkptr:
    .skip 8

    .type __dl_fini, @object
    .size __dl_fini, 8
    .global __dl_fini
__dl_fini:
    .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