imulvc.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* imulvc.c Copyright (C) 1993-1996 Codemist Ltd */
  2. /* Signature: 60c250ae 23-Apr-1996 */
  3. /*
  4. * This code implements Imultiply and Idivide in 80386 (and up) assembly
  5. * code. I use the __stdcall calling convention.
  6. */
  7. #include "machine.h"
  8. #include "tags.h"
  9. #include "externs.h"
  10. #include "cslerror.h"
  11. #include "sys.h"
  12. /*
  13. * Get rid of unwanted warnings about lack of return values...
  14. */
  15. #pragma warning (disable : 4035)
  16. unsigned32 __stdcall Imultiply(unsigned32 *rlow,
  17. unsigned32 a, unsigned32 b, unsigned32 c)
  18. {
  19. /*
  20. * uns64 r = (uns64)a*(uns64)b + (uns64)c;
  21. * *rlow = (unsigned32)(r & 0x7fffffff);
  22. * return (unsigned32)(r >> 31);
  23. */
  24. __asm
  25. {
  26. mov eax, b
  27. mul a
  28. mov ecx, rlow
  29. add eax, c
  30. adc edx, 0 ; carry into top half
  31. add eax, eax
  32. adc edx, edx
  33. shr eax, 1
  34. mov DWORD PTR [ecx], eax
  35. mov eax, edx
  36. }
  37. }
  38. unsigned32 __stdcall Idiv10_9(unsigned32 *qp, unsigned32 high31, unsigned32 low31)
  39. {
  40. /*
  41. * uns64 p = ((uns64)high31 << 31) | (uns64)low31;
  42. * *qp = (unsigned32)(p / (uns64)1000000000U);
  43. * return (unsigned32)(p % (uns64)1000000000U);
  44. */
  45. __asm {
  46. mov edx, high31
  47. mov eax, low31
  48. shl eax, 1
  49. shr edx, 1
  50. rcr eax, 1 ; That glued together 31+31 bits
  51. mov ecx, 1000000000
  52. div ecx
  53. mov ecx, qp
  54. mov DWORD PTR [ecx], eax
  55. mov eax, edx
  56. }
  57. }
  58. unsigned32 __stdcall Idivide(unsigned32 *qp, unsigned32 a,
  59. unsigned32 b, unsigned32 c)
  60. {
  61. /*
  62. * uns64 p = ((uns64)a << 31) | (uns64)b;
  63. * *qp = (unsigned32)(p / (uns64)c);
  64. * return (unsigned32)(p % (uns64)c);
  65. */
  66. __asm {
  67. mov edx, a
  68. mov eax, b
  69. shl eax, 1
  70. shr edx, 1
  71. rcr eax, 1 ; That glued together 31+31 bits
  72. mov ecx, c
  73. div ecx
  74. mov ecx, qp
  75. mov DWORD PTR [ecx], eax
  76. mov eax, edx
  77. }
  78. }
  79. /* end of imulvc.c */