blob: 8b6352efceef2629138490602f4e7fcb7519b533 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*---------------------------------------------------------------------------+
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
97
98
99
100/* Normalise without reporting underflow or overflow */
101ENTRY(FPU_normalize_nuo)
102 pushl %ebp
103 movl %esp,%ebp
104 pushl %ebx
105
106 movl PARAM1,%ebx
107
108 movl SIGH(%ebx),%edx
109 movl SIGL(%ebx),%eax
110
111 orl %edx,%edx /* ms bits */
112 js L_exit_nuo_valid /* Already normalized */
113 jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */
114
115 orl %eax,%eax
116 jz L_exit_nuo_zero /* The contents are zero */
117
118 movl %eax,%edx
119 xorl %eax,%eax
120 subw $32,EXP(%ebx) /* This can cause an underflow */
121
122/* We need to shift left by 1 - 31 bits */
123L_nuo_shift_1:
124 bsrl %edx,%ecx /* get the required shift in %ecx */
125 subl $31,%ecx
126 negl %ecx
127 shld %cl,%eax,%edx
128 shl %cl,%eax
129 subw %cx,EXP(%ebx) /* This can cause an underflow */
130
131 movl %edx,SIGH(%ebx)
132 movl %eax,SIGL(%ebx)
133
134L_exit_nuo_valid:
135 movl TAG_Valid,%eax
136
137 popl %ebx
138 leave
139 ret
140
141L_exit_nuo_zero:
142 movl TAG_Zero,%eax
143 movw EXP_UNDER,EXP(%ebx)
144
145 popl %ebx
146 leave
147 ret