sparc.inc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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:fpc_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.16 2004-11-21 19:11:33 peter
  301. * fix bootstrapping
  302. Revision 1.15 2004/11/21 15:35:23 peter
  303. * float routines all use internproc and compilerproc helpers
  304. Revision 1.14 2004/11/03 20:53:58 florian
  305. * get_frame fixed
  306. Revision 1.13 2004/10/14 19:45:39 florian
  307. + added and implemented functions for locked operations
  308. Revision 1.12 2004/10/03 12:41:30 florian
  309. * made sqrt, sqr and abs internal for the sparc
  310. Revision 1.11 2004/10/02 20:46:20 florian
  311. * made assembler implementation of move
  312. Revision 1.10 2004/09/23 11:30:41 florian
  313. * fixed indention
  314. Revision 1.9 2004/09/12 12:04:23 peter
  315. * restore traps when returning with longjmp
  316. Revision 1.8 2004/08/04 19:27:10 florian
  317. * fixed floating point and integer exception handling on sparc/linux
  318. Revision 1.7 2004/05/30 20:03:05 florian
  319. * ?
  320. Revision 1.6 2004/05/27 23:34:37 peter
  321. * backtrace support
  322. Revision 1.5 2004/01/02 17:22:14 jonas
  323. + fpc_cpuinit procedure to allow cpu/fpu initialisation before any unit
  324. initialises
  325. + fpu exceptions for invalid operations and division by zero enabled for
  326. ppc
  327. Revision 1.4 2003/12/04 21:42:07 peter
  328. * register calling updates
  329. Revision 1.3 2003/03/17 14:30:11 peter
  330. * changed address parameter/return values to pointer instead
  331. of longint
  332. Revision 1.2 2003/02/05 21:48:34 mazen
  333. * fixing run time errors related to unimplemented abstract methods in CG
  334. + giving empty emplementations for some RTL functions
  335. Revision 1.1 2002/11/16 20:10:31 florian
  336. + sparc specific rtl skeleton added
  337. }