Annotation of lucent/sys/src/alef/k/mul.c, revision 1.1

1.1     ! root        1: #include <u.h>
        !             2: #include <libc.h>
        !             3: #include <bio.h>
        !             4: #include <ctype.h>
        !             5: #define Extern extern
        !             6: #include "parl.h"
        !             7: #include "globl.h"
        !             8: 
        !             9: /*
        !            10:  * code sequences for multiply by constant.
        !            11:  * [a-l][0-3]
        !            12:  *     lsl     $(A-'a'),r0,r1
        !            13:  * [+][0-7]
        !            14:  *     add     r0,r1,r2
        !            15:  * [-][0-7]
        !            16:  *     sub     r0,r1,r2
        !            17:  */
        !            18: 
        !            19: static int     multabp;
        !            20: static long    mulval;
        !            21: static char*   mulcp;
        !            22: static long    valmax;
        !            23: static int     shmax;
        !            24: 
        !            25: static int     docode(char *hp, char *cp, int r0, int r1);
        !            26: static int     gen1(int len);
        !            27: static int     gen2(int len, long r1);
        !            28: static int     gen3(int len, long r0, long r1, int flag);
        !            29: enum
        !            30: {
        !            31:        SR1     = 1<<0,         /* r1 has been shifted */
        !            32:        SR0     = 1<<1,         /* r0 has been shifted */
        !            33:        UR1     = 1<<2,         /* r1 has not been used */
        !            34:        UR0     = 1<<3,         /* r0 has not been used */
        !            35: };
        !            36: 
        !            37: Multab*
        !            38: mulcon0(long v)
        !            39: {
        !            40:        int a1, a2, g;
        !            41:        Multab *m, *m1;
        !            42:        char hint[10];
        !            43: 
        !            44:        if(v < 0)
        !            45:                v = -v;
        !            46: 
        !            47:        /*
        !            48:         * look in cache
        !            49:         */
        !            50:        m = multab;
        !            51:        for(g=0; g<nelem(multab); g++) {
        !            52:                if(m->val == v) {
        !            53:                        if(m->code[0] == 0)
        !            54:                                return 0;
        !            55:                        return m;
        !            56:                }
        !            57:                m++;
        !            58:        }
        !            59: 
        !            60:        /*
        !            61:         * select a spot in cache to overwrite
        !            62:         */
        !            63:        multabp++;
        !            64:        if(multabp < 0 || multabp >= nelem(multab))
        !            65:                multabp = 0;
        !            66:        m = multab+multabp;
        !            67:        m->val = v;
        !            68:        mulval = v;
        !            69: 
        !            70:        /*
        !            71:         * look in execption hint table
        !            72:         */
        !            73:        a1 = 0;
        !            74:        a2 = hintabsize;
        !            75:        for(;;) {
        !            76:                if(a1 >= a2)
        !            77:                        goto no;
        !            78:                g = (a2 + a1)/2;
        !            79:                if(v < hintab[g].val) {
        !            80:                        a2 = g;
        !            81:                        continue;
        !            82:                }
        !            83:                if(v > hintab[g].val) {
        !            84:                        a1 = g+1;
        !            85:                        continue;
        !            86:                }
        !            87:                break;
        !            88:        }
        !            89: 
        !            90:        if(docode(hintab[g].hint, m->code, 1, 0))
        !            91:                return m;
        !            92:        print("multiply table failure %ld\n", v);
        !            93:        m->code[0] = 0;
        !            94:        return 0;
        !            95: 
        !            96: no:
        !            97:        /*
        !            98:         * try to search
        !            99:         */
        !           100:        hint[0] = 0;
        !           101:        for(g=1; g<=6; g++) {
        !           102:                if(g >= 6 && v >= 65535)
        !           103:                        break;
        !           104:                mulcp = hint+g;
        !           105:                *mulcp = 0;
        !           106:                if(gen1(g)) {
        !           107:                        if(docode(hint, m->code, 1, 0))
        !           108:                                return m;
        !           109:                        print("multiply table failure %ld\n", v);
        !           110:                        break;
        !           111:                }
        !           112:        }
        !           113: 
        !           114:        /*
        !           115:         * try a recur followed by a shift
        !           116:         */
        !           117:        g = 0;
        !           118:        while(!(v & 1)) {
        !           119:                g++;
        !           120:                v >>= 1;
        !           121:        }
        !           122:        if(g) {
        !           123:                m1 = mulcon0(v);
        !           124:                if(m1) {
        !           125:                        strcpy(m->code, m1->code);
        !           126:                        sprint(strchr(m->code, 0), "%c0", g+'a');
        !           127:                        return m;
        !           128:                }
        !           129:        }
        !           130:        m->code[0] = 0;
        !           131:        return 0;
        !           132: }
        !           133: 
        !           134: static int
        !           135: docode(char *hp, char *cp, int r0, int r1)
        !           136: {
        !           137:        int c, i;
        !           138: 
        !           139:        c = *hp++;
        !           140:        *cp = c;
        !           141:        cp += 2;
        !           142:        switch(c) {
        !           143:        default:
        !           144:                c -= 'a';
        !           145:                if(c < 1 || c >= 30)
        !           146:                        break;
        !           147:                for(i=0; i<4; i++) {
        !           148:                        switch(i) {
        !           149:                        case 0:
        !           150:                                if(docode(hp, cp, r0<<c, r1))
        !           151:                                        goto out;
        !           152:                                break;
        !           153:                        case 1:
        !           154:                                if(docode(hp, cp, r1<<c, r1))
        !           155:                                        goto out;
        !           156:                                break;
        !           157:                        case 2:
        !           158:                                if(docode(hp, cp, r0, r0<<c))
        !           159:                                        goto out;
        !           160:                                break;
        !           161:                        case 3:
        !           162:                                if(docode(hp, cp, r0, r1<<c))
        !           163:                                        goto out;
        !           164:                                break;
        !           165:                        }
        !           166:                }
        !           167:                break;
        !           168: 
        !           169:        case '+':
        !           170:                for(i=0; i<8; i++) {
        !           171:                        cp[-1] = i+'0';
        !           172:                        switch(i) {
        !           173:                        case 1:
        !           174:                                if(docode(hp, cp, r0+r1, r1))
        !           175:                                        goto out;
        !           176:                                break;
        !           177:                        case 5:
        !           178:                                if(docode(hp, cp, r0, r0+r1))
        !           179:                                        goto out;
        !           180:                                break;
        !           181:                        }
        !           182:                }
        !           183:                break;
        !           184: 
        !           185:        case '-':
        !           186:                for(i=0; i<8; i++) {
        !           187:                        cp[-1] = i+'0';
        !           188:                        switch(i) {
        !           189:                        case 1:
        !           190:                                if(docode(hp, cp, r0-r1, r1))
        !           191:                                        goto out;
        !           192:                                break;
        !           193:                        case 2:
        !           194:                                if(docode(hp, cp, r1-r0, r1))
        !           195:                                        goto out;
        !           196:                                break;
        !           197:                        case 5:
        !           198:                                if(docode(hp, cp, r0, r0-r1))
        !           199:                                        goto out;
        !           200:                                break;
        !           201:                        case 6:
        !           202:                                if(docode(hp, cp, r0, r1-r0))
        !           203:                                        goto out;
        !           204:                                break;
        !           205:                        }
        !           206:                }
        !           207:                break;
        !           208: 
        !           209:        case 0:
        !           210:                if(r0 == mulval)
        !           211:                        return 1;
        !           212:        }
        !           213:        return 0;
        !           214: 
        !           215: out:
        !           216:        cp[-1] = i+'0';
        !           217:        return 1;
        !           218: }
        !           219: 
        !           220: static int
        !           221: gen1(int len)
        !           222: {
        !           223:        int i;
        !           224: 
        !           225:        for(shmax=1; shmax<30; shmax++) {
        !           226:                valmax = 1<<shmax;
        !           227:                if(valmax >= mulval)
        !           228:                        break;
        !           229:        }
        !           230:        if(mulval == 1)
        !           231:                return 1;
        !           232: 
        !           233:        len--;
        !           234:        for(i=1; i<=shmax; i++)
        !           235:                if(gen2(len, 1<<i)) {
        !           236:                        *--mulcp = 'a'+i;
        !           237:                        return 1;
        !           238:                }
        !           239:        return 0;
        !           240: }
        !           241: 
        !           242: static int
        !           243: gen2(int len, long r1)
        !           244: {
        !           245:        int i;
        !           246: 
        !           247:        if(len <= 0) {
        !           248:                if(r1 == mulval)
        !           249:                        return 1;
        !           250:                return 0;
        !           251:        }
        !           252: 
        !           253:        len--;
        !           254:        if(len == 0)
        !           255:                goto calcr0;
        !           256: 
        !           257:        if(gen3(len, r1, r1+1, UR1)) {
        !           258:                i = '+';
        !           259:                goto out;
        !           260:        }
        !           261:        if(gen3(len, r1-1, r1, UR0)) {
        !           262:                i = '-';
        !           263:                goto out;
        !           264:        }
        !           265:        if(gen3(len, 1, r1+1, UR1)) {
        !           266:                i = '+';
        !           267:                goto out;
        !           268:        }
        !           269:        if(gen3(len, 1, r1-1, UR1)) {
        !           270:                i = '-';
        !           271:                goto out;
        !           272:        }
        !           273: 
        !           274:        return 0;
        !           275: 
        !           276: calcr0:
        !           277:        if(mulval == r1+1) {
        !           278:                i = '+';
        !           279:                goto out;
        !           280:        }
        !           281:        if(mulval == r1-1) {
        !           282:                i = '-';
        !           283:                goto out;
        !           284:        }
        !           285:        return 0;
        !           286: 
        !           287: out:
        !           288:        *--mulcp = i;
        !           289:        return 1;
        !           290: }
        !           291: 
        !           292: static int
        !           293: gen3(int len, long r0, long r1, int flag)
        !           294: {
        !           295:        int i, f1, f2;
        !           296:        long x;
        !           297: 
        !           298:        if(r0 <= 0 ||
        !           299:           r0 >= r1 ||
        !           300:           r1 > valmax)
        !           301:                return 0;
        !           302: 
        !           303:        len--;
        !           304:        if(len == 0)
        !           305:                goto calcr0;
        !           306: 
        !           307:        if(!(flag & UR1)) {
        !           308:                f1 = UR1|SR1;
        !           309:                for(i=1; i<=shmax; i++) {
        !           310:                        x = r0<<i;
        !           311:                        if(x > valmax)
        !           312:                                break;
        !           313:                        if(gen3(len, r0, x, f1)) {
        !           314:                                i += 'a';
        !           315:                                goto out;
        !           316:                        }
        !           317:                }
        !           318:        }
        !           319: 
        !           320:        if(!(flag & UR0)) {
        !           321:                f1 = UR1|SR1;
        !           322:                for(i=1; i<=shmax; i++) {
        !           323:                        x = r1<<i;
        !           324:                        if(x > valmax)
        !           325:                                break;
        !           326:                        if(gen3(len, r1, x, f1)) {
        !           327:                                i += 'a';
        !           328:                                goto out;
        !           329:                        }
        !           330:                }
        !           331:        }
        !           332: 
        !           333:        if(!(flag & SR1)) {
        !           334:                f1 = UR1|SR1|(flag&UR0);
        !           335:                for(i=1; i<=shmax; i++) {
        !           336:                        x = r1<<i;
        !           337:                        if(x > valmax)
        !           338:                                break;
        !           339:                        if(gen3(len, r0, x, f1)) {
        !           340:                                i += 'a';
        !           341:                                goto out;
        !           342:                        }
        !           343:                }
        !           344:        }
        !           345: 
        !           346:        if(!(flag & SR0)) {
        !           347:                f1 = UR0|SR0|(flag&(SR1|UR1));
        !           348: 
        !           349:                f2 = UR1|SR1;
        !           350:                if(flag & UR1)
        !           351:                        f2 |= UR0;
        !           352:                if(flag & SR1)
        !           353:                        f2 |= SR0;
        !           354: 
        !           355:                for(i=1; i<=shmax; i++) {
        !           356:                        x = r0<<i;
        !           357:                        if(x > valmax)
        !           358:                                break;
        !           359:                        if(x > r1) {
        !           360:                                if(gen3(len, r1, x, f2)) {
        !           361:                                        i += 'a';
        !           362:                                        goto out;
        !           363:                                }
        !           364:                        } else
        !           365:                                if(gen3(len, x, r1, f1)) {
        !           366:                                        i += 'a';
        !           367:                                        goto out;
        !           368:                                }
        !           369:                }
        !           370:        }
        !           371: 
        !           372:        x = r1+r0;
        !           373:        if(gen3(len, r0, x, UR1)) {
        !           374:                i = '+';
        !           375:                goto out;
        !           376:        }
        !           377: 
        !           378:        if(gen3(len, r1, x, UR1)) {
        !           379:                i = '+';
        !           380:                goto out;
        !           381:        }
        !           382: 
        !           383:        x = r1-r0;
        !           384:        if(gen3(len, x, r1, UR0)) {
        !           385:                i = '-';
        !           386:                goto out;
        !           387:        }
        !           388: 
        !           389:        if(x > r0) {
        !           390:                if(gen3(len, r0, x, UR1)) {
        !           391:                        i = '-';
        !           392:                        goto out;
        !           393:                }
        !           394:        } else
        !           395:                if(gen3(len, x, r0, UR0)) {
        !           396:                        i = '-';
        !           397:                        goto out;
        !           398:                }
        !           399: 
        !           400:        return 0;
        !           401: 
        !           402: calcr0:
        !           403:        f1 = flag & (UR0|UR1);
        !           404:        if(f1 == UR1) {
        !           405:                for(i=1; i<=shmax; i++) {
        !           406:                        x = r1<<i;
        !           407:                        if(x >= mulval) {
        !           408:                                if(x == mulval) {
        !           409:                                        i += 'a';
        !           410:                                        goto out;
        !           411:                                }
        !           412:                                break;
        !           413:                        }
        !           414:                }
        !           415:        }
        !           416: 
        !           417:        if(mulval == r1+r0) {
        !           418:                i = '+';
        !           419:                goto out;
        !           420:        }
        !           421:        if(mulval == r1-r0) {
        !           422:                i = '-';
        !           423:                goto out;
        !           424:        }
        !           425: 
        !           426:        return 0;
        !           427: 
        !           428: out:
        !           429:        *--mulcp = i;
        !           430:        return 1;
        !           431: }
        !           432: 
        !           433: /*
        !           434:  * hint table has numbers that
        !           435:  * the search algorithm fails on.
        !           436:  * <1000:
        !           437:  *     all numbers
        !           438:  * <5000:
        !           439:  *     ÷ by 5
        !           440:  * <10000:
        !           441:  *     ÷ by 50
        !           442:  * <65536:
        !           443:  *     ÷ by 250
        !           444:  */
        !           445: Hintab hintab[] =
        !           446: {
        !           447:        683,    "b++d+e+",
        !           448:        687,    "b+e++e-",
        !           449:        691,    "b++d+e+",
        !           450:        731,    "b++d+e+",
        !           451:        811,    "b++d+i+",
        !           452:        821,    "b++e+e+",
        !           453:        843,    "b+d++e+",
        !           454:        851,    "b+f-+e-",
        !           455:        853,    "b++e+e+",
        !           456:        877,    "c++++g-",
        !           457:        933,    "b+c++g-",
        !           458:        981,    "c-+e-d+",
        !           459:        1375,   "b+c+b+h-",
        !           460:        1675,   "d+b++h+",
        !           461:        2425,   "c++f-e+",
        !           462:        2675,   "c+d++f-",
        !           463:        2750,   "b+d-b+h-",
        !           464:        2775,   "c-+g-e-",
        !           465:        3125,   "b++e+g+",
        !           466:        3275,   "b+c+g+e+",
        !           467:        3350,   "c++++i+",
        !           468:        3475,   "c-+e-f-",
        !           469:        3525,   "c-+d+g-",
        !           470:        3625,   "c-+e-j+",
        !           471:        3675,   "b+d+d+e+",
        !           472:        3725,   "b+d-+h+",
        !           473:        3925,   "b+d+f-d-",
        !           474:        4275,   "b+g++e+",
        !           475:        4325,   "b+h-+d+",
        !           476:        4425,   "b+b+g-j-",
        !           477:        4525,   "b+d-d+f+",
        !           478:        4675,   "c++d-g+",
        !           479:        4775,   "b+d+b+g-",
        !           480:        4825,   "c+c-+i-",
        !           481:        4850,   "c++++i-",
        !           482:        4925,   "b++e-g-",
        !           483:        4975,   "c+f++e-",
        !           484:        5500,   "b+g-c+d+",
        !           485:        6700,   "d+b++i+",
        !           486:        9700,   "d++++j-",
        !           487:        11000,  "b+f-c-h-",
        !           488:        11750,  "b+d+g+j-",
        !           489:        12500,  "b+c+e-k+",
        !           490:        13250,  "b+d+e-f+",
        !           491:        13750,  "b+h-c-d+",
        !           492:        14250,  "b+g-c+e-",
        !           493:        14500,  "c+f+j-d-",
        !           494:        14750,  "d-g--f+",
        !           495:        16750,  "b+e-d-n+",
        !           496:        17750,  "c+h-b+e+",
        !           497:        18250,  "d+b+h-d+",
        !           498:        18750,  "b+g-++f+",
        !           499:        19250,  "b+e+b+h+",
        !           500:        19750,  "b++h--f-",
        !           501:        20250,  "b+e-l-c+",
        !           502:        20750,  "c++bi+e-",
        !           503:        21250,  "b+i+l+c+",
        !           504:        22000,  "b+e+d-g-",
        !           505:        22250,  "b+d-h+k-",
        !           506:        22750,  "b+d-e-g+",
        !           507:        23250,  "b+c+h+e-",
        !           508:        23500,  "b+g-c-g-",
        !           509:        23750,  "b+g-b+h-",
        !           510:        24250,  "c++g+m-",
        !           511:        24750,  "b+e+e+j-",
        !           512:        25000,  "b++dh+g+",
        !           513:        25250,  "b+e+d-g-",
        !           514:        25750,  "b+e+b+j+",
        !           515:        26250,  "b+h+c+e+",
        !           516:        26500,  "b+h+c+g+",
        !           517:        26750,  "b+d+e+g-",
        !           518:        27250,  "b+e+e+f+",
        !           519:        27500,  "c-i-c-d+",
        !           520:        27750,  "b+bd++j+",
        !           521:        28250,  "d-d-++i-",
        !           522:        28500,  "c+c-h-e-",
        !           523:        29000,  "b+g-d-f+",
        !           524:        29500,  "c+h+++e-",
        !           525:        29750,  "b+g+f-c+",
        !           526:        30250,  "b+f-g-c+",
        !           527:        33500,  "c-f-d-n+",
        !           528:        33750,  "b+d-b+j-",
        !           529:        34250,  "c+e+++i+",
        !           530:        35250,  "e+b+d+k+",
        !           531:        35500,  "c+e+d-g-",
        !           532:        35750,  "c+i-++e+",
        !           533:        36250,  "b+bh-d+e+",
        !           534:        36500,  "c+c-h-e-",
        !           535:        36750,  "d+e--i+",
        !           536:        37250,  "b+g+g+b+",
        !           537:        37500,  "b+h-b+f+",
        !           538:        37750,  "c+be++j-",
        !           539:        38500,  "b+e+b+i+",
        !           540:        38750,  "d+i-b+d+",
        !           541:        39250,  "b+g-l-+d+",
        !           542:        39500,  "b+g-c+g-",
        !           543:        39750,  "b+bh-c+f-",
        !           544:        40250,  "b+bf+d+g-",
        !           545:        40500,  "b+g-c+g+",
        !           546:        40750,  "c+b+i-e+",
        !           547:        41250,  "d++bf+h+",
        !           548:        41500,  "b+j+c+d-",
        !           549:        41750,  "c+f+b+h-",
        !           550:        42500,  "c+h++g+",
        !           551:        42750,  "b+g+d-f-",
        !           552:        43250,  "b+l-e+d-",
        !           553:        43750,  "c+bd+h+f-",
        !           554:        44000,  "b+f+g-d-",
        !           555:        44250,  "b+d-g--f+",
        !           556:        44500,  "c+e+c+h+",
        !           557:        44750,  "b+e+d-h-",
        !           558:        45250,  "b++g+j-g+",
        !           559:        45500,  "c+d+e-g+",
        !           560:        45750,  "b+d-h-e-",
        !           561:        46250,  "c+bd++j+",
        !           562:        46500,  "b+d-c-j-",
        !           563:        46750,  "e-e-b+g-",
        !           564:        47000,  "b+c+d-j-",
        !           565:        47250,  "b+e+e-g-",
        !           566:        47500,  "b+g-c-h-",
        !           567:        47750,  "b+f-c+h-",
        !           568:        48250,  "d--h+n-",
        !           569:        48500,  "b+c-g+m-",
        !           570:        48750,  "b+e+e-g+",
        !           571:        49500,  "c-f+e+j-",
        !           572:        49750,  "c+c+g++f-",
        !           573:        50000,  "b+e+e+k+",
        !           574:        50250,  "b++i++g+",
        !           575:        50500,  "c+g+f-i+",
        !           576:        50750,  "b+e+d+k-",
        !           577:        51500,  "b+i+c-f+",
        !           578:        51750,  "b+bd+g-e-",
        !           579:        52250,  "b+d+g-j+",
        !           580:        52500,  "c+c+f+g+",
        !           581:        52750,  "b+c+e+i+",
        !           582:        53000,  "b+i+c+g+",
        !           583:        53500,  "c+g+g-n+",
        !           584:        53750,  "b+j+d-c+",
        !           585:        54250,  "b+d-g-j-",
        !           586:        54500,  "c-f+e+f+",
        !           587:        54750,  "b+f-+c+g+",
        !           588:        55000,  "b+g-d-g-",
        !           589:        55250,  "b+e+e+g+",
        !           590:        55500,  "b+cd++j+",
        !           591:        55750,  "b+bh-d-f-",
        !           592:        56250,  "c+d-b+j-",
        !           593:        56500,  "c+d+c+i+",
        !           594:        56750,  "b+e+d++h-",
        !           595:        57000,  "b+d+g-f+",
        !           596:        57250,  "b+f-m+d-",
        !           597:        57750,  "b+i+c+e-",
        !           598:        58000,  "b+e+d+h+",
        !           599:        58250,  "c+b+g+g+",
        !           600:        58750,  "d-e-j--e+",
        !           601:        59000,  "d-i-+e+",
        !           602:        59250,  "e--h-m+",
        !           603:        59500,  "c+c-h+f-",
        !           604:        59750,  "b+bh-e+i-",
        !           605:        60250,  "b+bh-e-e-",
        !           606:        60500,  "c+c-g-g-",
        !           607:        60750,  "b+e-l-e-",
        !           608:        61250,  "b+g-g-c+",
        !           609:        61750,  "b+g-c+g+",
        !           610:        62250,  "f--+c-i-",
        !           611:        62750,  "e+f--+g+",
        !           612:        64750,  "b+f+d+p-",
        !           613: };
        !           614: int    hintabsize      = nelem(hintab);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.