mips.inc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2006-2007 by David Zhang
  4. Processor dependent implementation for the system unit for MIPS
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. MIPS specific stuff
  13. ****************************************************************************}
  14. function get_fsr : dword;assembler;nostackframe;[public, alias: 'FPC_GETFSR'];
  15. var
  16. fsr : dword;
  17. asm
  18. cfc1 $2,$31
  19. end;
  20. procedure set_fsr(fsr : dword);assembler;[public, alias: 'FPC_SETFSR'];
  21. var
  22. _fsr : dword;
  23. asm
  24. ctc1 $4,$31
  25. end;
  26. function get_got_z : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT_Z'];
  27. asm
  28. move $2,$28
  29. end;
  30. procedure fpc_cpuinit;
  31. var
  32. tmp32: longint;
  33. begin
  34. { don't let libraries influence the FPU cw set by the host program }
  35. if not IsLibrary then
  36. begin
  37. { enable div by 0 and invalid operation fpu exceptions }
  38. { round towards zero; ieee compliant arithmetics }
  39. tmp32 := get_fsr();
  40. set_fsr((tmp32 and $fffffffc) or $00000001);
  41. end;
  42. end;
  43. {$define FPC_SYSTEM_HAS_GET_FRAME}
  44. function get_frame:pointer;assembler;nostackframe;
  45. asm
  46. lw $2,0($sp)
  47. end;
  48. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  49. function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe;
  50. asm
  51. lw $2,4($4) // #movl 4(%eax),%eax
  52. end;
  53. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  54. function get_caller_frame(framebp:pointer):pointer;assembler;nostackframe;
  55. asm
  56. lw $2,0($4) // #movl (%eax),%eax
  57. end;
  58. {$define FPC_SYSTEM_HAS_SPTR}
  59. function Sptr:Pointer;assembler;nostackframe;
  60. asm
  61. move $2,$sp
  62. end;
  63. {$ifdef USE_MIPS_STK2_ASM}
  64. {$ifndef FPC_SYSTEM_HAS_MOVE}
  65. {$define FPC_SYSTEM_HAS_MOVE}
  66. procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;
  67. asm
  68. {
  69. Registers:
  70. $7 temp. to do copying
  71. $8 inc/decrement
  72. $9/l0/l1/l2 qword move
  73. }
  74. sw $4,0($23)
  75. sw $5,-4($23)
  76. sw $6,-8($23)
  77. sw $7,-12($23)
  78. sw $8,-16($23)
  79. sw $9,-20($23)
  80. sw $10,-24($23)
  81. sw $11,-28($23)
  82. sw $12,-32($23)
  83. sw $13,-36($23)
  84. sw $14,-40($23)
  85. addiu $23,$23,-44
  86. // count <= 0 ?
  87. ble $6,$0,.Lmoveexit
  88. nop
  89. // source = dest ?
  90. beq $4,$5,.Lmoveexit
  91. nop
  92. // possible overlap?
  93. bgt $4,$5,.Lnopossibleoverlap
  94. nop
  95. // source < dest ....
  96. addu $7,$6,$4
  97. // overlap?
  98. // source+count < dest ?
  99. blt $7,$5,.Lnopossibleoverlap
  100. nop
  101. .Lcopybackward:
  102. // check alignment of source and dest
  103. or $2,$4,$5
  104. // move src and dest to the end of the blocks
  105. // assuming 16 byte block size
  106. addiu $3,$6,-1
  107. addu $4,$4,$3
  108. addu $5,$5,$3
  109. b .Lmovebytewise
  110. li $3,-1
  111. .Lnopossibleoverlap:
  112. // check alignment of source and dest
  113. or $2,$4,$5
  114. // everything 16 byte aligned ?
  115. andi $13,$2,15
  116. beq $13,$0,.Lmovetwordwise
  117. // load direction in delay slot
  118. li $3,16
  119. andi $13,$2,7
  120. beq $13,$0,.Lmoveqwordwise
  121. li $3,8
  122. andi $13,$2,3
  123. beq $13,$0,.Lmovedwordwise
  124. li $3,4
  125. andi $13,$2,1
  126. beq $13,$0,.Lmovewordwise
  127. li $3,2
  128. b .Lmovebytewise
  129. li $3,1
  130. .Lmovetwordwise:
  131. srl $13,$6,4
  132. sll $14,$13,4
  133. beq $14,$0,.Lmoveqwordwise_shift
  134. nop
  135. .Lmovetwordwise_loop:
  136. lw $9,0($4)
  137. lw $10,4($4)
  138. addiu $13,$13,-1
  139. lw $11,8($4)
  140. lw $12,12($4)
  141. addu $4,$4,$3
  142. sw $9,0($5)
  143. sw $10,4($5)
  144. sw $11,8($5)
  145. sw $12,12($5)
  146. addu $5,$5,$3
  147. bne $13,$0,.Lmovetwordwise_loop
  148. nop
  149. subu $6,$6,$14
  150. beq $6,$0,.Lmoveexit
  151. nop
  152. .Lmoveqwordwise_shift:
  153. sra $3,$3,1
  154. .Lmoveqwordwise:
  155. srl $13,$6,3
  156. sll $14,$13,3
  157. beq $14,$0,.Lmovedwordwise_shift
  158. nop
  159. .Lmoveqwordwise_loop:
  160. lw $9,0($4)
  161. lw $10,4($4)
  162. addiu $13,$13,-1
  163. addu $4,$3,$4
  164. sw $9,0($5)
  165. sw $10,4($5)
  166. addu $5,$3,$5
  167. bne $13,$0,.Lmoveqwordwise_loop
  168. nop
  169. subu $6,$6,$14
  170. beq $6,$0,.Lmoveexit
  171. nop
  172. .Lmovedwordwise_shift:
  173. sra $3,$3,1
  174. .Lmovedwordwise:
  175. srl $13,$6,2
  176. sll $14,$13,2
  177. beq $14,$0,.Lmovewordwise_shift
  178. nop
  179. .Lmovedwordwise_loop:
  180. lw $9,0($4)
  181. addiu $13,$13,-1
  182. addu $4,$4,$3
  183. sw $9,0($5)
  184. addu $5,$5,$3
  185. bne $13,$0,.Lmovedwordwise_loop
  186. nop
  187. subu $6,$6,$14
  188. beq $6,$0,.Lmoveexit
  189. nop
  190. .Lmovewordwise_shift:
  191. sra $3,$3,1
  192. .Lmovewordwise:
  193. srl $13,$6,1
  194. sll $14,$13,1
  195. beq $14,$0, .Lmovebytewise_shift
  196. nop
  197. .Lmovewordwise_loop:
  198. lhu $9,0($4)
  199. addiu $13,$13,-1
  200. addu $4,$4,$3
  201. sh $9,0($5)
  202. addu $5,$5,$3
  203. bne $13,$0,.Lmovewordwise_loop
  204. nop
  205. subu $6,$6,$14
  206. beq $6,$0, .Lmoveexit
  207. nop
  208. .Lmovebytewise_shift:
  209. sra $3,$3,1
  210. .Lmovebytewise:
  211. beq $6,$0, .Lmoveexit
  212. nop
  213. lbu $9,0($4)
  214. addiu $6,$6,-1
  215. addu $4,$4,$3
  216. sb $9,0($5)
  217. addu $5,$5,$3
  218. bne $6,$0,.Lmovebytewise
  219. nop
  220. .Lmoveexit:
  221. addiu $23,$23,44
  222. lw $4,0($23)
  223. lw $5,-4($23)
  224. lw $6,-8($23)
  225. lw $7,-12($23)
  226. lw $8,-16($23)
  227. lw $9,-20($23)
  228. lw $10,-24($23)
  229. lw $11,-28($23)
  230. lw $12,-32($23)
  231. lw $13,-36($23)
  232. lw $14,-40($23)
  233. end;
  234. {$endif FPC_SYSTEM_HAS_MOVE}
  235. {****************************************************************************
  236. Integer math
  237. ****************************************************************************}
  238. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  239. function abs(l:longint):longint; assembler;{$ifdef SYSTEMINLINE}inline;{$endif}nostackframe;
  240. asm
  241. sra $1,$4,31 // $at,$4,31
  242. xor $2,$4,$1 // $2,$4,$at
  243. sub $2,$2,$1 // $2,$2,$at
  244. end;
  245. var
  246. fpc_system_lock : longint; export name 'fpc_system_lock';
  247. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  248. function declocked(var l : longint) : boolean;assembler;nostackframe;
  249. { input: address of l in $4 }
  250. { output: boolean indicating whether l is zero after decrementing }
  251. asm
  252. sw $4,0($23)
  253. sw $5,-4($23)
  254. sw $6,-8($23)
  255. sw $7,-12($23)
  256. sw $8,-16($23)
  257. sw $9,-20($23)
  258. sw $10,-24($23)
  259. sw $11,-28($23)
  260. sw $12,-32($23)
  261. sw $13,-36($23)
  262. sw $14,-40($23)
  263. addiu $23,$23,-44
  264. .Ldeclocked1:
  265. lui $5,%hi(fpc_system_lock)
  266. addiu $5,$5,%lo(fpc_system_lock)
  267. ll $6,0($5)
  268. ori $7,$6,1
  269. beq $7,$6,.Ldeclocked1
  270. nop
  271. sc $7,0($5)
  272. beq $7,$0,.Ldeclocked1
  273. nop
  274. lw $5,0($4)
  275. addiu $5,$5,-1
  276. sw $5,0($4)
  277. seq $2,$5,$0
  278. { unlock }
  279. lui $5,%hi(fpc_system_lock)
  280. addiu $5,$5,%lo(fpc_system_lock)
  281. sw $0,0($5)
  282. addiu $23,$23,44
  283. lw $4,0($23)
  284. lw $5,-4($23)
  285. lw $6,-8($23)
  286. lw $7,-12($23)
  287. lw $8,-16($23)
  288. lw $9,-20($23)
  289. lw $10,-24($23)
  290. lw $11,-28($23)
  291. lw $12,-32($23)
  292. lw $13,-36($23)
  293. lw $14,-40($23)
  294. end;
  295. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  296. procedure inclocked(var l : longint);assembler;nostackframe;
  297. asm
  298. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  299. worse the effort, especially while waiting :)
  300. }
  301. { unlock }
  302. sw $4,0($23)
  303. sw $5,-4($23)
  304. sw $6,-8($23)
  305. sw $7,-12($23)
  306. sw $8,-16($23)
  307. sw $9,-20($23)
  308. sw $10,-24($23)
  309. sw $11,-28($23)
  310. sw $12,-32($23)
  311. sw $13,-36($23)
  312. sw $14,-40($23)
  313. addiu $23,$23,-44
  314. .Ldeclocked1:
  315. lui $5,%hi(fpc_system_lock)
  316. addiu $5,$5,%lo(fpc_system_lock)
  317. ll $6,0($5)
  318. ori $7,$6,1
  319. beq $7,$6,.Ldeclocked1
  320. nop
  321. sc $7,0($5)
  322. beq $7,$0,.Ldeclocked1
  323. nop
  324. lw $5,0($4)
  325. addiu $5,$5,1
  326. sw $5,0($4)
  327. { unlock }
  328. lui $5,%hi(fpc_system_lock)
  329. addiu $5,$5,%lo(fpc_system_lock)
  330. sw $0,0($5)
  331. addiu $23,$23,44
  332. lw $4,0($23)
  333. lw $5,-4($23)
  334. lw $6,-8($23)
  335. lw $7,-12($23)
  336. lw $8,-16($23)
  337. lw $9,-20($23)
  338. lw $10,-24($23)
  339. lw $11,-28($23)
  340. lw $12,-32($23)
  341. lw $13,-36($23)
  342. lw $14,-40($23)
  343. end;
  344. {$endif def USE_MIPS_STK2_ASM}
  345. function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
  346. asm
  347. { FIXME!!!!!!!!! }
  348. end;
  349. function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
  350. asm
  351. { FIXME!!!!!!!!! }
  352. end;
  353. function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
  354. asm
  355. { FIXME!!!!!!!!! }
  356. end;
  357. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe;
  358. asm
  359. { FIXME!!!!!!!!! }
  360. end;
  361. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler; nostackframe;
  362. asm
  363. { FIXME!!!!!!!!! }
  364. end;