]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/cris/mulsi3.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / cris / mulsi3.S
CommitLineData
99dee823 1;; Copyright (C) 2001-2021 Free Software Foundation, Inc.
ad41bd84
JM
2;;
3;; This file is part of GCC.
4;;
5;; GCC is free software; you can redistribute it and/or modify it under
6;; the terms of the GNU General Public License as published by the Free
7;; Software Foundation; either version 3, or (at your option) any later
8;; version.
9;;
10;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
12;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13;; for more details.
14;;
15;; Under Section 7 of GPL version 3, you are granted additional
16;; permissions described in the GCC Runtime Library Exception, version
17;; 3.1, as published by the Free Software Foundation.
18;;
19;; You should have received a copy of the GNU General Public License and
20;; a copy of the GCC Runtime Library Exception along with this program;
21;; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22;; <http://www.gnu.org/licenses/>.
23;;
0b85d816
HPN
24;; This code used to be expanded through interesting expansions in
25;; the machine description, compiled from this code:
26;;
27;; #ifdef L_mulsi3
28;; long __Mul (unsigned long a, unsigned long b) __attribute__ ((__const__));
29;;
30;; /* This must be compiled with the -mexpand-mul flag, to synthesize the
31;; multiplication from the mstep instructions. The check for
32;; smaller-size multiplication pays off in the order of .5-10%;
33;; estimated median 1%, depending on application.
34;; FIXME: It can be further optimized if we go to assembler code, as
35;; gcc 2.7.2 adds a few unnecessary instructions and does not put the
36;; basic blocks in optimal order. */
37;; long
38;; __Mul (unsigned long a, unsigned long b)
39;; {
40;; #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
41;; /* In case other code is compiled without -march=v10, they will
42;; contain calls to __Mul, regardless of flags at link-time. The
43;; "else"-code below will work, but is unnecessarily slow. This
44;; sometimes cuts a few minutes off from simulation time by just
45;; returning a "mulu.d". */
46;; return a * b;
47;; #else
48;; unsigned long min;
49;;
50;; /* Get minimum via the bound insn. */
51;; min = a < b ? a : b;
52;;
53;; /* Can we omit computation of the high part? */
54;; if (min > 65535)
55;; /* No. Perform full multiplication. */
56;; return a * b;
57;; else
58;; {
59;; /* Check if both operands are within 16 bits. */
60;; unsigned long max;
61;;
62;; /* Get maximum, by knowing the minimum.
63;; This will partition a and b into max and min.
64;; This is not currently something GCC understands,
65;; so do this trick by asm. */
66;; __asm__ ("xor %1,%0\n\txor %2,%0"
67;; : "=r" (max)
68;; : "r" (b), "r" (a), "0" (min));
69;;
70;; if (max > 65535)
71;; /* Make GCC understand that only the low part of "min" will be
72;; used. */
73;; return max * (unsigned short) min;
74;; else
75;; /* Only the low parts of both operands are necessary. */
76;; return ((unsigned short) max) * (unsigned short) min;
77;; }
78;; #endif /* not __CRIS_arch_version >= 10 */
79;; }
80;; #endif /* L_mulsi3 */
81;;
82;; That approach was abandoned since the caveats outweighted the
83;; benefits. The expand-multiplication machinery is also removed, so you
84;; can't do this anymore.
85;;
86;; For doubters of there being any benefits, some where: insensitivity to:
87;; - ABI changes (mostly for experimentation)
88;; - assembler syntax differences (mostly debug format).
89;; - insn scheduling issues.
90;; Most ABI experiments will presumably happen with arches with mul insns,
91;; so that argument doesn't really hold anymore, and it's unlikely there
92;; being new arch variants needing insn scheduling and not having mul
93;; insns.
94
95;; ELF and a.out have different syntax for local labels: the "wrong"
96;; one may not be omitted from the object.
97#undef L
98#ifdef __AOUT__
99# define L(x) x
100#else
101# define L(x) .x
102#endif
103
104 .global ___Mul
105 .type ___Mul,@function
106___Mul:
107#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
86da66b5
HPN
108;; Can't have the mulu.d last on a cache-line (in the delay-slot of the
109;; "ret"), due to hardware bug. See documentation for -mmul-bug-workaround.
110;; Not worthwhile to conditionalize here.
111 .p2alignw 2,0x050f
0b85d816 112 mulu.d $r11,$r10
86da66b5
HPN
113 ret
114 nop
0b85d816 115#else
0e499e75
HPN
116;; See if we can avoid multiplying some of the parts, knowing
117;; they're zero.
118
0b85d816 119 move.d $r11,$r9
0e499e75 120 bound.d $r10,$r9
0b85d816
HPN
121 cmpu.w 65535,$r9
122 bls L(L3)
0e499e75 123 move.d $r10,$r12
0b85d816 124
0e499e75
HPN
125;; Nope, have to do all the parts of a 32-bit multiplication.
126;; See head comment in optabs.c:expand_doubleword_mult.
127
128 move.d $r10,$r13
129 movu.w $r11,$r9 ; ab*cd = (a*d + b*c)<<16 + b*d
0b85d816 130 lslq 16,$r13
0e499e75 131 mstep $r9,$r13 ; d*b
0b85d816
HPN
132 mstep $r9,$r13
133 mstep $r9,$r13
134 mstep $r9,$r13
135 mstep $r9,$r13
136 mstep $r9,$r13
137 mstep $r9,$r13
138 mstep $r9,$r13
139 mstep $r9,$r13
140 mstep $r9,$r13
141 mstep $r9,$r13
142 mstep $r9,$r13
143 mstep $r9,$r13
144 mstep $r9,$r13
145 mstep $r9,$r13
146 mstep $r9,$r13
147 clear.w $r10
148 test.d $r10
0e499e75 149 mstep $r9,$r10 ; d*a
0b85d816
HPN
150 mstep $r9,$r10
151 mstep $r9,$r10
152 mstep $r9,$r10
153 mstep $r9,$r10
154 mstep $r9,$r10
155 mstep $r9,$r10
156 mstep $r9,$r10
157 mstep $r9,$r10
158 mstep $r9,$r10
159 mstep $r9,$r10
160 mstep $r9,$r10
161 mstep $r9,$r10
162 mstep $r9,$r10
163 mstep $r9,$r10
164 mstep $r9,$r10
165 movu.w $r12,$r12
0e499e75
HPN
166 clear.w $r11
167 move.d $r11,$r9 ; Doubles as a "test.d" preparing for the mstep.
168 mstep $r12,$r9 ; b*c
0b85d816
HPN
169 mstep $r12,$r9
170 mstep $r12,$r9
171 mstep $r12,$r9
172 mstep $r12,$r9
173 mstep $r12,$r9
174 mstep $r12,$r9
175 mstep $r12,$r9
176 mstep $r12,$r9
177 mstep $r12,$r9
178 mstep $r12,$r9
179 mstep $r12,$r9
180 mstep $r12,$r9
181 mstep $r12,$r9
182 mstep $r12,$r9
183 mstep $r12,$r9
184 add.w $r9,$r10
185 lslq 16,$r10
186 ret
187 add.d $r13,$r10
188
189L(L3):
0e499e75
HPN
190;; Form the maximum in $r10, by knowing the minimum, $r9.
191;; (We don't know which one of $r10 or $r11 it is.)
192;; Check if the largest operand is still just 16 bits.
193
194 xor $r9,$r10
0b85d816 195 xor $r11,$r10
0b85d816
HPN
196 cmpu.w 65535,$r10
197 bls L(L5)
198 movu.w $r9,$r13
199
0e499e75
HPN
200;; We have ab*cd = (a*c)<<32 + (a*d + b*c)<<16 + b*d, but c==0
201;; so we only need (a*d)<<16 + b*d with d = $r13, ab = $r10.
202;; We drop the upper part of (a*d)<<16 as we're only doing a
203;; 32-bit-result multiplication.
204
0b85d816
HPN
205 move.d $r10,$r9
206 lslq 16,$r9
0e499e75 207 mstep $r13,$r9 ; b*d
0b85d816
HPN
208 mstep $r13,$r9
209 mstep $r13,$r9
210 mstep $r13,$r9
211 mstep $r13,$r9
212 mstep $r13,$r9
213 mstep $r13,$r9
214 mstep $r13,$r9
215 mstep $r13,$r9
216 mstep $r13,$r9
217 mstep $r13,$r9
218 mstep $r13,$r9
219 mstep $r13,$r9
220 mstep $r13,$r9
221 mstep $r13,$r9
222 mstep $r13,$r9
223 clear.w $r10
224 test.d $r10
0e499e75 225 mstep $r13,$r10 ; a*d
0b85d816
HPN
226 mstep $r13,$r10
227 mstep $r13,$r10
228 mstep $r13,$r10
229 mstep $r13,$r10
230 mstep $r13,$r10
231 mstep $r13,$r10
232 mstep $r13,$r10
233 mstep $r13,$r10
234 mstep $r13,$r10
235 mstep $r13,$r10
236 mstep $r13,$r10
237 mstep $r13,$r10
238 mstep $r13,$r10
239 mstep $r13,$r10
240 mstep $r13,$r10
241 lslq 16,$r10
242 ret
243 add.d $r9,$r10
244
245L(L5):
0e499e75
HPN
246;; We have ab*cd = (a*c)<<32 + (a*d + b*c)<<16 + b*d, but a and c==0
247;; so b*d (with b=$r13, a=$r10) it is.
248
0b85d816 249 lslq 16,$r10
0e499e75
HPN
250 mstep $r13,$r10
251 mstep $r13,$r10
252 mstep $r13,$r10
253 mstep $r13,$r10
254 mstep $r13,$r10
255 mstep $r13,$r10
256 mstep $r13,$r10
257 mstep $r13,$r10
258 mstep $r13,$r10
259 mstep $r13,$r10
260 mstep $r13,$r10
261 mstep $r13,$r10
262 mstep $r13,$r10
263 mstep $r13,$r10
264 mstep $r13,$r10
0b85d816 265 ret
0e499e75 266 mstep $r13,$r10
0b85d816
HPN
267#endif
268L(Lfe1):
269 .size ___Mul,L(Lfe1)-___Mul