2
0

math.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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. cp R24, R1
  80. cpc R25, R1
  81. {$endif CPUAVR_16_REGS}
  82. brne .LNonZero
  83. {$ifdef CPUAVR_HAS_JMP_CALL}
  84. call fpc_divbyzero
  85. .LNonZero:
  86. call fpc_divmod_word
  87. {$else CPUAVR_HAS_JMP_CALL}
  88. rcall fpc_divbyzero
  89. .LNonZero:
  90. rcall fpc_divmod_word
  91. {$endif CPUAVR_HAS_JMP_CALL}
  92. {$if not(defined(CPUAVR_HAS_MOVW))}
  93. mov R24, R20
  94. mov R25, R21
  95. {$else CPUAVR_16_REGS}
  96. movw R24, R22
  97. {$endif CPUAVR_16_REGS}
  98. end;
  99. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  100. {$ifdef FPC_IS_SYSTEM}
  101. function fpc_div_word(n, z: word): word; external name 'FPC_DIV_WORD';
  102. {$endif FPC_IS_SYSTEM}
  103. {$endif FPC_SYSTEM_HAS_DIV_WORD}
  104. {$ifndef FPC_SYSTEM_HAS_MOD_WORD}
  105. {$define FPC_SYSTEM_HAS_MOD_WORD}
  106. // z in Ra, n in Rb, 0 in Rp
  107. function fpc_mod_word(n, z: word): word; assembler; nostackframe;
  108. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_WORD'];{$endif}
  109. asm
  110. {$ifdef CPUAVR_16_REGS}
  111. cp R24, R17
  112. cpc R25, R17
  113. {$else CPUAVR_16_REGS}
  114. cp R24, R1
  115. cpc R25, R1
  116. {$endif CPUAVR_16_REGS}
  117. brne .LNonZero
  118. {$ifdef CPUAVR_HAS_JMP_CALL}
  119. call fpc_divbyzero
  120. .LNonZero:
  121. call fpc_divmod_word
  122. {$else CPUAVR_HAS_JMP_CALL}
  123. rcall fpc_divbyzero
  124. .LNonZero:
  125. rcall fpc_divmod_word
  126. {$endif CPUAVR_HAS_JMP_CALL}
  127. {$if not(defined(CPUAVR_HAS_MOVW))}
  128. mov R24, R20
  129. mov R25, R21
  130. {$else not(defined(CPUAVR_HAS_MOVW))}
  131. movw R24, R20
  132. {$endif not(defined(CPUAVR_HAS_MOVW))}
  133. end;
  134. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  135. {$ifdef FPC_IS_SYSTEM}
  136. function fpc_mod_word(n, z: word): word; external name 'FPC_MOD_WORD';
  137. {$endif FPC_IS_SYSTEM}
  138. {$endif FPC_SYSTEM_HAS_MOD_WORD}
  139. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  140. {$define FPC_SYSTEM_HAS_DIV_DWORD}
  141. // z in Ra, n in Rb, 0 in Rp
  142. function fpc_div_dword(n, z: dword): dword; assembler; nostackframe;
  143. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_DWORD'];{$endif}
  144. asm
  145. {$ifdef CPUAVR_16_REGS}
  146. cp R24, R17
  147. cpc R25, R17
  148. cpc R22, R17
  149. cpc R23, R17
  150. {$else CPUAVR_16_REGS}
  151. cp R24, R1
  152. cpc R25, R1
  153. cpc R22, R1
  154. cpc R23, R1
  155. {$endif CPUAVR_16_REGS}
  156. brne .LNonZero
  157. {$ifdef CPUAVR_HAS_JMP_CALL}
  158. call fpc_divbyzero
  159. .LNonZero:
  160. call fpc_divmod_dword
  161. {$else CPUAVR_HAS_JMP_CALL}
  162. rcall fpc_divbyzero
  163. .LNonZero:
  164. rcall fpc_divmod_dword
  165. {$endif CPUAVR_HAS_JMP_CALL}
  166. {$if not(defined(CPUAVR_HAS_MOVW))}
  167. mov R22, R18 // Move result from R18:R21 to R22:R25
  168. mov R23, R19 // Move result from R18:R21 to R22:R25
  169. mov R24, R20
  170. mov R25, R21
  171. {$else not(defined(CPUAVR_HAS_MOVW))}
  172. movw R22, R18 // Move result from R18:R21 to R22:R25
  173. movw R24, R20
  174. {$endif not(defined(CPUAVR_HAS_MOVW))}
  175. end;
  176. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  177. {$ifdef FPC_IS_SYSTEM}
  178. function fpc_div_dword(n, z: dword): dword; external name 'FPC_DIV_DWORD';
  179. {$endif FPC_IS_SYSTEM}
  180. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  181. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  182. {$define FPC_SYSTEM_HAS_MOD_DWORD}
  183. // z in Ra, n in Rb, 0 in Rp
  184. function fpc_mod_dword(n, z: dword): dword; assembler; nostackframe;
  185. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_DWORD'];{$endif}
  186. asm
  187. {$ifdef CPUAVR_16_REGS}
  188. cp R24, R17
  189. cpc R25, R17
  190. cpc R22, R17
  191. cpc R23, R17
  192. {$else CPUAVR_16_REGS}
  193. cp R24, R1
  194. cpc R25, R1
  195. cpc R22, R1
  196. cpc R23, R1
  197. {$endif CPUAVR_16_REGS}
  198. brne .LNonZero
  199. {$ifdef CPUAVR_HAS_JMP_CALL}
  200. call fpc_divbyzero
  201. .LNonZero:
  202. call fpc_divmod_dword
  203. {$else CPUAVR_HAS_JMP_CALL}
  204. rcall fpc_divbyzero
  205. .LNonZero:
  206. rcall fpc_divmod_dword
  207. {$endif CPUAVR_HAS_JMP_CALL}
  208. end;
  209. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  210. {$ifdef FPC_IS_SYSTEM}
  211. function fpc_mod_dword(n, z: dword): dword; external name 'FPC_MOD_DWORD';
  212. {$endif FPC_IS_SYSTEM}
  213. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  214. {$ifndef FPC_SYSTEM_HAS_BSF_BYTE}
  215. {$define FPC_SYSTEM_HAS_BSF_BYTE}
  216. function BsfByte(Const AValue: Byte): Byte;
  217. var
  218. i, value: byte;
  219. begin
  220. Value:=AValue;
  221. for i:=0 to 7 do
  222. begin
  223. if odd(Value) then
  224. exit(i);
  225. Value:=Value shr 1;
  226. end;
  227. result:=$FF;
  228. end;
  229. {$endif}
  230. {$ifndef FPC_SYSTEM_HAS_BSR_BYTE}
  231. {$define FPC_SYSTEM_HAS_BSR_BYTE}
  232. function BsrByte(Const AValue: Byte): Byte;
  233. var
  234. i, value: byte;
  235. begin
  236. Value:=AValue;
  237. for i:=0 to 7 do
  238. begin
  239. if (Value and $80)<>0 then
  240. exit(i);
  241. Value:=Value shl 1;
  242. end;
  243. result:=$FF;
  244. end;
  245. {$endif}