int64p.inc 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2006 by the Free Pascal development team
  4. This file contains some helper routines for int64 and qword
  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. {$ifndef FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64}
  12. {$define FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64}
  13. function fpc_mul_longint_to_int64(f1,f2 : longint) : int64;[public,alias: 'FPC_MUL_LONGINT_TO_INT64']; assembler; nostackframe; compilerproc;
  14. asm
  15. tst.l d0
  16. beq.s @xit0
  17. tst.l d1
  18. beq.s @xit0
  19. {$ifndef CPUCOLDFIRE}
  20. movem.l d2-d5,-(sp)
  21. {$else}
  22. lea -20(sp),sp
  23. movem.l d2-d6,(sp)
  24. {$endif}
  25. move.l d0,d5
  26. eor.l d1,d5
  27. move.l d0,d2
  28. bpl.s @pos0
  29. neg.l d2
  30. neg.l d0
  31. @pos0:
  32. move.l d1,d4
  33. bpl.s @pos1
  34. neg.l d4
  35. neg.l d1
  36. @pos1:
  37. move.l d0,d3
  38. swap d4
  39. swap d3
  40. mulu.w d1,d0
  41. mulu.w d3,d1
  42. mulu.w d4,d2
  43. mulu.w d4,d3
  44. {$ifdef CPUCOLDFIRE}
  45. { backup lo value of d0 }
  46. clr.l d6
  47. move.w d0,d6
  48. clr.w d0
  49. {$endif}
  50. swap d0
  51. clr.l d4
  52. {$ifndef CPUCOLDFIRE}
  53. add.w d1,d0
  54. addx.l d4,d3
  55. add.w d2,d0
  56. addx.l d4,d3
  57. {$else}
  58. { accumulate the carry bits of both add operations in d4 and add them at
  59. once to d3 }
  60. move.w d1,d4
  61. add.l d4,d0
  62. move.w d2,d4
  63. add.l d4,d0
  64. move.l d0,d4
  65. lsr.l #8,d4
  66. lsr.l #8,d4
  67. add.l d4,d3
  68. {$endif}
  69. clr.w d1
  70. clr.w d2
  71. swap d1
  72. swap d2
  73. add.l d3,d1
  74. swap d0
  75. {$ifdef CPUCOLDFIRE}
  76. { add original lo value of d0 }
  77. swap d6
  78. clr.w d6
  79. swap d6
  80. add.l d6,d0
  81. {$endif}
  82. add.l d2,d1
  83. tst.l d5
  84. bpl.s @xit
  85. neg.l d0
  86. negx.l d1
  87. @xit:
  88. {$ifndef CPUCOLDFIRE}
  89. movem.l (sp)+,d2-d5
  90. exg.l d0,d1
  91. {$else}
  92. move.l d0,d2
  93. move.l d1,d0
  94. move.l d2,d1
  95. movem.l (sp),d2-d6
  96. lea 20(sp),sp
  97. {$endif}
  98. rts
  99. @xit0:
  100. clr.l d0
  101. clr.l d1
  102. end;
  103. {$endif FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64}