]> git.ipfire.org Git - thirdparty/kernel/linux.git/blob - arch/x86/math-emu/reg_norm.S
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[thirdparty/kernel/linux.git] / arch / x86 / math-emu / reg_norm.S
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
24 ENTRY(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 */
46 L_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
57 L_done:
58 cmpw EXP_OVER,EXP(%ebx)
59 jge L_overflow
60
61 cmpw EXP_UNDER,EXP(%ebx)
62 jle L_underflow
63
64 L_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
71 L_exit:
72 popl %ebx
73 leave
74 ret
75
76
77 L_zero:
78 movw $0,EXP(%ebx)
79 movl TAG_Zero,%eax
80 jmp L_exit
81
82 L_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
90 L_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 ENDPROC(FPU_normalize)
98
99
100
101 /* Normalise without reporting underflow or overflow */
102 ENTRY(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 */
124 L_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
135 L_exit_nuo_valid:
136 movl TAG_Valid,%eax
137
138 popl %ebx
139 leave
140 ret
141
142 L_exit_nuo_zero:
143 movl TAG_Zero,%eax
144 movw EXP_UNDER,EXP(%ebx)
145
146 popl %ebx
147 leave
148 ret
149 ENDPROC(FPU_normalize_nuo)