prt0.as 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * This file is part of the Free Pascal run time library.
  3. * Copyright (c) 2005 by Thomas Schatzl,
  4. * member of the Free Pascal development team.
  5. *
  6. * Startup code for normal programs, PowerPC64 version.
  7. *
  8. * See the file COPYING.FPC, included in this distribution,
  9. * for details about the copyright.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. */
  15. .macro LOAD_64BIT_VAL ra, value
  16. lis \ra,\value@highest
  17. ori \ra,\ra,\value@higher
  18. sldi \ra,\ra,32
  19. oris \ra,\ra,\value@h
  20. ori \ra,\ra,\value@l
  21. .endm
  22. /* create function prolog for symbol "fn" */
  23. .macro FUNCTION_PROLOG fn
  24. .section ".text"
  25. .align 2
  26. .globl \fn
  27. .section ".opd", "aw"
  28. .align 3
  29. \fn:
  30. .quad .\fn, .TOC.@tocbase, 0
  31. .previous
  32. .size \fn, 24
  33. .type \fn, @function
  34. .globl .\fn
  35. .\fn:
  36. .endm
  37. /*
  38. * "ptrgl" glue code for calls via pointer. This function
  39. * sequence loads the data from the function descriptor
  40. * referenced by R11 into the CTR register (function address),
  41. * R2 (GOT/TOC pointer), and R11 (the outer frame pointer).
  42. *
  43. * On entry, R11 must be set to point to the function descriptor.
  44. *
  45. * See also the 64-bit PowerPC ABI specification for more
  46. * information, chapter 3.5.11 (in v1.7).
  47. */
  48. .section ".text"
  49. .align 3
  50. .globl .ptrgl
  51. .ptrgl:
  52. ld 0, 0(11)
  53. std 2, 40(1)
  54. mtctr 0
  55. ld 2, 8(11)
  56. ld 11, 8(11)
  57. bctr
  58. .long 0
  59. .byte 0, 12, 128, 0, 0, 0, 0, 0
  60. .type .ptrgl, @function
  61. .size .ptrgl, . - .ptrgl
  62. /*
  63. * Function prolog/epilog helpers, which are part of the 64-bit
  64. * PowerPC ABI.
  65. *
  66. * See also the 64-bit PowerPC ABI specification for more
  67. * information, chapter 3.5.5, "Register saving and restoring
  68. * function" (in v1.7).
  69. */
  70. /* Each _savegpr0_N routine saves the general registers from rN to r31,
  71. * inclusive. When the routine is called, r1 must point to the start
  72. * of the general register save area. R0 must contain the old LR on
  73. * entry.
  74. */
  75. _savegpr0_14: std 14,-144(1)
  76. _savegpr0_15: std 15,-136(1)
  77. _savegpr0_16: std 16,-128(1)
  78. _savegpr0_17: std 17,-120(1)
  79. _savegpr0_18: std 18,-112(1)
  80. _savegpr0_19: std 19,-104(1)
  81. _savegpr0_20: std 20,-96(1)
  82. _savegpr0_21: std 21,-88(1)
  83. _savegpr0_22: std 22,-80(1)
  84. _savegpr0_23: std 23,-72(1)
  85. _savegpr0_24: std 24,-64(1)
  86. _savegpr0_25: std 25,-56(1)
  87. _savegpr0_26: std 26,-48(1)
  88. _savegpr0_27: std 27,-40(1)
  89. _savegpr0_28: std 28,-32(1)
  90. _savegpr0_29: std 29,-24(1)
  91. _savegpr0_30: std 30,-16(1)
  92. _savegpr0_31:
  93. std 31,-8(1)
  94. std 0, 16(1)
  95. blr
  96. .long 0
  97. .byte 0, 12, 64, 0, 0, 0, 0, 0
  98. /* Each _restgpr0_N routine restores the general registers from rN to r31,
  99. * inclusive. When the routine is called, r1 must point to the start
  100. * of the general register save area.
  101. */
  102. _restgpr0_14: ld 14,-144(1)
  103. _restgpr0_15: ld 15,-136(1)
  104. _restgpr0_16: ld 16,-128(1)
  105. _restgpr0_17: ld 17,-120(1)
  106. _restgpr0_18: ld 18,-112(1)
  107. _restgpr0_19: ld 19,-104(1)
  108. _restgpr0_20: ld 20,-96(1)
  109. _restgpr0_21: ld 21,-88(1)
  110. _restgpr0_22: ld 22,-80(1)
  111. _restgpr0_23: ld 23,-72(1)
  112. _restgpr0_24: ld 24,-64(1)
  113. _restgpr0_25: ld 25,-56(1)
  114. _restgpr0_26: ld 26,-48(1)
  115. _restgpr0_27: ld 27,-40(1)
  116. _restgpr0_28: ld 28,-32(1)
  117. _restgpr0_29:
  118. ld 0, 16(1)
  119. ld 29,-24(1)
  120. mtlr 0
  121. ld 30,-16(1)
  122. ld 31,-8(1)
  123. blr
  124. .long 0
  125. .byte 0, 12, 64, 0, 0, 0, 0, 0
  126. _restgpr0_30: ld 30,-16(1)
  127. _restgpr0_31: ld 0, 16(1)
  128. ld 31,-8(1)
  129. mtlr 0
  130. blr
  131. .long 0
  132. .byte 0, 12, 64, 0, 0, 0, 0, 0
  133. /* Each _savegpr1_N routine saves the general registers from rN to r31,
  134. * inclusive. When the routine is called, r12
  135. * must point to the start of the general register save area.
  136. */
  137. _savegpr1_14: std 14,-144(12)
  138. _savegpr1_15: std 15,-136(12)
  139. _savegpr1_16: std 16,-128(12)
  140. _savegpr1_17: std 17,-120(12)
  141. _savegpr1_18: std 18,-112(12)
  142. _savegpr1_19: std 19,-104(12)
  143. _savegpr1_20: std 20,-96(12)
  144. _savegpr1_21: std 21,-88(12)
  145. _savegpr1_22: std 22,-80(12)
  146. _savegpr1_23: std 23,-72(12)
  147. _savegpr1_24: std 24,-64(12)
  148. _savegpr1_25: std 25,-56(12)
  149. _savegpr1_26: std 26,-48(12)
  150. _savegpr1_27: std 27,-40(12)
  151. _savegpr1_28: std 28,-32(12)
  152. _savegpr1_29: std 29,-24(12)
  153. _savegpr1_30: std 30,-16(12)
  154. _savegpr1_31: std 31,-8(12)
  155. blr
  156. .long 0
  157. .byte 0, 12, 64, 0, 0, 0, 0, 0
  158. /* The _restgpr1_N routines restore the general registers from rN to r31.
  159. * When the routine is called, r12 must point to the start of the general
  160. * register save area.
  161. */
  162. _restgpr1_14: ld 14,-144(12)
  163. _restgpr1_15: ld 15,-136(12)
  164. _restgpr1_16: ld 16,-128(12)
  165. _restgpr1_17: ld 17,-120(12)
  166. _restgpr1_18: ld 18,-112(12)
  167. _restgpr1_19: ld 19,-104(12)
  168. _restgpr1_20: ld 20,-96(12)
  169. _restgpr1_21: ld 21,-88(12)
  170. _restgpr1_22: ld 22,-80(12)
  171. _restgpr1_23: ld 23,-72(12)
  172. _restgpr1_24: ld 24,-64(12)
  173. _restgpr1_25: ld 25,-56(12)
  174. _restgpr1_26: ld 26,-48(12)
  175. _restgpr1_27: ld 27,-40(12)
  176. _restgpr1_28: ld 28,-32(12)
  177. _restgpr1_29: ld 29,-24(12)
  178. _restgpr1_30: ld 30,-16(12)
  179. _restgpr1_31: ld 31,-8(12)
  180. blr
  181. .long 0
  182. .byte 0, 12, 64, 0, 0, 0, 0, 0
  183. /* Each _savefpr_M routine saves the floating point registers from fM to f31,
  184. * inclusive. When the routine is called, r1 must point to the start of the
  185. * floating point register save area, and r0 must contain the value of LR on
  186. * function entry.
  187. */
  188. _savefpr_14: stfd 14,-144(1)
  189. _savefpr_15: stfd 15,-136(1)
  190. _savefpr_16: stfd 16,-128(1)
  191. _savefpr_17: stfd 17,-120(1)
  192. _savefpr_18: stfd 18,-112(1)
  193. _savefpr_19: stfd 19,-104(1)
  194. _savefpr_20: stfd 20,-96(1)
  195. _savefpr_21: stfd 21,-88(1)
  196. _savefpr_22: stfd 22,-80(1)
  197. _savefpr_23: stfd 23,-72(1)
  198. _savefpr_24: stfd 24,-64(1)
  199. _savefpr_25: stfd 25,-56(1)
  200. _savefpr_26: stfd 26,-48(1)
  201. _savefpr_27: stfd 27,-40(1)
  202. _savefpr_28: stfd 28,-32(1)
  203. _savefpr_29: stfd 29,-24(1)
  204. _savefpr_30: stfd 30,-16(1)
  205. _savefpr_31: stfd 31,-8(1)
  206. std 0, 16(1)
  207. blr
  208. .long 0
  209. .byte 0, 12, 64, 0, 0, 0, 0, 0
  210. /* The _restfpr_M routines restore the floating point registers from fM to f31.
  211. * When the routine is called, r1 must point to the start of the floating point
  212. * register save area.
  213. */
  214. _restfpr_14: lfd 14,-144(1)
  215. _restfpr_15: lfd 15,-136(1)
  216. _restfpr_16: lfd 16,-128(1)
  217. _restfpr_17: lfd 17,-120(1)
  218. _restfpr_18: lfd 18,-112(1)
  219. _restfpr_19: lfd 19,-104(1)
  220. _restfpr_20: lfd 20,-96(1)
  221. _restfpr_21: lfd 21,-88(1)
  222. _restfpr_22: lfd 22,-80(1)
  223. _restfpr_23: lfd 23,-72(1)
  224. _restfpr_24: lfd 24,-64(1)
  225. _restfpr_25: lfd 25,-56(1)
  226. _restfpr_26: lfd 26,-48(1)
  227. _restfpr_27: lfd 27,-40(1)
  228. _restfpr_28: lfd 28,-32(1)
  229. _restfpr_29:
  230. ld 0, 16(1)
  231. lfd 29,-24(1)
  232. mtlr 0
  233. lfd 30,-16(1)
  234. lfd 31,-8(1)
  235. blr
  236. .long 0
  237. .byte 0, 12, 64, 0, 0, 0, 0, 0
  238. _restfpr_30: lfd 30,-16(1)
  239. _restfpr_31:
  240. ld 0, 16(1)
  241. lfd 31,-8(1)
  242. mtlr 0
  243. blr
  244. .long 0
  245. .byte 0, 12, 64, 0, 0, 0, 0, 0
  246. /* Each _savevr_M routine saves the vector registers from vM to v31, inclusive.
  247. * When the routine is called, r0 must point to the word just beyound the end
  248. * of the vector register save area. On return the value of r0 is unchanged
  249. * while r12 may be modified.
  250. */
  251. /* commented out for now, unused
  252. _savevr_20: addi r12,r0,-192
  253. stvx v20,r12,r0
  254. _savevr_21: addi r12,r0,-176
  255. stvx v21,r12,r0
  256. _savevr_22: addi r12,r0,-160
  257. stvx v22,r12,r0
  258. _savevr_23: addi r12,r0,-144
  259. stvx v23,r12,r0
  260. _savevr_24: addi r12,r0,-128
  261. stvx v24,r12,r0
  262. _savevr_25: addi r12,r0,-112
  263. stvx v25,r12,r0
  264. _savevr_26: addi r12,r0,-96
  265. stvx v26,r12,r0
  266. _savevr_27: addi r12,r0,-80
  267. stvx v27,r12,r0
  268. _savevr_28: addi r12,r0,-64
  269. stvx v28,r12,r0
  270. _savevr_29: addi r12,r0,-48
  271. stvx v29,r12,r0
  272. _savevr_30: addi r12,r0,-32
  273. stvx v30,r12,r0
  274. _savevr_31: addi r12,r0,-16
  275. stvx v31,r12,r0
  276. blr
  277. */
  278. /* The _restvr_M routines restore the vector registers from vM to v31. When the
  279. * routine is called, r0 must point to the word just beyound the end of the
  280. * vector register save area. On return the value of r0 is unchanged while r12
  281. * may be modified.
  282. */
  283. /* commented out for now, unused
  284. _restvr_20: addi r12,r0,-192
  285. lvx v20,r12,r0
  286. _restvr_21: addi r12,r0,-176
  287. lvx v21,r12,r0
  288. _restvr_22: addi r12,r0,-160
  289. lvx v22,r12,r0
  290. _restvr_23: addi r12,r0,-144
  291. lvx v23,r12,r0
  292. _restvr_24: addi r12,r0,-128
  293. lvx v24,r12,r0
  294. _restvr_25: addi r12,r0,-112
  295. lvx v25,r12,r0
  296. _restvr_26: addi r12,r0,-96
  297. lvx v26,r12,r0
  298. _restvr_27: addi r12,r0,-80
  299. lvx v27,r12,r0
  300. _restvr_28: addi r12,r0,-64
  301. lvx v28,r12,r0
  302. _restvr_29: addi r12,r0,-48
  303. lvx v29,r12,r0
  304. _restvr_30: addi r12,r0,-32
  305. lvx v30,r12,r0
  306. _restvr_31: addi r12,r0,-16
  307. lvx v31,r12,r0
  308. blr
  309. */
  310. /*
  311. * Main program entry point label (function), called by the loader
  312. */
  313. FUNCTION_PROLOG _start
  314. mr 26, 1 /* save stack pointer */
  315. /* Set up an initial stack frame, and clear the LR */
  316. clrrdi 1, 1, 5 /* align r1 */
  317. li 0, 0
  318. stdu 1,-128(1)
  319. mtlr 0
  320. std 0, 0(1) /* r1 = pointer to NULL value */
  321. /* store argument count (= 0(r1) )*/
  322. ld 3, 0(26)
  323. LOAD_64BIT_VAL 10, operatingsystem_parameter_argc
  324. stw 3, 0(10)
  325. /* calculate argument vector address and store (= 8(r1) + 8 ) */
  326. addi 4, 26, 8
  327. LOAD_64BIT_VAL 10, operatingsystem_parameter_argv
  328. std 4, 0(10)
  329. /* store environment pointer (= argv + (argc+1)* 8 ) */
  330. addi 5, 3, 1
  331. sldi 5, 5, 3
  332. add 5, 4, 5
  333. LOAD_64BIT_VAL 10, operatingsystem_parameter_envp
  334. std 5, 0(10)
  335. LOAD_64BIT_VAL 8, __stkptr
  336. std 1,0(8)
  337. bl .PASCALMAIN
  338. nop
  339. /* directly jump to exit procedure, not via the function pointer */
  340. b ._haltproc
  341. FUNCTION_PROLOG _haltproc
  342. /* exit call */
  343. li 0, 1
  344. sc
  345. b ._haltproc
  346. /* Define a symbol for the first piece of initialized data. */
  347. .section ".data"
  348. .globl __data_start
  349. __data_start:
  350. data_start:
  351. .text
  352. .comm __stkptr, 8
  353. .comm operatingsystem_parameter_argc, 4
  354. .comm operatingsystem_parameter_argv, 8
  355. .comm operatingsystem_parameter_envp, 8