1;; Copyright (C) 2001-2022 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. 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;; 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 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. 118 119 move.d $r11,$r9 120 bound.d $r10,$r9 121 cmpu.w 65535,$r9 122 bls L(L3) 123 move.d $r10,$r12 124 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 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 188 189L(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. 193 194 xor $r9,$r10 195 xor $r11,$r10 196 cmpu.w 65535,$r10 197 bls L(L5) 198 movu.w $r9,$r13 199 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 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 244 245L(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. 248 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 268L(Lfe1): 269 .size ___Mul,L(Lfe1)-___Mul 270