Annotation of OpenXM_contrib2/asir2000/asm/ddM.c, Revision 1.1.1.1
1.1 noro 1: /* $OpenXM: OpenXM/src/asir99/asm/ddM.c,v 1.1.1.1 1999/11/10 08:12:25 noro Exp $ */
2: #include "ca.h"
3: #include "base.h"
4: #include "inline.h"
5:
6: void ksquareummain(int,UM,UM);
7: void kmulummain(int,UM,UM,UM);
8: void c_copyum(UM,int,int *);
9: void copyum(UM,UM);
10: void extractum(UM,int,int,UM);
11: void ksquareum(int,UM,UM);
12: void kmulum(int,UM,UM,UM);
13:
14: /*
15: * mod is declared as 'int', because several xxxum functions contains signed
16: * integer addition/subtraction. So mod should be less than 2^31.
17: */
18:
19: void mulum(mod,p1,p2,pr)
20: int mod;
21: UM p1,p2,pr;
22: {
23: int *pc1,*pcr;
24: int *c1,*c2,*cr;
25: unsigned int mul;
26: int i,j,d1,d2;
27:
28: if ( ( (d1 = DEG(p1)) < 0) || ( (d2 = DEG(p2)) < 0 ) ) {
29: DEG(pr) = -1;
30: return;
31: }
32: c1 = COEF(p1); c2 = COEF(p2); cr = COEF(pr);
33: bzero((char *)cr,(int)((d1+d2+1)*sizeof(int)));
34: for ( i = 0; i <= d2; i++, cr++ )
35: if ( mul = *c2++ )
36: for ( j = 0, pc1 = c1, pcr = cr; j <= d1; j++, pc1++, pcr++ ) {
37: DMAR(*pc1,mul,*pcr,mod,*pcr)
38: }
39: DEG(pr) = d1 + d2;
40: }
41:
42: void mulsum(mod,p,n,pr)
43: int mod,n;
44: UM p,pr;
45: {
46: int *sp,*dp;
47: int i;
48:
49: for ( i = DEG(pr) = DEG(p), sp = COEF(p)+i, dp = COEF(pr)+i;
50: i >= 0; i--, dp--, sp-- ) {
51: DMAR(*sp,n,0,mod,*dp)
52: }
53: }
54:
55: int divum(mod,p1,p2,pq)
56: int mod;
57: UM p1,p2,pq;
58: {
59: int *pc1,*pct;
60: int *c1,*c2,*ct;
61: unsigned int inv,hd,tmp;
62: int i,j, d1,d2,dd;
63:
64: if ( (d1 = DEG(p1)) < (d2 = DEG(p2)) ) {
65: DEG(pq) = -1;
66: return d1;
67: }
68: c1 = COEF(p1); c2 = COEF(p2); dd = d1-d2;
69: if ( ( hd = c2[d2] ) != 1 ) {
70: inv = invm(hd,mod);
71: for ( pc1 = c2 + d2; pc1 >= c2; pc1-- ) {
72: DMAR(*pc1,inv,0,mod,*pc1)
73: }
74: } else
75: inv = 1;
76: for ( i = dd, ct = c1+d1; i >= 0; i-- )
77: if ( tmp = *ct-- ) {
78: tmp = mod - tmp;
79: for ( j = d2-1, pct = ct, pc1 = c2+j; j >= 0; j--, pct--, pc1-- ) {
80: DMAR(*pc1,tmp,*pct,mod,*pct)
81: }
82: }
83: if ( inv != 1 ) {
84: for ( pc1 = c1+d2, pct = c1+d1; pc1 <= pct; pc1++ ) {
85: DMAR(*pc1,inv,0,mod,*pc1)
86: }
87: for ( pc1 = c2, pct = c2+d2, inv = hd; pc1 <= pct; pc1++ ) {
88: DMAR(*pc1,inv,0,mod,*pc1)
89: }
90: }
91: for ( i = d2-1, pc1 = c1+i; i >= 0 && !(*pc1); pc1--, i-- );
92: for ( DEG(pq) = j = dd, pc1 = c1+d1, pct = COEF(pq)+j; j >= 0; j-- )
93: *pct-- = *pc1--;
94: return i;
95: }
96:
97: void diffum(mod,f,fd)
98: int mod;
99: UM f,fd;
100: {
101: int *dp,*sp;
102: int i;
103: UL ltmp;
104:
105: for ( i = DEG(f), dp = COEF(fd)+i-1, sp = COEF(f)+i;
106: i >= 1; i--, dp--, sp-- ) {
107: DMAR(*sp,i,0,mod,*dp)
108: }
109: degum(fd,DEG(f) - 1);
110: }
111:
112: unsigned int pwrm(mod,a,n)
113: int mod,a;
114: int n;
115: {
116: unsigned int s,t;
117:
118: if ( !n )
119: return 1;
120: else if ( n == 1 )
121: return a;
122: else {
123: t = pwrm(mod,a,n/2);
124: DMAR(t,t,0,mod,s)
125: if ( n % 2 ) {
126: DMAR(s,a,0,mod,t)
127: return t;
128: } else
129: return s;
130: }
131: }
132:
133: unsigned int invm(s,mod)
134: unsigned int s;
135: int mod;
136: {
137: unsigned int r,a2,q;
138: unsigned int f1,f2,a1;
139:
140: for ( f1 = s, f2 = mod, a1 = 1, a2 = 0; ; ) {
141: q = f1/f2; r = f1 - f2*q; f1 = f2;
142: if ( !(f2 = r) )
143: break;
144: DMAR(a2,q,0,mod,r)
145: /* r = ( a1 - r + mod ) % mod; */
146: if ( a1 >= r )
147: r = a1 - r;
148: else {
149: r = (mod - r) + a1;
150: }
151: a1 = a2; a2 = r;
152: }
153: /* return( ( a2 >= 0 ? a2 : a2 + mod ) ); */
154: return a2;
155: }
156:
157: unsigned int rem(n,m)
158: N n;
159: unsigned int m;
160: {
161: unsigned int *x;
162: unsigned int t,r;
163: int i;
164:
165: if ( !n )
166: return 0;
167: for ( i = PL(n)-1, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) {
168: #if defined(sparc)
169: r = dsar(m,r,*x);
170: #else
171: DSAB(m,r,*x,t,r)
172: #endif
173: }
174: return r;
175: }
176:
177: #ifndef sparc
178: void addpadic(mod,n,n1,n2)
179: int mod;
180: int n;
181: unsigned int *n1,*n2;
182: {
183: unsigned int carry,tmp;
184: int i;
185:
186: for ( i = 0, carry = 0; i < n; i++ ) {
187: tmp = *n1++ + *n2 + carry;
188: DQR(tmp,mod,carry,*n2++)
189: /*
190: carry = tmp / mod;
191: *n2++ = tmp - ( carry * mod );
192: */
193: }
194: }
195: #endif
196:
197: void mulpadic(mod,n,n1,n2,nr)
198: int mod;
199: int n;
200: unsigned int *n1;
201: unsigned int *n2,*nr;
202: {
203: unsigned int *pn1,*pnr;
204: unsigned int carry,mul;
205: int i,j;
206:
207: bzero((char *)nr,(int)(n*sizeof(int)));
208: for ( j = 0; j < n; j++, n2++, nr++ )
209: if ( mul = *n2 )
210: for ( i = j, carry = 0, pn1 = n1, pnr = nr;
211: i < n; i++, pn1++, pnr++ ) {
212: carry += *pnr;
213: DMAB(mod,*pn1,mul,carry,carry,*pnr)
214: }
215: }
216:
217: extern up_kara_mag;
218:
219: void kmulum(mod,n1,n2,nr)
220: UM n1,n2,nr;
221: {
222: UM n,t,s,m,carry;
223: int d,d1,d2,len,i,l;
224: unsigned int *r,*r0;
225:
226: if ( !n1 || !n2 ) {
227: nr->d = -1; return;
228: }
229: d1 = DEG(n1)+1; d2 = DEG(n2)+1;
230: if ( (d1 < up_kara_mag) || (d2 < up_kara_mag) ) {
231: mulum(mod,n1,n2,nr); return;
232: }
233: if ( d1 < d2 ) {
234: n = n1; n1 = n2; n2 = n;
235: d = d1; d1 = d2; d2 = d;
236: }
237: if ( d2 > (d1+1)/2 ) {
238: kmulummain(mod,n1,n2,nr); return;
239: }
240: d = (d1/d2)+((d1%d2)!=0);
241: len = (d+1)*d2;
242: r0 = (unsigned int *)ALLOCA(len*sizeof(int));
243: bzero((char *)r0,len*sizeof(int));
244: m = W_UMALLOC(d2+1);
245: carry = W_UMALLOC(d2+1);
246: t = W_UMALLOC(d1+d2+1);
247: s = W_UMALLOC(d1+d2+1);
248: for ( carry = 0, i = 0, r = r0; i < d; i++, r += d2 ) {
249: extractum(n1,i*d2,d2,m);
250: if ( m ) {
251: kmulum(mod,m,n2,t);
252: addum(mod,t,carry,s);
253: c_copyum(s,d2,r);
254: extractum(s,d2,d2,carry);
255: } else {
256: c_copyum(carry,d2,r);
257: carry = 0;
258: }
259: }
260: c_copyum(carry,d2,r);
261: for ( l = len - 1; !r0[l]; l-- );
262: l++;
263: DEG(nr) = l-1;
264: bcopy((char *)r0,(char *)COEF(nr),l*sizeof(int));
265: }
266:
267: void ksquareum(mod,n1,nr)
268: int mod;
269: UM n1,nr;
270: {
271: int d1;
272:
273: if ( !n1 ) {
274: nr->d = -1; return;
275: }
276: d1 = DEG(n1)+1;
277: if ( (d1 < up_kara_mag) ) {
278: pwrum(mod,n1,2,nr); return;
279: }
280: ksquareummain(mod,n1,nr);
281: }
282:
283: void extractum(n,index,len,nr)
284: UM n;
285: int index,len;
286: UM nr;
287: {
288: int *m;
289: int l;
290:
291: if ( !n ) {
292: nr->d = -1; return;
293: }
294: m = COEF(n)+index;
295: if ( (l = (DEG(n)+1)-index) >= len ) {
296: for ( l = len - 1; (l >= 0) && !m[l]; l-- );
297: l++;
298: }
299: if ( l <= 0 ) {
300: nr->d = -1; return;
301: } else {
302: DEG(nr) = l-1;
303: bcopy((char *)m,(char *)COEF(nr),l*sizeof(Q));
304: }
305: }
306:
307: void copyum(n1,n2)
308: UM n1,n2;
309: {
310: n2->d = n1->d;
311: bcopy((char *)n1->c,(char *)n2->c,(n1->d+1)*sizeof(int));
312: }
313:
314: void c_copyum(n,len,p)
315: UM n;
316: int len;
317: int *p;
318: {
319: if ( n )
320: bcopy((char *)COEF(n),(char *)p,MIN((DEG(n)+1),len)*sizeof(int));
321: }
322:
323: void kmulummain(mod,n1,n2,nr)
324: int mod;
325: UM n1,n2,nr;
326: {
327: int d1,d2,h,len;
328: UM n1lo,n1hi,n2lo,n2hi,hi,lo,mid1,mid2,mid,s1,s2,t1,t2;
329:
330: d1 = DEG(n1)+1; d2 = DEG(n2)+1; h = (d1+1)/2;
331: n1lo = W_UMALLOC(d1+1); n1hi = W_UMALLOC(d1+1);
332: n2lo = W_UMALLOC(d2+1); n2hi = W_UMALLOC(d2+1);
333: lo = W_UMALLOC(d1+d2+1); hi = W_UMALLOC(d1+d2+1);
334: mid1 = W_UMALLOC(d1+d2+1); mid2 = W_UMALLOC(d1+d2+1);
335: mid = W_UMALLOC(d1+d2+1);
336: s1 = W_UMALLOC(d1+d2+1); s2 = W_UMALLOC(d1+d2+1);
337: extractum(n1,0,h,n1lo); extractum(n1,h,d1-h,n1hi);
338: extractum(n2,0,h,n2lo); extractum(n2,h,d2-h,n2hi);
339: kmulum(mod,n1hi,n2hi,hi); kmulum(mod,n1lo,n2lo,lo);
340: len = DEG(hi)+1+2*h; t1 = W_UMALLOC(len-1); DEG(t1) = len-1;
341: bzero((char *)COEF(t1),len*sizeof(int));
342: if ( lo )
343: bcopy((char *)COEF(lo),(char *)COEF(t1),(DEG(lo)+1)*sizeof(int));
344: if ( hi )
345: bcopy((char *)COEF(hi),(char *)(COEF(t1)+2*h),(DEG(hi)+1)*sizeof(int));
346:
347: addum(mod,hi,lo,mid1);
348: subum(mod,n1hi,n1lo,s1); subum(mod,n2lo,n2hi,s2); kmulum(mod,s1,s2,mid2);
349: addum(mod,mid1,mid2,mid);
350: if ( mid ) {
351: len = DEG(mid)+1+h; t2 = W_UMALLOC(len-1); DEG(t2) = len-1;
352: bzero((char *)COEF(t2),len*sizeof(int));
353: bcopy((char *)COEF(mid),(char *)(COEF(t2)+h),(DEG(mid)+1)*sizeof(int));
354: addum(mod,t1,t2,nr);
355: } else
356: copyum(t1,nr);
357: }
358:
359: void ksquareummain(mod,n1,nr)
360: int mod;
361: UM n1,nr;
362: {
363: int d1,h,len;
364: UM n1lo,n1hi,hi,lo,mid1,mid2,mid,s1,t1,t2;
365:
366: d1 = DEG(n1)+1; h = (d1+1)/2;
367: n1lo = W_UMALLOC(d1+1); n1hi = W_UMALLOC(d1+1);
368: lo = W_UMALLOC(2*d1+1); hi = W_UMALLOC(2*d1+1);
369: mid1 = W_UMALLOC(2*d1+1); mid2 = W_UMALLOC(2*d1+1);
370: mid = W_UMALLOC(2*d1+1);
371: s1 = W_UMALLOC(2*d1+1);
372: extractum(n1,0,h,n1lo); extractum(n1,h,d1-h,n1hi);
373: ksquareum(mod,n1hi,hi); ksquareum(mod,n1lo,lo);
374: len = DEG(hi)+1+2*h; t1 = W_UMALLOC(len-1); DEG(t1) = len-1;
375: bzero((char *)COEF(t1),len*sizeof(int));
376: if ( lo )
377: bcopy((char *)COEF(lo),(char *)COEF(t1),(DEG(lo)+1)*sizeof(int));
378: if ( hi )
379: bcopy((char *)COEF(hi),(char *)(COEF(t1)+2*h),(DEG(hi)+1)*sizeof(int));
380:
381: addum(mod,hi,lo,mid1);
382: subum(mod,n1hi,n1lo,s1); ksquareum(mod,s1,mid2);
383: subum(mod,mid1,mid2,mid);
384: if ( mid ) {
385: len = DEG(mid)+1+h; t2 = W_UMALLOC(len-1); DEG(t2) = len-1;
386: bzero((char *)COEF(t2),len*sizeof(int));
387: bcopy((char *)COEF(mid),(char *)(COEF(t2)+h),(DEG(mid)+1)*sizeof(int));
388: addum(mod,t1,t2,nr);
389: } else
390: copyum(t1,nr);
391: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>