sparc.inc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2002-2004 by the Free Pascal development team.
  5. Processor dependent implementation for the system unit for
  6. Sparc
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {****************************************************************************
  14. SPARC specific stuff
  15. ****************************************************************************}
  16. function get_fsr : dword;assembler;nostackframe;
  17. var
  18. fsr : dword;
  19. asm
  20. st %fsr,fsr
  21. ld fsr,%o0
  22. end;
  23. function get_got : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT'];
  24. asm
  25. retl
  26. add %o7,%l7,%l7
  27. end;
  28. procedure set_fsr(fsr : dword);assembler;
  29. var
  30. _fsr : dword;
  31. asm
  32. // force memory location
  33. st fsr,_fsr
  34. ld _fsr,%fsr
  35. end;
  36. procedure fpc_cpuinit;
  37. begin
  38. { enable div by 0 and invalid operation fpu exceptions }
  39. { round towards zero; ieee compliant arithmetics }
  40. set_fsr((get_fsr and $3fbfffff) or $09000000);
  41. end;
  42. {$define FPC_SYSTEM_HAS_GET_FRAME}
  43. function get_frame:pointer;assembler;nostackframe;
  44. asm
  45. mov %fp,%o0
  46. end;
  47. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  48. function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe;
  49. asm
  50. { framebp = %o0 }
  51. { flush register windows, so they are stored in the stack }
  52. ta 3
  53. ld [%o0+60],%o0
  54. { add 8 to skip jmpl and delay slot }
  55. add %o0,8,%o0
  56. end;
  57. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  58. function get_caller_frame(framebp:pointer):pointer;assembler;nostackframe;
  59. asm
  60. { flush register windows, so they are stored in the stack }
  61. ta 3
  62. { framebp = %o0 }
  63. ld [%o0+56],%o0
  64. end;
  65. {$define FPC_SYSTEM_HAS_SPTR}
  66. function Sptr:Pointer;assembler;nostackframe;
  67. asm
  68. mov %sp,%o0
  69. end;
  70. {$define FPC_SYSTEM_HAS_MOVE}
  71. procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;
  72. {
  73. Registers:
  74. %l0 temp. to do copying
  75. %l1 inc/decrement
  76. %l2/l3/l4/l5 qword move
  77. }
  78. asm
  79. // count < 0 ?
  80. cmp %g0,%i2
  81. bge .Lmoveexit
  82. nop
  83. // possible overlap?
  84. cmp %i0,%i1
  85. bcc .Lnopossibleoverlap
  86. nop
  87. // source < dest ....
  88. add %i0,%i2,%l0
  89. // overlap?
  90. cmp %l0,%i1
  91. // source+count < dest ?
  92. bcs .Lnopossibleoverlap
  93. nop
  94. .Lcopybackward:
  95. // check alignment of source and dest
  96. or %i0,%i1,%l0
  97. // move src and dest to the end of the blocks
  98. // assuming 16 byte block size
  99. sub %i2,1,%l1
  100. add %i0,%l1,%i0
  101. add %i1,%l1,%i1
  102. {
  103. // everything 16 byte aligned ?
  104. andcc %l0,15,%l0
  105. be .Lmovetwordwise
  106. // load direction in delay slot
  107. mov -16,%l1
  108. // adjust according to block size
  109. add %i0,8,%i0
  110. add %i1,8,%i1
  111. andcc %l0,7,%l0
  112. be .Lmoveqwordwise
  113. mov -8,%l1
  114. // adjust according to block size
  115. add %i0,4,%i0
  116. add %i1,4,%i1
  117. andcc %l0,3,%l0
  118. be .Lmovedwordwise
  119. mov -4,%l1
  120. // adjust according to block size
  121. add %i0,2,%i0
  122. add %i1,2,%i1
  123. andcc %l0,1,%l0
  124. be .Lmovewordwise
  125. mov -2,%l1
  126. // adjust according to block size
  127. add %i0,1,%i0
  128. add %i1,1,%i1
  129. }
  130. ba .Lmovebytewise
  131. mov -1,%l1
  132. .Lnopossibleoverlap:
  133. // check alignment of source and dest
  134. or %i0,%i1,%l0
  135. // everything 16 byte aligned ?
  136. andcc %l0,15,%l0
  137. be .Lmovetwordwise
  138. // load direction in delay slot
  139. mov 16,%l1
  140. andcc %l0,7,%l0
  141. be .Lmoveqwordwise
  142. mov 8,%l1
  143. andcc %l0,3,%l0
  144. be .Lmovedwordwise
  145. mov 4,%l1
  146. andcc %l0,1,%l0
  147. be .Lmovewordwise
  148. mov 2,%l1
  149. ba .Lmovebytewise
  150. mov 1,%l1
  151. .Lmovetwordwise:
  152. srl %i2,4,%l6
  153. cmp %g0,%l6
  154. sll %l6,4,%l7
  155. be .Lmoveqwordwise_shift
  156. nop
  157. .Lmovetwordwise_loop:
  158. ld [%i0],%l2
  159. ld [%i0+4],%l3
  160. subcc %l6,1,%l6
  161. ld [%i0+8],%l4
  162. ld [%i0+12],%l5
  163. add %i0,%l1,%i0
  164. st %l2,[%i1]
  165. st %l3,[%i1+4]
  166. st %l4,[%i1+8]
  167. st %l5,[%i1+12]
  168. add %i1,%l1,%i1
  169. bne .Lmovetwordwise_loop
  170. nop
  171. subcc %i2,%l7,%i2
  172. be .Lmoveexit
  173. nop
  174. .Lmoveqwordwise_shift:
  175. sra %l1,1,%l1
  176. .Lmoveqwordwise:
  177. srl %i2,3,%l6
  178. cmp %g0,%l6
  179. sll %l6,3,%l7
  180. be .Lmovedwordwise_shift
  181. nop
  182. .Lmoveqwordwise_loop:
  183. ld [%i0],%l2
  184. ld [%i0+4],%l3
  185. subcc %l6,1,%l6
  186. add %i0,%l1,%i0
  187. st %l2,[%i1]
  188. st %l3,[%i1+4]
  189. add %i1,%l1,%i1
  190. bne .Lmoveqwordwise_loop
  191. nop
  192. subcc %i2,%l7,%i2
  193. be .Lmoveexit
  194. nop
  195. .Lmovedwordwise_shift:
  196. sra %l1,1,%l1
  197. .Lmovedwordwise:
  198. srl %i2,2,%l6
  199. cmp %g0,%l6
  200. sll %l6,2,%l7
  201. be .Lmovewordwise_shift
  202. nop
  203. .Lmovedwordwise_loop:
  204. ld [%i0],%l0
  205. subcc %l6,1,%l6
  206. add %i0,%l1,%i0
  207. st %l0,[%i1]
  208. add %i1,%l1,%i1
  209. bne .Lmovedwordwise_loop
  210. nop
  211. subcc %i2,%l7,%i2
  212. be .Lmoveexit
  213. nop
  214. .Lmovewordwise_shift:
  215. sra %l1,1,%l1
  216. .Lmovewordwise:
  217. srl %i2,1,%l6
  218. cmp %g0,%l6
  219. sll %l6,1,%l7
  220. be .Lmovebytewise_shift
  221. nop
  222. .Lmovewordwise_loop:
  223. lduh [%i0],%l0
  224. subcc %l6,1,%l6
  225. add %i0,%l1,%i0
  226. sth %l0,[%i1]
  227. add %i1,%l1,%i1
  228. bne .Lmovewordwise_loop
  229. nop
  230. subcc %i2,%l7,%i2
  231. be .Lmoveexit
  232. nop
  233. .Lmovebytewise_shift:
  234. sra %l1,1,%l1
  235. .Lmovebytewise:
  236. cmp %g0,%i2
  237. be .Lmoveexit
  238. nop
  239. ldub [%i0],%l0
  240. subcc %i2,1,%i2
  241. add %i0,%l1,%i0
  242. stb %l0,[%i1]
  243. add %i1,%l1,%i1
  244. bne .Lmovebytewise
  245. nop
  246. .Lmoveexit:
  247. end;
  248. {****************************************************************************
  249. Integer math
  250. ****************************************************************************}
  251. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  252. function abs(l:longint):longint; assembler;{$ifdef SYSTEMINLINE}inline;{$endif}nostackframe;{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_abs];{$endif}
  253. asm
  254. sra %o0,31,%g1
  255. add %o0,%g1,%o0
  256. xor %o0,%g1,%o0
  257. end;
  258. var
  259. fpc_system_lock : byte;export name 'fpc_system_lock';
  260. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  261. function declocked(var l : longint) : boolean;assembler;nostackframe;
  262. asm
  263. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  264. worse the effort, especially while waiting :)
  265. }
  266. .Ldeclocked1:
  267. sethi %hi(fpc_system_lock), %g1
  268. or %g1,%lo(fpc_system_lock), %g1
  269. ldstub [%g1],%g1
  270. cmp %g1,0
  271. bne .Ldeclocked1
  272. nop
  273. ld [%o0],%g1
  274. sub %g1,1,%g1
  275. st %g1,[%o0]
  276. subcc %g1,1,%g0
  277. addx %g0,%g0,%o0
  278. { unlock }
  279. sethi %hi(fpc_system_lock), %g1
  280. or %g1,%lo(fpc_system_lock), %g1
  281. stb %g0,[%g1]
  282. end;
  283. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  284. procedure inclocked(var l : longint);assembler;nostackframe;
  285. asm
  286. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  287. worse the effort, especially while waiting :)
  288. }
  289. .Linclocked1:
  290. sethi %hi(fpc_system_lock), %g1
  291. or %g1,%lo(fpc_system_lock), %g1
  292. ldstub [%g1],%g1
  293. cmp %g1,0
  294. bne .Linclocked1
  295. nop
  296. ld [%o0],%g1
  297. add %g1,1,%g1
  298. st %g1,[%o0]
  299. { unlock }
  300. sethi %hi(fpc_system_lock), %g1
  301. or %g1,%lo(fpc_system_lock), %g1
  302. stb %g0,[%g1]
  303. end;
  304. {
  305. $Log$
  306. Revision 1.18 2005-01-27 21:26:39 florian
  307. + getgot function added
  308. Revision 1.17 2005/01/18 20:37:26 florian
  309. * set floating point precision and ieee compliance
  310. Revision 1.16 2004/11/21 19:11:33 peter
  311. * fix bootstrapping
  312. Revision 1.15 2004/11/21 15:35:23 peter
  313. * float routines all use internproc and compilerproc helpers
  314. Revision 1.14 2004/11/03 20:53:58 florian
  315. * get_frame fixed
  316. Revision 1.13 2004/10/14 19:45:39 florian
  317. + added and implemented functions for locked operations
  318. Revision 1.12 2004/10/03 12:41:30 florian
  319. * made sqrt, sqr and abs internal for the sparc
  320. Revision 1.11 2004/10/02 20:46:20 florian
  321. * made assembler implementation of move
  322. Revision 1.10 2004/09/23 11:30:41 florian
  323. * fixed indention
  324. Revision 1.9 2004/09/12 12:04:23 peter
  325. * restore traps when returning with longjmp
  326. Revision 1.8 2004/08/04 19:27:10 florian
  327. * fixed floating point and integer exception handling on sparc/linux
  328. Revision 1.7 2004/05/30 20:03:05 florian
  329. * ?
  330. Revision 1.6 2004/05/27 23:34:37 peter
  331. * backtrace support
  332. Revision 1.5 2004/01/02 17:22:14 jonas
  333. + fpc_cpuinit procedure to allow cpu/fpu initialisation before any unit
  334. initialises
  335. + fpu exceptions for invalid operations and division by zero enabled for
  336. ppc
  337. Revision 1.4 2003/12/04 21:42:07 peter
  338. * register calling updates
  339. Revision 1.3 2003/03/17 14:30:11 peter
  340. * changed address parameter/return values to pointer instead
  341. of longint
  342. Revision 1.2 2003/02/05 21:48:34 mazen
  343. * fixing run time errors related to unimplemented abstract methods in CG
  344. + giving empty emplementations for some RTL functions
  345. Revision 1.1 2002/11/16 20:10:31 florian
  346. + sparc specific rtl skeleton added
  347. }