smovecr.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. |
  2. | smovecr.sa 3.1 12/10/90
  3. |
  4. | The entry point sMOVECR returns the constant at the
  5. | offset given in the instruction field.
  6. |
  7. | Input: An offset in the instruction word.
  8. |
  9. | Output: The constant rounded to the user's rounding
  10. | mode unchecked for overflow.
  11. |
  12. | Modified: fp0.
  13. |
  14. |
  15. | Copyright (C) Motorola, Inc. 1990
  16. | All Rights Reserved
  17. |
  18. | For details on the license for this file, please see the
  19. | file, README, in this same directory.
  20. |SMOVECR idnt 2,1 | Motorola 040 Floating Point Software Package
  21. |section 8
  22. #include "fpsp.h"
  23. |xref nrm_set
  24. |xref round
  25. |xref PIRN
  26. |xref PIRZRM
  27. |xref PIRP
  28. |xref SMALRN
  29. |xref SMALRZRM
  30. |xref SMALRP
  31. |xref BIGRN
  32. |xref BIGRZRM
  33. |xref BIGRP
  34. FZERO: .long 00000000
  35. |
  36. | FMOVECR
  37. |
  38. .global smovcr
  39. smovcr:
  40. bfextu CMDREG1B(%a6){#9:#7},%d0 |get offset
  41. bfextu USER_FPCR(%a6){#26:#2},%d1 |get rmode
  42. |
  43. | check range of offset
  44. |
  45. tstb %d0 |if zero, offset is to pi
  46. beqs PI_TBL |it is pi
  47. cmpib #0x0a,%d0 |check range $01 - $0a
  48. bles Z_VAL |if in this range, return zero
  49. cmpib #0x0e,%d0 |check range $0b - $0e
  50. bles SM_TBL |valid constants in this range
  51. cmpib #0x2f,%d0 |check range $10 - $2f
  52. bles Z_VAL |if in this range, return zero
  53. cmpib #0x3f,%d0 |check range $30 - $3f
  54. ble BG_TBL |valid constants in this range
  55. Z_VAL:
  56. fmoves FZERO,%fp0
  57. rts
  58. PI_TBL:
  59. tstb %d1 |offset is zero, check for rmode
  60. beqs PI_RN |if zero, rn mode
  61. cmpib #0x3,%d1 |check for rp
  62. beqs PI_RP |if 3, rp mode
  63. PI_RZRM:
  64. leal PIRZRM,%a0 |rmode is rz or rm, load PIRZRM in a0
  65. bra set_finx
  66. PI_RN:
  67. leal PIRN,%a0 |rmode is rn, load PIRN in a0
  68. bra set_finx
  69. PI_RP:
  70. leal PIRP,%a0 |rmode is rp, load PIRP in a0
  71. bra set_finx
  72. SM_TBL:
  73. subil #0xb,%d0 |make offset in 0 - 4 range
  74. tstb %d1 |check for rmode
  75. beqs SM_RN |if zero, rn mode
  76. cmpib #0x3,%d1 |check for rp
  77. beqs SM_RP |if 3, rp mode
  78. SM_RZRM:
  79. leal SMALRZRM,%a0 |rmode is rz or rm, load SMRZRM in a0
  80. cmpib #0x2,%d0 |check if result is inex
  81. ble set_finx |if 0 - 2, it is inexact
  82. bra no_finx |if 3, it is exact
  83. SM_RN:
  84. leal SMALRN,%a0 |rmode is rn, load SMRN in a0
  85. cmpib #0x2,%d0 |check if result is inex
  86. ble set_finx |if 0 - 2, it is inexact
  87. bra no_finx |if 3, it is exact
  88. SM_RP:
  89. leal SMALRP,%a0 |rmode is rp, load SMRP in a0
  90. cmpib #0x2,%d0 |check if result is inex
  91. ble set_finx |if 0 - 2, it is inexact
  92. bra no_finx |if 3, it is exact
  93. BG_TBL:
  94. subil #0x30,%d0 |make offset in 0 - f range
  95. tstb %d1 |check for rmode
  96. beqs BG_RN |if zero, rn mode
  97. cmpib #0x3,%d1 |check for rp
  98. beqs BG_RP |if 3, rp mode
  99. BG_RZRM:
  100. leal BIGRZRM,%a0 |rmode is rz or rm, load BGRZRM in a0
  101. cmpib #0x1,%d0 |check if result is inex
  102. ble set_finx |if 0 - 1, it is inexact
  103. cmpib #0x7,%d0 |second check
  104. ble no_finx |if 0 - 7, it is exact
  105. bra set_finx |if 8 - f, it is inexact
  106. BG_RN:
  107. leal BIGRN,%a0 |rmode is rn, load BGRN in a0
  108. cmpib #0x1,%d0 |check if result is inex
  109. ble set_finx |if 0 - 1, it is inexact
  110. cmpib #0x7,%d0 |second check
  111. ble no_finx |if 0 - 7, it is exact
  112. bra set_finx |if 8 - f, it is inexact
  113. BG_RP:
  114. leal BIGRP,%a0 |rmode is rp, load SMRP in a0
  115. cmpib #0x1,%d0 |check if result is inex
  116. ble set_finx |if 0 - 1, it is inexact
  117. cmpib #0x7,%d0 |second check
  118. ble no_finx |if 0 - 7, it is exact
  119. | bra set_finx ;if 8 - f, it is inexact
  120. set_finx:
  121. orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
  122. no_finx:
  123. mulul #12,%d0 |use offset to point into tables
  124. movel %d1,L_SCR1(%a6) |load mode for round call
  125. bfextu USER_FPCR(%a6){#24:#2},%d1 |get precision
  126. tstl %d1 |check if extended precision
  127. |
  128. | Precision is extended
  129. |
  130. bnes not_ext |if extended, do not call round
  131. fmovemx (%a0,%d0),%fp0-%fp0 |return result in fp0
  132. rts
  133. |
  134. | Precision is single or double
  135. |
  136. not_ext:
  137. swap %d1 |rnd prec in upper word of d1
  138. addl L_SCR1(%a6),%d1 |merge rmode in low word of d1
  139. movel (%a0,%d0),FP_SCR1(%a6) |load first word to temp storage
  140. movel 4(%a0,%d0),FP_SCR1+4(%a6) |load second word
  141. movel 8(%a0,%d0),FP_SCR1+8(%a6) |load third word
  142. clrl %d0 |clear g,r,s
  143. lea FP_SCR1(%a6),%a0
  144. btstb #sign_bit,LOCAL_EX(%a0)
  145. sne LOCAL_SGN(%a0) |convert to internal ext. format
  146. bsr round |go round the mantissa
  147. bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format
  148. beqs fin_fcr
  149. bsetb #sign_bit,LOCAL_EX(%a0)
  150. fin_fcr:
  151. fmovemx (%a0),%fp0-%fp0
  152. rts
  153. |end