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

VxWorks

开发平台:

C/C++

  1. /* get_op.s - Motorola 68040 FP get opclass routine (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. 01f,31may96,ms   updated to mototorola version 2.3
  10. 01e,21jul93,kdl  added .text (SPR #2372).
  11. 01d,23aug92,jcf  changed bxxx to jxx.
  12. 01c,26may92,rrr  the tree shuffle
  13. 01b,10jan92,kdl  added modification history; general cleanup.
  14. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  15. */
  16. /*
  17. DESCRIPTION
  18. get_opsa 3.5 4/26/91
  19.  Description: This routine is called by the unsupported format/data
  20. type exception handler ('unsupp' - vector 55) and the unimplemented
  21. instruction exception handler ('unimp' - vector 11).  'get_op'
  22. determines the opclass (0, 2, or 3) and branches to the
  23. opclass handler routine.  See 68881/2 User's Manual table 4-11
  24. for a description of the opclasses.
  25. For UNSUPPORTED data/format (exception vector 55) and for
  26. UNIMPLEMENTED instructions (exception vector 11) the following
  27. applies:
  28. - For unnormormalized numbers (opclass 0, 2, or 3) the
  29. number(s) is normalized and the operand type tag is updated.
  30. - For a packed number (opclass 2) the number is unpacked and the
  31. operand type tag is updated.
  32. - For denormalized numbers (opclass 0 or 2) the number(s) is not
  33. changed but passed to the next module.  The next module for
  34. unimp is __x_do_func, the next module for unsupp is __x_res_func.
  35. For UNSUPPORTED data/format (exception vector 55) only the
  36. following applies:
  37. - If there is a move out with a packed number (opclass 3) the
  38. number is packed and written to user memory.  For the other
  39. opclasses the number(s) are written back to the fsave stack
  40. and the instruction is then restored back into the '040.  The
  41. '040 is then able to complete the instruction.
  42. For example:
  43. faddx fpm,fpn where the fpm contains an unnormalized number.
  44. The '040 takes an unsupported data trap and gets to this
  45. routine.  The number is normalized, put back on the stack and
  46. then an frestore is done to restore the instruction back into
  47. the '040.  The '040 then re-executes the faddx fpm,fpn with
  48. a normalized number in the source and the instruction is
  49. successful.
  50. Next consider if in the process of normalizing the un-
  51. normalized number it becomes a denormalized number.  The
  52. routine which converts the unnorm to a norm (called mk_norm)
  53. detects this and tags the number as a denorm.  The routine
  54. __x_res_func sees the denorm tag and converts the denorm to a
  55. norm.  The instruction is then restored back into the '040
  56. which re_executess the instruction.
  57. Copyright (C) Motorola, Inc. 1990
  58. All Rights Reserved
  59. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  60. The copyright notice above does not evidence any
  61. actual or intended publication of such source code.
  62. GET_OP    idnt    2,1 Motorola 040 Floating Point Software Package
  63. section 8
  64. NOMANUAL
  65. */
  66. #include "fpsp040E.h"
  67. .globl __x_PIRN,__x_PIRZRM,__x_PIRP
  68. .globl __x_SMALRN,__x_SMALRZRM,__x_SMALRP
  69. .globl __x_BIGRN,__x_BIGRZRM,__x_BIGRP
  70. __x_PIRN:
  71. .long 0x40000000,0xc90fdaa2,0x2168c235    | pi
  72. __x_PIRZRM:
  73. .long 0x40000000,0xc90fdaa2,0x2168c234    | pi
  74. __x_PIRP:
  75. .long 0x40000000,0xc90fdaa2,0x2168c235    | pi
  76. |round to nearest
  77. __x_SMALRN:
  78. .long 0x3ffd0000,0x9a209a84,0xfbcff798    | log10(2)
  79. .long 0x40000000,0xadf85458,0xa2bb4a9a    | e
  80. .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    | log2(e)
  81. .long 0x3ffd0000,0xde5bd8a9,0x37287195    | log10(e)
  82. .long 0x00000000,0x00000000,0x00000000    | 0.0
  83. | round to zero; round to negative infinity
  84. __x_SMALRZRM:
  85. .long 0x3ffd0000,0x9a209a84,0xfbcff798    | log10(2)
  86. .long 0x40000000,0xadf85458,0xa2bb4a9a    | e
  87. .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb    | log2(e)
  88. .long 0x3ffd0000,0xde5bd8a9,0x37287195    | log10(e)
  89. .long 0x00000000,0x00000000,0x00000000    | 0.0
  90. | round to positive infinity
  91. __x_SMALRP:
  92. .long 0x3ffd0000,0x9a209a84,0xfbcff799    | log10(2)
  93. .long 0x40000000,0xadf85458,0xa2bb4a9b    | e
  94. .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    | log2(e)
  95. .long 0x3ffd0000,0xde5bd8a9,0x37287195    | log10(e)
  96. .long 0x00000000,0x00000000,0x00000000    | 0.0
  97. |round to nearest
  98. __x_BIGRN:
  99. .long 0x3ffe0000,0xb17217f7,0xd1cf79ac    | ln(2)
  100. .long 0x40000000,0x935d8ddd,0xaaa8ac17    | ln(10)
  101. .long 0x3fff0000,0x80000000,0x00000000    | 10 ^ 0
  102. .globl __x_PTENRN
  103. __x_PTENRN:
  104. .long 0x40020000,0xA0000000,0x00000000    | 10 ^ 1
  105. .long 0x40050000,0xC8000000,0x00000000    | 10 ^ 2
  106. .long 0x400C0000,0x9C400000,0x00000000    | 10 ^ 4
  107. .long 0x40190000,0xBEBC2000,0x00000000    | 10 ^ 8
  108. .long 0x40340000,0x8E1BC9BF,0x04000000    | 10 ^ 16
  109. .long 0x40690000,0x9DC5ADA8,0x2B70B59E    | 10 ^ 32
  110. .long 0x40D30000,0xC2781F49,0xFFCFA6D5    | 10 ^ 64
  111. .long 0x41A80000,0x93BA47C9,0x80E98CE0    | 10 ^ 128
  112. .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    | 10 ^ 256
  113. .long 0x46A30000,0xE319A0AE,0xA60E91C7    | 10 ^ 512
  114. .long 0x4D480000,0xC9767586,0x81750C17    | 10 ^ 1024
  115. .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    | 10 ^ 2048
  116. .long 0x75250000,0xC4605202,0x8A20979B    | 10 ^ 4096
  117. |round to minus infinity
  118. __x_BIGRZRM:
  119. .long 0x3ffe0000,0xb17217f7,0xd1cf79ab    | ln(2)
  120. .long 0x40000000,0x935d8ddd,0xaaa8ac16    | ln(10)
  121. .long 0x3fff0000,0x80000000,0x00000000    | 10 ^ 0
  122. .globl __x_PTENRM
  123. __x_PTENRM:
  124. .long 0x40020000,0xA0000000,0x00000000    | 10 ^ 1
  125. .long 0x40050000,0xC8000000,0x00000000    | 10 ^ 2
  126. .long 0x400C0000,0x9C400000,0x00000000    | 10 ^ 4
  127. .long 0x40190000,0xBEBC2000,0x00000000    | 10 ^ 8
  128. .long 0x40340000,0x8E1BC9BF,0x04000000    | 10 ^ 16
  129. .long 0x40690000,0x9DC5ADA8,0x2B70B59D    | 10 ^ 32
  130. .long 0x40D30000,0xC2781F49,0xFFCFA6D5    | 10 ^ 64
  131. .long 0x41A80000,0x93BA47C9,0x80E98CDF    | 10 ^ 128
  132. .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D    | 10 ^ 256
  133. .long 0x46A30000,0xE319A0AE,0xA60E91C6    | 10 ^ 512
  134. .long 0x4D480000,0xC9767586,0x81750C17    | 10 ^ 1024
  135. .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    | 10 ^ 2048
  136. .long 0x75250000,0xC4605202,0x8A20979A    | 10 ^ 4096
  137. |round to positive infinity
  138. __x_BIGRP:
  139. .long 0x3ffe0000,0xb17217f7,0xd1cf79ac    | ln(2)
  140. .long 0x40000000,0x935d8ddd,0xaaa8ac17    | ln(10)
  141. .long 0x3fff0000,0x80000000,0x00000000    | 10 ^ 0
  142. .globl __x_PTENRP
  143. __x_PTENRP:
  144. .long 0x40020000,0xA0000000,0x00000000    | 10 ^ 1
  145. .long 0x40050000,0xC8000000,0x00000000    | 10 ^ 2
  146. .long 0x400C0000,0x9C400000,0x00000000    | 10 ^ 4
  147. .long 0x40190000,0xBEBC2000,0x00000000    | 10 ^ 8
  148. .long 0x40340000,0x8E1BC9BF,0x04000000    | 10 ^ 16
  149. .long 0x40690000,0x9DC5ADA8,0x2B70B59E    | 10 ^ 32
  150. .long 0x40D30000,0xC2781F49,0xFFCFA6D6    | 10 ^ 64
  151. .long 0x41A80000,0x93BA47C9,0x80E98CE0    | 10 ^ 128
  152. .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    | 10 ^ 256
  153. .long 0x46A30000,0xE319A0AE,0xA60E91C7    | 10 ^ 512
  154. .long 0x4D480000,0xC9767586,0x81750C18    | 10 ^ 1024
  155. .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6    | 10 ^ 2048
  156. .long 0x75250000,0xC4605202,0x8A20979B    | 10 ^ 4096
  157. | xref __x_nrm_zero
  158. | xref __x_decbin
  159. | xref __x_round
  160. .globl    __x_get_op
  161. .globl    __x_uns_getop
  162. .globl    __x_uni_getop
  163. .text
  164. __x_get_op:
  165. clrb a6@(DY_MO_FLG)
  166. tstb a6@(UFLG_TMP) | test flag for unsupp/unimp state
  167. jeq  __x_uni_getop
  168. __x_uns_getop:
  169. btst #direction_bit,a6@(CMDREG1B)
  170. jne  opclass3 | branch if a fmovel out (any kind)
  171. btst #6,a6@(CMDREG1B)
  172. jeq  uns_notpacked
  173. bfextu a6@(CMDREG1B){#3:#3},d0
  174. cmpb #3,d0
  175. jeq  pack_source | check for a packed src op, branch if so
  176. uns_notpacked:
  177. bsrl chk_dy_mo | set the dyadic/monadic flag
  178. tstb a6@(DY_MO_FLG)
  179. jeq  src_op_ck | if monadic, go check src op
  180. | | else, check dst op (fall through)
  181. btst #7,a6@(DTAG)
  182. jeq  src_op_ck | if dst op is norm, check src op
  183. jra  dst_ex_dnrm | else, handle destination unnorm/dnrm
  184. __x_uni_getop:
  185. bfextu a6@(CMDREG1B){#0:#6},d0 | get opclass and src fields
  186. cmpil #0x17,d0 | if op class and size fields are 0x17,
  187. | | it is FMOVECR|  if not, continue
  188. |
  189. | If the instruction is fmovecr, exit __x_get_op.  It is handled
  190. | in __x_do_func and smovecrsa.
  191. |
  192. jne  not_fmovecr | handle fmovecr as an unimplemented inst
  193. rts
  194. not_fmovecr:
  195. btst #E1,a6@(E_BYTE) | if set, there is a packed operand
  196. jne  pack_source | check for packed src op, branch if so
  197. | The following lines of are coded to optimize on normalized operands
  198. moveb a6@(STAG),d0
  199. orb a6@(DTAG),d0 | check if either of STAG/DTAG msb set
  200. jmi  dest_op_ck | if so, some op needs to be fixed
  201. rts
  202. dest_op_ck:
  203. btst #7,a6@(DTAG) | check for unsupported data types in
  204. jeq  src_op_ck | the destination, if not, check src op
  205. bsrl chk_dy_mo | set dyadic/monadic flag
  206. tstb a6@(DY_MO_FLG) |
  207. jeq  src_op_ck | if monadic, check src op
  208. |
  209. | At this point, destination has an extended denorm or unnorm.
  210. |
  211. dst_ex_dnrm:
  212. movew a6@(FPTEMP_EX),d0 | get destination exponent
  213. andiw #0x7fff,d0 | mask sign, check if exp = 0000
  214. jeq  src_op_ck | if denorm then check source op.
  215. | | denorms are taken care of in __x_res_func
  216. | | (unsupp) or __x_do_func (unimp)
  217. | | else unnorm fall through
  218. lea a6@(FPTEMP),a0 | point a0 to dop - used in mk_norm
  219. bsrl mk_norm | go normalize - mk_norm returns:
  220. | | L_SCR1{7:5} = operand tag
  221. | |  (000 = norm, 100 = denorm)
  222. | | L_SCR1{4} = fpte15 or ete15
  223. | |  0 = exp >  0x3fff
  224. | |  1 = exp <= 0x3fff
  225. | | and puts the normalized num back
  226. | | on the fsave stack
  227. |
  228. moveb a6@(L_SCR1),a6@(DTAG) | write the new tag # fpte15
  229. | | to the fsave stack and fall
  230. | | through to check source operand
  231. |
  232. src_op_ck:
  233. btst #7,a6@(STAG)
  234. jeq  end_getop | check for unsupported data types on the
  235. | | source operand
  236. btst #5,a6@(STAG)
  237. jne  src_sd_dnrm | if bit 5 set, handle sgl/dbl denorms
  238. |
  239. | At this point only unnorms or extended denorms are possible.
  240. |
  241. src_ex_dnrm:
  242. movew a6@(ETEMP_EX),d0 | get source exponent
  243. andiw #0x7fff,d0 | mask sign, check if exp = 0000
  244. jeq  end_getop | if denorm then exit, denorms are
  245. | | handled in __x_do_func
  246. lea a6@(ETEMP),a0 | point a0 to sop - used in mk_norm
  247. bsrl mk_norm | go normalize - mk_norm returns:
  248. | | L_SCR1{7:5} = operand tag
  249. | |  (000 = norm, 100 = denorm)
  250. | | L_SCR1{4} = fpte15 or ete15
  251. | |  0 = exp >  0x3fff
  252. | |  1 = exp <= 0x3fff
  253. | | and puts the normalized num back
  254. | | on the fsave stack
  255. |
  256. moveb a6@(L_SCR1),a6@(STAG) | write the new tag # ete15
  257. rts | end_getop
  258. |
  259. | At this point, only single or double denorms are possible.
  260. | If the inst is not fmove, normalize the source.  If it is,
  261. | do nothing to the input.
  262. |
  263. src_sd_dnrm:
  264. btst #4,a6@(CMDREG1B) | differentiate between sgl/dbl denorm
  265. jne  is_double
  266. is_single:
  267. movew #0x3f81,d1 | write bias for sgl denorm
  268. jra  common | goto the common code
  269. is_double:
  270. movew #0x3c01,d1 | write the bias for a dbl denorm
  271. common:
  272. btst #sign_bit,a6@(ETEMP_EX) | grab sign bit of mantissa
  273. jeq  pos
  274. bset #15,d1 | set sign bit because it is negative
  275. pos:
  276. movew d1,a6@(ETEMP_EX)
  277. | | put exponent on stack
  278. movew a6@(CMDREG1B),d1
  279. andw #0xe3ff,d1 | clear out source specifier
  280. orw #0x0800,d1 | set source specifier to extended prec
  281. movew d1,a6@(CMDREG1B) | write back to the command word in stack
  282. | | this is needed to fix unsupp data stack
  283. lea a6@(ETEMP),a0 | point a0 to sop
  284. bsrl mk_norm | convert sgl/dbl denorm to norm
  285. moveb a6@(L_SCR1),a6@(STAG) | put tag into source tag reg - d0
  286. rts | end_getop
  287. |
  288. | At this point, the source is definitely packed, whether
  289. | instruction is dyadic or monadic is still unknown
  290. |
  291. pack_source:
  292. movel a6@(FPTEMP_LO),a6@(ETEMP) | write ms part of packed
  293. | | number to etemp slot
  294. bsrl chk_dy_mo | set dyadic/monadic flag
  295. bsrl unpack
  296. tstb a6@(DY_MO_FLG)
  297. jeq  end_getop | if monadic, exit
  298. | | else, fix FPTEMP
  299. pack_dya:
  300. bfextu a6@(CMDREG1B){#6:#3},d0 | extract dest fp reg
  301. movel #7,d1
  302. subl d0,d1
  303. clrl d0
  304. bset d1,d0 | set up d0 as a dynamic register mask
  305. fmovemx d0,a6@(FPTEMP) | write to FPTEMP
  306. btst #7,a6@(DTAG) | check dest tag for unnorm or denorm
  307. jne  dst_ex_dnrm | else, handle the unnorm or ext denorm
  308. |
  309. | Dest is not denormalized.  Check for norm, and set fpte15
  310. | accordingly.
  311. |
  312. moveb a6@(DTAG),d0
  313. andib #0xf0,d0 | strip to only dtag:fpte15
  314. tstb d0 | check for normalized value
  315. jne  end_getop | if inf/nan/zero leave __x_get_op
  316. movew a6@(FPTEMP_EX),d0
  317. andiw #0x7fff,d0
  318. cmpiw #0x3fff,d0 | check if fpte15 needs setting
  319. jge  end_getop | if >= 0x3fff, leave fpte15=0
  320. orb #0x10,a6@(DTAG)
  321. jra  end_getop
  322. |
  323. | At this point, it is either an fmoveout packed, unnorm or denorm
  324. |
  325. opclass3:
  326. clrb a6@(DY_MO_FLG) | set dyadic/monadic flag to monadic
  327. bfextu a6@(CMDREG1B){#4:#2},d0
  328. cmpib #3,d0
  329. jne  src_ex_dnrm | if not equal, must be unnorm or denorm
  330. | | else it is a packed move out
  331. | | exit
  332. end_getop:
  333. rts
  334. |
  335. | Sets the DY_MO_FLG correctly. This is used only on if it is an
  336. | unuspported data type exception.  Set if dyadic.
  337. |
  338. chk_dy_mo:
  339. movew a6@(CMDREG1B),d0
  340. btst #5,d0 | testing extension command word
  341. jeq  set_mon | if bit 5 = 0 then monadic
  342. btst #4,d0 | know that bit 5 = 1
  343. jeq  set_dya | if bit 4 = 0 then dyadic
  344. andiw #0x007f,d0 | get rid of all but extension bits {6:0}
  345. cmpiw  #0x0038,d0 | if extension = 0x38 then fcmp (dyadic)
  346. jne  set_mon
  347. set_dya:
  348. st a6@(DY_MO_FLG) | set the inst flag type to dyadic
  349. rts
  350. set_mon:
  351. clrb a6@(DY_MO_FLG) | set the inst flag type to monadic
  352. rts
  353. |
  354. | MK_NORM
  355. |
  356. | Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
  357. | exception if denorm.
  358. |
  359. | CASE opclass 0x0 unsupp
  360. | mk_norm till msb set
  361. | set tag = norm
  362. |
  363. | CASE opclass 0x0 unimp
  364. | mk_norm till msb set or exp = 0
  365. | if integer bit = 0
  366. |    tag = denorm
  367. | else
  368. |    tag = norm
  369. |
  370. | CASE opclass 011 unsupp
  371. | mk_norm till msb set or exp = 0
  372. | if integer bit = 0
  373. |    tag = denorm
  374. |    set unfl_nmcexe = 1
  375. | else
  376. |    tag = norm
  377. |
  378. | if exp <= 0x3fff
  379. |   set ete15 or fpte15 = 1
  380. | else set ete15 or fpte15 = 0
  381. | input:
  382. | a0 = points to operand to be normalized
  383. | output:
  384. | L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
  385. | L_SCR1{4}   = fpte15 or ete15 (0 = exp > 0x3fff, 1 = exp <=0x3fff)
  386. | the normalized operand is placed back on the fsave stack
  387. mk_norm:
  388. clrl a6@(L_SCR1)
  389. bclr #sign_bit,a0@(LOCAL_EX)
  390. sne a0@(LOCAL_SGN) | transform into internal extended format
  391. cmpib #0x2c,a6@(1+EXC_VEC) | check if unimp
  392. jne  uns_data | branch if unsupp
  393. bsrl uni_inst | call if unimp (opclass 0x0)
  394. jra  reload
  395. uns_data:
  396. btst #direction_bit,a6@(CMDREG1B) | check transfer direction
  397. jne  bit_set | branch if set (opclass 011)
  398. bsrl uns_opx | call if opclass 0x0
  399. jra  reload
  400. bit_set:
  401. bsrl uns_op3 | opclass 011
  402. reload:
  403. cmpw #0x3fff,a0@(LOCAL_EX) | if exp > 0x3fff
  404. jgt  end_mk |    fpte15/ete15 already set to 0
  405. bset #4,a6@(L_SCR1) | else set fpte15/ete15 to 1
  406. | | calling routine actually sets the
  407. | | value on the stack (along with the
  408. /* | | tag), since this routine doesn't  */
  409. | | know if it should set ete15 or fpte15
  410. /* | | ie, it doesn't know if this is the  */
  411. | | src op or dest op.
  412. end_mk:
  413. bfclr a0@(LOCAL_SGN){#0:#8}
  414. jeq  end_mk_pos
  415. bset #sign_bit,a0@(LOCAL_EX) | convert back to IEEE format
  416. end_mk_pos:
  417. rts
  418. |
  419. |     CASE opclass 011 unsupp
  420. |
  421. uns_op3:
  422. bsrl __x_nrm_zero | normalize till msb = 1 or exp = zero
  423. btst #7,a0@(LOCAL_HI) | if msb = 1
  424. jne  no_unfl | then branch
  425. set_unfl:
  426. orw #dnrm_tag,a6@(L_SCR1) | set denorm tag
  427. bset #__x_unfl_bit,a6@(FPSR_EXCEPT) | set unfl exception bit
  428. no_unfl:
  429. rts
  430. |
  431. |     CASE opclass 0x0 unsupp
  432. |
  433. uns_opx:
  434. bsrl __x_nrm_zero | normalize the number
  435. btst #7,a0@(LOCAL_HI) | check if integer bit (j-bit) is set
  436. jeq  uns_den | if clear then now have a denorm
  437. uns_nrm:
  438. orb #__x_norm_tag,a6@(L_SCR1) | set tag to norm
  439. rts
  440. uns_den:
  441. orb #dnrm_tag,a6@(L_SCR1) | set tag to denorm
  442. rts
  443. |
  444. |     CASE opclass 0x0 unimp
  445. |
  446. uni_inst:
  447. bsrl __x_nrm_zero
  448. btst #7,a0@(LOCAL_HI) | check if integer bit (j-bit) is set
  449. jeq  uni_den | if clear then now have a denorm
  450. uni_nrm:
  451. orb #__x_norm_tag,a6@(L_SCR1) | set tag to norm
  452. rts
  453. uni_den:
  454. orb #dnrm_tag,a6@(L_SCR1) | set tag to denorm
  455. rts
  456. |
  457. | Decimal to binary conversion
  458. |
  459. | Special cases of inf and NaNs are completed outside of __x_decbin.
  460. | If the input is an snan, the snan bit is not set.
  461. |
  462. | input:
  463. | a6@(ETEMP) - points to packed decimal string in memory
  464. | output:
  465. | fp0 - contains packed string converted to extended precision
  466. | ETEMP - same as fp0
  467. unpack:
  468. movew a6@(CMDREG1B),d0 /* | examine command word, looking for fmove's */
  469. andw #0x3b,d0
  470. jeq  move_unpack | special handling for fmove: must set FPSR_CC
  471. movew a6@(ETEMP),d0 | get word with inf information
  472. bfextu d0{#20:#12},d1 | get exponent into d1
  473. cmpiw #0x0fff,d1 | test for inf or NaN
  474. jne  try_zero | if not equal, it is not special
  475. bfextu d0{#17:#3},d1 | get SE and y bits into d1
  476. cmpiw #7,d1 | SE and y bits must be on for special
  477. jne  try_zero | if not on, it is not special
  478. |input is of the special cases of inf and NaN
  479. tstl a6@(ETEMP_HI) | check ms mantissa
  480. jne  fix_nan | if non-zero, it is a NaN
  481. tstl a6@(ETEMP_LO) | check ls mantissa
  482. jne  fix_nan | if non-zero, it is a NaN
  483. jra  finish | special already on stack
  484. fix_nan:
  485. btst #signan_bit,a6@(ETEMP_HI) | test for snan
  486. jne  finish
  487. orl #__x_snaniop_mask,a6@(USER_FPSR) | always set snan if it is so
  488. jra  finish
  489. try_zero:
  490. movew a6@(ETEMP_EX+2),d0 | get word 4
  491. andiw #0x000f,d0 | clear all but last ni(y)bble
  492. tstw d0 | check for zero.
  493. jne  not_spec
  494. tstl a6@(ETEMP_HI) | check words 3 and 2
  495. jne  not_spec
  496. tstl a6@(ETEMP_LO) | check words 1 and 0
  497. jne  not_spec
  498. tstl a6@(ETEMP) | test sign of the zero
  499. jge  pos_zero
  500. movel #0x80000000,a6@(ETEMP) | write neg zero to etemp
  501. clrl a6@(ETEMP_HI)
  502. clrl a6@(ETEMP_LO)
  503. jra  finish
  504. pos_zero:
  505. clrl a6@(ETEMP)
  506. clrl a6@(ETEMP_HI)
  507. clrl a6@(ETEMP_LO)
  508. jra  finish
  509. not_spec:
  510. fmovemx fp0-fp1,a7@- | save fp0 - __x_decbin returns in it
  511. bsrl __x_decbin
  512. fmovex fp0,a6@(ETEMP) | put the unpacked sop in the fsave stack
  513. fmovemx a7@+,fp0-fp1
  514. fmovel #0,FPSR | clr fpsr from __x_decbin
  515. jra  finish
  516. |
  517. | Special handling for packed move in:  Same results as all other
  518. | packed cases, but we must set the FPSR condition codes properly.
  519. |
  520. move_unpack:
  521. movew a6@(ETEMP),d0 | get word with inf information
  522. bfextu d0{#20:#12},d1 | get exponent into d1
  523. cmpiw #0x0fff,d1 | test for inf or NaN
  524. jne  mtry_zero | if not equal, it is not special
  525. bfextu d0{#17:#3},d1 | get SE and y bits into d1
  526. cmpiw #7,d1 | SE and y bits must be on for special
  527. jne  mtry_zero | if not on, it is not special
  528. |input is of the special cases of inf and NaN
  529. tstl a6@(ETEMP_HI) | check ms mantissa
  530. jne  mfix_nan | if non-zero, it is a NaN
  531. tstl a6@(ETEMP_LO) | check ls mantissa
  532. jne  mfix_nan | if non-zero, it is a NaN
  533. |input is inf
  534. orl #inf_mask,a6@(USER_FPSR) | set I bit
  535. tstl a6@(ETEMP) | check sign
  536. jge  finish
  537. orl #neg_mask,a6@(USER_FPSR) | set N bit
  538. jra  finish | special already on stack
  539. mfix_nan:
  540. orl #nan_mask,a6@(USER_FPSR) | set NaN bit
  541. moveb #nan_tag,a6@(STAG) | set stag to NaN
  542. btst #signan_bit,a6@(ETEMP_HI) | test for snan
  543. jne  mn_snan
  544. orl #__x_snaniop_mask,a6@(USER_FPSR) | set snan bit
  545. btst #__x_snan_bit,a6@(fpcr_ENABLE) | test for snan enabled
  546. jne  mn_snan
  547. bset #signan_bit,a6@(ETEMP_HI) | force snans to qnans
  548. mn_snan:
  549. tstl a6@(ETEMP) | check for sign
  550. jge  finish | if clr, go on
  551. orl #neg_mask,a6@(USER_FPSR) | set N bit
  552. jra  finish
  553. mtry_zero:
  554. movew a6@(ETEMP_EX+2),d0 | get word 4
  555. andiw #0x000f,d0 | clear all but last ni(y)bble
  556. tstw d0 | check for zero.
  557. jne  mnot_spec
  558. tstl a6@(ETEMP_HI) | check words 3 and 2
  559. jne  mnot_spec
  560. tstl a6@(ETEMP_LO) | check words 1 and 0
  561. jne  mnot_spec
  562. tstl a6@(ETEMP) | test sign of the zero
  563. jge  mpos_zero
  564. orl #neg_mask+z_mask,a6@(USER_FPSR) | set N and Z
  565. movel #0x80000000,a6@(ETEMP) | write neg zero to etemp
  566. clrl a6@(ETEMP_HI)
  567. clrl a6@(ETEMP_LO)
  568. jra  finish
  569. mpos_zero:
  570. orl #z_mask,a6@(USER_FPSR) | set Z
  571. clrl a6@(ETEMP)
  572. clrl a6@(ETEMP_HI)
  573. clrl a6@(ETEMP_LO)
  574. jra  finish
  575. mnot_spec:
  576. fmovemx fp0-fp1,a7@- | save fp0 - __x_decbin returns in it
  577. bsrl __x_decbin
  578. fmovex fp0,a6@(ETEMP)
  579. | | put the unpacked sop in the fsave stack
  580. fmovemx a7@+,fp0-fp1
  581. finish:
  582. movew a6@(CMDREG1B),d0 | get the command word
  583. andw #0xfbff,d0 | change the source specifier field to
  584. | | extended (was packed).
  585. movew d0,a6@(CMDREG1B) | write command word back to fsave stack
  586. | | we need to do this so the 040 will
  587. | | re-execute the inst. without taking
  588. | | another packed trap.
  589. fix_stag:
  590. |Converted result is now in etemp on fsave stack, now set the source
  591. |tag (stag)
  592. | if (ete =0x7fff) then INF or NAN
  593. | if (etemp = $x.0----0) then
  594. | stag = INF
  595. | else
  596. | stag = NAN
  597. | else
  598. | if (ete = 0x0000) then
  599. | stag = ZERO
  600. | else
  601. | stag = NORM
  602. |
  603. | Note also that the etemp_15 bit (just right of the stag) must
  604. | be set accordingly.
  605. |
  606. movew a6@(ETEMP_EX),d1
  607. andiw #0x7fff,d1   | strip sign
  608. cmpw   #0x7fff,d1
  609. jne    z_or_nrm
  610. movel a6@(ETEMP_HI),d1
  611. jne  is_nan
  612. movel a6@(ETEMP_LO),d1
  613. jne  is_nan
  614. is_inf:
  615. moveb #0x40,a6@(STAG)
  616. movel #0x40,d0
  617. rts
  618. is_nan:
  619. moveb #0x60,a6@(STAG)
  620. movel #0x60,d0
  621. rts
  622. z_or_nrm:
  623. tstw d1
  624. jne  is_nrm
  625. is_zro:
  626. | For a zero, set etemp_15
  627. moveb #0x30,a6@(STAG)
  628. movel #0x20,d0
  629. rts
  630. is_nrm:
  631. | For a norm, check if the exp <= 0x3fff|  if so, set etemp_15
  632. cmpiw #0x3fff,d1
  633. jle  set_bit15
  634. moveb #0,a6@(STAG)
  635. jra  end_is_nrm
  636. set_bit15:
  637. moveb #0x10,a6@(STAG)
  638. end_is_nrm:
  639. movel #0,d0
  640. end_fix:
  641. rts
  642. end_get:
  643. rts
  644. | end