Ver código fonte

AROS: improve ARM-startupcode with Alloc own stack, if OS stack is too small

git-svn-id: trunk@34901 -
marcus 8 anos atrás
pai
commit
f3d080f57a
1 arquivos alterados com 177 adições e 44 exclusões
  1. 177 44
      rtl/aros/arm/prt0.as

+ 177 - 44
rtl/aros/arm/prt0.as

@@ -1,4 +1,4 @@
-/* 
+/*
   This file is part of the Free Pascal run time library.
   This file is part of the Free Pascal run time library.
   Copyright (c) 2016 by Marcus Sackrow
   Copyright (c) 2016 by Marcus Sackrow
 
 
@@ -10,57 +10,190 @@
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY;without even the implied warranty of
   but WITHOUT ANY WARRANTY;without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   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:
 _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 initial stackpointer*/
-	ldr ip,=__stkptr
-	str sp,[ip]
-	
-	bl PASCALMAIN
-
-	/*mov r0,#71
-	bl _RawCharS
-	mov r0,#10
-	bl _RawCharS*/
-
-	.globl  _haltproc
-	.type   _haltproc,#function
+  # 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:
 _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
+
+  # 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]
 
 
-	pop {r0-r12,r14}
+  # restore registers
+  pop {r0-r12,r14}
 
 
-	/* exitcode should be r0*/
-	ldr ip,=operatingsystem_result
-	ldr r0,[ip]
+  # exitcode should be r0
+  ldr ip,=operatingsystem_result
+  ldr r0,[ip]
 
 
-	ldr ip,=_Backjump
-	ldr lr,[ip]
-	bx lr
-	
+  # 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
+  /* Define a symbol for the first piece of initialized data.  */
+  .data
+  .globl __data_start
 __data_start:
 __data_start:
-	.long 0
-	.weak data_start
-	data_start = __data_start
+  .long 0
+  .weak data_start
+  data_start = __data_start
 
 
 .bss
 .bss
   .comm __stkptr,4
   .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