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