reg_u_mul.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. .file "reg_u_mul.S"
  2. /*---------------------------------------------------------------------------+
  3.  |  reg_u_mul.S                                                              |
  4.  |                                                                           |
  5.  | Core multiplication routine                                               |
  6.  |                                                                           |
  7.  | Copyright (C) 1992,1993,1995,1997                                         |
  8.  |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
  9.  |                  E-mail   billm@suburbia.net                              |
  10.  |                                                                           |
  11.  |                                                                           |
  12.  +---------------------------------------------------------------------------*/
  13. /*---------------------------------------------------------------------------+
  14.  |   Basic multiplication routine.                                           |
  15.  |   Does not check the resulting exponent for overflow/underflow            |
  16.  |                                                                           |
  17.  |   FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw);         |
  18.  |                                                                           |
  19.  |   Internal working is at approx 128 bits.                                 |
  20.  |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
  21.  +---------------------------------------------------------------------------*/
  22. #include "exception.h"
  23. #include "fpu_emu.h"
  24. #include "control_w.h"
  25. #ifndef NON_REENTRANT_FPU
  26. /*  Local storage on the stack: */
  27. #define FPU_accum_0 -4(%ebp) /* ms word */
  28. #define FPU_accum_1 -8(%ebp)
  29. #else
  30. /*  Local storage in a static area: */
  31. .data
  32. .align 4,0
  33. FPU_accum_0:
  34. .long 0
  35. FPU_accum_1:
  36. .long 0
  37. #endif /* NON_REENTRANT_FPU */
  38. .text
  39. ENTRY(FPU_u_mul)
  40. pushl %ebp
  41. movl %esp,%ebp
  42. #ifndef NON_REENTRANT_FPU
  43. subl $8,%esp
  44. #endif /* NON_REENTRANT_FPU */ 
  45. pushl %esi
  46. pushl %edi
  47. pushl %ebx
  48. movl PARAM1,%esi
  49. movl PARAM2,%edi
  50. #ifdef PARANOID
  51. testl $0x80000000,SIGH(%esi)
  52. jz L_bugged
  53. testl $0x80000000,SIGH(%edi)
  54. jz L_bugged
  55. #endif /* PARANOID */
  56. xorl %ecx,%ecx
  57. xorl %ebx,%ebx
  58. movl SIGL(%esi),%eax
  59. mull SIGL(%edi)
  60. movl %eax,FPU_accum_0
  61. movl %edx,FPU_accum_1
  62. movl SIGL(%esi),%eax
  63. mull SIGH(%edi)
  64. addl %eax,FPU_accum_1
  65. adcl %edx,%ebx
  66. /* adcl $0,%ecx // overflow here is not possible */
  67. movl SIGH(%esi),%eax
  68. mull SIGL(%edi)
  69. addl %eax,FPU_accum_1
  70. adcl %edx,%ebx
  71. adcl $0,%ecx
  72. movl SIGH(%esi),%eax
  73. mull SIGH(%edi)
  74. addl %eax,%ebx
  75. adcl %edx,%ecx
  76. /* Get the sum of the exponents. */
  77. movl PARAM6,%eax
  78. subl EXP_BIAS-1,%eax
  79. /* Two denormals can cause an exponent underflow */
  80. cmpl EXP_WAY_UNDER,%eax
  81. jg Exp_not_underflow
  82. /* Set to a really low value allow correct handling */
  83. movl EXP_WAY_UNDER,%eax
  84. Exp_not_underflow:
  85. /*  Have now finished with the sources */
  86. movl PARAM3,%edi /* Point to the destination */
  87. movw %ax,EXP(%edi)
  88. /*  Now make sure that the result is normalized */
  89. testl $0x80000000,%ecx
  90. jnz LResult_Normalised
  91. /* Normalize by shifting left one bit */
  92. shll $1,FPU_accum_0
  93. rcll $1,FPU_accum_1
  94. rcll $1,%ebx
  95. rcll $1,%ecx
  96. decw EXP(%edi)
  97. LResult_Normalised:
  98. movl FPU_accum_0,%eax
  99. movl FPU_accum_1,%edx
  100. orl %eax,%eax
  101. jz L_extent_zero
  102. orl $1,%edx
  103. L_extent_zero:
  104. movl %ecx,%eax
  105. jmp fpu_reg_round
  106. #ifdef PARANOID
  107. L_bugged:
  108. pushl EX_INTERNAL|0x205
  109. call EXCEPTION
  110. pop %ebx
  111. jmp L_exit
  112. L_exit:
  113. popl %ebx
  114. popl %edi
  115. popl %esi
  116. leave
  117. ret
  118. #endif /* PARANOID */