x_store.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* x_store.sa 3.2 1/24/91 331.1Smycroft* 341.1Smycroft* store --- store operand to memory or register 351.1Smycroft* 361.1Smycroft* Used by underflow and overflow handlers. 371.1Smycroft* 381.1Smycroft* a6 = points to fp value to be stored. 391.1Smycroft* 401.1Smycroft 411.1SmycroftX_STORE IDNT 2,1 Motorola 040 Floating Point Software Package 421.1Smycroft 431.1Smycroft section 8 441.1Smycroft 451.1Smycroftfpreg_mask: 461.1Smycroft dc.b $80,$40,$20,$10,$08,$04,$02,$01 471.1Smycroft 481.1Smycroft include fpsp.h 491.1Smycroft 501.1Smycroft xref mem_write 511.1Smycroft xref get_fline 521.1Smycroft xref g_opcls 531.1Smycroft xref g_dfmtou 541.1Smycroft xref reg_dest 551.1Smycroft 561.1Smycroft xdef dest_ext 571.1Smycroft xdef dest_dbl 581.1Smycroft xdef dest_sgl 591.1Smycroft 601.1Smycroft xdef store 611.1Smycroftstore: 621.1Smycroft btst.b #E3,E_BYTE(a6) 631.1Smycroft beq.b E1_sto 641.1SmycroftE3_sto: 651.1Smycroft move.l CMDREG3B(a6),d0 661.1Smycroft bfextu d0{6:3},d0 ;isolate dest. reg from cmdreg3b 671.1Smycroftsto_fp: 681.1Smycroft lea fpreg_mask,a1 691.1Smycroft move.b (a1,d0.w),d0 ;convert reg# to dynamic register mask 701.1Smycroft tst.b LOCAL_SGN(a0) 711.1Smycroft beq.b is_pos 721.1Smycroft bset.b #sign_bit,LOCAL_EX(a0) 731.1Smycroftis_pos: 741.1Smycroft fmovem.x (a0),d0 ;move to correct register 751.1Smycroft* 761.1Smycroft* if fp0-fp3 is being modified, we must put a copy 771.1Smycroft* in the USER_FPn variable on the stack because all exception 781.1Smycroft* handlers restore fp0-fp3 from there. 791.1Smycroft* 801.1Smycroft cmp.b #$80,d0 811.1Smycroft bne.b not_fp0 821.1Smycroft fmovem.x fp0,USER_FP0(a6) 831.1Smycroft rts 841.1Smycroftnot_fp0: 851.1Smycroft cmp.b #$40,d0 861.1Smycroft bne.b not_fp1 871.1Smycroft fmovem.x fp1,USER_FP1(a6) 881.1Smycroft rts 891.1Smycroftnot_fp1: 901.1Smycroft cmp.b #$20,d0 911.1Smycroft bne.b not_fp2 921.1Smycroft fmovem.x fp2,USER_FP2(a6) 931.1Smycroft rts 941.1Smycroftnot_fp2: 951.1Smycroft cmp.b #$10,d0 961.1Smycroft bne.b not_fp3 971.1Smycroft fmovem.x fp3,USER_FP3(a6) 981.1Smycroft rts 991.1Smycroftnot_fp3: 1001.1Smycroft rts 1011.1Smycroft 1021.1SmycroftE1_sto: 1031.1Smycroft bsr.l g_opcls ;returns opclass in d0 1041.1Smycroft cmpi.b #3,d0 1051.1Smycroft beq opc011 ;branch if opclass 3 1061.1Smycroft move.l CMDREG1B(a6),d0 1071.1Smycroft bfextu d0{6:3},d0 ;extract destination register 1081.1Smycroft bra.b sto_fp 1091.1Smycroft 1101.1Smycroftopc011: 1111.1Smycroft bsr.l g_dfmtou ;returns dest format in d0 1121.1Smycroft* ;ext=00, sgl=01, dbl=10 1131.1Smycroft move.l a0,a1 ;save source addr in a1 1141.1Smycroft move.l EXC_EA(a6),a0 ;get the address 1151.1Smycroft cmpi.l #0,d0 ;if dest format is extended 1161.1Smycroft beq.w dest_ext ;then branch 1171.1Smycroft cmpi.l #1,d0 ;if dest format is single 1181.1Smycroft beq.b dest_sgl ;then branch 1191.1Smycroft* 1201.1Smycroft* fall through to dest_dbl 1211.1Smycroft* 1221.1Smycroft 1231.1Smycroft* 1241.1Smycroft* dest_dbl --- write double precision value to user space 1251.1Smycroft* 1261.1Smycroft*Input 1271.1Smycroft* a0 -> destination address 1281.1Smycroft* a1 -> source in extended precision 1291.1Smycroft*Output 1301.1Smycroft* a0 -> destroyed 1311.1Smycroft* a1 -> destroyed 1321.1Smycroft* d0 -> 0 1331.1Smycroft* 1341.1Smycroft*Changes extended precision to double precision. 1351.1Smycroft* Note: no attempt is made to round the extended value to double. 1361.1Smycroft* dbl_sign = ext_sign 1371.1Smycroft* dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias) 1381.1Smycroft* get rid of ext integer bit 1391.1Smycroft* dbl_mant = ext_mant{62:12} 1401.1Smycroft* 1411.1Smycroft* --------------- --------------- --------------- 1421.1Smycroft* extended -> |s| exp | |1| ms mant | | ls mant | 1431.1Smycroft* --------------- --------------- --------------- 1441.1Smycroft* 95 64 63 62 32 31 11 0 1451.1Smycroft* | | 1461.1Smycroft* | | 1471.1Smycroft* | | 1481.1Smycroft* v v 1491.1Smycroft* --------------- --------------- 1501.1Smycroft* double -> |s|exp| mant | | mant | 1511.1Smycroft* --------------- --------------- 1521.1Smycroft* 63 51 32 31 0 1531.1Smycroft* 1541.1Smycroftdest_dbl: 1551.1Smycroft clr.l d0 ;clear d0 1561.1Smycroft move.w LOCAL_EX(a1),d0 ;get exponent 1571.1Smycroft sub.w #$3fff,d0 ;subtract extended precision bias 1581.1Smycroft cmp.w #$4000,d0 ;check if inf 1591.1Smycroft beq.b inf ;if so, special case 1601.1Smycroft add.w #$3ff,d0 ;add double precision bias 1611.1Smycroft swap d0 ;d0 now in upper word 1621.1Smycroft lsl.l #4,d0 ;d0 now in proper place for dbl prec exp 1631.1Smycroft tst.b LOCAL_SGN(a1) 1641.1Smycroft beq.b get_mant ;if postive, go process mantissa 1651.1Smycroft bset.l #31,d0 ;if negative, put in sign information 1661.1Smycroft* ; before continuing 1671.1Smycroft bra.b get_mant ;go process mantissa 1681.1Smycroftinf: 1691.1Smycroft move.l #$7ff00000,d0 ;load dbl inf exponent 1701.1Smycroft clr.l LOCAL_HI(a1) ;clear msb 1711.1Smycroft tst.b LOCAL_SGN(a1) 1721.1Smycroft beq.b dbl_inf ;if positive, go ahead and write it 1731.1Smycroft bset.l #31,d0 ;if negative put in sign information 1741.1Smycroftdbl_inf: 1751.1Smycroft move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack 1761.1Smycroft bra.b dbl_wrt 1771.1Smycroftget_mant: 1781.1Smycroft move.l LOCAL_HI(a1),d1 ;get ms mantissa 1791.1Smycroft bfextu d1{1:20},d1 ;get upper 20 bits of ms 1801.1Smycroft or.l d1,d0 ;put these bits in ms word of double 1811.1Smycroft move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack 1821.1Smycroft move.l LOCAL_HI(a1),d1 ;get ms mantissa 1831.1Smycroft move.l #21,d0 ;load shift count 1841.1Smycroft lsl.l d0,d1 ;put lower 11 bits in upper bits 1851.1Smycroft move.l d1,LOCAL_HI(a1) ;build lower lword in memory 1861.1Smycroft move.l LOCAL_LO(a1),d1 ;get ls mantissa 1871.1Smycroft bfextu d1{0:21},d0 ;get ls 21 bits of double 1881.1Smycroft or.l d0,LOCAL_HI(a1) ;put them in double result 1891.1Smycroftdbl_wrt: 1901.1Smycroft move.l #$8,d0 ;byte count for double precision number 1911.1Smycroft exg a0,a1 ;a0=supervisor source, a1=user dest 1921.1Smycroft bsr.l mem_write ;move the number to the user's memory 1931.1Smycroft rts 1941.1Smycroft* 1951.1Smycroft* dest_sgl --- write single precision value to user space 1961.1Smycroft* 1971.1Smycroft*Input 1981.1Smycroft* a0 -> destination address 1991.1Smycroft* a1 -> source in extended precision 2001.1Smycroft* 2011.1Smycroft*Output 2021.1Smycroft* a0 -> destroyed 2031.1Smycroft* a1 -> destroyed 2041.1Smycroft* d0 -> 0 2051.1Smycroft* 2061.1Smycroft*Changes extended precision to single precision. 2071.1Smycroft* sgl_sign = ext_sign 2081.1Smycroft* sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias) 2091.1Smycroft* get rid of ext integer bit 2101.1Smycroft* sgl_mant = ext_mant{62:12} 2111.1Smycroft* 2121.1Smycroft* --------------- --------------- --------------- 2131.1Smycroft* extended -> |s| exp | |1| ms mant | | ls mant | 2141.1Smycroft* --------------- --------------- --------------- 2151.1Smycroft* 95 64 63 62 40 32 31 12 0 2161.1Smycroft* | | 2171.1Smycroft* | | 2181.1Smycroft* | | 2191.1Smycroft* v v 2201.1Smycroft* --------------- 2211.1Smycroft* single -> |s|exp| mant | 2221.1Smycroft* --------------- 2231.1Smycroft* 31 22 0 2241.1Smycroft* 2251.1Smycroftdest_sgl: 2261.1Smycroft clr.l d0 2271.1Smycroft move.w LOCAL_EX(a1),d0 ;get exponent 2281.1Smycroft sub.w #$3fff,d0 ;subtract extended precision bias 2291.1Smycroft cmp.w #$4000,d0 ;check if inf 2301.1Smycroft beq.b sinf ;if so, special case 2311.1Smycroft add.w #$7f,d0 ;add single precision bias 2321.1Smycroft swap d0 ;put exp in upper word of d0 2331.1Smycroft lsl.l #7,d0 ;shift it into single exp bits 2341.1Smycroft tst.b LOCAL_SGN(a1) 2351.1Smycroft beq.b get_sman ;if positive, continue 2361.1Smycroft bset.l #31,d0 ;if negative, put in sign first 2371.1Smycroft bra.b get_sman ;get mantissa 2381.1Smycroftsinf: 2391.1Smycroft move.l #$7f800000,d0 ;load single inf exp to d0 2401.1Smycroft tst.b LOCAL_SGN(a1) 2411.1Smycroft beq.b sgl_wrt ;if positive, continue 2421.1Smycroft bset.l #31,d0 ;if negative, put in sign info 2431.1Smycroft bra.b sgl_wrt 2441.1Smycroft 2451.1Smycroftget_sman: 2461.1Smycroft move.l LOCAL_HI(a1),d1 ;get ms mantissa 2471.1Smycroft bfextu d1{1:23},d1 ;get upper 23 bits of ms 2481.1Smycroft or.l d1,d0 ;put these bits in ms word of single 2491.1Smycroft 2501.1Smycroftsgl_wrt: 2511.1Smycroft move.l d0,L_SCR1(a6) ;put the new exp back on the stack 2521.1Smycroft move.l #$4,d0 ;byte count for single precision number 2531.1Smycroft tst.l a0 ;users destination address 2541.1Smycroft beq.b sgl_Dn ;destination is a data register 2551.1Smycroft exg a0,a1 ;a0=supervisor source, a1=user dest 2561.1Smycroft lea.l L_SCR1(a6),a0 ;point a0 to data 2571.1Smycroft bsr.l mem_write ;move the number to the user's memory 2581.1Smycroft rts 2591.1Smycroftsgl_Dn: 2601.1Smycroft bsr.l get_fline ;returns fline word in d0 2611.1Smycroft and.w #$7,d0 ;isolate register number 2621.1Smycroft move.l d0,d1 ;d1 has size:reg formatted for reg_dest 2631.1Smycroft or.l #$10,d1 ;reg_dest wants size added to reg# 2641.1Smycroft bra.l reg_dest ;size is X, rts in reg_dest will 2651.1Smycroft* ;return to caller of dest_sgl 2661.1Smycroft 2671.1Smycroftdest_ext: 2681.1Smycroft tst.b LOCAL_SGN(a1) ;put back sign into exponent word 2691.1Smycroft beq.b dstx_cont 2701.1Smycroft bset.b #sign_bit,LOCAL_EX(a1) 2711.1Smycroftdstx_cont: 2721.1Smycroft clr.b LOCAL_SGN(a1) ;clear out the sign byte 2731.1Smycroft 2741.1Smycroft move.l #$0c,d0 ;byte count for extended number 2751.1Smycroft exg a0,a1 ;a0=supervisor source, a1=user dest 2761.1Smycroft bsr.l mem_write ;move the number to the user's memory 2771.1Smycroft rts 2781.1Smycroft 2791.1Smycroft end 280