| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #
- # This file is part of the Free Pascal run time library.
- # Copyright (c) 2015-2016 by Marcus Sackrow
- #
- # AROS x86_64 startup code
- #
- # 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.
- #
- #**********************************************************************}
- # AROS startup code
- .text
- .align 8
- .section .aros.startup, "ax"
- .globl start
- .globl _start
- .type _start,@function
- _start:
- start:
- # save registers, suggested by
- # System V Application Binary Interface
- # AMD64 Architecture Processor Support
- # 0.99.6 page 21 Fig. 3.4
- push %rbp
- push %rbx
- push %r12
- push %r13
- push %r14
- push %r15
- movq %rdx, _ExecBase
- movq %rsp, STKPTR
- # todo: stack change (see i386)
- # FindTask(nil)
- movq _ExecBase, %rsi /* Execbase to rsi */
- movq $0, %rdi /* 1. Argument nil */
- movq -392(%rsi), %rax /* calculate jump address */
- call *%rax /* do the call */
- # PTask in %rax -> get data from PTask splower rbx, spupper rcx
- movq 112(%rax), %rcx
- movq 104(%rax), %rbx
- subq %rbx, %rcx
- # check if Stack is big enough
- cmpl __stklen, %ecx
- jl _AllocStack /* we need a stack */
- # no stack needed, clear StackAreaPtr jump to Pascal routine
- xorq %rax, %rax
- movq %rax, StackAreaPtr
- jmp _NoAllocStack
- # Alloc a new Stack and swap to it
- _AllocStack:
- # AllocVec(__stklen, MEMF_ANY)
- movq _ExecBase, %rdx /* execbase Execbase is already in %rdx */
- movq $0, %rsi /* 2. Argument MEMF_ANY to %rsi */
- movl __stklen, %edi /* 1. Argument stklen to %edi */
- call *-912(%rdx) /* Do the call */
- # save the Stack Area
- movq %rax, StackAreaPtr
- # Check if we got some memory
- cmpq $0, %rax
- je _exit
- # Setup StackSwapStruct
- lea StackSwapStruct, %rcx /* StackSwapStruct in RCX */
- movq StackAreaPtr, %rax
- movq %rax,(%rcx) /* stk_Lower Bottom of the stack */
- xorq %rbx, %rbx
- movl __stklen, %ebx /* get Stacklen */
- addq %rbx, %rax /* add stacklen to lower stack pointer */
- movq %rax, 8(%rcx) /* Top of the stack */
- movq %rax, 16(%rcx) /* Initial stackpointer */
- # NewStackSwap(StackSwapStruct, _initProc, StackSwapArgs)
- movq _ExecBase, %rcx /* Execbase to rcx */
- lea StackSwapArgs, %rdx /* 3. Argument StackSwapArgument -> rdx */
- lea _initProc, %rsi /* 2. Argument FunktionPtr -> rsi */
- lea StackSwapStruct, %rdi /* 1. Argument StackSwapStruct -> rdi */
- call *-1072(%rcx) /* Do the call */
- jmp _afterMain
- _NoAllocStack:
- call _initProc
- _afterMain:
- # test it StackArea Ptr assigned
- movq StackAreaPtr,%rax
- cmpq $0, StackAreaPtr
- je _exit /* its nil -> direkt exit */
- # FreeVec(StackAreaPtr)
- movq _ExecBase, %rsi /* ExecBase as last argument %rsi */
- movq StackAreaPtr, %rdi /* StackAreaPtr 1 Argument %rdi */
- call *-920(%rsi) /* Do the call */
- _exit:
- # set returncode
- movslq operatingsystem_result,%rax
- # get back all registers
- mov STKPTR, %rsp
- pop %r15
- pop %r14
- pop %r13
- pop %r12
- pop %rbx
- pop %rbp
- # bye bye
- ret
- _initProc:
- push %rbp
- push %rbx
- push %r12
- push %r13
- push %r14
- push %r15
- # Save stack pointer
- movq %rsp,SSTKPTR
- # call the pascal main function
- callq PASCALMAIN
- # entry to stop the program
- .globl _haltproc
- .type _haltproc,@function
- _haltproc:
- # restore the old stackPtr and return
- movq SSTKPTR,%rsp
- pop %r15
- pop %r14
- pop %r13
- pop %r12
- pop %rbx
- pop %rbp
- ret
- /*----------------------------------------------------*/
- .data
- .globl __data_start
- __data_start:
- .long 0
- .weak data_start
- data_start = __data_start
- .bss
- .type STKPTR,@object
- .size STKPTR,8
- STKPTR: .skip 8
- .type SSTKPTR,@object
- .size SSTKPTR,8
- SSTKPTR: .skip 8
- .type _ExecBase,@object
- .size _ExecBase,8
- .global _ExecBase
- _ExecBase: .skip 8
- .type StackAreaPtr,@object
- .size StackAreaPtr,8
- StackAreaPtr: .skip 8
- .type StackSwapStruct,@object
- .size StackSwapStruct,24
- StackSwapStruct: .skip 24
- .type StackSwapStruct,@object
- .size StackSwapStruct,64
- StackSwapArgs: .skip 64
|