head     56.3;
access   ;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.58.31;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.29.46;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.07.12.31.38;  author jwh;  state Exp;
branches ;
next     1.1;

1.1
date     91.03.13.09.07.10;  author jwh;  state Exp;
branches ;
next     ;


desc
@@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@*
*       x_store.sa 3.1 12/10/90
*
*       store --- store operand to memory or register
*
*       Used by underflow and overflow handlers.
*
*       a6 = points to fp value to be stored.
*

*               Copyright (C) Motorola, Inc. 1990
*                       All Rights Reserved
*
*       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
*       The copyright notice above does not evidence any
*       actual or intended publication of such source code.



fpreg_mask    equ    *
	dc.b    $80,$40,$20,$10,$08,$04,$02,$01

	include fpsp_h

	refr    mem_write
	refr    get_fline
	refr    g_opcls
	refr    g_dfmtou
	refr    reg_dest

	def     dest_ext
	def     dest_dbl
	def     dest_sgl

	def     store
store    equ    *
	btst    #E3,E_BYTE(a6)
	beq.b   E1_sto
E3_sto    equ    *
	move.l  CMDREG3B(a6),d0
	bfextu  d0{6:3},d0              ;isolate dest. reg from cmdreg3b
sto_fp    equ    *
	lea     fpreg_mask,a1
	move.b  (a1,d0.w),d0            ;convert reg# to dynamic register mask
	tst.b   LOCAL_SGN(a0)
	beq.b   is_pos
	bset    #sign_bit,LOCAL_EX(a0)
is_pos    equ    *
	fmovem.x (a0),d0                ;move to correct register
*
*       if fp0-fp3 is being modified, we must put a copy
*       in the USER_FPn variable on the stack because all exception
*       handlers restore fp0-fp3 from there.
*
	cmp.b   #$80,d0
	bne.b   not_fp0
	fmovem.x fp0,USER_FP0(a6)
	rts
not_fp0    equ    *
	cmp.b   #$40,d0
	bne.b   not_fp1
	fmovem.x fp1,USER_FP1(a6)
	rts
not_fp1    equ    *
	cmp.b   #$20,d0
	bne.b   not_fp2
	fmovem.x fp1,USER_FP2(a6)
	rts
not_fp2    equ    *
	cmp.b   #$10,d0
	bne.b   not_fp3
	fmovem.x fp1,USER_FP3(a6)
	rts
not_fp3    equ    *
	rts

E1_sto    equ    *
	bsr.l   g_opcls         ;returns opclass in d0
	cmpi.b  #3,d0
	beq     opc011          ;branch if opclass 3
	move.l  CMDREG1B(a6),d0
	bfextu  d0{6:3},d0      ;extract destination register
	bra.b   sto_fp

opc011    equ    *
	bsr.l   g_dfmtou        ;returns dest format in d0
*                               ;ext=00, sgl=01, dbl=10
	move.l  a0,a1           ;save source addr in a1
	move.l  EXC_EA(a6),a0   ;get the address
	cmpi.l  #0,d0           ;if dest format is extended
	beq.w   dest_ext        ;then branch
	cmpi.l  #1,d0           ;if dest format is single
	beq.b   dest_sgl        ;then branch
*
*       fall through to dest_dbl
*

*
*       dest_dbl --- write double precision value to user space
*
*Input
*       a0 -> destination address
*       a1 -> source in extended precision
*Output
*       a0 -> destroyed
*       a1 -> destroyed
*       d0 -> 0
*
*Changes extended precision to double precision.
* Note: no attempt is made to round the extended value to double.
*       dbl_sign = ext_sign
*       dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
*       get rid of ext integer bit
*       dbl_mant = ext_mant{62:12}
*
*               ---------------   ---------------    ---------------
*  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
*               ---------------   ---------------    ---------------
*                95         64    63 62       32      31     11   0
*                                    |                       |
*                                    |                       |
*                                    |                       |
*                                    v                       v
*                             ---------------   ---------------
*  double   ->                |s|exp| mant  |   |  mant       |
*                             ---------------   ---------------
*                             63     51   32   31              0
*
dest_dbl    equ    *
	clr.l   d0              ;clear d0
	move.w  LOCAL_EX(a1),d0 ;get exponent
	sub.w   #$3fff,d0       ;subtract extended precision bias
	cmp.w   #$4000,d0       ;check if inf
	beq.b   inf             ;if so, special case
	add.w   #$3ff,d0        ;add double precision bias
	swap    d0              ;d0 now in upper word
	lsl.l   #4,d0           ;d0 now in proper place for dbl prec exp
	tst.b   LOCAL_SGN(a1)
	beq.b   get_mant        ;if postive, go process mantissa
	bset    #31,d0          ;if negative, put in sign information
*                               ; before continuing
	bra.b   get_mant        ;go process mantissa
inf    equ    *
	move.l  #$7ff00000,d0   ;load dbl inf exponent
	clr.l   LOCAL_HI(a1)    ;clear msb
	tst.b   LOCAL_SGN(a1)
	beq.b   dbl_inf         ;if positive, go ahead and write it
	bset    #31,d0          ;if negative put in sign information
dbl_inf    equ    *
	move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
	bra.b   dbl_wrt
get_mant    equ    *
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	bfextu  d1{1:20},d1     ;get upper 20 bits of ms
	or.l    d1,d0           ;put these bits in ms word of double
	move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	move.l  #21,d0          ;load shift count
	lsl.l   d0,d1           ;put lower 11 bits in upper bits
	move.l  d1,LOCAL_HI(a1) ;build lower lword in memory
	move.l  LOCAL_LO(a1),d1 ;get ls mantissa
	bfextu  d1{0:21},d0     ;get ls 21 bits of double
	or.l    d0,LOCAL_HI(a1) ;put them in double result
dbl_wrt    equ    *
	move.l  #$8,d0          ;byte count for double precision number
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	bsr.l   mem_write       ;move the number to the user's memory
	rts
*
*       dest_sgl --- write single precision value to user space
*
*Input
*       a0 -> destination address
*       a1 -> source in extended precision
*
*Output
*       a0 -> destroyed
*       a1 -> destroyed
*       d0 -> 0
*
*Changes extended precision to single precision.
*       sgl_sign = ext_sign
*       sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
*       get rid of ext integer bit
*       sgl_mant = ext_mant{62:12}
*
*               ---------------   ---------------    ---------------
*  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
*               ---------------   ---------------    ---------------
*                95         64    63 62    40 32      31     12   0
*                                    |     |
*                                    |     |
*                                    |     |
*                                    v     v
*                             ---------------
*  single   ->                |s|exp| mant  |
*                             ---------------
*                             31     22     0
*
dest_sgl    equ    *
	clr.l   d0
	move.w  LOCAL_EX(a1),d0 ;get exponent
	sub.w   #$3fff,d0       ;subtract extended precision bias
	cmp.w   #$4000,d0       ;check if inf
	beq.b   sinf            ;if so, special case
	add.w   #$7f,d0         ;add single precision bias
	swap    d0              ;put exp in upper word of d0
	lsl.l   #7,d0           ;shift it into single exp bits
	tst.b   LOCAL_SGN(a1)
	beq.b   get_sman        ;if positive, continue
	bset    #31,d0          ;if negative, put in sign first
	bra.b   get_sman        ;get mantissa
sinf    equ    *
	move.l  #$7f800000,d0   ;load single inf exp to d0
	tst.b   LOCAL_SGN(a1)
	beq.b   sgl_wrt         ;if positive, continue
	bset    #31,d0          ;if negative, put in sign info
	bra.b   sgl_wrt

get_sman    equ    *
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	bfextu  d1{1:23},d1     ;get upper 23 bits of ms
	or.l    d1,d0           ;put these bits in ms word of single

sgl_wrt    equ    *
	move.l  d0,L_SCR1(a6)   ;put the new exp back on the stack
	move.l  #$4,d0          ;byte count for single precision number
	tst.l   a0              ;users destination address
	beq.b   sgl_Dn          ;destination is a data register
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	lea     L_SCR1(a6),a0   ;point a0 to data
	bsr.l   mem_write       ;move the number to the user's memory
	rts
sgl_Dn    equ    *
	bsr.l   get_fline       ;returns fline word in d0
	and.w   #$7,d0          ;isolate register number
	move.l  d0,d1           ;d1 has size:reg formatted for reg_dest
	or.l    #$10,d1         ;reg_dest wants size added to reg#
	bra.l   reg_dest        ;size is X, rts in reg_dest will
*                               ;return to caller of dest_sgl

dest_ext    equ    *
	tst.b   LOCAL_SGN(a1)   ;put back sign into exponent word
	beq.b   dstx_cont
	bset    #sign_bit,LOCAL_EX(a1)
dstx_cont    equ    *
	clr.b   LOCAL_SGN(a1)   ;clear out the sign byte

	move.l  #$0c,d0         ;byte count for extended number
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	bsr.l   mem_write       ;move the number to the user's memory
	rts

	end
@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 254
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 254
*
*       x_store.sa 3.1 12/10/90
*
*       store --- store operand to memory or register
*
*       Used by underflow and overflow handlers.
*
*       a6 = points to fp value to be stored.
*

*               Copyright (C) Motorola, Inc. 1990
*                       All Rights Reserved
*
*       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
*       The copyright notice above does not evidence any
*       actual or intended publication of such source code.



fpreg_mask    equ    *
	dc.b    $80,$40,$20,$10,$08,$04,$02,$01

	include fpsp_h

	refr    mem_write
	refr    get_fline
	refr    g_opcls
	refr    g_dfmtou
	refr    reg_dest

	def     dest_ext
	def     dest_dbl
	def     dest_sgl

	def     store
store    equ    *
	btst    #E3,E_BYTE(a6)
	beq.b   E1_sto
E3_sto    equ    *
	move.l  CMDREG3B(a6),d0
	bfextu  d0{6:3},d0              ;isolate dest. reg from cmdreg3b
sto_fp    equ    *
	lea     fpreg_mask,a1
	move.b  (a1,d0.w),d0            ;convert reg# to dynamic register mask
	tst.b   LOCAL_SGN(a0)
	beq.b   is_pos
	bset    #sign_bit,LOCAL_EX(a0)
is_pos    equ    *
	fmovem.x (a0),d0                ;move to correct register
*
*       if fp0-fp3 is being modified, we must put a copy
*       in the USER_FPn variable on the stack because all exception
*       handlers restore fp0-fp3 from there.
*
	cmp.b   #$80,d0
	bne.b   not_fp0
	fmovem.x fp0,USER_FP0(a6)
	rts
not_fp0    equ    *
	cmp.b   #$40,d0
	bne.b   not_fp1
	fmovem.x fp1,USER_FP1(a6)
	rts
not_fp1    equ    *
	cmp.b   #$20,d0
	bne.b   not_fp2
	fmovem.x fp1,USER_FP2(a6)
	rts
not_fp2    equ    *
	cmp.b   #$10,d0
	bne.b   not_fp3
	fmovem.x fp1,USER_FP3(a6)
	rts
not_fp3    equ    *
	rts

E1_sto    equ    *
	bsr.l   g_opcls         ;returns opclass in d0
	cmpi.b  #3,d0
	beq     opc011          ;branch if opclass 3
	move.l  CMDREG1B(a6),d0
	bfextu  d0{6:3},d0      ;extract destination register
	bra.b   sto_fp

opc011    equ    *
	bsr.l   g_dfmtou        ;returns dest format in d0
*                               ;ext=00, sgl=01, dbl=10
	move.l  a0,a1           ;save source addr in a1
	move.l  EXC_EA(a6),a0   ;get the address
	cmpi.l  #0,d0           ;if dest format is extended
	beq.w   dest_ext        ;then branch
	cmpi.l  #1,d0           ;if dest format is single
	beq.b   dest_sgl        ;then branch
*
*       fall through to dest_dbl
*

*
*       dest_dbl --- write double precision value to user space
*
*Input
*       a0 -> destination address
*       a1 -> source in extended precision
*Output
*       a0 -> destroyed
*       a1 -> destroyed
*       d0 -> 0
*
*Changes extended precision to double precision.
* Note: no attempt is made to round the extended value to double.
*       dbl_sign = ext_sign
*       dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
*       get rid of ext integer bit
*       dbl_mant = ext_mant{62:12}
*
*               ---------------   ---------------    ---------------
*  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
*               ---------------   ---------------    ---------------
*                95         64    63 62       32      31     11   0
*                                    |                       |
*                                    |                       |
*                                    |                       |
*                                    v                       v
*                             ---------------   ---------------
*  double   ->                |s|exp| mant  |   |  mant       |
*                             ---------------   ---------------
*                             63     51   32   31              0
*
dest_dbl    equ    *
	clr.l   d0              ;clear d0
	move.w  LOCAL_EX(a1),d0 ;get exponent
	sub.w   #$3fff,d0       ;subtract extended precision bias
	cmp.w   #$4000,d0       ;check if inf
	beq.b   inf             ;if so, special case
	add.w   #$3ff,d0        ;add double precision bias
	swap    d0              ;d0 now in upper word
	lsl.l   #4,d0           ;d0 now in proper place for dbl prec exp
	tst.b   LOCAL_SGN(a1)
	beq.b   get_mant        ;if postive, go process mantissa
	bset    #31,d0          ;if negative, put in sign information
*                               ; before continuing
	bra.b   get_mant        ;go process mantissa
inf    equ    *
	move.l  #$7ff00000,d0   ;load dbl inf exponent
	clr.l   LOCAL_HI(a1)    ;clear msb
	tst.b   LOCAL_SGN(a1)
	beq.b   dbl_inf         ;if positive, go ahead and write it
	bset    #31,d0          ;if negative put in sign information
dbl_inf    equ    *
	move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
	bra.b   dbl_wrt
get_mant    equ    *
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	bfextu  d1{1:20},d1     ;get upper 20 bits of ms
	or.l    d1,d0           ;put these bits in ms word of double
	move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	move.l  #21,d0          ;load shift count
	lsl.l   d0,d1           ;put lower 11 bits in upper bits
	move.l  d1,LOCAL_HI(a1) ;build lower lword in memory
	move.l  LOCAL_LO(a1),d1 ;get ls mantissa
	bfextu  d1{0:21},d0     ;get ls 21 bits of double
	or.l    d0,LOCAL_HI(a1) ;put them in double result
dbl_wrt    equ    *
	move.l  #$8,d0          ;byte count for double precision number
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	bsr.l   mem_write       ;move the number to the user's memory
	rts
*
*       dest_sgl --- write single precision value to user space
*
*Input
*       a0 -> destination address
*       a1 -> source in extended precision
*
*Output
*       a0 -> destroyed
*       a1 -> destroyed
*       d0 -> 0
*
*Changes extended precision to single precision.
*       sgl_sign = ext_sign
*       sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
*       get rid of ext integer bit
*       sgl_mant = ext_mant{62:12}
*
*               ---------------   ---------------    ---------------
*  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
*               ---------------   ---------------    ---------------
*                95         64    63 62    40 32      31     12   0
*                                    |     |
*                                    |     |
*                                    |     |
*                                    v     v
*                             ---------------
*  single   ->                |s|exp| mant  |
*                             ---------------
*                             31     22     0
*
dest_sgl    equ    *
	clr.l   d0
	move.w  LOCAL_EX(a1),d0 ;get exponent
	sub.w   #$3fff,d0       ;subtract extended precision bias
	cmp.w   #$4000,d0       ;check if inf
	beq.b   sinf            ;if so, special case
	add.w   #$7f,d0         ;add single precision bias
	swap    d0              ;put exp in upper word of d0
	lsl.l   #7,d0           ;shift it into single exp bits
	tst.b   LOCAL_SGN(a1)
	beq.b   get_sman        ;if positive, continue
	bset    #31,d0          ;if negative, put in sign first
	bra.b   get_sman        ;get mantissa
sinf    equ    *
	move.l  #$7f800000,d0   ;load single inf exp to d0
	tst.b   LOCAL_SGN(a1)
	beq.b   sgl_wrt         ;if positive, continue
	bset    #31,d0          ;if negative, put in sign info
	bra.b   sgl_wrt

get_sman    equ    *
	move.l  LOCAL_HI(a1),d1 ;get ms mantissa
	bfextu  d1{1:23},d1     ;get upper 23 bits of ms
	or.l    d1,d0           ;put these bits in ms word of single

sgl_wrt    equ    *
	move.l  d0,L_SCR1(a6)   ;put the new exp back on the stack
	move.l  #$4,d0          ;byte count for single precision number
	tst.l   a0              ;users destination address
	beq.b   sgl_Dn          ;destination is a data register
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	lea     L_SCR1(a6),a0   ;point a0 to data
	bsr.l   mem_write       ;move the number to the user's memory
	rts
sgl_Dn    equ    *
	bsr.l   get_fline       ;returns fline word in d0
	and.w   #$7,d0          ;isolate register number
	move.l  d0,d1           ;d1 has size:reg formatted for reg_dest
	or.l    #$10,d1         ;reg_dest wants size added to reg#
	bra.l   reg_dest        ;size is X, rts in reg_dest will
*                               ;return to caller of dest_sgl

dest_ext    equ    *
	tst.b   LOCAL_SGN(a1)   ;put back sign into exponent word
	beq.b   dstx_cont
	bset    #sign_bit,LOCAL_EX(a1)
dstx_cont    equ    *
	clr.b   LOCAL_SGN(a1)   ;clear out the sign byte

	move.l  #$0c,d0         ;byte count for extended number
	exg     a0,a1           ;a0=supervisor source, a1=user dest
	bsr.l   mem_write       ;move the number to the user's memory
	rts

	end
@


1.1
log
@Initial revision
@
text
@@
