1 ;; Copyright (C) 2001-2017 Free Software Foundation, Inc.
3 ;; This file is part of GCC.
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
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
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:
28 ;; long __Mul (unsigned long a, unsigned long b) __attribute__ ((__const__));
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. */
38 ;; __Mul (unsigned long a, unsigned long b)
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". */
50 ;; /* Get minimum via the bound insn. */
51 ;; min = a < b ? a : b;
53 ;; /* Can we omit computation of the high part? */
55 ;; /* No. Perform full multiplication. */
59 ;; /* Check if both operands are within 16 bits. */
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"
68 ;; : "r" (b), "r" (a), "0" (min));
71 ;; /* Make GCC understand that only the low part of "min" will be
73 ;; return max * (unsigned short) min;
75 ;; /* Only the low parts of both operands are necessary. */
76 ;; return ((unsigned short) max) * (unsigned short) min;
78 ;; #endif /* not __CRIS_arch_version >= 10 */
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
95 ;; ELF and a.out have different syntax for local labels: the "wrong"
96 ;; one may not be omitted from the object.
105 .type ___Mul,@function
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.
116 ;; See if we can avoid multiplying some of the parts, knowing
125 ;; Nope, have to do all the parts of a 32-bit multiplication.
126 ;; See head comment in optabs.c:expand_doubleword_mult.
129 movu.w $r11,$r9 ; ab*cd = (a*d + b*c)<<16 + b*d
167 move.d $r11,$r9 ; Doubles as a "test.d" preparing for the mstep.
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.
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.
225 mstep $r13,$r10 ; a*d
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.
269 .size ___Mul,L(Lfe1)-___Mul