get_op.sa revision 1.3
11.3Scgd* $NetBSD: get_op.sa,v 1.3 1994/10/26 07:49:09 cgd 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.1Smycroft beq.b 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.1Smycroft bfextu CMDREG1B(a6){0:6},d0 ;get opclass and src fields 2221.1Smycroft cmpi.l #$17,d0 ;if op class and size fields are $17, 2231.1Smycroft* ;it is FMOVECR; if not, continue 2241.1Smycroft* 2251.1Smycroft* If the instruction is fmovecr, exit get_op. It is handled 2261.1Smycroft* in do_func and smovecr.sa. 2271.1Smycroft* 2281.1Smycroft bne.w not_fmovecr ;handle fmovecr as an unimplemented inst 2291.1Smycroft rts 2301.1Smycroft 2311.1Smycroftnot_fmovecr: 2321.1Smycroft btst.b #E1,E_BYTE(a6) ;if set, there is a packed operand 2331.1Smycroft bne.w pack_source ;check for packed src op, branch if so 2341.1Smycroft 2351.1Smycroft* The following lines of are coded to optimize on normalized operands 2361.1Smycroft move.b STAG(a6),d0 2371.1Smycroft or.b DTAG(a6),d0 ;check if either of STAG/DTAG msb set 2381.1Smycroft bmi.b dest_op_ck ;if so, some op needs to be fixed 2391.1Smycroft rts 2401.1Smycroft 2411.1Smycroftdest_op_ck: 2421.1Smycroft btst.b #7,DTAG(a6) ;check for unsupported data types in 2431.1Smycroft beq.b src_op_ck ;the destination, if not, check src op 2441.1Smycroft bsr chk_dy_mo ;set dyadic/monadic flag 2451.1Smycroft tst.b DY_MO_FLG(a6) ; 2461.1Smycroft beq.b src_op_ck ;if monadic, check src op 2471.1Smycroft* 2481.1Smycroft* At this point, destination has an extended denorm or unnorm. 2491.1Smycroft* 2501.1Smycroftdst_ex_dnrm: 2511.1Smycroft move.w FPTEMP_EX(a6),d0 ;get destination exponent 2521.1Smycroft andi.w #$7fff,d0 ;mask sign, check if exp = 0000 2531.1Smycroft beq.b src_op_ck ;if denorm then check source op. 2541.1Smycroft* ;denorms are taken care of in res_func 2551.1Smycroft* ;(unsupp) or do_func (unimp) 2561.1Smycroft* ;else unnorm fall through 2571.1Smycroft lea.l FPTEMP(a6),a0 ;point a0 to dop - used in mk_norm 2581.1Smycroft bsr mk_norm ;go normalize - mk_norm returns: 2591.1Smycroft* ;L_SCR1{7:5} = operand tag 2601.1Smycroft* ; (000 = norm, 100 = denorm) 2611.1Smycroft* ;L_SCR1{4} = fpte15 or ete15 2621.1Smycroft* ; 0 = exp > $3fff 2631.1Smycroft* ; 1 = exp <= $3fff 2641.1Smycroft* ;and puts the normalized num back 2651.1Smycroft* ;on the fsave stack 2661.1Smycroft* 2671.1Smycroft move.b L_SCR1(a6),DTAG(a6) ;write the new tag & fpte15 2681.1Smycroft* ;to the fsave stack and fall 2691.1Smycroft* ;through to check source operand 2701.1Smycroft* 2711.1Smycroftsrc_op_ck: 2721.1Smycroft btst.b #7,STAG(a6) 2731.1Smycroft beq.w end_getop ;check for unsupported data types on the 2741.1Smycroft* ;source operand 2751.1Smycroft btst.b #5,STAG(a6) 2761.1Smycroft bne.b src_sd_dnrm ;if bit 5 set, handle sgl/dbl denorms 2771.1Smycroft* 2781.1Smycroft* At this point only unnorms or extended denorms are possible. 2791.1Smycroft* 2801.1Smycroftsrc_ex_dnrm: 2811.1Smycroft move.w ETEMP_EX(a6),d0 ;get source exponent 2821.1Smycroft andi.w #$7fff,d0 ;mask sign, check if exp = 0000 2831.1Smycroft beq.w end_getop ;if denorm then exit, denorms are 2841.1Smycroft* ;handled in do_func 2851.1Smycroft lea.l ETEMP(a6),a0 ;point a0 to sop - used in mk_norm 2861.1Smycroft bsr mk_norm ;go normalize - mk_norm returns: 2871.1Smycroft* ;L_SCR1{7:5} = operand tag 2881.1Smycroft* ; (000 = norm, 100 = denorm) 2891.1Smycroft* ;L_SCR1{4} = fpte15 or ete15 2901.1Smycroft* ; 0 = exp > $3fff 2911.1Smycroft* ; 1 = exp <= $3fff 2921.1Smycroft* ;and puts the normalized num back 2931.1Smycroft* ;on the fsave stack 2941.1Smycroft* 2951.1Smycroft move.b L_SCR1(a6),STAG(a6) ;write the new tag & ete15 2961.1Smycroft rts ;end_getop 2971.1Smycroft 2981.1Smycroft* 2991.1Smycroft* At this point, only single or double denorms are possible. 3001.1Smycroft* If the inst is not fmove, normalize the source. If it is, 3011.1Smycroft* do nothing to the input. 3021.1Smycroft* 3031.1Smycroftsrc_sd_dnrm: 3041.1Smycroft btst.b #4,CMDREG1B(a6) ;differentiate between sgl/dbl denorm 3051.1Smycroft bne.b is_double 3061.1Smycroftis_single: 3071.1Smycroft move.w #$3f81,d1 ;write bias for sgl denorm 3081.1Smycroft bra.b common ;goto the common code 3091.1Smycroftis_double: 3101.1Smycroft move.w #$3c01,d1 ;write the bias for a dbl denorm 3111.1Smycroftcommon: 3121.1Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;grab sign bit of mantissa 3131.1Smycroft beq.b pos 3141.1Smycroft bset #15,d1 ;set sign bit because it is negative 3151.1Smycroftpos: 3161.1Smycroft move.w d1,ETEMP_EX(a6) 3171.1Smycroft* ;put exponent on stack 3181.1Smycroft 3191.1Smycroft move.w CMDREG1B(a6),d1 3201.1Smycroft and.w #$e3ff,d1 ;clear out source specifier 3211.1Smycroft or.w #$0800,d1 ;set source specifier to extended prec 3221.1Smycroft move.w d1,CMDREG1B(a6) ;write back to the command word in stack 3231.1Smycroft* ;this is needed to fix unsupp data stack 3241.1Smycroft lea.l ETEMP(a6),a0 ;point a0 to sop 3251.1Smycroft 3261.1Smycroft bsr mk_norm ;convert sgl/dbl denorm to norm 3271.1Smycroft move.b L_SCR1(a6),STAG(a6) ;put tag into source tag reg - d0 3281.1Smycroft rts ;end_getop 3291.1Smycroft* 3301.1Smycroft* At this point, the source is definitely packed, whether 3311.1Smycroft* instruction is dyadic or monadic is still unknown 3321.1Smycroft* 3331.1Smycroftpack_source: 3341.1Smycroft move.l FPTEMP_LO(a6),ETEMP(a6) ;write ms part of packed 3351.1Smycroft* ;number to etemp slot 3361.1Smycroft bsr chk_dy_mo ;set dyadic/monadic flag 3371.1Smycroft bsr unpack 3381.1Smycroft 3391.1Smycroft tst.b DY_MO_FLG(a6) 3401.1Smycroft beq.b end_getop ;if monadic, exit 3411.1Smycroft* ;else, fix FPTEMP 3421.1Smycroftpack_dya: 3431.1Smycroft bfextu CMDREG1B(a6){6:3},d0 ;extract dest fp reg 3441.1Smycroft move.l #7,d1 3451.1Smycroft sub.l d0,d1 3461.1Smycroft clr.l d0 3471.1Smycroft bset.l d1,d0 ;set up d0 as a dynamic register mask 3481.1Smycroft fmovem.x d0,FPTEMP(a6) ;write to FPTEMP 3491.1Smycroft 3501.1Smycroft btst.b #7,DTAG(a6) ;check dest tag for unnorm or denorm 3511.1Smycroft bne.w dst_ex_dnrm ;else, handle the unnorm or ext denorm 3521.1Smycroft* 3531.1Smycroft* Dest is not denormalized. Check for norm, and set fpte15 3541.1Smycroft* accordingly. 3551.1Smycroft* 3561.1Smycroft move.b DTAG(a6),d0 3571.1Smycroft andi.b #$f0,d0 ;strip to only dtag:fpte15 3581.1Smycroft tst.b d0 ;check for normalized value 3591.1Smycroft bne.b end_getop ;if inf/nan/zero leave get_op 3601.1Smycroft move.w FPTEMP_EX(a6),d0 3611.1Smycroft andi.w #$7fff,d0 3621.1Smycroft cmpi.w #$3fff,d0 ;check if fpte15 needs setting 3631.1Smycroft bge.b end_getop ;if >= $3fff, leave fpte15=0 3641.1Smycroft or.b #$10,DTAG(a6) 3651.1Smycroft bra.b end_getop 3661.1Smycroft 3671.1Smycroft* 3681.1Smycroft* At this point, it is either an fmoveout packed, unnorm or denorm 3691.1Smycroft* 3701.1Smycroftopclass3: 3711.1Smycroft clr.b DY_MO_FLG(a6) ;set dyadic/monadic flag to monadic 3721.1Smycroft bfextu CMDREG1B(a6){4:2},d0 3731.1Smycroft cmpi.b #3,d0 3741.1Smycroft bne.w src_ex_dnrm ;if not equal, must be unnorm or denorm 3751.1Smycroft* ;else it is a packed move out 3761.1Smycroft* ;exit 3771.1Smycroftend_getop: 3781.1Smycroft rts 3791.1Smycroft 3801.1Smycroft* 3811.1Smycroft* Sets the DY_MO_FLG correctly. This is used only on if it is an 3821.1Smycroft* unuspported data type exception. Set if dyadic. 3831.1Smycroft* 3841.1Smycroftchk_dy_mo: 3851.1Smycroft move.w CMDREG1B(a6),d0 3861.1Smycroft btst.l #5,d0 ;testing extension command word 3871.1Smycroft beq.b set_mon ;if bit 5 = 0 then monadic 3881.1Smycroft btst.l #4,d0 ;know that bit 5 = 1 3891.1Smycroft beq.b set_dya ;if bit 4 = 0 then dyadic 3901.1Smycroft andi.w #$007f,d0 ;get rid of all but extension bits {6:0} 3911.1Smycroft cmpi.w #$0038,d0 ;if extension = $38 then fcmp (dyadic) 3921.1Smycroft bne.b set_mon 3931.1Smycroftset_dya: 3941.1Smycroft st.b DY_MO_FLG(a6) ;set the inst flag type to dyadic 3951.1Smycroft rts 3961.1Smycroftset_mon: 3971.1Smycroft clr.b DY_MO_FLG(a6) ;set the inst flag type to monadic 3981.1Smycroft rts 3991.1Smycroft* 4001.1Smycroft* MK_NORM 4011.1Smycroft* 4021.1Smycroft* Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl 4031.1Smycroft* exception if denorm. 4041.1Smycroft* 4051.1Smycroft* CASE opclass 0x0 unsupp 4061.1Smycroft* mk_norm till msb set 4071.1Smycroft* set tag = norm 4081.1Smycroft* 4091.1Smycroft* CASE opclass 0x0 unimp 4101.1Smycroft* mk_norm till msb set or exp = 0 4111.1Smycroft* if integer bit = 0 4121.1Smycroft* tag = denorm 4131.1Smycroft* else 4141.1Smycroft* tag = norm 4151.1Smycroft* 4161.1Smycroft* CASE opclass 011 unsupp 4171.1Smycroft* mk_norm till msb set or exp = 0 4181.1Smycroft* if integer bit = 0 4191.1Smycroft* tag = denorm 4201.1Smycroft* set unfl_nmcexe = 1 4211.1Smycroft* else 4221.1Smycroft* tag = norm 4231.1Smycroft* 4241.1Smycroft* if exp <= $3fff 4251.1Smycroft* set ete15 or fpte15 = 1 4261.1Smycroft* else set ete15 or fpte15 = 0 4271.1Smycroft 4281.1Smycroft* input: 4291.1Smycroft* a0 = points to operand to be normalized 4301.1Smycroft* output: 4311.1Smycroft* L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) 4321.1Smycroft* L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) 4331.1Smycroft* the normalized operand is placed back on the fsave stack 4341.1Smycroftmk_norm: 4351.1Smycroft clr.l L_SCR1(a6) 4361.1Smycroft bclr.b #sign_bit,LOCAL_EX(a0) 4371.1Smycroft sne LOCAL_SGN(a0) ;transform into internal extended format 4381.1Smycroft 4391.1Smycroft cmpi.b #$2c,1+EXC_VEC(a6) ;check if unimp 4401.1Smycroft bne.b uns_data ;branch if unsupp 4411.1Smycroft bsr uni_inst ;call if unimp (opclass 0x0) 4421.1Smycroft bra.b reload 4431.1Smycroftuns_data: 4441.1Smycroft btst.b #direction_bit,CMDREG1B(a6) ;check transfer direction 4451.1Smycroft bne.b bit_set ;branch if set (opclass 011) 4461.1Smycroft bsr uns_opx ;call if opclass 0x0 4471.1Smycroft bra.b reload 4481.1Smycroftbit_set: 4491.1Smycroft bsr uns_op3 ;opclass 011 4501.1Smycroftreload: 4511.1Smycroft cmp.w #$3fff,LOCAL_EX(a0) ;if exp > $3fff 4521.1Smycroft bgt.b end_mk ; fpte15/ete15 already set to 0 4531.1Smycroft bset.b #4,L_SCR1(a6) ;else set fpte15/ete15 to 1 4541.1Smycroft* ;calling routine actually sets the 4551.1Smycroft* ;value on the stack (along with the 4561.1Smycroft* ;tag), since this routine doesn't 4571.1Smycroft* ;know if it should set ete15 or fpte15 4581.1Smycroft* ;ie, it doesn't know if this is the 4591.1Smycroft* ;src op or dest op. 4601.1Smycroftend_mk: 4611.1Smycroft bfclr LOCAL_SGN(a0){0:8} 4621.1Smycroft beq.b end_mk_pos 4631.1Smycroft bset.b #sign_bit,LOCAL_EX(a0) ;convert back to IEEE format 4641.1Smycroftend_mk_pos: 4651.1Smycroft rts 4661.1Smycroft* 4671.1Smycroft* CASE opclass 011 unsupp 4681.1Smycroft* 4691.1Smycroftuns_op3: 4701.1Smycroft bsr nrm_zero ;normalize till msb = 1 or exp = zero 4711.1Smycroft btst.b #7,LOCAL_HI(a0) ;if msb = 1 4721.1Smycroft bne.b no_unfl ;then branch 4731.1Smycroftset_unfl: 4741.2Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set denorm tag 4751.1Smycroft bset.b #unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit 4761.1Smycroftno_unfl: 4771.1Smycroft rts 4781.1Smycroft* 4791.1Smycroft* CASE opclass 0x0 unsupp 4801.1Smycroft* 4811.1Smycroftuns_opx: 4821.1Smycroft bsr nrm_zero ;normalize the number 4831.1Smycroft btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 4841.1Smycroft beq.b uns_den ;if clear then now have a denorm 4851.1Smycroftuns_nrm: 4861.1Smycroft or.b #norm_tag,L_SCR1(a6) ;set tag to norm 4871.1Smycroft rts 4881.1Smycroftuns_den: 4891.1Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 4901.1Smycroft rts 4911.1Smycroft* 4921.1Smycroft* CASE opclass 0x0 unimp 4931.1Smycroft* 4941.1Smycroftuni_inst: 4951.1Smycroft bsr nrm_zero 4961.1Smycroft btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 4971.1Smycroft beq.b uni_den ;if clear then now have a denorm 4981.1Smycroftuni_nrm: 4991.1Smycroft or.b #norm_tag,L_SCR1(a6) ;set tag to norm 5001.1Smycroft rts 5011.1Smycroftuni_den: 5021.1Smycroft or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 5031.1Smycroft rts 5041.1Smycroft 5051.1Smycroft* 5061.1Smycroft* Decimal to binary conversion 5071.1Smycroft* 5081.1Smycroft* Special cases of inf and NaNs are completed outside of decbin. 5091.1Smycroft* If the input is an snan, the snan bit is not set. 5101.1Smycroft* 5111.1Smycroft* input: 5121.1Smycroft* ETEMP(a6) - points to packed decimal string in memory 5131.1Smycroft* output: 5141.1Smycroft* fp0 - contains packed string converted to extended precision 5151.1Smycroft* ETEMP - same as fp0 5161.1Smycroftunpack: 5171.1Smycroft move.w CMDREG1B(a6),d0 ;examine command word, looking for fmove's 5181.1Smycroft and.w #$3b,d0 5191.1Smycroft beq move_unpack ;special handling for fmove: must set FPSR_CC 5201.1Smycroft 5211.1Smycroft move.w ETEMP(a6),d0 ;get word with inf information 5221.1Smycroft bfextu d0{20:12},d1 ;get exponent into d1 5231.1Smycroft cmpi.w #$0fff,d1 ;test for inf or NaN 5241.1Smycroft bne.b try_zero ;if not equal, it is not special 5251.1Smycroft bfextu d0{17:3},d1 ;get SE and y bits into d1 5261.1Smycroft cmpi.w #7,d1 ;SE and y bits must be on for special 5271.1Smycroft bne.b try_zero ;if not on, it is not special 5281.1Smycroft*input is of the special cases of inf and NaN 5291.1Smycroft tst.l ETEMP_HI(a6) ;check ms mantissa 5301.1Smycroft bne.b fix_nan ;if non-zero, it is a NaN 5311.1Smycroft tst.l ETEMP_LO(a6) ;check ls mantissa 5321.1Smycroft bne.b fix_nan ;if non-zero, it is a NaN 5331.1Smycroft bra.w finish ;special already on stack 5341.1Smycroftfix_nan: 5351.1Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 5361.1Smycroft bne.w finish 5371.1Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;always set snan if it is so 5381.1Smycroft bra.w finish 5391.1Smycrofttry_zero: 5401.1Smycroft move.w ETEMP_EX+2(a6),d0 ;get word 4 5411.1Smycroft andi.w #$000f,d0 ;clear all but last ni(y)bble 5421.1Smycroft tst.w d0 ;check for zero. 5431.1Smycroft bne.w not_spec 5441.1Smycroft tst.l ETEMP_HI(a6) ;check words 3 and 2 5451.1Smycroft bne.w not_spec 5461.1Smycroft tst.l ETEMP_LO(a6) ;check words 1 and 0 5471.1Smycroft bne.w not_spec 5481.1Smycroft tst.l ETEMP(a6) ;test sign of the zero 5491.1Smycroft bge.b pos_zero 5501.1Smycroft move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 5511.1Smycroft clr.l ETEMP_HI(a6) 5521.1Smycroft clr.l ETEMP_LO(a6) 5531.1Smycroft bra.w finish 5541.1Smycroftpos_zero: 5551.1Smycroft clr.l ETEMP(a6) 5561.1Smycroft clr.l ETEMP_HI(a6) 5571.1Smycroft clr.l ETEMP_LO(a6) 5581.1Smycroft bra.w finish 5591.1Smycroft 5601.1Smycroftnot_spec: 5611.1Smycroft fmovem.x fp0-fp1,-(a7) ;save fp0 - decbin returns in it 5621.1Smycroft bsr decbin 5631.1Smycroft fmove.x fp0,ETEMP(a6) ;put the unpacked sop in the fsave stack 5641.1Smycroft fmovem.x (a7)+,fp0-fp1 5651.1Smycroft fmove.l #0,FPSR ;clr fpsr from decbin 5661.1Smycroft bra finish 5671.1Smycroft 5681.1Smycroft* 5691.1Smycroft* Special handling for packed move in: Same results as all other 5701.1Smycroft* packed cases, but we must set the FPSR condition codes properly. 5711.1Smycroft* 5721.1Smycroftmove_unpack: 5731.1Smycroft move.w ETEMP(a6),d0 ;get word with inf information 5741.1Smycroft bfextu d0{20:12},d1 ;get exponent into d1 5751.1Smycroft cmpi.w #$0fff,d1 ;test for inf or NaN 5761.1Smycroft bne.b mtry_zero ;if not equal, it is not special 5771.1Smycroft bfextu d0{17:3},d1 ;get SE and y bits into d1 5781.1Smycroft cmpi.w #7,d1 ;SE and y bits must be on for special 5791.1Smycroft bne.b mtry_zero ;if not on, it is not special 5801.1Smycroft*input is of the special cases of inf and NaN 5811.1Smycroft tst.l ETEMP_HI(a6) ;check ms mantissa 5821.1Smycroft bne.b mfix_nan ;if non-zero, it is a NaN 5831.1Smycroft tst.l ETEMP_LO(a6) ;check ls mantissa 5841.1Smycroft bne.b mfix_nan ;if non-zero, it is a NaN 5851.1Smycroft*input is inf 5861.1Smycroft or.l #inf_mask,USER_FPSR(a6) ;set I bit 5871.1Smycroft tst.l ETEMP(a6) ;check sign 5881.1Smycroft bge.w finish 5891.1Smycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit 5901.1Smycroft bra.w finish ;special already on stack 5911.1Smycroftmfix_nan: 5921.1Smycroft or.l #nan_mask,USER_FPSR(a6) ;set NaN bit 5931.1Smycroft move.b #nan_tag,STAG(a6) ;set stag to NaN 5941.1Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 5951.1Smycroft bne.b mn_snan 5961.1Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set snan bit 5971.1Smycroft btst.b #snan_bit,FPCR_ENABLE(a6) ;test for snan enabled 5981.1Smycroft bne.b mn_snan 5991.1Smycroft bset.b #signan_bit,ETEMP_HI(a6) ;force snans to qnans 6001.1Smycroftmn_snan: 6011.1Smycroft tst.l ETEMP(a6) ;check for sign 6021.1Smycroft bge.w finish ;if clr, go on 6031.1Smycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit 6041.1Smycroft bra.w finish 6051.1Smycroft 6061.1Smycroftmtry_zero: 6071.1Smycroft move.w ETEMP_EX+2(a6),d0 ;get word 4 6081.1Smycroft andi.w #$000f,d0 ;clear all but last ni(y)bble 6091.1Smycroft tst.w d0 ;check for zero. 6101.1Smycroft bne.b mnot_spec 6111.1Smycroft tst.l ETEMP_HI(a6) ;check words 3 and 2 6121.1Smycroft bne.b mnot_spec 6131.1Smycroft tst.l ETEMP_LO(a6) ;check words 1 and 0 6141.1Smycroft bne.b mnot_spec 6151.1Smycroft tst.l ETEMP(a6) ;test sign of the zero 6161.1Smycroft bge.b mpos_zero 6171.1Smycroft or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z 6181.1Smycroft move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 6191.1Smycroft clr.l ETEMP_HI(a6) 6201.1Smycroft clr.l ETEMP_LO(a6) 6211.1Smycroft bra.b finish 6221.1Smycroftmpos_zero: 6231.1Smycroft or.l #z_mask,USER_FPSR(a6) ;set Z 6241.1Smycroft clr.l ETEMP(a6) 6251.1Smycroft clr.l ETEMP_HI(a6) 6261.1Smycroft clr.l ETEMP_LO(a6) 6271.1Smycroft bra.b finish 6281.1Smycroft 6291.1Smycroftmnot_spec: 6301.1Smycroft fmovem.x fp0-fp1,-(a7) ;save fp0 ,fp1 - decbin returns in fp0 6311.1Smycroft bsr decbin 6321.1Smycroft fmove.x fp0,ETEMP(a6) 6331.1Smycroft* ;put the unpacked sop in the fsave stack 6341.1Smycroft fmovem.x (a7)+,fp0-fp1 6351.1Smycroft 6361.1Smycroftfinish: 6371.1Smycroft move.w CMDREG1B(a6),d0 ;get the command word 6381.1Smycroft and.w #$fbff,d0 ;change the source specifier field to 6391.1Smycroft* ;extended (was packed). 6401.1Smycroft move.w d0,CMDREG1B(a6) ;write command word back to fsave stack 6411.1Smycroft* ;we need to do this so the 040 will 6421.1Smycroft* ;re-execute the inst. without taking 6431.1Smycroft* ;another packed trap. 6441.1Smycroft 6451.1Smycroftfix_stag: 6461.1Smycroft*Converted result is now in etemp on fsave stack, now set the source 6471.1Smycroft*tag (stag) 6481.1Smycroft* if (ete =$7fff) then INF or NAN 6491.1Smycroft* if (etemp = $x.0----0) then 6501.1Smycroft* stag = INF 6511.1Smycroft* else 6521.1Smycroft* stag = NAN 6531.1Smycroft* else 6541.1Smycroft* if (ete = $0000) then 6551.1Smycroft* stag = ZERO 6561.1Smycroft* else 6571.1Smycroft* stag = NORM 6581.1Smycroft* 6591.1Smycroft* Note also that the etemp_15 bit (just right of the stag) must 6601.1Smycroft* be set accordingly. 6611.1Smycroft* 6621.1Smycroft move.w ETEMP_EX(a6),d1 6631.1Smycroft andi.w #$7fff,d1 ;strip sign 6641.1Smycroft cmp.w #$7fff,d1 6651.1Smycroft bne.b z_or_nrm 6661.1Smycroft move.l ETEMP_HI(a6),d1 6671.1Smycroft bne.b is_nan 6681.1Smycroft move.l ETEMP_LO(a6),d1 6691.1Smycroft bne.b is_nan 6701.1Smycroftis_inf: 6711.1Smycroft move.b #$40,STAG(a6) 6721.1Smycroft move.l #$40,d0 6731.1Smycroft rts 6741.1Smycroftis_nan: 6751.1Smycroft move.b #$60,STAG(a6) 6761.1Smycroft move.l #$60,d0 6771.1Smycroft rts 6781.1Smycroftz_or_nrm: 6791.1Smycroft tst.w d1 6801.1Smycroft bne.b is_nrm 6811.1Smycroftis_zro: 6821.1Smycroft* For a zero, set etemp_15 6831.1Smycroft move.b #$30,STAG(a6) 6841.1Smycroft move.l #$20,d0 6851.1Smycroft rts 6861.1Smycroftis_nrm: 6871.1Smycroft* For a norm, check if the exp <= $3fff; if so, set etemp_15 6881.1Smycroft cmpi.w #$3fff,d1 6891.1Smycroft ble.b set_bit15 6901.2Smycroft clr.b STAG(a6) 6911.1Smycroft bra.b end_is_nrm 6921.1Smycroftset_bit15: 6931.1Smycroft move.b #$10,STAG(a6) 6941.1Smycroftend_is_nrm: 6951.2Smycroft clr.l d0 6961.1Smycroftend_fix: 6971.1Smycroft rts 6981.1Smycroft 6991.1Smycroftend_get: 7001.1Smycroft rts 7011.1Smycroft end 702