math.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2008 by the Free Pascal development team.
  4. Implementation of mathematical Routines (only for real)
  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. {$i divide.inc}
  12. {$ifndef FPC_SYSTEM_HAS_DIV_BYTE}
  13. {$define FPC_SYSTEM_HAS_DIV_BYTE}
  14. // z (dividend) = q(quotient) x n(divisor) + p(remainder)
  15. // z in Ra, n in Rb, 0 in Rp
  16. function fpc_div_byte(n, z: byte): byte; assembler; nostackframe;
  17. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_BYTE'];{$endif}
  18. asm
  19. {$ifdef CPUAVR_16_REGS}
  20. cp R24, R17
  21. {$else CPUAVR_16_REGS}
  22. cp R24, R1
  23. {$endif CPUAVR_16_REGS}
  24. brne .LNonZero
  25. {$ifdef CPUAVR_HAS_JMP_CALL}
  26. call fpc_divbyzero
  27. .LNonZero:
  28. call fpc_divmod_byte
  29. {$else CPUAVR_HAS_JMP_CALL}
  30. rcall fpc_divbyzero
  31. .LNonZero:
  32. rcall fpc_divmod_byte
  33. {$endif CPUAVR_HAS_JMP_CALL}
  34. mov R24, R22
  35. end;
  36. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  37. {$ifdef FPC_IS_SYSTEM}
  38. function fpc_div_byte(n, z: byte): byte; external name 'FPC_DIV_BYTE';
  39. {$endif FPC_IS_SYSTEM}
  40. {$endif FPC_SYSTEM_HAS_DIV_BYTE}
  41. {$ifndef FPC_SYSTEM_HAS_MOD_BYTE}
  42. {$define FPC_SYSTEM_HAS_MOD_BYTE}
  43. // z in Ra, n in Rb, 0 in Rp
  44. function fpc_mod_byte(n, z: byte): byte; assembler; nostackframe;
  45. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_BYTE'];{$endif}
  46. asm
  47. {$ifdef CPUAVR_16_REGS}
  48. cp R24, R17
  49. {$else CPUAVR_16_REGS}
  50. cp R24, R1
  51. {$endif CPUAVR_16_REGS}
  52. brne .LNonZero
  53. {$ifdef CPUAVR_HAS_JMP_CALL}
  54. call fpc_divbyzero
  55. .LNonZero:
  56. call fpc_divmod_byte
  57. {$else CPUAVR_HAS_JMP_CALL}
  58. rcall fpc_divbyzero
  59. .LNonZero:
  60. rcall fpc_divmod_byte
  61. {$endif CPUAVR_HAS_JMP_CALL}
  62. mov R24, R20
  63. end;
  64. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  65. {$ifdef FPC_IS_SYSTEM}
  66. function fpc_mod_byte(n, z: byte): byte; external name 'FPC_MOD_BYTE';
  67. {$endif FPC_IS_SYSTEM}
  68. {$endif FPC_SYSTEM_HAS_MOD_BYTE}
  69. {$ifndef FPC_SYSTEM_HAS_DIV_WORD}
  70. {$define FPC_SYSTEM_HAS_DIV_WORD}
  71. // z in Ra, n in Rb, 0 in Rp
  72. function fpc_div_word(n, z: word): word; assembler; nostackframe;
  73. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_WORD'];{$endif}
  74. asm
  75. {$ifdef CPUAVR_16_REGS}
  76. cp R24, R17
  77. cpc R25, R17
  78. {$else CPUAVR_16_REGS}
  79. {$ifdef CPUAVR_HAS_ADIW}
  80. sbiw R24,0
  81. {$else CPUAVR_HAS_ADIW}
  82. cp R24, R1
  83. cpc R25, R1
  84. {$endif CPUAVR_HAS_ADIW}
  85. {$endif CPUAVR_16_REGS}
  86. brne .LNonZero
  87. {$ifdef CPUAVR_HAS_JMP_CALL}
  88. call fpc_divbyzero
  89. .LNonZero:
  90. call fpc_divmod_word
  91. {$else CPUAVR_HAS_JMP_CALL}
  92. rcall fpc_divbyzero
  93. .LNonZero:
  94. rcall fpc_divmod_word
  95. {$endif CPUAVR_HAS_JMP_CALL}
  96. {$if not(defined(CPUAVR_HAS_MOVW))}
  97. mov R24, R20
  98. mov R25, R21
  99. {$else CPUAVR_16_REGS}
  100. movw R24, R22
  101. {$endif CPUAVR_16_REGS}
  102. end;
  103. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  104. {$ifdef FPC_IS_SYSTEM}
  105. function fpc_div_word(n, z: word): word; external name 'FPC_DIV_WORD';
  106. {$endif FPC_IS_SYSTEM}
  107. {$endif FPC_SYSTEM_HAS_DIV_WORD}
  108. {$ifndef FPC_SYSTEM_HAS_MOD_WORD}
  109. {$define FPC_SYSTEM_HAS_MOD_WORD}
  110. // z in Ra, n in Rb, 0 in Rp
  111. function fpc_mod_word(n, z: word): word; assembler; nostackframe;
  112. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_WORD'];{$endif}
  113. asm
  114. {$ifdef CPUAVR_16_REGS}
  115. cp R24, R17
  116. cpc R25, R17
  117. {$else CPUAVR_16_REGS}
  118. {$ifdef CPUAVR_HAS_ADIW}
  119. sbiw R24,0
  120. {$else CPUAVR_HAS_ADIW}
  121. cp R24, R1
  122. cpc R25, R1
  123. {$endif CPUAVR_HAS_ADIW}
  124. {$endif CPUAVR_16_REGS}
  125. brne .LNonZero
  126. {$ifdef CPUAVR_HAS_JMP_CALL}
  127. call fpc_divbyzero
  128. .LNonZero:
  129. call fpc_divmod_word
  130. {$else CPUAVR_HAS_JMP_CALL}
  131. rcall fpc_divbyzero
  132. .LNonZero:
  133. rcall fpc_divmod_word
  134. {$endif CPUAVR_HAS_JMP_CALL}
  135. {$if not(defined(CPUAVR_HAS_MOVW))}
  136. mov R24, R20
  137. mov R25, R21
  138. {$else not(defined(CPUAVR_HAS_MOVW))}
  139. movw R24, R20
  140. {$endif not(defined(CPUAVR_HAS_MOVW))}
  141. end;
  142. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  143. {$ifdef FPC_IS_SYSTEM}
  144. function fpc_mod_word(n, z: word): word; external name 'FPC_MOD_WORD';
  145. {$endif FPC_IS_SYSTEM}
  146. {$endif FPC_SYSTEM_HAS_MOD_WORD}
  147. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  148. {$define FPC_SYSTEM_HAS_DIV_DWORD}
  149. // z in Ra, n in Rb, 0 in Rp
  150. function fpc_div_dword(n, z: dword): dword; assembler; nostackframe;
  151. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_DWORD'];{$endif}
  152. asm
  153. {$ifdef CPUAVR_16_REGS}
  154. cp R24, R17
  155. cpc R25, R17
  156. cpc R22, R17
  157. cpc R23, R17
  158. {$else CPUAVR_16_REGS}
  159. cp R24, R1
  160. cpc R25, R1
  161. cpc R22, R1
  162. cpc R23, R1
  163. {$endif CPUAVR_16_REGS}
  164. brne .LNonZero
  165. {$ifdef CPUAVR_HAS_JMP_CALL}
  166. call fpc_divbyzero
  167. .LNonZero:
  168. call fpc_divmod_dword
  169. {$else CPUAVR_HAS_JMP_CALL}
  170. rcall fpc_divbyzero
  171. .LNonZero:
  172. rcall fpc_divmod_dword
  173. {$endif CPUAVR_HAS_JMP_CALL}
  174. {$if not(defined(CPUAVR_HAS_MOVW))}
  175. mov R22, R18 // Move result from R18:R21 to R22:R25
  176. mov R23, R19 // Move result from R18:R21 to R22:R25
  177. mov R24, R20
  178. mov R25, R21
  179. {$else not(defined(CPUAVR_HAS_MOVW))}
  180. movw R22, R18 // Move result from R18:R21 to R22:R25
  181. movw R24, R20
  182. {$endif not(defined(CPUAVR_HAS_MOVW))}
  183. end;
  184. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  185. {$ifdef FPC_IS_SYSTEM}
  186. function fpc_div_dword(n, z: dword): dword; external name 'FPC_DIV_DWORD';
  187. {$endif FPC_IS_SYSTEM}
  188. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  189. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  190. {$define FPC_SYSTEM_HAS_MOD_DWORD}
  191. // z in Ra, n in Rb, 0 in Rp
  192. function fpc_mod_dword(n, z: dword): dword; assembler; nostackframe;
  193. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_DWORD'];{$endif}
  194. asm
  195. {$ifdef CPUAVR_16_REGS}
  196. cp R24, R17
  197. cpc R25, R17
  198. cpc R22, R17
  199. cpc R23, R17
  200. {$else CPUAVR_16_REGS}
  201. cp R24, R1
  202. cpc R25, R1
  203. cpc R22, R1
  204. cpc R23, R1
  205. {$endif CPUAVR_16_REGS}
  206. brne .LNonZero
  207. {$ifdef CPUAVR_HAS_JMP_CALL}
  208. call fpc_divbyzero
  209. .LNonZero:
  210. call fpc_divmod_dword
  211. {$else CPUAVR_HAS_JMP_CALL}
  212. rcall fpc_divbyzero
  213. .LNonZero:
  214. rcall fpc_divmod_dword
  215. {$endif CPUAVR_HAS_JMP_CALL}
  216. end;
  217. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  218. {$ifdef FPC_IS_SYSTEM}
  219. function fpc_mod_dword(n, z: dword): dword; external name 'FPC_MOD_DWORD';
  220. {$endif FPC_IS_SYSTEM}
  221. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  222. {$ifndef FPC_SYSTEM_HAS_BSF_BYTE}
  223. {$define FPC_SYSTEM_HAS_BSF_BYTE}
  224. function BsfByte(Const AValue: Byte): Byte;
  225. var
  226. i, value: byte;
  227. begin
  228. Value:=AValue;
  229. for i:=0 to 7 do
  230. begin
  231. if odd(Value) then
  232. exit(i);
  233. Value:=Value shr 1;
  234. end;
  235. result:=$FF;
  236. end;
  237. {$endif}
  238. {$ifndef FPC_SYSTEM_HAS_BSR_BYTE}
  239. {$define FPC_SYSTEM_HAS_BSR_BYTE}
  240. function BsrByte(Const AValue: Byte): Byte;
  241. var
  242. i, value: byte;
  243. begin
  244. Value:=AValue;
  245. for i:=0 to 7 do
  246. begin
  247. if (Value and $80)<>0 then
  248. exit(i);
  249. Value:=Value shl 1;
  250. end;
  251. result:=$FF;
  252. end;
  253. {$endif}