umulsidi3.S revision 1.1.1.6
1;; Copyright (C) 2001-2018 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 is derived from mulsi3.S, observing that the mstep*16-based 25;; multiplications there, from which it is formed, are actually 26;; zero-extending; in gcc-speak "umulhisi3". The difference to *this* 27;; function is just a missing top mstep*16 sequence and shifts and 64-bit 28;; additions for the high part. Compared to an implementation based on 29;; calling __Mul four times (see default implementation of umul_ppmm in 30;; longlong.h), this will complete in a time between a fourth and a third 31;; of that, assuming the value-based optimizations don't strike. If they 32;; all strike there (very often) but none here, we still win, though by a 33;; lesser margin, due to lesser total overhead. 34 35#define L(x) .x 36#define CONCAT1(a, b) CONCAT2(a, b) 37#define CONCAT2(a, b) a ## b 38 39#ifdef __USER_LABEL_PREFIX__ 40# define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) 41#else 42# define SYM(x) x 43#endif 44 45 .global SYM(__umulsidi3) 46 .type SYM(__umulsidi3),@function 47SYM(__umulsidi3): 48#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10 49;; Can't have the mulu.d last on a cache-line, due to a hardware bug. See 50;; the documentation for -mmul-bug-workaround. 51;; Not worthwhile to conditionalize here. 52 .p2alignw 2,0x050f 53 mulu.d $r11,$r10 54 ret 55 move $mof,$r11 56#else 57 move.d $r11,$r9 58 bound.d $r10,$r9 59 cmpu.w 65535,$r9 60 bls L(L3) 61 move.d $r10,$r12 62 63 move.d $r10,$r13 64 movu.w $r11,$r9 ; ab*cd = (a*c)<<32 (a*d + b*c)<<16 + b*d 65 66;; We're called for floating point numbers very often with the "low" 16 67;; bits zero, so it's worthwhile to optimize for that. 68 69 beq L(L6) ; d == 0? 70 lslq 16,$r13 71 72 beq L(L7) ; b == 0? 73 clear.w $r10 74 75 mstep $r9,$r13 ; d*b 76 mstep $r9,$r13 77 mstep $r9,$r13 78 mstep $r9,$r13 79 mstep $r9,$r13 80 mstep $r9,$r13 81 mstep $r9,$r13 82 mstep $r9,$r13 83 mstep $r9,$r13 84 mstep $r9,$r13 85 mstep $r9,$r13 86 mstep $r9,$r13 87 mstep $r9,$r13 88 mstep $r9,$r13 89 mstep $r9,$r13 90 mstep $r9,$r13 91 92L(L7): 93 test.d $r10 94 mstep $r9,$r10 ; d*a 95 mstep $r9,$r10 96 mstep $r9,$r10 97 mstep $r9,$r10 98 mstep $r9,$r10 99 mstep $r9,$r10 100 mstep $r9,$r10 101 mstep $r9,$r10 102 mstep $r9,$r10 103 mstep $r9,$r10 104 mstep $r9,$r10 105 mstep $r9,$r10 106 mstep $r9,$r10 107 mstep $r9,$r10 108 mstep $r9,$r10 109 mstep $r9,$r10 110 111;; d*a in $r10, d*b in $r13, ab in $r12 and cd in $r11 112;; $r9 = d, need to do b*c and a*c; we can drop d. 113;; so $r9 is up for use and we can shift down $r11 as the mstep 114;; source for the next mstep-part. 115 116L(L8): 117 lsrq 16,$r11 118 move.d $r12,$r9 119 lslq 16,$r9 120 beq L(L9) ; b == 0? 121 mstep $r11,$r9 122 123 mstep $r11,$r9 ; b*c 124 mstep $r11,$r9 125 mstep $r11,$r9 126 mstep $r11,$r9 127 mstep $r11,$r9 128 mstep $r11,$r9 129 mstep $r11,$r9 130 mstep $r11,$r9 131 mstep $r11,$r9 132 mstep $r11,$r9 133 mstep $r11,$r9 134 mstep $r11,$r9 135 mstep $r11,$r9 136 mstep $r11,$r9 137 mstep $r11,$r9 138L(L9): 139 140;; d*a in $r10, d*b in $r13, c*b in $r9, ab in $r12 and c in $r11, 141;; need to do a*c. We want that to end up in $r11, so we shift up $r11 to 142;; now use as the destination operand. We'd need a test insn to update N 143;; to do it the other way round. 144 145 lsrq 16,$r12 146 lslq 16,$r11 147 mstep $r12,$r11 148 mstep $r12,$r11 149 mstep $r12,$r11 150 mstep $r12,$r11 151 mstep $r12,$r11 152 mstep $r12,$r11 153 mstep $r12,$r11 154 mstep $r12,$r11 155 mstep $r12,$r11 156 mstep $r12,$r11 157 mstep $r12,$r11 158 mstep $r12,$r11 159 mstep $r12,$r11 160 mstep $r12,$r11 161 mstep $r12,$r11 162 mstep $r12,$r11 163 164;; d*a in $r10, d*b in $r13, c*b in $r9, a*c in $r11 ($r12 free). 165;; Need (a*d + b*c)<<16 + b*d into $r10 and 166;; a*c + (a*d + b*c)>>16 plus carry from the additions into $r11. 167 168 add.d $r9,$r10 ; (a*d + b*c) - may produce a carry. 169 scs $r12 ; The carry corresponds to bit 16 of $r11. 170 lslq 16,$r12 171 add.d $r12,$r11 ; $r11 = a*c + carry from (a*d + b*c). 172 173#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 8 174 swapw $r10 175 addu.w $r10,$r11 ; $r11 = a*c + (a*d + b*c) >> 16 including carry. 176 clear.w $r10 ; $r10 = (a*d + b*c) << 16 177#else 178 move.d $r10,$r9 179 lsrq 16,$r9 180 add.d $r9,$r11 ; $r11 = a*c + (a*d + b*c) >> 16 including carry. 181 lslq 16,$r10 ; $r10 = (a*d + b*c) << 16 182#endif 183 add.d $r13,$r10 ; $r10 = (a*d + b*c) << 16 + b*d - may produce a carry. 184 scs $r9 185 ret 186 add.d $r9,$r11 ; Last carry added to the high-order 32 bits. 187 188L(L6): 189 clear.d $r13 190 ba L(L8) 191 clear.d $r10 192 193L(L11): 194 clear.d $r10 195 ret 196 clear.d $r11 197 198L(L3): 199;; Form the maximum in $r10, by knowing the minimum, $r9. 200;; (We don't know which one of $r10 or $r11 it is.) 201;; Check if the largest operand is still just 16 bits. 202 203 xor $r9,$r10 204 xor $r11,$r10 205 cmpu.w 65535,$r10 206 bls L(L5) 207 movu.w $r9,$r13 208 209;; We have ab*cd = (a*c)<<32 + (a*d + b*c)<<16 + b*d, but c==0 210;; so we only need (a*d)<<16 + b*d with d = $r13, ab = $r10. 211;; Remember that the upper part of (a*d)<<16 goes into the lower part 212;; of $r11 and there may be a carry from adding the low 32 parts. 213 beq L(L11) ; d == 0? 214 move.d $r10,$r9 215 216 lslq 16,$r9 217 beq L(L10) ; b == 0? 218 clear.w $r10 219 220 mstep $r13,$r9 ; b*d 221 mstep $r13,$r9 222 mstep $r13,$r9 223 mstep $r13,$r9 224 mstep $r13,$r9 225 mstep $r13,$r9 226 mstep $r13,$r9 227 mstep $r13,$r9 228 mstep $r13,$r9 229 mstep $r13,$r9 230 mstep $r13,$r9 231 mstep $r13,$r9 232 mstep $r13,$r9 233 mstep $r13,$r9 234 mstep $r13,$r9 235 mstep $r13,$r9 236L(L10): 237 test.d $r10 238 mstep $r13,$r10 ; a*d 239 mstep $r13,$r10 240 mstep $r13,$r10 241 mstep $r13,$r10 242 mstep $r13,$r10 243 mstep $r13,$r10 244 mstep $r13,$r10 245 mstep $r13,$r10 246 mstep $r13,$r10 247 mstep $r13,$r10 248 mstep $r13,$r10 249 mstep $r13,$r10 250 mstep $r13,$r10 251 mstep $r13,$r10 252 mstep $r13,$r10 253 mstep $r13,$r10 254 move.d $r10,$r11 255 lsrq 16,$r11 256 lslq 16,$r10 257 add.d $r9,$r10 258 scs $r12 259 ret 260 add.d $r12,$r11 261 262L(L5): 263;; We have ab*cd = (a*c)<<32 + (a*d + b*c)<<16 + b*d, but a and c==0 264;; so b*d (with min=b=$r13, max=d=$r10) it is. As it won't overflow the 265;; 32-bit part, just set $r11 to 0. 266 267 lslq 16,$r10 268 clear.d $r11 269 270 mstep $r13,$r10 271 mstep $r13,$r10 272 mstep $r13,$r10 273 mstep $r13,$r10 274 mstep $r13,$r10 275 mstep $r13,$r10 276 mstep $r13,$r10 277 mstep $r13,$r10 278 mstep $r13,$r10 279 mstep $r13,$r10 280 mstep $r13,$r10 281 mstep $r13,$r10 282 mstep $r13,$r10 283 mstep $r13,$r10 284 mstep $r13,$r10 285 ret 286 mstep $r13,$r10 287#endif 288L(Lfe1): 289 .size SYM(__umulsidi3),L(Lfe1)-SYM(__umulsidi3) 290