diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/i386/math-emu/reg_u_mul.S |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/i386/math-emu/reg_u_mul.S')
-rw-r--r-- | arch/i386/math-emu/reg_u_mul.S | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/arch/i386/math-emu/reg_u_mul.S b/arch/i386/math-emu/reg_u_mul.S new file mode 100644 index 000000000000..973f12af97df --- /dev/null +++ b/arch/i386/math-emu/reg_u_mul.S | |||
@@ -0,0 +1,148 @@ | |||
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 | ||
39 | FPU_accum_0: | ||
40 | .long 0 | ||
41 | FPU_accum_1: | ||
42 | .long 0 | ||
43 | #endif /* NON_REENTRANT_FPU */ | ||
44 | |||
45 | |||
46 | .text | ||
47 | ENTRY(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 | |||
104 | Exp_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 | |||
121 | LResult_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 | |||
129 | L_extent_zero: | ||
130 | movl %ecx,%eax | ||
131 | jmp fpu_reg_round | ||
132 | |||
133 | |||
134 | #ifdef PARANOID | ||
135 | L_bugged: | ||
136 | pushl EX_INTERNAL|0x205 | ||
137 | call EXCEPTION | ||
138 | pop %ebx | ||
139 | jmp L_exit | ||
140 | |||
141 | L_exit: | ||
142 | popl %ebx | ||
143 | popl %edi | ||
144 | popl %esi | ||
145 | leave | ||
146 | ret | ||
147 | #endif /* PARANOID */ | ||
148 | |||