x_store.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* x_store.s - Motorola 68040 FP storage routines (EXC) */
  2. /* Copyright 1991-1993 Wind River Systems, Inc. */
  3. .data
  4. .globl _copyright_wind_river
  5. .long _copyright_wind_river
  6. /*
  7. modification history
  8. --------------------
  9. 01e,21jul93,kdl  added .text (SPR #2372).
  10. 01d,23aug92,jcf  changed bxxx to jxx.
  11. 01c,26may92,rrr  the tree shuffle
  12. 01b,10jan92,kdl  added modification history; general cleanup.
  13. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  14. */
  15. /*
  16. DESCRIPTION
  17. x_storesa 3.2 1/24/91
  18. __x_store --- store operand to memory or register
  19. Used by underflow and overflow handlers.
  20. a6 = points to fp value to be stored.
  21. Copyright (C) Motorola, Inc. 1990
  22. All Rights Reserved
  23. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  24. The copyright notice above does not evidence any
  25. actual or intended publication of such source code.
  26. X_STORE idnt    2,1 Motorola 040 Floating Point Software Package
  27. section 8
  28. NOMANUAL
  29. */
  30. fpreg_mask:
  31. .byte 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
  32. #include "fpsp040E.h"
  33. | xref __x_mem_write
  34. | xref __x_get_fline
  35. | xref __x_g_opcls
  36. | xref __x_g_dfmtou
  37. | xref __x_reg_dest
  38. .globl __x_dest_ext
  39. .globl __x_dest_dbl
  40. .globl __x_dest_sgl
  41. .text
  42. .globl __x_store
  43. __x_store:
  44. btst #E3,a6@(E_BYTE)
  45. jeq  E1_sto
  46. E3_sto:
  47. movel a6@(CMDREG3B),d0
  48. bfextu d0{#6:#3},d0 | isolate dest. reg from cmdreg3b
  49. sto_fp:
  50. lea fpreg_mask,a1
  51. moveb a1@(d0:w),d0 | convert reg# to dynamic register mask
  52. tstb a0@(LOCAL_SGN)
  53. jeq  is_pos
  54. bset #sign_bit,a0@(LOCAL_EX)
  55. is_pos:
  56. fmovemx a0@,d0 | move to correct register
  57. |
  58. | if fp0-fp3 is being modified, we must put a copy
  59. | in the USER_FPn variable on the stack because all exception
  60. | handlers restore fp0-fp3 from there.
  61. |
  62. cmpb #0x80,d0
  63. jne  not_fp0
  64. fmovemx fp0-fp0,a6@(USER_FP0)
  65. rts
  66. not_fp0:
  67. cmpb #0x40,d0
  68. jne  not_fp1
  69. fmovemx fp1-fp1,a6@(USER_FP1)
  70. rts
  71. not_fp1:
  72. cmpb #0x20,d0
  73. jne  not_fp2
  74. fmovemx fp2-fp2,a6@(USER_FP2)
  75. rts
  76. not_fp2:
  77. cmpb #0x10,d0
  78. jne  not_fp3
  79. fmovemx fp3-fp3,a6@(USER_FP3)
  80. rts
  81. not_fp3:
  82. rts
  83. E1_sto:
  84. bsrl __x_g_opcls | returns opclass in d0
  85. cmpib #3,d0
  86. jeq  opc011 | branch if opclass 3
  87. movel a6@(CMDREG1B),d0
  88. bfextu d0{#6:#3},d0 | extract destination register
  89. jra  sto_fp
  90. opc011:
  91. bsrl __x_g_dfmtou | returns dest format in d0
  92. | | ext=00, sgl=01, dbl=10
  93. movel a0,a1 | save source addr in a1
  94. movel a6@(EXC_EA),a0 | get the address
  95. cmpil #0,d0 | if dest format is extended
  96. jeq  __x_dest_ext | then branch
  97. cmpil #1,d0 | if dest format is single
  98. jeq  __x_dest_sgl | then branch
  99. |
  100. | fall through to __x_dest_dbl
  101. |
  102. |
  103. | __x_dest_dbl --- write double precision value to user space
  104. |
  105. |Input
  106. | a0 -> destination address
  107. | a1 -> source in extended precision
  108. |Output
  109. | a0 -> destroyed
  110. | a1 -> destroyed
  111. | d0 -> 0
  112. |
  113. |Changes extended precision to double precision.
  114. | Note: no attempt is made to round the extended value to double.
  115. | dbl_sign = ext_sign
  116. | dbl_exp = ext_exp - 0x3fff(ext bias) + 0x7ff(dbl bias)
  117. | get rid of ext integer bit
  118. | dbl_mant = ext_mant{62:12}
  119. |
  120. |      ---------------   ---------------    ---------------
  121. |  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
  122. |      ---------------   ---------------    ---------------
  123. |      95     64    63 62       32      31     11   0
  124. |      |      |
  125. |      |      |
  126. |      |      |
  127. |                v         v
  128. |            ---------------   ---------------
  129. |  double   ->         |s|exp| mant  |   |  mant       |
  130. |            ---------------   ---------------
  131. |             63     51   32   31        0
  132. |
  133. __x_dest_dbl:
  134. clrl d0 | clear d0
  135. movew a1@(LOCAL_EX),d0 | get exponent
  136. subw #0x3fff,d0 | subtract extended precision bias
  137. cmpw #0x4000,d0 | check if inf
  138. jeq  inf | if so, special case
  139. addw #0x3ff,d0 | add double precision bias
  140. swap d0 | d0 now in upper word
  141. lsll #4,d0 | d0 now in proper place for dbl prec exp
  142. tstb a1@(LOCAL_SGN)
  143. jeq  get_mant | if postive, go process mantissa
  144. bset #31,d0 | if negative, put in sign information
  145. | |  before continuing
  146. jra  get_mant | go process mantissa
  147. inf:
  148. movel #0x7ff00000,d0 | load dbl inf exponent
  149. clrl a1@(LOCAL_HI) | clear msb
  150. tstb a1@(LOCAL_SGN)
  151. jeq  dbl_inf | if positive, go ahead and write it
  152. bset #31,d0 | if negative put in sign information
  153. dbl_inf:
  154. movel d0,a1@(LOCAL_EX) | put the new exp back on the stack
  155. jra  dbl_wrt
  156. get_mant:
  157. movel a1@(LOCAL_HI),d1 | get ms mantissa
  158. bfextu d1{#1:#20},d1 | get upper 20 bits of ms
  159. orl d1,d0 | put these bits in ms word of double
  160. movel d0,a1@(LOCAL_EX) | put the new exp back on the stack
  161. movel a1@(LOCAL_HI),d1 | get ms mantissa
  162. movel #21,d0 | load shift count
  163. lsll d0,d1 | put lower 11 bits in upper bits
  164. movel d1,a1@(LOCAL_HI) | build lower lword in memory
  165. movel a1@(LOCAL_LO),d1 | get ls mantissa
  166. bfextu d1{#0:#21},d0 | get ls 21 bits of double
  167. orl d0,a1@(LOCAL_HI) | put them in double result
  168. dbl_wrt:
  169. movel #0x8,d0 | byte count for double precision number
  170. exg a0,a1 | a0=supervisor source, a1=user dest
  171. bsrl __x_mem_write /* | move the number to the user's memory */
  172. rts
  173. |
  174. | __x_dest_sgl --- write single precision value to user space
  175. |
  176. |Input
  177. | a0 -> destination address
  178. | a1 -> source in extended precision
  179. |
  180. |Output
  181. | a0 -> destroyed
  182. | a1 -> destroyed
  183. | d0 -> 0
  184. |
  185. |Changes extended precision to single precision.
  186. | sgl_sign = ext_sign
  187. | sgl_exp = ext_exp - 0x3fff(ext bias) + 0x7f(sgl bias)
  188. | get rid of ext integer bit
  189. | sgl_mant = ext_mant{62:12}
  190. |
  191. |      ---------------   ---------------    ---------------
  192. |  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
  193. |      ---------------   ---------------    ---------------
  194. |      95     64    63 62    40 32      31     12   0
  195. |      |    |
  196. |      |    |
  197. |      |    |
  198. |                v     v
  199. |            ---------------
  200. |  single   ->         |s|exp| mant  |
  201. |            ---------------
  202. |             31     22     0
  203. |
  204. __x_dest_sgl:
  205. clrl d0
  206. movew a1@(LOCAL_EX),d0 | get exponent
  207. subw #0x3fff,d0 | subtract extended precision bias
  208. cmpw #0x4000,d0 | check if inf
  209. jeq  __x_sinf | if so, special case
  210. addw #0x7f,d0 | add single precision bias
  211. swap d0 | put exp in upper word of d0
  212. lsll #7,d0 | shift it into single exp bits
  213. tstb a1@(LOCAL_SGN)
  214. jeq  get_sman | if positive, continue
  215. bset #31,d0 | if negative, put in sign first
  216. jra  get_sman | get mantissa
  217. __x_sinf:
  218. movel #0x7f800000,d0 | load single inf exp to d0
  219. tstb a1@(LOCAL_SGN)
  220. jeq  sgl_wrt | if positive, continue
  221. bset #31,d0 | if negative, put in sign info
  222. jra  sgl_wrt
  223. get_sman:
  224. movel a1@(LOCAL_HI),d1 | get ms mantissa
  225. bfextu d1{#1:#23},d1 | get upper 23 bits of ms
  226. orl d1,d0 | put these bits in ms word of single
  227. sgl_wrt:
  228. movel d0,a6@(L_SCR1) | put the new exp back on the stack
  229. movel #0x4,d0 | byte count for single precision number
  230. tstl a0 | users destination address
  231. jeq  sgl_Dn | destination is a data register
  232. exg a0,a1 | a0=supervisor source, a1=user dest
  233. lea a6@(L_SCR1),a0 | point a0 to data
  234. bsrl __x_mem_write /* | move the number to the user's memory */
  235. rts
  236. sgl_Dn:
  237. bsrl __x_get_fline | returns fline word in d0
  238. andw #0x7,d0 | isolate register number
  239. movel d0,d1 | d1 has size:reg formatted for __x_reg_dest
  240. orl #0x10,d1 | reg_dest wants size added to reg#
  241. jra  __x_reg_dest | size is X, rts in __x_reg_dest will
  242. | | return to caller of __x_dest_sgl
  243. __x_dest_ext:
  244. tstb a1@(LOCAL_SGN) | put back sign into exponent word
  245. jeq  dstx_cont
  246. bset #sign_bit,a1@(LOCAL_EX)
  247. dstx_cont:
  248. clrb a1@(LOCAL_SGN) | clear out the sign byte
  249. movel #0x0c,d0 | byte count for extended number
  250. exg a0,a1 | a0=supervisor source, a1=user dest
  251. bsrl __x_mem_write /* | move the number to the user's memory */
  252. rts
  253. | end