x_ovfl.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. |
  2. | x_ovfl.sa 3.5 7/1/91
  3. |
  4. | fpsp_ovfl --- FPSP handler for overflow exception
  5. |
  6. | Overflow occurs when a floating-point intermediate result is
  7. | too large to be represented in a floating-point data register,
  8. | or when storing to memory, the contents of a floating-point
  9. | data register are too large to be represented in the
  10. | destination format.
  11. |
  12. | Trap disabled results
  13. |
  14. | If the instruction is move_out, then garbage is stored in the
  15. | destination. If the instruction is not move_out, then the
  16. | destination is not affected. For 68881 compatibility, the
  17. | following values should be stored at the destination, based
  18. | on the current rounding mode:
  19. |
  20. | RN Infinity with the sign of the intermediate result.
  21. | RZ Largest magnitude number, with the sign of the
  22. | intermediate result.
  23. | RM For pos overflow, the largest pos number. For neg overflow,
  24. | -infinity
  25. | RP For pos overflow, +infinity. For neg overflow, the largest
  26. | neg number
  27. |
  28. | Trap enabled results
  29. | All trap disabled code applies. In addition the exceptional
  30. | operand needs to be made available to the users exception handler
  31. | with a bias of $6000 subtracted from the exponent.
  32. |
  33. |
  34. | Copyright (C) Motorola, Inc. 1990
  35. | All Rights Reserved
  36. |
  37. | For details on the license for this file, please see the
  38. | file, README, in this same directory.
  39. X_OVFL: |idnt 2,1 | Motorola 040 Floating Point Software Package
  40. |section 8
  41. #include "fpsp.h"
  42. |xref ovf_r_x2
  43. |xref ovf_r_x3
  44. |xref store
  45. |xref real_ovfl
  46. |xref real_inex
  47. |xref fpsp_done
  48. |xref g_opcls
  49. |xref b1238_fix
  50. .global fpsp_ovfl
  51. fpsp_ovfl:
  52. link %a6,#-LOCAL_SIZE
  53. fsave -(%a7)
  54. moveml %d0-%d1/%a0-%a1,USER_DA(%a6)
  55. fmovemx %fp0-%fp3,USER_FP0(%a6)
  56. fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
  57. |
  58. | The 040 doesn't set the AINEX bit in the FPSR, the following
  59. | line temporarily rectifies this error.
  60. |
  61. bsetb #ainex_bit,FPSR_AEXCEPT(%a6)
  62. |
  63. bsrl ovf_adj |denormalize, round & store interm op
  64. |
  65. | if overflow traps not enabled check for inexact exception
  66. |
  67. btstb #ovfl_bit,FPCR_ENABLE(%a6)
  68. beqs ck_inex
  69. |
  70. btstb #E3,E_BYTE(%a6)
  71. beqs no_e3_1
  72. bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
  73. bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
  74. bsrl b1238_fix
  75. movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
  76. orl #sx_mask,E_BYTE(%a6)
  77. no_e3_1:
  78. moveml USER_DA(%a6),%d0-%d1/%a0-%a1
  79. fmovemx USER_FP0(%a6),%fp0-%fp3
  80. fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
  81. frestore (%a7)+
  82. unlk %a6
  83. bral real_ovfl
  84. |
  85. | It is possible to have either inex2 or inex1 exceptions with the
  86. | ovfl. If the inex enable bit is set in the FPCR, and either
  87. | inex2 or inex1 occurred, we must clean up and branch to the
  88. | real inex handler.
  89. |
  90. ck_inex:
  91. | move.b FPCR_ENABLE(%a6),%d0
  92. | and.b FPSR_EXCEPT(%a6),%d0
  93. | andi.b #$3,%d0
  94. btstb #inex2_bit,FPCR_ENABLE(%a6)
  95. beqs ovfl_exit
  96. |
  97. | Inexact enabled and reported, and we must take an inexact exception.
  98. |
  99. take_inex:
  100. btstb #E3,E_BYTE(%a6)
  101. beqs no_e3_2
  102. bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
  103. bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
  104. bsrl b1238_fix
  105. movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
  106. orl #sx_mask,E_BYTE(%a6)
  107. no_e3_2:
  108. moveb #INEX_VEC,EXC_VEC+1(%a6)
  109. moveml USER_DA(%a6),%d0-%d1/%a0-%a1
  110. fmovemx USER_FP0(%a6),%fp0-%fp3
  111. fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
  112. frestore (%a7)+
  113. unlk %a6
  114. bral real_inex
  115. ovfl_exit:
  116. bclrb #E3,E_BYTE(%a6) |test and clear E3 bit
  117. beqs e1_set
  118. |
  119. | Clear dirty bit on dest resister in the frame before branching
  120. | to b1238_fix.
  121. |
  122. bfextu CMDREG3B(%a6){#6:#3},%d0 |get dest reg no
  123. bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
  124. bsrl b1238_fix |test for bug1238 case
  125. movel USER_FPSR(%a6),FPSR_SHADOW(%a6)
  126. orl #sx_mask,E_BYTE(%a6)
  127. moveml USER_DA(%a6),%d0-%d1/%a0-%a1
  128. fmovemx USER_FP0(%a6),%fp0-%fp3
  129. fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
  130. frestore (%a7)+
  131. unlk %a6
  132. bral fpsp_done
  133. e1_set:
  134. moveml USER_DA(%a6),%d0-%d1/%a0-%a1
  135. fmovemx USER_FP0(%a6),%fp0-%fp3
  136. fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
  137. unlk %a6
  138. bral fpsp_done
  139. |
  140. | ovf_adj
  141. |
  142. ovf_adj:
  143. |
  144. | Have a0 point to the correct operand.
  145. |
  146. btstb #E3,E_BYTE(%a6) |test E3 bit
  147. beqs ovf_e1
  148. lea WBTEMP(%a6),%a0
  149. bras ovf_com
  150. ovf_e1:
  151. lea ETEMP(%a6),%a0
  152. ovf_com:
  153. bclrb #sign_bit,LOCAL_EX(%a0)
  154. sne LOCAL_SGN(%a0)
  155. bsrl g_opcls |returns opclass in d0
  156. cmpiw #3,%d0 |check for opclass3
  157. bnes not_opc011
  158. |
  159. | FPSR_CC is saved and restored because ovf_r_x3 affects it. The
  160. | CCs are defined to be 'not affected' for the opclass3 instruction.
  161. |
  162. moveb FPSR_CC(%a6),L_SCR1(%a6)
  163. bsrl ovf_r_x3 |returns a0 pointing to result
  164. moveb L_SCR1(%a6),FPSR_CC(%a6)
  165. bral store |stores to memory or register
  166. not_opc011:
  167. bsrl ovf_r_x2 |returns a0 pointing to result
  168. bral store |stores to memory or register
  169. |end