From f3d080f57a8bdf017aa9a0227aacb04b6b5dc4c5 Mon Sep 17 00:00:00 2001 From: marcus Date: Tue, 15 Nov 2016 19:33:46 +0000 Subject: [PATCH] AROS: improve ARM-startupcode with Alloc own stack, if OS stack is too small git-svn-id: trunk@34901 - --- rtl/aros/arm/prt0.as | 215 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 174 insertions(+), 41 deletions(-) diff --git a/rtl/aros/arm/prt0.as b/rtl/aros/arm/prt0.as index 70d09a6b03..8bd87bcfac 100644 --- a/rtl/aros/arm/prt0.as +++ b/rtl/aros/arm/prt0.as @@ -1,4 +1,4 @@ -/* +/* This file is part of the Free Pascal run time library. Copyright (c) 2016 by Marcus Sackrow @@ -10,57 +10,190 @@ 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 + + .text + .globl _start + .type _start,#function _start: - push {r0-r12,r14} - ldr ip,=_Backjump - str lr,[ip] - /* ExecBase */ - ldr ip,=_ExecBase - str r5, [ip] /* Execbase seems to be in r5 ;-)*/ + # save registers + push {r0-r12,r14} + # save the back jump into OS + ldr ip,=_Backjump + str lr,[ip] - /* Save initial stackpointer*/ - ldr ip,=__stkptr - str sp,[ip] - - bl PASCALMAIN + /* ExecBase */ + ldr ip,=_ExecBase + str r2, [ip] /* ExecBase seems to be in r2 ;-)*/ - /*mov r0,#71 - bl _RawCharS - mov r0,#10 - bl _RawCharS*/ + /* Save initial stackpointer*/ + ldr ip,=__stkptr + str sp,[ip] - .globl _haltproc - .type _haltproc,#function + # 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: - - ldr ip,=__stkptr - ldr sp,[ip] + # Check if StackAreaPtr not set -> no need to free, can directly exit + ldr ip,=StackAreaPtr + ldr r0,[ip] + cmp r0, #0 + beq _exit - pop {r0-r12,r14} + # StackAreaPtr is assigned, so we did the Stack Swap and must + # swap back and free the memory - /* exitcode should be r0*/ - ldr ip,=operatingsystem_result - ldr r0,[ip] + # 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 - ldr ip,=_Backjump - ldr lr,[ip] - bx lr - +/* jumps here after Stackswap leaving -> with original stack again*/ +_afterstackswap: + # get StackAreaPtr + ldr ip,=StackAreaPtr + ldr r0,[ip] - /* Define a symbol for the first piece of initialized data. */ - .data - .globl __data_start + # 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 + .long 0 + .weak data_start + data_start = __data_start .bss .comm __stkptr,4 - .comm _ExecBase,4 - .comm _Backjump,4 + .comm __stkptr1,4 + .comm _ExecBase,4 + .comm _Backjump,4 + .comm StackAreaPtr,4 + .comm StackSwapStruct, 12 + .comm StackSwapArgs, 32