diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-03-26 12:17:06 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-03-26 15:12:49 +0200 |
commit | 3cf2bf633fe443460563cd00c6489d16c1073fee (patch) | |
tree | 596d1ffb8e954b78662df86a709ee2311689ef26 /c/src/lib/libcpu/m68k/m68040/fpsp/scale.S | |
parent | bsps/m68k: Move libcpu content to bsps (diff) | |
download | rtems-3cf2bf633fe443460563cd00c6489d16c1073fee.tar.bz2 |
bsps/m68k: Move fpsp support to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/scale.S')
-rw-r--r-- | c/src/lib/libcpu/m68k/m68040/fpsp/scale.S | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/scale.S b/c/src/lib/libcpu/m68k/m68040/fpsp/scale.S deleted file mode 100644 index 2846c4e157..0000000000 --- a/c/src/lib/libcpu/m68k/m68040/fpsp/scale.S +++ /dev/null @@ -1,373 +0,0 @@ -#include "fpsp-namespace.h" -// -// -// scale.sa 3.3 7/30/91 -// -// The entry point sSCALE computes the destination operand -// scaled by the source operand. If the absolute 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. - -//SCALE idnt 2,1 | Motorola 040 Floating Point Software Package - - |section 8 - -#include "fpsp.defs" - - |xref t_ovfl2 - |xref t_unfl - |xref round - |xref t_resdnrm - -SRC_BNDS: .short 0x3fff,0x400c - -// -// This entry point is used by the unimplemented instruction exception -// handler. -// -// -// -// FSCALE -// - .global sscale -sscale: - fmovel #0,%fpcr //clr user enabled exc - clrl %d1 - movew FPTEMP(%a6),%d1 //get dest exponent - smi L_SCR1(%a6) //use L_SCR1 to hold sign - andil #0x7fff,%d1 //strip sign - movew ETEMP(%a6),%d0 //check src bounds - andiw #0x7fff,%d0 //clr sign bit - cmp2w SRC_BNDS,%d0 - bccs src_in - cmpiw #0x400c,%d0 //test for too large - bge src_out -// -// The source input is below 1, so we check for denormalized numbers -// and set unfl. -// -src_small: - moveb DTAG(%a6),%d0 - andib #0xe0,%d0 - tstb %d0 - beqs no_denorm - st STORE_FLG(%a6) //dest already contains result - orl #unfl_mask,USER_FPSR(%a6) //set UNFL -den_done: - leal FPTEMP(%a6),%a0 - bra t_resdnrm -no_denorm: - fmovel USER_FPCR(%a6),%FPCR - fmovex FPTEMP(%a6),%fp0 //simply return dest - rts - - -// -// Source is within 2^14 range. To perform the int operation, -// move it to d0. -// -src_in: - fmovex ETEMP(%a6),%fp0 //move in src for int - fmovel #rz_mode,%fpcr //force rz for src conversion - fmovel %fp0,%d0 //int src to d0 - fmovel #0,%FPSR //clr status from above - tstw ETEMP(%a6) //check src sign - blt 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: - tstw %d1 //check for denorm - beq dst_dnrm - addl %d0,%d1 //add src to dest exp - beqs denorm //if zero, result is denorm - cmpil #0x7fff,%d1 //test for overflow - bges ovfl - tstb L_SCR1(%a6) - beqs spos_pos - orw #0x8000,%d1 -spos_pos: - movew %d1,FPTEMP(%a6) //result in FPTEMP - fmovel USER_FPCR(%a6),%FPCR - fmovex FPTEMP(%a6),%fp0 //write result to fp0 - rts -ovfl: - tstb L_SCR1(%a6) - beqs sovl_pos - orw #0x8000,%d1 -sovl_pos: - movew FPTEMP(%a6),ETEMP(%a6) //result in ETEMP - movel FPTEMP_HI(%a6),ETEMP_HI(%a6) - movel FPTEMP_LO(%a6),ETEMP_LO(%a6) - bra t_ovfl2 - -denorm: - tstb L_SCR1(%a6) - beqs den_pos - orw #0x8000,%d1 -den_pos: - tstl FPTEMP_HI(%a6) //check j bit - blts nden_exit //if set, not denorm - movew %d1,ETEMP(%a6) //input expected in ETEMP - movel FPTEMP_HI(%a6),ETEMP_HI(%a6) - movel FPTEMP_LO(%a6),ETEMP_LO(%a6) - orl #unfl_bit,USER_FPSR(%a6) //set unfl - leal ETEMP(%a6),%a0 - bra t_resdnrm -nden_exit: - movew %d1,FPTEMP(%a6) //result in FPTEMP - fmovel USER_FPCR(%a6),%FPCR - fmovex 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: - addl %d0,%d1 //add src to dest - beqs denorm //if zero, result is denorm - blts fix_dnrm //if negative, result is -// ;needing denormalization - tstb L_SCR1(%a6) - beqs sneg_pos - orw #0x8000,%d1 -sneg_pos: - movew %d1,FPTEMP(%a6) //result in FPTEMP - fmovel USER_FPCR(%a6),%FPCR - fmovex 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: - cmpiw #0xffc0,%d1 //lower bound for normalization - blt fix_unfl //if lower, catastrophic unfl - movew %d1,%d0 //use d0 for exp - movel %d2,-(%a7) //free d2 for norm - movel FPTEMP_HI(%a6),%d1 - movel FPTEMP_LO(%a6),%d2 - clrl L_SCR2(%a6) -fix_loop: - addw #1,%d0 //drive d0 to 0 - lsrl #1,%d1 //while shifting the - roxrl #1,%d2 //mantissa to the right - bccs no_carry - st L_SCR2(%a6) //use L_SCR2 to capture inex -no_carry: - tstw %d0 //it is finished when - blts fix_loop //d0 is zero or the mantissa - tstb L_SCR2(%a6) - beqs tst_zero - orl #unfl_inx_mask,USER_FPSR(%a6) -// ;set unfl, aunfl, ainex -// -// Test for zero. If zero, simply use fmove to return +/- zero -// to the fpu. -// -tst_zero: - clrw FPTEMP_EX(%a6) - tstb L_SCR1(%a6) //test for sign - beqs tst_con - orw #0x8000,FPTEMP_EX(%a6) //set sign bit -tst_con: - movel %d1,FPTEMP_HI(%a6) - movel %d2,FPTEMP_LO(%a6) - movel (%a7)+,%d2 - tstl %d1 - bnes not_zero - tstl FPTEMP_LO(%a6) - bnes 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. -// - btstb #5,FPCR_MODE(%a6) //test if rm or rp - beqs no_dir - btstb #4,FPCR_MODE(%a6) //check which one - beqs zer_rm -zer_rp: - tstb L_SCR1(%a6) //check sign - bnes no_dir //if set, neg op, no inc - movel #1,FPTEMP_LO(%a6) //set lsb - bras sm_dnrm -zer_rm: - tstb L_SCR1(%a6) //check sign - beqs no_dir //if clr, neg op, no inc - movel #1,FPTEMP_LO(%a6) //set lsb - orl #neg_mask,USER_FPSR(%a6) //set N - bras sm_dnrm -no_dir: - fmovel USER_FPCR(%a6),%FPCR - fmovex 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: - movel FPTEMP_EX(%a6),ETEMP_EX(%a6) - movel FPTEMP_HI(%a6),ETEMP_HI(%a6) - movel FPTEMP_LO(%a6),ETEMP_LO(%a6) - leal ETEMP(%a6),%a0 - bra t_resdnrm - -// -// Result is still denormalized. -// -not_zero: - orl #unfl_mask,USER_FPSR(%a6) //set unfl - tstb L_SCR1(%a6) //check for sign - beqs fix_exit - orl #neg_mask,USER_FPSR(%a6) //set N -fix_exit: - bras sm_dnrm - - -// -// The result has underflowed to zero. Return zero and set -// unfl, aunfl, and ainex. -// -fix_unfl: - orl #unfl_inx_mask,USER_FPSR(%a6) - btstb #5,FPCR_MODE(%a6) //test if rm or rp - beqs no_dir2 - btstb #4,FPCR_MODE(%a6) //check which one - beqs zer_rm2 -zer_rp2: - tstb L_SCR1(%a6) //check sign - bnes no_dir2 //if set, neg op, no inc - clrl FPTEMP_EX(%a6) - clrl FPTEMP_HI(%a6) - movel #1,FPTEMP_LO(%a6) //set lsb - bras sm_dnrm //return smallest denorm -zer_rm2: - tstb L_SCR1(%a6) //check sign - beqs no_dir2 //if clr, neg op, no inc - movew #0x8000,FPTEMP_EX(%a6) - clrl FPTEMP_HI(%a6) - movel #1,FPTEMP_LO(%a6) //set lsb - orl #neg_mask,USER_FPSR(%a6) //set N - bra sm_dnrm //return smallest denorm - -no_dir2: - tstb L_SCR1(%a6) - bges pos_zero -neg_zero: - clrl FP_SCR1(%a6) //clear the exceptional operand - clrl FP_SCR1+4(%a6) //for gen_except. - clrl FP_SCR1+8(%a6) - fmoves #0x80000000,%fp0 - rts -pos_zero: - clrl FP_SCR1(%a6) //clear the exceptional operand - clrl FP_SCR1+4(%a6) //for gen_except. - clrl FP_SCR1+8(%a6) - fmoves #0x00000000,%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: - moveml %d2/%d3,-(%a7) - movew FPTEMP_EX(%a6),%d1 - movel FPTEMP_HI(%a6),%d2 - movel FPTEMP_LO(%a6),%d3 -dst_loop: - tstl %d2 //test for normalized result - blts dst_norm //exit loop if so - tstl %d0 //otherwise, test shift count - beqs dst_fin //if zero, shifting is done - subil #1,%d0 //dec src - lsll #1,%d3 - roxll #1,%d2 - bras dst_loop -// -// Destination became normalized. Simply add the remaining -// portion of the src to the exponent. -// -dst_norm: - addw %d0,%d1 //dst is normalized; add src - tstb L_SCR1(%a6) - beqs dnrm_pos - orl #0x8000,%d1 -dnrm_pos: - movemw %d1,FPTEMP_EX(%a6) - moveml %d2,FPTEMP_HI(%a6) - moveml %d3,FPTEMP_LO(%a6) - fmovel USER_FPCR(%a6),%FPCR - fmovex FPTEMP(%a6),%fp0 - moveml (%a7)+,%d2/%d3 - rts - -// -// Destination remained denormalized. Call t_excdnrm with -// exceptional operand in ETEMP. -// -dst_fin: - tstb L_SCR1(%a6) //check for sign - beqs dst_exit - orl #neg_mask,USER_FPSR(%a6) //set N - orl #0x8000,%d1 -dst_exit: - movemw %d1,ETEMP_EX(%a6) - moveml %d2,ETEMP_HI(%a6) - moveml %d3,ETEMP_LO(%a6) - orl #unfl_mask,USER_FPSR(%a6) //set unfl - moveml (%a7)+,%d2/%d3 - leal 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: - tstb L_SCR1(%a6) - beqs scro_pos - orl #0x8000,%d1 -scro_pos: - movel FPTEMP_HI(%a6),ETEMP_HI(%a6) - movel FPTEMP_LO(%a6),ETEMP_LO(%a6) - tstw ETEMP(%a6) - blts res_neg -res_pos: - movew %d1,ETEMP(%a6) //result in ETEMP - bra t_ovfl2 -res_neg: - movew %d1,ETEMP(%a6) //result in ETEMP - leal ETEMP(%a6),%a0 - bra t_unfl - |end |