supermario/base/SuperMarioProj.1994-02-09/OS/FPUEmulation/MoveCR.a
2019-06-29 23:17:50 +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