Loading...
1/* SPDX-License-Identifier: GPL-2.0 */
2 .file "reg_u_mul.S"
3/*---------------------------------------------------------------------------+
4 | reg_u_mul.S |
5 | |
6 | Core multiplication routine |
7 | |
8 | Copyright (C) 1992,1993,1995,1997 |
9 | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
10 | E-mail billm@suburbia.net |
11 | |
12 | |
13 +---------------------------------------------------------------------------*/
14
15/*---------------------------------------------------------------------------+
16 | Basic multiplication routine. |
17 | Does not check the resulting exponent for overflow/underflow |
18 | |
19 | FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); |
20 | |
21 | Internal working is at approx 128 bits. |
22 | Result is rounded to nearest 53 or 64 bits, using "nearest or even". |
23 +---------------------------------------------------------------------------*/
24
25#include "exception.h"
26#include "fpu_emu.h"
27#include "control_w.h"
28
29
30
31#ifndef NON_REENTRANT_FPU
32/* Local storage on the stack: */
33#define FPU_accum_0 -4(%ebp) /* ms word */
34#define FPU_accum_1 -8(%ebp)
35
36#else
37/* Local storage in a static area: */
38.data
39 .align 4,0
40FPU_accum_0:
41 .long 0
42FPU_accum_1:
43 .long 0
44#endif /* NON_REENTRANT_FPU */
45
46
47.text
48SYM_FUNC_START(FPU_u_mul)
49 pushl %ebp
50 movl %esp,%ebp
51#ifndef NON_REENTRANT_FPU
52 subl $8,%esp
53#endif /* NON_REENTRANT_FPU */
54
55 pushl %esi
56 pushl %edi
57 pushl %ebx
58
59 movl PARAM1,%esi
60 movl PARAM2,%edi
61
62#ifdef PARANOID
63 testl $0x80000000,SIGH(%esi)
64 jz L_bugged
65 testl $0x80000000,SIGH(%edi)
66 jz L_bugged
67#endif /* PARANOID */
68
69 xorl %ecx,%ecx
70 xorl %ebx,%ebx
71
72 movl SIGL(%esi),%eax
73 mull SIGL(%edi)
74 movl %eax,FPU_accum_0
75 movl %edx,FPU_accum_1
76
77 movl SIGL(%esi),%eax
78 mull SIGH(%edi)
79 addl %eax,FPU_accum_1
80 adcl %edx,%ebx
81/* adcl $0,%ecx // overflow here is not possible */
82
83 movl SIGH(%esi),%eax
84 mull SIGL(%edi)
85 addl %eax,FPU_accum_1
86 adcl %edx,%ebx
87 adcl $0,%ecx
88
89 movl SIGH(%esi),%eax
90 mull SIGH(%edi)
91 addl %eax,%ebx
92 adcl %edx,%ecx
93
94 /* Get the sum of the exponents. */
95 movl PARAM6,%eax
96 subl EXP_BIAS-1,%eax
97
98 /* Two denormals can cause an exponent underflow */
99 cmpl EXP_WAY_UNDER,%eax
100 jg Exp_not_underflow
101
102 /* Set to a really low value allow correct handling */
103 movl EXP_WAY_UNDER,%eax
104
105Exp_not_underflow:
106
107/* Have now finished with the sources */
108 movl PARAM3,%edi /* Point to the destination */
109 movw %ax,EXP(%edi)
110
111/* Now make sure that the result is normalized */
112 testl $0x80000000,%ecx
113 jnz LResult_Normalised
114
115 /* Normalize by shifting left one bit */
116 shll $1,FPU_accum_0
117 rcll $1,FPU_accum_1
118 rcll $1,%ebx
119 rcll $1,%ecx
120 decw EXP(%edi)
121
122LResult_Normalised:
123 movl FPU_accum_0,%eax
124 movl FPU_accum_1,%edx
125 orl %eax,%eax
126 jz L_extent_zero
127
128 orl $1,%edx
129
130L_extent_zero:
131 movl %ecx,%eax
132 jmp fpu_reg_round
133
134
135#ifdef PARANOID
136L_bugged:
137 pushl EX_INTERNAL|0x205
138 call EXCEPTION
139 pop %ebx
140 jmp L_exit
141
142L_exit:
143 popl %ebx
144 popl %edi
145 popl %esi
146 leave
147 RET
148#endif /* PARANOID */
149
150SYM_FUNC_END(FPU_u_mul)
1 .file "reg_u_mul.S"
2/*---------------------------------------------------------------------------+
3 | reg_u_mul.S |
4 | |
5 | Core multiplication routine |
6 | |
7 | Copyright (C) 1992,1993,1995,1997 |
8 | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
9 | E-mail billm@suburbia.net |
10 | |
11 | |
12 +---------------------------------------------------------------------------*/
13
14/*---------------------------------------------------------------------------+
15 | Basic multiplication routine. |
16 | Does not check the resulting exponent for overflow/underflow |
17 | |
18 | FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); |
19 | |
20 | Internal working is at approx 128 bits. |
21 | Result is rounded to nearest 53 or 64 bits, using "nearest or even". |
22 +---------------------------------------------------------------------------*/
23
24#include "exception.h"
25#include "fpu_emu.h"
26#include "control_w.h"
27
28
29
30#ifndef NON_REENTRANT_FPU
31/* Local storage on the stack: */
32#define FPU_accum_0 -4(%ebp) /* ms word */
33#define FPU_accum_1 -8(%ebp)
34
35#else
36/* Local storage in a static area: */
37.data
38 .align 4,0
39FPU_accum_0:
40 .long 0
41FPU_accum_1:
42 .long 0
43#endif /* NON_REENTRANT_FPU */
44
45
46.text
47ENTRY(FPU_u_mul)
48 pushl %ebp
49 movl %esp,%ebp
50#ifndef NON_REENTRANT_FPU
51 subl $8,%esp
52#endif /* NON_REENTRANT_FPU */
53
54 pushl %esi
55 pushl %edi
56 pushl %ebx
57
58 movl PARAM1,%esi
59 movl PARAM2,%edi
60
61#ifdef PARANOID
62 testl $0x80000000,SIGH(%esi)
63 jz L_bugged
64 testl $0x80000000,SIGH(%edi)
65 jz L_bugged
66#endif /* PARANOID */
67
68 xorl %ecx,%ecx
69 xorl %ebx,%ebx
70
71 movl SIGL(%esi),%eax
72 mull SIGL(%edi)
73 movl %eax,FPU_accum_0
74 movl %edx,FPU_accum_1
75
76 movl SIGL(%esi),%eax
77 mull SIGH(%edi)
78 addl %eax,FPU_accum_1
79 adcl %edx,%ebx
80/* adcl $0,%ecx // overflow here is not possible */
81
82 movl SIGH(%esi),%eax
83 mull SIGL(%edi)
84 addl %eax,FPU_accum_1
85 adcl %edx,%ebx
86 adcl $0,%ecx
87
88 movl SIGH(%esi),%eax
89 mull SIGH(%edi)
90 addl %eax,%ebx
91 adcl %edx,%ecx
92
93 /* Get the sum of the exponents. */
94 movl PARAM6,%eax
95 subl EXP_BIAS-1,%eax
96
97 /* Two denormals can cause an exponent underflow */
98 cmpl EXP_WAY_UNDER,%eax
99 jg Exp_not_underflow
100
101 /* Set to a really low value allow correct handling */
102 movl EXP_WAY_UNDER,%eax
103
104Exp_not_underflow:
105
106/* Have now finished with the sources */
107 movl PARAM3,%edi /* Point to the destination */
108 movw %ax,EXP(%edi)
109
110/* Now make sure that the result is normalized */
111 testl $0x80000000,%ecx
112 jnz LResult_Normalised
113
114 /* Normalize by shifting left one bit */
115 shll $1,FPU_accum_0
116 rcll $1,FPU_accum_1
117 rcll $1,%ebx
118 rcll $1,%ecx
119 decw EXP(%edi)
120
121LResult_Normalised:
122 movl FPU_accum_0,%eax
123 movl FPU_accum_1,%edx
124 orl %eax,%eax
125 jz L_extent_zero
126
127 orl $1,%edx
128
129L_extent_zero:
130 movl %ecx,%eax
131 jmp fpu_reg_round
132
133
134#ifdef PARANOID
135L_bugged:
136 pushl EX_INTERNAL|0x205
137 call EXCEPTION
138 pop %ebx
139 jmp L_exit
140
141L_exit:
142 popl %ebx
143 popl %edi
144 popl %esi
145 leave
146 ret
147#endif /* PARANOID */
148