123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*---------------------------------------------------------------------------+
- | reg_norm.S |
- | |
- | Copyright (C) 1992,1993,1994,1995,1997 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@suburbia.net |
- | |
- | Normalize the value in a FPU_REG. |
- | |
- | Call from C as: |
- | int FPU_normalize(FPU_REG *n) |
- | |
- | int FPU_normalize_nuo(FPU_REG *n) |
- | |
- | Return value is the tag of the answer, or-ed with FPU_Exception if |
- | one was raised, or -1 on internal error. |
- | |
- +---------------------------------------------------------------------------*/
- #include "fpu_emu.h"
- .text
- ENTRY(FPU_normalize)
- pushl %ebp
- movl %esp,%ebp
- pushl %ebx
- movl PARAM1,%ebx
- movl SIGH(%ebx),%edx
- movl SIGL(%ebx),%eax
- orl %edx,%edx /* ms bits */
- js L_done /* Already normalized */
- jnz L_shift_1 /* Shift left 1 - 31 bits */
- orl %eax,%eax
- jz L_zero /* The contents are zero */
- movl %eax,%edx
- xorl %eax,%eax
- subw $32,EXP(%ebx) /* This can cause an underflow */
- /* We need to shift left by 1 - 31 bits */
- L_shift_1:
- bsrl %edx,%ecx /* get the required shift in %ecx */
- subl $31,%ecx
- negl %ecx
- shld %cl,%eax,%edx
- shl %cl,%eax
- subw %cx,EXP(%ebx) /* This can cause an underflow */
- movl %edx,SIGH(%ebx)
- movl %eax,SIGL(%ebx)
- L_done:
- cmpw EXP_OVER,EXP(%ebx)
- jge L_overflow
- cmpw EXP_UNDER,EXP(%ebx)
- jle L_underflow
- L_exit_valid:
- movl TAG_Valid,%eax
- /* Convert the exponent to 80x87 form. */
- addw EXTENDED_Ebias,EXP(%ebx)
- andw $0x7fff,EXP(%ebx)
- L_exit:
- popl %ebx
- leave
- ret
- L_zero:
- movw $0,EXP(%ebx)
- movl TAG_Zero,%eax
- jmp L_exit
- L_underflow:
- /* Convert the exponent to 80x87 form. */
- addw EXTENDED_Ebias,EXP(%ebx)
- push %ebx
- call arith_underflow
- pop %ebx
- jmp L_exit
- L_overflow:
- /* Convert the exponent to 80x87 form. */
- addw EXTENDED_Ebias,EXP(%ebx)
- push %ebx
- call arith_overflow
- pop %ebx
- jmp L_exit
- /* Normalise without reporting underflow or overflow */
- ENTRY(FPU_normalize_nuo)
- pushl %ebp
- movl %esp,%ebp
- pushl %ebx
- movl PARAM1,%ebx
- movl SIGH(%ebx),%edx
- movl SIGL(%ebx),%eax
- orl %edx,%edx /* ms bits */
- js L_exit_nuo_valid /* Already normalized */
- jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */
- orl %eax,%eax
- jz L_exit_nuo_zero /* The contents are zero */
- movl %eax,%edx
- xorl %eax,%eax
- subw $32,EXP(%ebx) /* This can cause an underflow */
- /* We need to shift left by 1 - 31 bits */
- L_nuo_shift_1:
- bsrl %edx,%ecx /* get the required shift in %ecx */
- subl $31,%ecx
- negl %ecx
- shld %cl,%eax,%edx
- shl %cl,%eax
- subw %cx,EXP(%ebx) /* This can cause an underflow */
- movl %edx,SIGH(%ebx)
- movl %eax,SIGL(%ebx)
- L_exit_nuo_valid:
- movl TAG_Valid,%eax
- popl %ebx
- leave
- ret
- L_exit_nuo_zero:
- movl TAG_Zero,%eax
- movw EXP_UNDER,EXP(%ebx)
- popl %ebx
- leave
- ret
|