123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /*
- This file is part of the Free Pascal run time library.
- Copyright (c) 2016 by Marcus Sackrow
- Startup code for AROS/ARM RTL
- 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.
- r0 = argc
- r1 = argv
- r2 = ExecBase
- */
- .text
- .globl _start
- .type _start,#function
- _start:
- # save registers
- push {r0-r12,r14}
- # save the back jump into OS
- ldr ip,=_Backjump
- str lr,[ip]
- /* ExecBase */
- ldr ip,=_ExecBase
- str r2, [ip] /* ExecBase seems to be in r2 ;-)*/
- /* Save initial stackpointer*/
- ldr ip,=__stkptr
- str sp,[ip]
- # jump back -> exit
- ldr ip,=_exit
- ldr lr,[ip]
- /* check for stack extent */
- /* FindTask(nil) */
- # execbase to r1
- ldr r1,=_ExecBase
- ldr r1,[r1]
- # nil to r0
- mov r0,#0
- # caluclate offset
- ldr r12,[r1, #-196]
- # do it
- blx r12
- /* get data from PTask splower r0, spupper r1 */
- mov r1, r0
- ldr r0, [r0, #60]
- ldr r1, [r1, #64]
- /* sub spUpper- spLower */
- sub r0,r1,r0
- /* compre with stacklen */
- ldr r1,=__stklen
- ldr r1,[r1]
- /* if OS stack bigger jump to nostack -> no stackswap needed */
- cmp r0, r1
- bge _nostack
- /* alloc a new stack and swap to it */
- _withstack:
- /* AllocVec(__stklen, MEMF_ANY) */
- # execbase to r2
- ldr r2,=_ExecBase
- ldr r2,[r2]
- # MEMF_ANY (0) to r1
- mov r1,#0
- # stacksize to r0
- ldr r0,=__stklen
- ldr r0,[r0]
- # do the call
- ldr r12,[r2, #-456]
- blx r12
- # save the Pointer to StackAreaPtr
- ldr ip,=StackAreaPtr
- str r0,[ip]
- # check if we got some Memory -> else byebye
- cmp r0, #0
- beq _exit
- /* Prepare StackSwapStruct */
- ldr ip,=StackSwapStruct
- str r0,[ip] /* stk_Lower */
- # get stacklen
- ldr r1,=__stklen
- ldr r1,[r1]
- # add StackLen to Lower Stack
- add r0,r1,r0
- # put upper stack swap
- str r0,[ip, #4] /* stk_Upper */
- # start pointer
- str r0,[ip, #8] /* stk_Pointer */
- /* NewStackSwap(StackSwapStruct, _runpascal, StackSwapArgs) */
- # 4. ExecBase
- ldr r3,=_ExecBase
- ldr r3,[r3]
- # 3. StackSwapArgs
- ldr r2,=StackSwapArgs
- # 2. funcptr
- ldr r1,=_runpascal
- # 1. StackSwapStruct
- ldr r0,=StackSwapStruct
- # do the call
- ldr r12,[r3, #-536]
- blx r12
- # after Stackswap we just to _afterstackswap to leave the program
- bl _afterstackswap
- /* NewStackswap will jump here */
- _runpascal:
- # save registers on the new stack
- push {r0-r12,lr}
- # save the stackswapped stackptr to
- ldr ip,=__stkptr1
- str sp,[ip]
- /* Main Program for both cases */
- _nostack:
- # call the Pascal Main
- bl PASCALMAIN
- # seems never reach this point
- /* haltproc is called by Pascal */
- .globl _haltproc
- .type _haltproc,#function
- _haltproc:
- # Check if StackAreaPtr not set -> no need to free, can directly exit
- ldr ip,=StackAreaPtr
- ldr r0,[ip]
- cmp r0, #0
- beq _exit
- # StackAreaPtr is assigned, so we did the Stack Swap and must
- # swap back and free the memory
- # get back the stackswaped stack and get back all registers and jump back
- # to stackswap -> leave the Stack
- ldr ip,=__stkptr1
- ldr sp,[ip]
- pop {r0-r12,lr}
- bx lr
- /* jumps here after Stackswap leaving -> with original stack again*/
- _afterstackswap:
- # get StackAreaPtr
- ldr ip,=StackAreaPtr
- ldr r0,[ip]
- # freeVec(StackAreaPtr)
- #execbase to r1
- ldr r1,=_ExecBase
- ldr r1,[r1]
- #calc FreeVec offset
- ldr r12,[r1, #-460]
- blx r12
- /* jumps here on error or if no stackswap was done */
- _exit:
- # get back the original OS Stack
- ldr ip,=__stkptr
- ldr sp,[ip]
- # restore registers
- pop {r0-r12,r14}
- # exitcode should be r0
- ldr ip,=operatingsystem_result
- ldr r0,[ip]
- # jump back to OS
- ldr ip,=_Backjump
- ldr lr,[ip]
- bx lr
- /* Define a symbol for the first piece of initialized data. */
- .data
- .globl __data_start
- __data_start:
- .long 0
- .weak data_start
- data_start = __data_start
- .bss
- .comm __stkptr,4
- .comm __stkptr1,4
- .comm _ExecBase,4
- .comm _Backjump,4
- .comm StackAreaPtr,4
- .comm StackSwapStruct, 12
- .comm StackSwapArgs, 32
|