sparc.inc 15 KB

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