📄 util.s
字号:
//// $Id: util.S,v 1.2 1999/07/26 22:11:02 joel Exp $//// util.sa 3.7 7/29/91//// This file contains routines used by other programs.//// ovf_res: used by overflow to force the correct// result. ovf_r_k, ovf_r_x2, ovf_r_x3 are // derivatives of this routine.// get_fline: get user's opcode word// g_dfmtou: returns the destination format.// g_opcls: returns the opclass of the float instruction.// g_rndpr: returns the rounding precision. // reg_dest: write byte, word, or long data to Dn////// 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.//UTIL idnt 2,1 | Motorola 040 Floating Point Software Package |section 8#include "fpsp.defs" |xref mem_read .global g_dfmtou .global g_opcls .global g_rndpr .global get_fline .global reg_dest//// Final result table for ovf_res. Note that the negative counterparts// are unnecessary as ovf_res always returns the sign separately from// the exponent.// ;+infEXT_PINF: .long 0x7fff0000,0x00000000,0x00000000,0x00000000 // ;largest +extEXT_PLRG: .long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 // ;largest magnitude +sgl in extSGL_PLRG: .long 0x407e0000,0xffffff00,0x00000000,0x00000000 // ;largest magnitude +dbl in extDBL_PLRG: .long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 // ;largest -exttblovfl: .long EXT_RN .long EXT_RZ .long EXT_RM .long EXT_RP .long SGL_RN .long SGL_RZ .long SGL_RM .long SGL_RP .long DBL_RN .long DBL_RZ .long DBL_RM .long DBL_RP .long error .long error .long error .long error//// ovf_r_k --- overflow result calculation//// This entry point is used by kernel_ex. //// This forces the destination precision to be extended//// Input: operand in ETEMP// Output: a result is in ETEMP (internal extended format)// .global ovf_r_kovf_r_k: lea ETEMP(%a6),%a0 //a0 points to source operand bclrb #sign_bit,ETEMP_EX(%a6) sne ETEMP_SGN(%a6) //convert to internal IEEE format//// ovf_r_x2 --- overflow result calculation//// This entry point used by x_ovfl. (opclass 0 and 2)//// Input a0 points to an operand in the internal extended format// Output a0 points to the result in the internal extended format//// This sets the round precision according to the user's FPCR unless the// instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul,// fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg.// If the instruction is fsgldiv of fsglmul, the rounding precision must be// extended. If the instruction is not fsgldiv or fsglmul but a force-// precision instruction, the rounding precision is then set to the force// precision. .global ovf_r_x2ovf_r_x2: btstb #E3,E_BYTE(%a6) //check for nu exception beql ovf_e1_exc //it is cu exceptionovf_e3_exc: movew CMDREG3B(%a6),%d0 //get the command word andiw #0x00000060,%d0 //clear all bits except 6 and 5 cmpil #0x00000040,%d0 beql ovff_sgl //force precision is single cmpil #0x00000060,%d0 beql ovff_dbl //force precision is double movew CMDREG3B(%a6),%d0 //get the command word again andil #0x7f,%d0 //clear all except operation cmpil #0x33,%d0 beql ovf_fsgl //fsglmul or fsgldiv cmpil #0x30,%d0 beql ovf_fsgl bra ovf_fpcr //instruction is none of the above// ;use FPCRovf_e1_exc: movew CMDREG1B(%a6),%d0 //get command word andil #0x00000044,%d0 //clear all bits except 6 and 2 cmpil #0x00000040,%d0 beql ovff_sgl //the instruction is force single cmpil #0x00000044,%d0 beql ovff_dbl //the instruction is force double movew CMDREG1B(%a6),%d0 //again get the command word andil #0x0000007f,%d0 //clear all except the op code cmpil #0x00000027,%d0 beql ovf_fsgl //fsglmul cmpil #0x00000024,%d0 beql ovf_fsgl //fsgldiv bra ovf_fpcr //none of the above, use FPCR// //// Inst is either fsgldiv or fsglmul. Force extended precision.//ovf_fsgl: clrl %d0 bra ovf_resovff_sgl: movel #0x00000001,%d0 //set single bra ovf_resovff_dbl: movel #0x00000002,%d0 //set double bra ovf_res//// The precision is in the fpcr.//ovf_fpcr: bfextu FPCR_MODE(%a6){#0:#2},%d0 //set round precision bra ovf_res ////// ovf_r_x3 --- overflow result calculation//// This entry point used by x_ovfl. (opclass 3 only)//// Input a0 points to an operand in the internal extended format// Output a0 points to the result in the internal extended format//// This sets the round precision according to the destination size.// .global ovf_r_x3ovf_r_x3: bsr g_dfmtou //get dest fmt in d0{1:0}// ;for fmovout, the destination format// ;is the rounding precision//// ovf_res --- overflow result calculation//// Input:// a0 points to operand in internal extended format// Output:// a0 points to result in internal extended format// .global ovf_resovf_res: lsll #2,%d0 //move round precision to d0{3:2} bfextu FPCR_MODE(%a6){#2:#2},%d1 //set round mode orl %d1,%d0 //index is fmt:mode in d0{3:0} leal tblovfl,%a1 //load a1 with table address movel %a1@(%d0:l:4),%a1 //use d0 as index to the table jmp (%a1) //go to the correct routine////case DEST_FMT = EXT//EXT_RN: leal EXT_PINF,%a1 //answer is +/- infinity bsetb #inf_bit,FPSR_CC(%a6) bra set_sign //now go set the sign EXT_RZ: leal EXT_PLRG,%a1 //answer is +/- large number bra set_sign //now go set the signEXT_RM: tstb LOCAL_SGN(%a0) //if negative overflow beqs e_rm_pose_rm_neg: leal EXT_PINF,%a1 //answer is negative infinity orl #neginf_mask,USER_FPSR(%a6) bra end_ovfre_rm_pos: leal EXT_PLRG,%a1 //answer is large positive number bra end_ovfrEXT_RP: tstb LOCAL_SGN(%a0) //if negative overflow beqs e_rp_pose_rp_neg: leal EXT_PLRG,%a1 //answer is large negative number bsetb #neg_bit,FPSR_CC(%a6) bra end_ovfre_rp_pos: leal EXT_PINF,%a1 //answer is positive infinity bsetb #inf_bit,FPSR_CC(%a6) bra end_ovfr////case DEST_FMT = DBL//DBL_RN: leal EXT_PINF,%a1 //answer is +/- infinity bsetb #inf_bit,FPSR_CC(%a6) bra set_signDBL_RZ: leal DBL_PLRG,%a1 //answer is +/- large number bra set_sign //now go set the signDBL_RM: tstb LOCAL_SGN(%a0) //if negative overflow beqs d_rm_posd_rm_neg: leal EXT_PINF,%a1 //answer is negative infinity orl #neginf_mask,USER_FPSR(%a6) bra end_ovfr //inf is same for all precisions (ext,dbl,sgl)d_rm_pos: leal DBL_PLRG,%a1 //answer is large positive number bra end_ovfrDBL_RP: tstb LOCAL_SGN(%a0) //if negative overflow beqs d_rp_posd_rp_neg: leal DBL_PLRG,%a1 //answer is large negative number bsetb #neg_bit,FPSR_CC(%a6) bra end_ovfrd_rp_pos: leal EXT_PINF,%a1 //answer is positive infinity bsetb #inf_bit,FPSR_CC(%a6) bra end_ovfr////case DEST_FMT = SGL//SGL_RN: leal EXT_PINF,%a1 //answer is +/- infinity bsetb #inf_bit,FPSR_CC(%a6) bras set_signSGL_RZ: leal SGL_PLRG,%a1 //answer is +/- large number bras set_signSGL_RM: tstb LOCAL_SGN(%a0) //if negative overflow beqs s_rm_poss_rm_neg: leal EXT_PINF,%a1 //answer is negative infinity orl #neginf_mask,USER_FPSR(%a6) bras end_ovfrs_rm_pos: leal SGL_PLRG,%a1 //answer is large positive number bras end_ovfrSGL_RP: tstb LOCAL_SGN(%a0) //if negative overflow beqs s_rp_poss_rp_neg: leal SGL_PLRG,%a1 //answer is large negative number bsetb #neg_bit,FPSR_CC(%a6) bras end_ovfrs_rp_pos: leal EXT_PINF,%a1 //answer is positive infinity bsetb #inf_bit,FPSR_CC(%a6) bras end_ovfrset_sign: tstb LOCAL_SGN(%a0) //if negative overflow beqs end_ovfrneg_sign: bsetb #neg_bit,FPSR_CC(%a6)end_ovfr: movew LOCAL_EX(%a1),LOCAL_EX(%a0) //do not overwrite sign movel LOCAL_HI(%a1),LOCAL_HI(%a0) movel LOCAL_LO(%a1),LOCAL_LO(%a0) rts//// ERROR//error: rts//// get_fline --- get f-line opcode of interrupted instruction//// Returns opcode in the low word of d0.//get_fline: movel USER_FPIAR(%a6),%a0 //opcode address movel #0,-(%a7) //reserve a word on the stack leal 2(%a7),%a1 //point to low word of temporary movel #2,%d0 //count bsrl mem_read movel (%a7)+,%d0 rts//// g_rndpr --- put rounding precision in d0{1:0}// // valid return codes are:// 00 - extended // 01 - single// 10 - double//// begin// get rounding precision (cmdreg3b{6:5})// begin// case opclass = 011 (move out)// get destination format - this is the also the rounding precision//// case opclass = 0x0// if E3// *case RndPr(from cmdreg3b{6:5} = 11 then RND_PREC = DBL// *case RndPr(from cmdreg3b{6:5} = 10 then RND_PREC = SGL// case RndPr(from cmdreg3b{6:5} = 00 | 01// use precision from FPCR{7:6}// case 00 then RND_PREC = EXT// case 01 then RND_PREC = SGL// case 10 then RND_PREC = DBL// else E1// use precision in FPCR{7:6}// case 00 then RND_PREC = EXT// case 01 then RND_PREC = SGL// case 10 then RND_PREC = DBL// end//g_rndpr: bsr g_opcls //get opclass in d0{2:0} cmpw #0x0003,%d0 //check for opclass 011 bnes op_0x0//// For move out instructions (opclass 011) the destination format// is the same as the rounding precision. Pass results from g_dfmtou.// bsr g_dfmtou rtsop_0x0: btstb #E3,E_BYTE(%a6) beql unf_e1_exc //branch to e1 underflowunf_e3_exc: movel CMDREG3B(%a6),%d0 //rounding precision in d0{10:9} bfextu %d0{#9:#2},%d0 //move the rounding prec bits to d0{1:0} cmpil #0x2,%d0 beql unff_sgl //force precision is single cmpil #0x3,%d0 //force precision is double beql unff_dbl movew CMDREG3B(%a6),%d0 //get the command word again andil #0x7f,%d0 //clear all except operation cmpil #0x33,%d0 beql unf_fsgl //fsglmul or fsgldiv cmpil #0x30,%d0 beql unf_fsgl //fsgldiv or fsglmul bra unf_fpcrunf_e1_exc: movel CMDREG1B(%a6),%d0 //get 32 bits off the stack, 1st 16 bits// ;are the command word
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -