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);[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_overflow,float_flag_underflow,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. flushw
  66. ldx [%o0+STACK_BIAS+120],%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. flushw
  84. ldx [%o0+STACK_BIAS+112],%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:{$ifdef MOVE_HAS_SIZEUINT_COUNT}SizeUInt{$else}SizeInt{$endif});[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;nostackframe;
  279. asm
  280. .Ldeclocked1:
  281. ld [%o0],%g4
  282. sub %g4,1,%g1
  283. cas [%o0],%g4,%g1
  284. cmp %g4,%g1
  285. bne .Ldeclocked1
  286. sub %g1,1,%g1
  287. movrz %g1,1,%o0
  288. movrnz %g1,0,%o0
  289. end;
  290. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  291. procedure inclocked(var l : longint);assembler;nostackframe;
  292. asm
  293. .Linclocked1:
  294. ld [%o0],%g4
  295. add %g4,1,%g1
  296. cas [%o0],%g4,%g1
  297. cmp %g4,%g1
  298. bne .Linclocked1
  299. nop
  300. end;
  301. function InterLockedDecrement (var Target: longint) : longint;assembler;nostackframe;
  302. asm
  303. .LInterLockedDecrement1:
  304. ld [%o0],%g4
  305. sub %g4,1,%g1
  306. cas [%o0],%g4,%g1
  307. cmp %g4,%g1
  308. bne .LInterLockedDecrement1
  309. nop
  310. sub %g1,1,%o0
  311. end;
  312. function InterLockedIncrement (var Target: longint) : longint;assembler;nostackframe;
  313. asm
  314. .LInterLockedIncrement1:
  315. ld [%o0],%g4
  316. add %g4,1,%g1
  317. cas [%o0],%g4,%g1
  318. cmp %g4,%g1
  319. bne .LInterLockedIncrement1
  320. nop
  321. add %g1,1,%o0
  322. end;
  323. function InterLockedExchange (var Target: longint;Source : longint) : longint;assembler;nostackframe;
  324. asm
  325. .LInterLockedExchange1:
  326. mov %o1,%g1
  327. ld [%o0],%g4
  328. cas [%o0],%g4,%g1
  329. cmp %g4,%g1
  330. bne .LInterLockedExchange1
  331. nop
  332. mov %g1,%o0
  333. end;
  334. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;assembler;nostackframe;
  335. asm
  336. .LInterLockedExchangeAdd1:
  337. ld [%o0],%g4
  338. add %g4,%o1,%g1
  339. cas [%o0],%g4,%g1
  340. cmp %g4,%g1
  341. bne .LInterLockedExchangeAdd1
  342. nop
  343. mov %g1,%o0
  344. end;
  345. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;nostackframe;
  346. asm
  347. cas [%o0],%o2,%o1
  348. mov %o1,%o0
  349. end;
  350. function InterLockedDecrement64(var Target: Int64) : Int64;assembler;nostackframe;
  351. asm
  352. .LInterLockedDecrement641:
  353. ldx [%o0],%g4
  354. sub %g4,1,%g1
  355. casx [%o0],%g4,%g1
  356. cmp %g4,%g1
  357. bne %xcc,.LInterLockedDecrement641
  358. nop
  359. sub %g1,1,%o0
  360. end;
  361. function InterLockedIncrement64(var Target: Int64) : Int64;assembler;nostackframe;
  362. asm
  363. .LInterLockedIncrement641:
  364. ldx [%o0],%g4
  365. add %g4,1,%g1
  366. casx [%o0],%g4,%g1
  367. cmp %g4,%g1
  368. bne %xcc,.LInterLockedIncrement641
  369. nop
  370. add %g1,1,%o0
  371. end;
  372. function InterLockedExchange64(var Target: Int64;Source : Int64) : Int64;assembler;nostackframe;
  373. asm
  374. .LInterLockedExchange641:
  375. mov %o1,%g1
  376. ldx [%o0],%g4
  377. casx [%o0],%g4,%g1
  378. cmp %g4,%g1
  379. bne %xcc,.LInterLockedExchange641
  380. nop
  381. mov %g1,%o0
  382. end;
  383. function InterLockedExchangeAdd64(var Target: Int64;Source : Int64) : Int64;assembler;nostackframe;
  384. asm
  385. .LInterLockedExchangeAdd641:
  386. ldx [%o0],%g4
  387. add %g4,%o1,%g1
  388. casx [%o0],%g4,%g1
  389. cmp %g4,%g1
  390. bne %xcc,.LInterLockedExchangeAdd641
  391. nop
  392. mov %g1,%o0
  393. end;
  394. function InterlockedCompareExchange64(var Target: Int64; NewValue: Int64; Comperand: Int64): Int64;assembler;nostackframe;
  395. asm
  396. casx [%o0],%o2,%o1
  397. mov %o1,%o0
  398. end;
  399. {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
  400. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  401. const
  402. LoadLoad = $01;
  403. StoreLoad = $02;
  404. LoadStore = $04;
  405. StoreStore = $08;
  406. LookAside = $10;
  407. MemIssue = $20;
  408. Sync = $40;
  409. {$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
  410. {$define CPUSPARC_HAS_MEMBAR}
  411. {$endif}
  412. procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  413. asm
  414. {$ifdef CPUSPARC_HAS_MEMBAR}
  415. ba,pt .L1
  416. membar LoadLoad
  417. .L1:
  418. {$endif}
  419. end;
  420. procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
  421. begin
  422. { reads imply barrier on earlier reads depended on }
  423. end;
  424. procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  425. asm
  426. {$ifdef CPUSPARC_HAS_MEMBAR}
  427. ba,pt .L1
  428. membar LoadLoad + LoadStore + StoreLoad + StoreStore
  429. .L1:
  430. {$endif}
  431. end;
  432. procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  433. asm
  434. {$ifdef CPUSPARC_HAS_MEMBAR}
  435. ba,pt .L1
  436. stbar
  437. .L1:
  438. {$endif}
  439. end;
  440. {$endif}
  441. {$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
  442. {$define FPC_SYSTEM_HAS_SAR_QWORD}
  443. function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
  444. asm
  445. { %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
  446. and %o2,63,%o2
  447. subcc %o2,32,%g0
  448. bcc .L1
  449. nop
  450. srl %o1,%o2,%o1
  451. subcc %o2,%g0,%g0
  452. be .Lexit
  453. sra %o0,%o2,%o0
  454. sub %g0,%o2,%o3
  455. sll %o0,%o3,%o3
  456. ba .Lexit
  457. or %o3,%o1,%o1
  458. .L1:
  459. sra %o0,%o2,%o1
  460. sra %o0,31,%o0
  461. .Lexit:
  462. end;
  463. {$endif FPC_SYSTEM_HAS_SAR_QWORD}