sparc.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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. ta 3
  67. ld [%o0+60],%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. ta 3
  85. ld [%o0+56],%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:longint);[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;
  280. {$ifndef FPC_PIC}nostackframe;{$endif}
  281. asm
  282. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  283. worse the effort, especially while waiting :)
  284. }
  285. {$ifdef FPC_PIC}
  286. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  287. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  288. call get_got
  289. nop
  290. {$endif FPC_PIC}
  291. .Ldeclocked1:
  292. sethi %hi(fpc_system_lock), %g1
  293. or %g1,%lo(fpc_system_lock), %g1
  294. {$ifdef FPC_PIC}
  295. ld [%g1+%l7],%g1
  296. {$endif FPC_PIC}
  297. ldstub [%g1],%g1
  298. cmp %g1,0
  299. bne .Ldeclocked1
  300. nop
  301. {$ifdef FPC_PIC}
  302. ld [%i0],%g1
  303. sub %g1,1,%g1
  304. st %g1,[%i0]
  305. subcc %g1,1,%g0
  306. addx %g0,%g0,%i0
  307. {$else not FPC_PIC}
  308. ld [%o0],%g1
  309. sub %g1,1,%g1
  310. st %g1,[%o0]
  311. subcc %g1,1,%g0
  312. addx %g0,%g0,%o0
  313. {$endif FPC_PIC}
  314. { unlock }
  315. sethi %hi(fpc_system_lock), %g1
  316. or %g1,%lo(fpc_system_lock), %g1
  317. {$ifdef FPC_PIC}
  318. ld [%g1+%l7],%g1
  319. {$endif FPC_PIC}
  320. stb %g0,[%g1]
  321. end;
  322. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  323. procedure inclocked(var l : longint);assembler;
  324. {$ifndef FPC_PIC}nostackframe;{$endif}
  325. asm
  326. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  327. worse the effort, especially while waiting :)
  328. }
  329. {$ifdef FPC_PIC}
  330. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  331. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  332. call get_got
  333. nop
  334. {$endif FPC_PIC}
  335. .Linclocked1:
  336. sethi %hi(fpc_system_lock), %g1
  337. or %g1,%lo(fpc_system_lock), %g1
  338. {$ifdef FPC_PIC}
  339. ld [%g1+%l7],%g1
  340. {$endif FPC_PIC}
  341. ldstub [%g1],%g1
  342. cmp %g1,0
  343. bne .Linclocked1
  344. nop
  345. {$ifdef FPC_PIC}
  346. ld [%i0],%g1
  347. add %g1,1,%g1
  348. st %g1,[%i0]
  349. {$else not FPC_PIC}
  350. ld [%o0],%g1
  351. add %g1,1,%g1
  352. st %g1,[%o0]
  353. {$endif FPC_PIC}
  354. { unlock }
  355. sethi %hi(fpc_system_lock), %g1
  356. or %g1,%lo(fpc_system_lock), %g1
  357. {$ifdef FPC_PIC}
  358. ld [%g1+%l7],%g1
  359. {$endif FPC_PIC}
  360. stb %g0,[%g1]
  361. end;
  362. function InterLockedDecrement (var Target: longint) : longint; assembler;
  363. {$ifndef FPC_PIC}nostackframe;{$endif}
  364. asm
  365. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  366. worse the effort, especially while waiting :)
  367. }
  368. {$ifdef FPC_PIC}
  369. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  370. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  371. call get_got
  372. nop
  373. {$endif FPC_PIC}
  374. .LInterLockedDecrement1:
  375. sethi %hi(fpc_system_lock), %g1
  376. or %g1,%lo(fpc_system_lock), %g1
  377. {$ifdef FPC_PIC}
  378. ld [%g1+%l7],%g1
  379. {$endif FPC_PIC}
  380. ldstub [%g1],%g1
  381. cmp %g1,0
  382. bne .LInterLockedDecrement1
  383. nop
  384. {$ifdef FPC_PIC}
  385. ld [%i0],%g1
  386. sub %g1,1,%g1
  387. st %g1,[%i0]
  388. mov %g1,%i0
  389. {$else not FPC_PIC}
  390. ld [%o0],%g1
  391. sub %g1,1,%g1
  392. st %g1,[%o0]
  393. mov %g1,%o0
  394. {$endif FPC_PIC}
  395. { unlock }
  396. sethi %hi(fpc_system_lock), %g1
  397. or %g1,%lo(fpc_system_lock), %g1
  398. {$ifdef FPC_PIC}
  399. ld [%g1+%l7],%g1
  400. {$endif FPC_PIC}
  401. stb %g0,[%g1]
  402. end;
  403. function InterLockedIncrement (var Target: longint) : longint; assembler;
  404. {$ifndef FPC_PIC}nostackframe;{$endif}
  405. asm
  406. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  407. worse the effort, especially while waiting :)
  408. }
  409. {$ifdef FPC_PIC}
  410. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  411. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  412. call get_got
  413. nop
  414. {$endif FPC_PIC}
  415. .LInterLockedIncrement1:
  416. sethi %hi(fpc_system_lock), %g1
  417. or %g1,%lo(fpc_system_lock), %g1
  418. {$ifdef FPC_PIC}
  419. ld [%g1+%l7],%g1
  420. {$endif FPC_PIC}
  421. ldstub [%g1],%g1
  422. cmp %g1,0
  423. bne .LInterLockedIncrement1
  424. nop
  425. {$ifdef FPC_PIC}
  426. ld [%i0],%g1
  427. add %g1,1,%g1
  428. st %g1,[%i0]
  429. mov %g1,%i0
  430. {$else not FPC_PIC}
  431. ld [%o0],%g1
  432. add %g1,1,%g1
  433. st %g1,[%o0]
  434. mov %g1,%o0
  435. {$endif FPC_PIC}
  436. { unlock }
  437. sethi %hi(fpc_system_lock), %g1
  438. or %g1,%lo(fpc_system_lock), %g1
  439. {$ifdef FPC_PIC}
  440. ld [%g1+%l7],%g1
  441. {$endif FPC_PIC}
  442. stb %g0,[%g1]
  443. end;
  444. function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler;
  445. {$ifndef FPC_PIC}nostackframe;{$endif}
  446. asm
  447. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  448. worse the effort, especially while waiting :)
  449. }
  450. {$ifdef FPC_PIC}
  451. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  452. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  453. call get_got
  454. nop
  455. {$endif FPC_PIC}
  456. .LInterLockedExchange1:
  457. sethi %hi(fpc_system_lock), %g1
  458. or %g1,%lo(fpc_system_lock), %g1
  459. {$ifdef FPC_PIC}
  460. ld [%g1+%l7],%g1
  461. {$endif FPC_PIC}
  462. ldstub [%g1],%g1
  463. cmp %g1,0
  464. bne .LInterLockedExchange1
  465. nop
  466. {$ifdef FPC_PIC}
  467. ld [%i0],%g1
  468. st %i1,[%i0]
  469. mov %g1,%i0
  470. {$else not FPC_PIC}
  471. ld [%o0],%g1
  472. st %o1,[%o0]
  473. mov %g1,%o0
  474. {$endif FPC_PIC}
  475. { unlock }
  476. sethi %hi(fpc_system_lock), %g1
  477. or %g1,%lo(fpc_system_lock), %g1
  478. {$ifdef FPC_PIC}
  479. ld [%g1+%l7],%g1
  480. {$endif FPC_PIC}
  481. stb %g0,[%g1]
  482. end;
  483. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler;
  484. {$ifndef FPC_PIC}nostackframe;{$endif}
  485. asm
  486. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  487. worse the effort, especially while waiting :)
  488. }
  489. {$ifdef FPC_PIC}
  490. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  491. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  492. call get_got
  493. nop
  494. {$endif FPC_PIC}
  495. .LInterLockedExchangeAdd1:
  496. sethi %hi(fpc_system_lock), %g1
  497. or %g1,%lo(fpc_system_lock), %g1
  498. {$ifdef FPC_PIC}
  499. ld [%g1+%l7],%g1
  500. {$endif FPC_PIC}
  501. ldstub [%g1],%g1
  502. cmp %g1,0
  503. bne .LInterLockedExchangeAdd1
  504. nop
  505. {$ifdef FPC_PIC}
  506. ld [%i0],%g1
  507. add %g1,%i1,%i1
  508. st %i1,[%i0]
  509. mov %g1,%i0
  510. {$else not FPC_PIC}
  511. ld [%o0],%g1
  512. add %g1,%o1,%o1
  513. st %o1,[%o0]
  514. mov %g1,%o0
  515. {$endif FPC_PIC}
  516. { unlock }
  517. sethi %hi(fpc_system_lock), %g1
  518. or %g1,%lo(fpc_system_lock), %g1
  519. {$ifdef FPC_PIC}
  520. ld [%g1+%l7],%g1
  521. {$endif FPC_PIC}
  522. stb %g0,[%g1]
  523. end;
  524. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler;
  525. {$ifndef FPC_PIC}nostackframe;{$endif}
  526. asm
  527. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  528. worse the effort, especially while waiting :)
  529. }
  530. { input: address of target in o0, newvalue in o1, comparand in o2 }
  531. { output: value stored in target before entry of the function }
  532. { side-effect: NewValue stored in target if (target = comparand) }
  533. {$ifdef FPC_PIC}
  534. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  535. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  536. call get_got
  537. nop
  538. {$endif FPC_PIC}
  539. .LInterlockedCompareExchange1:
  540. sethi %hi(fpc_system_lock), %g1
  541. or %g1,%lo(fpc_system_lock), %g1
  542. {$ifdef FPC_PIC}
  543. ld [%g1+%l7],%g1
  544. {$endif FPC_PIC}
  545. ldstub [%g1],%g1
  546. cmp %g1,0
  547. bne .LInterlockedCompareExchange1
  548. nop
  549. {$ifdef FPC_PIC}
  550. ld [%i0],%g1
  551. cmp %g1,%i2
  552. bne .LInterlockedCompareExchange2
  553. nop
  554. st %i1,[%i0]
  555. .LInterlockedCompareExchange2:
  556. mov %g1,%i0
  557. {$else not FPC_PIC}
  558. ld [%o0],%g1
  559. cmp %g1,%o2
  560. bne .LInterlockedCompareExchange2
  561. nop
  562. st %o1,[%o0]
  563. .LInterlockedCompareExchange2:
  564. mov %g1,%o0
  565. {$endif FPC_PIC}
  566. { unlock }
  567. sethi %hi(fpc_system_lock), %g1
  568. or %g1,%lo(fpc_system_lock), %g1
  569. {$ifdef FPC_PIC}
  570. ld [%g1+%l7],%g1
  571. {$endif FPC_PIC}
  572. stb %g0,[%g1]
  573. end;
  574. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  575. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  576. const
  577. LoadLoad = $01;
  578. StoreLoad = $02;
  579. LoadStore = $04;
  580. StoreStore = $08;
  581. LookAside = $10;
  582. MemIssue = $20;
  583. Sync = $40;
  584. {$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
  585. {$define CPUSPARC_HAS_MEMBAR}
  586. {$endif}
  587. procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  588. asm
  589. {$ifdef CPUSPARC_HAS_MEMBAR}
  590. ba,pt .L1
  591. membar LoadLoad
  592. .L1:
  593. {$endif}
  594. end;
  595. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  596. begin
  597. { reads imply barrier on earlier reads depended on }
  598. end;
  599. procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  600. asm
  601. {$ifdef CPUSPARC_HAS_MEMBAR}
  602. ba,pt .L1
  603. membar LoadLoad + LoadStore + StoreLoad + StoreStore
  604. .L1:
  605. {$endif}
  606. end;
  607. procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  608. asm
  609. {$ifdef CPUSPARC_HAS_MEMBAR}
  610. ba,pt .L1
  611. stbar
  612. .L1:
  613. {$endif}
  614. end;
  615. {$endif}
  616. {$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
  617. {$define FPC_SYSTEM_HAS_SAR_QWORD}
  618. function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
  619. asm
  620. { %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
  621. and %o2,63,%o2
  622. subcc %o2,32,%g0
  623. bcc .L1
  624. nop
  625. srl %o1,%o2,%o1
  626. subcc %o2,%g0,%g0
  627. be .Lexit
  628. sra %o0,%o2,%o0
  629. sub %g0,%o2,%o3
  630. sll %o0,%o3,%o3
  631. ba .Lexit
  632. or %o3,%o1,%o1
  633. .L1:
  634. sra %o0,%o2,%o1
  635. sra %o0,31,%o0
  636. .Lexit:
  637. end;
  638. {$endif FPC_SYSTEM_HAS_SAR_QWORD}