URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [x_unfl.S] - Rev 208
Go to most recent revision | Compare with Previous | Blame | View Log
//// $Id: x_unfl.S,v 1.2 2001-09-27 12:01:22 chris Exp $//// x_unfl.sa 3.4 7/1/91//// fpsp_unfl --- FPSP handler for underflow exception//// Trap disabled results// For 881/2 compatibility, sw must denormalize the intermediate// result, then store the result. Denormalization is accomplished// by taking the intermediate result (which is always normalized) and// shifting the mantissa right while incrementing the exponent until// it is equal to the denormalized exponent for the destination// format. After denormalization, the result is rounded to the// destination format.//// Trap enabled results// All trap disabled code applies. In addition the exceptional// operand needs to made available to the user with a bias of $6000// added to the exponent.//// 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.X_UNFL: //idnt 2,1 | Motorola 040 Floating Point Software Package|section 8#include "fpsp.defs"|xref denorm|xref round|xref store|xref g_rndpr|xref g_opcls|xref g_dfmtou|xref real_unfl|xref real_inex|xref fpsp_done|xref b1238_fix.global fpsp_unflfpsp_unfl:link %a6,#-LOCAL_SIZEfsave -(%a7)moveml %d0-%d1/%a0-%a1,USER_DA(%a6)fmovemx %fp0-%fp3,USER_FP0(%a6)fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)//bsrl unf_res //denormalize, round & store interm op//// If underflow exceptions are not enabled, check for inexact// exception//btstb #unfl_bit,FPCR_ENABLE(%a6)beqs ck_inexbtstb #E3,E_BYTE(%a6)beqs no_e3_1//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//bfextu CMDREG3B(%a6){#6:#3},%d0 //get dest reg nobclrb %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bitbsrl b1238_fix //test for bug1238 casemovel USER_FPSR(%a6),FPSR_SHADOW(%a6)orl #sx_mask,E_BYTE(%a6)no_e3_1:moveml USER_DA(%a6),%d0-%d1/%a0-%a1fmovemx USER_FP0(%a6),%fp0-%fp3fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiarfrestore (%a7)+unlk %a6bral real_unfl//// It is possible to have either inex2 or inex1 exceptions with the// unfl. If the inex enable bit is set in the FPCR, and either// inex2 or inex1 occurred, we must clean up and branch to the// real inex handler.//ck_inex:moveb FPCR_ENABLE(%a6),%d0andb FPSR_EXCEPT(%a6),%d0andib #0x3,%d0beqs unfl_done//// Inexact enabled and reported, and we must take an inexact exception//take_inex:btstb #E3,E_BYTE(%a6)beqs no_e3_2//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//bfextu CMDREG3B(%a6){#6:#3},%d0 //get dest reg nobclrb %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bitbsrl b1238_fix //test for bug1238 casemovel USER_FPSR(%a6),FPSR_SHADOW(%a6)orl #sx_mask,E_BYTE(%a6)no_e3_2:moveb #INEX_VEC,EXC_VEC+1(%a6)moveml USER_DA(%a6),%d0-%d1/%a0-%a1fmovemx USER_FP0(%a6),%fp0-%fp3fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiarfrestore (%a7)+unlk %a6bral real_inexunfl_done:bclrb #E3,E_BYTE(%a6)beqs e1_set //if set then branch//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//bfextu CMDREG3B(%a6){#6:#3},%d0 //get dest reg nobclrb %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bitbsrl b1238_fix //test for bug1238 casemovel USER_FPSR(%a6),FPSR_SHADOW(%a6)orl #sx_mask,E_BYTE(%a6)moveml USER_DA(%a6),%d0-%d1/%a0-%a1fmovemx USER_FP0(%a6),%fp0-%fp3fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiarfrestore (%a7)+unlk %a6bral fpsp_donee1_set:moveml USER_DA(%a6),%d0-%d1/%a0-%a1fmovemx USER_FP0(%a6),%fp0-%fp3fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiarunlk %a6bral fpsp_done//// unf_res --- underflow result calculation//unf_res:bsrl g_rndpr //returns RND_PREC in d0 0=ext,// ;1=sgl, 2=dbl// ;we need the RND_PREC in the// ;upper word for roundmovew #0,-(%a7)movew %d0,-(%a7) //copy RND_PREC to stack////// If the exception bit set is E3, the exceptional operand from the// fpu is in WBTEMP; else it is in FPTEMP.//btstb #E3,E_BYTE(%a6)beqs unf_E1unf_E3:lea WBTEMP(%a6),%a0 //a0 now points to operand//// Test for fsgldiv and fsglmul. If the inst was one of these, then// force the precision to extended for the denorm routine. Use// the user's precision for the round routine.//movew CMDREG3B(%a6),%d1 //check for fsgldiv or fsglmulandiw #0x7f,%d1cmpiw #0x30,%d1 //check for sgldivbeqs unf_sglcmpiw #0x33,%d1 //check for sglmulbnes unf_cont //if not, use fpcr prec in roundunf_sgl:clrl %d0movew #0x1,(%a7) //override g_rndpr precision// ;force singlebras unf_contunf_E1:lea FPTEMP(%a6),%a0 //a0 now points to operandunf_cont:bclrb #sign_bit,LOCAL_EX(%a0) //clear sign bitsne LOCAL_SGN(%a0) //store signbsrl denorm //returns denorm, a0 points to it//// WARNING:// ;d0 has guard,round sticky bit// ;make sure that it is not corrupted// ;before it reaches the round subroutine// ;also ensure that a0 isn't corrupted//// Set up d1 for round subroutine d1 contains the PREC/MODE// information respectively on upper/lower register halves.//bfextu FPCR_MODE(%a6){#2:#2},%d1 //get mode from FPCR// ;mode in lower d1addl (%a7)+,%d1 //merge PREC/MODE//// WARNING: a0 and d0 are assumed to be intact between the denorm and// round subroutines. All code between these two subroutines// must not corrupt a0 and d0.////// Perform Round// Input: a0 points to input operand// d0{31:29} has guard, round, sticky// d1{01:00} has rounding mode// d1{17:16} has rounding precision// Output: a0 points to rounded operand//bsrl round //returns rounded denorm at (a0)//// Differentiate between store to memory vs. store to register//unf_store:bsrl g_opcls //returns opclass in d0{2:0}cmpib #0x3,%d0bnes not_opc011//// At this point, a store to memory is pending//opc011:bsrl g_dfmtoutstb %d0beqs ext_opc011 //If extended, do not subtract// ;If destination format is sgl/dbl,tstb LOCAL_HI(%a0) //If rounded result is normal,don't// ;subtractbmis ext_opc011subqw #1,LOCAL_EX(%a0) //account for denorm bias vs.// ;normalized bias// ; normalized denormalized// ;single $7f $7e// ;double $3ff $3fe//ext_opc011:bsrl store //stores to memorybras unf_done //finish up//// At this point, a store to a float register is pending//not_opc011:bsrl store //stores to float register// ;a0 is not corrupted on a store to a// ;float register.//// Set the condition codes according to result//tstl LOCAL_HI(%a0) //check upper mantissabnes ck_sgntstl LOCAL_LO(%a0) //check lower mantissabnes ck_sgnbsetb #z_bit,FPSR_CC(%a6) //set condition codes if zerock_sgn:btstb #sign_bit,LOCAL_EX(%a0) //check the sign bitbeqs unf_donebsetb #neg_bit,FPSR_CC(%a6)//// Finish.//unf_done:btstb #inex2_bit,FPSR_EXCEPT(%a6)beqs no_aunflbsetb #aunfl_bit,FPSR_AEXCEPT(%a6)no_aunfl:rts|end
Go to most recent revision | Compare with Previous | Blame | View Log
