mipsel.inc 7.8 KB

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