sparc64.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2002-2004 by the Free Pascal development team.
  4. Processor dependent implementation for the system unit for
  5. Sparc
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. SPARC specific stuff
  14. ****************************************************************************}
  15. function get_fsr : dword;assembler;[public, alias: 'FPC_GETFSR'];
  16. var
  17. fsr : dword;
  18. asm
  19. st %fsr,fsr
  20. ld fsr,%l0
  21. st %l0,__result
  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. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  37. Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
  38. begin
  39. { enable div by 0 and invalid operation fpu exceptions
  40. round towards zero; ieee compliant arithmetics }
  41. set_fsr((get_fsr and $3fbfffff) or $09000000);
  42. end;
  43. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  44. Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
  45. begin
  46. end;
  47. procedure fpc_cpuinit;
  48. begin
  49. SysResetFPU;
  50. if not(IsLibrary) then
  51. SysInitFPU;
  52. end;
  53. {$define FPC_SYSTEM_HAS_GET_FRAME}
  54. function get_frame:pointer;assembler;nostackframe;
  55. asm
  56. mov %fp,%o0
  57. end;
  58. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  59. function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
  60. asm
  61. { framebp = %o0 }
  62. subcc %o0,0,%o0
  63. be .Lframezero
  64. nop
  65. { flush register windows, so they are stored in the stack }
  66. flushw
  67. ldx [%o0+STACK_BIAS+120],%o0
  68. { check if new %o0 register is zero }
  69. subcc %o0,0,%o0
  70. be .Lframezero
  71. nop
  72. { if not zero, add 8 to skip jmpl and delay slot }
  73. add %o0,8,%o0
  74. .Lframezero:
  75. end;
  76. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  77. function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
  78. asm
  79. { framebp = %o0 }
  80. subcc %o0,0,%o0
  81. be .Lframezero
  82. nop
  83. { flush register windows, so they are stored in the stack }
  84. flushw
  85. ldx [%o0+STACK_BIAS+112],%o0
  86. .Lframezero:
  87. end;
  88. {$define FPC_SYSTEM_HAS_SPTR}
  89. function Sptr:Pointer;assembler;nostackframe;
  90. asm
  91. mov %sp,%o0
  92. end;
  93. {$ifndef FPC_SYSTEM_HAS_MOVE}
  94. {$define FPC_SYSTEM_HAS_MOVE}
  95. procedure Move(const source;var dest;count:{$ifdef MOVE_HAS_SIZEUINT_COUNT}SizeUInt{$else}SizeInt{$endif});[public, alias: 'FPC_MOVE'];assembler;
  96. {
  97. Registers:
  98. %l0 temp. to do copying
  99. %l1 inc/decrement
  100. %l2/l3/l4/l5 qword move
  101. }
  102. asm
  103. // count < 0 ?
  104. cmp %g0,%i2
  105. bge .Lmoveexit
  106. nop
  107. // possible overlap?
  108. cmp %i0,%i1
  109. bcc .Lnopossibleoverlap
  110. nop
  111. // source < dest ....
  112. add %i0,%i2,%l0
  113. // overlap?
  114. cmp %l0,%i1
  115. // source+count < dest ?
  116. bcs .Lnopossibleoverlap
  117. nop
  118. .Lcopybackward:
  119. // check alignment of source and dest
  120. or %i0,%i1,%l0
  121. // move src and dest to the end of the blocks
  122. // assuming 16 byte block size
  123. sub %i2,1,%l1
  124. add %i0,%l1,%i0
  125. add %i1,%l1,%i1
  126. {
  127. // everything 16 byte aligned ?
  128. andcc %l0,15,%l0
  129. be .Lmovetwordwise
  130. // load direction in delay slot
  131. mov -16,%l1
  132. // adjust according to block size
  133. add %i0,8,%i0
  134. add %i1,8,%i1
  135. andcc %l0,7,%l0
  136. be .Lmoveqwordwise
  137. mov -8,%l1
  138. // adjust according to block size
  139. add %i0,4,%i0
  140. add %i1,4,%i1
  141. andcc %l0,3,%l0
  142. be .Lmovedwordwise
  143. mov -4,%l1
  144. // adjust according to block size
  145. add %i0,2,%i0
  146. add %i1,2,%i1
  147. andcc %l0,1,%l0
  148. be .Lmovewordwise
  149. mov -2,%l1
  150. // adjust according to block size
  151. add %i0,1,%i0
  152. add %i1,1,%i1
  153. }
  154. ba .Lmovebytewise
  155. mov -1,%l1
  156. .Lnopossibleoverlap:
  157. // check alignment of source and dest
  158. or %i0,%i1,%l0
  159. // everything 16 byte aligned ?
  160. andcc %l0,15,%l0
  161. be .Lmovetwordwise
  162. // load direction in delay slot
  163. mov 16,%l1
  164. andcc %l0,7,%l0
  165. be .Lmoveqwordwise
  166. mov 8,%l1
  167. andcc %l0,3,%l0
  168. be .Lmovedwordwise
  169. mov 4,%l1
  170. andcc %l0,1,%l0
  171. be .Lmovewordwise
  172. mov 2,%l1
  173. ba .Lmovebytewise
  174. mov 1,%l1
  175. .Lmovetwordwise:
  176. srl %i2,4,%l6
  177. cmp %g0,%l6
  178. sll %l6,4,%l7
  179. be .Lmoveqwordwise_shift
  180. nop
  181. .Lmovetwordwise_loop:
  182. ld [%i0],%l2
  183. ld [%i0+4],%l3
  184. subcc %l6,1,%l6
  185. ld [%i0+8],%l4
  186. ld [%i0+12],%l5
  187. add %i0,%l1,%i0
  188. st %l2,[%i1]
  189. st %l3,[%i1+4]
  190. st %l4,[%i1+8]
  191. st %l5,[%i1+12]
  192. add %i1,%l1,%i1
  193. bne .Lmovetwordwise_loop
  194. nop
  195. subcc %i2,%l7,%i2
  196. be .Lmoveexit
  197. nop
  198. .Lmoveqwordwise_shift:
  199. sra %l1,1,%l1
  200. .Lmoveqwordwise:
  201. srl %i2,3,%l6
  202. cmp %g0,%l6
  203. sll %l6,3,%l7
  204. be .Lmovedwordwise_shift
  205. nop
  206. .Lmoveqwordwise_loop:
  207. ld [%i0],%l2
  208. ld [%i0+4],%l3
  209. subcc %l6,1,%l6
  210. add %i0,%l1,%i0
  211. st %l2,[%i1]
  212. st %l3,[%i1+4]
  213. add %i1,%l1,%i1
  214. bne .Lmoveqwordwise_loop
  215. nop
  216. subcc %i2,%l7,%i2
  217. be .Lmoveexit
  218. nop
  219. .Lmovedwordwise_shift:
  220. sra %l1,1,%l1
  221. .Lmovedwordwise:
  222. srl %i2,2,%l6
  223. cmp %g0,%l6
  224. sll %l6,2,%l7
  225. be .Lmovewordwise_shift
  226. nop
  227. .Lmovedwordwise_loop:
  228. ld [%i0],%l0
  229. subcc %l6,1,%l6
  230. add %i0,%l1,%i0
  231. st %l0,[%i1]
  232. add %i1,%l1,%i1
  233. bne .Lmovedwordwise_loop
  234. nop
  235. subcc %i2,%l7,%i2
  236. be .Lmoveexit
  237. nop
  238. .Lmovewordwise_shift:
  239. sra %l1,1,%l1
  240. .Lmovewordwise:
  241. srl %i2,1,%l6
  242. cmp %g0,%l6
  243. sll %l6,1,%l7
  244. be .Lmovebytewise_shift
  245. nop
  246. .Lmovewordwise_loop:
  247. lduh [%i0],%l0
  248. subcc %l6,1,%l6
  249. add %i0,%l1,%i0
  250. sth %l0,[%i1]
  251. add %i1,%l1,%i1
  252. bne .Lmovewordwise_loop
  253. nop
  254. subcc %i2,%l7,%i2
  255. be .Lmoveexit
  256. nop
  257. .Lmovebytewise_shift:
  258. sra %l1,1,%l1
  259. .Lmovebytewise:
  260. cmp %g0,%i2
  261. be .Lmoveexit
  262. nop
  263. ldub [%i0],%l0
  264. subcc %i2,1,%i2
  265. add %i0,%l1,%i0
  266. stb %l0,[%i1]
  267. add %i1,%l1,%i1
  268. bne .Lmovebytewise
  269. nop
  270. .Lmoveexit:
  271. end;
  272. {$endif FPC_SYSTEM_HAS_MOVE}
  273. {****************************************************************************
  274. Integer math
  275. ****************************************************************************}
  276. var
  277. fpc_system_lock : byte;export name 'fpc_system_lock';
  278. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  279. function declocked(var l : longint) : boolean;assembler;nostackframe;
  280. asm
  281. .Ldeclocked1:
  282. ld [%o0],%g4
  283. sub %g4,1,%g1
  284. cas [%o0],%g4,%g1
  285. cmp %g4,%g1
  286. bne .Ldeclocked1
  287. sub %g1,1,%g1
  288. movrz %g1,1,%o0
  289. movrnz %g1,0,%o0
  290. end;
  291. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  292. procedure inclocked(var l : longint);assembler;nostackframe;
  293. asm
  294. .Linclocked1:
  295. ld [%o0],%g4
  296. add %g4,1,%g1
  297. cas [%o0],%g4,%g1
  298. cmp %g4,%g1
  299. bne .Linclocked1
  300. nop
  301. end;
  302. function InterLockedDecrement (var Target: longint) : longint;assembler;nostackframe;
  303. asm
  304. .LInterLockedDecrement1:
  305. ld [%o0],%g4
  306. sub %g4,1,%g1
  307. cas [%o0],%g4,%g1
  308. cmp %g4,%g1
  309. bne .LInterLockedDecrement1
  310. nop
  311. sub %g1,1,%o0
  312. end;
  313. function InterLockedIncrement (var Target: longint) : longint;assembler;nostackframe;
  314. asm
  315. .LInterLockedIncrement1:
  316. ld [%o0],%g4
  317. add %g4,1,%g1
  318. cas [%o0],%g4,%g1
  319. cmp %g4,%g1
  320. bne .LInterLockedIncrement1
  321. nop
  322. add %g1,1,%o0
  323. end;
  324. function InterLockedExchange (var Target: longint;Source : longint) : longint;assembler;nostackframe;
  325. asm
  326. .LInterLockedExchange1:
  327. mov %o1,%g1
  328. ld [%o0],%g4
  329. cas [%o0],%g4,%g1
  330. cmp %g4,%g1
  331. bne .LInterLockedExchange1
  332. nop
  333. mov %g1,%o0
  334. end;
  335. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;assembler;nostackframe;
  336. asm
  337. .LInterLockedExchangeAdd1:
  338. ld [%o0],%g4
  339. add %g4,%o1,%g1
  340. cas [%o0],%g4,%g1
  341. cmp %g4,%g1
  342. bne .LInterLockedExchangeAdd1
  343. nop
  344. mov %g1,%o0
  345. end;
  346. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;nostackframe;
  347. asm
  348. cas [%o0],%o2,%o1
  349. mov %o1,%o0
  350. end;
  351. function InterLockedDecrement64(var Target: Int64) : Int64;assembler;nostackframe;
  352. asm
  353. .LInterLockedDecrement641:
  354. ldx [%o0],%g4
  355. sub %g4,1,%g1
  356. casx [%o0],%g4,%g1
  357. cmp %g4,%g1
  358. bne %xcc,.LInterLockedDecrement641
  359. nop
  360. sub %g1,1,%o0
  361. end;
  362. function InterLockedIncrement64(var Target: Int64) : Int64;assembler;nostackframe;
  363. asm
  364. .LInterLockedIncrement641:
  365. ldx [%o0],%g4
  366. add %g4,1,%g1
  367. casx [%o0],%g4,%g1
  368. cmp %g4,%g1
  369. bne %xcc,.LInterLockedIncrement641
  370. nop
  371. add %g1,1,%o0
  372. end;
  373. function InterLockedExchange64(var Target: Int64;Source : Int64) : Int64;assembler;nostackframe;
  374. asm
  375. .LInterLockedExchange641:
  376. mov %o1,%g1
  377. ldx [%o0],%g4
  378. casx [%o0],%g4,%g1
  379. cmp %g4,%g1
  380. bne %xcc,.LInterLockedExchange641
  381. nop
  382. mov %g1,%o0
  383. end;
  384. function InterLockedExchangeAdd64(var Target: Int64;Source : Int64) : Int64;assembler;nostackframe;
  385. asm
  386. .LInterLockedExchangeAdd641:
  387. ldx [%o0],%g4
  388. add %g4,%o1,%g1
  389. casx [%o0],%g4,%g1
  390. cmp %g4,%g1
  391. bne %xcc,.LInterLockedExchangeAdd641
  392. nop
  393. mov %g1,%o0
  394. end;
  395. function InterlockedCompareExchange64(var Target: Int64; NewValue: Int64; Comperand: Int64): Int64;assembler;nostackframe;
  396. asm
  397. casx [%o0],%o2,%o1
  398. mov %o1,%o0
  399. end;
  400. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  401. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  402. const
  403. LoadLoad = $01;
  404. StoreLoad = $02;
  405. LoadStore = $04;
  406. StoreStore = $08;
  407. LookAside = $10;
  408. MemIssue = $20;
  409. Sync = $40;
  410. {$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
  411. {$define CPUSPARC_HAS_MEMBAR}
  412. {$endif}
  413. procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  414. asm
  415. {$ifdef CPUSPARC_HAS_MEMBAR}
  416. ba,pt .L1
  417. membar LoadLoad
  418. .L1:
  419. {$endif}
  420. end;
  421. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  422. begin
  423. { reads imply barrier on earlier reads depended on }
  424. end;
  425. procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  426. asm
  427. {$ifdef CPUSPARC_HAS_MEMBAR}
  428. ba,pt .L1
  429. membar LoadLoad + LoadStore + StoreLoad + StoreStore
  430. .L1:
  431. {$endif}
  432. end;
  433. procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  434. asm
  435. {$ifdef CPUSPARC_HAS_MEMBAR}
  436. ba,pt .L1
  437. stbar
  438. .L1:
  439. {$endif}
  440. end;
  441. {$endif}
  442. {$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
  443. {$define FPC_SYSTEM_HAS_SAR_QWORD}
  444. function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
  445. asm
  446. { %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
  447. and %o2,63,%o2
  448. subcc %o2,32,%g0
  449. bcc .L1
  450. nop
  451. srl %o1,%o2,%o1
  452. subcc %o2,%g0,%g0
  453. be .Lexit
  454. sra %o0,%o2,%o0
  455. sub %g0,%o2,%o3
  456. sll %o0,%o3,%o3
  457. ba .Lexit
  458. or %o3,%o1,%o1
  459. .L1:
  460. sra %o0,%o2,%o1
  461. sra %o0,31,%o0
  462. .Lexit:
  463. end;
  464. {$endif FPC_SYSTEM_HAS_SAR_QWORD}