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);[public, alias: 'FPC_SETFSR'];
  24. begin
  25. DefaultFPUControlWord:=fsr;
  26. asm
  27. ld fsr,%fsr
  28. end;
  29. end;
  30. function GetNativeFPUControlWord: TNativeFPUControlWord; {$if defined(SYSTEMINLINE)}inline;{$endif}
  31. begin
  32. result:=get_fsr;
  33. end;
  34. procedure SetNativeFPUControlWord(const cw: TNativeFPUControlWord); {$if defined(SYSTEMINLINE)}inline;{$endif}
  35. begin
  36. set_fsr(cw);
  37. end;
  38. function get_got : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT'];
  39. asm
  40. retl
  41. add %o7,%l7,%l7
  42. end;
  43. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  44. Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
  45. begin
  46. { enable div by 0 and invalid operation fpu exceptions
  47. round towards zero; ieee compliant arithmetics }
  48. set_fsr((get_fsr and $3fbfffff) or $09000000);
  49. softfloat_exception_mask:=[float_flag_underflow,float_flag_overflow,float_flag_inexact,float_flag_denormal];
  50. softfloat_exception_flags:=[];
  51. end;
  52. {$define FPC_SYSTEM_HAS_GET_FRAME}
  53. function get_frame:pointer;assembler;nostackframe;
  54. asm
  55. mov %fp,%o0
  56. end;
  57. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  58. function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
  59. asm
  60. { framebp = %o0 }
  61. subcc %o0,0,%o0
  62. be .Lframezero
  63. nop
  64. { flush register windows, so they are stored in the stack }
  65. ta 3
  66. ld [%o0+60],%o0
  67. { check if new %o0 register is zero }
  68. subcc %o0,0,%o0
  69. be .Lframezero
  70. nop
  71. { if not zero, add 8 to skip jmpl and delay slot }
  72. add %o0,8,%o0
  73. .Lframezero:
  74. end;
  75. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  76. function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
  77. asm
  78. { framebp = %o0 }
  79. subcc %o0,0,%o0
  80. be .Lframezero
  81. nop
  82. { flush register windows, so they are stored in the stack }
  83. ta 3
  84. ld [%o0+56],%o0
  85. .Lframezero:
  86. end;
  87. {$define FPC_SYSTEM_HAS_SPTR}
  88. function Sptr:Pointer;assembler;nostackframe;
  89. asm
  90. mov %sp,%o0
  91. end;
  92. {$ifndef FPC_SYSTEM_HAS_MOVE}
  93. {$define FPC_SYSTEM_HAS_MOVE}
  94. procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;
  95. {
  96. Registers:
  97. %l0 temp. to do copying
  98. %l1 inc/decrement
  99. %l2/l3/l4/l5 qword move
  100. }
  101. asm
  102. // count < 0 ?
  103. cmp %g0,%i2
  104. bge .Lmoveexit
  105. nop
  106. // possible overlap?
  107. cmp %i0,%i1
  108. bcc .Lnopossibleoverlap
  109. nop
  110. // source < dest ....
  111. add %i0,%i2,%l0
  112. // overlap?
  113. cmp %l0,%i1
  114. // source+count < dest ?
  115. bcs .Lnopossibleoverlap
  116. nop
  117. .Lcopybackward:
  118. // check alignment of source and dest
  119. or %i0,%i1,%l0
  120. // move src and dest to the end of the blocks
  121. // assuming 16 byte block size
  122. sub %i2,1,%l1
  123. add %i0,%l1,%i0
  124. add %i1,%l1,%i1
  125. {
  126. // everything 16 byte aligned ?
  127. andcc %l0,15,%l0
  128. be .Lmovetwordwise
  129. // load direction in delay slot
  130. mov -16,%l1
  131. // adjust according to block size
  132. add %i0,8,%i0
  133. add %i1,8,%i1
  134. andcc %l0,7,%l0
  135. be .Lmoveqwordwise
  136. mov -8,%l1
  137. // adjust according to block size
  138. add %i0,4,%i0
  139. add %i1,4,%i1
  140. andcc %l0,3,%l0
  141. be .Lmovedwordwise
  142. mov -4,%l1
  143. // adjust according to block size
  144. add %i0,2,%i0
  145. add %i1,2,%i1
  146. andcc %l0,1,%l0
  147. be .Lmovewordwise
  148. mov -2,%l1
  149. // adjust according to block size
  150. add %i0,1,%i0
  151. add %i1,1,%i1
  152. }
  153. ba .Lmovebytewise
  154. mov -1,%l1
  155. .Lnopossibleoverlap:
  156. // check alignment of source and dest
  157. or %i0,%i1,%l0
  158. // everything 16 byte aligned ?
  159. andcc %l0,15,%l0
  160. be .Lmovetwordwise
  161. // load direction in delay slot
  162. mov 16,%l1
  163. andcc %l0,7,%l0
  164. be .Lmoveqwordwise
  165. mov 8,%l1
  166. andcc %l0,3,%l0
  167. be .Lmovedwordwise
  168. mov 4,%l1
  169. andcc %l0,1,%l0
  170. be .Lmovewordwise
  171. mov 2,%l1
  172. ba .Lmovebytewise
  173. mov 1,%l1
  174. .Lmovetwordwise:
  175. srl %i2,4,%l6
  176. cmp %g0,%l6
  177. sll %l6,4,%l7
  178. be .Lmoveqwordwise_shift
  179. nop
  180. .Lmovetwordwise_loop:
  181. ld [%i0],%l2
  182. ld [%i0+4],%l3
  183. subcc %l6,1,%l6
  184. ld [%i0+8],%l4
  185. ld [%i0+12],%l5
  186. add %i0,%l1,%i0
  187. st %l2,[%i1]
  188. st %l3,[%i1+4]
  189. st %l4,[%i1+8]
  190. st %l5,[%i1+12]
  191. add %i1,%l1,%i1
  192. bne .Lmovetwordwise_loop
  193. nop
  194. subcc %i2,%l7,%i2
  195. be .Lmoveexit
  196. nop
  197. .Lmoveqwordwise_shift:
  198. sra %l1,1,%l1
  199. .Lmoveqwordwise:
  200. srl %i2,3,%l6
  201. cmp %g0,%l6
  202. sll %l6,3,%l7
  203. be .Lmovedwordwise_shift
  204. nop
  205. .Lmoveqwordwise_loop:
  206. ld [%i0],%l2
  207. ld [%i0+4],%l3
  208. subcc %l6,1,%l6
  209. add %i0,%l1,%i0
  210. st %l2,[%i1]
  211. st %l3,[%i1+4]
  212. add %i1,%l1,%i1
  213. bne .Lmoveqwordwise_loop
  214. nop
  215. subcc %i2,%l7,%i2
  216. be .Lmoveexit
  217. nop
  218. .Lmovedwordwise_shift:
  219. sra %l1,1,%l1
  220. .Lmovedwordwise:
  221. srl %i2,2,%l6
  222. cmp %g0,%l6
  223. sll %l6,2,%l7
  224. be .Lmovewordwise_shift
  225. nop
  226. .Lmovedwordwise_loop:
  227. ld [%i0],%l0
  228. subcc %l6,1,%l6
  229. add %i0,%l1,%i0
  230. st %l0,[%i1]
  231. add %i1,%l1,%i1
  232. bne .Lmovedwordwise_loop
  233. nop
  234. subcc %i2,%l7,%i2
  235. be .Lmoveexit
  236. nop
  237. .Lmovewordwise_shift:
  238. sra %l1,1,%l1
  239. .Lmovewordwise:
  240. srl %i2,1,%l6
  241. cmp %g0,%l6
  242. sll %l6,1,%l7
  243. be .Lmovebytewise_shift
  244. nop
  245. .Lmovewordwise_loop:
  246. lduh [%i0],%l0
  247. subcc %l6,1,%l6
  248. add %i0,%l1,%i0
  249. sth %l0,[%i1]
  250. add %i1,%l1,%i1
  251. bne .Lmovewordwise_loop
  252. nop
  253. subcc %i2,%l7,%i2
  254. be .Lmoveexit
  255. nop
  256. .Lmovebytewise_shift:
  257. sra %l1,1,%l1
  258. .Lmovebytewise:
  259. cmp %g0,%i2
  260. be .Lmoveexit
  261. nop
  262. ldub [%i0],%l0
  263. subcc %i2,1,%i2
  264. add %i0,%l1,%i0
  265. stb %l0,[%i1]
  266. add %i1,%l1,%i1
  267. bne .Lmovebytewise
  268. nop
  269. .Lmoveexit:
  270. end;
  271. {$endif FPC_SYSTEM_HAS_MOVE}
  272. {****************************************************************************
  273. Integer math
  274. ****************************************************************************}
  275. var
  276. fpc_system_lock : byte;export name 'fpc_system_lock';
  277. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  278. function declocked(var l : longint) : boolean;assembler;
  279. {$ifndef FPC_PIC}nostackframe;{$endif}
  280. asm
  281. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  282. worse the effort, especially while waiting :)
  283. }
  284. {$ifdef FPC_PIC}
  285. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  286. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  287. call get_got
  288. nop
  289. {$endif FPC_PIC}
  290. .Ldeclocked1:
  291. sethi %hi(fpc_system_lock), %g1
  292. or %g1,%lo(fpc_system_lock), %g1
  293. {$ifdef FPC_PIC}
  294. ld [%g1+%l7],%g1
  295. {$endif FPC_PIC}
  296. ldstub [%g1],%g1
  297. cmp %g1,0
  298. bne .Ldeclocked1
  299. nop
  300. {$ifdef FPC_PIC}
  301. ld [%i0],%g1
  302. sub %g1,1,%g1
  303. st %g1,[%i0]
  304. subcc %g1,1,%g0
  305. addx %g0,%g0,%i0
  306. {$else not FPC_PIC}
  307. ld [%o0],%g1
  308. sub %g1,1,%g1
  309. st %g1,[%o0]
  310. subcc %g1,1,%g0
  311. addx %g0,%g0,%o0
  312. {$endif FPC_PIC}
  313. { unlock }
  314. sethi %hi(fpc_system_lock), %g1
  315. or %g1,%lo(fpc_system_lock), %g1
  316. {$ifdef FPC_PIC}
  317. ld [%g1+%l7],%g1
  318. {$endif FPC_PIC}
  319. stb %g0,[%g1]
  320. end;
  321. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  322. procedure inclocked(var l : longint);assembler;
  323. {$ifndef FPC_PIC}nostackframe;{$endif}
  324. asm
  325. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  326. worse the effort, especially while waiting :)
  327. }
  328. {$ifdef FPC_PIC}
  329. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  330. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  331. call get_got
  332. nop
  333. {$endif FPC_PIC}
  334. .Linclocked1:
  335. sethi %hi(fpc_system_lock), %g1
  336. or %g1,%lo(fpc_system_lock), %g1
  337. {$ifdef FPC_PIC}
  338. ld [%g1+%l7],%g1
  339. {$endif FPC_PIC}
  340. ldstub [%g1],%g1
  341. cmp %g1,0
  342. bne .Linclocked1
  343. nop
  344. {$ifdef FPC_PIC}
  345. ld [%i0],%g1
  346. add %g1,1,%g1
  347. st %g1,[%i0]
  348. {$else not FPC_PIC}
  349. ld [%o0],%g1
  350. add %g1,1,%g1
  351. st %g1,[%o0]
  352. {$endif FPC_PIC}
  353. { unlock }
  354. sethi %hi(fpc_system_lock), %g1
  355. or %g1,%lo(fpc_system_lock), %g1
  356. {$ifdef FPC_PIC}
  357. ld [%g1+%l7],%g1
  358. {$endif FPC_PIC}
  359. stb %g0,[%g1]
  360. end;
  361. function InterLockedDecrement (var Target: longint) : longint; assembler;
  362. {$ifndef FPC_PIC}nostackframe;{$endif}
  363. asm
  364. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  365. worse the effort, especially while waiting :)
  366. }
  367. {$ifdef FPC_PIC}
  368. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  369. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  370. call get_got
  371. nop
  372. {$endif FPC_PIC}
  373. .LInterLockedDecrement1:
  374. sethi %hi(fpc_system_lock), %g1
  375. or %g1,%lo(fpc_system_lock), %g1
  376. {$ifdef FPC_PIC}
  377. ld [%g1+%l7],%g1
  378. {$endif FPC_PIC}
  379. ldstub [%g1],%g1
  380. cmp %g1,0
  381. bne .LInterLockedDecrement1
  382. nop
  383. {$ifdef FPC_PIC}
  384. ld [%i0],%g1
  385. sub %g1,1,%g1
  386. st %g1,[%i0]
  387. mov %g1,%i0
  388. {$else not FPC_PIC}
  389. ld [%o0],%g1
  390. sub %g1,1,%g1
  391. st %g1,[%o0]
  392. mov %g1,%o0
  393. {$endif FPC_PIC}
  394. { unlock }
  395. sethi %hi(fpc_system_lock), %g1
  396. or %g1,%lo(fpc_system_lock), %g1
  397. {$ifdef FPC_PIC}
  398. ld [%g1+%l7],%g1
  399. {$endif FPC_PIC}
  400. stb %g0,[%g1]
  401. end;
  402. function InterLockedIncrement (var Target: longint) : longint; assembler;
  403. {$ifndef FPC_PIC}nostackframe;{$endif}
  404. asm
  405. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  406. worse the effort, especially while waiting :)
  407. }
  408. {$ifdef FPC_PIC}
  409. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  410. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  411. call get_got
  412. nop
  413. {$endif FPC_PIC}
  414. .LInterLockedIncrement1:
  415. sethi %hi(fpc_system_lock), %g1
  416. or %g1,%lo(fpc_system_lock), %g1
  417. {$ifdef FPC_PIC}
  418. ld [%g1+%l7],%g1
  419. {$endif FPC_PIC}
  420. ldstub [%g1],%g1
  421. cmp %g1,0
  422. bne .LInterLockedIncrement1
  423. nop
  424. {$ifdef FPC_PIC}
  425. ld [%i0],%g1
  426. add %g1,1,%g1
  427. st %g1,[%i0]
  428. mov %g1,%i0
  429. {$else not FPC_PIC}
  430. ld [%o0],%g1
  431. add %g1,1,%g1
  432. st %g1,[%o0]
  433. mov %g1,%o0
  434. {$endif FPC_PIC}
  435. { unlock }
  436. sethi %hi(fpc_system_lock), %g1
  437. or %g1,%lo(fpc_system_lock), %g1
  438. {$ifdef FPC_PIC}
  439. ld [%g1+%l7],%g1
  440. {$endif FPC_PIC}
  441. stb %g0,[%g1]
  442. end;
  443. function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler;
  444. {$ifndef FPC_PIC}nostackframe;{$endif}
  445. asm
  446. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  447. worse the effort, especially while waiting :)
  448. }
  449. {$ifdef FPC_PIC}
  450. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  451. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  452. call get_got
  453. nop
  454. {$endif FPC_PIC}
  455. .LInterLockedExchange1:
  456. sethi %hi(fpc_system_lock), %g1
  457. or %g1,%lo(fpc_system_lock), %g1
  458. {$ifdef FPC_PIC}
  459. ld [%g1+%l7],%g1
  460. {$endif FPC_PIC}
  461. ldstub [%g1],%g1
  462. cmp %g1,0
  463. bne .LInterLockedExchange1
  464. nop
  465. {$ifdef FPC_PIC}
  466. ld [%i0],%g1
  467. st %i1,[%i0]
  468. mov %g1,%i0
  469. {$else not FPC_PIC}
  470. ld [%o0],%g1
  471. st %o1,[%o0]
  472. mov %g1,%o0
  473. {$endif FPC_PIC}
  474. { unlock }
  475. sethi %hi(fpc_system_lock), %g1
  476. or %g1,%lo(fpc_system_lock), %g1
  477. {$ifdef FPC_PIC}
  478. ld [%g1+%l7],%g1
  479. {$endif FPC_PIC}
  480. stb %g0,[%g1]
  481. end;
  482. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler;
  483. {$ifndef FPC_PIC}nostackframe;{$endif}
  484. asm
  485. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  486. worse the effort, especially while waiting :)
  487. }
  488. {$ifdef FPC_PIC}
  489. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  490. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  491. call get_got
  492. nop
  493. {$endif FPC_PIC}
  494. .LInterLockedExchangeAdd1:
  495. sethi %hi(fpc_system_lock), %g1
  496. or %g1,%lo(fpc_system_lock), %g1
  497. {$ifdef FPC_PIC}
  498. ld [%g1+%l7],%g1
  499. {$endif FPC_PIC}
  500. ldstub [%g1],%g1
  501. cmp %g1,0
  502. bne .LInterLockedExchangeAdd1
  503. nop
  504. {$ifdef FPC_PIC}
  505. ld [%i0],%g1
  506. add %g1,%i1,%i1
  507. st %i1,[%i0]
  508. mov %g1,%i0
  509. {$else not FPC_PIC}
  510. ld [%o0],%g1
  511. add %g1,%o1,%o1
  512. st %o1,[%o0]
  513. mov %g1,%o0
  514. {$endif FPC_PIC}
  515. { unlock }
  516. sethi %hi(fpc_system_lock), %g1
  517. or %g1,%lo(fpc_system_lock), %g1
  518. {$ifdef FPC_PIC}
  519. ld [%g1+%l7],%g1
  520. {$endif FPC_PIC}
  521. stb %g0,[%g1]
  522. end;
  523. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler;
  524. {$ifndef FPC_PIC}nostackframe;{$endif}
  525. asm
  526. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  527. worse the effort, especially while waiting :)
  528. }
  529. { input: address of target in o0, newvalue in o1, comparand in o2 }
  530. { output: value stored in target before entry of the function }
  531. { side-effect: NewValue stored in target if (target = comparand) }
  532. {$ifdef FPC_PIC}
  533. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  534. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  535. call get_got
  536. nop
  537. {$endif FPC_PIC}
  538. .LInterlockedCompareExchange1:
  539. sethi %hi(fpc_system_lock), %g1
  540. or %g1,%lo(fpc_system_lock), %g1
  541. {$ifdef FPC_PIC}
  542. ld [%g1+%l7],%g1
  543. {$endif FPC_PIC}
  544. ldstub [%g1],%g1
  545. cmp %g1,0
  546. bne .LInterlockedCompareExchange1
  547. nop
  548. {$ifdef FPC_PIC}
  549. ld [%i0],%g1
  550. cmp %g1,%i2
  551. bne .LInterlockedCompareExchange2
  552. nop
  553. st %i1,[%i0]
  554. .LInterlockedCompareExchange2:
  555. mov %g1,%i0
  556. {$else not FPC_PIC}
  557. ld [%o0],%g1
  558. cmp %g1,%o2
  559. bne .LInterlockedCompareExchange2
  560. nop
  561. st %o1,[%o0]
  562. .LInterlockedCompareExchange2:
  563. mov %g1,%o0
  564. {$endif FPC_PIC}
  565. { unlock }
  566. sethi %hi(fpc_system_lock), %g1
  567. or %g1,%lo(fpc_system_lock), %g1
  568. {$ifdef FPC_PIC}
  569. ld [%g1+%l7],%g1
  570. {$endif FPC_PIC}
  571. stb %g0,[%g1]
  572. end;
  573. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  574. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  575. const
  576. LoadLoad = $01;
  577. StoreLoad = $02;
  578. LoadStore = $04;
  579. StoreStore = $08;
  580. LookAside = $10;
  581. MemIssue = $20;
  582. Sync = $40;
  583. {$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
  584. {$define CPUSPARC_HAS_MEMBAR}
  585. {$endif}
  586. procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  587. asm
  588. {$ifdef CPUSPARC_HAS_MEMBAR}
  589. ba,pt .L1
  590. membar LoadLoad
  591. .L1:
  592. {$endif}
  593. end;
  594. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  595. begin
  596. { reads imply barrier on earlier reads depended on }
  597. end;
  598. procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  599. asm
  600. {$ifdef CPUSPARC_HAS_MEMBAR}
  601. ba,pt .L1
  602. membar LoadLoad + LoadStore + StoreLoad + StoreStore
  603. .L1:
  604. {$endif}
  605. end;
  606. procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  607. asm
  608. {$ifdef CPUSPARC_HAS_MEMBAR}
  609. ba,pt .L1
  610. stbar
  611. .L1:
  612. {$endif}
  613. end;
  614. {$endif}
  615. {$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
  616. {$define FPC_SYSTEM_HAS_SAR_QWORD}
  617. function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
  618. asm
  619. { %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
  620. and %o2,63,%o2
  621. subcc %o2,32,%g0
  622. bcc .L1
  623. nop
  624. srl %o1,%o2,%o1
  625. subcc %o2,%g0,%g0
  626. be .Lexit
  627. sra %o0,%o2,%o0
  628. sub %g0,%o2,%o3
  629. sll %o0,%o3,%o3
  630. ba .Lexit
  631. or %o3,%o1,%o1
  632. .L1:
  633. sra %o0,%o2,%o1
  634. sra %o0,31,%o0
  635. .Lexit:
  636. end;
  637. {$endif FPC_SYSTEM_HAS_SAR_QWORD}