si_g.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. {*
  2. * Startup code for programs linked with GNU libc, PowerPC64
  3. * version.
  4. *
  5. * Adapted from the glibc-sources (2.16) 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,2009
  13. Free Software Foundation, Inc.
  14. This file is part of the GNU C Library.
  15. The GNU C Library is free software; you can redistribute it and/or
  16. modify it under the terms of the GNU Lesser General Public
  17. License as published by the Free Software Foundation; either
  18. version 2.1 of the License, or (at your option) any later version.
  19. In addition to the permissions in the GNU Lesser General Public
  20. License, the Free Software Foundation gives you unlimited
  21. permission to link the compiled version of this file with other
  22. programs, and to distribute those programs without any restriction
  23. coming from the use of this file. (The GNU Lesser General Public
  24. License restrictions do apply in other respects; for example, they
  25. cover modification of the file, and distribution when not linked
  26. into another program.)
  27. Note that people who make modified versions of this file are not
  28. obligated to grant this special exception for their modified
  29. versions; it is their choice whether to do so. The GNU Lesser
  30. General Public License gives permission to release a modified
  31. version without this exception; this exception also makes it
  32. possible to release a modified version which carries forward this
  33. exception.
  34. The GNU C Library is distributed in the hope that it will be useful,
  35. but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  37. Lesser General Public License for more details.
  38. You should have received a copy of the GNU Lesser General Public
  39. License along with the GNU C Library; if not, see
  40. <http://www.gnu.org/licenses/>. *}
  41. {$goto on}
  42. {$ifndef _CALL_ELF or (_CALL_ELF = 1)}
  43. {*
  44. * "ptrgl" glue code for calls via pointer. This function
  45. * sequence loads the data from the function descriptor
  46. * referenced by R11 into the CTR register (function address),
  47. * R2 (GOT/TOC pointer), and R11 (the outer frame pointer).
  48. *
  49. * On entry, R11 must be set to point to the function descriptor.
  50. *
  51. * See also the 64-bit PowerPC ABI specification for more
  52. * information, chapter 3.5.11 (in v1.7).
  53. *}
  54. procedure ptrgl; cdecl; public; assembler; nostackframe;
  55. asm
  56. ld r0, 0(r11)
  57. std r2, 40(r1)
  58. mtctr r0
  59. ld r2, 8(r11)
  60. ld r11, 16(r11)
  61. bctr
  62. end;
  63. {$endif _CALL_ELF}
  64. {*
  65. * Function prolog/epilog helpers, which are part of the 64-bit
  66. * PowerPC ABI.
  67. *
  68. * See also the 64-bit PowerPC ABI specification for more
  69. * information, chapter 3.5.5, "Register saving and restoring
  70. * function" (in v1.7).
  71. *}
  72. {* Each _savegpr0_N routine saves the general registers from rN to r31,
  73. * inclusive. When the routine is called, r1 must point to the start
  74. * of the general register save area. R0 must contain the old LR on
  75. * entry.
  76. *}
  77. label
  78. _savegpr0_15,
  79. _savegpr0_16,
  80. _savegpr0_17,
  81. _savegpr0_18,
  82. _savegpr0_19,
  83. _savegpr0_20,
  84. _savegpr0_21,
  85. _savegpr0_22,
  86. _savegpr0_23,
  87. _savegpr0_24,
  88. _savegpr0_25,
  89. _savegpr0_26,
  90. _savegpr0_27,
  91. _savegpr0_28,
  92. _savegpr0_29,
  93. _savegpr0_30,
  94. _savegpr0_31;
  95. procedure _savegpr0_14; cdecl; public; assembler; nostackframe;
  96. asm
  97. .globl _savegpr0_15
  98. .globl _savegpr0_16
  99. .globl _savegpr0_17
  100. .globl _savegpr0_18
  101. .globl _savegpr0_19
  102. .globl _savegpr0_20
  103. .globl _savegpr0_21
  104. .globl _savegpr0_22
  105. .globl _savegpr0_23
  106. .globl _savegpr0_24
  107. .globl _savegpr0_25
  108. .globl _savegpr0_26
  109. .globl _savegpr0_27
  110. .globl _savegpr0_28
  111. .globl _savegpr0_29
  112. .globl _savegpr0_30
  113. .globl _savegpr0_31
  114. std r14,-144(r1)
  115. _savegpr0_15:
  116. std r15,-136(r1)
  117. _savegpr0_16:
  118. std r16,-128(r1)
  119. _savegpr0_17:
  120. std r17,-120(r1)
  121. _savegpr0_18:
  122. std r18,-112(r1)
  123. _savegpr0_19:
  124. std r19,-104(r1)
  125. _savegpr0_20:
  126. std r20,-96(r1)
  127. _savegpr0_21:
  128. std r21,-88(r1)
  129. _savegpr0_22:
  130. std r22,-80(r1)
  131. _savegpr0_23:
  132. std r23,-72(r1)
  133. _savegpr0_24:
  134. std r24,-64(r1)
  135. _savegpr0_25:
  136. std r25,-56(r1)
  137. _savegpr0_26:
  138. std r26,-48(r1)
  139. _savegpr0_27:
  140. std r27,-40(r1)
  141. _savegpr0_28:
  142. std r28,-32(r1)
  143. _savegpr0_29:
  144. std r29,-24(r1)
  145. _savegpr0_30:
  146. std r30,-16(r1)
  147. _savegpr0_31:
  148. std r31,-8(r1)
  149. std r0, 16(r1)
  150. blr
  151. end;
  152. label
  153. _restgpr0_15,
  154. _restgpr0_16,
  155. _restgpr0_17,
  156. _restgpr0_18,
  157. _restgpr0_19,
  158. _restgpr0_20,
  159. _restgpr0_21,
  160. _restgpr0_22,
  161. _restgpr0_23,
  162. _restgpr0_24,
  163. _restgpr0_25,
  164. _restgpr0_26,
  165. _restgpr0_27,
  166. _restgpr0_28,
  167. _restgpr0_29,
  168. _restgpr0_31;
  169. {* Each _restgpr0_N routine restores the general registers from rN to r31,
  170. * inclusive. When the routine is called, r1 must point to the start
  171. * of the general register save area.
  172. *}
  173. procedure _restgpr0_14; cdecl; public; assembler; nostackframe;
  174. asm
  175. .globl _restgpr0_15
  176. .globl _restgpr0_16
  177. .globl _restgpr0_17
  178. .globl _restgpr0_18
  179. .globl _restgpr0_19
  180. .globl _restgpr0_20
  181. .globl _restgpr0_21
  182. .globl _restgpr0_22
  183. .globl _restgpr0_23
  184. .globl _restgpr0_24
  185. .globl _restgpr0_25
  186. .globl _restgpr0_26
  187. .globl _restgpr0_27
  188. .globl _restgpr0_28
  189. .globl _restgpr0_29
  190. ld r14,-144(r1)
  191. _restgpr0_15:
  192. ld r15,-136(r1)
  193. _restgpr0_16:
  194. ld r16,-128(r1)
  195. _restgpr0_17:
  196. ld r17,-120(r1)
  197. _restgpr0_18:
  198. ld r18,-112(r1)
  199. _restgpr0_19:
  200. ld r19,-104(r1)
  201. _restgpr0_20:
  202. ld r20,-96(r1)
  203. _restgpr0_21:
  204. ld r21,-88(r1)
  205. _restgpr0_22:
  206. ld r22,-80(r1)
  207. _restgpr0_23:
  208. ld r23,-72(r1)
  209. _restgpr0_24:
  210. ld r24,-64(r1)
  211. _restgpr0_25:
  212. ld r25,-56(r1)
  213. _restgpr0_26:
  214. ld r26,-48(r1)
  215. _restgpr0_27:
  216. ld r27,-40(r1)
  217. _restgpr0_28:
  218. ld r28,-32(r1)
  219. _restgpr0_29:
  220. ld r0, 16(r1)
  221. ld r29,-24(r1)
  222. mtlr r0
  223. ld r30,-16(r1)
  224. ld r31,-8(r1)
  225. blr
  226. end;
  227. procedure _restgpr0_30; cdecl; public; assembler; nostackframe;
  228. asm
  229. ld r30,-16(r1)
  230. _restgpr0_31:
  231. ld r0, 16(r1)
  232. ld r31,-8(r1)
  233. mtlr 0
  234. blr
  235. end;
  236. {* Each _savegpr1_N routine saves the general registers from rN to r31,
  237. * inclusive. When the routine is called, r12
  238. * must point to the start of the general register save area.
  239. *}
  240. label
  241. _savegpr1_15,
  242. _savegpr1_16,
  243. _savegpr1_17,
  244. _savegpr1_18,
  245. _savegpr1_19,
  246. _savegpr1_20,
  247. _savegpr1_21,
  248. _savegpr1_22,
  249. _savegpr1_23,
  250. _savegpr1_24,
  251. _savegpr1_25,
  252. _savegpr1_26,
  253. _savegpr1_27,
  254. _savegpr1_28,
  255. _savegpr1_29,
  256. _savegpr1_30,
  257. _savegpr1_31;
  258. procedure _savegpr1_14; cdecl; public; assembler; nostackframe;
  259. asm
  260. .globl _savegpr1_15
  261. .globl _savegpr1_16
  262. .globl _savegpr1_17
  263. .globl _savegpr1_18
  264. .globl _savegpr1_19
  265. .globl _savegpr1_20
  266. .globl _savegpr1_21
  267. .globl _savegpr1_22
  268. .globl _savegpr1_23
  269. .globl _savegpr1_24
  270. .globl _savegpr1_25
  271. .globl _savegpr1_26
  272. .globl _savegpr1_27
  273. .globl _savegpr1_28
  274. .globl _savegpr1_29
  275. .globl _savegpr1_30
  276. .globl _savegpr1_31
  277. std r14,-144(r12)
  278. _savegpr1_15:
  279. std r15,-136(r12)
  280. _savegpr1_16:
  281. std r16,-128(r12)
  282. _savegpr1_17:
  283. std r17,-120(r12)
  284. _savegpr1_18:
  285. std r18,-112(r12)
  286. _savegpr1_19:
  287. std r19,-104(r12)
  288. _savegpr1_20:
  289. std r20,-96(r12)
  290. _savegpr1_21:
  291. std r21,-88(r12)
  292. _savegpr1_22:
  293. std r22,-80(r12)
  294. _savegpr1_23:
  295. std r23,-72(r12)
  296. _savegpr1_24:
  297. std r24,-64(r12)
  298. _savegpr1_25:
  299. std r25,-56(r12)
  300. _savegpr1_26:
  301. std r26,-48(r12)
  302. _savegpr1_27:
  303. std r27,-40(r12)
  304. _savegpr1_28:
  305. std r28,-32(r12)
  306. _savegpr1_29:
  307. std r29,-24(r12)
  308. _savegpr1_30:
  309. std r30,-16(r12)
  310. _savegpr1_31:
  311. std r31,-8(r12)
  312. blr
  313. end;
  314. {* The _restgpr1_N routines restore the general registers from rN to r31.
  315. * When the routine is called, r12 must point to the start of the general
  316. * register save area.
  317. *}
  318. label
  319. _restgpr1_15,
  320. _restgpr1_16,
  321. _restgpr1_17,
  322. _restgpr1_18,
  323. _restgpr1_19,
  324. _restgpr1_20,
  325. _restgpr1_21,
  326. _restgpr1_22,
  327. _restgpr1_23,
  328. _restgpr1_24,
  329. _restgpr1_25,
  330. _restgpr1_26,
  331. _restgpr1_27,
  332. _restgpr1_28,
  333. _restgpr1_29,
  334. _restgpr1_30,
  335. _restgpr1_31;
  336. procedure _restgpr1_14; cdecl; public; assembler; nostackframe;
  337. asm
  338. .globl _restgpr1_15
  339. .globl _restgpr1_16
  340. .globl _restgpr1_17
  341. .globl _restgpr1_18
  342. .globl _restgpr1_19
  343. .globl _restgpr1_20
  344. .globl _restgpr1_21
  345. .globl _restgpr1_22
  346. .globl _restgpr1_23
  347. .globl _restgpr1_24
  348. .globl _restgpr1_25
  349. .globl _restgpr1_26
  350. .globl _restgpr1_27
  351. .globl _restgpr1_28
  352. .globl _restgpr1_29
  353. .globl _restgpr1_30
  354. .globl _restgpr1_31
  355. ld r14,-144(r12)
  356. _restgpr1_15:
  357. ld r15,-136(r12)
  358. _restgpr1_16:
  359. ld r16,-128(r12)
  360. _restgpr1_17:
  361. ld r17,-120(r12)
  362. _restgpr1_18:
  363. ld r18,-112(r12)
  364. _restgpr1_19:
  365. ld r19,-104(r12)
  366. _restgpr1_20:
  367. ld r20,-96(r12)
  368. _restgpr1_21:
  369. ld r21,-88(r12)
  370. _restgpr1_22:
  371. ld r22,-80(r12)
  372. _restgpr1_23:
  373. ld r23,-72(r12)
  374. _restgpr1_24:
  375. ld r24,-64(r12)
  376. _restgpr1_25:
  377. ld r25,-56(r12)
  378. _restgpr1_26:
  379. ld r26,-48(r12)
  380. _restgpr1_27:
  381. ld r27,-40(r12)
  382. _restgpr1_28:
  383. ld r28,-32(r12)
  384. _restgpr1_29:
  385. ld r29,-24(r12)
  386. _restgpr1_30:
  387. ld r30,-16(r12)
  388. _restgpr1_31:
  389. ld r31,-8(r12)
  390. blr
  391. end;
  392. {* Each _savefpr_M routine saves the floating point registers from fM to f31,
  393. * inclusive. When the routine is called, r1 must point to the start of the
  394. * floating point register save area, and r0 must contain the value of LR on
  395. * function entry.
  396. *}
  397. label
  398. _savefpr_15,
  399. _savefpr_16,
  400. _savefpr_17,
  401. _savefpr_18,
  402. _savefpr_19,
  403. _savefpr_20,
  404. _savefpr_21,
  405. _savefpr_22,
  406. _savefpr_23,
  407. _savefpr_24,
  408. _savefpr_25,
  409. _savefpr_26,
  410. _savefpr_27,
  411. _savefpr_28,
  412. _savefpr_29,
  413. _savefpr_30,
  414. _savefpr_31;
  415. procedure _savefpr_14; cdecl; public; assembler; nostackframe;
  416. asm
  417. .globl _savefpr_15
  418. .globl _savefpr_16
  419. .globl _savefpr_17
  420. .globl _savefpr_18
  421. .globl _savefpr_19
  422. .globl _savefpr_20
  423. .globl _savefpr_21
  424. .globl _savefpr_22
  425. .globl _savefpr_23
  426. .globl _savefpr_24
  427. .globl _savefpr_25
  428. .globl _savefpr_26
  429. .globl _savefpr_27
  430. .globl _savefpr_28
  431. .globl _savefpr_29
  432. .globl _savefpr_30
  433. .globl _savefpr_31
  434. stfd r14,-144(r1)
  435. _savefpr_15:
  436. stfd r15,-136(r1)
  437. _savefpr_16:
  438. stfd r16,-128(r1)
  439. _savefpr_17:
  440. stfd r17,-120(r1)
  441. _savefpr_18:
  442. stfd r18,-112(r1)
  443. _savefpr_19:
  444. stfd r19,-104(r1)
  445. _savefpr_20:
  446. stfd r20,-96(r1)
  447. _savefpr_21:
  448. stfd r21,-88(r1)
  449. _savefpr_22:
  450. stfd r22,-80(r1)
  451. _savefpr_23:
  452. stfd r23,-72(r1)
  453. _savefpr_24:
  454. stfd r24,-64(r1)
  455. _savefpr_25:
  456. stfd r25,-56(r1)
  457. _savefpr_26:
  458. stfd r26,-48(r1)
  459. _savefpr_27:
  460. stfd r27,-40(r1)
  461. _savefpr_28:
  462. stfd r28,-32(r1)
  463. _savefpr_29:
  464. stfd r29,-24(r1)
  465. _savefpr_30:
  466. stfd r30,-16(r1)
  467. _savefpr_31:
  468. stfd r31,-8(r1)
  469. std r0, 16(r1)
  470. blr
  471. end;
  472. {* The _restfpr_M routines restore the floating point registers from fM to f31.
  473. * When the routine is called, r1 must point to the start of the floating point
  474. * register save area.
  475. *}
  476. label
  477. _restfpr_15,
  478. _restfpr_16,
  479. _restfpr_17,
  480. _restfpr_18,
  481. _restfpr_19,
  482. _restfpr_20,
  483. _restfpr_21,
  484. _restfpr_22,
  485. _restfpr_23,
  486. _restfpr_24,
  487. _restfpr_25,
  488. _restfpr_26,
  489. _restfpr_27,
  490. _restfpr_28,
  491. _restfpr_29,
  492. _restfpr_31;
  493. procedure _restfpr_14; cdecl; public; assembler; nostackframe;
  494. asm
  495. .globl _restfpr_15
  496. .globl _restfpr_16
  497. .globl _restfpr_17
  498. .globl _restfpr_18
  499. .globl _restfpr_19
  500. .globl _restfpr_20
  501. .globl _restfpr_21
  502. .globl _restfpr_22
  503. .globl _restfpr_23
  504. .globl _restfpr_24
  505. .globl _restfpr_25
  506. .globl _restfpr_26
  507. .globl _restfpr_27
  508. .globl _restfpr_28
  509. .globl _restfpr_29
  510. lfd r14,-144(r1)
  511. _restfpr_15:
  512. lfd r15,-136(r1)
  513. _restfpr_16:
  514. lfd r16,-128(r1)
  515. _restfpr_17:
  516. lfd r17,-120(r1)
  517. _restfpr_18:
  518. lfd r18,-112(r1)
  519. _restfpr_19:
  520. lfd r19,-104(r1)
  521. _restfpr_20:
  522. lfd r20,-96(r1)
  523. _restfpr_21:
  524. lfd r21,-88(r1)
  525. _restfpr_22:
  526. lfd r22,-80(r1)
  527. _restfpr_23:
  528. lfd r23,-72(r1)
  529. _restfpr_24:
  530. lfd r24,-64(r1)
  531. _restfpr_25:
  532. lfd r25,-56(r1)
  533. _restfpr_26:
  534. lfd r26,-48(r1)
  535. _restfpr_27:
  536. lfd r27,-40(r1)
  537. _restfpr_28:
  538. lfd r28,-32(r1)
  539. _restfpr_29:
  540. ld r0, 16(r1)
  541. lfd r29,-24(r1)
  542. mtlr r0
  543. lfd r30,-16(r1)
  544. lfd r31,-8(r1)
  545. blr
  546. end;
  547. procedure _restfpr_30; cdecl; public; assembler; nostackframe;
  548. asm
  549. .globl _restfpr_31
  550. lfd r30,-16(r1)
  551. _restfpr_31:
  552. ld r0, 16(r1)
  553. lfd r31,-8(r1)
  554. mtlr r0
  555. blr
  556. end;
  557. {* Each _savevr_M routine saves the vector registers from vM to v31, inclusive.
  558. * When the routine is called, r0 must point to the word just beyound the end
  559. * of the vector register save area. On return the value of r0 is unchanged
  560. * while r12 may be modified.
  561. *}
  562. {* commented out for now, unused
  563. _savevr_20: addi r12,r0,-192
  564. stvx v20,r12,r0
  565. _savevr_21: addi r12,r0,-176
  566. stvx v21,r12,r0
  567. _savevr_22: addi r12,r0,-160
  568. stvx v22,r12,r0
  569. _savevr_23: addi r12,r0,-144
  570. stvx v23,r12,r0
  571. _savevr_24: addi r12,r0,-128
  572. stvx v24,r12,r0
  573. _savevr_25: addi r12,r0,-112
  574. stvx v25,r12,r0
  575. _savevr_26: addi r12,r0,-96
  576. stvx v26,r12,r0
  577. _savevr_27: addi r12,r0,-80
  578. stvx v27,r12,r0
  579. _savevr_28: addi r12,r0,-64
  580. stvx v28,r12,r0
  581. _savevr_29: addi r12,r0,-48
  582. stvx v29,r12,r0
  583. _savevr_30: addi r12,r0,-32
  584. stvx v30,r12,r0
  585. _savevr_31: addi r12,r0,-16
  586. stvx v31,r12,r0
  587. blr
  588. *}
  589. {* The _restvr_M routines restore the vector registers from vM to v31. When the
  590. * routine is called, r0 must point to the word just beyound the end of the
  591. * vector register save area. On return the value of r0 is unchanged while r12
  592. * may be modified.
  593. *}
  594. {* commented out for now, unused
  595. _restvr_20: addi r12,r0,-192
  596. lvx v20,r12,r0
  597. _restvr_21: addi r12,r0,-176
  598. lvx v21,r12,r0
  599. _restvr_22: addi r12,r0,-160
  600. lvx v22,r12,r0
  601. _restvr_23: addi r12,r0,-144
  602. lvx v23,r12,r0
  603. _restvr_24: addi r12,r0,-128
  604. lvx v24,r12,r0
  605. _restvr_25: addi r12,r0,-112
  606. lvx v25,r12,r0
  607. _restvr_26: addi r12,r0,-96
  608. lvx v26,r12,r0
  609. _restvr_27: addi r12,r0,-80
  610. lvx v27,r12,r0
  611. _restvr_28: addi r12,r0,-64
  612. lvx v28,r12,r0
  613. _restvr_29: addi r12,r0,-48
  614. lvx v29,r12,r0
  615. _restvr_30: addi r12,r0,-32
  616. lvx v30,r12,r0
  617. _restvr_31: addi r12,r0,-16
  618. lvx v31,r12,r0
  619. blr
  620. *}
  621. {******************************************************************************
  622. Process start/halt
  623. ******************************************************************************}
  624. procedure __libc_csu_init; cdecl; external;
  625. procedure __libc_csu_fini; cdecl; external;
  626. procedure __libc_start_main(r3,r4,r5,r6,r7,r8,r9: pointer); cdecl; external;
  627. type
  628. tatexit_cb = procedure; cdecl;
  629. procedure atexit(cb: tatexit_cb); cdecl; external;
  630. procedure gmon_monstartup(text_start, text_stop: pointer); cdecl; external name '__monstartup';
  631. procedure gmon_mcleanup; cdecl; external name '_mcleanup';
  632. var etext: pointer; cvar; external;
  633. var
  634. __fpc_ret: pointer;
  635. procedure firstproc;
  636. begin
  637. end;
  638. procedure save_argc_argv_envp_stkptr_fpcret_call_monstartup(argc: longint; argv, envp: ppchar; stkptr: pointer);
  639. var
  640. start: pointer;
  641. begin
  642. operatingsystem_parameter_argc:=argc;
  643. operatingsystem_parameter_argv:=argv;
  644. operatingsystem_parameter_envp:=envp;
  645. initialstkptr:=stkptr;
  646. __fpc_ret:=stkptr;
  647. start:=@firstproc;
  648. {$ifndef _CALL_ELF or (_CALL_ELF = 1)}
  649. { load code address from function descriptor }
  650. start:=ppointer(start)^;
  651. {$endif}
  652. gmon_monstartup(start,@etext);
  653. atexit(@gmon_mcleanup);
  654. end;
  655. procedure _haltproc(exitcode: longint); cdecl; forward;
  656. var
  657. TOCSTART: pointer; external name '.TOC.';
  658. label
  659. __data_start,
  660. data_start;
  661. {*
  662. * This is our FreePascal main procedure which is called by
  663. * libc after initializing.
  664. *}
  665. procedure main_stub(argc: longint; argv, envp: ppchar); cdecl; assembler; nostackframe;
  666. asm
  667. {$if defined(_CALL_ELF) and (_CALL_ELF = 2)}
  668. .L1:
  669. addis r2,r12,(TOCSTART-.L1)@ha
  670. addi r2,r2,(TOCSTART-.L1)@l
  671. .localentry main_stub, . - main_stub
  672. {$endif}
  673. mflr r0
  674. std r0,16(r1)
  675. stdu r1,-128(r1)
  676. mr r6, r1
  677. bl save_argc_argv_envp_stkptr_fpcret_call_monstartup
  678. bl PASCALMAIN
  679. nop
  680. b _haltproc
  681. .section ".data"
  682. .globl __data_start
  683. __data_start:
  684. data_start:
  685. .text
  686. end;
  687. const
  688. start_addresses: record
  689. sda_base: pointer;
  690. main: pointer;
  691. libc_csu_init: pointer;
  692. libc_csu_fini: pointer;
  693. end
  694. = (sda_base: nil; {* was _SDA_BASE_ but not in 64-bit ABI }
  695. main: @main_stub;
  696. libc_csu_init: @__libc_csu_init;
  697. libc_csu_fini: @__libc_csu_fini
  698. );
  699. procedure call_libc_start_main(r3,r4,r5,r6,r7,r8,r9: pointer); cdecl;
  700. begin
  701. __libc_start_main(r3,r4,r5,r6,r7,@start_addresses,r9);
  702. asm
  703. { not reached }
  704. { trap }
  705. .long 0xffe00008
  706. end;
  707. end;
  708. {*
  709. * the real entry point for the program
  710. *}
  711. procedure _start; cdecl; public; assembler; nostackframe;
  712. asm
  713. {$if defined(_CALL_ELF) and (_CALL_ELF = 2)}
  714. .L1:
  715. addis r2,r12,(TOCSTART-.L1)@ha
  716. addi r2,r2,(TOCSTART-.L1)@l
  717. .localentry _start, . - _start
  718. {$endif}
  719. mr r9,r1 { save the stack pointer }
  720. { Set up an initial stack frame, and clear the LR. }
  721. rldicr r1,r1,0,59
  722. li r0,0
  723. stdu r1,-128(r1)
  724. mtlr r0
  725. std r0,0(r1)
  726. bl call_libc_start_main
  727. nop
  728. end;
  729. procedure _haltproc(exitcode: longint); cdecl; public;
  730. var
  731. localret: pointer;
  732. begin
  733. localret:=__fpc_ret;
  734. { return via initial stack }
  735. asm
  736. lwa r3, exitcode
  737. ld r1, localret
  738. addi r1, r1, 128
  739. ld r0, 16(r1)
  740. mtlr r0
  741. blr
  742. end;
  743. end;