[BACK]Return to Z.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / engine

Annotation of OpenXM_contrib2/asir2000/engine/Z.c, Revision 1.3

1.2       noro        1: #if 0
1.1       noro        2: #include "ca.h"
                      3: #include "inline.h"
1.2       noro        4: #endif
1.1       noro        5:
                      6: typedef struct oZ {
                      7:        int p;
                      8:        unsigned int b[1];
                      9: } *Z;
                     10:
1.3     ! noro       11: #define IMM_MAX 1073741823
        !            12: #define IMM_MIN -1073741823
        !            13:
        !            14: /* immediate int -> Z */
        !            15: #define IMMTOZ(c,n) ((c)>=IMM_MIN&&(c)<=IMM_MAX?(n)=(Z)(((c)<<1)|1):(n)=immtoz(c))
        !            16: /* immediate Z ? */
        !            17: #define IS_IMM(c) (((unsigned int)c)&1)
        !            18: /* Z can be conver to immediate ? */
        !            19: #define IS_IMMZ(n) (SL(n) == 1&&BD(n)[0]<=IMM_MAX)
        !            20: /* Z -> immediate Z */
        !            21: #define IMMZTOZ(n,z) (SL(n)<0?(z)=(Z)(((-BD(n)[0])<<1)|1):(Z)(((BD(n)[0])<<1)|1))
        !            22: /* Z -> immediate int */
        !            23: #define ZTOIMM(c) (((int)(c))>>1)
1.1       noro       24: #define ZALLOC(d) ((Z)MALLOC_ATOMIC(TRUESIZE(oZ,(d)-1,int)))
                     25: #define SL(n) ((n)->p)
                     26:
1.3     ! noro       27: Z immtoz(int c);
1.1       noro       28: Z qtoz(Q n);
                     29: Q ztoq(Z n);
                     30: Z chsgnz(Z n);
                     31: Z dupz(Z n);
                     32: Z addz(Z n1,Z n2);
                     33: Z subz(Z n1,Z n2);
                     34: Z mulz(Z n1,Z n2);
                     35: Z divsz(Z n1,Z n2);
                     36: Z divz(Z n1,Z n2,Z *rem);
                     37: Z gcdz(Z n1,Z n2);
                     38: Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2);
                     39: Z estimate_array_gcdz(Z *a,int n);
                     40: Z array_gcdz(Z *a,int n);
1.2       noro       41: void mkwcz(int k,int l,Z *t);
1.1       noro       42: int remzi(Z n,int m);
                     43: inline void _addz(Z n1,Z n2,Z nr);
                     44: inline void _subz(Z n1,Z n2,Z nr);
                     45: inline void _mulz(Z n1,Z n2,Z nr);
                     46: inline int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
                     47: inline int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
                     48:
1.3     ! noro       49: Z immtoz(int c)
        !            50: {
        !            51:        Z z;
        !            52:
        !            53:        z = ZALLOC(1);
        !            54:        if ( c < 0 ) {
        !            55:                SL(z) = -1; BD(z)[0] = -c;
        !            56:        } else {
        !            57:                SL(z) = 1; BD(z)[0] = c;
        !            58:        }
        !            59:        return z;
        !            60: }
        !            61:
        !            62: int sgnz(Z n)
1.2       noro       63: {
                     64:        if ( !n ) return 0;
1.3     ! noro       65:        else if ( IS_IMM(n) ) return ZTOIMM(n)>0?1:1;
1.2       noro       66:        else if ( SL(n) < 0 ) return -1;
                     67:        else return 1;
                     68: }
                     69:
1.1       noro       70: z_mag(Z n)
                     71: {
1.3     ! noro       72:        int n;
        !            73:
        !            74:        if ( !n ) return 0;
        !            75:        else if ( IS_IMM(n) ) {
        !            76:                c = ZTOIMM(n);
        !            77:                if ( c < 0 ) c = -c;
        !            78:                for ( i = 0; c; c >>= 1, i++ );
        !            79:                return i;
        !            80:        }
        !            81:        else return n_bits((N)n);
1.1       noro       82: }
                     83:
                     84: Z qtoz(Q n)
                     85: {
1.3     ! noro       86:        Z r,t;
1.1       noro       87:
                     88:        if ( !n ) return 0;
                     89:        else if ( !INT(n) )
                     90:                error("qtoz : invalid input");
                     91:        else {
1.3     ! noro       92:                t = (Z)NM(n);
        !            93:                if ( IS_IMMZ(t) ) {
        !            94:                        IMMZTOZ(t,r);
        !            95:                } else {
        !            96:                        r = dupz((Z)t);
        !            97:                }
1.1       noro       98:                if ( SGN(n) < 0 ) SL(r) = -SL(r);
                     99:                return r;
                    100:        }
                    101: }
                    102:
                    103: Q ztoq(Z n)
                    104: {
                    105:        Q r;
                    106:        Z nm;
1.3     ! noro      107:        int sgn,c;
1.1       noro      108:
                    109:        if ( !n ) return 0;
1.3     ! noro      110:        else if ( IS_IMM(n) ) {
        !           111:                c = ZTOIMM(n);
        !           112:                STOQ(c,r);
        !           113:                return r;
        !           114:        } else {
1.1       noro      115:                nm = dupz(n);
                    116:                if ( SL(nm) < 0 ) {
                    117:                        sgn = -1;
                    118:                        SL(nm) = -SL(nm);
                    119:                } else
                    120:                        sgn = 1;
                    121:                NTOQ((N)nm,sgn,r);
                    122:                return r;
                    123:        }
                    124: }
                    125:
                    126: Z dupz(Z n)
                    127: {
                    128:        Z nr;
                    129:        int sd,i;
                    130:
                    131:        if ( !n ) return 0;
1.3     ! noro      132:        else if ( IS_IMM(n) ) return n;
        !           133:        else {
        !           134:                if ( (sd = SL(n)) < 0 ) sd = -sd;
        !           135:                nr = ZALLOC(sd);
        !           136:                SL(nr) = SL(n);
        !           137:                for ( i = 0; i < sd; i++ ) BD(nr)[i] = BD(n)[i];
        !           138:                return nr;
        !           139:        }
1.1       noro      140: }
                    141:
                    142: Z chsgnz(Z n)
                    143: {
                    144:        Z r;
1.3     ! noro      145:        int c;
1.1       noro      146:
                    147:        if ( !n ) return 0;
1.3     ! noro      148:        else if ( IS_IMM(n) ) {
        !           149:                c = -ZTOIMM(n);
        !           150:                IMMTOZ(c,r);
        !           151:                return r;
        !           152:        } else {
1.1       noro      153:                r = dupz(n);
                    154:                SL(r) = -SL(r);
                    155:                return r;
                    156:        }
                    157: }
                    158:
1.3     ! noro      159:
1.1       noro      160: Z addz(Z n1,Z n2)
                    161: {
1.3     ! noro      162:        int d1,d2,d,c;
        !           163:        Z r,r1;
        !           164:        struct oZ t;
1.1       noro      165:
                    166:        if ( !n1 ) return dupz(n2);
                    167:        else if ( !n2 ) return dupz(n1);
1.3     ! noro      168:        else if ( IS_IMM(n1) ) {
        !           169:                if ( IS_IMM(n2) ) {
        !           170:                        c = ZTOIMM(n1)+ZTOIMM(n2);
        !           171:                        IMMTOZ(c,r);
        !           172:                        return r;
        !           173:                } else {
        !           174:                        c = ZTOIMM(n1);
        !           175:                        if ( c < 0 ) {
        !           176:                                t.p = -1; t.b[0] = -c;
1.1       noro      177:                        } else {
1.3     ! noro      178:                                t.p = 1; t.b[0] = c;
1.1       noro      179:                        }
1.3     ! noro      180:                        if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
        !           181:                        r = ZALLOC(d2+1);
        !           182:                        _addz(&t,n2,r);
        !           183:                        return r;
        !           184:                }
        !           185:        } else if ( IS_IMM(n2) ) {
        !           186:                c = ZTOIMM(n2);
        !           187:                if ( c < 0 ) {
        !           188:                        t.p = -1; t.b[0] = -c;
1.1       noro      189:                } else {
1.3     ! noro      190:                        t.p = 1; t.b[0] = c;
        !           191:                }
        !           192:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
        !           193:                r = ZALLOC(d1+1);
        !           194:                _addz(n1,&t,r);
        !           195:                return r;
        !           196:        } else {
        !           197:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
        !           198:                if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
        !           199:                d = MAX(d1,d2)+1;
        !           200:                r = ZALLOC(d);
        !           201:                _addz(n1,n2,r);
        !           202:                if ( !SL(r) ) r = 0;
        !           203:                else if ( IS_IMMZ(r) ) {
        !           204:                        IMMZTOZ(r,r1); r = r1;
1.1       noro      205:                }
1.3     ! noro      206:                return r;
1.1       noro      207:        }
                    208: }
                    209:
                    210: Z subz(Z n1,Z n2)
                    211: {
1.3     ! noro      212:        int d1,d2,d,c;
        !           213:        Z r,r1;
        !           214:        struct oZ t;
1.1       noro      215:
1.3     ! noro      216:        if ( !n1 ) {
        !           217:                r = dupz(n2);
        !           218:                SL(r) = -SL(r);
        !           219:                return r;
        !           220:        } else if ( !n2 ) return dupz(n1);
        !           221:        else if ( IS_IMM(n1) ) {
        !           222:                if ( IS_IMM(n2) ) {
        !           223:                        c = ZTOIMM(n1)-ZTOIMM(n2);
        !           224:                        IMMTOZ(c,r);
        !           225:                        return r;
        !           226:                } else {
        !           227:                        c = ZTOIMM(n1);
        !           228:                        if ( c < 0 ) {
        !           229:                                t.p = -1; t.b[0] = -c;
        !           230:                        } else {
        !           231:                                t.p = 1; t.b[0] = c;
        !           232:                        }
        !           233:                        if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
        !           234:                        r = ZALLOC(d2+1);
        !           235:                        _subz(&t,n2,r);
        !           236:                        return r;
        !           237:                }
        !           238:        } else if ( IS_IMM(n2) ) {
        !           239:                c = ZTOIMM(n2);
        !           240:                if ( c < 0 ) {
        !           241:                        t.p = -1; t.b[0] = -c;
        !           242:                } else {
        !           243:                        t.p = 1; t.b[0] = c;
        !           244:                }
        !           245:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
        !           246:                r = ZALLOC(d1+1);
        !           247:                _subz(n1,&t,r);
        !           248:                return r;
        !           249:        } else {
        !           250:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
        !           251:                if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
        !           252:                d = MAX(d1,d2)+1;
        !           253:                r = ZALLOC(d);
        !           254:                _subz(n1,n2,r);
        !           255:                if ( !SL(r) ) r = 0;
        !           256:                else if ( IS_IMMZ(r) ) {
        !           257:                        IMMZTOZ(r,r1); r = r1;
1.1       noro      258:                }
1.3     ! noro      259:                return r;
1.1       noro      260:        }
                    261: }
                    262:
                    263: Z mulz(Z n1,Z n2)
                    264: {
1.3     ! noro      265:        int d1,d2,sgn,i;
1.1       noro      266:        unsigned int u1,u2,u,l;
1.3     ! noro      267:        Z r;
1.1       noro      268:
                    269:        if ( !n1 || !n2 ) return 0;
1.3     ! noro      270:
        !           271:        if ( IS_IMM(n1) ) {
        !           272:                sgn = 1;
        !           273:                u1 = ZTOIMM(n1); if ( u1 < 0 ) { sgn = -sgn; u1 = -u1; }
        !           274:                if ( IS_IMM(n2) ) {
        !           275:                        u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; }
1.1       noro      276:                        DM(u1,u2,u,l);
1.3     ! noro      277:                        if ( !u ) {
        !           278:                                IMMTOZ(l,r);
1.1       noro      279:                        } else {
1.3     ! noro      280:                                r = ZALLOC(2); SL(r) = 2; BD(r)[1] = u; BD(r)[0] = l;
1.1       noro      281:                        }
                    282:                } else {
1.3     ! noro      283:                        if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
        !           284:                        r = ZALLOC(d2+1);
        !           285:                        for ( i = d2; i >= 0; i-- ) BD(r)[i] = 0;
        !           286:                        muln_1(BD(n2),d2,u1,BD(r));
        !           287:                        SL(r) = BD(r)[d2]?d2+1:d2;
1.1       noro      288:                }
1.3     ! noro      289:        } else if ( IS_IMM(n2) ) {
        !           290:                sgn = 1;
        !           291:                u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; }
        !           292:                if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
        !           293:                r = ZALLOC(d1+1);
        !           294:                for ( i = d1; i >= 0; i-- ) BD(r)[i] = 0;
        !           295:                muln_1(BD(n1),d1,u2,BD(r));
        !           296:                SL(r) = BD(r)[d1]?d1+1:d1;
        !           297:        } else {
        !           298:                sgn = 1;
        !           299:                if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
        !           300:                if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
        !           301:                r = ZALLOC(d1+d2);
        !           302:                _mulz(n1,n2,r);
1.1       noro      303:        }
1.3     ! noro      304:        if ( sgn < 0 ) SL(r) = -SL(r);
        !           305:        return r;
1.1       noro      306: }
                    307:
1.3     ! noro      308: /* kokokara */
1.1       noro      309:
                    310: Z divsz(Z n1,Z n2)
                    311: {
1.3     ! noro      312:        int sgn,d1,d2;
        !           313:        Z q;
1.1       noro      314:
                    315:        if ( !n2 ) error("divsz : division by 0");
1.3     ! noro      316:        if ( !n1 ) return 0;
        !           317:
        !           318:        if ( IS_IMM(n1) ) {
        !           319:                if ( !IS_IMM(n2) )
        !           320:                        error("divsz : cannot happen");
        !           321:                c = ZTOIMM(n1)/ZTOIMM(n2);
        !           322:                IMMTOZ(c,q);
        !           323:                return q;
1.1       noro      324:        }
1.3     ! noro      325:        if ( IS_IMM(n2) ) {
        !           326:                sgn = 1;
        !           327:                u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; }
        !           328:                diviz(n1,u2,&q);
        !           329:                if ( sgn < 0 ) SL(q) = -SL(q);
        !           330:                return q;
        !           331:        }
        !           332:
        !           333:        sgn = 1;
        !           334:        if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
        !           335:        if ( d2 == 1 ) {
        !           336:                diviz(n1,BD(u2)[0],&q);
        !           337:                if ( sgn < 0 ) SL(q) = -SL(q);
        !           338:                return q;
        !           339:        }
        !           340:        if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
        !           341:        if ( d1 < d2 ) error("divsz : cannot happen");
        !           342:        return q;
1.1       noro      343: }
                    344:
                    345: Z gcdz(Z n1,Z n2)
                    346: {
1.3     ! noro      347:        int d1,d2;
1.1       noro      348:        N gcd;
                    349:
                    350:        if ( !n1 ) return n2;
                    351:        else if ( !n2 ) return n1;
                    352:
                    353:        n1 = dupz(n1);
                    354:        if ( SL(n1) < 0 ) SL(n1) = -SL(n1);
                    355:        n2 = dupz(n2);
                    356:        if ( SL(n2) < 0 ) SL(n2) = -SL(n2);
                    357:        gcdn((N)n1,(N)n2,&gcd);
                    358:        return (Z)gcd;
                    359: }
                    360:
                    361: int remzi(Z n,int m)
                    362: {
                    363:        unsigned int *x;
                    364:        unsigned int t,r;
                    365:        int i;
                    366:
                    367:        if ( !n ) return 0;
                    368:        i = SL(n);
                    369:        if ( i < 0 ) i = -i;
                    370:        for ( i--, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) {
                    371: #if defined(sparc)
                    372:                r = dsa(m,r,*x);
                    373: #else
                    374:                DSAB(m,r,*x,t,r);
                    375: #endif
                    376:        }
                    377:        return r;
                    378: }
                    379:
                    380: Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2)
                    381: {
                    382:        Z gcd;
                    383:
                    384:        gcd = gcdz(n1,n2);
                    385:        *c1 = divsz(n1,gcd);
                    386:        *c2 = divsz(n2,gcd);
                    387:        return gcd;
                    388: }
                    389:
                    390: Z estimate_array_gcdz(Z *b,int n)
                    391: {
                    392:        int m,i,j,sd;
                    393:        Z *a;
                    394:        Z s,t;
                    395:
                    396:        a = (Z *)ALLOCA(n*sizeof(Z));
                    397:        for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
                    398:        n = j;
                    399:        if ( !n ) return 0;
                    400:        if ( n == 1 ) return a[0];
                    401:
                    402:        m = n/2;
                    403:        for ( i = 0, s = 0; i < m; i++ ) {
                    404:                if ( !a[i] ) continue;
                    405:                else s = (SL(a[i])<0)?subz(s,a[i]):addz(s,a[i]);
                    406:        }
                    407:        for ( t = 0; i < n; i++ ) {
                    408:                if ( !a[i] ) continue;
                    409:                else t = (SL(a[i])<0)?subz(t,a[i]):addz(t,a[i]);
                    410:        }
                    411:        return gcdz(s,t);
                    412: }
                    413:
                    414: Z array_gcdz(Z *b,int n)
                    415: {
                    416:        int m,i,j,sd;
                    417:        Z *a;
                    418:        Z gcd;
                    419:
                    420:        a = (Z *)ALLOCA(n*sizeof(Z));
                    421:        for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
                    422:        n = j;
                    423:        if ( !n ) return 0;
                    424:        if ( n == 1 ) return a[0];
                    425:        gcd = a[0];
                    426:        for ( i = 1; i < n; i++ )
                    427:                gcd = gcdz(gcd,a[i]);
                    428:        return gcd;
                    429: }
                    430:
                    431: void _copyz(Z n1,Z n2)
                    432: {
                    433:        int n,i;
                    434:
                    435:        if ( !n1 || !SL(n1) ) SL(n2) = 0;
                    436:        else {
                    437:                n = SL(n2) = SL(n1);
                    438:                if ( n < 0 ) n = -n;
                    439:                for ( i = 0; i < n; i++ ) BD(n2)[i] = BD(n1)[i];
                    440:        }
                    441: }
                    442:
                    443: void _addz(Z n1,Z n2,Z nr)
                    444: {
1.3     ! noro      445:        int d1,d2;
1.1       noro      446:
                    447:        if ( !n1 || !SL(n1) ) _copyz(n2,nr);
                    448:        else if ( !n2 || !SL(n2) ) _copyz(n1,nr);
1.3     ! noro      449:        else if ( (d1=SL(n1)) > 0 )
        !           450:                if ( (d2=SL(n2)) > 0 )
        !           451:                        SL(nr) = _addz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1       noro      452:                else
1.3     ! noro      453:                        SL(nr) = _subz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
        !           454:        else if ( (d2=SL(n2)) > 0 )
        !           455:                SL(nr) = _subz_main(BD(n2),d2,BD(n1),-d1,BD(nr));
1.1       noro      456:        else
1.3     ! noro      457:                SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1       noro      458: }
                    459:
                    460: void _subz(Z n1,Z n2,Z nr)
                    461: {
1.3     ! noro      462:        int d1,d2;
1.1       noro      463:
                    464:        if ( !n1 || !SL(n1) ) _copyz(n2,nr);
                    465:        else if ( !n2 || !SL(n2) ) {
                    466:                _copyz(n1,nr);
                    467:                SL(nr) = -SL(nr);
1.3     ! noro      468:        } else if ( (d1=SL(n1)) > 0 )
        !           469:                if ( (d2=SL(n2)) > 0 )
        !           470:                        SL(nr) = _subz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1       noro      471:                else
1.3     ! noro      472:                        SL(nr) = _addz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
        !           473:        else if ( (d2=SL(n2)) > 0 )
        !           474:                SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),d2,BD(nr));
1.1       noro      475:        else
1.3     ! noro      476:                SL(nr) = -_subz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1       noro      477: }
                    478:
                    479: void _mulz(Z n1,Z n2,Z nr)
                    480: {
1.3     ! noro      481:        int d1,d2;
1.1       noro      482:        int i,d,sgn;
                    483:        unsigned int mul;
                    484:        unsigned int *m1,*m2;
                    485:
                    486:        if ( !n1 || !SL(n1) || !n2 || !SL(n2) )
                    487:                SL(nr) = 0;
                    488:        else {
1.3     ! noro      489:                d1 = SL(n1); d2 = SL(n2);
1.1       noro      490:                sgn = 1;
1.3     ! noro      491:                if ( d1 < 0 ) { sgn = -sgn; d1 = -d1; }
        !           492:                if ( d2 < 0 ) { sgn = -sgn; d2 = -d2; }
        !           493:                d = d1+d2;
1.1       noro      494:                for ( i = d-1, m1 = BD(nr); i >= 0; i-- ) *m1++ = 0;
1.3     ! noro      495:                for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
        !           496:                        if ( mul = *m2 ) muln_1(m1,d1,mul,BD(nr)+i);
1.1       noro      497:                SL(nr) = sgn*(BD(nr)[d-1]?d:d-1);
                    498:        }
                    499: }
                    500:
                    501: int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
                    502: {
                    503:        int d,i;
                    504:        unsigned int tmp,c;
                    505:        unsigned int *t;
                    506:
                    507:        if ( d2 > d1 ) {
                    508:                t = m1; m1 = m2; m2 = t;
                    509:                d = d1; d1 = d2; d2 = d;
                    510:        }
                    511: #if defined(VISUAL)
                    512:        __asm {
                    513:        push    esi
                    514:        push    edi
                    515:        mov esi,m1
                    516:        mov edi,m2
                    517:        mov ebx,mr
                    518:        mov ecx,d2
                    519:        xor     eax,eax
                    520:        Lstart__addz:
                    521:        mov eax,DWORD PTR [esi]
                    522:        mov edx,DWORD PTR [edi]
                    523:        adc eax,edx
                    524:        mov DWORD PTR [ebx],eax
                    525:        lea esi,DWORD PTR [esi+4]
                    526:        lea edi,DWORD PTR [edi+4]
                    527:        lea ebx,DWORD PTR [ebx+4]
                    528:        dec ecx
                    529:        jnz Lstart__addz
                    530:        pop     edi
                    531:        pop     esi
                    532:        mov eax,0
                    533:        adc eax,eax
                    534:        mov c,eax
                    535:        }
                    536: #elif defined(i386)
                    537:        asm volatile("\
                    538:        movl    %1,%%esi;\
                    539:        movl    %2,%%edi;\
                    540:        movl    %3,%%ebx;\
                    541:        movl    %4,%%ecx;\
                    542:        testl   %%eax,%%eax;\
                    543:        Lstart__addz:;\
                    544:        movl    (%%esi),%%eax;\
                    545:        movl    (%%edi),%%edx;\
                    546:        adcl    %%edx,%%eax;\
                    547:        movl    %%eax,(%%ebx);\
                    548:        leal    4(%%esi),%%esi;\
                    549:        leal    4(%%edi),%%edi;\
                    550:        leal    4(%%ebx),%%ebx;\
                    551:        decl    %%ecx;\
                    552:        jnz Lstart__addz;\
                    553:        movl    $0,%%eax;\
                    554:        adcl    %%eax,%%eax;\
                    555:        movl    %%eax,%0"\
                    556:        :"=m"(c)\
                    557:        :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
                    558:        :"eax","ebx","ecx","edx","esi","edi");
                    559: #else
                    560:        for ( i = 0, c = 0, mr = BD(nr); i < d2; i++, m1++, m2++, mr++ ) {
                    561:                tmp = *m1 + *m2;
                    562:                if ( tmp < *m1 ) {
                    563:                        tmp += c;
                    564:                        c = 1;
                    565:                } else {
                    566:                        tmp += c;
                    567:                        c = tmp < c ? 1 : 0;
                    568:                }
                    569:                *mr = tmp;
                    570:        }
                    571: #endif
                    572:        for ( i = d2, m1 += d2, mr += d2; (i < d1) && c ; i++ ) {
                    573:                tmp = *m1++ + c;
                    574:                c = tmp < c ? 1 : 0;
                    575:                *mr++ = tmp;
                    576:        }
                    577:        for ( ; i < d1; i++ )
                    578:                        *mr++ = *m1++;
                    579:        *mr = c;
                    580:        return (c?d1+1:d1);
                    581: }
                    582:
                    583: int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
                    584: {
                    585:        int d,i,sgn;
                    586:        unsigned int t,tmp,br;
                    587:        unsigned int *m;
                    588:
                    589:        if ( d1 > d2 ) sgn = 1;
                    590:        else if ( d1 < d2 ) sgn = -1;
                    591:        else {
                    592:                for ( i = d1-1; i >= 0 && m1[i] == m2[i]; i-- );
                    593:                if ( i < 0 ) return 0;
                    594:                if ( m1[i] > m2[i] ) sgn = 1;
                    595:                else if ( m1[i] < m2[i] ) sgn = -1;
                    596:        }
                    597:        if ( sgn < 0 ) {
                    598:                m = m1; m1 = m2; m2 = m;
                    599:                d = d1; d1 = d2; d2 = d;
                    600:        }
                    601: #if defined(VISUAL)
                    602:        __asm {
                    603:        push    esi
                    604:        push    edi
                    605:        mov esi,m1
                    606:        mov edi,m2
                    607:        mov ebx,mr
                    608:        mov ecx,d2
                    609:        xor     eax,eax
                    610:        Lstart__subz:
                    611:        mov eax,DWORD PTR [esi]
                    612:        mov edx,DWORD PTR [edi]
                    613:        sbb eax,edx
                    614:        mov DWORD PTR [ebx],eax
                    615:        lea esi,DWORD PTR [esi+4]
                    616:        lea edi,DWORD PTR [edi+4]
                    617:        lea ebx,DWORD PTR [ebx+4]
                    618:        dec ecx
                    619:        jnz Lstart__subz
                    620:        pop     edi
                    621:        pop     esi
                    622:        mov eax,0
                    623:        adc eax,eax
                    624:        mov br,eax
                    625:        }
                    626: #elif defined(i386)
                    627:        asm volatile("\
                    628:        movl    %1,%%esi;\
                    629:        movl    %2,%%edi;\
                    630:        movl    %3,%%ebx;\
                    631:        movl    %4,%%ecx;\
                    632:        testl   %%eax,%%eax;\
                    633:        Lstart__subz:;\
                    634:        movl    (%%esi),%%eax;\
                    635:        movl    (%%edi),%%edx;\
                    636:        sbbl    %%edx,%%eax;\
                    637:        movl    %%eax,(%%ebx);\
                    638:        leal    4(%%esi),%%esi;\
                    639:        leal    4(%%edi),%%edi;\
                    640:        leal    4(%%ebx),%%ebx;\
                    641:        decl    %%ecx;\
                    642:        jnz Lstart__subz;\
                    643:        movl    $0,%%eax;\
                    644:        adcl    %%eax,%%eax;\
                    645:        movl    %%eax,%0"\
                    646:        :"=m"(br)\
                    647:        :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
                    648:        :"eax","ebx","ecx","edx","esi","edi");
                    649: #else
                    650:        for ( i = 0, br = 0, mr = BD(nr); i < d2; i++, mr++ ) {
                    651:                t = *m1++;
                    652:                tmp = *m2++ + br;
                    653:                if ( br > 0 && !tmp ) {
                    654:                        /* tmp = 2^32 => br = 1 */
                    655:                }else {
                    656:                        tmp = t-tmp;
                    657:                        br = tmp > t ? 1 : 0;
                    658:                        *mr = tmp;
                    659:                }
                    660:        }
                    661: #endif
                    662:        for ( i = d2, m1 += d2, mr += d2; (i < d1) && br; i++ ) {
                    663:                t = *m1++;
                    664:                tmp = t - br;
                    665:                br = tmp > t ? 1 : 0;
                    666:                *mr++ = tmp;
                    667:        }
                    668:        for ( ; i < d1; i++ )
                    669:                *mr++ = *m1++;
                    670:        for ( i = d1-1, mr--; i >= 0 && !*mr--; i-- );
                    671:        return sgn*(i+1);
                    672: }
                    673:
                    674: /* XXX */
                    675:
                    676: void printz(Z n)
                    677: {
                    678:        int sd;
                    679:
                    680:        if ( !n )
                    681:                fprintf(asir_out,"0");
                    682:        else {
                    683:                if ( (sd = SL(n)) < 0 ) { SL(n) = -SL(n); fprintf(asir_out,"-"); }
                    684:                printn((N)n);
                    685:                if ( sd < 0 ) SL(n) = -SL(n);
1.2       noro      686:        }
                    687: }
                    688:
                    689: /*
                    690:  *  Dx^k*x^l = W(k,l,0)*x^l*Dx^k+W(k,l,1)*x^(l-1)*x^(k-1)*+...
                    691:  *
                    692:  *  t = [W(k,l,0) W(k,l,1) ... W(k,l,min(k,l)]
                    693:  *  where W(k,l,i) = i! * kCi * lCi
                    694:  */
                    695:
                    696: void mkwcz(int k,int l,Z *t)
                    697: {
                    698:        int i,n,up,low;
                    699:        N nm,d,c;
                    700:
                    701:        n = MIN(k,l);
                    702:        for ( t[0] = (Z)ONEN, i = 1; i <= n; i++ ) {
                    703:                DM(k-i+1,l-i+1,up,low);
                    704:                if ( up ) {
                    705:                        nm = NALLOC(2); PL(nm) = 2; BD(nm)[0] = low; BD(nm)[1] = up;
                    706:                } else {
                    707:                        nm = NALLOC(1); PL(nm) = 1; BD(nm)[0] = low;
                    708:                }
                    709:                kmuln((N)t[i-1],nm,&d); divin(d,i,&c); t[i] = (Z)c;
1.1       noro      710:        }
                    711: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>