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

source code of linux/arch/x86/math-emu/reg_norm.S