sparc.inc 8.6 KB

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