18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| get_op.sa 3.6 5/19/92 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| get_op.sa 3.5 4/26/91 58c2ecf20Sopenharmony_ci| 68c2ecf20Sopenharmony_ci| Description: This routine is called by the unsupported format/data 78c2ecf20Sopenharmony_ci| type exception handler ('unsupp' - vector 55) and the unimplemented 88c2ecf20Sopenharmony_ci| instruction exception handler ('unimp' - vector 11). 'get_op' 98c2ecf20Sopenharmony_ci| determines the opclass (0, 2, or 3) and branches to the 108c2ecf20Sopenharmony_ci| opclass handler routine. See 68881/2 User's Manual table 4-11 118c2ecf20Sopenharmony_ci| for a description of the opclasses. 128c2ecf20Sopenharmony_ci| 138c2ecf20Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) and for 148c2ecf20Sopenharmony_ci| UNIMPLEMENTED instructions (exception vector 11) the following 158c2ecf20Sopenharmony_ci| applies: 168c2ecf20Sopenharmony_ci| 178c2ecf20Sopenharmony_ci| - For unnormalized numbers (opclass 0, 2, or 3) the 188c2ecf20Sopenharmony_ci| number(s) is normalized and the operand type tag is updated. 198c2ecf20Sopenharmony_ci| 208c2ecf20Sopenharmony_ci| - For a packed number (opclass 2) the number is unpacked and the 218c2ecf20Sopenharmony_ci| operand type tag is updated. 228c2ecf20Sopenharmony_ci| 238c2ecf20Sopenharmony_ci| - For denormalized numbers (opclass 0 or 2) the number(s) is not 248c2ecf20Sopenharmony_ci| changed but passed to the next module. The next module for 258c2ecf20Sopenharmony_ci| unimp is do_func, the next module for unsupp is res_func. 268c2ecf20Sopenharmony_ci| 278c2ecf20Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) only the 288c2ecf20Sopenharmony_ci| following applies: 298c2ecf20Sopenharmony_ci| 308c2ecf20Sopenharmony_ci| - If there is a move out with a packed number (opclass 3) the 318c2ecf20Sopenharmony_ci| number is packed and written to user memory. For the other 328c2ecf20Sopenharmony_ci| opclasses the number(s) are written back to the fsave stack 338c2ecf20Sopenharmony_ci| and the instruction is then restored back into the '040. The 348c2ecf20Sopenharmony_ci| '040 is then able to complete the instruction. 358c2ecf20Sopenharmony_ci| 368c2ecf20Sopenharmony_ci| For example: 378c2ecf20Sopenharmony_ci| fadd.x fpm,fpn where the fpm contains an unnormalized number. 388c2ecf20Sopenharmony_ci| The '040 takes an unsupported data trap and gets to this 398c2ecf20Sopenharmony_ci| routine. The number is normalized, put back on the stack and 408c2ecf20Sopenharmony_ci| then an frestore is done to restore the instruction back into 418c2ecf20Sopenharmony_ci| the '040. The '040 then re-executes the fadd.x fpm,fpn with 428c2ecf20Sopenharmony_ci| a normalized number in the source and the instruction is 438c2ecf20Sopenharmony_ci| successful. 448c2ecf20Sopenharmony_ci| 458c2ecf20Sopenharmony_ci| Next consider if in the process of normalizing the un- 468c2ecf20Sopenharmony_ci| normalized number it becomes a denormalized number. The 478c2ecf20Sopenharmony_ci| routine which converts the unnorm to a norm (called mk_norm) 488c2ecf20Sopenharmony_ci| detects this and tags the number as a denorm. The routine 498c2ecf20Sopenharmony_ci| res_func sees the denorm tag and converts the denorm to a 508c2ecf20Sopenharmony_ci| norm. The instruction is then restored back into the '040 518c2ecf20Sopenharmony_ci| which re_executes the instruction. 528c2ecf20Sopenharmony_ci| 538c2ecf20Sopenharmony_ci| 548c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 558c2ecf20Sopenharmony_ci| All Rights Reserved 568c2ecf20Sopenharmony_ci| 578c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 588c2ecf20Sopenharmony_ci| file, README, in this same directory. 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ciGET_OP: |idnt 2,1 | Motorola 040 Floating Point Software Package 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci |section 8 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#include "fpsp.h" 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci .global PIRN,PIRZRM,PIRP 678c2ecf20Sopenharmony_ci .global SMALRN,SMALRZRM,SMALRP 688c2ecf20Sopenharmony_ci .global BIGRN,BIGRZRM,BIGRP 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciPIRN: 718c2ecf20Sopenharmony_ci .long 0x40000000,0xc90fdaa2,0x2168c235 |pi 728c2ecf20Sopenharmony_ciPIRZRM: 738c2ecf20Sopenharmony_ci .long 0x40000000,0xc90fdaa2,0x2168c234 |pi 748c2ecf20Sopenharmony_ciPIRP: 758c2ecf20Sopenharmony_ci .long 0x40000000,0xc90fdaa2,0x2168c235 |pi 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci|round to nearest 788c2ecf20Sopenharmony_ciSMALRN: 798c2ecf20Sopenharmony_ci .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2) 808c2ecf20Sopenharmony_ci .long 0x40000000,0xadf85458,0xa2bb4a9a |e 818c2ecf20Sopenharmony_ci .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e) 828c2ecf20Sopenharmony_ci .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 838c2ecf20Sopenharmony_ci .long 0x00000000,0x00000000,0x00000000 |0.0 848c2ecf20Sopenharmony_ci| round to zero;round to negative infinity 858c2ecf20Sopenharmony_ciSMALRZRM: 868c2ecf20Sopenharmony_ci .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2) 878c2ecf20Sopenharmony_ci .long 0x40000000,0xadf85458,0xa2bb4a9a |e 888c2ecf20Sopenharmony_ci .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb |log2(e) 898c2ecf20Sopenharmony_ci .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 908c2ecf20Sopenharmony_ci .long 0x00000000,0x00000000,0x00000000 |0.0 918c2ecf20Sopenharmony_ci| round to positive infinity 928c2ecf20Sopenharmony_ciSMALRP: 938c2ecf20Sopenharmony_ci .long 0x3ffd0000,0x9a209a84,0xfbcff799 |log10(2) 948c2ecf20Sopenharmony_ci .long 0x40000000,0xadf85458,0xa2bb4a9b |e 958c2ecf20Sopenharmony_ci .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e) 968c2ecf20Sopenharmony_ci .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 978c2ecf20Sopenharmony_ci .long 0x00000000,0x00000000,0x00000000 |0.0 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci|round to nearest 1008c2ecf20Sopenharmony_ciBIGRN: 1018c2ecf20Sopenharmony_ci .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2) 1028c2ecf20Sopenharmony_ci .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10) 1038c2ecf20Sopenharmony_ci .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci .global PTENRN 1068c2ecf20Sopenharmony_ciPTENRN: 1078c2ecf20Sopenharmony_ci .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 1088c2ecf20Sopenharmony_ci .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 1098c2ecf20Sopenharmony_ci .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 1108c2ecf20Sopenharmony_ci .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 1118c2ecf20Sopenharmony_ci .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 1128c2ecf20Sopenharmony_ci .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32 1138c2ecf20Sopenharmony_ci .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64 1148c2ecf20Sopenharmony_ci .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128 1158c2ecf20Sopenharmony_ci .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256 1168c2ecf20Sopenharmony_ci .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512 1178c2ecf20Sopenharmony_ci .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024 1188c2ecf20Sopenharmony_ci .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048 1198c2ecf20Sopenharmony_ci .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096 1208c2ecf20Sopenharmony_ci|round to minus infinity 1218c2ecf20Sopenharmony_ciBIGRZRM: 1228c2ecf20Sopenharmony_ci .long 0x3ffe0000,0xb17217f7,0xd1cf79ab |ln(2) 1238c2ecf20Sopenharmony_ci .long 0x40000000,0x935d8ddd,0xaaa8ac16 |ln(10) 1248c2ecf20Sopenharmony_ci .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci .global PTENRM 1278c2ecf20Sopenharmony_ciPTENRM: 1288c2ecf20Sopenharmony_ci .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 1298c2ecf20Sopenharmony_ci .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 1308c2ecf20Sopenharmony_ci .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 1318c2ecf20Sopenharmony_ci .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 1328c2ecf20Sopenharmony_ci .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 1338c2ecf20Sopenharmony_ci .long 0x40690000,0x9DC5ADA8,0x2B70B59D |10 ^ 32 1348c2ecf20Sopenharmony_ci .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64 1358c2ecf20Sopenharmony_ci .long 0x41A80000,0x93BA47C9,0x80E98CDF |10 ^ 128 1368c2ecf20Sopenharmony_ci .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D |10 ^ 256 1378c2ecf20Sopenharmony_ci .long 0x46A30000,0xE319A0AE,0xA60E91C6 |10 ^ 512 1388c2ecf20Sopenharmony_ci .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024 1398c2ecf20Sopenharmony_ci .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048 1408c2ecf20Sopenharmony_ci .long 0x75250000,0xC4605202,0x8A20979A |10 ^ 4096 1418c2ecf20Sopenharmony_ci|round to positive infinity 1428c2ecf20Sopenharmony_ciBIGRP: 1438c2ecf20Sopenharmony_ci .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2) 1448c2ecf20Sopenharmony_ci .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10) 1458c2ecf20Sopenharmony_ci .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci .global PTENRP 1488c2ecf20Sopenharmony_ciPTENRP: 1498c2ecf20Sopenharmony_ci .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 1508c2ecf20Sopenharmony_ci .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 1518c2ecf20Sopenharmony_ci .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 1528c2ecf20Sopenharmony_ci .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 1538c2ecf20Sopenharmony_ci .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 1548c2ecf20Sopenharmony_ci .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32 1558c2ecf20Sopenharmony_ci .long 0x40D30000,0xC2781F49,0xFFCFA6D6 |10 ^ 64 1568c2ecf20Sopenharmony_ci .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128 1578c2ecf20Sopenharmony_ci .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256 1588c2ecf20Sopenharmony_ci .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512 1598c2ecf20Sopenharmony_ci .long 0x4D480000,0xC9767586,0x81750C18 |10 ^ 1024 1608c2ecf20Sopenharmony_ci .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 |10 ^ 2048 1618c2ecf20Sopenharmony_ci .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci |xref nrm_zero 1648c2ecf20Sopenharmony_ci |xref decbin 1658c2ecf20Sopenharmony_ci |xref round 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci .global get_op 1688c2ecf20Sopenharmony_ci .global uns_getop 1698c2ecf20Sopenharmony_ci .global uni_getop 1708c2ecf20Sopenharmony_ciget_op: 1718c2ecf20Sopenharmony_ci clrb DY_MO_FLG(%a6) 1728c2ecf20Sopenharmony_ci tstb UFLG_TMP(%a6) |test flag for unsupp/unimp state 1738c2ecf20Sopenharmony_ci beq uni_getop 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ciuns_getop: 1768c2ecf20Sopenharmony_ci btstb #direction_bit,CMDREG1B(%a6) 1778c2ecf20Sopenharmony_ci bne opclass3 |branch if a fmove out (any kind) 1788c2ecf20Sopenharmony_ci btstb #6,CMDREG1B(%a6) 1798c2ecf20Sopenharmony_ci beqs uns_notpacked 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci bfextu CMDREG1B(%a6){#3:#3},%d0 1828c2ecf20Sopenharmony_ci cmpb #3,%d0 1838c2ecf20Sopenharmony_ci beq pack_source |check for a packed src op, branch if so 1848c2ecf20Sopenharmony_ciuns_notpacked: 1858c2ecf20Sopenharmony_ci bsr chk_dy_mo |set the dyadic/monadic flag 1868c2ecf20Sopenharmony_ci tstb DY_MO_FLG(%a6) 1878c2ecf20Sopenharmony_ci beqs src_op_ck |if monadic, go check src op 1888c2ecf20Sopenharmony_ci| ;else, check dst op (fall through) 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci btstb #7,DTAG(%a6) 1918c2ecf20Sopenharmony_ci beqs src_op_ck |if dst op is norm, check src op 1928c2ecf20Sopenharmony_ci bras dst_ex_dnrm |else, handle destination unnorm/dnrm 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciuni_getop: 1958c2ecf20Sopenharmony_ci bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields 1968c2ecf20Sopenharmony_ci cmpil #0x17,%d0 |if op class and size fields are $17, 1978c2ecf20Sopenharmony_ci| ;it is FMOVECR; if not, continue 1988c2ecf20Sopenharmony_ci| 1998c2ecf20Sopenharmony_ci| If the instruction is fmovecr, exit get_op. It is handled 2008c2ecf20Sopenharmony_ci| in do_func and smovecr.sa. 2018c2ecf20Sopenharmony_ci| 2028c2ecf20Sopenharmony_ci bne not_fmovecr |handle fmovecr as an unimplemented inst 2038c2ecf20Sopenharmony_ci rts 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cinot_fmovecr: 2068c2ecf20Sopenharmony_ci btstb #E1,E_BYTE(%a6) |if set, there is a packed operand 2078c2ecf20Sopenharmony_ci bne pack_source |check for packed src op, branch if so 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci| The following lines of are coded to optimize on normalized operands 2108c2ecf20Sopenharmony_ci moveb STAG(%a6),%d0 2118c2ecf20Sopenharmony_ci orb DTAG(%a6),%d0 |check if either of STAG/DTAG msb set 2128c2ecf20Sopenharmony_ci bmis dest_op_ck |if so, some op needs to be fixed 2138c2ecf20Sopenharmony_ci rts 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cidest_op_ck: 2168c2ecf20Sopenharmony_ci btstb #7,DTAG(%a6) |check for unsupported data types in 2178c2ecf20Sopenharmony_ci beqs src_op_ck |the destination, if not, check src op 2188c2ecf20Sopenharmony_ci bsr chk_dy_mo |set dyadic/monadic flag 2198c2ecf20Sopenharmony_ci tstb DY_MO_FLG(%a6) | 2208c2ecf20Sopenharmony_ci beqs src_op_ck |if monadic, check src op 2218c2ecf20Sopenharmony_ci| 2228c2ecf20Sopenharmony_ci| At this point, destination has an extended denorm or unnorm. 2238c2ecf20Sopenharmony_ci| 2248c2ecf20Sopenharmony_cidst_ex_dnrm: 2258c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 |get destination exponent 2268c2ecf20Sopenharmony_ci andiw #0x7fff,%d0 |mask sign, check if exp = 0000 2278c2ecf20Sopenharmony_ci beqs src_op_ck |if denorm then check source op. 2288c2ecf20Sopenharmony_ci| ;denorms are taken care of in res_func 2298c2ecf20Sopenharmony_ci| ;(unsupp) or do_func (unimp) 2308c2ecf20Sopenharmony_ci| ;else unnorm fall through 2318c2ecf20Sopenharmony_ci leal FPTEMP(%a6),%a0 |point a0 to dop - used in mk_norm 2328c2ecf20Sopenharmony_ci bsr mk_norm |go normalize - mk_norm returns: 2338c2ecf20Sopenharmony_ci| ;L_SCR1{7:5} = operand tag 2348c2ecf20Sopenharmony_ci| ; (000 = norm, 100 = denorm) 2358c2ecf20Sopenharmony_ci| ;L_SCR1{4} = fpte15 or ete15 2368c2ecf20Sopenharmony_ci| ; 0 = exp > $3fff 2378c2ecf20Sopenharmony_ci| ; 1 = exp <= $3fff 2388c2ecf20Sopenharmony_ci| ;and puts the normalized num back 2398c2ecf20Sopenharmony_ci| ;on the fsave stack 2408c2ecf20Sopenharmony_ci| 2418c2ecf20Sopenharmony_ci moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15 2428c2ecf20Sopenharmony_ci| ;to the fsave stack and fall 2438c2ecf20Sopenharmony_ci| ;through to check source operand 2448c2ecf20Sopenharmony_ci| 2458c2ecf20Sopenharmony_cisrc_op_ck: 2468c2ecf20Sopenharmony_ci btstb #7,STAG(%a6) 2478c2ecf20Sopenharmony_ci beq end_getop |check for unsupported data types on the 2488c2ecf20Sopenharmony_ci| ;source operand 2498c2ecf20Sopenharmony_ci btstb #5,STAG(%a6) 2508c2ecf20Sopenharmony_ci bnes src_sd_dnrm |if bit 5 set, handle sgl/dbl denorms 2518c2ecf20Sopenharmony_ci| 2528c2ecf20Sopenharmony_ci| At this point only unnorms or extended denorms are possible. 2538c2ecf20Sopenharmony_ci| 2548c2ecf20Sopenharmony_cisrc_ex_dnrm: 2558c2ecf20Sopenharmony_ci movew ETEMP_EX(%a6),%d0 |get source exponent 2568c2ecf20Sopenharmony_ci andiw #0x7fff,%d0 |mask sign, check if exp = 0000 2578c2ecf20Sopenharmony_ci beq end_getop |if denorm then exit, denorms are 2588c2ecf20Sopenharmony_ci| ;handled in do_func 2598c2ecf20Sopenharmony_ci leal ETEMP(%a6),%a0 |point a0 to sop - used in mk_norm 2608c2ecf20Sopenharmony_ci bsr mk_norm |go normalize - mk_norm returns: 2618c2ecf20Sopenharmony_ci| ;L_SCR1{7:5} = operand tag 2628c2ecf20Sopenharmony_ci| ; (000 = norm, 100 = denorm) 2638c2ecf20Sopenharmony_ci| ;L_SCR1{4} = fpte15 or ete15 2648c2ecf20Sopenharmony_ci| ; 0 = exp > $3fff 2658c2ecf20Sopenharmony_ci| ; 1 = exp <= $3fff 2668c2ecf20Sopenharmony_ci| ;and puts the normalized num back 2678c2ecf20Sopenharmony_ci| ;on the fsave stack 2688c2ecf20Sopenharmony_ci| 2698c2ecf20Sopenharmony_ci moveb L_SCR1(%a6),STAG(%a6) |write the new tag & ete15 2708c2ecf20Sopenharmony_ci rts |end_getop 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci| 2738c2ecf20Sopenharmony_ci| At this point, only single or double denorms are possible. 2748c2ecf20Sopenharmony_ci| If the inst is not fmove, normalize the source. If it is, 2758c2ecf20Sopenharmony_ci| do nothing to the input. 2768c2ecf20Sopenharmony_ci| 2778c2ecf20Sopenharmony_cisrc_sd_dnrm: 2788c2ecf20Sopenharmony_ci btstb #4,CMDREG1B(%a6) |differentiate between sgl/dbl denorm 2798c2ecf20Sopenharmony_ci bnes is_double 2808c2ecf20Sopenharmony_ciis_single: 2818c2ecf20Sopenharmony_ci movew #0x3f81,%d1 |write bias for sgl denorm 2828c2ecf20Sopenharmony_ci bras common |goto the common code 2838c2ecf20Sopenharmony_ciis_double: 2848c2ecf20Sopenharmony_ci movew #0x3c01,%d1 |write the bias for a dbl denorm 2858c2ecf20Sopenharmony_cicommon: 2868c2ecf20Sopenharmony_ci btstb #sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa 2878c2ecf20Sopenharmony_ci beqs pos 2888c2ecf20Sopenharmony_ci bset #15,%d1 |set sign bit because it is negative 2898c2ecf20Sopenharmony_cipos: 2908c2ecf20Sopenharmony_ci movew %d1,ETEMP_EX(%a6) 2918c2ecf20Sopenharmony_ci| ;put exponent on stack 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci movew CMDREG1B(%a6),%d1 2948c2ecf20Sopenharmony_ci andw #0xe3ff,%d1 |clear out source specifier 2958c2ecf20Sopenharmony_ci orw #0x0800,%d1 |set source specifier to extended prec 2968c2ecf20Sopenharmony_ci movew %d1,CMDREG1B(%a6) |write back to the command word in stack 2978c2ecf20Sopenharmony_ci| ;this is needed to fix unsupp data stack 2988c2ecf20Sopenharmony_ci leal ETEMP(%a6),%a0 |point a0 to sop 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci bsr mk_norm |convert sgl/dbl denorm to norm 3018c2ecf20Sopenharmony_ci moveb L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0 3028c2ecf20Sopenharmony_ci rts |end_getop 3038c2ecf20Sopenharmony_ci| 3048c2ecf20Sopenharmony_ci| At this point, the source is definitely packed, whether 3058c2ecf20Sopenharmony_ci| instruction is dyadic or monadic is still unknown 3068c2ecf20Sopenharmony_ci| 3078c2ecf20Sopenharmony_cipack_source: 3088c2ecf20Sopenharmony_ci movel FPTEMP_LO(%a6),ETEMP(%a6) |write ms part of packed 3098c2ecf20Sopenharmony_ci| ;number to etemp slot 3108c2ecf20Sopenharmony_ci bsr chk_dy_mo |set dyadic/monadic flag 3118c2ecf20Sopenharmony_ci bsr unpack 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci tstb DY_MO_FLG(%a6) 3148c2ecf20Sopenharmony_ci beqs end_getop |if monadic, exit 3158c2ecf20Sopenharmony_ci| ;else, fix FPTEMP 3168c2ecf20Sopenharmony_cipack_dya: 3178c2ecf20Sopenharmony_ci bfextu CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg 3188c2ecf20Sopenharmony_ci movel #7,%d1 3198c2ecf20Sopenharmony_ci subl %d0,%d1 3208c2ecf20Sopenharmony_ci clrl %d0 3218c2ecf20Sopenharmony_ci bsetl %d1,%d0 |set up d0 as a dynamic register mask 3228c2ecf20Sopenharmony_ci fmovemx %d0,FPTEMP(%a6) |write to FPTEMP 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci btstb #7,DTAG(%a6) |check dest tag for unnorm or denorm 3258c2ecf20Sopenharmony_ci bne dst_ex_dnrm |else, handle the unnorm or ext denorm 3268c2ecf20Sopenharmony_ci| 3278c2ecf20Sopenharmony_ci| Dest is not denormalized. Check for norm, and set fpte15 3288c2ecf20Sopenharmony_ci| accordingly. 3298c2ecf20Sopenharmony_ci| 3308c2ecf20Sopenharmony_ci moveb DTAG(%a6),%d0 3318c2ecf20Sopenharmony_ci andib #0xf0,%d0 |strip to only dtag:fpte15 3328c2ecf20Sopenharmony_ci tstb %d0 |check for normalized value 3338c2ecf20Sopenharmony_ci bnes end_getop |if inf/nan/zero leave get_op 3348c2ecf20Sopenharmony_ci movew FPTEMP_EX(%a6),%d0 3358c2ecf20Sopenharmony_ci andiw #0x7fff,%d0 3368c2ecf20Sopenharmony_ci cmpiw #0x3fff,%d0 |check if fpte15 needs setting 3378c2ecf20Sopenharmony_ci bges end_getop |if >= $3fff, leave fpte15=0 3388c2ecf20Sopenharmony_ci orb #0x10,DTAG(%a6) 3398c2ecf20Sopenharmony_ci bras end_getop 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci| 3428c2ecf20Sopenharmony_ci| At this point, it is either an fmoveout packed, unnorm or denorm 3438c2ecf20Sopenharmony_ci| 3448c2ecf20Sopenharmony_ciopclass3: 3458c2ecf20Sopenharmony_ci clrb DY_MO_FLG(%a6) |set dyadic/monadic flag to monadic 3468c2ecf20Sopenharmony_ci bfextu CMDREG1B(%a6){#4:#2},%d0 3478c2ecf20Sopenharmony_ci cmpib #3,%d0 3488c2ecf20Sopenharmony_ci bne src_ex_dnrm |if not equal, must be unnorm or denorm 3498c2ecf20Sopenharmony_ci| ;else it is a packed move out 3508c2ecf20Sopenharmony_ci| ;exit 3518c2ecf20Sopenharmony_ciend_getop: 3528c2ecf20Sopenharmony_ci rts 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci| 3558c2ecf20Sopenharmony_ci| Sets the DY_MO_FLG correctly. This is used only on if it is an 3568c2ecf20Sopenharmony_ci| unsupported data type exception. Set if dyadic. 3578c2ecf20Sopenharmony_ci| 3588c2ecf20Sopenharmony_cichk_dy_mo: 3598c2ecf20Sopenharmony_ci movew CMDREG1B(%a6),%d0 3608c2ecf20Sopenharmony_ci btstl #5,%d0 |testing extension command word 3618c2ecf20Sopenharmony_ci beqs set_mon |if bit 5 = 0 then monadic 3628c2ecf20Sopenharmony_ci btstl #4,%d0 |know that bit 5 = 1 3638c2ecf20Sopenharmony_ci beqs set_dya |if bit 4 = 0 then dyadic 3648c2ecf20Sopenharmony_ci andiw #0x007f,%d0 |get rid of all but extension bits {6:0} 3658c2ecf20Sopenharmony_ci cmpiw #0x0038,%d0 |if extension = $38 then fcmp (dyadic) 3668c2ecf20Sopenharmony_ci bnes set_mon 3678c2ecf20Sopenharmony_ciset_dya: 3688c2ecf20Sopenharmony_ci st DY_MO_FLG(%a6) |set the inst flag type to dyadic 3698c2ecf20Sopenharmony_ci rts 3708c2ecf20Sopenharmony_ciset_mon: 3718c2ecf20Sopenharmony_ci clrb DY_MO_FLG(%a6) |set the inst flag type to monadic 3728c2ecf20Sopenharmony_ci rts 3738c2ecf20Sopenharmony_ci| 3748c2ecf20Sopenharmony_ci| MK_NORM 3758c2ecf20Sopenharmony_ci| 3768c2ecf20Sopenharmony_ci| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl 3778c2ecf20Sopenharmony_ci| exception if denorm. 3788c2ecf20Sopenharmony_ci| 3798c2ecf20Sopenharmony_ci| CASE opclass 0x0 unsupp 3808c2ecf20Sopenharmony_ci| mk_norm till msb set 3818c2ecf20Sopenharmony_ci| set tag = norm 3828c2ecf20Sopenharmony_ci| 3838c2ecf20Sopenharmony_ci| CASE opclass 0x0 unimp 3848c2ecf20Sopenharmony_ci| mk_norm till msb set or exp = 0 3858c2ecf20Sopenharmony_ci| if integer bit = 0 3868c2ecf20Sopenharmony_ci| tag = denorm 3878c2ecf20Sopenharmony_ci| else 3888c2ecf20Sopenharmony_ci| tag = norm 3898c2ecf20Sopenharmony_ci| 3908c2ecf20Sopenharmony_ci| CASE opclass 011 unsupp 3918c2ecf20Sopenharmony_ci| mk_norm till msb set or exp = 0 3928c2ecf20Sopenharmony_ci| if integer bit = 0 3938c2ecf20Sopenharmony_ci| tag = denorm 3948c2ecf20Sopenharmony_ci| set unfl_nmcexe = 1 3958c2ecf20Sopenharmony_ci| else 3968c2ecf20Sopenharmony_ci| tag = norm 3978c2ecf20Sopenharmony_ci| 3988c2ecf20Sopenharmony_ci| if exp <= $3fff 3998c2ecf20Sopenharmony_ci| set ete15 or fpte15 = 1 4008c2ecf20Sopenharmony_ci| else set ete15 or fpte15 = 0 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci| input: 4038c2ecf20Sopenharmony_ci| a0 = points to operand to be normalized 4048c2ecf20Sopenharmony_ci| output: 4058c2ecf20Sopenharmony_ci| L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) 4068c2ecf20Sopenharmony_ci| L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) 4078c2ecf20Sopenharmony_ci| the normalized operand is placed back on the fsave stack 4088c2ecf20Sopenharmony_cimk_norm: 4098c2ecf20Sopenharmony_ci clrl L_SCR1(%a6) 4108c2ecf20Sopenharmony_ci bclrb #sign_bit,LOCAL_EX(%a0) 4118c2ecf20Sopenharmony_ci sne LOCAL_SGN(%a0) |transform into internal extended format 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci cmpib #0x2c,1+EXC_VEC(%a6) |check if unimp 4148c2ecf20Sopenharmony_ci bnes uns_data |branch if unsupp 4158c2ecf20Sopenharmony_ci bsr uni_inst |call if unimp (opclass 0x0) 4168c2ecf20Sopenharmony_ci bras reload 4178c2ecf20Sopenharmony_ciuns_data: 4188c2ecf20Sopenharmony_ci btstb #direction_bit,CMDREG1B(%a6) |check transfer direction 4198c2ecf20Sopenharmony_ci bnes bit_set |branch if set (opclass 011) 4208c2ecf20Sopenharmony_ci bsr uns_opx |call if opclass 0x0 4218c2ecf20Sopenharmony_ci bras reload 4228c2ecf20Sopenharmony_cibit_set: 4238c2ecf20Sopenharmony_ci bsr uns_op3 |opclass 011 4248c2ecf20Sopenharmony_cireload: 4258c2ecf20Sopenharmony_ci cmpw #0x3fff,LOCAL_EX(%a0) |if exp > $3fff 4268c2ecf20Sopenharmony_ci bgts end_mk | fpte15/ete15 already set to 0 4278c2ecf20Sopenharmony_ci bsetb #4,L_SCR1(%a6) |else set fpte15/ete15 to 1 4288c2ecf20Sopenharmony_ci| ;calling routine actually sets the 4298c2ecf20Sopenharmony_ci| ;value on the stack (along with the 4308c2ecf20Sopenharmony_ci| ;tag), since this routine doesn't 4318c2ecf20Sopenharmony_ci| ;know if it should set ete15 or fpte15 4328c2ecf20Sopenharmony_ci| ;ie, it doesn't know if this is the 4338c2ecf20Sopenharmony_ci| ;src op or dest op. 4348c2ecf20Sopenharmony_ciend_mk: 4358c2ecf20Sopenharmony_ci bfclr LOCAL_SGN(%a0){#0:#8} 4368c2ecf20Sopenharmony_ci beqs end_mk_pos 4378c2ecf20Sopenharmony_ci bsetb #sign_bit,LOCAL_EX(%a0) |convert back to IEEE format 4388c2ecf20Sopenharmony_ciend_mk_pos: 4398c2ecf20Sopenharmony_ci rts 4408c2ecf20Sopenharmony_ci| 4418c2ecf20Sopenharmony_ci| CASE opclass 011 unsupp 4428c2ecf20Sopenharmony_ci| 4438c2ecf20Sopenharmony_ciuns_op3: 4448c2ecf20Sopenharmony_ci bsr nrm_zero |normalize till msb = 1 or exp = zero 4458c2ecf20Sopenharmony_ci btstb #7,LOCAL_HI(%a0) |if msb = 1 4468c2ecf20Sopenharmony_ci bnes no_unfl |then branch 4478c2ecf20Sopenharmony_ciset_unfl: 4488c2ecf20Sopenharmony_ci orw #dnrm_tag,L_SCR1(%a6) |set denorm tag 4498c2ecf20Sopenharmony_ci bsetb #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit 4508c2ecf20Sopenharmony_cino_unfl: 4518c2ecf20Sopenharmony_ci rts 4528c2ecf20Sopenharmony_ci| 4538c2ecf20Sopenharmony_ci| CASE opclass 0x0 unsupp 4548c2ecf20Sopenharmony_ci| 4558c2ecf20Sopenharmony_ciuns_opx: 4568c2ecf20Sopenharmony_ci bsr nrm_zero |normalize the number 4578c2ecf20Sopenharmony_ci btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set 4588c2ecf20Sopenharmony_ci beqs uns_den |if clear then now have a denorm 4598c2ecf20Sopenharmony_ciuns_nrm: 4608c2ecf20Sopenharmony_ci orb #norm_tag,L_SCR1(%a6) |set tag to norm 4618c2ecf20Sopenharmony_ci rts 4628c2ecf20Sopenharmony_ciuns_den: 4638c2ecf20Sopenharmony_ci orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm 4648c2ecf20Sopenharmony_ci rts 4658c2ecf20Sopenharmony_ci| 4668c2ecf20Sopenharmony_ci| CASE opclass 0x0 unimp 4678c2ecf20Sopenharmony_ci| 4688c2ecf20Sopenharmony_ciuni_inst: 4698c2ecf20Sopenharmony_ci bsr nrm_zero 4708c2ecf20Sopenharmony_ci btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set 4718c2ecf20Sopenharmony_ci beqs uni_den |if clear then now have a denorm 4728c2ecf20Sopenharmony_ciuni_nrm: 4738c2ecf20Sopenharmony_ci orb #norm_tag,L_SCR1(%a6) |set tag to norm 4748c2ecf20Sopenharmony_ci rts 4758c2ecf20Sopenharmony_ciuni_den: 4768c2ecf20Sopenharmony_ci orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm 4778c2ecf20Sopenharmony_ci rts 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci| 4808c2ecf20Sopenharmony_ci| Decimal to binary conversion 4818c2ecf20Sopenharmony_ci| 4828c2ecf20Sopenharmony_ci| Special cases of inf and NaNs are completed outside of decbin. 4838c2ecf20Sopenharmony_ci| If the input is an snan, the snan bit is not set. 4848c2ecf20Sopenharmony_ci| 4858c2ecf20Sopenharmony_ci| input: 4868c2ecf20Sopenharmony_ci| ETEMP(a6) - points to packed decimal string in memory 4878c2ecf20Sopenharmony_ci| output: 4888c2ecf20Sopenharmony_ci| fp0 - contains packed string converted to extended precision 4898c2ecf20Sopenharmony_ci| ETEMP - same as fp0 4908c2ecf20Sopenharmony_ciunpack: 4918c2ecf20Sopenharmony_ci movew CMDREG1B(%a6),%d0 |examine command word, looking for fmove's 4928c2ecf20Sopenharmony_ci andw #0x3b,%d0 4938c2ecf20Sopenharmony_ci beq move_unpack |special handling for fmove: must set FPSR_CC 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci movew ETEMP(%a6),%d0 |get word with inf information 4968c2ecf20Sopenharmony_ci bfextu %d0{#20:#12},%d1 |get exponent into d1 4978c2ecf20Sopenharmony_ci cmpiw #0x0fff,%d1 |test for inf or NaN 4988c2ecf20Sopenharmony_ci bnes try_zero |if not equal, it is not special 4998c2ecf20Sopenharmony_ci bfextu %d0{#17:#3},%d1 |get SE and y bits into d1 5008c2ecf20Sopenharmony_ci cmpiw #7,%d1 |SE and y bits must be on for special 5018c2ecf20Sopenharmony_ci bnes try_zero |if not on, it is not special 5028c2ecf20Sopenharmony_ci|input is of the special cases of inf and NaN 5038c2ecf20Sopenharmony_ci tstl ETEMP_HI(%a6) |check ms mantissa 5048c2ecf20Sopenharmony_ci bnes fix_nan |if non-zero, it is a NaN 5058c2ecf20Sopenharmony_ci tstl ETEMP_LO(%a6) |check ls mantissa 5068c2ecf20Sopenharmony_ci bnes fix_nan |if non-zero, it is a NaN 5078c2ecf20Sopenharmony_ci bra finish |special already on stack 5088c2ecf20Sopenharmony_cifix_nan: 5098c2ecf20Sopenharmony_ci btstb #signan_bit,ETEMP_HI(%a6) |test for snan 5108c2ecf20Sopenharmony_ci bne finish 5118c2ecf20Sopenharmony_ci orl #snaniop_mask,USER_FPSR(%a6) |always set snan if it is so 5128c2ecf20Sopenharmony_ci bra finish 5138c2ecf20Sopenharmony_citry_zero: 5148c2ecf20Sopenharmony_ci movew ETEMP_EX+2(%a6),%d0 |get word 4 5158c2ecf20Sopenharmony_ci andiw #0x000f,%d0 |clear all but last ni(y)bble 5168c2ecf20Sopenharmony_ci tstw %d0 |check for zero. 5178c2ecf20Sopenharmony_ci bne not_spec 5188c2ecf20Sopenharmony_ci tstl ETEMP_HI(%a6) |check words 3 and 2 5198c2ecf20Sopenharmony_ci bne not_spec 5208c2ecf20Sopenharmony_ci tstl ETEMP_LO(%a6) |check words 1 and 0 5218c2ecf20Sopenharmony_ci bne not_spec 5228c2ecf20Sopenharmony_ci tstl ETEMP(%a6) |test sign of the zero 5238c2ecf20Sopenharmony_ci bges pos_zero 5248c2ecf20Sopenharmony_ci movel #0x80000000,ETEMP(%a6) |write neg zero to etemp 5258c2ecf20Sopenharmony_ci clrl ETEMP_HI(%a6) 5268c2ecf20Sopenharmony_ci clrl ETEMP_LO(%a6) 5278c2ecf20Sopenharmony_ci bra finish 5288c2ecf20Sopenharmony_cipos_zero: 5298c2ecf20Sopenharmony_ci clrl ETEMP(%a6) 5308c2ecf20Sopenharmony_ci clrl ETEMP_HI(%a6) 5318c2ecf20Sopenharmony_ci clrl ETEMP_LO(%a6) 5328c2ecf20Sopenharmony_ci bra finish 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_cinot_spec: 5358c2ecf20Sopenharmony_ci fmovemx %fp0-%fp1,-(%a7) |save fp0 - decbin returns in it 5368c2ecf20Sopenharmony_ci bsr decbin 5378c2ecf20Sopenharmony_ci fmovex %fp0,ETEMP(%a6) |put the unpacked sop in the fsave stack 5388c2ecf20Sopenharmony_ci fmovemx (%a7)+,%fp0-%fp1 5398c2ecf20Sopenharmony_ci fmovel #0,%FPSR |clr fpsr from decbin 5408c2ecf20Sopenharmony_ci bra finish 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci| 5438c2ecf20Sopenharmony_ci| Special handling for packed move in: Same results as all other 5448c2ecf20Sopenharmony_ci| packed cases, but we must set the FPSR condition codes properly. 5458c2ecf20Sopenharmony_ci| 5468c2ecf20Sopenharmony_cimove_unpack: 5478c2ecf20Sopenharmony_ci movew ETEMP(%a6),%d0 |get word with inf information 5488c2ecf20Sopenharmony_ci bfextu %d0{#20:#12},%d1 |get exponent into d1 5498c2ecf20Sopenharmony_ci cmpiw #0x0fff,%d1 |test for inf or NaN 5508c2ecf20Sopenharmony_ci bnes mtry_zero |if not equal, it is not special 5518c2ecf20Sopenharmony_ci bfextu %d0{#17:#3},%d1 |get SE and y bits into d1 5528c2ecf20Sopenharmony_ci cmpiw #7,%d1 |SE and y bits must be on for special 5538c2ecf20Sopenharmony_ci bnes mtry_zero |if not on, it is not special 5548c2ecf20Sopenharmony_ci|input is of the special cases of inf and NaN 5558c2ecf20Sopenharmony_ci tstl ETEMP_HI(%a6) |check ms mantissa 5568c2ecf20Sopenharmony_ci bnes mfix_nan |if non-zero, it is a NaN 5578c2ecf20Sopenharmony_ci tstl ETEMP_LO(%a6) |check ls mantissa 5588c2ecf20Sopenharmony_ci bnes mfix_nan |if non-zero, it is a NaN 5598c2ecf20Sopenharmony_ci|input is inf 5608c2ecf20Sopenharmony_ci orl #inf_mask,USER_FPSR(%a6) |set I bit 5618c2ecf20Sopenharmony_ci tstl ETEMP(%a6) |check sign 5628c2ecf20Sopenharmony_ci bge finish 5638c2ecf20Sopenharmony_ci orl #neg_mask,USER_FPSR(%a6) |set N bit 5648c2ecf20Sopenharmony_ci bra finish |special already on stack 5658c2ecf20Sopenharmony_cimfix_nan: 5668c2ecf20Sopenharmony_ci orl #nan_mask,USER_FPSR(%a6) |set NaN bit 5678c2ecf20Sopenharmony_ci moveb #nan_tag,STAG(%a6) |set stag to NaN 5688c2ecf20Sopenharmony_ci btstb #signan_bit,ETEMP_HI(%a6) |test for snan 5698c2ecf20Sopenharmony_ci bnes mn_snan 5708c2ecf20Sopenharmony_ci orl #snaniop_mask,USER_FPSR(%a6) |set snan bit 5718c2ecf20Sopenharmony_ci btstb #snan_bit,FPCR_ENABLE(%a6) |test for snan enabled 5728c2ecf20Sopenharmony_ci bnes mn_snan 5738c2ecf20Sopenharmony_ci bsetb #signan_bit,ETEMP_HI(%a6) |force snans to qnans 5748c2ecf20Sopenharmony_cimn_snan: 5758c2ecf20Sopenharmony_ci tstl ETEMP(%a6) |check for sign 5768c2ecf20Sopenharmony_ci bge finish |if clr, go on 5778c2ecf20Sopenharmony_ci orl #neg_mask,USER_FPSR(%a6) |set N bit 5788c2ecf20Sopenharmony_ci bra finish 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_cimtry_zero: 5818c2ecf20Sopenharmony_ci movew ETEMP_EX+2(%a6),%d0 |get word 4 5828c2ecf20Sopenharmony_ci andiw #0x000f,%d0 |clear all but last ni(y)bble 5838c2ecf20Sopenharmony_ci tstw %d0 |check for zero. 5848c2ecf20Sopenharmony_ci bnes mnot_spec 5858c2ecf20Sopenharmony_ci tstl ETEMP_HI(%a6) |check words 3 and 2 5868c2ecf20Sopenharmony_ci bnes mnot_spec 5878c2ecf20Sopenharmony_ci tstl ETEMP_LO(%a6) |check words 1 and 0 5888c2ecf20Sopenharmony_ci bnes mnot_spec 5898c2ecf20Sopenharmony_ci tstl ETEMP(%a6) |test sign of the zero 5908c2ecf20Sopenharmony_ci bges mpos_zero 5918c2ecf20Sopenharmony_ci orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z 5928c2ecf20Sopenharmony_ci movel #0x80000000,ETEMP(%a6) |write neg zero to etemp 5938c2ecf20Sopenharmony_ci clrl ETEMP_HI(%a6) 5948c2ecf20Sopenharmony_ci clrl ETEMP_LO(%a6) 5958c2ecf20Sopenharmony_ci bras finish 5968c2ecf20Sopenharmony_cimpos_zero: 5978c2ecf20Sopenharmony_ci orl #z_mask,USER_FPSR(%a6) |set Z 5988c2ecf20Sopenharmony_ci clrl ETEMP(%a6) 5998c2ecf20Sopenharmony_ci clrl ETEMP_HI(%a6) 6008c2ecf20Sopenharmony_ci clrl ETEMP_LO(%a6) 6018c2ecf20Sopenharmony_ci bras finish 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_cimnot_spec: 6048c2ecf20Sopenharmony_ci fmovemx %fp0-%fp1,-(%a7) |save fp0 ,fp1 - decbin returns in fp0 6058c2ecf20Sopenharmony_ci bsr decbin 6068c2ecf20Sopenharmony_ci fmovex %fp0,ETEMP(%a6) 6078c2ecf20Sopenharmony_ci| ;put the unpacked sop in the fsave stack 6088c2ecf20Sopenharmony_ci fmovemx (%a7)+,%fp0-%fp1 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_cifinish: 6118c2ecf20Sopenharmony_ci movew CMDREG1B(%a6),%d0 |get the command word 6128c2ecf20Sopenharmony_ci andw #0xfbff,%d0 |change the source specifier field to 6138c2ecf20Sopenharmony_ci| ;extended (was packed). 6148c2ecf20Sopenharmony_ci movew %d0,CMDREG1B(%a6) |write command word back to fsave stack 6158c2ecf20Sopenharmony_ci| ;we need to do this so the 040 will 6168c2ecf20Sopenharmony_ci| ;re-execute the inst. without taking 6178c2ecf20Sopenharmony_ci| ;another packed trap. 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_cifix_stag: 6208c2ecf20Sopenharmony_ci|Converted result is now in etemp on fsave stack, now set the source 6218c2ecf20Sopenharmony_ci|tag (stag) 6228c2ecf20Sopenharmony_ci| if (ete =$7fff) then INF or NAN 6238c2ecf20Sopenharmony_ci| if (etemp = $x.0----0) then 6248c2ecf20Sopenharmony_ci| stag = INF 6258c2ecf20Sopenharmony_ci| else 6268c2ecf20Sopenharmony_ci| stag = NAN 6278c2ecf20Sopenharmony_ci| else 6288c2ecf20Sopenharmony_ci| if (ete = $0000) then 6298c2ecf20Sopenharmony_ci| stag = ZERO 6308c2ecf20Sopenharmony_ci| else 6318c2ecf20Sopenharmony_ci| stag = NORM 6328c2ecf20Sopenharmony_ci| 6338c2ecf20Sopenharmony_ci| Note also that the etemp_15 bit (just right of the stag) must 6348c2ecf20Sopenharmony_ci| be set accordingly. 6358c2ecf20Sopenharmony_ci| 6368c2ecf20Sopenharmony_ci movew ETEMP_EX(%a6),%d1 6378c2ecf20Sopenharmony_ci andiw #0x7fff,%d1 |strip sign 6388c2ecf20Sopenharmony_ci cmpw #0x7fff,%d1 6398c2ecf20Sopenharmony_ci bnes z_or_nrm 6408c2ecf20Sopenharmony_ci movel ETEMP_HI(%a6),%d1 6418c2ecf20Sopenharmony_ci bnes is_nan 6428c2ecf20Sopenharmony_ci movel ETEMP_LO(%a6),%d1 6438c2ecf20Sopenharmony_ci bnes is_nan 6448c2ecf20Sopenharmony_ciis_inf: 6458c2ecf20Sopenharmony_ci moveb #0x40,STAG(%a6) 6468c2ecf20Sopenharmony_ci movel #0x40,%d0 6478c2ecf20Sopenharmony_ci rts 6488c2ecf20Sopenharmony_ciis_nan: 6498c2ecf20Sopenharmony_ci moveb #0x60,STAG(%a6) 6508c2ecf20Sopenharmony_ci movel #0x60,%d0 6518c2ecf20Sopenharmony_ci rts 6528c2ecf20Sopenharmony_ciz_or_nrm: 6538c2ecf20Sopenharmony_ci tstw %d1 6548c2ecf20Sopenharmony_ci bnes is_nrm 6558c2ecf20Sopenharmony_ciis_zro: 6568c2ecf20Sopenharmony_ci| For a zero, set etemp_15 6578c2ecf20Sopenharmony_ci moveb #0x30,STAG(%a6) 6588c2ecf20Sopenharmony_ci movel #0x20,%d0 6598c2ecf20Sopenharmony_ci rts 6608c2ecf20Sopenharmony_ciis_nrm: 6618c2ecf20Sopenharmony_ci| For a norm, check if the exp <= $3fff; if so, set etemp_15 6628c2ecf20Sopenharmony_ci cmpiw #0x3fff,%d1 6638c2ecf20Sopenharmony_ci bles set_bit15 6648c2ecf20Sopenharmony_ci moveb #0,STAG(%a6) 6658c2ecf20Sopenharmony_ci bras end_is_nrm 6668c2ecf20Sopenharmony_ciset_bit15: 6678c2ecf20Sopenharmony_ci moveb #0x10,STAG(%a6) 6688c2ecf20Sopenharmony_ciend_is_nrm: 6698c2ecf20Sopenharmony_ci movel #0,%d0 6708c2ecf20Sopenharmony_ciend_fix: 6718c2ecf20Sopenharmony_ci rts 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ciend_get: 6748c2ecf20Sopenharmony_ci rts 6758c2ecf20Sopenharmony_ci |end 676