mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 11:39:40 +01:00 
			
		
		
		
	* forgot to commit ppc64 gprt0.as used for gprof support
* fixed ppc64 exception mask stuff (same as 3136 for ppc32) git-svn-id: trunk@3298 -
This commit is contained in:
		
							parent
							
								
									d98336156f
								
							
						
					
					
						commit
						a9df7aa81a
					
				@ -1,4 +1,441 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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., 59 Temple Place, Suite 330, Boston, MA
 | 
			
		||||
   02111-1307 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
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* empty */
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
    b   .__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)
 | 
			
		||||
 | 
			
		||||
    LOAD_64BIT_VAL 3, _start
 | 
			
		||||
    ld 3, 0(3)
 | 
			
		||||
    LOAD_64BIT_VAL 4, etext
 | 
			
		||||
    bl  .__monstartup
 | 
			
		||||
    nop
 | 
			
		||||
 | 
			
		||||
    LOAD_64BIT_VAL 3, _mcleanup
 | 
			
		||||
    bl .atexit
 | 
			
		||||
    nop
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
    .comm __stkptr, 8
 | 
			
		||||
 | 
			
		||||
    .comm operatingsystem_parameter_argc, 4
 | 
			
		||||
    .comm operatingsystem_parameter_argv, 8
 | 
			
		||||
    .comm operatingsystem_parameter_envp, 8
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ const
 | 
			
		||||
  UnderflowMask        = %00100000;
 | 
			
		||||
  ZeroDivideMask       = %00010000;
 | 
			
		||||
  InexactMask          = %00001000;
 | 
			
		||||
  ExceptionsPendingMask = %11111111111111100000011100000000;
 | 
			
		||||
 | 
			
		||||
  ExceptionMask        = InvalidOperationMask or OverflowMask or UnderflowMask or ZeroDivideMask or InexactMask;
 | 
			
		||||
 | 
			
		||||
@ -29,14 +30,14 @@ const
 | 
			
		||||
function getFPSCR : DWord; assembler; nostackframe;
 | 
			
		||||
asm
 | 
			
		||||
  mffs f0
 | 
			
		||||
  stfd f0, -8(r1)
 | 
			
		||||
  ld r3, -8(r1)
 | 
			
		||||
  stfd f0, -12(r1)
 | 
			
		||||
  lwz r3, -8(r1)
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure setFPSCR(newFPSCR : DWord); assembler; nostackframe;
 | 
			
		||||
asm
 | 
			
		||||
  std r3, -8(r1)
 | 
			
		||||
  lfd f0, -8(r1)
 | 
			
		||||
  stw r3, -8(r1)
 | 
			
		||||
  lfd f0, -12(r1)
 | 
			
		||||
  mtfsf 255, f0
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -80,15 +81,15 @@ end;
 | 
			
		||||
function GetExceptionMask: TFPUExceptionMask;
 | 
			
		||||
begin
 | 
			
		||||
  result := [];
 | 
			
		||||
  if ((getFPSCR and InvalidOperationMask) <> 0) then 
 | 
			
		||||
  if ((getFPSCR and InvalidOperationMask) = 0) then 
 | 
			
		||||
    result := result + [exInvalidOp];
 | 
			
		||||
  if ((getFPSCR and OverflowMask) <> 0) then 
 | 
			
		||||
  if ((getFPSCR and OverflowMask) = 0) then 
 | 
			
		||||
    result := result + [exOverflow];
 | 
			
		||||
  if ((getFPSCR and UnderflowMask) <> 0) then 
 | 
			
		||||
  if ((getFPSCR and UnderflowMask) = 0) then 
 | 
			
		||||
    result := result + [exUnderflow];
 | 
			
		||||
  if ((getFPSCR and ZeroDivideMask) <> 0) then 
 | 
			
		||||
  if ((getFPSCR and ZeroDivideMask) = 0) then 
 | 
			
		||||
    result := result + [exZeroDivide];
 | 
			
		||||
  if ((getFPSCR and InexactMask) <> 0) then 
 | 
			
		||||
  if ((getFPSCR and InexactMask) = 0) then 
 | 
			
		||||
    result := result + [exPrecision];
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -108,7 +109,7 @@ begin
 | 
			
		||||
  if (exPrecision in Mask) then
 | 
			
		||||
    mode := mode or InexactMask;
 | 
			
		||||
  
 | 
			
		||||
  setFPSCR((getFPSCR and (not ExceptionMask)) or mode);
 | 
			
		||||
  setFPSCR((getFPSCR or ExceptionMask) and not mode and not ExceptionsPendingMask);
 | 
			
		||||
  result := Mask - [exDenormalized];
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user