mac-rom/OS/FPUEmulation/MoveCR.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

175 lines
4.8 KiB
Plaintext

;
; File: MoveCR.a
;
; Contains: Emulation of the unimplemented FMOVECR instruction
;
; Originally Written by: Motorola Inc.
; Adapted to Apple/MPW: Jon Okada
;
; Copyright: © 1990, 1991 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: Mac32
;
; Change History (most recent first):
;
; <1> 3/30/91 BG First checked into TERROR/BBS.
;
; movecr.a
; Based upon Motorola file 'smovecr.sa'.
; CHANGE LOG:
; 07 Jan 91 JPO Deleted constant FZERO and embedded its value in
; the FMOVE instruction which referenced it. Renamed
; label "not_ext" to "cr_notext" to avoid duplicate symbol.
;
*
* 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
;FZERO dc.l 00000000 ; deleted <1/7/91, JPO>
*
* FMOVECR
*
smovcr:
bfextu CMDREG1B(a6){9:7},d0 ;get offset
bfextu USER_FPCR(a6){26:2},d1 ;get rmode
*
* check range of offset
*
tst.b d0 ;if zero, offset is to pi
beq.b PI_TBL ;it is pi
cmpi.b #$0a,d0 ;check range $01 - $0a
ble.b Z_VAL ;if in this range, return zero
cmpi.b #$0e,d0 ;check range $0b - $0e
ble.b SM_TBL ;valid constants in this range
cmpi.b #$2f,d0 ;check range $10 - $2f
ble.b Z_VAL ;if in this range, return zero
cmpi.b #$3f,d0 ;check range $30 - $3f
ble.b BG_TBL ;valid constants in this range
Z_VAL:
fmove.b #0,fp0 ; return zero <1/7/91, JPO>
rts
PI_TBL:
tst.b d1 ;offset is zero, check for rmode
beq.b PI_RN ;if zero, rn mode
cmpi.b #$3,d1 ;check for rp
beq.b PI_RP ;if 3, rp mode
PI_RZRM:
lea.l PIRZRM,a0 ;rmode is rz or rm, load PIRZRM in a0
bra set_finx
PI_RN:
lea.l PIRN,a0 ;rmode is rn, load PIRN in a0
bra set_finx
PI_RP:
lea.l PIRP,a0 ;rmode is rp, load PIRP in a0
bra.b set_finx
SM_TBL:
subi.l #$b,d0 ;make offset in 0 - 4 range
tst.b d1 ;check for rmode
beq.b SM_RN ;if zero, rn mode
cmpi.b #$3,d1 ;check for rp
beq.b SM_RP ;if 3, rp mode
SM_RZRM:
lea.l SMALRZRM,a0 ;rmode is rz or rm, load SMRZRM in a0
cmpi.b #$2,d0 ;check if result is inex
ble.b set_finx ;if 0 - 2, it is inexact
bra.b no_finx ;if 3, it is exact
SM_RN:
lea.l SMALRN,a0 ;rmode is rn, load SMRN in a0
cmpi.b #$2,d0 ;check if result is inex
ble.b set_finx ;if 0 - 2, it is inexact
bra.b no_finx ;if 3, it is exact
SM_RP:
lea.l SMALRP,a0 ;rmode is rp, load SMRP in a0
cmpi.b #$2,d0 ;check if result is inex
ble.b set_finx ;if 0 - 2, it is inexact
bra.b no_finx ;if 3, it is exact
BG_TBL:
subi.l #$30,d0 ;make offset in 0 - f range
tst.b d1 ;check for rmode
beq.b BG_RN ;if zero, rn mode
cmpi.b #$3,d1 ;check for rp
beq.b BG_RP ;if 3, rp mode
BG_RZRM:
lea.l BIGRZRM,a0 ;rmode is rz or rm, load BGRZRM in a0
cmpi.b #$1,d0 ;check if result is inex
ble.b set_finx ;if 0 - 1, it is inexact
cmpi.b #$7,d0 ;second check
ble.b no_finx ;if 0 - 7, it is exact
bra.b set_finx ;if 8 - f, it is inexact
BG_RN:
lea.l BIGRN,a0 ;rmode is rn, load BGRN in a0
cmpi.b #$1,d0 ;check if result is inex
ble.b set_finx ;if 0 - 1, it is inexact
cmpi.b #$7,d0 ;second check
ble.b no_finx ;if 0 - 7, it is exact
bra.b set_finx ;if 8 - f, it is inexact
BG_RP:
lea.l BIGRP,a0 ;rmode is rp, load SMRP in a0
cmpi.b #$1,d0 ;check if result is inex
ble.b set_finx ;if 0 - 1, it is inexact
cmpi.b #$7,d0 ;second check
ble.b no_finx ;if 0 - 7, it is exact
* bra set_finx ;if 8 - f, it is inexact
set_finx:
or.l #inx2a_mask,USER_FPSR(a6) ;set inex2/ainex
no_finx:
mulu.l #12,d0 ;use offset to point into tables
move.l d1,L_SCR1(a6) ;load mode for round call
bfextu USER_FPCR(a6){24:2},d1 ;get precision
tst.l d1 ;check if extended precision
*
* Precision is extended
*
bne.b cr_notext ;if extended, do not call round - label renamed <1/7/91, JPO>
fmovem.x (a0,d0),fp0 ;return result in fp0
rts
*
* Precision is single or double
*
cr_notext: ; label renamed <1/7/91, JPO>
swap d1 ;rnd prec in upper word of d1
add.l L_SCR1(a6),d1 ;merge rmode in low word of d1
move.l (a0,d0),FP_SCR1(a6) ;load first word to temp storage
move.l 4(a0,d0),FP_SCR1+4(a6) ;load second word
move.l 8(a0,d0),FP_SCR1+8(a6) ;load third word
clr.l d0 ;clear g,r,s
lea FP_SCR1(a6),a0
btst.b #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
beq.b fin_fcr
bset.b #sign_bit,LOCAL_EX(a0)
fin_fcr:
fmovem.x (a0),fp0
rts