Annotation of lucent/sys/src/alef/k/mul.c, revision 1.1.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.