gprt0.as 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * Startup code for programs linked with GNU libc, PowerPC64
  3. * version.
  4. *
  5. * Adapted from the glibc-sources (2.3.5) in the file
  6. *
  7. * sysdeps/powerpc/powerpc64/elf/start.S
  8. *
  9. * Original header follows.
  10. */
  11. /* Startup code for programs linked with GNU libc. PowerPC64 version.
  12. Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
  13. This file is part of the GNU C Library.
  14. The GNU C Library is free software; you can redistribute it and/or
  15. modify it under the terms of the GNU Lesser General Public
  16. License as published by the Free Software Foundation; either
  17. version 2.1 of the License, or (at your option) any later version.
  18. The GNU C Library is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. Lesser General Public License for more details.
  22. You should have received a copy of the GNU Lesser General Public
  23. License along with the GNU C Library; if not, write to the Free
  24. Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  25. 02110-1301 USA. */
  26. /* some macros which simplify the startup code */
  27. /* load the 64 bit value "value" into register ra */
  28. .macro LOAD_64BIT_VAL ra, value
  29. lis \ra,\value@highest
  30. ori \ra,\ra,\value@higher
  31. sldi \ra,\ra,32
  32. oris \ra,\ra,\value@h
  33. ori \ra,\ra,\value@l
  34. .endm
  35. /* create function prolog for symbol "fn" */
  36. .macro FUNCTION_PROLOG fn
  37. .section ".text"
  38. .align 2
  39. .globl \fn
  40. .section ".opd", "aw"
  41. .align 3
  42. \fn:
  43. .quad .\fn, .TOC.@tocbase, 0
  44. .previous
  45. .size \fn, 24
  46. .type \fn, @function
  47. .globl .\fn
  48. .\fn:
  49. .endm
  50. /*
  51. * "ptrgl" glue code for calls via pointer. This function
  52. * sequence loads the data from the function descriptor
  53. * referenced by R11 into the CTR register (function address),
  54. * R2 (GOT/TOC pointer), and R11 (the outer frame pointer).
  55. *
  56. * On entry, R11 must be set to point to the function descriptor.
  57. *
  58. * See also the 64-bit PowerPC ABI specification for more
  59. * information, chapter 3.5.11 (in v1.7).
  60. */
  61. .section ".text"
  62. .align 3
  63. .globl .ptrgl
  64. .ptrgl:
  65. ld 0, 0(11)
  66. std 2, 40(1)
  67. mtctr 0
  68. ld 2, 8(11)
  69. ld 11, 8(11)
  70. bctr
  71. .long 0
  72. .byte 0, 12, 128, 0, 0, 0, 0, 0
  73. .type .ptrgl, @function
  74. .size .ptrgl, . - .ptrgl
  75. /*
  76. * Function prolog/epilog helpers, which are part of the 64-bit
  77. * PowerPC ABI.
  78. *
  79. * See also the 64-bit PowerPC ABI specification for more
  80. * information, chapter 3.5.5, "Register saving and restoring
  81. * function" (in v1.7).
  82. */
  83. /* Each _savegpr0_N routine saves the general registers from rN to r31,
  84. * inclusive. When the routine is called, r1 must point to the start
  85. * of the general register save area. R0 must contain the old LR on
  86. * entry.
  87. */
  88. _savegpr0_14: std 14,-144(1)
  89. _savegpr0_15: std 15,-136(1)
  90. _savegpr0_16: std 16,-128(1)
  91. _savegpr0_17: std 17,-120(1)
  92. _savegpr0_18: std 18,-112(1)
  93. _savegpr0_19: std 19,-104(1)
  94. _savegpr0_20: std 20,-96(1)
  95. _savegpr0_21: std 21,-88(1)
  96. _savegpr0_22: std 22,-80(1)
  97. _savegpr0_23: std 23,-72(1)
  98. _savegpr0_24: std 24,-64(1)
  99. _savegpr0_25: std 25,-56(1)
  100. _savegpr0_26: std 26,-48(1)
  101. _savegpr0_27: std 27,-40(1)
  102. _savegpr0_28: std 28,-32(1)
  103. _savegpr0_29: std 29,-24(1)
  104. _savegpr0_30: std 30,-16(1)
  105. _savegpr0_31:
  106. std 31,-8(1)
  107. std 0, 16(1)
  108. blr
  109. .long 0
  110. .byte 0, 12, 64, 0, 0, 0, 0, 0
  111. /* Each _restgpr0_N routine restores the general registers from rN to r31,
  112. * inclusive. When the routine is called, r1 must point to the start
  113. * of the general register save area.
  114. */
  115. _restgpr0_14: ld 14,-144(1)
  116. _restgpr0_15: ld 15,-136(1)
  117. _restgpr0_16: ld 16,-128(1)
  118. _restgpr0_17: ld 17,-120(1)
  119. _restgpr0_18: ld 18,-112(1)
  120. _restgpr0_19: ld 19,-104(1)
  121. _restgpr0_20: ld 20,-96(1)
  122. _restgpr0_21: ld 21,-88(1)
  123. _restgpr0_22: ld 22,-80(1)
  124. _restgpr0_23: ld 23,-72(1)
  125. _restgpr0_24: ld 24,-64(1)
  126. _restgpr0_25: ld 25,-56(1)
  127. _restgpr0_26: ld 26,-48(1)
  128. _restgpr0_27: ld 27,-40(1)
  129. _restgpr0_28: ld 28,-32(1)
  130. _restgpr0_29:
  131. ld 0, 16(1)
  132. ld 29,-24(1)
  133. mtlr 0
  134. ld 30,-16(1)
  135. ld 31,-8(1)
  136. blr
  137. .long 0
  138. .byte 0, 12, 64, 0, 0, 0, 0, 0
  139. _restgpr0_30: ld 30,-16(1)
  140. _restgpr0_31: ld 0, 16(1)
  141. ld 31,-8(1)
  142. mtlr 0
  143. blr
  144. .long 0
  145. .byte 0, 12, 64, 0, 0, 0, 0, 0
  146. /* Each _savegpr1_N routine saves the general registers from rN to r31,
  147. * inclusive. When the routine is called, r12
  148. * must point to the start of the general register save area.
  149. */
  150. _savegpr1_14: std 14,-144(12)
  151. _savegpr1_15: std 15,-136(12)
  152. _savegpr1_16: std 16,-128(12)
  153. _savegpr1_17: std 17,-120(12)
  154. _savegpr1_18: std 18,-112(12)
  155. _savegpr1_19: std 19,-104(12)
  156. _savegpr1_20: std 20,-96(12)
  157. _savegpr1_21: std 21,-88(12)
  158. _savegpr1_22: std 22,-80(12)
  159. _savegpr1_23: std 23,-72(12)
  160. _savegpr1_24: std 24,-64(12)
  161. _savegpr1_25: std 25,-56(12)
  162. _savegpr1_26: std 26,-48(12)
  163. _savegpr1_27: std 27,-40(12)
  164. _savegpr1_28: std 28,-32(12)
  165. _savegpr1_29: std 29,-24(12)
  166. _savegpr1_30: std 30,-16(12)
  167. _savegpr1_31: std 31,-8(12)
  168. blr
  169. .long 0
  170. .byte 0, 12, 64, 0, 0, 0, 0, 0
  171. /* The _restgpr1_N routines restore the general registers from rN to r31.
  172. * When the routine is called, r12 must point to the start of the general
  173. * register save area.
  174. */
  175. _restgpr1_14: ld 14,-144(12)
  176. _restgpr1_15: ld 15,-136(12)
  177. _restgpr1_16: ld 16,-128(12)
  178. _restgpr1_17: ld 17,-120(12)
  179. _restgpr1_18: ld 18,-112(12)
  180. _restgpr1_19: ld 19,-104(12)
  181. _restgpr1_20: ld 20,-96(12)
  182. _restgpr1_21: ld 21,-88(12)
  183. _restgpr1_22: ld 22,-80(12)
  184. _restgpr1_23: ld 23,-72(12)
  185. _restgpr1_24: ld 24,-64(12)
  186. _restgpr1_25: ld 25,-56(12)
  187. _restgpr1_26: ld 26,-48(12)
  188. _restgpr1_27: ld 27,-40(12)
  189. _restgpr1_28: ld 28,-32(12)
  190. _restgpr1_29: ld 29,-24(12)
  191. _restgpr1_30: ld 30,-16(12)
  192. _restgpr1_31: ld 31,-8(12)
  193. blr
  194. .long 0
  195. .byte 0, 12, 64, 0, 0, 0, 0, 0
  196. /* Each _savefpr_M routine saves the floating point registers from fM to f31,
  197. * inclusive. When the routine is called, r1 must point to the start of the
  198. * floating point register save area, and r0 must contain the value of LR on
  199. * function entry.
  200. */
  201. _savefpr_14: stfd 14,-144(1)
  202. _savefpr_15: stfd 15,-136(1)
  203. _savefpr_16: stfd 16,-128(1)
  204. _savefpr_17: stfd 17,-120(1)
  205. _savefpr_18: stfd 18,-112(1)
  206. _savefpr_19: stfd 19,-104(1)
  207. _savefpr_20: stfd 20,-96(1)
  208. _savefpr_21: stfd 21,-88(1)
  209. _savefpr_22: stfd 22,-80(1)
  210. _savefpr_23: stfd 23,-72(1)
  211. _savefpr_24: stfd 24,-64(1)
  212. _savefpr_25: stfd 25,-56(1)
  213. _savefpr_26: stfd 26,-48(1)
  214. _savefpr_27: stfd 27,-40(1)
  215. _savefpr_28: stfd 28,-32(1)
  216. _savefpr_29: stfd 29,-24(1)
  217. _savefpr_30: stfd 30,-16(1)
  218. _savefpr_31: stfd 31,-8(1)
  219. std 0, 16(1)
  220. blr
  221. .long 0
  222. .byte 0, 12, 64, 0, 0, 0, 0, 0
  223. /* The _restfpr_M routines restore the floating point registers from fM to f31.
  224. * When the routine is called, r1 must point to the start of the floating point
  225. * register save area.
  226. */
  227. _restfpr_14: lfd 14,-144(1)
  228. _restfpr_15: lfd 15,-136(1)
  229. _restfpr_16: lfd 16,-128(1)
  230. _restfpr_17: lfd 17,-120(1)
  231. _restfpr_18: lfd 18,-112(1)
  232. _restfpr_19: lfd 19,-104(1)
  233. _restfpr_20: lfd 20,-96(1)
  234. _restfpr_21: lfd 21,-88(1)
  235. _restfpr_22: lfd 22,-80(1)
  236. _restfpr_23: lfd 23,-72(1)
  237. _restfpr_24: lfd 24,-64(1)
  238. _restfpr_25: lfd 25,-56(1)
  239. _restfpr_26: lfd 26,-48(1)
  240. _restfpr_27: lfd 27,-40(1)
  241. _restfpr_28: lfd 28,-32(1)
  242. _restfpr_29:
  243. ld 0, 16(1)
  244. lfd 29,-24(1)
  245. mtlr 0
  246. lfd 30,-16(1)
  247. lfd 31,-8(1)
  248. blr
  249. .long 0
  250. .byte 0, 12, 64, 0, 0, 0, 0, 0
  251. _restfpr_30: lfd 30,-16(1)
  252. _restfpr_31:
  253. ld 0, 16(1)
  254. lfd 31,-8(1)
  255. mtlr 0
  256. blr
  257. .long 0
  258. .byte 0, 12, 64, 0, 0, 0, 0, 0
  259. /* Each _savevr_M routine saves the vector registers from vM to v31, inclusive.
  260. * When the routine is called, r0 must point to the word just beyound the end
  261. * of the vector register save area. On return the value of r0 is unchanged
  262. * while r12 may be modified.
  263. */
  264. /* commented out for now, unused
  265. _savevr_20: addi r12,r0,-192
  266. stvx v20,r12,r0
  267. _savevr_21: addi r12,r0,-176
  268. stvx v21,r12,r0
  269. _savevr_22: addi r12,r0,-160
  270. stvx v22,r12,r0
  271. _savevr_23: addi r12,r0,-144
  272. stvx v23,r12,r0
  273. _savevr_24: addi r12,r0,-128
  274. stvx v24,r12,r0
  275. _savevr_25: addi r12,r0,-112
  276. stvx v25,r12,r0
  277. _savevr_26: addi r12,r0,-96
  278. stvx v26,r12,r0
  279. _savevr_27: addi r12,r0,-80
  280. stvx v27,r12,r0
  281. _savevr_28: addi r12,r0,-64
  282. stvx v28,r12,r0
  283. _savevr_29: addi r12,r0,-48
  284. stvx v29,r12,r0
  285. _savevr_30: addi r12,r0,-32
  286. stvx v30,r12,r0
  287. _savevr_31: addi r12,r0,-16
  288. stvx v31,r12,r0
  289. blr
  290. */
  291. /* The _restvr_M routines restore the vector registers from vM to v31. When the
  292. * routine is called, r0 must point to the word just beyound the end of the
  293. * vector register save area. On return the value of r0 is unchanged while r12
  294. * may be modified.
  295. */
  296. /* commented out for now, unused
  297. _restvr_20: addi r12,r0,-192
  298. lvx v20,r12,r0
  299. _restvr_21: addi r12,r0,-176
  300. lvx v21,r12,r0
  301. _restvr_22: addi r12,r0,-160
  302. lvx v22,r12,r0
  303. _restvr_23: addi r12,r0,-144
  304. lvx v23,r12,r0
  305. _restvr_24: addi r12,r0,-128
  306. lvx v24,r12,r0
  307. _restvr_25: addi r12,r0,-112
  308. lvx v25,r12,r0
  309. _restvr_26: addi r12,r0,-96
  310. lvx v26,r12,r0
  311. _restvr_27: addi r12,r0,-80
  312. lvx v27,r12,r0
  313. _restvr_28: addi r12,r0,-64
  314. lvx v28,r12,r0
  315. _restvr_29: addi r12,r0,-48
  316. lvx v29,r12,r0
  317. _restvr_30: addi r12,r0,-32
  318. lvx v30,r12,r0
  319. _restvr_31: addi r12,r0,-16
  320. lvx v31,r12,r0
  321. blr
  322. */
  323. /*
  324. * start_addresses is a structure containing the real
  325. * entry point (next to other things not interesting to
  326. * us here).
  327. *
  328. * All references in the struct are function descriptors
  329. *
  330. */
  331. .section ".rodata"
  332. .align 3
  333. start_addresses:
  334. .quad 0 /* was _SDA_BASE_ but not in 64-bit ABI*/
  335. .quad main_stub
  336. .quad __libc_csu_init
  337. .quad __libc_csu_fini
  338. .size start_adresses, .-start_addresses
  339. /*
  340. * the real entry point for the program
  341. */
  342. FUNCTION_PROLOG _start
  343. mr 9,1 /* save the stack pointer */
  344. /* Set up an initial stack frame, and clear the LR. */
  345. clrrdi 1,1,4
  346. li 0,0
  347. stdu 1,-128(1)
  348. mtlr 0
  349. std 0,0(1)
  350. /* put the address of start_addresses in r8... */
  351. /* PPC64 ABI uses R13 for thread local, so we leave it alone */
  352. LOAD_64BIT_VAL 8, start_addresses
  353. b __libc_start_main
  354. nop /* a NOP for the linker */
  355. /*
  356. * This is our FreePascal main procedure which is called by
  357. * libc after initializing.
  358. */
  359. FUNCTION_PROLOG main_stub
  360. mflr 0
  361. std 0,16(1)
  362. stdu 1,-128(1)
  363. LOAD_64BIT_VAL 8, operatingsystem_parameter_argc
  364. stw 3,0(8)
  365. LOAD_64BIT_VAL 8, operatingsystem_parameter_argv
  366. std 4,0(8)
  367. LOAD_64BIT_VAL 8, operatingsystem_parameter_envp
  368. std 5,0(8)
  369. LOAD_64BIT_VAL 8, __stkptr
  370. std 1,0(8)
  371. LOAD_64BIT_VAL 8, ___fpc_ret
  372. std 1,0(8)
  373. LOAD_64BIT_VAL 3, _start
  374. ld 3, 0(3)
  375. LOAD_64BIT_VAL 4, etext
  376. bl __monstartup
  377. nop
  378. LOAD_64BIT_VAL 3, _mcleanup
  379. bl atexit
  380. nop
  381. bl PASCALMAIN
  382. nop
  383. b ._haltproc
  384. FUNCTION_PROLOG _haltproc
  385. LOAD_64BIT_VAL 8, ___fpc_ret
  386. ld 1, 0(8)
  387. addi 1, 1, 128
  388. ld 0, 16(1)
  389. mtlr 0
  390. blr
  391. /* Define a symbol for the first piece of initialized data. */
  392. .section ".data"
  393. .globl __data_start
  394. __data_start:
  395. data_start:
  396. ___fpc_ret: /* return address to libc */
  397. .quad 0
  398. .section ".bss"
  399. .type __stkptr, @object
  400. .size __stkptr, 8
  401. .global __stkptr
  402. __stkptr:
  403. .skip 8
  404. .type operatingsystem_parameters, @object
  405. .size operatingsystem_parameters, 24
  406. operatingsystem_parameters:
  407. .skip 3 * 8
  408. .global operatingsystem_parameter_argc
  409. .global operatingsystem_parameter_argv
  410. .global operatingsystem_parameter_envp
  411. .set operatingsystem_parameter_argc, operatingsystem_parameters+0
  412. .set operatingsystem_parameter_argv, operatingsystem_parameters+8
  413. .set operatingsystem_parameter_envp, operatingsystem_parameters+16
  414. .section .note.GNU-stack,"",%progbits