Fix broken MinGW build of gcc.c
[official-gcc.git] / libgcc / config / cris / mulsi3.S
blobfbb705f382827a088473e87a50def4f97d9b7a2d
1 ;; Copyright (C) 2001-2017 Free Software Foundation, Inc.
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.
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.
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/>.
24 ;; This code used to be expanded through interesting expansions in
25 ;; the machine description, compiled from this code:
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 */
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.
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.
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
104         .global ___Mul
105         .type   ___Mul,@function
106 ___Mul:
107 #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
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
112         mulu.d $r11,$r10
113         ret
114         nop
115 #else
116 ;; See if we can avoid multiplying some of the parts, knowing
117 ;; they're zero.
119         move.d $r11,$r9
120         bound.d $r10,$r9
121         cmpu.w 65535,$r9
122         bls L(L3)
123         move.d $r10,$r12
125 ;; Nope, have to do all the parts of a 32-bit multiplication.
126 ;; See head comment in optabs.c:expand_doubleword_mult.
128         move.d $r10,$r13
129         movu.w $r11,$r9 ; ab*cd = (a*d + b*c)<<16 + b*d
130         lslq 16,$r13
131         mstep $r9,$r13  ; d*b
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
149         mstep $r9,$r10  ; d*a
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
166         clear.w $r11
167         move.d $r11,$r9 ; Doubles as a "test.d" preparing for the mstep.
168         mstep $r12,$r9  ; b*c
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
189 L(L3):
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.
194         xor $r9,$r10
195         xor $r11,$r10
196         cmpu.w 65535,$r10
197         bls L(L5)
198         movu.w $r9,$r13
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.
205         move.d $r10,$r9
206         lslq 16,$r9
207         mstep $r13,$r9  ; b*d
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
225         mstep $r13,$r10 ; a*d
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
245 L(L5):
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.
249         lslq 16,$r10
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
265         ret
266         mstep $r13,$r10
267 #endif
268 L(Lfe1):
269         .size   ___Mul,L(Lfe1)-___Mul