License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-2.6-block.git] / arch / x86 / math-emu / reg_norm.S
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
25 ENTRY(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 */
47 L_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
58 L_done:
59         cmpw    EXP_OVER,EXP(%ebx)
60         jge     L_overflow
61
62         cmpw    EXP_UNDER,EXP(%ebx)
63         jle     L_underflow
64
65 L_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
72 L_exit:
73         popl    %ebx
74         leave
75         ret
76
77
78 L_zero:
79         movw    $0,EXP(%ebx)
80         movl    TAG_Zero,%eax
81         jmp     L_exit
82
83 L_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
91 L_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
98 ENDPROC(FPU_normalize)
99
100
101
102 /* Normalise without reporting underflow or overflow */
103 ENTRY(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 */
125 L_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
136 L_exit_nuo_valid:
137         movl    TAG_Valid,%eax
138
139         popl    %ebx
140         leave
141         ret
142
143 L_exit_nuo_zero:
144         movl    TAG_Zero,%eax
145         movw    EXP_UNDER,EXP(%ebx)
146
147         popl    %ebx
148         leave
149         ret
150 ENDPROC(FPU_normalize_nuo)