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


56.1
date     91.11.05.09.33.36;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.11.56;  author jwh;  state Exp;
branches ;
next     54.2;

54.2
date     91.08.21.14.38.49;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.19.01;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.20.01;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.04.34;  author jwh;  state Exp;
branches ;
next     51.2;

51.2
date     91.02.10.16.32.24;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.03.47;  author jwh;  state Exp;
branches ;
next     1.1;

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


desc
@first version.
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.2
log
@
pws2rcs automatic delta on Wed Aug 21 13:42:03 MDT 1991
@
text
@@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@a0 369
*
*       scale.sa 3.1 12/10/90
*
*       The entry point sSCALE computes the destination operand
*       scaled by the source operand.  If the absoulute value of
*       the source operand is (>= 2^14) an overflow or underflow
*       is returned.
*
*       The entry point sscale is called from do_func to emulate
*       the fscale unimplemented instruction.
*
*       Input: Double-extended destination operand in FPTEMP,
*               double-extended source operand in ETEMP.
*
*       Output: The function returns scale(X,Y) to fp0.
*
*       Modifies: fp0.
*
*       Algorithm:
*
*               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.



	include fpsp_h

	refr    t_ovfl2
	refr    t_unfl
	refr    round
	refr    t_resdnrm

* added to replace single-precision floating point immediates
V80000000  dc.l  $80000000
V00000000  dc.l  $00000000

SRC_BNDS dc.w   $3fff,$400c

*
* This entry point is used by the unimplemented instruction exception
* handler.
*
*
*
*       FSCALE
*
	def     sscale
sscale    equ    *
	fmove.l         #0,FPCONTROL            ;clr user enabled exc
	clr.l           d1
	move.w          FPTEMP(a6),d1   ;get dest exponent
	smi             L_SCR1(a6)      ;use L_SCR1 to hold sign
	andi.l          #$7fff,d1       ;strip sign
	move.w          ETEMP(a6),d0    ;check src bounds
	andi.w          #$7fff,d0       ;clr sign bit
	cmp2.w          SRC_BNDS,d0
	bcc.b           src_in
	cmpi.w          #$400c,d0       ;test for too large
	bge.w           src_out
*
* The source input is below 1, so we check for denormalized numbers
* and set unfl.
*
src_small    equ    *
	move.b          DTAG(a6),d0
	andi.b          #$e0,d0
	tst.b           d0
	beq.b           no_denorm
	st              STORE_FLG(a6)   ;dest already contains result
	ori.l           #unfl_mask,USER_FPSTATUS(a6) ;set UNFL
den_done    equ    *
	lea             FPTEMP(a6),a0
	bra             t_resdnrm
no_denorm    equ    *
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0  ;simply return dest
	rts


*
* Source is within 2^14 range.  To perform the int operation,
* move it to d0.
*
src_in    equ    *
	fmove.x         ETEMP(a6),fp0   ;move in src for int
	fmove.l         #rz_mode,FPCONTROL      ;force rz for src conversion
	fmove.l         fp0,d0          ;int src to d0
	fmove.l         #0,FPSTATUS             ;clr status from above
	tst.w           ETEMP(a6)       ;check src sign
	blt.w           src_neg
*
* Source is positive.  Add the src to the dest exponent.
* The result can be denormalized, if src = 0, or overflow,
* if the result of the add sets a bit in the upper word.
*
src_pos    equ    *
	tst.w           d1              ;check for denorm
	beq.w           dst_dnrm
	add.l           d0,d1           ;add src to dest exp
	beq.b           denorm          ;if zero, result is denorm
	cmpi.l          #$7fff,d1       ;test for overflow
	bge.b           ovfl
	tst.b           L_SCR1(a6)
	beq.b           spos_pos
	or.w            #$8000,d1
spos_pos    equ    *
	move.w          d1,FPTEMP(a6)   ;result in FPTEMP
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0  ;write result to fp0
	rts
ovfl    equ    *
	tst.b           L_SCR1(a6)
	beq.b           sovl_pos
	or.w            #$8000,d1
sovl_pos    equ    *
	move.w          FPTEMP(a6),ETEMP(a6)    ;result in ETEMP
	move.l          FPTEMP_HI(a6),ETEMP_HI(a6)
	move.l          FPTEMP_LO(a6),ETEMP_LO(a6)
	bra             t_ovfl2

denorm    equ    *
	tst.b           L_SCR1(a6)
	beq.b           den_pos
	or.w            #$8000,d1
den_pos    equ    *
	tst.l           FPTEMP_HI(a6)   ;check j bit
	blt.b           nden_exit       ;if set, not denorm
	move.w          d1,ETEMP(a6)    ;input expected in ETEMP
	move.l          FPTEMP_HI(a6),ETEMP_HI(a6)
	move.l          FPTEMP_LO(a6),ETEMP_LO(a6)
	ori.l           #unfl_bit,USER_FPSTATUS(a6)     ;set unfl
	lea             ETEMP(a6),a0
	bra             t_resdnrm
nden_exit    equ    *
	move.w          d1,FPTEMP(a6)   ;result in FPTEMP
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0  ;write result to fp0
	rts

*
* Source is negative.  Add the src to the dest exponent.
* (The result exponent will be reduced).  The result can be
* denormalized.
*
src_neg    equ    *
	add.l           d0,d1           ;add src to dest
	beq.b           denorm          ;if zero, result is denorm
	blt.b           fix_dnrm        ;if negative, result is
*                                       ;needing denormalization
	tst.b           L_SCR1(a6)
	beq.b           sneg_pos
	or.w            #$8000,d1
sneg_pos    equ    *
	move.w          d1,FPTEMP(a6)   ;result in FPTEMP
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0  ;write result to fp0
	rts


*
* The result exponent is below denorm value.  Test for catastrophic
* underflow and force zero if true.  If not, try to shift the
* mantissa right until a zero exponent exists.
*
fix_dnrm    equ    *
	cmpi.w          #$ffc0,d1       ;lower bound for normalization
	blt.w           fix_unfl        ;if lower, catastrophic unfl
	move.w          d1,d0           ;use d0 for exp
	move.l          d2,-(a7)        ;free d2 for norm
	move.l          FPTEMP_HI(a6),d1
	move.l          FPTEMP_LO(a6),d2
	clr.l           L_SCR2(a6)
fix_loop    equ    *
	add.w           #1,d0           ;drive d0 to 0
	lsr.l           #1,d1           ;while shifting the
	roxr.l          #1,d2           ;mantissa to the right
	bcc.b           no_carry
	st              L_SCR2(a6)      ;use L_SCR2 to capture inex
no_carry    equ    *
	tst.w           d0              ;it is finished when
	blt.b           fix_loop        ;d0 is zero or the mantissa
	tst.b           L_SCR2(a6)
	beq.b           tst_zero
	ori.l           #unfl_inx_mask,USER_FPSTATUS(a6)
*                                       ;set unfl, aunfl, ainex
*
* Test for zero. If zero, simply use fmove to return +/- zero
* to the fpu.
*
tst_zero    equ    *
	clr.w           FPTEMP_EX(a6)
	tst.b           L_SCR1(a6)      ;test for sign
	beq.b           tst_con
	ori.w           #$8000,FPTEMP_EX(a6) ;set sign bit
tst_con    equ    *
	move.l          d1,FPTEMP_HI(a6)
	move.l          d2,FPTEMP_LO(a6)
	move.l          (a7)+,d2
	tst.l           d1
	bne.b           not_zero
	tst.l           FPTEMP_LO(a6)
	bne.b           not_zero
*
* Result is zero.  Check for rounding mode to set lsb.  If the
* mode is rp, and the zero is positive, return smallest denorm.
* If the mode is rm, and the zero is negative, return smallest
* negative denorm.
*
	btst            #5,FPCONTROL_MODE(a6) ;test if rm or rp
	beq.b           no_dir
	btst            #4,FPCONTROL_MODE(a6) ;check which one
	beq.b           zer_rm
zer_rp    equ    *
	tst.b           L_SCR1(a6)      ;check sign
	bne.b           no_dir          ;if set, neg op, no inc
	move.l          #1,FPTEMP_LO(a6) ;set lsb
	bra.b           sm_dnrm
zer_rm    equ    *
	tst.b           L_SCR1(a6)      ;check sign
	beq.b           no_dir          ;if clr, neg op, no inc
	move.l          #1,FPTEMP_LO(a6) ;set lsb
	ori.l           #neg_mask,USER_FPSTATUS(a6) ;set N
	bra.b           sm_dnrm
no_dir    equ    *
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0  ;use fmove to set cc's
	rts

*
* The rounding mode changed the zero to a smallest denorm. Call
* t_resdnrm with exceptional operand in ETEMP.
*
sm_dnrm    equ    *
	move.l          FPTEMP_EX(a6),ETEMP_EX(a6)
	move.l          FPTEMP_HI(a6),ETEMP_HI(a6)
	move.l          FPTEMP_LO(a6),ETEMP_LO(a6)
	lea             ETEMP(a6),a0
	bra             t_resdnrm

*
* Result is still denormalized.
*
not_zero    equ    *
	ori.l           #unfl_mask,USER_FPSTATUS(a6) ;set unfl
	tst.b           L_SCR1(a6)      ;check for sign
	beq.b           fix_exit
	ori.l           #neg_mask,USER_FPSTATUS(a6) ;set N
fix_exit    equ    *
	bra.b           sm_dnrm


*
* The result has underflowed to zero. Return zero and set
* unfl, aunfl, and ainex.
*
fix_unfl    equ    *
	ori.l           #unfl_inx_mask,USER_FPSTATUS(a6)
	btst            #5,FPCONTROL_MODE(a6) ;test if rm or rp
	beq.b           no_dir2
	btst            #4,FPCONTROL_MODE(a6) ;check which one
	beq.b           zer_rm2
zer_rp2    equ    *
	tst.b           L_SCR1(a6)      ;check sign
	bne.b           no_dir2         ;if set, neg op, no inc
	clr.l           FPTEMP_EX(a6)
	clr.l           FPTEMP_HI(a6)
	move.l          #1,FPTEMP_LO(a6) ;set lsb
	bra.b           sm_dnrm         ;return smallest denorm
zer_rm2    equ    *
	tst.b           L_SCR1(a6)      ;check sign
	beq.b           no_dir2         ;if clr, neg op, no inc
	move.w          #$8000,FPTEMP_EX(a6)
	clr.l           FPTEMP_HI(a6)
	move.l          #1,FPTEMP_LO(a6) ;set lsb
	ori.l           #neg_mask,USER_FPSTATUS(a6) ;set N
	bra.w           sm_dnrm         ;return smallest denorm

no_dir2    equ    *
	tst.b           L_SCR1(a6)
	bge.b           pos_zero
neg_zero    equ    *
*       fmove.s         #:80000000,fp0
	fmove.s         V80000000,fp0
	rts
pos_zero    equ    *
*       fmove.s         #:00000000,fp0
	fmove.s         V00000000,fp0
	rts

*
* The destination is a denormalized number.  It must be handled
* by first shifting the bits in the mantissa until it is normalized,
* then adding the remainder of the source to the exponent.
*
dst_dnrm    equ    *
	movem.l         d2/d3,-(a7)
	move.w          FPTEMP_EX(a6),d1
	move.l          FPTEMP_HI(a6),d2
	move.l          FPTEMP_LO(a6),d3
dst_loop    equ    *
	tst.l           d0              ;check if src is zero
	beq.b           dst_fin
	tst.l           d2              ;test for j-bit set
	blt.b           dst_norm
	subi.l          #1,d0           ;dec src
	lsl.l           #1,d3
	roxl.l          #1,d2
	bra.b           dst_loop
*
* Destination became normalized.  Simply add the remaining
* portion of the src to the exponent.
*
dst_norm    equ    *
	add.w           d0,d1           ;dst is normalized; add src
	tst.b           L_SCR1(a6)
	beq.b           dnrm_pos
	or.l            #$8000,d1
dnrm_pos    equ    *
	movem.w         d1,FPTEMP_EX(a6)
	movem.l         d2,FPTEMP_HI(a6)
	movem.l         d3,FPTEMP_LO(a6)
	fmove.l         USER_FPCONTROL(a6),FPCONTROL
	fmove.x         FPTEMP(a6),fp0
	movem.l         (a7)+,d2/d3
	rts

*
* Destination remained denormalized.  Call t_excdnrm with
* exceptional operand in ETEMP.
*
dst_fin    equ    *
	tst.b           L_SCR1(a6)      ;check for sign
	beq.b           dst_exit
	ori.l           #neg_mask,USER_FPSTATUS(a6) ;set N
	or.l            #$8000,d1
dst_exit    equ    *
	movem.w         d1,ETEMP_EX(a6)
	movem.l         d2,ETEMP_HI(a6)
	movem.l         d3,ETEMP_LO(a6)
	ori.l           #unfl_mask,USER_FPSTATUS(a6) ;set unfl
	movem.l         (a7)+,d2/d3
	lea             ETEMP(a6),a0
	bra             t_resdnrm

*
* Source is outside of 2^14 range.  Test the sign and branch
* to the appropriate exception handler.
*
src_out    equ    *
	tst.b           L_SCR1(a6)
	beq.b           scro_pos
	or.l            #$8000,d1
scro_pos    equ    *
	move.l          FPTEMP_HI(a6),ETEMP_HI(a6)
	move.l          FPTEMP_LO(a6),ETEMP_LO(a6)
	tst.w           ETEMP(a6)
	blt.b           res_neg
res_pos    equ    *
	move.w          d1,ETEMP(a6)    ;result in ETEMP
	bra             t_ovfl2
res_neg    equ    *
	move.w          d1,ETEMP(a6)    ;result in ETEMP
	lea             ETEMP(a6),a0
	bra             t_unfl
	end
@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.2
log
@*** empty log message ***
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@d30 1
a30 1
	include fpsp.h
@


1.1
log
@Initial revision
@
text
@@
