1*2a598d0bSHerbert Xu /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. 2*2a598d0bSHerbert Xu * Note: I added some stuff for use with gnupg 3*2a598d0bSHerbert Xu * 4*2a598d0bSHerbert Xu * Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998, 5*2a598d0bSHerbert Xu * 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 6*2a598d0bSHerbert Xu * 7*2a598d0bSHerbert Xu * This file is free software; you can redistribute it and/or modify 8*2a598d0bSHerbert Xu * it under the terms of the GNU Library General Public License as published by 9*2a598d0bSHerbert Xu * the Free Software Foundation; either version 2 of the License, or (at your 10*2a598d0bSHerbert Xu * option) any later version. 11*2a598d0bSHerbert Xu * 12*2a598d0bSHerbert Xu * This file is distributed in the hope that it will be useful, but 13*2a598d0bSHerbert Xu * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14*2a598d0bSHerbert Xu * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15*2a598d0bSHerbert Xu * License for more details. 16*2a598d0bSHerbert Xu * 17*2a598d0bSHerbert Xu * You should have received a copy of the GNU Library General Public License 18*2a598d0bSHerbert Xu * along with this file; see the file COPYING.LIB. If not, write to 19*2a598d0bSHerbert Xu * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 20*2a598d0bSHerbert Xu * MA 02111-1307, USA. */ 21*2a598d0bSHerbert Xu 22*2a598d0bSHerbert Xu #include <linux/count_zeros.h> 23*2a598d0bSHerbert Xu 24*2a598d0bSHerbert Xu /* You have to define the following before including this file: 25*2a598d0bSHerbert Xu * 26*2a598d0bSHerbert Xu * UWtype -- An unsigned type, default type for operations (typically a "word") 27*2a598d0bSHerbert Xu * UHWtype -- An unsigned type, at least half the size of UWtype. 28*2a598d0bSHerbert Xu * UDWtype -- An unsigned type, at least twice as large a UWtype 29*2a598d0bSHerbert Xu * W_TYPE_SIZE -- size in bits of UWtype 30*2a598d0bSHerbert Xu * 31*2a598d0bSHerbert Xu * SItype, USItype -- Signed and unsigned 32 bit types. 32*2a598d0bSHerbert Xu * DItype, UDItype -- Signed and unsigned 64 bit types. 33*2a598d0bSHerbert Xu * 34*2a598d0bSHerbert Xu * On a 32 bit machine UWtype should typically be USItype; 35*2a598d0bSHerbert Xu * on a 64 bit machine, UWtype should typically be UDItype. 36*2a598d0bSHerbert Xu */ 37*2a598d0bSHerbert Xu 38*2a598d0bSHerbert Xu #define __BITS4 (W_TYPE_SIZE / 4) 39*2a598d0bSHerbert Xu #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) 40*2a598d0bSHerbert Xu #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) 41*2a598d0bSHerbert Xu #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) 42*2a598d0bSHerbert Xu 43*2a598d0bSHerbert Xu /* This is used to make sure no undesirable sharing between different libraries 44*2a598d0bSHerbert Xu that use this file takes place. */ 45*2a598d0bSHerbert Xu #ifndef __MPN 46*2a598d0bSHerbert Xu #define __MPN(x) __##x 47*2a598d0bSHerbert Xu #endif 48*2a598d0bSHerbert Xu 49*2a598d0bSHerbert Xu /* Define auxiliary asm macros. 50*2a598d0bSHerbert Xu * 51*2a598d0bSHerbert Xu * 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two 52*2a598d0bSHerbert Xu * UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype 53*2a598d0bSHerbert Xu * word product in HIGH_PROD and LOW_PROD. 54*2a598d0bSHerbert Xu * 55*2a598d0bSHerbert Xu * 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a 56*2a598d0bSHerbert Xu * UDWtype product. This is just a variant of umul_ppmm. 57*2a598d0bSHerbert Xu 58*2a598d0bSHerbert Xu * 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 59*2a598d0bSHerbert Xu * denominator) divides a UDWtype, composed by the UWtype integers 60*2a598d0bSHerbert Xu * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient 61*2a598d0bSHerbert Xu * in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less 62*2a598d0bSHerbert Xu * than DENOMINATOR for correct operation. If, in addition, the most 63*2a598d0bSHerbert Xu * significant bit of DENOMINATOR must be 1, then the pre-processor symbol 64*2a598d0bSHerbert Xu * UDIV_NEEDS_NORMALIZATION is defined to 1. 65*2a598d0bSHerbert Xu * 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 66*2a598d0bSHerbert Xu * denominator). Like udiv_qrnnd but the numbers are signed. The quotient 67*2a598d0bSHerbert Xu * is rounded towards 0. 68*2a598d0bSHerbert Xu * 69*2a598d0bSHerbert Xu * 5) count_leading_zeros(count, x) counts the number of zero-bits from the 70*2a598d0bSHerbert Xu * msb to the first non-zero bit in the UWtype X. This is the number of 71*2a598d0bSHerbert Xu * steps X needs to be shifted left to set the msb. Undefined for X == 0, 72*2a598d0bSHerbert Xu * unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. 73*2a598d0bSHerbert Xu * 74*2a598d0bSHerbert Xu * 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts 75*2a598d0bSHerbert Xu * from the least significant end. 76*2a598d0bSHerbert Xu * 77*2a598d0bSHerbert Xu * 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, 78*2a598d0bSHerbert Xu * high_addend_2, low_addend_2) adds two UWtype integers, composed by 79*2a598d0bSHerbert Xu * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 80*2a598d0bSHerbert Xu * respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow 81*2a598d0bSHerbert Xu * (i.e. carry out) is not stored anywhere, and is lost. 82*2a598d0bSHerbert Xu * 83*2a598d0bSHerbert Xu * 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, 84*2a598d0bSHerbert Xu * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, 85*2a598d0bSHerbert Xu * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and 86*2a598d0bSHerbert Xu * LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE 87*2a598d0bSHerbert Xu * and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, 88*2a598d0bSHerbert Xu * and is lost. 89*2a598d0bSHerbert Xu * 90*2a598d0bSHerbert Xu * If any of these macros are left undefined for a particular CPU, 91*2a598d0bSHerbert Xu * C macros are used. */ 92*2a598d0bSHerbert Xu 93*2a598d0bSHerbert Xu /* The CPUs come in alphabetical order below. 94*2a598d0bSHerbert Xu * 95*2a598d0bSHerbert Xu * Please add support for more CPUs here, or improve the current support 96*2a598d0bSHerbert Xu * for the CPUs below! */ 97*2a598d0bSHerbert Xu 98*2a598d0bSHerbert Xu #if defined(__GNUC__) && !defined(NO_ASM) 99*2a598d0bSHerbert Xu 100*2a598d0bSHerbert Xu /* We sometimes need to clobber "cc" with gcc2, but that would not be 101*2a598d0bSHerbert Xu understood by gcc1. Use cpp to avoid major code duplication. */ 102*2a598d0bSHerbert Xu #if __GNUC__ < 2 103*2a598d0bSHerbert Xu #define __CLOBBER_CC 104*2a598d0bSHerbert Xu #define __AND_CLOBBER_CC 105*2a598d0bSHerbert Xu #else /* __GNUC__ >= 2 */ 106*2a598d0bSHerbert Xu #define __CLOBBER_CC : "cc" 107*2a598d0bSHerbert Xu #define __AND_CLOBBER_CC , "cc" 108*2a598d0bSHerbert Xu #endif /* __GNUC__ < 2 */ 109*2a598d0bSHerbert Xu 110*2a598d0bSHerbert Xu /*************************************** 111*2a598d0bSHerbert Xu ************** A29K ***************** 112*2a598d0bSHerbert Xu ***************************************/ 113*2a598d0bSHerbert Xu #if (defined(__a29k__) || defined(_AM29K)) && W_TYPE_SIZE == 32 114*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 115*2a598d0bSHerbert Xu __asm__ ("add %1,%4,%5\n" \ 116*2a598d0bSHerbert Xu "addc %0,%2,%3" \ 117*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 118*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 119*2a598d0bSHerbert Xu : "%r" ((USItype)(ah)), \ 120*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 121*2a598d0bSHerbert Xu "%r" ((USItype)(al)), \ 122*2a598d0bSHerbert Xu "rI" ((USItype)(bl))) 123*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 124*2a598d0bSHerbert Xu __asm__ ("sub %1,%4,%5\n" \ 125*2a598d0bSHerbert Xu "subc %0,%2,%3" \ 126*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 127*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 128*2a598d0bSHerbert Xu : "r" ((USItype)(ah)), \ 129*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 130*2a598d0bSHerbert Xu "r" ((USItype)(al)), \ 131*2a598d0bSHerbert Xu "rI" ((USItype)(bl))) 132*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, m0, m1) \ 133*2a598d0bSHerbert Xu do { \ 134*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 135*2a598d0bSHerbert Xu __asm__ ("multiplu %0,%1,%2" \ 136*2a598d0bSHerbert Xu : "=r" ((USItype)(xl)) \ 137*2a598d0bSHerbert Xu : "r" (__m0), \ 138*2a598d0bSHerbert Xu "r" (__m1)); \ 139*2a598d0bSHerbert Xu __asm__ ("multmu %0,%1,%2" \ 140*2a598d0bSHerbert Xu : "=r" ((USItype)(xh)) \ 141*2a598d0bSHerbert Xu : "r" (__m0), \ 142*2a598d0bSHerbert Xu "r" (__m1)); \ 143*2a598d0bSHerbert Xu } while (0) 144*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 145*2a598d0bSHerbert Xu __asm__ ("dividu %0,%3,%4" \ 146*2a598d0bSHerbert Xu : "=r" ((USItype)(q)), \ 147*2a598d0bSHerbert Xu "=q" ((USItype)(r)) \ 148*2a598d0bSHerbert Xu : "1" ((USItype)(n1)), \ 149*2a598d0bSHerbert Xu "r" ((USItype)(n0)), \ 150*2a598d0bSHerbert Xu "r" ((USItype)(d))) 151*2a598d0bSHerbert Xu #endif /* __a29k__ */ 152*2a598d0bSHerbert Xu 153*2a598d0bSHerbert Xu #if defined(__alpha) && W_TYPE_SIZE == 64 154*2a598d0bSHerbert Xu #define umul_ppmm(ph, pl, m0, m1) \ 155*2a598d0bSHerbert Xu do { \ 156*2a598d0bSHerbert Xu UDItype __m0 = (m0), __m1 = (m1); \ 157*2a598d0bSHerbert Xu (ph) = __builtin_alpha_umulh(__m0, __m1); \ 158*2a598d0bSHerbert Xu (pl) = __m0 * __m1; \ 159*2a598d0bSHerbert Xu } while (0) 160*2a598d0bSHerbert Xu #define UMUL_TIME 46 161*2a598d0bSHerbert Xu #ifndef LONGLONG_STANDALONE 162*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 163*2a598d0bSHerbert Xu do { UDItype __r; \ 164*2a598d0bSHerbert Xu (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ 165*2a598d0bSHerbert Xu (r) = __r; \ 166*2a598d0bSHerbert Xu } while (0) 167*2a598d0bSHerbert Xu extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); 168*2a598d0bSHerbert Xu #define UDIV_TIME 220 169*2a598d0bSHerbert Xu #endif /* LONGLONG_STANDALONE */ 170*2a598d0bSHerbert Xu #endif /* __alpha */ 171*2a598d0bSHerbert Xu 172*2a598d0bSHerbert Xu /*************************************** 173*2a598d0bSHerbert Xu ************** ARM ****************** 174*2a598d0bSHerbert Xu ***************************************/ 175*2a598d0bSHerbert Xu #if defined(__arm__) && W_TYPE_SIZE == 32 176*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 177*2a598d0bSHerbert Xu __asm__ ("adds %1, %4, %5\n" \ 178*2a598d0bSHerbert Xu "adc %0, %2, %3" \ 179*2a598d0bSHerbert Xu : "=r" (sh), \ 180*2a598d0bSHerbert Xu "=&r" (sl) \ 181*2a598d0bSHerbert Xu : "%r" ((USItype)(ah)), \ 182*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 183*2a598d0bSHerbert Xu "%r" ((USItype)(al)), \ 184*2a598d0bSHerbert Xu "rI" ((USItype)(bl))) 185*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 186*2a598d0bSHerbert Xu __asm__ ("subs %1, %4, %5\n" \ 187*2a598d0bSHerbert Xu "sbc %0, %2, %3" \ 188*2a598d0bSHerbert Xu : "=r" (sh), \ 189*2a598d0bSHerbert Xu "=&r" (sl) \ 190*2a598d0bSHerbert Xu : "r" ((USItype)(ah)), \ 191*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 192*2a598d0bSHerbert Xu "r" ((USItype)(al)), \ 193*2a598d0bSHerbert Xu "rI" ((USItype)(bl))) 194*2a598d0bSHerbert Xu #if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__ 195*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, a, b) \ 196*2a598d0bSHerbert Xu __asm__ ("@ Inlined umul_ppmm\n" \ 197*2a598d0bSHerbert Xu "mov %|r0, %2, lsr #16 @ AAAA\n" \ 198*2a598d0bSHerbert Xu "mov %|r2, %3, lsr #16 @ BBBB\n" \ 199*2a598d0bSHerbert Xu "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \ 200*2a598d0bSHerbert Xu "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \ 201*2a598d0bSHerbert Xu "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \ 202*2a598d0bSHerbert Xu "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \ 203*2a598d0bSHerbert Xu "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \ 204*2a598d0bSHerbert Xu "mul %0, %|r0, %0 @ AAAA * bbbb\n" \ 205*2a598d0bSHerbert Xu "adds %|r0, %1, %0 @ central sum\n" \ 206*2a598d0bSHerbert Xu "addcs %|r2, %|r2, #65536\n" \ 207*2a598d0bSHerbert Xu "adds %1, %|r1, %|r0, lsl #16\n" \ 208*2a598d0bSHerbert Xu "adc %0, %|r2, %|r0, lsr #16" \ 209*2a598d0bSHerbert Xu : "=&r" (xh), \ 210*2a598d0bSHerbert Xu "=r" (xl) \ 211*2a598d0bSHerbert Xu : "r" ((USItype)(a)), \ 212*2a598d0bSHerbert Xu "r" ((USItype)(b)) \ 213*2a598d0bSHerbert Xu : "r0", "r1", "r2") 214*2a598d0bSHerbert Xu #else 215*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, a, b) \ 216*2a598d0bSHerbert Xu __asm__ ("@ Inlined umul_ppmm\n" \ 217*2a598d0bSHerbert Xu "umull %1, %0, %2, %3" \ 218*2a598d0bSHerbert Xu : "=&r" (xh), \ 219*2a598d0bSHerbert Xu "=&r" (xl) \ 220*2a598d0bSHerbert Xu : "r" ((USItype)(a)), \ 221*2a598d0bSHerbert Xu "r" ((USItype)(b)) \ 222*2a598d0bSHerbert Xu : "r0", "r1") 223*2a598d0bSHerbert Xu #endif 224*2a598d0bSHerbert Xu #define UMUL_TIME 20 225*2a598d0bSHerbert Xu #define UDIV_TIME 100 226*2a598d0bSHerbert Xu #endif /* __arm__ */ 227*2a598d0bSHerbert Xu 228*2a598d0bSHerbert Xu /*************************************** 229*2a598d0bSHerbert Xu ************** CLIPPER ************** 230*2a598d0bSHerbert Xu ***************************************/ 231*2a598d0bSHerbert Xu #if defined(__clipper__) && W_TYPE_SIZE == 32 232*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 233*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 234*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 235*2a598d0bSHerbert Xu } __xx; \ 236*2a598d0bSHerbert Xu __asm__ ("mulwux %2,%0" \ 237*2a598d0bSHerbert Xu : "=r" (__xx.__ll) \ 238*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 239*2a598d0bSHerbert Xu "r" ((USItype)(v))); \ 240*2a598d0bSHerbert Xu (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; }) 241*2a598d0bSHerbert Xu #define smul_ppmm(w1, w0, u, v) \ 242*2a598d0bSHerbert Xu ({union {DItype __ll; \ 243*2a598d0bSHerbert Xu struct {SItype __l, __h; } __i; \ 244*2a598d0bSHerbert Xu } __xx; \ 245*2a598d0bSHerbert Xu __asm__ ("mulwx %2,%0" \ 246*2a598d0bSHerbert Xu : "=r" (__xx.__ll) \ 247*2a598d0bSHerbert Xu : "%0" ((SItype)(u)), \ 248*2a598d0bSHerbert Xu "r" ((SItype)(v))); \ 249*2a598d0bSHerbert Xu (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; }) 250*2a598d0bSHerbert Xu #define __umulsidi3(u, v) \ 251*2a598d0bSHerbert Xu ({UDItype __w; \ 252*2a598d0bSHerbert Xu __asm__ ("mulwux %2,%0" \ 253*2a598d0bSHerbert Xu : "=r" (__w) \ 254*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 255*2a598d0bSHerbert Xu "r" ((USItype)(v))); \ 256*2a598d0bSHerbert Xu __w; }) 257*2a598d0bSHerbert Xu #endif /* __clipper__ */ 258*2a598d0bSHerbert Xu 259*2a598d0bSHerbert Xu /*************************************** 260*2a598d0bSHerbert Xu ************** GMICRO *************** 261*2a598d0bSHerbert Xu ***************************************/ 262*2a598d0bSHerbert Xu #if defined(__gmicro__) && W_TYPE_SIZE == 32 263*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 264*2a598d0bSHerbert Xu __asm__ ("add.w %5,%1\n" \ 265*2a598d0bSHerbert Xu "addx %3,%0" \ 266*2a598d0bSHerbert Xu : "=g" ((USItype)(sh)), \ 267*2a598d0bSHerbert Xu "=&g" ((USItype)(sl)) \ 268*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 269*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 270*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 271*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 272*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 273*2a598d0bSHerbert Xu __asm__ ("sub.w %5,%1\n" \ 274*2a598d0bSHerbert Xu "subx %3,%0" \ 275*2a598d0bSHerbert Xu : "=g" ((USItype)(sh)), \ 276*2a598d0bSHerbert Xu "=&g" ((USItype)(sl)) \ 277*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 278*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 279*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 280*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 281*2a598d0bSHerbert Xu #define umul_ppmm(ph, pl, m0, m1) \ 282*2a598d0bSHerbert Xu __asm__ ("mulx %3,%0,%1" \ 283*2a598d0bSHerbert Xu : "=g" ((USItype)(ph)), \ 284*2a598d0bSHerbert Xu "=r" ((USItype)(pl)) \ 285*2a598d0bSHerbert Xu : "%0" ((USItype)(m0)), \ 286*2a598d0bSHerbert Xu "g" ((USItype)(m1))) 287*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, nh, nl, d) \ 288*2a598d0bSHerbert Xu __asm__ ("divx %4,%0,%1" \ 289*2a598d0bSHerbert Xu : "=g" ((USItype)(q)), \ 290*2a598d0bSHerbert Xu "=r" ((USItype)(r)) \ 291*2a598d0bSHerbert Xu : "1" ((USItype)(nh)), \ 292*2a598d0bSHerbert Xu "0" ((USItype)(nl)), \ 293*2a598d0bSHerbert Xu "g" ((USItype)(d))) 294*2a598d0bSHerbert Xu #endif 295*2a598d0bSHerbert Xu 296*2a598d0bSHerbert Xu /*************************************** 297*2a598d0bSHerbert Xu ************** HPPA ***************** 298*2a598d0bSHerbert Xu ***************************************/ 299*2a598d0bSHerbert Xu #if defined(__hppa) && W_TYPE_SIZE == 32 300*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 301*2a598d0bSHerbert Xu __asm__ ("add %4,%5,%1\n" \ 302*2a598d0bSHerbert Xu "addc %2,%3,%0" \ 303*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 304*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 305*2a598d0bSHerbert Xu : "%rM" ((USItype)(ah)), \ 306*2a598d0bSHerbert Xu "rM" ((USItype)(bh)), \ 307*2a598d0bSHerbert Xu "%rM" ((USItype)(al)), \ 308*2a598d0bSHerbert Xu "rM" ((USItype)(bl))) 309*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 310*2a598d0bSHerbert Xu __asm__ ("sub %4,%5,%1\n" \ 311*2a598d0bSHerbert Xu "subb %2,%3,%0" \ 312*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 313*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 314*2a598d0bSHerbert Xu : "rM" ((USItype)(ah)), \ 315*2a598d0bSHerbert Xu "rM" ((USItype)(bh)), \ 316*2a598d0bSHerbert Xu "rM" ((USItype)(al)), \ 317*2a598d0bSHerbert Xu "rM" ((USItype)(bl))) 318*2a598d0bSHerbert Xu #if 0 && defined(_PA_RISC1_1) 319*2a598d0bSHerbert Xu /* xmpyu uses floating point register which is not allowed in Linux kernel. */ 320*2a598d0bSHerbert Xu #define umul_ppmm(wh, wl, u, v) \ 321*2a598d0bSHerbert Xu do { \ 322*2a598d0bSHerbert Xu union {UDItype __ll; \ 323*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 324*2a598d0bSHerbert Xu } __xx; \ 325*2a598d0bSHerbert Xu __asm__ ("xmpyu %1,%2,%0" \ 326*2a598d0bSHerbert Xu : "=*f" (__xx.__ll) \ 327*2a598d0bSHerbert Xu : "*f" ((USItype)(u)), \ 328*2a598d0bSHerbert Xu "*f" ((USItype)(v))); \ 329*2a598d0bSHerbert Xu (wh) = __xx.__i.__h; \ 330*2a598d0bSHerbert Xu (wl) = __xx.__i.__l; \ 331*2a598d0bSHerbert Xu } while (0) 332*2a598d0bSHerbert Xu #define UMUL_TIME 8 333*2a598d0bSHerbert Xu #define UDIV_TIME 60 334*2a598d0bSHerbert Xu #else 335*2a598d0bSHerbert Xu #define UMUL_TIME 40 336*2a598d0bSHerbert Xu #define UDIV_TIME 80 337*2a598d0bSHerbert Xu #endif 338*2a598d0bSHerbert Xu #if 0 /* #ifndef LONGLONG_STANDALONE */ 339*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 340*2a598d0bSHerbert Xu do { USItype __r; \ 341*2a598d0bSHerbert Xu (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ 342*2a598d0bSHerbert Xu (r) = __r; \ 343*2a598d0bSHerbert Xu } while (0) 344*2a598d0bSHerbert Xu extern USItype __udiv_qrnnd(); 345*2a598d0bSHerbert Xu #endif /* LONGLONG_STANDALONE */ 346*2a598d0bSHerbert Xu #endif /* hppa */ 347*2a598d0bSHerbert Xu 348*2a598d0bSHerbert Xu /*************************************** 349*2a598d0bSHerbert Xu ************** I370 ***************** 350*2a598d0bSHerbert Xu ***************************************/ 351*2a598d0bSHerbert Xu #if (defined(__i370__) || defined(__mvs__)) && W_TYPE_SIZE == 32 352*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, m0, m1) \ 353*2a598d0bSHerbert Xu do { \ 354*2a598d0bSHerbert Xu union {UDItype __ll; \ 355*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 356*2a598d0bSHerbert Xu } __xx; \ 357*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 358*2a598d0bSHerbert Xu __asm__ ("mr %0,%3" \ 359*2a598d0bSHerbert Xu : "=r" (__xx.__i.__h), \ 360*2a598d0bSHerbert Xu "=r" (__xx.__i.__l) \ 361*2a598d0bSHerbert Xu : "%1" (__m0), \ 362*2a598d0bSHerbert Xu "r" (__m1)); \ 363*2a598d0bSHerbert Xu (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 364*2a598d0bSHerbert Xu (xh) += ((((SItype) __m0 >> 31) & __m1) \ 365*2a598d0bSHerbert Xu + (((SItype) __m1 >> 31) & __m0)); \ 366*2a598d0bSHerbert Xu } while (0) 367*2a598d0bSHerbert Xu #define smul_ppmm(xh, xl, m0, m1) \ 368*2a598d0bSHerbert Xu do { \ 369*2a598d0bSHerbert Xu union {DItype __ll; \ 370*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 371*2a598d0bSHerbert Xu } __xx; \ 372*2a598d0bSHerbert Xu __asm__ ("mr %0,%3" \ 373*2a598d0bSHerbert Xu : "=r" (__xx.__i.__h), \ 374*2a598d0bSHerbert Xu "=r" (__xx.__i.__l) \ 375*2a598d0bSHerbert Xu : "%1" (m0), \ 376*2a598d0bSHerbert Xu "r" (m1)); \ 377*2a598d0bSHerbert Xu (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 378*2a598d0bSHerbert Xu } while (0) 379*2a598d0bSHerbert Xu #define sdiv_qrnnd(q, r, n1, n0, d) \ 380*2a598d0bSHerbert Xu do { \ 381*2a598d0bSHerbert Xu union {DItype __ll; \ 382*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 383*2a598d0bSHerbert Xu } __xx; \ 384*2a598d0bSHerbert Xu __xx.__i.__h = n1; __xx.__i.__l = n0; \ 385*2a598d0bSHerbert Xu __asm__ ("dr %0,%2" \ 386*2a598d0bSHerbert Xu : "=r" (__xx.__ll) \ 387*2a598d0bSHerbert Xu : "0" (__xx.__ll), "r" (d)); \ 388*2a598d0bSHerbert Xu (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ 389*2a598d0bSHerbert Xu } while (0) 390*2a598d0bSHerbert Xu #endif 391*2a598d0bSHerbert Xu 392*2a598d0bSHerbert Xu /*************************************** 393*2a598d0bSHerbert Xu ************** I386 ***************** 394*2a598d0bSHerbert Xu ***************************************/ 395*2a598d0bSHerbert Xu #undef __i386__ 396*2a598d0bSHerbert Xu #if (defined(__i386__) || defined(__i486__)) && W_TYPE_SIZE == 32 397*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 398*2a598d0bSHerbert Xu __asm__ ("addl %5,%1\n" \ 399*2a598d0bSHerbert Xu "adcl %3,%0" \ 400*2a598d0bSHerbert Xu : "=r" (sh), \ 401*2a598d0bSHerbert Xu "=&r" (sl) \ 402*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 403*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 404*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 405*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 406*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 407*2a598d0bSHerbert Xu __asm__ ("subl %5,%1\n" \ 408*2a598d0bSHerbert Xu "sbbl %3,%0" \ 409*2a598d0bSHerbert Xu : "=r" (sh), \ 410*2a598d0bSHerbert Xu "=&r" (sl) \ 411*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 412*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 413*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 414*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 415*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 416*2a598d0bSHerbert Xu __asm__ ("mull %3" \ 417*2a598d0bSHerbert Xu : "=a" (w0), \ 418*2a598d0bSHerbert Xu "=d" (w1) \ 419*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 420*2a598d0bSHerbert Xu "rm" ((USItype)(v))) 421*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 422*2a598d0bSHerbert Xu __asm__ ("divl %4" \ 423*2a598d0bSHerbert Xu : "=a" (q), \ 424*2a598d0bSHerbert Xu "=d" (r) \ 425*2a598d0bSHerbert Xu : "0" ((USItype)(n0)), \ 426*2a598d0bSHerbert Xu "1" ((USItype)(n1)), \ 427*2a598d0bSHerbert Xu "rm" ((USItype)(d))) 428*2a598d0bSHerbert Xu #ifndef UMUL_TIME 429*2a598d0bSHerbert Xu #define UMUL_TIME 40 430*2a598d0bSHerbert Xu #endif 431*2a598d0bSHerbert Xu #ifndef UDIV_TIME 432*2a598d0bSHerbert Xu #define UDIV_TIME 40 433*2a598d0bSHerbert Xu #endif 434*2a598d0bSHerbert Xu #endif /* 80x86 */ 435*2a598d0bSHerbert Xu 436*2a598d0bSHerbert Xu /*************************************** 437*2a598d0bSHerbert Xu ************** I860 ***************** 438*2a598d0bSHerbert Xu ***************************************/ 439*2a598d0bSHerbert Xu #if defined(__i860__) && W_TYPE_SIZE == 32 440*2a598d0bSHerbert Xu #define rshift_rhlc(r, h, l, c) \ 441*2a598d0bSHerbert Xu __asm__ ("shr %3,r0,r0\n" \ 442*2a598d0bSHerbert Xu "shrd %1,%2,%0" \ 443*2a598d0bSHerbert Xu "=r" (r) : "r" (h), "r" (l), "rn" (c)) 444*2a598d0bSHerbert Xu #endif /* i860 */ 445*2a598d0bSHerbert Xu 446*2a598d0bSHerbert Xu /*************************************** 447*2a598d0bSHerbert Xu ************** I960 ***************** 448*2a598d0bSHerbert Xu ***************************************/ 449*2a598d0bSHerbert Xu #if defined(__i960__) && W_TYPE_SIZE == 32 450*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 451*2a598d0bSHerbert Xu __asm__ ("cmpo 1,0\n" \ 452*2a598d0bSHerbert Xu "addc %5,%4,%1\n" \ 453*2a598d0bSHerbert Xu "addc %3,%2,%0" \ 454*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 455*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 456*2a598d0bSHerbert Xu : "%dI" ((USItype)(ah)), \ 457*2a598d0bSHerbert Xu "dI" ((USItype)(bh)), \ 458*2a598d0bSHerbert Xu "%dI" ((USItype)(al)), \ 459*2a598d0bSHerbert Xu "dI" ((USItype)(bl))) 460*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 461*2a598d0bSHerbert Xu __asm__ ("cmpo 0,0\n" \ 462*2a598d0bSHerbert Xu "subc %5,%4,%1\n" \ 463*2a598d0bSHerbert Xu "subc %3,%2,%0" \ 464*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 465*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 466*2a598d0bSHerbert Xu : "dI" ((USItype)(ah)), \ 467*2a598d0bSHerbert Xu "dI" ((USItype)(bh)), \ 468*2a598d0bSHerbert Xu "dI" ((USItype)(al)), \ 469*2a598d0bSHerbert Xu "dI" ((USItype)(bl))) 470*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 471*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 472*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 473*2a598d0bSHerbert Xu } __xx; \ 474*2a598d0bSHerbert Xu __asm__ ("emul %2,%1,%0" \ 475*2a598d0bSHerbert Xu : "=d" (__xx.__ll) \ 476*2a598d0bSHerbert Xu : "%dI" ((USItype)(u)), \ 477*2a598d0bSHerbert Xu "dI" ((USItype)(v))); \ 478*2a598d0bSHerbert Xu (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; }) 479*2a598d0bSHerbert Xu #define __umulsidi3(u, v) \ 480*2a598d0bSHerbert Xu ({UDItype __w; \ 481*2a598d0bSHerbert Xu __asm__ ("emul %2,%1,%0" \ 482*2a598d0bSHerbert Xu : "=d" (__w) \ 483*2a598d0bSHerbert Xu : "%dI" ((USItype)(u)), \ 484*2a598d0bSHerbert Xu "dI" ((USItype)(v))); \ 485*2a598d0bSHerbert Xu __w; }) 486*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, nh, nl, d) \ 487*2a598d0bSHerbert Xu do { \ 488*2a598d0bSHerbert Xu union {UDItype __ll; \ 489*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 490*2a598d0bSHerbert Xu } __nn; \ 491*2a598d0bSHerbert Xu __nn.__i.__h = (nh); __nn.__i.__l = (nl); \ 492*2a598d0bSHerbert Xu __asm__ ("ediv %d,%n,%0" \ 493*2a598d0bSHerbert Xu : "=d" (__rq.__ll) \ 494*2a598d0bSHerbert Xu : "dI" (__nn.__ll), \ 495*2a598d0bSHerbert Xu "dI" ((USItype)(d))); \ 496*2a598d0bSHerbert Xu (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ 497*2a598d0bSHerbert Xu } while (0) 498*2a598d0bSHerbert Xu #if defined(__i960mx) /* what is the proper symbol to test??? */ 499*2a598d0bSHerbert Xu #define rshift_rhlc(r, h, l, c) \ 500*2a598d0bSHerbert Xu do { \ 501*2a598d0bSHerbert Xu union {UDItype __ll; \ 502*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 503*2a598d0bSHerbert Xu } __nn; \ 504*2a598d0bSHerbert Xu __nn.__i.__h = (h); __nn.__i.__l = (l); \ 505*2a598d0bSHerbert Xu __asm__ ("shre %2,%1,%0" \ 506*2a598d0bSHerbert Xu : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \ 507*2a598d0bSHerbert Xu } 508*2a598d0bSHerbert Xu #endif /* i960mx */ 509*2a598d0bSHerbert Xu #endif /* i960 */ 510*2a598d0bSHerbert Xu 511*2a598d0bSHerbert Xu /*************************************** 512*2a598d0bSHerbert Xu ************** 68000 **************** 513*2a598d0bSHerbert Xu ***************************************/ 514*2a598d0bSHerbert Xu #if (defined(__mc68000__) || defined(__mc68020__) || defined(__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 515*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 516*2a598d0bSHerbert Xu __asm__ ("add%.l %5,%1\n" \ 517*2a598d0bSHerbert Xu "addx%.l %3,%0" \ 518*2a598d0bSHerbert Xu : "=d" ((USItype)(sh)), \ 519*2a598d0bSHerbert Xu "=&d" ((USItype)(sl)) \ 520*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 521*2a598d0bSHerbert Xu "d" ((USItype)(bh)), \ 522*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 523*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 524*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 525*2a598d0bSHerbert Xu __asm__ ("sub%.l %5,%1\n" \ 526*2a598d0bSHerbert Xu "subx%.l %3,%0" \ 527*2a598d0bSHerbert Xu : "=d" ((USItype)(sh)), \ 528*2a598d0bSHerbert Xu "=&d" ((USItype)(sl)) \ 529*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 530*2a598d0bSHerbert Xu "d" ((USItype)(bh)), \ 531*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 532*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 533*2a598d0bSHerbert Xu #if (defined(__mc68020__) || defined(__NeXT__) || defined(mc68020)) 534*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 535*2a598d0bSHerbert Xu __asm__ ("mulu%.l %3,%1:%0" \ 536*2a598d0bSHerbert Xu : "=d" ((USItype)(w0)), \ 537*2a598d0bSHerbert Xu "=d" ((USItype)(w1)) \ 538*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 539*2a598d0bSHerbert Xu "dmi" ((USItype)(v))) 540*2a598d0bSHerbert Xu #define UMUL_TIME 45 541*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 542*2a598d0bSHerbert Xu __asm__ ("divu%.l %4,%1:%0" \ 543*2a598d0bSHerbert Xu : "=d" ((USItype)(q)), \ 544*2a598d0bSHerbert Xu "=d" ((USItype)(r)) \ 545*2a598d0bSHerbert Xu : "0" ((USItype)(n0)), \ 546*2a598d0bSHerbert Xu "1" ((USItype)(n1)), \ 547*2a598d0bSHerbert Xu "dmi" ((USItype)(d))) 548*2a598d0bSHerbert Xu #define UDIV_TIME 90 549*2a598d0bSHerbert Xu #define sdiv_qrnnd(q, r, n1, n0, d) \ 550*2a598d0bSHerbert Xu __asm__ ("divs%.l %4,%1:%0" \ 551*2a598d0bSHerbert Xu : "=d" ((USItype)(q)), \ 552*2a598d0bSHerbert Xu "=d" ((USItype)(r)) \ 553*2a598d0bSHerbert Xu : "0" ((USItype)(n0)), \ 554*2a598d0bSHerbert Xu "1" ((USItype)(n1)), \ 555*2a598d0bSHerbert Xu "dmi" ((USItype)(d))) 556*2a598d0bSHerbert Xu #else /* not mc68020 */ 557*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, a, b) \ 558*2a598d0bSHerbert Xu do { USItype __umul_tmp1, __umul_tmp2; \ 559*2a598d0bSHerbert Xu __asm__ ("| Inlined umul_ppmm\n" \ 560*2a598d0bSHerbert Xu "move%.l %5,%3\n" \ 561*2a598d0bSHerbert Xu "move%.l %2,%0\n" \ 562*2a598d0bSHerbert Xu "move%.w %3,%1\n" \ 563*2a598d0bSHerbert Xu "swap %3\n" \ 564*2a598d0bSHerbert Xu "swap %0\n" \ 565*2a598d0bSHerbert Xu "mulu %2,%1\n" \ 566*2a598d0bSHerbert Xu "mulu %3,%0\n" \ 567*2a598d0bSHerbert Xu "mulu %2,%3\n" \ 568*2a598d0bSHerbert Xu "swap %2\n" \ 569*2a598d0bSHerbert Xu "mulu %5,%2\n" \ 570*2a598d0bSHerbert Xu "add%.l %3,%2\n" \ 571*2a598d0bSHerbert Xu "jcc 1f\n" \ 572*2a598d0bSHerbert Xu "add%.l %#0x10000,%0\n" \ 573*2a598d0bSHerbert Xu "1: move%.l %2,%3\n" \ 574*2a598d0bSHerbert Xu "clr%.w %2\n" \ 575*2a598d0bSHerbert Xu "swap %2\n" \ 576*2a598d0bSHerbert Xu "swap %3\n" \ 577*2a598d0bSHerbert Xu "clr%.w %3\n" \ 578*2a598d0bSHerbert Xu "add%.l %3,%1\n" \ 579*2a598d0bSHerbert Xu "addx%.l %2,%0\n" \ 580*2a598d0bSHerbert Xu "| End inlined umul_ppmm" \ 581*2a598d0bSHerbert Xu : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \ 582*2a598d0bSHerbert Xu "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ 583*2a598d0bSHerbert Xu : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ 584*2a598d0bSHerbert Xu } while (0) 585*2a598d0bSHerbert Xu #define UMUL_TIME 100 586*2a598d0bSHerbert Xu #define UDIV_TIME 400 587*2a598d0bSHerbert Xu #endif /* not mc68020 */ 588*2a598d0bSHerbert Xu #endif /* mc68000 */ 589*2a598d0bSHerbert Xu 590*2a598d0bSHerbert Xu /*************************************** 591*2a598d0bSHerbert Xu ************** 88000 **************** 592*2a598d0bSHerbert Xu ***************************************/ 593*2a598d0bSHerbert Xu #if defined(__m88000__) && W_TYPE_SIZE == 32 594*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 595*2a598d0bSHerbert Xu __asm__ ("addu.co %1,%r4,%r5\n" \ 596*2a598d0bSHerbert Xu "addu.ci %0,%r2,%r3" \ 597*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 598*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 599*2a598d0bSHerbert Xu : "%rJ" ((USItype)(ah)), \ 600*2a598d0bSHerbert Xu "rJ" ((USItype)(bh)), \ 601*2a598d0bSHerbert Xu "%rJ" ((USItype)(al)), \ 602*2a598d0bSHerbert Xu "rJ" ((USItype)(bl))) 603*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 604*2a598d0bSHerbert Xu __asm__ ("subu.co %1,%r4,%r5\n" \ 605*2a598d0bSHerbert Xu "subu.ci %0,%r2,%r3" \ 606*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 607*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 608*2a598d0bSHerbert Xu : "rJ" ((USItype)(ah)), \ 609*2a598d0bSHerbert Xu "rJ" ((USItype)(bh)), \ 610*2a598d0bSHerbert Xu "rJ" ((USItype)(al)), \ 611*2a598d0bSHerbert Xu "rJ" ((USItype)(bl))) 612*2a598d0bSHerbert Xu #if defined(__m88110__) 613*2a598d0bSHerbert Xu #define umul_ppmm(wh, wl, u, v) \ 614*2a598d0bSHerbert Xu do { \ 615*2a598d0bSHerbert Xu union {UDItype __ll; \ 616*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 617*2a598d0bSHerbert Xu } __x; \ 618*2a598d0bSHerbert Xu __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \ 619*2a598d0bSHerbert Xu (wh) = __x.__i.__h; \ 620*2a598d0bSHerbert Xu (wl) = __x.__i.__l; \ 621*2a598d0bSHerbert Xu } while (0) 622*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 623*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 624*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 625*2a598d0bSHerbert Xu } __x, __q; \ 626*2a598d0bSHerbert Xu __x.__i.__h = (n1); __x.__i.__l = (n0); \ 627*2a598d0bSHerbert Xu __asm__ ("divu.d %0,%1,%2" \ 628*2a598d0bSHerbert Xu : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \ 629*2a598d0bSHerbert Xu (r) = (n0) - __q.__l * (d); (q) = __q.__l; }) 630*2a598d0bSHerbert Xu #define UMUL_TIME 5 631*2a598d0bSHerbert Xu #define UDIV_TIME 25 632*2a598d0bSHerbert Xu #else 633*2a598d0bSHerbert Xu #define UMUL_TIME 17 634*2a598d0bSHerbert Xu #define UDIV_TIME 150 635*2a598d0bSHerbert Xu #endif /* __m88110__ */ 636*2a598d0bSHerbert Xu #endif /* __m88000__ */ 637*2a598d0bSHerbert Xu 638*2a598d0bSHerbert Xu /*************************************** 639*2a598d0bSHerbert Xu ************** MIPS ***************** 640*2a598d0bSHerbert Xu ***************************************/ 641*2a598d0bSHerbert Xu #if defined(__mips__) && W_TYPE_SIZE == 32 642*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 643*2a598d0bSHerbert Xu do { \ 644*2a598d0bSHerbert Xu UDItype __ll = (UDItype)(u) * (v); \ 645*2a598d0bSHerbert Xu w1 = __ll >> 32; \ 646*2a598d0bSHerbert Xu w0 = __ll; \ 647*2a598d0bSHerbert Xu } while (0) 648*2a598d0bSHerbert Xu #define UMUL_TIME 10 649*2a598d0bSHerbert Xu #define UDIV_TIME 100 650*2a598d0bSHerbert Xu #endif /* __mips__ */ 651*2a598d0bSHerbert Xu 652*2a598d0bSHerbert Xu /*************************************** 653*2a598d0bSHerbert Xu ************** MIPS/64 ************** 654*2a598d0bSHerbert Xu ***************************************/ 655*2a598d0bSHerbert Xu #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 656*2a598d0bSHerbert Xu #if defined(__mips_isa_rev) && __mips_isa_rev >= 6 && defined(CONFIG_CC_IS_GCC) 657*2a598d0bSHerbert Xu /* 658*2a598d0bSHerbert Xu * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C 659*2a598d0bSHerbert Xu * code below, so we special case MIPS64r6 until the compiler can do better. 660*2a598d0bSHerbert Xu */ 661*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 662*2a598d0bSHerbert Xu do { \ 663*2a598d0bSHerbert Xu __asm__ ("dmulu %0,%1,%2" \ 664*2a598d0bSHerbert Xu : "=d" ((UDItype)(w0)) \ 665*2a598d0bSHerbert Xu : "d" ((UDItype)(u)), \ 666*2a598d0bSHerbert Xu "d" ((UDItype)(v))); \ 667*2a598d0bSHerbert Xu __asm__ ("dmuhu %0,%1,%2" \ 668*2a598d0bSHerbert Xu : "=d" ((UDItype)(w1)) \ 669*2a598d0bSHerbert Xu : "d" ((UDItype)(u)), \ 670*2a598d0bSHerbert Xu "d" ((UDItype)(v))); \ 671*2a598d0bSHerbert Xu } while (0) 672*2a598d0bSHerbert Xu #else 673*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 674*2a598d0bSHerbert Xu do { \ 675*2a598d0bSHerbert Xu typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ 676*2a598d0bSHerbert Xu __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ 677*2a598d0bSHerbert Xu w1 = __ll >> 64; \ 678*2a598d0bSHerbert Xu w0 = __ll; \ 679*2a598d0bSHerbert Xu } while (0) 680*2a598d0bSHerbert Xu #endif 681*2a598d0bSHerbert Xu #define UMUL_TIME 20 682*2a598d0bSHerbert Xu #define UDIV_TIME 140 683*2a598d0bSHerbert Xu #endif /* __mips__ */ 684*2a598d0bSHerbert Xu 685*2a598d0bSHerbert Xu /*************************************** 686*2a598d0bSHerbert Xu ************** 32000 **************** 687*2a598d0bSHerbert Xu ***************************************/ 688*2a598d0bSHerbert Xu #if defined(__ns32000__) && W_TYPE_SIZE == 32 689*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 690*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 691*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 692*2a598d0bSHerbert Xu } __xx; \ 693*2a598d0bSHerbert Xu __asm__ ("meid %2,%0" \ 694*2a598d0bSHerbert Xu : "=g" (__xx.__ll) \ 695*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 696*2a598d0bSHerbert Xu "g" ((USItype)(v))); \ 697*2a598d0bSHerbert Xu (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; }) 698*2a598d0bSHerbert Xu #define __umulsidi3(u, v) \ 699*2a598d0bSHerbert Xu ({UDItype __w; \ 700*2a598d0bSHerbert Xu __asm__ ("meid %2,%0" \ 701*2a598d0bSHerbert Xu : "=g" (__w) \ 702*2a598d0bSHerbert Xu : "%0" ((USItype)(u)), \ 703*2a598d0bSHerbert Xu "g" ((USItype)(v))); \ 704*2a598d0bSHerbert Xu __w; }) 705*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 706*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 707*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 708*2a598d0bSHerbert Xu } __xx; \ 709*2a598d0bSHerbert Xu __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ 710*2a598d0bSHerbert Xu __asm__ ("deid %2,%0" \ 711*2a598d0bSHerbert Xu : "=g" (__xx.__ll) \ 712*2a598d0bSHerbert Xu : "0" (__xx.__ll), \ 713*2a598d0bSHerbert Xu "g" ((USItype)(d))); \ 714*2a598d0bSHerbert Xu (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) 715*2a598d0bSHerbert Xu #endif /* __ns32000__ */ 716*2a598d0bSHerbert Xu 717*2a598d0bSHerbert Xu /*************************************** 718*2a598d0bSHerbert Xu ************** PPC ****************** 719*2a598d0bSHerbert Xu ***************************************/ 720*2a598d0bSHerbert Xu #if (defined(_ARCH_PPC) || defined(_IBMR2)) && W_TYPE_SIZE == 32 721*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 722*2a598d0bSHerbert Xu do { \ 723*2a598d0bSHerbert Xu if (__builtin_constant_p(bh) && (bh) == 0) \ 724*2a598d0bSHerbert Xu __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ 725*2a598d0bSHerbert Xu : "=r" (sh), \ 726*2a598d0bSHerbert Xu "=&r" (sl) \ 727*2a598d0bSHerbert Xu : "%r" ((USItype)(ah)), \ 728*2a598d0bSHerbert Xu "%r" ((USItype)(al)), \ 729*2a598d0bSHerbert Xu "rI" ((USItype)(bl))); \ 730*2a598d0bSHerbert Xu else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \ 731*2a598d0bSHerbert Xu __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ 732*2a598d0bSHerbert Xu : "=r" (sh), \ 733*2a598d0bSHerbert Xu "=&r" (sl) \ 734*2a598d0bSHerbert Xu : "%r" ((USItype)(ah)), \ 735*2a598d0bSHerbert Xu "%r" ((USItype)(al)), \ 736*2a598d0bSHerbert Xu "rI" ((USItype)(bl))); \ 737*2a598d0bSHerbert Xu else \ 738*2a598d0bSHerbert Xu __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ 739*2a598d0bSHerbert Xu : "=r" (sh), \ 740*2a598d0bSHerbert Xu "=&r" (sl) \ 741*2a598d0bSHerbert Xu : "%r" ((USItype)(ah)), \ 742*2a598d0bSHerbert Xu "r" ((USItype)(bh)), \ 743*2a598d0bSHerbert Xu "%r" ((USItype)(al)), \ 744*2a598d0bSHerbert Xu "rI" ((USItype)(bl))); \ 745*2a598d0bSHerbert Xu } while (0) 746*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 747*2a598d0bSHerbert Xu do { \ 748*2a598d0bSHerbert Xu if (__builtin_constant_p(ah) && (ah) == 0) \ 749*2a598d0bSHerbert Xu __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ 750*2a598d0bSHerbert Xu : "=r" (sh), \ 751*2a598d0bSHerbert Xu "=&r" (sl) \ 752*2a598d0bSHerbert Xu : "r" ((USItype)(bh)), \ 753*2a598d0bSHerbert Xu "rI" ((USItype)(al)), \ 754*2a598d0bSHerbert Xu "r" ((USItype)(bl))); \ 755*2a598d0bSHerbert Xu else if (__builtin_constant_p(ah) && (ah) == ~(USItype) 0) \ 756*2a598d0bSHerbert Xu __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ 757*2a598d0bSHerbert Xu : "=r" (sh), \ 758*2a598d0bSHerbert Xu "=&r" (sl) \ 759*2a598d0bSHerbert Xu : "r" ((USItype)(bh)), \ 760*2a598d0bSHerbert Xu "rI" ((USItype)(al)), \ 761*2a598d0bSHerbert Xu "r" ((USItype)(bl))); \ 762*2a598d0bSHerbert Xu else if (__builtin_constant_p(bh) && (bh) == 0) \ 763*2a598d0bSHerbert Xu __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ 764*2a598d0bSHerbert Xu : "=r" (sh), \ 765*2a598d0bSHerbert Xu "=&r" (sl) \ 766*2a598d0bSHerbert Xu : "r" ((USItype)(ah)), \ 767*2a598d0bSHerbert Xu "rI" ((USItype)(al)), \ 768*2a598d0bSHerbert Xu "r" ((USItype)(bl))); \ 769*2a598d0bSHerbert Xu else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \ 770*2a598d0bSHerbert Xu __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ 771*2a598d0bSHerbert Xu : "=r" (sh), \ 772*2a598d0bSHerbert Xu "=&r" (sl) \ 773*2a598d0bSHerbert Xu : "r" ((USItype)(ah)), \ 774*2a598d0bSHerbert Xu "rI" ((USItype)(al)), \ 775*2a598d0bSHerbert Xu "r" ((USItype)(bl))); \ 776*2a598d0bSHerbert Xu else \ 777*2a598d0bSHerbert Xu __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ 778*2a598d0bSHerbert Xu : "=r" (sh), \ 779*2a598d0bSHerbert Xu "=&r" (sl) \ 780*2a598d0bSHerbert Xu : "r" ((USItype)(ah)), \ 781*2a598d0bSHerbert Xu "r" ((USItype)(bh)), \ 782*2a598d0bSHerbert Xu "rI" ((USItype)(al)), \ 783*2a598d0bSHerbert Xu "r" ((USItype)(bl))); \ 784*2a598d0bSHerbert Xu } while (0) 785*2a598d0bSHerbert Xu #if defined(_ARCH_PPC) 786*2a598d0bSHerbert Xu #define umul_ppmm(ph, pl, m0, m1) \ 787*2a598d0bSHerbert Xu do { \ 788*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 789*2a598d0bSHerbert Xu __asm__ ("mulhwu %0,%1,%2" \ 790*2a598d0bSHerbert Xu : "=r" (ph) \ 791*2a598d0bSHerbert Xu : "%r" (__m0), \ 792*2a598d0bSHerbert Xu "r" (__m1)); \ 793*2a598d0bSHerbert Xu (pl) = __m0 * __m1; \ 794*2a598d0bSHerbert Xu } while (0) 795*2a598d0bSHerbert Xu #define UMUL_TIME 15 796*2a598d0bSHerbert Xu #define smul_ppmm(ph, pl, m0, m1) \ 797*2a598d0bSHerbert Xu do { \ 798*2a598d0bSHerbert Xu SItype __m0 = (m0), __m1 = (m1); \ 799*2a598d0bSHerbert Xu __asm__ ("mulhw %0,%1,%2" \ 800*2a598d0bSHerbert Xu : "=r" ((SItype) ph) \ 801*2a598d0bSHerbert Xu : "%r" (__m0), \ 802*2a598d0bSHerbert Xu "r" (__m1)); \ 803*2a598d0bSHerbert Xu (pl) = __m0 * __m1; \ 804*2a598d0bSHerbert Xu } while (0) 805*2a598d0bSHerbert Xu #define SMUL_TIME 14 806*2a598d0bSHerbert Xu #define UDIV_TIME 120 807*2a598d0bSHerbert Xu #else 808*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, m0, m1) \ 809*2a598d0bSHerbert Xu do { \ 810*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 811*2a598d0bSHerbert Xu __asm__ ("mul %0,%2,%3" \ 812*2a598d0bSHerbert Xu : "=r" ((USItype)(xh)), \ 813*2a598d0bSHerbert Xu "=q" ((USItype)(xl)) \ 814*2a598d0bSHerbert Xu : "r" (__m0), \ 815*2a598d0bSHerbert Xu "r" (__m1)); \ 816*2a598d0bSHerbert Xu (xh) += ((((SItype) __m0 >> 31) & __m1) \ 817*2a598d0bSHerbert Xu + (((SItype) __m1 >> 31) & __m0)); \ 818*2a598d0bSHerbert Xu } while (0) 819*2a598d0bSHerbert Xu #define UMUL_TIME 8 820*2a598d0bSHerbert Xu #define smul_ppmm(xh, xl, m0, m1) \ 821*2a598d0bSHerbert Xu __asm__ ("mul %0,%2,%3" \ 822*2a598d0bSHerbert Xu : "=r" ((SItype)(xh)), \ 823*2a598d0bSHerbert Xu "=q" ((SItype)(xl)) \ 824*2a598d0bSHerbert Xu : "r" (m0), \ 825*2a598d0bSHerbert Xu "r" (m1)) 826*2a598d0bSHerbert Xu #define SMUL_TIME 4 827*2a598d0bSHerbert Xu #define sdiv_qrnnd(q, r, nh, nl, d) \ 828*2a598d0bSHerbert Xu __asm__ ("div %0,%2,%4" \ 829*2a598d0bSHerbert Xu : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ 830*2a598d0bSHerbert Xu : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) 831*2a598d0bSHerbert Xu #define UDIV_TIME 100 832*2a598d0bSHerbert Xu #endif 833*2a598d0bSHerbert Xu #endif /* Power architecture variants. */ 834*2a598d0bSHerbert Xu 835*2a598d0bSHerbert Xu /*************************************** 836*2a598d0bSHerbert Xu ************** PYR ****************** 837*2a598d0bSHerbert Xu ***************************************/ 838*2a598d0bSHerbert Xu #if defined(__pyr__) && W_TYPE_SIZE == 32 839*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 840*2a598d0bSHerbert Xu __asm__ ("addw %5,%1\n" \ 841*2a598d0bSHerbert Xu "addwc %3,%0" \ 842*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 843*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 844*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 845*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 846*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 847*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 848*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 849*2a598d0bSHerbert Xu __asm__ ("subw %5,%1\n" \ 850*2a598d0bSHerbert Xu "subwb %3,%0" \ 851*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 852*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 853*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 854*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 855*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 856*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 857*2a598d0bSHerbert Xu /* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ 858*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 859*2a598d0bSHerbert Xu ({union {UDItype __ll; \ 860*2a598d0bSHerbert Xu struct {USItype __h, __l; } __i; \ 861*2a598d0bSHerbert Xu } __xx; \ 862*2a598d0bSHerbert Xu __asm__ ("movw %1,%R0\n" \ 863*2a598d0bSHerbert Xu "uemul %2,%0" \ 864*2a598d0bSHerbert Xu : "=&r" (__xx.__ll) \ 865*2a598d0bSHerbert Xu : "g" ((USItype) (u)), \ 866*2a598d0bSHerbert Xu "g" ((USItype)(v))); \ 867*2a598d0bSHerbert Xu (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; }) 868*2a598d0bSHerbert Xu #endif /* __pyr__ */ 869*2a598d0bSHerbert Xu 870*2a598d0bSHerbert Xu /*************************************** 871*2a598d0bSHerbert Xu ************** RT/ROMP ************** 872*2a598d0bSHerbert Xu ***************************************/ 873*2a598d0bSHerbert Xu #if defined(__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 874*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 875*2a598d0bSHerbert Xu __asm__ ("a %1,%5\n" \ 876*2a598d0bSHerbert Xu "ae %0,%3" \ 877*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 878*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 879*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 880*2a598d0bSHerbert Xu "r" ((USItype)(bh)), \ 881*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 882*2a598d0bSHerbert Xu "r" ((USItype)(bl))) 883*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 884*2a598d0bSHerbert Xu __asm__ ("s %1,%5\n" \ 885*2a598d0bSHerbert Xu "se %0,%3" \ 886*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 887*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 888*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 889*2a598d0bSHerbert Xu "r" ((USItype)(bh)), \ 890*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 891*2a598d0bSHerbert Xu "r" ((USItype)(bl))) 892*2a598d0bSHerbert Xu #define umul_ppmm(ph, pl, m0, m1) \ 893*2a598d0bSHerbert Xu do { \ 894*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 895*2a598d0bSHerbert Xu __asm__ ( \ 896*2a598d0bSHerbert Xu "s r2,r2\n" \ 897*2a598d0bSHerbert Xu "mts r10,%2\n" \ 898*2a598d0bSHerbert Xu "m r2,%3\n" \ 899*2a598d0bSHerbert Xu "m r2,%3\n" \ 900*2a598d0bSHerbert Xu "m r2,%3\n" \ 901*2a598d0bSHerbert Xu "m r2,%3\n" \ 902*2a598d0bSHerbert Xu "m r2,%3\n" \ 903*2a598d0bSHerbert Xu "m r2,%3\n" \ 904*2a598d0bSHerbert Xu "m r2,%3\n" \ 905*2a598d0bSHerbert Xu "m r2,%3\n" \ 906*2a598d0bSHerbert Xu "m r2,%3\n" \ 907*2a598d0bSHerbert Xu "m r2,%3\n" \ 908*2a598d0bSHerbert Xu "m r2,%3\n" \ 909*2a598d0bSHerbert Xu "m r2,%3\n" \ 910*2a598d0bSHerbert Xu "m r2,%3\n" \ 911*2a598d0bSHerbert Xu "m r2,%3\n" \ 912*2a598d0bSHerbert Xu "m r2,%3\n" \ 913*2a598d0bSHerbert Xu "m r2,%3\n" \ 914*2a598d0bSHerbert Xu "cas %0,r2,r0\n" \ 915*2a598d0bSHerbert Xu "mfs r10,%1" \ 916*2a598d0bSHerbert Xu : "=r" ((USItype)(ph)), \ 917*2a598d0bSHerbert Xu "=r" ((USItype)(pl)) \ 918*2a598d0bSHerbert Xu : "%r" (__m0), \ 919*2a598d0bSHerbert Xu "r" (__m1) \ 920*2a598d0bSHerbert Xu : "r2"); \ 921*2a598d0bSHerbert Xu (ph) += ((((SItype) __m0 >> 31) & __m1) \ 922*2a598d0bSHerbert Xu + (((SItype) __m1 >> 31) & __m0)); \ 923*2a598d0bSHerbert Xu } while (0) 924*2a598d0bSHerbert Xu #define UMUL_TIME 20 925*2a598d0bSHerbert Xu #define UDIV_TIME 200 926*2a598d0bSHerbert Xu #endif /* RT/ROMP */ 927*2a598d0bSHerbert Xu 928*2a598d0bSHerbert Xu /*************************************** 929*2a598d0bSHerbert Xu ************** SH2 ****************** 930*2a598d0bSHerbert Xu ***************************************/ 931*2a598d0bSHerbert Xu #if (defined(__sh2__) || defined(__sh3__) || defined(__SH4__)) \ 932*2a598d0bSHerbert Xu && W_TYPE_SIZE == 32 933*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 934*2a598d0bSHerbert Xu __asm__ ( \ 935*2a598d0bSHerbert Xu "dmulu.l %2,%3\n" \ 936*2a598d0bSHerbert Xu "sts macl,%1\n" \ 937*2a598d0bSHerbert Xu "sts mach,%0" \ 938*2a598d0bSHerbert Xu : "=r" ((USItype)(w1)), \ 939*2a598d0bSHerbert Xu "=r" ((USItype)(w0)) \ 940*2a598d0bSHerbert Xu : "r" ((USItype)(u)), \ 941*2a598d0bSHerbert Xu "r" ((USItype)(v)) \ 942*2a598d0bSHerbert Xu : "macl", "mach") 943*2a598d0bSHerbert Xu #define UMUL_TIME 5 944*2a598d0bSHerbert Xu #endif 945*2a598d0bSHerbert Xu 946*2a598d0bSHerbert Xu /*************************************** 947*2a598d0bSHerbert Xu ************** SPARC **************** 948*2a598d0bSHerbert Xu ***************************************/ 949*2a598d0bSHerbert Xu #if defined(__sparc__) && W_TYPE_SIZE == 32 950*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 951*2a598d0bSHerbert Xu __asm__ ("addcc %r4,%5,%1\n" \ 952*2a598d0bSHerbert Xu "addx %r2,%3,%0" \ 953*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 954*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 955*2a598d0bSHerbert Xu : "%rJ" ((USItype)(ah)), \ 956*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 957*2a598d0bSHerbert Xu "%rJ" ((USItype)(al)), \ 958*2a598d0bSHerbert Xu "rI" ((USItype)(bl)) \ 959*2a598d0bSHerbert Xu __CLOBBER_CC) 960*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 961*2a598d0bSHerbert Xu __asm__ ("subcc %r4,%5,%1\n" \ 962*2a598d0bSHerbert Xu "subx %r2,%3,%0" \ 963*2a598d0bSHerbert Xu : "=r" ((USItype)(sh)), \ 964*2a598d0bSHerbert Xu "=&r" ((USItype)(sl)) \ 965*2a598d0bSHerbert Xu : "rJ" ((USItype)(ah)), \ 966*2a598d0bSHerbert Xu "rI" ((USItype)(bh)), \ 967*2a598d0bSHerbert Xu "rJ" ((USItype)(al)), \ 968*2a598d0bSHerbert Xu "rI" ((USItype)(bl)) \ 969*2a598d0bSHerbert Xu __CLOBBER_CC) 970*2a598d0bSHerbert Xu #if defined(__sparc_v8__) 971*2a598d0bSHerbert Xu /* Don't match immediate range because, 1) it is not often useful, 972*2a598d0bSHerbert Xu 2) the 'I' flag thinks of the range as a 13 bit signed interval, 973*2a598d0bSHerbert Xu while we want to match a 13 bit interval, sign extended to 32 bits, 974*2a598d0bSHerbert Xu but INTERPRETED AS UNSIGNED. */ 975*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 976*2a598d0bSHerbert Xu __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 977*2a598d0bSHerbert Xu : "=r" ((USItype)(w1)), \ 978*2a598d0bSHerbert Xu "=r" ((USItype)(w0)) \ 979*2a598d0bSHerbert Xu : "r" ((USItype)(u)), \ 980*2a598d0bSHerbert Xu "r" ((USItype)(v))) 981*2a598d0bSHerbert Xu #define UMUL_TIME 5 982*2a598d0bSHerbert Xu #ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ 983*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 984*2a598d0bSHerbert Xu do { \ 985*2a598d0bSHerbert Xu USItype __q; \ 986*2a598d0bSHerbert Xu __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ 987*2a598d0bSHerbert Xu : "=r" ((USItype)(__q)) \ 988*2a598d0bSHerbert Xu : "r" ((USItype)(n1)), \ 989*2a598d0bSHerbert Xu "r" ((USItype)(n0)), \ 990*2a598d0bSHerbert Xu "r" ((USItype)(d))); \ 991*2a598d0bSHerbert Xu (r) = (n0) - __q * (d); \ 992*2a598d0bSHerbert Xu (q) = __q; \ 993*2a598d0bSHerbert Xu } while (0) 994*2a598d0bSHerbert Xu #define UDIV_TIME 25 995*2a598d0bSHerbert Xu #endif /* SUPERSPARC */ 996*2a598d0bSHerbert Xu #else /* ! __sparc_v8__ */ 997*2a598d0bSHerbert Xu #if defined(__sparclite__) 998*2a598d0bSHerbert Xu /* This has hardware multiply but not divide. It also has two additional 999*2a598d0bSHerbert Xu instructions scan (ffs from high bit) and divscc. */ 1000*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 1001*2a598d0bSHerbert Xu __asm__ ("umul %2,%3,%1;rd %%y,%0" \ 1002*2a598d0bSHerbert Xu : "=r" ((USItype)(w1)), \ 1003*2a598d0bSHerbert Xu "=r" ((USItype)(w0)) \ 1004*2a598d0bSHerbert Xu : "r" ((USItype)(u)), \ 1005*2a598d0bSHerbert Xu "r" ((USItype)(v))) 1006*2a598d0bSHerbert Xu #define UMUL_TIME 5 1007*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 1008*2a598d0bSHerbert Xu __asm__ ("! Inlined udiv_qrnnd\n" \ 1009*2a598d0bSHerbert Xu "wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ 1010*2a598d0bSHerbert Xu "tst %%g0\n" \ 1011*2a598d0bSHerbert Xu "divscc %3,%4,%%g1\n" \ 1012*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1013*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1014*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1015*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1016*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1017*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1018*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1019*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1020*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1021*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1022*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1023*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1024*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1025*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1026*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1027*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1028*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1029*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1030*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1031*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1032*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1033*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1034*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1035*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1036*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1037*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1038*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1039*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1040*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1041*2a598d0bSHerbert Xu "divscc %%g1,%4,%%g1\n" \ 1042*2a598d0bSHerbert Xu "divscc %%g1,%4,%0\n" \ 1043*2a598d0bSHerbert Xu "rd %%y,%1\n" \ 1044*2a598d0bSHerbert Xu "bl,a 1f\n" \ 1045*2a598d0bSHerbert Xu "add %1,%4,%1\n" \ 1046*2a598d0bSHerbert Xu "1: ! End of inline udiv_qrnnd" \ 1047*2a598d0bSHerbert Xu : "=r" ((USItype)(q)), \ 1048*2a598d0bSHerbert Xu "=r" ((USItype)(r)) \ 1049*2a598d0bSHerbert Xu : "r" ((USItype)(n1)), \ 1050*2a598d0bSHerbert Xu "r" ((USItype)(n0)), \ 1051*2a598d0bSHerbert Xu "rI" ((USItype)(d)) \ 1052*2a598d0bSHerbert Xu : "%g1" __AND_CLOBBER_CC) 1053*2a598d0bSHerbert Xu #define UDIV_TIME 37 1054*2a598d0bSHerbert Xu #endif /* __sparclite__ */ 1055*2a598d0bSHerbert Xu #endif /* __sparc_v8__ */ 1056*2a598d0bSHerbert Xu /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ 1057*2a598d0bSHerbert Xu #ifndef umul_ppmm 1058*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 1059*2a598d0bSHerbert Xu __asm__ ("! Inlined umul_ppmm\n" \ 1060*2a598d0bSHerbert Xu "wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n" \ 1061*2a598d0bSHerbert Xu "sra %3,31,%%g2 ! Don't move this insn\n" \ 1062*2a598d0bSHerbert Xu "and %2,%%g2,%%g2 ! Don't move this insn\n" \ 1063*2a598d0bSHerbert Xu "andcc %%g0,0,%%g1 ! Don't move this insn\n" \ 1064*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1065*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1066*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1067*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1068*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1069*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1070*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1071*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1072*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1073*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1074*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1075*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1076*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1077*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1078*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1079*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1080*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1081*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1082*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1083*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1084*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1085*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1086*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1087*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1088*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1089*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1090*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1091*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1092*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1093*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1094*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1095*2a598d0bSHerbert Xu "mulscc %%g1,%3,%%g1\n" \ 1096*2a598d0bSHerbert Xu "mulscc %%g1,0,%%g1\n" \ 1097*2a598d0bSHerbert Xu "add %%g1,%%g2,%0\n" \ 1098*2a598d0bSHerbert Xu "rd %%y,%1" \ 1099*2a598d0bSHerbert Xu : "=r" ((USItype)(w1)), \ 1100*2a598d0bSHerbert Xu "=r" ((USItype)(w0)) \ 1101*2a598d0bSHerbert Xu : "%rI" ((USItype)(u)), \ 1102*2a598d0bSHerbert Xu "r" ((USItype)(v)) \ 1103*2a598d0bSHerbert Xu : "%g1", "%g2" __AND_CLOBBER_CC) 1104*2a598d0bSHerbert Xu #define UMUL_TIME 39 /* 39 instructions */ 1105*2a598d0bSHerbert Xu /* It's quite necessary to add this much assembler for the sparc. 1106*2a598d0bSHerbert Xu The default udiv_qrnnd (in C) is more than 10 times slower! */ 1107*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, n1, n0, d) \ 1108*2a598d0bSHerbert Xu __asm__ ("! Inlined udiv_qrnnd\n\t" \ 1109*2a598d0bSHerbert Xu "mov 32,%%g1\n\t" \ 1110*2a598d0bSHerbert Xu "subcc %1,%2,%%g0\n\t" \ 1111*2a598d0bSHerbert Xu "1: bcs 5f\n\t" \ 1112*2a598d0bSHerbert Xu "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ 1113*2a598d0bSHerbert Xu "sub %1,%2,%1 ! this kills msb of n\n\t" \ 1114*2a598d0bSHerbert Xu "addx %1,%1,%1 ! so this can't give carry\n\t" \ 1115*2a598d0bSHerbert Xu "subcc %%g1,1,%%g1\n\t" \ 1116*2a598d0bSHerbert Xu "2: bne 1b\n\t" \ 1117*2a598d0bSHerbert Xu "subcc %1,%2,%%g0\n\t" \ 1118*2a598d0bSHerbert Xu "bcs 3f\n\t" \ 1119*2a598d0bSHerbert Xu "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ 1120*2a598d0bSHerbert Xu "b 3f\n\t" \ 1121*2a598d0bSHerbert Xu "sub %1,%2,%1 ! this kills msb of n\n\t" \ 1122*2a598d0bSHerbert Xu "4: sub %1,%2,%1\n\t" \ 1123*2a598d0bSHerbert Xu "5: addxcc %1,%1,%1\n\t" \ 1124*2a598d0bSHerbert Xu "bcc 2b\n\t" \ 1125*2a598d0bSHerbert Xu "subcc %%g1,1,%%g1\n\t" \ 1126*2a598d0bSHerbert Xu "! Got carry from n. Subtract next step to cancel this carry.\n\t" \ 1127*2a598d0bSHerbert Xu "bne 4b\n\t" \ 1128*2a598d0bSHerbert Xu "addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n\t" \ 1129*2a598d0bSHerbert Xu "sub %1,%2,%1\n\t" \ 1130*2a598d0bSHerbert Xu "3: xnor %0,0,%0\n\t" \ 1131*2a598d0bSHerbert Xu "! End of inline udiv_qrnnd\n" \ 1132*2a598d0bSHerbert Xu : "=&r" ((USItype)(q)), \ 1133*2a598d0bSHerbert Xu "=&r" ((USItype)(r)) \ 1134*2a598d0bSHerbert Xu : "r" ((USItype)(d)), \ 1135*2a598d0bSHerbert Xu "1" ((USItype)(n1)), \ 1136*2a598d0bSHerbert Xu "0" ((USItype)(n0)) : "%g1", "cc") 1137*2a598d0bSHerbert Xu #define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ 1138*2a598d0bSHerbert Xu #endif 1139*2a598d0bSHerbert Xu #endif /* __sparc__ */ 1140*2a598d0bSHerbert Xu 1141*2a598d0bSHerbert Xu /*************************************** 1142*2a598d0bSHerbert Xu ************** VAX ****************** 1143*2a598d0bSHerbert Xu ***************************************/ 1144*2a598d0bSHerbert Xu #if defined(__vax__) && W_TYPE_SIZE == 32 1145*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 1146*2a598d0bSHerbert Xu __asm__ ("addl2 %5,%1\n" \ 1147*2a598d0bSHerbert Xu "adwc %3,%0" \ 1148*2a598d0bSHerbert Xu : "=g" ((USItype)(sh)), \ 1149*2a598d0bSHerbert Xu "=&g" ((USItype)(sl)) \ 1150*2a598d0bSHerbert Xu : "%0" ((USItype)(ah)), \ 1151*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 1152*2a598d0bSHerbert Xu "%1" ((USItype)(al)), \ 1153*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 1154*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 1155*2a598d0bSHerbert Xu __asm__ ("subl2 %5,%1\n" \ 1156*2a598d0bSHerbert Xu "sbwc %3,%0" \ 1157*2a598d0bSHerbert Xu : "=g" ((USItype)(sh)), \ 1158*2a598d0bSHerbert Xu "=&g" ((USItype)(sl)) \ 1159*2a598d0bSHerbert Xu : "0" ((USItype)(ah)), \ 1160*2a598d0bSHerbert Xu "g" ((USItype)(bh)), \ 1161*2a598d0bSHerbert Xu "1" ((USItype)(al)), \ 1162*2a598d0bSHerbert Xu "g" ((USItype)(bl))) 1163*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, m0, m1) \ 1164*2a598d0bSHerbert Xu do { \ 1165*2a598d0bSHerbert Xu union {UDItype __ll; \ 1166*2a598d0bSHerbert Xu struct {USItype __l, __h; } __i; \ 1167*2a598d0bSHerbert Xu } __xx; \ 1168*2a598d0bSHerbert Xu USItype __m0 = (m0), __m1 = (m1); \ 1169*2a598d0bSHerbert Xu __asm__ ("emul %1,%2,$0,%0" \ 1170*2a598d0bSHerbert Xu : "=g" (__xx.__ll) \ 1171*2a598d0bSHerbert Xu : "g" (__m0), \ 1172*2a598d0bSHerbert Xu "g" (__m1)); \ 1173*2a598d0bSHerbert Xu (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 1174*2a598d0bSHerbert Xu (xh) += ((((SItype) __m0 >> 31) & __m1) \ 1175*2a598d0bSHerbert Xu + (((SItype) __m1 >> 31) & __m0)); \ 1176*2a598d0bSHerbert Xu } while (0) 1177*2a598d0bSHerbert Xu #define sdiv_qrnnd(q, r, n1, n0, d) \ 1178*2a598d0bSHerbert Xu do { \ 1179*2a598d0bSHerbert Xu union {DItype __ll; \ 1180*2a598d0bSHerbert Xu struct {SItype __l, __h; } __i; \ 1181*2a598d0bSHerbert Xu } __xx; \ 1182*2a598d0bSHerbert Xu __xx.__i.__h = n1; __xx.__i.__l = n0; \ 1183*2a598d0bSHerbert Xu __asm__ ("ediv %3,%2,%0,%1" \ 1184*2a598d0bSHerbert Xu : "=g" (q), "=g" (r) \ 1185*2a598d0bSHerbert Xu : "g" (__xx.__ll), "g" (d)); \ 1186*2a598d0bSHerbert Xu } while (0) 1187*2a598d0bSHerbert Xu #endif /* __vax__ */ 1188*2a598d0bSHerbert Xu 1189*2a598d0bSHerbert Xu /*************************************** 1190*2a598d0bSHerbert Xu ************** Z8000 **************** 1191*2a598d0bSHerbert Xu ***************************************/ 1192*2a598d0bSHerbert Xu #if defined(__z8000__) && W_TYPE_SIZE == 16 1193*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 1194*2a598d0bSHerbert Xu __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ 1195*2a598d0bSHerbert Xu : "=r" ((unsigned int)(sh)), \ 1196*2a598d0bSHerbert Xu "=&r" ((unsigned int)(sl)) \ 1197*2a598d0bSHerbert Xu : "%0" ((unsigned int)(ah)), \ 1198*2a598d0bSHerbert Xu "r" ((unsigned int)(bh)), \ 1199*2a598d0bSHerbert Xu "%1" ((unsigned int)(al)), \ 1200*2a598d0bSHerbert Xu "rQR" ((unsigned int)(bl))) 1201*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 1202*2a598d0bSHerbert Xu __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ 1203*2a598d0bSHerbert Xu : "=r" ((unsigned int)(sh)), \ 1204*2a598d0bSHerbert Xu "=&r" ((unsigned int)(sl)) \ 1205*2a598d0bSHerbert Xu : "0" ((unsigned int)(ah)), \ 1206*2a598d0bSHerbert Xu "r" ((unsigned int)(bh)), \ 1207*2a598d0bSHerbert Xu "1" ((unsigned int)(al)), \ 1208*2a598d0bSHerbert Xu "rQR" ((unsigned int)(bl))) 1209*2a598d0bSHerbert Xu #define umul_ppmm(xh, xl, m0, m1) \ 1210*2a598d0bSHerbert Xu do { \ 1211*2a598d0bSHerbert Xu union {long int __ll; \ 1212*2a598d0bSHerbert Xu struct {unsigned int __h, __l; } __i; \ 1213*2a598d0bSHerbert Xu } __xx; \ 1214*2a598d0bSHerbert Xu unsigned int __m0 = (m0), __m1 = (m1); \ 1215*2a598d0bSHerbert Xu __asm__ ("mult %S0,%H3" \ 1216*2a598d0bSHerbert Xu : "=r" (__xx.__i.__h), \ 1217*2a598d0bSHerbert Xu "=r" (__xx.__i.__l) \ 1218*2a598d0bSHerbert Xu : "%1" (__m0), \ 1219*2a598d0bSHerbert Xu "rQR" (__m1)); \ 1220*2a598d0bSHerbert Xu (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ 1221*2a598d0bSHerbert Xu (xh) += ((((signed int) __m0 >> 15) & __m1) \ 1222*2a598d0bSHerbert Xu + (((signed int) __m1 >> 15) & __m0)); \ 1223*2a598d0bSHerbert Xu } while (0) 1224*2a598d0bSHerbert Xu #endif /* __z8000__ */ 1225*2a598d0bSHerbert Xu 1226*2a598d0bSHerbert Xu #endif /* __GNUC__ */ 1227*2a598d0bSHerbert Xu 1228*2a598d0bSHerbert Xu /*************************************** 1229*2a598d0bSHerbert Xu *********** Generic Versions ******** 1230*2a598d0bSHerbert Xu ***************************************/ 1231*2a598d0bSHerbert Xu #if !defined(umul_ppmm) && defined(__umulsidi3) 1232*2a598d0bSHerbert Xu #define umul_ppmm(ph, pl, m0, m1) \ 1233*2a598d0bSHerbert Xu { \ 1234*2a598d0bSHerbert Xu UDWtype __ll = __umulsidi3(m0, m1); \ 1235*2a598d0bSHerbert Xu ph = (UWtype) (__ll >> W_TYPE_SIZE); \ 1236*2a598d0bSHerbert Xu pl = (UWtype) __ll; \ 1237*2a598d0bSHerbert Xu } 1238*2a598d0bSHerbert Xu #endif 1239*2a598d0bSHerbert Xu 1240*2a598d0bSHerbert Xu #if !defined(__umulsidi3) 1241*2a598d0bSHerbert Xu #define __umulsidi3(u, v) \ 1242*2a598d0bSHerbert Xu ({UWtype __hi, __lo; \ 1243*2a598d0bSHerbert Xu umul_ppmm(__hi, __lo, u, v); \ 1244*2a598d0bSHerbert Xu ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) 1245*2a598d0bSHerbert Xu #endif 1246*2a598d0bSHerbert Xu 1247*2a598d0bSHerbert Xu /* If this machine has no inline assembler, use C macros. */ 1248*2a598d0bSHerbert Xu 1249*2a598d0bSHerbert Xu #if !defined(add_ssaaaa) 1250*2a598d0bSHerbert Xu #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 1251*2a598d0bSHerbert Xu do { \ 1252*2a598d0bSHerbert Xu UWtype __x; \ 1253*2a598d0bSHerbert Xu __x = (al) + (bl); \ 1254*2a598d0bSHerbert Xu (sh) = (ah) + (bh) + (__x < (al)); \ 1255*2a598d0bSHerbert Xu (sl) = __x; \ 1256*2a598d0bSHerbert Xu } while (0) 1257*2a598d0bSHerbert Xu #endif 1258*2a598d0bSHerbert Xu 1259*2a598d0bSHerbert Xu #if !defined(sub_ddmmss) 1260*2a598d0bSHerbert Xu #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 1261*2a598d0bSHerbert Xu do { \ 1262*2a598d0bSHerbert Xu UWtype __x; \ 1263*2a598d0bSHerbert Xu __x = (al) - (bl); \ 1264*2a598d0bSHerbert Xu (sh) = (ah) - (bh) - (__x > (al)); \ 1265*2a598d0bSHerbert Xu (sl) = __x; \ 1266*2a598d0bSHerbert Xu } while (0) 1267*2a598d0bSHerbert Xu #endif 1268*2a598d0bSHerbert Xu 1269*2a598d0bSHerbert Xu #if !defined(umul_ppmm) 1270*2a598d0bSHerbert Xu #define umul_ppmm(w1, w0, u, v) \ 1271*2a598d0bSHerbert Xu do { \ 1272*2a598d0bSHerbert Xu UWtype __x0, __x1, __x2, __x3; \ 1273*2a598d0bSHerbert Xu UHWtype __ul, __vl, __uh, __vh; \ 1274*2a598d0bSHerbert Xu UWtype __u = (u), __v = (v); \ 1275*2a598d0bSHerbert Xu \ 1276*2a598d0bSHerbert Xu __ul = __ll_lowpart(__u); \ 1277*2a598d0bSHerbert Xu __uh = __ll_highpart(__u); \ 1278*2a598d0bSHerbert Xu __vl = __ll_lowpart(__v); \ 1279*2a598d0bSHerbert Xu __vh = __ll_highpart(__v); \ 1280*2a598d0bSHerbert Xu \ 1281*2a598d0bSHerbert Xu __x0 = (UWtype) __ul * __vl; \ 1282*2a598d0bSHerbert Xu __x1 = (UWtype) __ul * __vh; \ 1283*2a598d0bSHerbert Xu __x2 = (UWtype) __uh * __vl; \ 1284*2a598d0bSHerbert Xu __x3 = (UWtype) __uh * __vh; \ 1285*2a598d0bSHerbert Xu \ 1286*2a598d0bSHerbert Xu __x1 += __ll_highpart(__x0);/* this can't give carry */ \ 1287*2a598d0bSHerbert Xu __x1 += __x2; /* but this indeed can */ \ 1288*2a598d0bSHerbert Xu if (__x1 < __x2) /* did we get it? */ \ 1289*2a598d0bSHerbert Xu __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 1290*2a598d0bSHerbert Xu \ 1291*2a598d0bSHerbert Xu (w1) = __x3 + __ll_highpart(__x1); \ 1292*2a598d0bSHerbert Xu (w0) = (__ll_lowpart(__x1) << W_TYPE_SIZE/2) + __ll_lowpart(__x0); \ 1293*2a598d0bSHerbert Xu } while (0) 1294*2a598d0bSHerbert Xu #endif 1295*2a598d0bSHerbert Xu 1296*2a598d0bSHerbert Xu #if !defined(umul_ppmm) 1297*2a598d0bSHerbert Xu #define smul_ppmm(w1, w0, u, v) \ 1298*2a598d0bSHerbert Xu do { \ 1299*2a598d0bSHerbert Xu UWtype __w1; \ 1300*2a598d0bSHerbert Xu UWtype __m0 = (u), __m1 = (v); \ 1301*2a598d0bSHerbert Xu umul_ppmm(__w1, w0, __m0, __m1); \ 1302*2a598d0bSHerbert Xu (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \ 1303*2a598d0bSHerbert Xu - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \ 1304*2a598d0bSHerbert Xu } while (0) 1305*2a598d0bSHerbert Xu #endif 1306*2a598d0bSHerbert Xu 1307*2a598d0bSHerbert Xu /* Define this unconditionally, so it can be used for debugging. */ 1308*2a598d0bSHerbert Xu #define __udiv_qrnnd_c(q, r, n1, n0, d) \ 1309*2a598d0bSHerbert Xu do { \ 1310*2a598d0bSHerbert Xu UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ 1311*2a598d0bSHerbert Xu __d1 = __ll_highpart(d); \ 1312*2a598d0bSHerbert Xu __d0 = __ll_lowpart(d); \ 1313*2a598d0bSHerbert Xu \ 1314*2a598d0bSHerbert Xu __r1 = (n1) % __d1; \ 1315*2a598d0bSHerbert Xu __q1 = (n1) / __d1; \ 1316*2a598d0bSHerbert Xu __m = (UWtype) __q1 * __d0; \ 1317*2a598d0bSHerbert Xu __r1 = __r1 * __ll_B | __ll_highpart(n0); \ 1318*2a598d0bSHerbert Xu if (__r1 < __m) { \ 1319*2a598d0bSHerbert Xu __q1--, __r1 += (d); \ 1320*2a598d0bSHerbert Xu if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \ 1321*2a598d0bSHerbert Xu if (__r1 < __m) \ 1322*2a598d0bSHerbert Xu __q1--, __r1 += (d); \ 1323*2a598d0bSHerbert Xu } \ 1324*2a598d0bSHerbert Xu __r1 -= __m; \ 1325*2a598d0bSHerbert Xu \ 1326*2a598d0bSHerbert Xu __r0 = __r1 % __d1; \ 1327*2a598d0bSHerbert Xu __q0 = __r1 / __d1; \ 1328*2a598d0bSHerbert Xu __m = (UWtype) __q0 * __d0; \ 1329*2a598d0bSHerbert Xu __r0 = __r0 * __ll_B | __ll_lowpart(n0); \ 1330*2a598d0bSHerbert Xu if (__r0 < __m) { \ 1331*2a598d0bSHerbert Xu __q0--, __r0 += (d); \ 1332*2a598d0bSHerbert Xu if (__r0 >= (d)) \ 1333*2a598d0bSHerbert Xu if (__r0 < __m) \ 1334*2a598d0bSHerbert Xu __q0--, __r0 += (d); \ 1335*2a598d0bSHerbert Xu } \ 1336*2a598d0bSHerbert Xu __r0 -= __m; \ 1337*2a598d0bSHerbert Xu \ 1338*2a598d0bSHerbert Xu (q) = (UWtype) __q1 * __ll_B | __q0; \ 1339*2a598d0bSHerbert Xu (r) = __r0; \ 1340*2a598d0bSHerbert Xu } while (0) 1341*2a598d0bSHerbert Xu 1342*2a598d0bSHerbert Xu /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through 1343*2a598d0bSHerbert Xu __udiv_w_sdiv (defined in libgcc or elsewhere). */ 1344*2a598d0bSHerbert Xu #if !defined(udiv_qrnnd) && defined(sdiv_qrnnd) 1345*2a598d0bSHerbert Xu #define udiv_qrnnd(q, r, nh, nl, d) \ 1346*2a598d0bSHerbert Xu do { \ 1347*2a598d0bSHerbert Xu UWtype __r; \ 1348*2a598d0bSHerbert Xu (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \ 1349*2a598d0bSHerbert Xu (r) = __r; \ 1350*2a598d0bSHerbert Xu } while (0) 1351*2a598d0bSHerbert Xu #endif 1352*2a598d0bSHerbert Xu 1353*2a598d0bSHerbert Xu /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ 1354*2a598d0bSHerbert Xu #if !defined(udiv_qrnnd) 1355*2a598d0bSHerbert Xu #define UDIV_NEEDS_NORMALIZATION 1 1356*2a598d0bSHerbert Xu #define udiv_qrnnd __udiv_qrnnd_c 1357*2a598d0bSHerbert Xu #endif 1358*2a598d0bSHerbert Xu 1359*2a598d0bSHerbert Xu #ifndef UDIV_NEEDS_NORMALIZATION 1360*2a598d0bSHerbert Xu #define UDIV_NEEDS_NORMALIZATION 0 1361*2a598d0bSHerbert Xu #endif 1362