/*---------------------------------------------------------------------------+1| reg_norm.S |2| |3| Copyright (C) 1992,1993,1994,1995,1997 |4| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |5| Australia. E-mail [email protected] |6| |7| Normalize the value in a FPU_REG. |8| |9| Call from C as: |10| int FPU_normalize(FPU_REG *n) |11| |12| int FPU_normalize_nuo(FPU_REG *n) |13| |14| Return value is the tag of the answer, or-ed with FPU_Exception if |15| one was raised, or -1 on internal error. |16| |17+---------------------------------------------------------------------------*/1819#include "fpu_emu.h"202122.text23ENTRY(FPU_normalize)24pushl %ebp25movl %esp,%ebp26pushl %ebx2728movl PARAM1,%ebx2930movl SIGH(%ebx),%edx31movl SIGL(%ebx),%eax3233orl %edx,%edx /* ms bits */34js L_done /* Already normalized */35jnz L_shift_1 /* Shift left 1 - 31 bits */3637orl %eax,%eax38jz L_zero /* The contents are zero */3940movl %eax,%edx41xorl %eax,%eax42subw $32,EXP(%ebx) /* This can cause an underflow */4344/* We need to shift left by 1 - 31 bits */45L_shift_1:46bsrl %edx,%ecx /* get the required shift in %ecx */47subl $31,%ecx48negl %ecx49shld %cl,%eax,%edx50shl %cl,%eax51subw %cx,EXP(%ebx) /* This can cause an underflow */5253movl %edx,SIGH(%ebx)54movl %eax,SIGL(%ebx)5556L_done:57cmpw EXP_OVER,EXP(%ebx)58jge L_overflow5960cmpw EXP_UNDER,EXP(%ebx)61jle L_underflow6263L_exit_valid:64movl TAG_Valid,%eax6566/* Convert the exponent to 80x87 form. */67addw EXTENDED_Ebias,EXP(%ebx)68andw $0x7fff,EXP(%ebx)6970L_exit:71popl %ebx72leave73ret747576L_zero:77movw $0,EXP(%ebx)78movl TAG_Zero,%eax79jmp L_exit8081L_underflow:82/* Convert the exponent to 80x87 form. */83addw EXTENDED_Ebias,EXP(%ebx)84push %ebx85call arith_underflow86pop %ebx87jmp L_exit8889L_overflow:90/* Convert the exponent to 80x87 form. */91addw EXTENDED_Ebias,EXP(%ebx)92push %ebx93call arith_overflow94pop %ebx95jmp L_exit96979899/* Normalise without reporting underflow or overflow */100ENTRY(FPU_normalize_nuo)101pushl %ebp102movl %esp,%ebp103pushl %ebx104105movl PARAM1,%ebx106107movl SIGH(%ebx),%edx108movl SIGL(%ebx),%eax109110orl %edx,%edx /* ms bits */111js L_exit_nuo_valid /* Already normalized */112jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */113114orl %eax,%eax115jz L_exit_nuo_zero /* The contents are zero */116117movl %eax,%edx118xorl %eax,%eax119subw $32,EXP(%ebx) /* This can cause an underflow */120121/* We need to shift left by 1 - 31 bits */122L_nuo_shift_1:123bsrl %edx,%ecx /* get the required shift in %ecx */124subl $31,%ecx125negl %ecx126shld %cl,%eax,%edx127shl %cl,%eax128subw %cx,EXP(%ebx) /* This can cause an underflow */129130movl %edx,SIGH(%ebx)131movl %eax,SIGL(%ebx)132133L_exit_nuo_valid:134movl TAG_Valid,%eax135136popl %ebx137leave138ret139140L_exit_nuo_zero:141movl TAG_Zero,%eax142movw EXP_UNDER,EXP(%ebx)143144popl %ebx145leave146ret147148149