/*---------------------------------------------------------------------------+ | 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