|
|
1.1.1.3 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; \
1.1.1.4 ! root 33: asm("mulul %3, %1:%0" : "=d" (xl) , "=d" (xh) : "0" (xl) , \
! 34: "d" (b)); \
1.1.1.3 root 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.