1/*---------------------------------------------------------------------------+ 2 | reg_norm.S | 3 | | 4 | Copyright (C) 1992,1993,1994,1995,1997 | 5 | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | 6 | Australia. E-mail billm@suburbia.net | 7 | | 8 | Normalize the value in a FPU_REG. | 9 | | 10 | Call from C as: | 11 | int FPU_normalize(FPU_REG *n) | 12 | | 13 | int FPU_normalize_nuo(FPU_REG *n) | 14 | | 15 | Return value is the tag of the answer, or-ed with FPU_Exception if | 16 | one was raised, or -1 on internal error. | 17 | | 18 +---------------------------------------------------------------------------*/ 19 20#include "fpu_emu.h" 21 22 23.text 24ENTRY(FPU_normalize) 25 pushl %ebp 26 movl %esp,%ebp 27 pushl %ebx 28 29 movl PARAM1,%ebx 30 31 movl SIGH(%ebx),%edx 32 movl SIGL(%ebx),%eax 33 34 orl %edx,%edx /* ms bits */ 35 js L_done /* Already normalized */ 36 jnz L_shift_1 /* Shift left 1 - 31 bits */ 37 38 orl %eax,%eax 39 jz L_zero /* The contents are zero */ 40 41 movl %eax,%edx 42 xorl %eax,%eax 43 subw $32,EXP(%ebx) /* This can cause an underflow */ 44 45/* We need to shift left by 1 - 31 bits */ 46L_shift_1: 47 bsrl %edx,%ecx /* get the required shift in %ecx */ 48 subl $31,%ecx 49 negl %ecx 50 shld %cl,%eax,%edx 51 shl %cl,%eax 52 subw %cx,EXP(%ebx) /* This can cause an underflow */ 53 54 movl %edx,SIGH(%ebx) 55 movl %eax,SIGL(%ebx) 56 57L_done: 58 cmpw EXP_OVER,EXP(%ebx) 59 jge L_overflow 60 61 cmpw EXP_UNDER,EXP(%ebx) 62 jle L_underflow 63 64L_exit_valid: 65 movl TAG_Valid,%eax 66 67 /* Convert the exponent to 80x87 form. */ 68 addw EXTENDED_Ebias,EXP(%ebx) 69 andw $0x7fff,EXP(%ebx) 70 71L_exit: 72 popl %ebx 73 leave 74 ret 75 76 77L_zero: 78 movw $0,EXP(%ebx) 79 movl TAG_Zero,%eax 80 jmp L_exit 81 82L_underflow: 83 /* Convert the exponent to 80x87 form. */ 84 addw EXTENDED_Ebias,EXP(%ebx) 85 push %ebx 86 call arith_underflow 87 pop %ebx 88 jmp L_exit 89 90L_overflow: 91 /* Convert the exponent to 80x87 form. */ 92 addw EXTENDED_Ebias,EXP(%ebx) 93 push %ebx 94 call arith_overflow 95 pop %ebx 96 jmp L_exit 97ENDPROC(FPU_normalize) 98 99 100 101/* Normalise without reporting underflow or overflow */ 102ENTRY(FPU_normalize_nuo) 103 pushl %ebp 104 movl %esp,%ebp 105 pushl %ebx 106 107 movl PARAM1,%ebx 108 109 movl SIGH(%ebx),%edx 110 movl SIGL(%ebx),%eax 111 112 orl %edx,%edx /* ms bits */ 113 js L_exit_nuo_valid /* Already normalized */ 114 jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */ 115 116 orl %eax,%eax 117 jz L_exit_nuo_zero /* The contents are zero */ 118 119 movl %eax,%edx 120 xorl %eax,%eax 121 subw $32,EXP(%ebx) /* This can cause an underflow */ 122 123/* We need to shift left by 1 - 31 bits */ 124L_nuo_shift_1: 125 bsrl %edx,%ecx /* get the required shift in %ecx */ 126 subl $31,%ecx 127 negl %ecx 128 shld %cl,%eax,%edx 129 shl %cl,%eax 130 subw %cx,EXP(%ebx) /* This can cause an underflow */ 131 132 movl %edx,SIGH(%ebx) 133 movl %eax,SIGL(%ebx) 134 135L_exit_nuo_valid: 136 movl TAG_Valid,%eax 137 138 popl %ebx 139 leave 140 ret 141 142L_exit_nuo_zero: 143 movl TAG_Zero,%eax 144 movw EXP_UNDER,EXP(%ebx) 145 146 popl %ebx 147 leave 148 ret 149ENDPROC(FPU_normalize_nuo) 150