sparc.inc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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;[public, alias: 'FPC_GETFSR'];
  17. var
  18. fsr : dword;
  19. asm
  20. st %fsr,fsr
  21. ld fsr,%o0
  22. end;
  23. procedure set_fsr(fsr : dword);assembler;[public, alias: 'FPC_SETFSR'];
  24. var
  25. _fsr : dword;
  26. asm
  27. // force memory location
  28. st fsr,_fsr
  29. ld _fsr,%fsr
  30. end;
  31. function get_got : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT'];
  32. asm
  33. retl
  34. add %o7,%l7,%l7
  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. {$ifndef FPC_SYSTEM_HAS_MOVE}
  71. {$define FPC_SYSTEM_HAS_MOVE}
  72. procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;
  73. {
  74. Registers:
  75. %l0 temp. to do copying
  76. %l1 inc/decrement
  77. %l2/l3/l4/l5 qword move
  78. }
  79. asm
  80. // count < 0 ?
  81. cmp %g0,%i2
  82. bge .Lmoveexit
  83. nop
  84. // possible overlap?
  85. cmp %i0,%i1
  86. bcc .Lnopossibleoverlap
  87. nop
  88. // source < dest ....
  89. add %i0,%i2,%l0
  90. // overlap?
  91. cmp %l0,%i1
  92. // source+count < dest ?
  93. bcs .Lnopossibleoverlap
  94. nop
  95. .Lcopybackward:
  96. // check alignment of source and dest
  97. or %i0,%i1,%l0
  98. // move src and dest to the end of the blocks
  99. // assuming 16 byte block size
  100. sub %i2,1,%l1
  101. add %i0,%l1,%i0
  102. add %i1,%l1,%i1
  103. {
  104. // everything 16 byte aligned ?
  105. andcc %l0,15,%l0
  106. be .Lmovetwordwise
  107. // load direction in delay slot
  108. mov -16,%l1
  109. // adjust according to block size
  110. add %i0,8,%i0
  111. add %i1,8,%i1
  112. andcc %l0,7,%l0
  113. be .Lmoveqwordwise
  114. mov -8,%l1
  115. // adjust according to block size
  116. add %i0,4,%i0
  117. add %i1,4,%i1
  118. andcc %l0,3,%l0
  119. be .Lmovedwordwise
  120. mov -4,%l1
  121. // adjust according to block size
  122. add %i0,2,%i0
  123. add %i1,2,%i1
  124. andcc %l0,1,%l0
  125. be .Lmovewordwise
  126. mov -2,%l1
  127. // adjust according to block size
  128. add %i0,1,%i0
  129. add %i1,1,%i1
  130. }
  131. ba .Lmovebytewise
  132. mov -1,%l1
  133. .Lnopossibleoverlap:
  134. // check alignment of source and dest
  135. or %i0,%i1,%l0
  136. // everything 16 byte aligned ?
  137. andcc %l0,15,%l0
  138. be .Lmovetwordwise
  139. // load direction in delay slot
  140. mov 16,%l1
  141. andcc %l0,7,%l0
  142. be .Lmoveqwordwise
  143. mov 8,%l1
  144. andcc %l0,3,%l0
  145. be .Lmovedwordwise
  146. mov 4,%l1
  147. andcc %l0,1,%l0
  148. be .Lmovewordwise
  149. mov 2,%l1
  150. ba .Lmovebytewise
  151. mov 1,%l1
  152. .Lmovetwordwise:
  153. srl %i2,4,%l6
  154. cmp %g0,%l6
  155. sll %l6,4,%l7
  156. be .Lmoveqwordwise_shift
  157. nop
  158. .Lmovetwordwise_loop:
  159. ld [%i0],%l2
  160. ld [%i0+4],%l3
  161. subcc %l6,1,%l6
  162. ld [%i0+8],%l4
  163. ld [%i0+12],%l5
  164. add %i0,%l1,%i0
  165. st %l2,[%i1]
  166. st %l3,[%i1+4]
  167. st %l4,[%i1+8]
  168. st %l5,[%i1+12]
  169. add %i1,%l1,%i1
  170. bne .Lmovetwordwise_loop
  171. nop
  172. subcc %i2,%l7,%i2
  173. be .Lmoveexit
  174. nop
  175. .Lmoveqwordwise_shift:
  176. sra %l1,1,%l1
  177. .Lmoveqwordwise:
  178. srl %i2,3,%l6
  179. cmp %g0,%l6
  180. sll %l6,3,%l7
  181. be .Lmovedwordwise_shift
  182. nop
  183. .Lmoveqwordwise_loop:
  184. ld [%i0],%l2
  185. ld [%i0+4],%l3
  186. subcc %l6,1,%l6
  187. add %i0,%l1,%i0
  188. st %l2,[%i1]
  189. st %l3,[%i1+4]
  190. add %i1,%l1,%i1
  191. bne .Lmoveqwordwise_loop
  192. nop
  193. subcc %i2,%l7,%i2
  194. be .Lmoveexit
  195. nop
  196. .Lmovedwordwise_shift:
  197. sra %l1,1,%l1
  198. .Lmovedwordwise:
  199. srl %i2,2,%l6
  200. cmp %g0,%l6
  201. sll %l6,2,%l7
  202. be .Lmovewordwise_shift
  203. nop
  204. .Lmovedwordwise_loop:
  205. ld [%i0],%l0
  206. subcc %l6,1,%l6
  207. add %i0,%l1,%i0
  208. st %l0,[%i1]
  209. add %i1,%l1,%i1
  210. bne .Lmovedwordwise_loop
  211. nop
  212. subcc %i2,%l7,%i2
  213. be .Lmoveexit
  214. nop
  215. .Lmovewordwise_shift:
  216. sra %l1,1,%l1
  217. .Lmovewordwise:
  218. srl %i2,1,%l6
  219. cmp %g0,%l6
  220. sll %l6,1,%l7
  221. be .Lmovebytewise_shift
  222. nop
  223. .Lmovewordwise_loop:
  224. lduh [%i0],%l0
  225. subcc %l6,1,%l6
  226. add %i0,%l1,%i0
  227. sth %l0,[%i1]
  228. add %i1,%l1,%i1
  229. bne .Lmovewordwise_loop
  230. nop
  231. subcc %i2,%l7,%i2
  232. be .Lmoveexit
  233. nop
  234. .Lmovebytewise_shift:
  235. sra %l1,1,%l1
  236. .Lmovebytewise:
  237. cmp %g0,%i2
  238. be .Lmoveexit
  239. nop
  240. ldub [%i0],%l0
  241. subcc %i2,1,%i2
  242. add %i0,%l1,%i0
  243. stb %l0,[%i1]
  244. add %i1,%l1,%i1
  245. bne .Lmovebytewise
  246. nop
  247. .Lmoveexit:
  248. end;
  249. {$endif FPC_SYSTEM_HAS_MOVE}
  250. {****************************************************************************
  251. Integer math
  252. ****************************************************************************}
  253. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  254. function abs(l:longint):longint; assembler;{$ifdef SYSTEMINLINE}inline;{$endif}nostackframe;{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_abs];{$endif}
  255. asm
  256. sra %o0,31,%g1
  257. add %o0,%g1,%o0
  258. xor %o0,%g1,%o0
  259. end;
  260. var
  261. fpc_system_lock : byte;export name 'fpc_system_lock';
  262. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  263. function declocked(var l : longint) : boolean;assembler;nostackframe;
  264. asm
  265. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  266. worse the effort, especially while waiting :)
  267. }
  268. .Ldeclocked1:
  269. sethi %hi(fpc_system_lock), %g1
  270. or %g1,%lo(fpc_system_lock), %g1
  271. ldstub [%g1],%g1
  272. cmp %g1,0
  273. bne .Ldeclocked1
  274. nop
  275. ld [%o0],%g1
  276. sub %g1,1,%g1
  277. st %g1,[%o0]
  278. subcc %g1,1,%g0
  279. addx %g0,%g0,%o0
  280. { unlock }
  281. sethi %hi(fpc_system_lock), %g1
  282. or %g1,%lo(fpc_system_lock), %g1
  283. stb %g0,[%g1]
  284. end;
  285. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  286. procedure inclocked(var l : longint);assembler;nostackframe;
  287. asm
  288. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  289. worse the effort, especially while waiting :)
  290. }
  291. .Linclocked1:
  292. sethi %hi(fpc_system_lock), %g1
  293. or %g1,%lo(fpc_system_lock), %g1
  294. ldstub [%g1],%g1
  295. cmp %g1,0
  296. bne .Linclocked1
  297. nop
  298. ld [%o0],%g1
  299. add %g1,1,%g1
  300. st %g1,[%o0]
  301. { unlock }
  302. sethi %hi(fpc_system_lock), %g1
  303. or %g1,%lo(fpc_system_lock), %g1
  304. stb %g0,[%g1]
  305. end;
  306. {
  307. $Log$
  308. Revision 1.21 2005-02-14 17:13:31 peter
  309. * truncate log
  310. Revision 1.20 2005/02/13 18:58:27 florian
  311. + FPU controll routines in math unit
  312. Revision 1.19 2005/02/07 22:17:48 peter
  313. * add $ifdef for move
  314. Revision 1.18 2005/01/27 21:26:39 florian
  315. + getgot function added
  316. Revision 1.17 2005/01/18 20:37:26 florian
  317. * set floating point precision and ieee compliance
  318. }