sparc.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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. {$ifdef VER3_2}
  362. function InterLockedDecrement (var Target: longint) : longint; assembler;
  363. {$else VER3_2}
  364. {$define FPC_SYSTEM_HAS_ATOMIC_DEC_32}
  365. function fpc_atomic_dec_32 (var Target: longint) : longint; assembler;
  366. {$endif VER3_2}
  367. {$ifndef FPC_PIC}nostackframe;{$endif}
  368. asm
  369. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  370. worse the effort, especially while waiting :)
  371. }
  372. {$ifdef FPC_PIC}
  373. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  374. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  375. call get_got
  376. nop
  377. {$endif FPC_PIC}
  378. .LInterLockedDecrement1:
  379. sethi %hi(fpc_system_lock), %g1
  380. or %g1,%lo(fpc_system_lock), %g1
  381. {$ifdef FPC_PIC}
  382. ld [%g1+%l7],%g1
  383. {$endif FPC_PIC}
  384. ldstub [%g1],%g1
  385. cmp %g1,0
  386. bne .LInterLockedDecrement1
  387. nop
  388. {$ifdef FPC_PIC}
  389. ld [%i0],%g1
  390. sub %g1,1,%g1
  391. st %g1,[%i0]
  392. mov %g1,%i0
  393. {$else not FPC_PIC}
  394. ld [%o0],%g1
  395. sub %g1,1,%g1
  396. st %g1,[%o0]
  397. mov %g1,%o0
  398. {$endif FPC_PIC}
  399. { unlock }
  400. sethi %hi(fpc_system_lock), %g1
  401. or %g1,%lo(fpc_system_lock), %g1
  402. {$ifdef FPC_PIC}
  403. ld [%g1+%l7],%g1
  404. {$endif FPC_PIC}
  405. stb %g0,[%g1]
  406. end;
  407. {$ifdef VER3_2}
  408. function InterLockedIncrement (var Target: longint) : longint; assembler;
  409. {$else VER3_2}
  410. {$define FPC_SYSTEM_HAS_ATOMIC_INC_32}
  411. function fpc_atomic_inc_32 (var Target: longint) : longint; assembler;
  412. {$endif VER3_2}
  413. {$ifndef FPC_PIC}nostackframe;{$endif}
  414. asm
  415. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  416. worse the effort, especially while waiting :)
  417. }
  418. {$ifdef FPC_PIC}
  419. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  420. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  421. call get_got
  422. nop
  423. {$endif FPC_PIC}
  424. .LInterLockedIncrement1:
  425. sethi %hi(fpc_system_lock), %g1
  426. or %g1,%lo(fpc_system_lock), %g1
  427. {$ifdef FPC_PIC}
  428. ld [%g1+%l7],%g1
  429. {$endif FPC_PIC}
  430. ldstub [%g1],%g1
  431. cmp %g1,0
  432. bne .LInterLockedIncrement1
  433. nop
  434. {$ifdef FPC_PIC}
  435. ld [%i0],%g1
  436. add %g1,1,%g1
  437. st %g1,[%i0]
  438. mov %g1,%i0
  439. {$else not FPC_PIC}
  440. ld [%o0],%g1
  441. add %g1,1,%g1
  442. st %g1,[%o0]
  443. mov %g1,%o0
  444. {$endif FPC_PIC}
  445. { unlock }
  446. sethi %hi(fpc_system_lock), %g1
  447. or %g1,%lo(fpc_system_lock), %g1
  448. {$ifdef FPC_PIC}
  449. ld [%g1+%l7],%g1
  450. {$endif FPC_PIC}
  451. stb %g0,[%g1]
  452. end;
  453. {$ifdef VER3_2}
  454. function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler;
  455. {$else VER3_2}
  456. {$define FPC_SYSTEM_HAS_ATOMIC_XCHG_32}
  457. function fpc_atomic_xchg_32 (var Target: longint;Source : longint) : longint; assembler;
  458. {$endif VER3_2}
  459. {$ifndef FPC_PIC}nostackframe;{$endif}
  460. asm
  461. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  462. worse the effort, especially while waiting :)
  463. }
  464. {$ifdef FPC_PIC}
  465. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  466. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  467. call get_got
  468. nop
  469. {$endif FPC_PIC}
  470. .LInterLockedExchange1:
  471. sethi %hi(fpc_system_lock), %g1
  472. or %g1,%lo(fpc_system_lock), %g1
  473. {$ifdef FPC_PIC}
  474. ld [%g1+%l7],%g1
  475. {$endif FPC_PIC}
  476. ldstub [%g1],%g1
  477. cmp %g1,0
  478. bne .LInterLockedExchange1
  479. nop
  480. {$ifdef FPC_PIC}
  481. ld [%i0],%g1
  482. st %i1,[%i0]
  483. mov %g1,%i0
  484. {$else not FPC_PIC}
  485. ld [%o0],%g1
  486. st %o1,[%o0]
  487. mov %g1,%o0
  488. {$endif FPC_PIC}
  489. { unlock }
  490. sethi %hi(fpc_system_lock), %g1
  491. or %g1,%lo(fpc_system_lock), %g1
  492. {$ifdef FPC_PIC}
  493. ld [%g1+%l7],%g1
  494. {$endif FPC_PIC}
  495. stb %g0,[%g1]
  496. end;
  497. {$ifdef VER3_2}
  498. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler;
  499. {$else VER3_2}
  500. {$define FPC_SYSTEM_HAS_ATOMIC_ADD_32}
  501. function fpc_atomic_add_32 (var Target: longint;Value : longint) : longint; assembler;
  502. {$endif VER3_2}
  503. {$ifndef FPC_PIC}nostackframe;{$endif}
  504. asm
  505. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  506. worse the effort, especially while waiting :)
  507. }
  508. {$ifdef FPC_PIC}
  509. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  510. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  511. call get_got
  512. nop
  513. {$endif FPC_PIC}
  514. .LInterLockedExchangeAdd1:
  515. sethi %hi(fpc_system_lock), %g1
  516. or %g1,%lo(fpc_system_lock), %g1
  517. {$ifdef FPC_PIC}
  518. ld [%g1+%l7],%g1
  519. {$endif FPC_PIC}
  520. ldstub [%g1],%g1
  521. cmp %g1,0
  522. bne .LInterLockedExchangeAdd1
  523. nop
  524. {$ifdef FPC_PIC}
  525. ld [%i0],%g1
  526. add %g1,%i1,%i1
  527. st %i1,[%i0]
  528. mov %g1,%i0
  529. {$else not FPC_PIC}
  530. ld [%o0],%g1
  531. add %g1,%o1,%o1
  532. st %o1,[%o0]
  533. mov %g1,%o0
  534. {$endif FPC_PIC}
  535. { unlock }
  536. sethi %hi(fpc_system_lock), %g1
  537. or %g1,%lo(fpc_system_lock), %g1
  538. {$ifdef FPC_PIC}
  539. ld [%g1+%l7],%g1
  540. {$endif FPC_PIC}
  541. stb %g0,[%g1]
  542. end;
  543. {$ifdef VER3_2}
  544. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler;
  545. {$else VER3_2}
  546. {$define FPC_SYSTEM_HAS_ATOMIC_XCHG_32}
  547. function fpc_atomic_xchg_32 (var Target: longint; NewValue: longint; Comparand: longint) : longint; [public,alias:'FPC_ATOMIC_CMP_XCHG_32']; assembler;
  548. {$endif VER3_2}
  549. {$ifndef FPC_PIC}nostackframe;{$endif}
  550. asm
  551. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  552. worse the effort, especially while waiting :)
  553. }
  554. { input: address of target in o0, newvalue in o1, comparand in o2 }
  555. { output: value stored in target before entry of the function }
  556. { side-effect: NewValue stored in target if (target = comparand) }
  557. {$ifdef FPC_PIC}
  558. sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
  559. or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
  560. call get_got
  561. nop
  562. {$endif FPC_PIC}
  563. .LInterlockedCompareExchange1:
  564. sethi %hi(fpc_system_lock), %g1
  565. or %g1,%lo(fpc_system_lock), %g1
  566. {$ifdef FPC_PIC}
  567. ld [%g1+%l7],%g1
  568. {$endif FPC_PIC}
  569. ldstub [%g1],%g1
  570. cmp %g1,0
  571. bne .LInterlockedCompareExchange1
  572. nop
  573. {$ifdef FPC_PIC}
  574. ld [%i0],%g1
  575. cmp %g1,%i2
  576. bne .LInterlockedCompareExchange2
  577. nop
  578. st %i1,[%i0]
  579. .LInterlockedCompareExchange2:
  580. mov %g1,%i0
  581. {$else not FPC_PIC}
  582. ld [%o0],%g1
  583. cmp %g1,%o2
  584. bne .LInterlockedCompareExchange2
  585. nop
  586. st %o1,[%o0]
  587. .LInterlockedCompareExchange2:
  588. mov %g1,%o0
  589. {$endif FPC_PIC}
  590. { unlock }
  591. sethi %hi(fpc_system_lock), %g1
  592. or %g1,%lo(fpc_system_lock), %g1
  593. {$ifdef FPC_PIC}
  594. ld [%g1+%l7],%g1
  595. {$endif FPC_PIC}
  596. stb %g0,[%g1]
  597. end;
  598. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  599. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  600. const
  601. LoadLoad = $01;
  602. StoreLoad = $02;
  603. LoadStore = $04;
  604. StoreStore = $08;
  605. LookAside = $10;
  606. MemIssue = $20;
  607. Sync = $40;
  608. {$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
  609. {$define CPUSPARC_HAS_MEMBAR}
  610. {$endif}
  611. procedure ReadBarrier;assembler;nostackframe;
  612. asm
  613. {$ifdef CPUSPARC_HAS_MEMBAR}
  614. ba,pt .L1
  615. membar LoadLoad
  616. .L1:
  617. {$endif}
  618. end;
  619. procedure ReadDependencyBarrier;
  620. begin
  621. { reads imply barrier on earlier reads depended on }
  622. end;
  623. procedure ReadWriteBarrier;assembler;nostackframe;
  624. asm
  625. {$ifdef CPUSPARC_HAS_MEMBAR}
  626. ba,pt .L1
  627. membar LoadLoad + LoadStore + StoreLoad + StoreStore
  628. .L1:
  629. {$endif}
  630. end;
  631. procedure WriteBarrier;assembler;nostackframe;
  632. asm
  633. {$ifdef CPUSPARC_HAS_MEMBAR}
  634. ba,pt .L1
  635. stbar
  636. .L1:
  637. {$endif}
  638. end;
  639. {$endif}
  640. {$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
  641. {$define FPC_SYSTEM_HAS_SAR_QWORD}
  642. function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
  643. asm
  644. { %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
  645. and %o2,63,%o2
  646. subcc %o2,32,%g0
  647. bcc .L1
  648. nop
  649. srl %o1,%o2,%o1
  650. subcc %o2,%g0,%g0
  651. be .Lexit
  652. sra %o0,%o2,%o0
  653. sub %g0,%o2,%o3
  654. sll %o0,%o3,%o3
  655. ba .Lexit
  656. or %o3,%o1,%o1
  657. .L1:
  658. sra %o0,%o2,%o1
  659. sra %o0,31,%o0
  660. .Lexit:
  661. end;
  662. {$endif FPC_SYSTEM_HAS_SAR_QWORD}