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