sparc.inc 8.8 KB

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