mipsel.inc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  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. {$ifndef FPC_SYSTEM_HAS_MOVE}
  64. {$define FPC_SYSTEM_HAS_MOVE}
  65. procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;
  66. asm
  67. {
  68. Registers:
  69. $7 temp. to do copying
  70. $8 inc/decrement
  71. $9/l0/l1/l2 qword move
  72. }
  73. sw $4,0($23)
  74. sw $5,-4($23)
  75. sw $6,-8($23)
  76. sw $7,-12($23)
  77. sw $8,-16($23)
  78. sw $9,-20($23)
  79. sw $10,-24($23)
  80. sw $11,-28($23)
  81. sw $12,-32($23)
  82. sw $13,-36($23)
  83. sw $14,-40($23)
  84. addiu $23,$23,-44
  85. # count <= 0 ?
  86. ble $6,$0,.Lmoveexit
  87. nop
  88. # source = dest ?
  89. beq $4,$5,.Lmoveexit
  90. nop
  91. # possible overlap?
  92. bgt $4,$5,.Lnopossibleoverlap
  93. nop
  94. # source < dest ....
  95. addu $7,$6,$4
  96. # overlap?
  97. # source+count < dest ?
  98. blt $7,$5,.Lnopossibleoverlap
  99. nop
  100. .Lcopybackward:
  101. # check alignment of source and dest
  102. or $2,$4,$5
  103. # move src and dest to the end of the blocks
  104. # assuming 16 byte block size
  105. addiu $3,$6,-1
  106. addu $4,$4,$3
  107. addu $5,$5,$3
  108. b .Lmovebytewise
  109. li $3,-1
  110. .Lnopossibleoverlap:
  111. # check alignment of source and dest
  112. or $2,$4,$5
  113. # everything 16 byte aligned ?
  114. andi $13,$2,15
  115. beq $13,$0,.Lmovetwordwise
  116. # load direction in delay slot
  117. li $3,16
  118. andi $13,$2,7
  119. beq $13,$0,.Lmoveqwordwise
  120. li $3,8
  121. andi $13,$2,3
  122. beq $13,$0,.Lmovedwordwise
  123. li $3,4
  124. andi $13,$2,1
  125. beq $13,$0,.Lmovewordwise
  126. li $3,2
  127. b .Lmovebytewise
  128. li $3,1
  129. .Lmovetwordwise:
  130. srl $13,$6,4
  131. sll $14,$13,4
  132. beq $14,$0,.Lmoveqwordwise_shift
  133. nop
  134. .Lmovetwordwise_loop:
  135. lw $9,0($4)
  136. lw $10,4($4)
  137. addiu $13,$13,-1
  138. lw $11,8($4)
  139. lw $12,12($4)
  140. addu $4,$4,$3
  141. sw $9,0($5)
  142. sw $10,4($5)
  143. sw $11,8($5)
  144. sw $12,12($5)
  145. addu $5,$5,$3
  146. bne $13,$0,.Lmovetwordwise_loop
  147. nop
  148. subu $6,$6,$14
  149. beq $6,$0,.Lmoveexit
  150. nop
  151. .Lmoveqwordwise_shift:
  152. sra $3,$3,1
  153. .Lmoveqwordwise:
  154. srl $13,$6,3
  155. sll $14,$13,3
  156. beq $14,$0,.Lmovedwordwise_shift
  157. nop
  158. .Lmoveqwordwise_loop:
  159. lw $9,0($4)
  160. lw $10,4($4)
  161. addiu $13,$13,-1
  162. addu $4,$3,$4
  163. sw $9,0($5)
  164. sw $10,4($5)
  165. addu $5,$3,$5
  166. bne $13,0,.Lmoveqwordwise_loop
  167. nop
  168. subu $6,$6,$14
  169. beq $6,$0,.Lmoveexit
  170. nop
  171. .Lmovedwordwise_shift:
  172. sra $3,$3,1
  173. .Lmovedwordwise:
  174. srl $13,$6,2
  175. sll $14,$13,2
  176. beq $14,$0,.Lmovewordwise_shift
  177. nop
  178. .Lmovedwordwise_loop:
  179. lw $9,0($4)
  180. addiu $13,$13,-1
  181. addu $4,$4,$3
  182. sw $9,0($5)
  183. addu $5,$5,$3
  184. bne $13,$0,.Lmovedwordwise_loop
  185. nop
  186. subu $6,$6,$14
  187. beq $6,$0,.Lmoveexit
  188. nop
  189. .Lmovewordwise_shift:
  190. sra $3,$3,1
  191. .Lmovewordwise:
  192. srl $13,$6,1
  193. sll $14,$13,1
  194. beq $14,$0, .Lmovebytewise_shift
  195. nop
  196. .Lmovewordwise_loop:
  197. lhu $9,0($4)
  198. addiu $13,$13,-1
  199. addu $4,$4,$3
  200. sh $9,0($5)
  201. addu $5,$5,$3
  202. bne $13,$0,.Lmovewordwise_loop
  203. nop
  204. subu $6,$6,$14
  205. beq $6,$0, .Lmoveexit
  206. nop
  207. .Lmovebytewise_shift:
  208. sra $3,$3,1
  209. .Lmovebytewise:
  210. beq $6,$0, .Lmoveexit
  211. nop
  212. lbu $9,0($4)
  213. addiu $6,$6,-1
  214. addu $4,$4,$3
  215. sb $9,0($5)
  216. addu $5,$5,$3
  217. bne $6,$0,.Lmovebytewise
  218. nop
  219. .Lmoveexit:
  220. addiu $23,$23,44
  221. lw $4,0($23)
  222. lw $5,-4($23)
  223. lw $6,-8($23)
  224. lw $7,-12($23)
  225. lw $8,-16($23)
  226. lw $9,-20($23)
  227. lw $10,-24($23)
  228. lw $11,-28($23)
  229. lw $12,-32($23)
  230. lw $13,-36($23)
  231. lw $14,-40($23)
  232. end;
  233. {$endif FPC_SYSTEM_HAS_MOVE}
  234. {****************************************************************************
  235. Integer math
  236. ****************************************************************************}
  237. {$define FPC_SYSTEM_HAS_ABS_LONGINT}
  238. function abs(l:longint):longint; assembler;{$ifdef SYSTEMINLINE}inline;{$endif}nostackframe;{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_abs];{$endif}
  239. asm
  240. sra $1,$4,31 #$at,$4,31
  241. xor $2,$4,$1 #$2,$4,$at
  242. sub $2,$2,$1 #$2,$2,$at
  243. end;
  244. var
  245. fpc_system_lock : longint; export name 'fpc_system_lock';
  246. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  247. function declocked(var l : longint) : boolean;assembler;nostackframe;
  248. { input: address of l in $4 }
  249. { output: boolean indicating whether l is zero after decrementing }
  250. asm
  251. sw $4,0($23)
  252. sw $5,-4($23)
  253. sw $6,-8($23)
  254. sw $7,-12($23)
  255. sw $8,-16($23)
  256. sw $9,-20($23)
  257. sw $10,-24($23)
  258. sw $11,-28($23)
  259. sw $12,-32($23)
  260. sw $13,-36($23)
  261. sw $14,-40($23)
  262. addiu $23,$23,-44
  263. .Ldeclocked1:
  264. lui $5,%hi(fpc_system_lock)
  265. addiu $5,$5,%lo(fpc_system_lock)
  266. ll $6,0($5)
  267. ori $7,$6,1
  268. beq $7,$6,.Ldeclocked1
  269. nop
  270. sc $7,0($5)
  271. beq $7,$0,.Ldeclocked1
  272. nop
  273. lw $5,0($4)
  274. addiu $5,$5,-1
  275. sw $5,0($4)
  276. seq $2,$5,$0
  277. { unlock }
  278. lui $5,%hi(fpc_system_lock)
  279. addiu $5,$5,%lo(fpc_system_lock)
  280. sw $0,0($5)
  281. addiu $23,$23,44
  282. lw $4,0($23)
  283. lw $5,-4($23)
  284. lw $6,-8($23)
  285. lw $7,-12($23)
  286. lw $8,-16($23)
  287. lw $9,-20($23)
  288. lw $10,-24($23)
  289. lw $11,-28($23)
  290. lw $12,-32($23)
  291. lw $13,-36($23)
  292. lw $14,-40($23)
  293. end;
  294. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  295. procedure inclocked(var l : longint);assembler;nostackframe;
  296. asm
  297. { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
  298. worse the effort, especially while waiting :)
  299. }
  300. { unlock }
  301. sw $4,0($23)
  302. sw $5,-4($23)
  303. sw $6,-8($23)
  304. sw $7,-12($23)
  305. sw $8,-16($23)
  306. sw $9,-20($23)
  307. sw $10,-24($23)
  308. sw $11,-28($23)
  309. sw $12,-32($23)
  310. sw $13,-36($23)
  311. sw $14,-40($23)
  312. addiu $23,$23,-44
  313. .Ldeclocked1:
  314. lui $5,%hi(fpc_system_lock)
  315. addiu $5,$5,%lo(fpc_system_lock)
  316. ll $6,0($5)
  317. ori $7,$6,1
  318. beq $7,$6,.Ldeclocked1
  319. nop
  320. sc $7,0($5)
  321. beq $7,$0,.Ldeclocked1
  322. nop
  323. lw $5,0($4)
  324. addiu $5,$5,1
  325. sw $5,0($4)
  326. { unlock }
  327. lui $5,%hi(fpc_system_lock)
  328. addiu $5,$5,%lo(fpc_system_lock)
  329. sw $0,0($5)
  330. addiu $23,$23,44
  331. lw $4,0($23)
  332. lw $5,-4($23)
  333. lw $6,-8($23)
  334. lw $7,-12($23)
  335. lw $8,-16($23)
  336. lw $9,-20($23)
  337. lw $10,-24($23)
  338. lw $11,-28($23)
  339. lw $12,-32($23)
  340. lw $13,-36($23)
  341. lw $14,-40($23)
  342. end;