prt0.as 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #
  2. # This file is part of the Free Pascal run time library.
  3. # Copyright (c) 2015-2016 by Marcus Sackrow
  4. #
  5. # AROS x86_64 startup code
  6. #
  7. # See the file COPYING.FPC, included in this distribution,
  8. # for details about the copyright.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY;without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. #
  14. #**********************************************************************}
  15. # AROS startup code
  16. .text
  17. .align 8
  18. .section .aros.startup, "ax"
  19. .globl start
  20. .globl _start
  21. .type _start,@function
  22. _start:
  23. start:
  24. # save registers, suggested by
  25. # System V Application Binary Interface
  26. # AMD64 Architecture Processor Support
  27. # 0.99.6 page 21 Fig. 3.4
  28. push %rbp
  29. push %rbx
  30. push %r12
  31. push %r13
  32. push %r14
  33. push %r15
  34. movq %rdx, _ExecBase
  35. movq %rsp, STKPTR
  36. # todo: stack change (see i386)
  37. # FindTask(nil)
  38. movq _ExecBase, %rsi /* Execbase to rsi */
  39. movq $0, %rdi /* 1. Argument nil */
  40. movq -392(%rsi), %rax /* calculate jump address */
  41. call *%rax /* do the call */
  42. # PTask in %rax -> get data from PTask splower rbx, spupper rcx
  43. movq 112(%rax), %rcx
  44. movq 104(%rax), %rbx
  45. subq %rbx, %rcx
  46. # check if Stack is big enough
  47. cmpl __stklen, %ecx
  48. jl _AllocStack /* we need a stack */
  49. # no stack needed, clear StackAreaPtr jump to Pascal routine
  50. xorq %rax, %rax
  51. movq %rax, StackAreaPtr
  52. jmp _NoAllocStack
  53. # Alloc a new Stack and swap to it
  54. _AllocStack:
  55. # AllocVec(__stklen, MEMF_ANY)
  56. movq _ExecBase, %rdx /* execbase Execbase is already in %rdx */
  57. movq $0, %rsi /* 2. Argument MEMF_ANY to %rsi */
  58. movl __stklen, %edi /* 1. Argument stklen to %edi */
  59. call *-912(%rdx) /* Do the call */
  60. # save the Stack Area
  61. movq %rax, StackAreaPtr
  62. # Check if we got some memory
  63. cmpq $0, %rax
  64. je _exit
  65. # Setup StackSwapStruct
  66. lea StackSwapStruct, %rcx /* StackSwapStruct in RCX */
  67. movq StackAreaPtr, %rax
  68. movq %rax,(%rcx) /* stk_Lower Bottom of the stack */
  69. xorq %rbx, %rbx
  70. movl __stklen, %ebx /* get Stacklen */
  71. addq %rbx, %rax /* add stacklen to lower stack pointer */
  72. movq %rax, 8(%rcx) /* Top of the stack */
  73. movq %rax, 16(%rcx) /* Initial stackpointer */
  74. # NewStackSwap(StackSwapStruct, _initProc, StackSwapArgs)
  75. movq _ExecBase, %rcx /* Execbase to rcx */
  76. lea StackSwapArgs, %rdx /* 3. Argument StackSwapArgument -> rdx */
  77. lea _initProc, %rsi /* 2. Argument FunktionPtr -> rsi */
  78. lea StackSwapStruct, %rdi /* 1. Argument StackSwapStruct -> rdi */
  79. call *-1072(%rcx) /* Do the call */
  80. jmp _afterMain
  81. _NoAllocStack:
  82. call _initProc
  83. _afterMain:
  84. # test it StackArea Ptr assigned
  85. movq StackAreaPtr,%rax
  86. cmpq $0, StackAreaPtr
  87. je _exit /* its nil -> direkt exit */
  88. # FreeVec(StackAreaPtr)
  89. movq _ExecBase, %rsi /* ExecBase as last argument %rsi */
  90. movq StackAreaPtr, %rdi /* StackAreaPtr 1 Argument %rdi */
  91. call *-920(%rsi) /* Do the call */
  92. _exit:
  93. # set returncode
  94. movslq operatingsystem_result,%rax
  95. # get back all registers
  96. mov STKPTR, %rsp
  97. pop %r15
  98. pop %r14
  99. pop %r13
  100. pop %r12
  101. pop %rbx
  102. pop %rbp
  103. # bye bye
  104. ret
  105. _initProc:
  106. push %rbp
  107. push %rbx
  108. push %r12
  109. push %r13
  110. push %r14
  111. push %r15
  112. # Save stack pointer
  113. movq %rsp,SSTKPTR
  114. # call the pascal main function
  115. callq PASCALMAIN
  116. # entry to stop the program
  117. .globl _haltproc
  118. .type _haltproc,@function
  119. _haltproc:
  120. # restore the old stackPtr and return
  121. movq SSTKPTR,%rsp
  122. pop %r15
  123. pop %r14
  124. pop %r13
  125. pop %r12
  126. pop %rbx
  127. pop %rbp
  128. ret
  129. /*----------------------------------------------------*/
  130. .data
  131. .globl __data_start
  132. __data_start:
  133. .long 0
  134. .weak data_start
  135. data_start = __data_start
  136. .bss
  137. .type STKPTR,@object
  138. .size STKPTR,8
  139. STKPTR: .skip 8
  140. .type SSTKPTR,@object
  141. .size SSTKPTR,8
  142. SSTKPTR: .skip 8
  143. .type _ExecBase,@object
  144. .size _ExecBase,8
  145. .global _ExecBase
  146. _ExecBase: .skip 8
  147. .type StackAreaPtr,@object
  148. .size StackAreaPtr,8
  149. StackAreaPtr: .skip 8
  150. .type StackSwapStruct,@object
  151. .size StackSwapStruct,24
  152. StackSwapStruct: .skip 24
  153. .type StackSwapStruct,@object
  154. .size StackSwapStruct,64
  155. StackSwapArgs: .skip 64