1*4882a593Smuzhiyun| 2*4882a593Smuzhiyun| smovecr.sa 3.1 12/10/90 3*4882a593Smuzhiyun| 4*4882a593Smuzhiyun| The entry point sMOVECR returns the constant at the 5*4882a593Smuzhiyun| offset given in the instruction field. 6*4882a593Smuzhiyun| 7*4882a593Smuzhiyun| Input: An offset in the instruction word. 8*4882a593Smuzhiyun| 9*4882a593Smuzhiyun| Output: The constant rounded to the user's rounding 10*4882a593Smuzhiyun| mode unchecked for overflow. 11*4882a593Smuzhiyun| 12*4882a593Smuzhiyun| Modified: fp0. 13*4882a593Smuzhiyun| 14*4882a593Smuzhiyun| 15*4882a593Smuzhiyun| Copyright (C) Motorola, Inc. 1990 16*4882a593Smuzhiyun| All Rights Reserved 17*4882a593Smuzhiyun| 18*4882a593Smuzhiyun| For details on the license for this file, please see the 19*4882a593Smuzhiyun| file, README, in this same directory. 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun|SMOVECR idnt 2,1 | Motorola 040 Floating Point Software Package 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun |section 8 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun#include "fpsp.h" 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun |xref nrm_set 28*4882a593Smuzhiyun |xref round 29*4882a593Smuzhiyun |xref PIRN 30*4882a593Smuzhiyun |xref PIRZRM 31*4882a593Smuzhiyun |xref PIRP 32*4882a593Smuzhiyun |xref SMALRN 33*4882a593Smuzhiyun |xref SMALRZRM 34*4882a593Smuzhiyun |xref SMALRP 35*4882a593Smuzhiyun |xref BIGRN 36*4882a593Smuzhiyun |xref BIGRZRM 37*4882a593Smuzhiyun |xref BIGRP 38*4882a593Smuzhiyun 39*4882a593SmuzhiyunFZERO: .long 00000000 40*4882a593Smuzhiyun| 41*4882a593Smuzhiyun| FMOVECR 42*4882a593Smuzhiyun| 43*4882a593Smuzhiyun .global smovcr 44*4882a593Smuzhiyunsmovcr: 45*4882a593Smuzhiyun bfextu CMDREG1B(%a6){#9:#7},%d0 |get offset 46*4882a593Smuzhiyun bfextu USER_FPCR(%a6){#26:#2},%d1 |get rmode 47*4882a593Smuzhiyun| 48*4882a593Smuzhiyun| check range of offset 49*4882a593Smuzhiyun| 50*4882a593Smuzhiyun tstb %d0 |if zero, offset is to pi 51*4882a593Smuzhiyun beqs PI_TBL |it is pi 52*4882a593Smuzhiyun cmpib #0x0a,%d0 |check range $01 - $0a 53*4882a593Smuzhiyun bles Z_VAL |if in this range, return zero 54*4882a593Smuzhiyun cmpib #0x0e,%d0 |check range $0b - $0e 55*4882a593Smuzhiyun bles SM_TBL |valid constants in this range 56*4882a593Smuzhiyun cmpib #0x2f,%d0 |check range $10 - $2f 57*4882a593Smuzhiyun bles Z_VAL |if in this range, return zero 58*4882a593Smuzhiyun cmpib #0x3f,%d0 |check range $30 - $3f 59*4882a593Smuzhiyun ble BG_TBL |valid constants in this range 60*4882a593SmuzhiyunZ_VAL: 61*4882a593Smuzhiyun fmoves FZERO,%fp0 62*4882a593Smuzhiyun rts 63*4882a593SmuzhiyunPI_TBL: 64*4882a593Smuzhiyun tstb %d1 |offset is zero, check for rmode 65*4882a593Smuzhiyun beqs PI_RN |if zero, rn mode 66*4882a593Smuzhiyun cmpib #0x3,%d1 |check for rp 67*4882a593Smuzhiyun beqs PI_RP |if 3, rp mode 68*4882a593SmuzhiyunPI_RZRM: 69*4882a593Smuzhiyun leal PIRZRM,%a0 |rmode is rz or rm, load PIRZRM in a0 70*4882a593Smuzhiyun bra set_finx 71*4882a593SmuzhiyunPI_RN: 72*4882a593Smuzhiyun leal PIRN,%a0 |rmode is rn, load PIRN in a0 73*4882a593Smuzhiyun bra set_finx 74*4882a593SmuzhiyunPI_RP: 75*4882a593Smuzhiyun leal PIRP,%a0 |rmode is rp, load PIRP in a0 76*4882a593Smuzhiyun bra set_finx 77*4882a593SmuzhiyunSM_TBL: 78*4882a593Smuzhiyun subil #0xb,%d0 |make offset in 0 - 4 range 79*4882a593Smuzhiyun tstb %d1 |check for rmode 80*4882a593Smuzhiyun beqs SM_RN |if zero, rn mode 81*4882a593Smuzhiyun cmpib #0x3,%d1 |check for rp 82*4882a593Smuzhiyun beqs SM_RP |if 3, rp mode 83*4882a593SmuzhiyunSM_RZRM: 84*4882a593Smuzhiyun leal SMALRZRM,%a0 |rmode is rz or rm, load SMRZRM in a0 85*4882a593Smuzhiyun cmpib #0x2,%d0 |check if result is inex 86*4882a593Smuzhiyun ble set_finx |if 0 - 2, it is inexact 87*4882a593Smuzhiyun bra no_finx |if 3, it is exact 88*4882a593SmuzhiyunSM_RN: 89*4882a593Smuzhiyun leal SMALRN,%a0 |rmode is rn, load SMRN in a0 90*4882a593Smuzhiyun cmpib #0x2,%d0 |check if result is inex 91*4882a593Smuzhiyun ble set_finx |if 0 - 2, it is inexact 92*4882a593Smuzhiyun bra no_finx |if 3, it is exact 93*4882a593SmuzhiyunSM_RP: 94*4882a593Smuzhiyun leal SMALRP,%a0 |rmode is rp, load SMRP in a0 95*4882a593Smuzhiyun cmpib #0x2,%d0 |check if result is inex 96*4882a593Smuzhiyun ble set_finx |if 0 - 2, it is inexact 97*4882a593Smuzhiyun bra no_finx |if 3, it is exact 98*4882a593SmuzhiyunBG_TBL: 99*4882a593Smuzhiyun subil #0x30,%d0 |make offset in 0 - f range 100*4882a593Smuzhiyun tstb %d1 |check for rmode 101*4882a593Smuzhiyun beqs BG_RN |if zero, rn mode 102*4882a593Smuzhiyun cmpib #0x3,%d1 |check for rp 103*4882a593Smuzhiyun beqs BG_RP |if 3, rp mode 104*4882a593SmuzhiyunBG_RZRM: 105*4882a593Smuzhiyun leal BIGRZRM,%a0 |rmode is rz or rm, load BGRZRM in a0 106*4882a593Smuzhiyun cmpib #0x1,%d0 |check if result is inex 107*4882a593Smuzhiyun ble set_finx |if 0 - 1, it is inexact 108*4882a593Smuzhiyun cmpib #0x7,%d0 |second check 109*4882a593Smuzhiyun ble no_finx |if 0 - 7, it is exact 110*4882a593Smuzhiyun bra set_finx |if 8 - f, it is inexact 111*4882a593SmuzhiyunBG_RN: 112*4882a593Smuzhiyun leal BIGRN,%a0 |rmode is rn, load BGRN in a0 113*4882a593Smuzhiyun cmpib #0x1,%d0 |check if result is inex 114*4882a593Smuzhiyun ble set_finx |if 0 - 1, it is inexact 115*4882a593Smuzhiyun cmpib #0x7,%d0 |second check 116*4882a593Smuzhiyun ble no_finx |if 0 - 7, it is exact 117*4882a593Smuzhiyun bra set_finx |if 8 - f, it is inexact 118*4882a593SmuzhiyunBG_RP: 119*4882a593Smuzhiyun leal BIGRP,%a0 |rmode is rp, load SMRP in a0 120*4882a593Smuzhiyun cmpib #0x1,%d0 |check if result is inex 121*4882a593Smuzhiyun ble set_finx |if 0 - 1, it is inexact 122*4882a593Smuzhiyun cmpib #0x7,%d0 |second check 123*4882a593Smuzhiyun ble no_finx |if 0 - 7, it is exact 124*4882a593Smuzhiyun| bra set_finx ;if 8 - f, it is inexact 125*4882a593Smuzhiyunset_finx: 126*4882a593Smuzhiyun orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 127*4882a593Smuzhiyunno_finx: 128*4882a593Smuzhiyun mulul #12,%d0 |use offset to point into tables 129*4882a593Smuzhiyun movel %d1,L_SCR1(%a6) |load mode for round call 130*4882a593Smuzhiyun bfextu USER_FPCR(%a6){#24:#2},%d1 |get precision 131*4882a593Smuzhiyun tstl %d1 |check if extended precision 132*4882a593Smuzhiyun| 133*4882a593Smuzhiyun| Precision is extended 134*4882a593Smuzhiyun| 135*4882a593Smuzhiyun bnes not_ext |if extended, do not call round 136*4882a593Smuzhiyun fmovemx (%a0,%d0),%fp0-%fp0 |return result in fp0 137*4882a593Smuzhiyun rts 138*4882a593Smuzhiyun| 139*4882a593Smuzhiyun| Precision is single or double 140*4882a593Smuzhiyun| 141*4882a593Smuzhiyunnot_ext: 142*4882a593Smuzhiyun swap %d1 |rnd prec in upper word of d1 143*4882a593Smuzhiyun addl L_SCR1(%a6),%d1 |merge rmode in low word of d1 144*4882a593Smuzhiyun movel (%a0,%d0),FP_SCR1(%a6) |load first word to temp storage 145*4882a593Smuzhiyun movel 4(%a0,%d0),FP_SCR1+4(%a6) |load second word 146*4882a593Smuzhiyun movel 8(%a0,%d0),FP_SCR1+8(%a6) |load third word 147*4882a593Smuzhiyun clrl %d0 |clear g,r,s 148*4882a593Smuzhiyun lea FP_SCR1(%a6),%a0 149*4882a593Smuzhiyun btstb #sign_bit,LOCAL_EX(%a0) 150*4882a593Smuzhiyun sne LOCAL_SGN(%a0) |convert to internal ext. format 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun bsr round |go round the mantissa 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format 155*4882a593Smuzhiyun beqs fin_fcr 156*4882a593Smuzhiyun bsetb #sign_bit,LOCAL_EX(%a0) 157*4882a593Smuzhiyunfin_fcr: 158*4882a593Smuzhiyun fmovemx (%a0),%fp0-%fp0 159*4882a593Smuzhiyun rts 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun |end 162