|
|
1.1.1.5 ! root 1: /* ! 2: * lmul.h - Macros for doing a n x n -> 2N multiply. ! 3: * ! 4: * Included by R3000.C, for use in Philip Zimmermann's PGP program. ! 5: * Implemented by Castor Fu, Sep 1992. ! 6: * ! 7: * Define PATCH_ASM if you want to patch the assembly code yourself. . . ! 8: * ! 9: * Currently has support for mips, i386 and 680[2+]0 under GCC. ! 10: * ! 11: * The general (and generally undesired ) case manually ! 12: * performs the multiply by splitting the numbers up into two pieces. . . ! 13: * ! 14: * lmul(i1,i2,ol,oh) takes the product of i1, i2 and yields ol, oh ! 15: * the lower and upper halves of the result. ! 16: */ ! 17: ! 18: #ifdef PATCH_ASM ! 19: #define lmul(i1,i2,ol, oh) (ol=(i1)*(i2), oh=(i1)^(i2)) ! 20: #else ! 21: ! 22: #if defined(__GNUC__) && defined(mips) && defined(MUNIT32) ! 23: #define lmul(a,b,xl,xh) \ ! 24: { \ ! 25: asm("multu %2, %3\n\tmflo %0\n\tmfhi %1" : \ ! 26: "=d" (xl) , "=d" (xh) : "d" (a), "d" (b)); \ ! 27: } ! 28: #else ! 29: #if defined(__GNUC__) && defined(mc68020) && defined(MUNIT32) ! 30: #define lmul(a,b,xl,xh) \ ! 31: {\ ! 32: xl = a; \ ! 33: asm("mulul %3, %1:%0" : "=d" (xl) , "=d" (xh) : "0" (xl) , \ ! 34: "d" (b)); \ ! 35: } ! 36: #else ! 37: #if defined(__GNUC__) && defined(i386) && defined(MUNIT32) ! 38: #define lmul(a,b,xl,xh) asm("mull %3":"=a" (xl),"=d" (xh):"0" (a),"g" (b)) ! 39: #else ! 40: ! 41: #define MUNITHMASK (((unsigned long)1 <<(MULTUNITSIZE/2)) - 1) ! 42: ! 43: #ifdef MUNIT16 ! 44: #define lmul(a,b,xl,xh) \ ! 45: {\ ! 46: unsigned long XX = (unsigned long) (a)*(b); \ ! 47: xl = XX & 0xffff; \ ! 48: xh = XX >> 16; \ ! 49: } ! 50: ! 51: #else ! 52: #define lmul(a,b,xl, xh) \ ! 53: {\ ! 54: MULTUNIT Xaa, Xbb, Xal, Xah, Xbl, Xbh, Xx1,Xx2,Xx3,Xx4,Xx5,Xx6; \ ! 55: Xaa= (a); Xbb = (b); Xal = Xaa&MUNITHMASK; Xah = Xaa>>(MULTUNITSIZE/2); \ ! 56: Xbl = Xbb&MUNITHMASK; Xbh = Xbb>>(MULTUNITSIZE/2); \ ! 57: Xx1 = Xal*Xbl; \ ! 58: Xx2 = Xah*Xbl; \ ! 59: Xx3 = Xal*Xbh; \ ! 60: Xx4 = Xah*Xbh; \ ! 61: Xx5 = Xx2+Xx3; \ ! 62: Xx4 += ((MULTUNIT) (Xx5 < Xx2)) << (MULTUNITSIZE/2); \ ! 63: Xx6 = Xx1 + (Xx5 << (MULTUNITSIZE/2)); \ ! 64: Xx4 += (Xx6 < Xx1) + (Xx5>>(MULTUNITSIZE/2)); \ ! 65: \ ! 66: \ ! 67: xl = Xx6; \ ! 68: xh = Xx4; \ ! 69: } ! 70: #endif ! 71: #endif ! 72: #endif ! 73: #endif ! 74: #endif /* PATCH_ASM */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.