summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-04-16 17:33:04 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-04-16 17:33:04 +0000
commitf9b93da8b47ff7ea4d6573b75b6077f6efb8dbc6 (patch)
tree46e2747b2b8f04d36d530daad59481f4f79e3c00 /c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s
parentAdded --disable-tcpip option. (diff)
downloadrtems-f9b93da8b47ff7ea4d6573b75b6077f6efb8dbc6.tar.bz2
Added the MC68040 Floating Point Support Package. This was ported
to RTEMS by Eric Norum. It is freely distributable and was acquired from the Motorola WWW site. More info is in the FPSP README.
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s')
-rw-r--r--c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s162
1 files changed, 162 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s b/c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s
new file mode 100644
index 0000000000..cf45b2ec4d
--- /dev/null
+++ b/c/src/lib/libcpu/m68k/m68040/fpsp/smovecr.s
@@ -0,0 +1,162 @@
+//
+// smovecr.sa 3.1 12/10/90
+//
+// The entry point sMOVECR returns the constant at the
+// offset given in the instruction field.
+//
+// Input: An offset in the instruction word.
+//
+// Output: The constant rounded to the user's rounding
+// mode unchecked for overflow.
+//
+// Modified: fp0.
+//
+//
+// 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.
+
+//SMOVECR idnt 2,1 | Motorola 040 Floating Point Software Package
+
+ |section 8
+
+ .include "fpsp.defs"
+
+ |xref nrm_set
+ |xref round
+ |xref PIRN
+ |xref PIRZRM
+ |xref PIRP
+ |xref SMALRN
+ |xref SMALRZRM
+ |xref SMALRP
+ |xref BIGRN
+ |xref BIGRZRM
+ |xref BIGRP
+
+FZERO: .long 00000000
+//
+// FMOVECR
+//
+ .global smovcr
+smovcr:
+ bfextu CMDREG1B(%a6){#9:#7},%d0 //get offset
+ bfextu USER_FPCR(%a6){#26:#2},%d1 //get rmode
+//
+// check range of offset
+//
+ tstb %d0 //if zero, offset is to pi
+ beqs PI_TBL //it is pi
+ cmpib #0x0a,%d0 //check range $01 - $0a
+ bles Z_VAL //if in this range, return zero
+ cmpib #0x0e,%d0 //check range $0b - $0e
+ bles SM_TBL //valid constants in this range
+ cmpib #0x2f,%d0 //check range $10 - $2f
+ bles Z_VAL //if in this range, return zero
+ cmpib #0x3f,%d0 //check range $30 - $3f
+ ble BG_TBL //valid constants in this range
+Z_VAL:
+ fmoves FZERO,%fp0
+ rts
+PI_TBL:
+ tstb %d1 //offset is zero, check for rmode
+ beqs PI_RN //if zero, rn mode
+ cmpib #0x3,%d1 //check for rp
+ beqs PI_RP //if 3, rp mode
+PI_RZRM:
+ leal PIRZRM,%a0 //rmode is rz or rm, load PIRZRM in a0
+ bra set_finx
+PI_RN:
+ leal PIRN,%a0 //rmode is rn, load PIRN in a0
+ bra set_finx
+PI_RP:
+ leal PIRP,%a0 //rmode is rp, load PIRP in a0
+ bra set_finx
+SM_TBL:
+ subil #0xb,%d0 //make offset in 0 - 4 range
+ tstb %d1 //check for rmode
+ beqs SM_RN //if zero, rn mode
+ cmpib #0x3,%d1 //check for rp
+ beqs SM_RP //if 3, rp mode
+SM_RZRM:
+ leal SMALRZRM,%a0 //rmode is rz or rm, load SMRZRM in a0
+ cmpib #0x2,%d0 //check if result is inex
+ ble set_finx //if 0 - 2, it is inexact
+ bra no_finx //if 3, it is exact
+SM_RN:
+ leal SMALRN,%a0 //rmode is rn, load SMRN in a0
+ cmpib #0x2,%d0 //check if result is inex
+ ble set_finx //if 0 - 2, it is inexact
+ bra no_finx //if 3, it is exact
+SM_RP:
+ leal SMALRP,%a0 //rmode is rp, load SMRP in a0
+ cmpib #0x2,%d0 //check if result is inex
+ ble set_finx //if 0 - 2, it is inexact
+ bra no_finx //if 3, it is exact
+BG_TBL:
+ subil #0x30,%d0 //make offset in 0 - f range
+ tstb %d1 //check for rmode
+ beqs BG_RN //if zero, rn mode
+ cmpib #0x3,%d1 //check for rp
+ beqs BG_RP //if 3, rp mode
+BG_RZRM:
+ leal BIGRZRM,%a0 //rmode is rz or rm, load BGRZRM in a0
+ cmpib #0x1,%d0 //check if result is inex
+ ble set_finx //if 0 - 1, it is inexact
+ cmpib #0x7,%d0 //second check
+ ble no_finx //if 0 - 7, it is exact
+ bra set_finx //if 8 - f, it is inexact
+BG_RN:
+ leal BIGRN,%a0 //rmode is rn, load BGRN in a0
+ cmpib #0x1,%d0 //check if result is inex
+ ble set_finx //if 0 - 1, it is inexact
+ cmpib #0x7,%d0 //second check
+ ble no_finx //if 0 - 7, it is exact
+ bra set_finx //if 8 - f, it is inexact
+BG_RP:
+ leal BIGRP,%a0 //rmode is rp, load SMRP in a0
+ cmpib #0x1,%d0 //check if result is inex
+ ble set_finx //if 0 - 1, it is inexact
+ cmpib #0x7,%d0 //second check
+ ble no_finx //if 0 - 7, it is exact
+// bra set_finx ;if 8 - f, it is inexact
+set_finx:
+ orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainex
+no_finx:
+ mulul #12,%d0 //use offset to point into tables
+ movel %d1,L_SCR1(%a6) //load mode for round call
+ bfextu USER_FPCR(%a6){#24:#2},%d1 //get precision
+ tstl %d1 //check if extended precision
+//
+// Precision is extended
+//
+ bnes not_ext //if extended, do not call round
+ fmovemx (%a0,%d0),%fp0-%fp0 //return result in fp0
+ rts
+//
+// Precision is single or double
+//
+not_ext:
+ swap %d1 //rnd prec in upper word of d1
+ addl L_SCR1(%a6),%d1 //merge rmode in low word of d1
+ movel (%a0,%d0),FP_SCR1(%a6) //load first word to temp storage
+ movel 4(%a0,%d0),FP_SCR1+4(%a6) //load second word
+ movel 8(%a0,%d0),FP_SCR1+8(%a6) //load third word
+ clrl %d0 //clear g,r,s
+ lea FP_SCR1(%a6),%a0
+ btstb #sign_bit,LOCAL_EX(%a0)
+ sne LOCAL_SGN(%a0) //convert to internal ext. format
+
+ bsr round //go round the mantissa
+
+ bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format
+ beqs fin_fcr
+ bsetb #sign_bit,LOCAL_EX(%a0)
+fin_fcr:
+ fmovemx (%a0),%fp0-%fp0
+ rts
+
+ |end