/*---------------------------------------------------------------------------+ | reg_norm.S | | | | Copyright (C) 1992,1993,1994,1995 | | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | | Australia. E-mail billm@jacobi.maths.monash.edu.au | | | | Normalize the value in a FPU_REG. | | | | Call from C as: | | void normalize(FPU_REG *n) | | | | void normalize_nuo(FPU_REG *n) | | | +---------------------------------------------------------------------------*/ #include "fpu_emu.h" .text ENTRY(normalize) pushl %ebp movl %esp,%ebp pushl %ebx movl PARAM1,%ebx #ifdef PARANOID cmpb TW_Valid,TAG(%ebx) je L_ok pushl $0x220 call SYMBOL_NAME(FPU_exception) addl $4,%esp L_ok: #endif PARANOID 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 subl $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 subl %ecx,EXP(%ebx) /* This can cause an underflow */ movl %edx,SIGH(%ebx) movl %eax,SIGL(%ebx) L_done: cmpl EXP_OVER,EXP(%ebx) jge L_overflow cmpl EXP_UNDER,EXP(%ebx) jle L_underflow L_exit: popl %ebx leave ret L_zero: movl EXP_UNDER,EXP(%ebx) movb TW_Zero,TAG(%ebx) jmp L_exit L_underflow: push %ebx call SYMBOL_NAME(arith_underflow) pop %ebx jmp L_exit L_overflow: push %ebx call SYMBOL_NAME(arith_overflow) pop %ebx jmp L_exit /* Normalise without reporting underflow or overflow */ ENTRY(normalize_nuo) pushl %ebp movl %esp,%ebp pushl %ebx movl PARAM1,%ebx #ifdef PARANOID cmpb TW_Valid,TAG(%ebx) je L_ok_nuo pushl $0x221 call SYMBOL_NAME(FPU_exception) addl $4,%esp L_ok_nuo: #endif PARANOID movl SIGH(%ebx),%edx movl SIGL(%ebx),%eax orl %edx,%edx /* ms bits */ js L_exit /* Already normalized */ jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */ orl %eax,%eax jz L_zero /* The contents are zero */ movl %eax,%edx xorl %eax,%eax subl $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 subl %ecx,EXP(%ebx) /* This can cause an underflow */ movl %edx,SIGH(%ebx) movl %eax,SIGL(%ebx) jmp L_exit