get_op.sa revision 1.4
11.4Sbriggs* $NetBSD: get_op.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $ 21.3Scgd 31.1Smycroft* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 41.1Smycroft* M68000 Hi-Performance Microprocessor Division 51.1Smycroft* M68040 Software Package 61.1Smycroft* 71.1Smycroft* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 81.1Smycroft* All rights reserved. 91.1Smycroft* 101.1Smycroft* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 111.1Smycroft* To the maximum extent permitted by applicable law, 121.1Smycroft* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 131.1Smycroft* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 141.1Smycroft* PARTICULAR PURPOSE and any warranty against infringement with 151.1Smycroft* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 161.1Smycroft* and any accompanying written materials. 171.1Smycroft* 181.1Smycroft* To the maximum extent permitted by applicable law, 191.1Smycroft* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 201.1Smycroft* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 211.1Smycroft* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 221.1Smycroft* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 231.1Smycroft* SOFTWARE. Motorola assumes no responsibility for the maintenance 241.1Smycroft* and support of the SOFTWARE. 251.1Smycroft* 261.1Smycroft* You are hereby granted a copyright license to use, modify, and 271.1Smycroft* distribute the SOFTWARE so long as this entire notice is retained 281.1Smycroft* without alteration in any modified and/or redistributed versions, 291.1Smycroft* and that such modified versions are clearly identified as such. 301.1Smycroft* No licenses are granted by implication, estoppel or otherwise 311.1Smycroft* under any patents or trademarks of Motorola, Inc. 321.1Smycroft 331.1Smycroft* 341.1Smycroft* get_op.sa 3.6 5/19/92 351.1Smycroft* 361.1Smycroft* get_op.sa 3.5 4/26/91 371.1Smycroft* 381.1Smycroft* Description: This routine is called by the unsupported format/data 391.1Smycroft* type exception handler ('unsupp' - vector 55) and the unimplemented 401.1Smycroft* instruction exception handler ('unimp' - vector 11). 'get_op' 411.1Smycroft* determines the opclass (0, 2, or 3) and branches to the 421.1Smycroft* opclass handler routine. See 68881/2 User's Manual table 4-11 431.1Smycroft* for a description of the opclasses. 441.1Smycroft* 451.1Smycroft* For UNSUPPORTED data/format (exception vector 55) and for 461.1Smycroft* UNIMPLEMENTED instructions (exception vector 11) the following 471.1Smycroft* applies: 481.1Smycroft* 491.1Smycroft* - For unnormormalized numbers (opclass 0, 2, or 3) the 501.1Smycroft* number(s) is normalized and the operand type tag is updated. 511.1Smycroft* 521.1Smycroft* - For a packed number (opclass 2) the number is unpacked and the 531.1Smycroft* operand type tag is updated. 541.1Smycroft* 551.1Smycroft* - For denormalized numbers (opclass 0 or 2) the number(s) is not 561.1Smycroft* changed but passed to the next module. The next module for 571.1Smycroft* unimp is do_func, the next module for unsupp is res_func. 581.1Smycroft* 591.1Smycroft* For UNSUPPORTED data/format (exception vector 55) only the 601.1Smycroft* following applies: 611.1Smycroft* 621.1Smycroft* - If there is a move out with a packed number (opclass 3) the 631.1Smycroft* number is packed and written to user memory. For the other 641.1Smycroft* opclasses the number(s) are written back to the fsave stack 651.1Smycroft* and the instruction is then restored back into the '040. The 661.1Smycroft* '040 is then able to complete the instruction. 671.1Smycroft* 681.1Smycroft* For example: 691.1Smycroft* fadd.x fpm,fpn where the fpm contains an unnormalized number. 701.1Smycroft* The '040 takes an unsupported data trap and gets to this 711.1Smycroft* routine. The number is normalized, put back on the stack and 721.1Smycroft* then an frestore is done to restore the instruction back into 731.1Smycroft* the '040. The '040 then re-executes the fadd.x fpm,fpn with 741.1Smycroft* a normalized number in the source and the instruction is 751.1Smycroft* successful. 761.1Smycroft* 771.1Smycroft* Next consider if in the process of normalizing the un- 781.1Smycroft* normalized number it becomes a denormalized number. The 791.1Smycroft* routine which converts the unnorm to a norm (called mk_norm) 801.1Smycroft* detects this and tags the number as a denorm. The routine 811.1Smycroft* res_func sees the denorm tag and converts the denorm to a 821.1Smycroft* norm. The instruction is then restored back into the '040 831.1Smycroft* which re_executess the instruction. 841.1Smycroft* 851.1Smycroft 861.1SmycroftGET_OP IDNT 2,1 Motorola 040 Floating Point Software Package 871.1Smycroft 881.1Smycroft section 8 891.1Smycroft 901.1Smycroft include fpsp.h 911.1Smycroft 921.1Smycroft xdef PIRN,PIRZRM,PIRP 931.1Smycroft xdef SMALRN,SMALRZRM,SMALRP 941.1Smycroft xdef BIGRN,BIGRZRM,BIGRP 951.1Smycroft 961.1SmycroftPIRN: 971.1Smycroft dc.l $40000000,$c90fdaa2,$2168c235 ;pi 981.1SmycroftPIRZRM: 991.1Smycroft dc.l $40000000,$c90fdaa2,$2168c234 ;pi 1001.1SmycroftPIRP: 1011.1Smycroft dc.l $40000000,$c90fdaa2,$2168c235 ;pi 1021.1Smycroft 1031.1Smycroft*round to nearest 1041.1SmycroftSMALRN: 1051.1Smycroft dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2) 1061.1Smycroft dc.l $40000000,$adf85458,$a2bb4a9a ;e 1071.1Smycroft dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e) 1081.1Smycroft dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 1091.1Smycroft dc.l $00000000,$00000000,$00000000 ;0.0 1101.1Smycroft* round to zero;round to negative infinity 1111.1SmycroftSMALRZRM: 1121.1Smycroft dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2) 1131.1Smycroft dc.l $40000000,$adf85458,$a2bb4a9a ;e 1141.1Smycroft dc.l $3fff0000,$b8aa3b29,$5c17f0bb ;log2(e) 1151.1Smycroft dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 1161.1Smycroft dc.l $00000000,$00000000,$00000000 ;0.0 1171.1Smycroft* round to positive infinity 1181.1SmycroftSMALRP: 1191.1Smycroft dc.l $3ffd0000,$9a209a84,$fbcff799 ;log10(2) 1201.1Smycroft dc.l $40000000,$adf85458,$a2bb4a9b ;e 1211.1Smycroft dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e) 1221.1Smycroft dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 1231.1Smycroft dc.l $00000000,$00000000,$00000000 ;0.0 1241.1Smycroft 1251.1Smycroft*round to nearest 1261.1SmycroftBIGRN: 1271.1Smycroft dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2) 1281.1Smycroft dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10) 1291.1Smycroft dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 1301.1Smycroft 1311.1Smycroft xdef PTENRN 1321.1SmycroftPTENRN: 1331.1Smycroft dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 1341.1Smycroft dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 1351.1Smycroft dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 1361.1Smycroft dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 1371.1Smycroft dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 1381.1Smycroft dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32 1391.1Smycroft dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64 1401.1Smycroft dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128 1411.1Smycroft dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256 1421.1Smycroft dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512 1431.1Smycroft dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024 1441.1Smycroft dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048 1451.1Smycroft dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096 1461.1Smycroft*round to minus infinity 1471.1SmycroftBIGRZRM: 1481.1Smycroft dc.l $3ffe0000,$b17217f7,$d1cf79ab ;ln(2) 1491.1Smycroft dc.l $40000000,$935d8ddd,$aaa8ac16 ;ln(10) 1501.1Smycroft dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 1511.1Smycroft 1521.1Smycroft xdef PTENRM 1531.1SmycroftPTENRM: 1541.1Smycroft dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 1551.1Smycroft dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 1561.1Smycroft dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 1571.1Smycroft dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 1581.1Smycroft dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 1591.1Smycroft dc.l $40690000,$9DC5ADA8,$2B70B59D ;10 ^ 32 1601.1Smycroft dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64 1611.1Smycroft dc.l $41A80000,$93BA47C9,$80E98CDF ;10 ^ 128 1621.1Smycroft dc.l $43510000,$AA7EEBFB,$9DF9DE8D ;10 ^ 256 1631.1Smycroft dc.l $46A30000,$E319A0AE,$A60E91C6 ;10 ^ 512 1641.1Smycroft dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024 1651.1Smycroft dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048 1661.1Smycroft dc.l $75250000,$C4605202,$8A20979A ;10 ^ 4096 1671.1Smycroft*round to positive infinity 1681.1SmycroftBIGRP: 1691.1Smycroft dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2) 1701.1Smycroft dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10) 1711.1Smycroft dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 1721.1Smycroft 1731.1Smycroft xdef PTENRP 1741.1SmycroftPTENRP: 1751.1Smycroft dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 1761.1Smycroft dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 1771.1Smycroft dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 1781.1Smycroft dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 1791.1Smycroft dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 1801.1Smycroft dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32 1811.1Smycroft dc.l $40D30000,$C2781F49,$FFCFA6D6 ;10 ^ 64 1821.1Smycroft dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128 1831.1Smycroft dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256 1841.1Smycroft dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512 1851.1Smycroft dc.l $4D480000,$C9767586,$81750C18 ;10 ^ 1024 1861.1Smycroft dc.l $5A920000,$9E8B3B5D,$C53D5DE6 ;10 ^ 2048 1871.1Smycroft dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096 1881.1Smycroft 1891.1Smycroft xref nrm_zero 1901.1Smycroft xref decbin 1911.1Smycroft xref round 1921.1Smycroft 1931.1Smycroft xdef get_op 1941.1Smycroft xdef uns_getop 1951.1Smycroft xdef uni_getop 1961.1Smycroftget_op: 1971.1Smycroft clr.b DY_MO_FLG(a6) 1981.1Smycroft tst.b UFLG_TMP(a6) ;test flag for unsupp/unimp state 1991.4Sbriggs beq.b short_uni_getop 2001.1Smycroft 2011.1Smycroftuns_getop: 2021.1Smycroft btst.b #direction_bit,CMDREG1B(a6) 2031.1Smycroft bne.w opclass3 ;branch if a fmove out (any kind) 2041.1Smycroft btst.b #6,CMDREG1B(a6) 2051.1Smycroft beq.b uns_notpacked 2061.1Smycroft 2071.1Smycroft bfextu CMDREG1B(a6){3:3},d0 2081.1Smycroft cmp.b #3,d0 2091.1Smycroft beq.w pack_source ;check for a packed src op, branch if so 2101.1Smycroftuns_notpacked: 2111.1Smycroft bsr chk_dy_mo ;set the dyadic/monadic flag 2121.1Smycroft tst.b DY_MO_FLG(a6) 2131.1Smycroft beq.b src_op_ck ;if monadic, go check src op 2141.1Smycroft* ;else, check dst op (fall through) 2151.1Smycroft 2161.1Smycroft btst.b #7,DTAG(a6) 2171.1Smycroft beq.b src_op_ck ;if dst op is norm, check src op 2181.1Smycroft bra.b dst_ex_dnrm ;else, handle destination unnorm/dnrm 2191.1Smycroft 2201.1Smycroftuni_getop: 2211.4Sbriggsshort_uni_getop: 2221.1Smycroft bfextu CMDREG1B(a6){0:6},d0 ;get opclass and src fields 2231.1Smycroft cmpi.l #$17,d0 ;if op class and size fields are $17, 2241.1Smycroft* ;it is FMOVECR; if not, continue 2251.1Smycroft* 2261.1Smycroft* If the instruction is fmovecr, exit get_op. It is handled 2271.1Smycroft* in do_func and smovecr.sa. 2281.1Smycroft* 2291.1Smycroft bne.w not_fmovecr ;handle fmovecr as an unimplemented inst 2301.1Smycroft rts 2311.1Smycroft 2321.1Smycroftnot_fmovecr: 2331.1Smycroft btst.b #E1,E_BYTE(a6) ;if set, there is a packed operand 2341.1Smycroft bne.w pack_source ;check for packed src op, branch if so 2351.1Smycroft 2361.1Smycroft* The following lines of are coded to optimize on normalized operands 2371.1Smycroft move.b STAG(a6),d0 2381.1Smycroft or.b DTAG(a6),d0 ;check if either of STAG/DTAG msb set 2391.1Smycroft bmi.b dest_op_ck ;if so, some op needs to be fixed 2401.1Smycroft rts 2411.1Smycroft 2421.1Smycroftdest_op_ck: 2431.1Smycroft btst.b #7,DTAG(a6) ;check for unsupported data types in 2441.1Smycroft beq.b src_op_ck ;the destination, if not, check src op 2451.1Smycroft bsr chk_dy_mo ;set dyadic/monadic flag 2461.1Smycroft tst.b DY_MO_FLG(a6) ; 2471.1Smycroft beq.b src_op_ck ;if monadic, check src op 2481.1Smycroft* 2491.1Smycroft* At this point, destination has an extended denorm or unnorm. 2501.1Smycroft* 2511.1Smycroftdst_ex_dnrm: 2521.1Smycroft move.w FPTEMP_EX(a6),d0 ;get destination exponent 2531.1Smycroft andi.w #$7fff,d0 ;mask sign, check if exp = 0000 2541.1Smycroft beq.b src_op_ck ;if denorm then check source op. 2551.1Smycroft* ;denorms are taken care of in res_func 2561.1Smycroft* ;(unsupp) or do_func (unimp) 2571.1Smycroft* ;else unnorm fall through 2581.1Smycroft lea.l FPTEMP(a6),a0 ;point a0 to dop - used in mk_norm 2591.1Smycroft bsr mk_norm ;go normalize - mk_norm returns: 2601.1Smycroft* ;L_SCR1{7:5} = operand tag 2611.1Smycroft* ; (000 = norm, 100 = denorm) 2621.1Smycroft* ;L_SCR1{4} = fpte15 or ete15 2631.1Smycroft* ; 0 = exp > $3fff 2641.1Smycroft* ; 1 = exp <= $3fff 2651.1Smycroft* ;and puts the normalized num back 2661.1Smycroft* ;on the fsave stack 2671.1Smycroft* 2681.1Smycroft move.b L_SCR1(a6),DTAG(a6) ;write the new tag & fpte15 2691.1Smycroft* ;to the fsave stack and fall 2701.1Smycroft* ;through to check source operand 2711.1Smycroft* 2721.1Smycroftsrc_op_ck: 2731.1Smycroft btst.b #7,STAG(a6) 2741.1Smycroft beq.w end_getop ;check for unsupported data types on the 2751.1Smycroft* ;source operand 2761.1Smycroft btst.b #5,STAG(a6) 2771.1Smycroft bne.b src_sd_dnrm ;if bit 5 set, handle sgl/dbl denorms 2781.1Smycroft* 2791.1Smycroft* At this point only unnorms or extended denorms are possible. 2801.1Smycroft* 2811.1Smycroftsrc_ex_dnrm: 2821.1Smycroft move.w ETEMP_EX(a6),d0 ;get source exponent 2831.1Smycroft andi.w #$7fff,d0 ;mask sign, check if exp = 0000 2841.1Smycroft beq.w end_getop ;if denorm then exit, denorms are 2851.1Smycroft* ;handled in do_func 2861.1Smycroft lea.l ETEMP(a6),a0 ;point a0 to sop - used in mk_norm 2871.1Smycroft bsr mk_norm ;go normalize - mk_norm returns: 2881.1Smycroft* ;L_SCR1{7:5} = operand tag 2891.1Smycroft* ; (000 = norm, 100 = denorm) 2901.1Smycroft* ;L_SCR1{4} = fpte15 or ete15 2911.1Smycroft* ; 0 = exp > $3fff 2921.1Smycroft* ; 1 = exp <= $3fff 2931.1Smycroft* ;and puts the normalized num back 2941.1Smycroft* ;on the fsave stack 2951.1Smycroft* 2961.1Smycroft move.b L_SCR1(a6),STAG(a6) ;write the new tag & ete15 2971.1Smycroft rts ;end_getop 2981.1Smycroft 2991.1Smycroft* 3001.1Smycroft* At this point, only single or double denorms are possible. 3011.1Smycroft* If the inst is not fmove, normalize the source. If it is, 3021.1Smycroft* do nothing to the input. 3031.1Smycroft* 3041.1Smycroftsrc_sd_dnrm: 3051.1Smycroft btst.b #4,CMDREG1B(a6) ;differentiate between sgl/dbl denorm 3061.1Smycroft bne.b is_double 3071.1Smycroftis_single: 3081.1Smycroft move.w #$3f81,d1 ;write bias for sgl denorm 3091.1Smycroft bra.b common ;goto the common code 3101.1Smycroftis_double: 3111.1Smycroft move.w #$3c01,d1 ;write the bias for a dbl denorm 3121.1Smycroftcommon: 3131.1Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;grab sign bit of mantissa 3141.1Smycroft beq.b pos 3151.1Smycroft bset #15,d1 ;set sign bit because it is negative 3161.1Smycroftpos: 3171.1Smycroft move.w d1,ETEMP_EX(a6) 3181.1Smycroft* ;put exponent on stack 3191.1Smycroft 3201.1Smycroft move.w CMDREG1B(a6),d1 3211.1Smycroft and.w #$e3ff,d1 ;clear out source specifier 3221.1Smycroft or.w #$0800,d1 ;set source specifier to extended prec 3231.1Smycroft move.w d1,CMDREG1B(a6) ;write back to the command word in stack 3241.1Smycroft* ;this is needed to fix unsupp data stack 3251.1Smycroft lea.l ETEMP(a6),a0 ;point a0 to sop 3261.1Smycroft 3271.1Smycroft bsr mk_norm ;convert sgl/dbl denorm to norm 3281.1Smycroft move.b L_SCR1(a6),STAG(a6) ;put tag into source tag reg - d0 3291.1Smycroft rts ;end_getop 3301.1Smycroft* 3311.1Smycroft* At this point, the source is definitely packed, whether 3321.1Smycroft* instruction is dyadic or monadic is still unknown 3331.1Smycroft* 3341.1Smycroftpack_source: 3351.1Smycroft move.l FPTEMP_LO(a6),ETEMP(a6) ;write ms part of packed 3361.1Smycroft* ;number to etemp slot 3371.1Smycroft bsr chk_dy_mo ;set dyadic/monadic flag 3381.1Smycroft bsr unpack 3391.1Smycroft 3401.1Smycroft tst.b DY_MO_FLG(a6) 3411.1Smycroft beq.b end_getop ;if monadic, exit 3421.1Smycroft* ;else, fix FPTEMP 3431.1Smycroftpack_dya: 3441.1Smycroft bfextu CMDREG1B(a6){6:3},d0 ;extract dest fp reg 3451.1Smycroft move.l #7,d1 3461.1Smycroft sub.l d0,d1 3471.1Smycroft clr.l d0 3481.1Smycroft bset.l d1,d0 ;set up d0 as a dynamic register mask 3491.1Smycroft fmovem.x d0,FPTEMP(a6) ;write to FPTEMP 3501.1Smycroft 3511.1Smycroft btst.b #7,DTAG(a6) ;check dest tag for unnorm or denorm 3521.1Smycroft bne.w dst_ex_dnrm ;else, handle the unnorm or ext denorm 3531.1Smycroft* 3541.1Smycroft* Dest is not denormalized. Check for norm, and set fpte15 3551.1Smycroft* accordingly. 3561.1Smycroft* 3571.1Smycroft move.b DTAG(a6),d0 3581.1Smycroft andi.b #$f0,d0 ;strip to only dtag:fpte15 3591.1Smycroft tst.b d0 ;check for normalized value 3601.1Smycroft bne.b end_getop ;if inf/nan/zero leave get_op 3611.1Smycroft move.w FPTEMP_EX(a6),d0 3621.1Smycroft andi.w #$7fff,d0 3631.1Smycroft cmpi.w #$3fff,d0 ;check if fpte15 needs setting 3641.1Smycroft bge.b end_getop ;if >= $3fff, leave fpte15=0 3651.1Smycroft or.b #$10,DTAG(a6) 3661.1Smycroft bra.b end_getop 3671.1Smycroft 3681.1Smycroft* 3691.1Smycroft* At this point, it is either an fmoveout packed, unnorm or denorm 3701.1Smycroft* 3711.1Smycroftopclass3: 3721.1Smycroft clr.b DY_MO_FLG(a6) ;set dyadic/monadic flag to monadic 3731.1Smycroft bfextu CMDREG1B(a6){4:2},d0 3741.1Smycroft cmpi.b #3,d0 3751.1Smycroft bne.w src_ex_dnrm ;if not equal, must be unnorm or denorm 3761.1Smycroft* ;else it is a packed move out 3771.1Smycroft* ;exit 3781.1Smycroftend_getop: 3791.1Smycroft rts 3801.1Smycroft 3811.1Smycroft* 3821.1Smycroft* Sets the DY_MO_FLG correctly. This is used only on if it is an 3831.1Smycroft* unuspported data type exception. Set if dyadic. 3841.1Smycroft* 3851.1Smycroftchk_dy_mo: 3861.1Smycroft move.w CMDREG1B(a6),d0 3871.1Smycroft btst.l #5,d0 ;testing extension command word 3881.1Smycroft beq.b set_mon ;if bit 5 = 0 then monadic 3891.1Smycroft btst.l #4,d0 ;know that bit 5 = 1 3901.1Smycroft beq.b set_dya ;if bit 4 = 0 then dyadic 3911.1Smycroft andi.w #$007f,d0 ;get rid of all but extension bits {6:0} 3921.1Smycroft cmpi.w #$0038,d0 ;if extension = $38 then fcmp (dyadic) 3931.1Smycroft bne.b set_mon 3941.1Smycroftset_dya: 3951.1Smycroft st.b DY_MO_FLG(a6) ;set the inst flag type to dyadic 3961.1Smycroft rts 3971.1Smycroftset_mon: 3981.1Smycroft clr.b DY_MO_FLG(a6) ;set the inst flag type to monadic 3991.1Smycroft rts 4001.1Smycroft* 4011.1Smycroft* MK_NORM 4021.1Smycroft* 4031.1Smycroft* Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl 4041.1Smycroft* exception if denorm. 4051.1Smycroft* 4061.1Smycroft* CASE opclass 0x0 unsupp 4071.1Smycroft* mk_norm till msb set 4081.1Smycroft* set tag = norm 4091.1Smycroft* 4101.1Smycroft* CASE opclass 0x0 unimp 4111.1Smycroft* mk_norm till msb set or exp = 0 4121.1Smycroft* if integer bit = 0 4131.1Smycroft* tag = denorm 4141.1Smycroft* else 4151.1Smycroft* tag = norm 4161.1Smycroft* 4171.1Smycroft* CASE opclass 011 unsupp 4181.1Smycroft* mk_norm till msb set or exp = 0 4191.1Smycroft* if integer bit = 0 4201.1Smycroft* tag = denorm 4211.1Smycroft* set unfl_nmcexe = 1 4221.1Smycroft* else 4231.1Smycroft* tag = norm 4241.1Smycroft* 4251.1Smycroft* if exp <= $3fff 4261.1Smycroft* set ete15 or fpte15 = 1 4271.1Smycroft* else set ete15 or fpte15 = 0 4281.1Smycroft 4291.1Smycroft* input: 4301.1Smycroft* a0 = points to operand to be normalized 4311.1Smycroft* output: 4321.1Smycroft* L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) 4331.1Smycroft* L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) 4341.1Smycroft* the normalized operand is placed back on the fsave stack 4351.1Smycroftmk_norm: 4361.1Smycroft clr.l L_SCR1(a6) 4371.1Smycroft bclr.b #sign_bit,LOCAL_EX(a0) 4381.1Smycroft sne LOCAL_SGN(a0) ;transform into internal extended format 4391.1Smycroft 4401.1Smycroft cmpi.b #$2c,1+EXC_VEC(a6) ;check if unimp 4411.1Smycroft bne.b uns_data ;branch if unsupp 4421.1Smycroft bsr uni_inst ;call if unimp (opclass 0x0) 4431.1Smycroft bra.b reload 4441.1Smycroftuns_data: 4451.1Smycroft btst.b #direction_bit,CMDREG1B(a6) ;check transfer direction 4461.1Smycroft bne.b bit_set ;branch if set (opclass 011) 4471.1Smycroft bsr uns_opx ;call if opclass 0x0 4481.1Smycroft bra.b reload 4491.1Smycroftbit_set: 4501.1Smycroft bsr uns_op3 ;opclass 011 4511.1Smycroftreload: 4521.1Smycroft cmp.w #$3fff,LOCAL_EX(a0) ;if exp > $3fff 4531.1Smycroft bgt.b end_mk ; fpte15/ete15 already set to 0 4541.1Smycroft bset.b #4,L_SCR1(a6) ;else set fpte15/ete15 to 1 4551.1Smycroft* ;calling routine actually sets the 4561.1Smycroft* ;value on the stack (along with the 4571.1Smycroft* ;tag), since this routine doesn't 4581.1Smycroft* ;know if it should set ete15 or fpte15 4591.1Smycroft* ;ie, it doesn't know if this is the 4601.1Smycroft* ;src op or dest op. 4611.1Smycroftend_mk: 4621.1Smycroft bfclr LOCAL_SGN(a0){0:8} 4631.1Smycroft beq.b end_mk_pos 4641.1Smycroft bset.b #sign_bit,LOCAL_EX(a0) ;convert back to IEEE format 4651.1Smycroftend_mk_pos: 4661.1Smycroft rts 4671.1Smycroft* 4681.1Smycroft* CASE opclass 011 unsupp 4691.1Smycroft* 4701.1Smycroftuns_op3: 4711.1Smycroft bsr nrm_zero ;normalize till msb = 1 or exp = zero 4721.1Smycroft btst.b #7,LOCAL_HI(a0) ;if msb = 1 4731.1Smycroft bne.b no_unfl ;then branch 4741.1Smycroftset_unfl: 4751.2Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set denorm tag 4761.1Smycroft bset.b #unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit 4771.1Smycroftno_unfl: 4781.1Smycroft rts 4791.1Smycroft* 4801.1Smycroft* CASE opclass 0x0 unsupp 4811.1Smycroft* 4821.1Smycroftuns_opx: 4831.1Smycroft bsr nrm_zero ;normalize the number 4841.1Smycroft btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 4851.1Smycroft beq.b uns_den ;if clear then now have a denorm 4861.1Smycroftuns_nrm: 4871.1Smycroft or.b #norm_tag,L_SCR1(a6) ;set tag to norm 4881.1Smycroft rts 4891.1Smycroftuns_den: 4901.1Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 4911.1Smycroft rts 4921.1Smycroft* 4931.1Smycroft* CASE opclass 0x0 unimp 4941.1Smycroft* 4951.1Smycroftuni_inst: 4961.1Smycroft bsr nrm_zero 4971.1Smycroft btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 4981.1Smycroft beq.b uni_den ;if clear then now have a denorm 4991.1Smycroftuni_nrm: 5001.1Smycroft or.b #norm_tag,L_SCR1(a6) ;set tag to norm 5011.1Smycroft rts 5021.1Smycroftuni_den: 5031.1Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 5041.1Smycroft rts 5051.1Smycroft 5061.1Smycroft* 5071.1Smycroft* Decimal to binary conversion 5081.1Smycroft* 5091.1Smycroft* Special cases of inf and NaNs are completed outside of decbin. 5101.1Smycroft* If the input is an snan, the snan bit is not set. 5111.1Smycroft* 5121.1Smycroft* input: 5131.1Smycroft* ETEMP(a6) - points to packed decimal string in memory 5141.1Smycroft* output: 5151.1Smycroft* fp0 - contains packed string converted to extended precision 5161.1Smycroft* ETEMP - same as fp0 5171.1Smycroftunpack: 5181.1Smycroft move.w CMDREG1B(a6),d0 ;examine command word, looking for fmove's 5191.1Smycroft and.w #$3b,d0 5201.1Smycroft beq move_unpack ;special handling for fmove: must set FPSR_CC 5211.1Smycroft 5221.1Smycroft move.w ETEMP(a6),d0 ;get word with inf information 5231.1Smycroft bfextu d0{20:12},d1 ;get exponent into d1 5241.1Smycroft cmpi.w #$0fff,d1 ;test for inf or NaN 5251.1Smycroft bne.b try_zero ;if not equal, it is not special 5261.1Smycroft bfextu d0{17:3},d1 ;get SE and y bits into d1 5271.1Smycroft cmpi.w #7,d1 ;SE and y bits must be on for special 5281.1Smycroft bne.b try_zero ;if not on, it is not special 5291.1Smycroft*input is of the special cases of inf and NaN 5301.1Smycroft tst.l ETEMP_HI(a6) ;check ms mantissa 5311.1Smycroft bne.b fix_nan ;if non-zero, it is a NaN 5321.1Smycroft tst.l ETEMP_LO(a6) ;check ls mantissa 5331.1Smycroft bne.b fix_nan ;if non-zero, it is a NaN 5341.1Smycroft bra.w finish ;special already on stack 5351.1Smycroftfix_nan: 5361.1Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 5371.1Smycroft bne.w finish 5381.1Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;always set snan if it is so 5391.1Smycroft bra.w finish 5401.1Smycrofttry_zero: 5411.1Smycroft move.w ETEMP_EX+2(a6),d0 ;get word 4 5421.1Smycroft andi.w #$000f,d0 ;clear all but last ni(y)bble 5431.1Smycroft tst.w d0 ;check for zero. 5441.1Smycroft bne.w not_spec 5451.1Smycroft tst.l ETEMP_HI(a6) ;check words 3 and 2 5461.1Smycroft bne.w not_spec 5471.1Smycroft tst.l ETEMP_LO(a6) ;check words 1 and 0 5481.1Smycroft bne.w not_spec 5491.1Smycroft tst.l ETEMP(a6) ;test sign of the zero 5501.1Smycroft bge.b pos_zero 5511.1Smycroft move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 5521.1Smycroft clr.l ETEMP_HI(a6) 5531.1Smycroft clr.l ETEMP_LO(a6) 5541.1Smycroft bra.w finish 5551.1Smycroftpos_zero: 5561.1Smycroft clr.l ETEMP(a6) 5571.1Smycroft clr.l ETEMP_HI(a6) 5581.1Smycroft clr.l ETEMP_LO(a6) 5591.1Smycroft bra.w finish 5601.1Smycroft 5611.1Smycroftnot_spec: 5621.1Smycroft fmovem.x fp0-fp1,-(a7) ;save fp0 - decbin returns in it 5631.1Smycroft bsr decbin 5641.1Smycroft fmove.x fp0,ETEMP(a6) ;put the unpacked sop in the fsave stack 5651.1Smycroft fmovem.x (a7)+,fp0-fp1 5661.1Smycroft fmove.l #0,FPSR ;clr fpsr from decbin 5671.1Smycroft bra finish 5681.1Smycroft 5691.1Smycroft* 5701.1Smycroft* Special handling for packed move in: Same results as all other 5711.1Smycroft* packed cases, but we must set the FPSR condition codes properly. 5721.1Smycroft* 5731.1Smycroftmove_unpack: 5741.1Smycroft move.w ETEMP(a6),d0 ;get word with inf information 5751.1Smycroft bfextu d0{20:12},d1 ;get exponent into d1 5761.1Smycroft cmpi.w #$0fff,d1 ;test for inf or NaN 5771.1Smycroft bne.b mtry_zero ;if not equal, it is not special 5781.1Smycroft bfextu d0{17:3},d1 ;get SE and y bits into d1 5791.1Smycroft cmpi.w #7,d1 ;SE and y bits must be on for special 5801.1Smycroft bne.b mtry_zero ;if not on, it is not special 5811.1Smycroft*input is of the special cases of inf and NaN 5821.1Smycroft tst.l ETEMP_HI(a6) ;check ms mantissa 5831.1Smycroft bne.b mfix_nan ;if non-zero, it is a NaN 5841.1Smycroft tst.l ETEMP_LO(a6) ;check ls mantissa 5851.1Smycroft bne.b mfix_nan ;if non-zero, it is a NaN 5861.1Smycroft*input is inf 5871.1Smycroft or.l #inf_mask,USER_FPSR(a6) ;set I bit 5881.1Smycroft tst.l ETEMP(a6) ;check sign 5891.1Smycroft bge.w finish 5901.1Smycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit 5911.1Smycroft bra.w finish ;special already on stack 5921.1Smycroftmfix_nan: 5931.1Smycroft or.l #nan_mask,USER_FPSR(a6) ;set NaN bit 5941.1Smycroft move.b #nan_tag,STAG(a6) ;set stag to NaN 5951.1Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 5961.1Smycroft bne.b mn_snan 5971.1Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set snan bit 5981.1Smycroft btst.b #snan_bit,FPCR_ENABLE(a6) ;test for snan enabled 5991.1Smycroft bne.b mn_snan 6001.1Smycroft bset.b #signan_bit,ETEMP_HI(a6) ;force snans to qnans 6011.1Smycroftmn_snan: 6021.1Smycroft tst.l ETEMP(a6) ;check for sign 6031.1Smycroft bge.w finish ;if clr, go on 6041.1Smycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit 6051.1Smycroft bra.w finish 6061.1Smycroft 6071.1Smycroftmtry_zero: 6081.1Smycroft move.w ETEMP_EX+2(a6),d0 ;get word 4 6091.1Smycroft andi.w #$000f,d0 ;clear all but last ni(y)bble 6101.1Smycroft tst.w d0 ;check for zero. 6111.1Smycroft bne.b mnot_spec 6121.1Smycroft tst.l ETEMP_HI(a6) ;check words 3 and 2 6131.1Smycroft bne.b mnot_spec 6141.1Smycroft tst.l ETEMP_LO(a6) ;check words 1 and 0 6151.1Smycroft bne.b mnot_spec 6161.1Smycroft tst.l ETEMP(a6) ;test sign of the zero 6171.1Smycroft bge.b mpos_zero 6181.1Smycroft or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z 6191.1Smycroft move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 6201.1Smycroft clr.l ETEMP_HI(a6) 6211.1Smycroft clr.l ETEMP_LO(a6) 6221.1Smycroft bra.b finish 6231.1Smycroftmpos_zero: 6241.1Smycroft or.l #z_mask,USER_FPSR(a6) ;set Z 6251.1Smycroft clr.l ETEMP(a6) 6261.1Smycroft clr.l ETEMP_HI(a6) 6271.1Smycroft clr.l ETEMP_LO(a6) 6281.1Smycroft bra.b finish 6291.1Smycroft 6301.1Smycroftmnot_spec: 6311.1Smycroft fmovem.x fp0-fp1,-(a7) ;save fp0 ,fp1 - decbin returns in fp0 6321.1Smycroft bsr decbin 6331.1Smycroft fmove.x fp0,ETEMP(a6) 6341.1Smycroft* ;put the unpacked sop in the fsave stack 6351.1Smycroft fmovem.x (a7)+,fp0-fp1 6361.1Smycroft 6371.1Smycroftfinish: 6381.1Smycroft move.w CMDREG1B(a6),d0 ;get the command word 6391.1Smycroft and.w #$fbff,d0 ;change the source specifier field to 6401.1Smycroft* ;extended (was packed). 6411.1Smycroft move.w d0,CMDREG1B(a6) ;write command word back to fsave stack 6421.1Smycroft* ;we need to do this so the 040 will 6431.1Smycroft* ;re-execute the inst. without taking 6441.1Smycroft* ;another packed trap. 6451.1Smycroft 6461.1Smycroftfix_stag: 6471.1Smycroft*Converted result is now in etemp on fsave stack, now set the source 6481.1Smycroft*tag (stag) 6491.1Smycroft* if (ete =$7fff) then INF or NAN 6501.1Smycroft* if (etemp = $x.0----0) then 6511.1Smycroft* stag = INF 6521.1Smycroft* else 6531.1Smycroft* stag = NAN 6541.1Smycroft* else 6551.1Smycroft* if (ete = $0000) then 6561.1Smycroft* stag = ZERO 6571.1Smycroft* else 6581.1Smycroft* stag = NORM 6591.1Smycroft* 6601.1Smycroft* Note also that the etemp_15 bit (just right of the stag) must 6611.1Smycroft* be set accordingly. 6621.1Smycroft* 6631.1Smycroft move.w ETEMP_EX(a6),d1 6641.1Smycroft andi.w #$7fff,d1 ;strip sign 6651.1Smycroft cmp.w #$7fff,d1 6661.1Smycroft bne.b z_or_nrm 6671.1Smycroft move.l ETEMP_HI(a6),d1 6681.1Smycroft bne.b is_nan 6691.1Smycroft move.l ETEMP_LO(a6),d1 6701.1Smycroft bne.b is_nan 6711.1Smycroftis_inf: 6721.1Smycroft move.b #$40,STAG(a6) 6731.1Smycroft move.l #$40,d0 6741.1Smycroft rts 6751.1Smycroftis_nan: 6761.1Smycroft move.b #$60,STAG(a6) 6771.1Smycroft move.l #$60,d0 6781.1Smycroft rts 6791.1Smycroftz_or_nrm: 6801.1Smycroft tst.w d1 6811.1Smycroft bne.b is_nrm 6821.1Smycroftis_zro: 6831.1Smycroft* For a zero, set etemp_15 6841.1Smycroft move.b #$30,STAG(a6) 6851.1Smycroft move.l #$20,d0 6861.1Smycroft rts 6871.1Smycroftis_nrm: 6881.1Smycroft* For a norm, check if the exp <= $3fff; if so, set etemp_15 6891.1Smycroft cmpi.w #$3fff,d1 6901.1Smycroft ble.b set_bit15 6911.2Smycroft clr.b STAG(a6) 6921.1Smycroft bra.b end_is_nrm 6931.1Smycroftset_bit15: 6941.1Smycroft move.b #$10,STAG(a6) 6951.1Smycroftend_is_nrm: 6961.2Smycroft clr.l d0 6971.1Smycroftend_fix: 6981.1Smycroft rts 6991.1Smycroft 7001.1Smycroftend_get: 7011.1Smycroft rts 7021.1Smycroft end 703