math.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. cp R24, R1
  20. brne .LNonZero
  21. {$ifdef CPUAVR_HAS_JMP_CALL}
  22. call fpc_divbyzero
  23. .LNonZero:
  24. call fpc_divmod_byte
  25. {$else CPUAVR_HAS_JMP_CALL}
  26. rcall fpc_divbyzero
  27. .LNonZero:
  28. rcall fpc_divmod_byte
  29. {$endif CPUAVR_HAS_JMP_CALL}
  30. mov R24, R22
  31. end;
  32. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  33. {$ifdef FPC_IS_SYSTEM}
  34. function fpc_div_byte(n, z: byte): byte; external name 'FPC_DIV_BYTE';
  35. {$endif FPC_IS_SYSTEM}
  36. {$endif FPC_SYSTEM_HAS_DIV_BYTE}
  37. {$ifndef FPC_SYSTEM_HAS_MOD_BYTE}
  38. {$define FPC_SYSTEM_HAS_MOD_BYTE}
  39. // z in Ra, n in Rb, 0 in Rp
  40. function fpc_mod_byte(n, z: byte): byte; assembler; nostackframe;
  41. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_BYTE'];{$endif}
  42. asm
  43. cp R24, R1
  44. brne .LNonZero
  45. {$ifdef CPUAVR_HAS_JMP_CALL}
  46. call fpc_divbyzero
  47. .LNonZero:
  48. call fpc_divmod_byte
  49. {$else CPUAVR_HAS_JMP_CALL}
  50. rcall fpc_divbyzero
  51. .LNonZero:
  52. rcall fpc_divmod_byte
  53. {$endif CPUAVR_HAS_JMP_CALL}
  54. mov R24, R20
  55. end;
  56. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  57. {$ifdef FPC_IS_SYSTEM}
  58. function fpc_mod_byte(n, z: byte): byte; external name 'FPC_MOD_BYTE';
  59. {$endif FPC_IS_SYSTEM}
  60. {$endif FPC_SYSTEM_HAS_MOD_BYTE}
  61. {$ifndef FPC_SYSTEM_HAS_DIV_WORD}
  62. {$define FPC_SYSTEM_HAS_DIV_WORD}
  63. // z in Ra, n in Rb, 0 in Rp
  64. function fpc_div_word(n, z: word): word; assembler; nostackframe;
  65. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_WORD'];{$endif}
  66. asm
  67. cp R24, R1
  68. cpc R25, R1
  69. brne .LNonZero
  70. {$ifdef CPUAVR_HAS_JMP_CALL}
  71. call fpc_divbyzero
  72. .LNonZero:
  73. call fpc_divmod_word
  74. {$else CPUAVR_HAS_JMP_CALL}
  75. rcall fpc_divbyzero
  76. .LNonZero:
  77. rcall fpc_divmod_word
  78. {$endif CPUAVR_HAS_JMP_CALL}
  79. movw R24, R22
  80. end;
  81. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  82. {$ifdef FPC_IS_SYSTEM}
  83. function fpc_div_word(n, z: word): word; external name 'FPC_DIV_WORD';
  84. {$endif FPC_IS_SYSTEM}
  85. {$endif FPC_SYSTEM_HAS_DIV_WORD}
  86. {$ifndef FPC_SYSTEM_HAS_MOD_WORD}
  87. {$define FPC_SYSTEM_HAS_MOD_WORD}
  88. // z in Ra, n in Rb, 0 in Rp
  89. function fpc_mod_word(n, z: word): word; assembler; nostackframe;
  90. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_WORD'];{$endif}
  91. asm
  92. cp R24, R1
  93. cpc R25, R1
  94. brne .LNonZero
  95. {$ifdef CPUAVR_HAS_JMP_CALL}
  96. call fpc_divbyzero
  97. .LNonZero:
  98. call fpc_divmod_word
  99. {$else CPUAVR_HAS_JMP_CALL}
  100. rcall fpc_divbyzero
  101. .LNonZero:
  102. rcall fpc_divmod_word
  103. {$endif CPUAVR_HAS_JMP_CALL}
  104. movw R24, R20
  105. end;
  106. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  107. {$ifdef FPC_IS_SYSTEM}
  108. function fpc_mod_word(n, z: word): word; external name 'FPC_MOD_WORD';
  109. {$endif FPC_IS_SYSTEM}
  110. {$endif FPC_SYSTEM_HAS_MOD_WORD}
  111. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  112. {$define FPC_SYSTEM_HAS_DIV_DWORD}
  113. // z in Ra, n in Rb, 0 in Rp
  114. function fpc_div_dword(n, z: dword): dword; assembler; nostackframe;
  115. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_DIV_DWORD'];{$endif}
  116. asm
  117. cp R24, R1
  118. cpc R25, R1
  119. cpc R22, R1
  120. cpc R23, R1
  121. brne .LNonZero
  122. {$ifdef CPUAVR_HAS_JMP_CALL}
  123. call fpc_divbyzero
  124. .LNonZero:
  125. call fpc_divmod_dword
  126. {$else CPUAVR_HAS_JMP_CALL}
  127. rcall fpc_divbyzero
  128. .LNonZero:
  129. rcall fpc_divmod_dword
  130. {$endif CPUAVR_HAS_JMP_CALL}
  131. movw R22, R18 // Move result from R18:R21 to R22:R25
  132. movw R24, R20
  133. end;
  134. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  135. {$ifdef FPC_IS_SYSTEM}
  136. function fpc_div_dword(n, z: dword): dword; external name 'FPC_DIV_DWORD';
  137. {$endif FPC_IS_SYSTEM}
  138. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  139. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  140. {$define FPC_SYSTEM_HAS_MOD_DWORD}
  141. // z in Ra, n in Rb, 0 in Rp
  142. function fpc_mod_dword(n, z: dword): dword; assembler; nostackframe;
  143. {$ifdef FPC_IS_SYSTEM}[public,alias: 'FPC_MOD_DWORD'];{$endif}
  144. asm
  145. cp R24, R1
  146. cpc R25, R1
  147. cpc R22, R1
  148. cpc R23, R1
  149. brne .LNonZero
  150. {$ifdef CPUAVR_HAS_JMP_CALL}
  151. call fpc_divbyzero
  152. .LNonZero:
  153. call fpc_divmod_dword
  154. {$else CPUAVR_HAS_JMP_CALL}
  155. rcall fpc_divbyzero
  156. .LNonZero:
  157. rcall fpc_divmod_dword
  158. {$endif CPUAVR_HAS_JMP_CALL}
  159. end;
  160. {It is a compilerproc (systemh.inc), make an alias for internal use.}
  161. {$ifdef FPC_IS_SYSTEM}
  162. function fpc_mod_dword(n, z: dword): dword; external name 'FPC_MOD_DWORD';
  163. {$endif FPC_IS_SYSTEM}
  164. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  165. {$ifndef FPC_SYSTEM_HAS_BSF_BYTE}
  166. {$define FPC_SYSTEM_HAS_BSF_BYTE}
  167. function BsfByte(Const AValue: Byte): Byte;
  168. var
  169. i, value: byte;
  170. begin
  171. Value:=AValue;
  172. for i:=0 to 7 do
  173. begin
  174. if odd(Value) then
  175. exit(i);
  176. Value:=Value shr 1;
  177. end;
  178. result:=$FF;
  179. end;
  180. {$endif}
  181. {$ifndef FPC_SYSTEM_HAS_BSR_BYTE}
  182. {$define FPC_SYSTEM_HAS_BSR_BYTE}
  183. function BsrByte(Const AValue: Byte): Byte;
  184. var
  185. i, value: byte;
  186. begin
  187. Value:=AValue;
  188. for i:=0 to 7 do
  189. begin
  190. if (Value and $80)<>0 then
  191. exit(i);
  192. Value:=Value shl 1;
  193. end;
  194. result:=$FF;
  195. end;
  196. {$endif}