Annotation of 43BSDTahoe/new/X/inline/machdep.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1984 Regents of the University of California */
                      2: 
                      3: #ifndef lint
                      4: static char sccsid[] = "@(#)machdep.c  1.4     (Berkeley)      9/20/84";
                      5: #endif not lint
                      6: 
                      7: #include <stdio.h>
                      8: #include <ctype.h>
                      9: #include "inline.h"
                     10: 
                     11: /*
                     12:  * The routines and tables in this file must be rewritten
                     13:  * for each new machine that this program is ported to.
                     14:  */
                     15: 
                     16: #ifdef vax
                     17: /*
                     18:  * Instruction stop table.
                     19:  * All instructions that implicitly modify any of the temporary
                     20:  * registers, change control flow, or implicitly loop must be
                     21:  * listed in this table. It is used to find the end of a basic
                     22:  * block when scanning backwards through the instruction stream
                     23:  * trying to merge the inline expansion.
                     24:  */
                     25: struct inststoptbl inststoptable[] = {
                     26:        { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" },
                     27:        { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" },
                     28:        { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" },
                     29:        { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" },
                     30:        { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" },
                     31:        { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" },
                     32:        { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" },
                     33:        { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" },
                     34:        { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" },
                     35:        { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" },
                     36:        { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" },
                     37:        { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" },
                     38:        { "bcs" }, { "brb" }, { "brw" }, { "jmp" },
                     39:        { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" },
                     40:        { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" },
                     41:        { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" },
                     42:        { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" },
                     43:        { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" },
                     44:        { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" },
                     45:        { "callg" }, { "calls" }, { "ret" },
                     46:        { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" },
                     47:        { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" },
                     48:        { "locc" }, { "skpc" }, { "matchc" }, { "crc" },
                     49:        { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" },
                     50:        { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" },
                     51:        { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" },
                     52:        { "ashp" }, { "editpc" },
                     53:        { "escd" }, { "esce" }, { "escf" },
                     54:        { "" }
                     55: };
                     56: 
                     57: /*
                     58:  * Check to see if a line is a candidate for replacement.
                     59:  * Return pointer to name to be looked up in pattern table.
                     60:  */
                     61: char *
                     62: doreplaceon(cp)
                     63:        char *cp;
                     64: {
                     65: 
                     66:        if (bcmp(cp, "calls\t$", 7) == 0)
                     67:                return (cp + 7);
                     68:        return (0);
                     69: }
                     70: 
                     71: /*
                     72:  * Find the next argument to the function being expanded.
                     73:  * If register ends with a '#' then source may be used directly.
                     74:  * If register ends with a '@' then source may be used if an indirect
                     75:  *    version exists.
                     76:  */
                     77: 
                     78: nextarg(argc, argv, flag)
                     79:        int argc;
                     80:        char *argv[];
                     81:        int *flag;
                     82: {
                     83:        register char *lastarg = argv[2];
                     84: 
                     85:        *flag = 0;
                     86: 
                     87:        if (argc == 3 &&
                     88:            bcmp(argv[0], "mov", 3) == 0 &&
                     89:            bcmp(argv[1], "(sp)+", 6) == 0 &&
                     90:            lastarg[0] == 'r' && isdigit(lastarg[1])) {
                     91:                if (lastarg[2] == '\0') {
                     92:                    return (lastarg[1] - '0');
                     93:                } else if (lastarg[2] == '$') {
                     94:                    *flag = F_VALUE;
                     95:                    return (lastarg[1] - '0');
                     96:                } else if (lastarg[2] == '*') {
                     97:                    *flag = F_INDIRECT;
                     98:                    return (lastarg[1] - '0');
                     99:                }
                    100:            }
                    101:        return (-1);
                    102: }
                    103: 
                    104: /*
                    105:  * Determine whether the current line pushes an argument.
                    106:  */
                    107:  ispusharg(argc, argv)
                    108:        int argc;
                    109:        char *argv[];
                    110: {
                    111: 
                    112:        if (argc < 2)
                    113:                return (0);
                    114:        if (argc == 2 && bcmp(argv[0], "push", 4) == 0)
                    115:                return (1);
                    116:        if (bcmp(argv[argc - 1], "-(sp)", 6) == 0)
                    117:                return (1);
                    118:        return (0);
                    119: }
                    120: 
                    121: /*
                    122:  * Determine which (if any) registers are modified
                    123:  * Return register number that is modified, -1 if none are modified.
                    124:  */
                    125: modifies(argc, argv)
                    126:        int argc;
                    127:        char *argv[];
                    128: {
                    129:        /*
                    130:         * For the VAX all we care about are r0 to r5
                    131:         */
                    132:        register char *lastarg = argv[argc - 1];
                    133: 
                    134:        if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
                    135:                return (lastarg[1] - '0');
                    136:        return (-1);
                    137: }
                    138: 
                    139: checkvar(argc, argv, flag, source, mod)
                    140: int argc;
                    141: char *argv[];
                    142: int flag;
                    143: char *source;
                    144: {
                    145:     register char *cp1, *cp2;
                    146:     register int opind = 0;
                    147:     char *indirect();
                    148: 
                    149:     if (flag == 0) return(0);
                    150: 
                    151:     if (bcmp(argv[0], "push", 4) != 0 && bcmp(argv[0], "mov", 3) != 0)
                    152:        return(0);
                    153: 
                    154:     cp1 = argv[1];
                    155:     while (*cp1) if (*cp1++ == 'r' && isdigit(*cp1) && 
                    156:                     (mod & (1 << (*cp1++ - '0'))) &&
                    157:                     (*cp1 == '\0' || *cp1 == ')' || *cp1 == ']'))
                    158:        return(0);
                    159: 
                    160:     if ((argv[0][0] == 'p' && argv[0][4] == 'a') || 
                    161:        (argv[0][0] == 'm' && argv[0][3] == 'a'))
                    162:        opind++;
                    163: 
                    164:     if (flag & F_VALUE) {
                    165:        if (opind) return(0);
                    166:        cp1 = argv[1];
                    167:        cp2 = source;
                    168:        while (*cp2++ = *cp1++) ;
                    169:        return(1);
                    170:     }
                    171:     
                    172:     if (flag & F_INDIRECT) {
                    173:        cp2 = source;
                    174:        if (opind) {
                    175:            cp1 = argv[1];
                    176:        } else {
                    177:            cp1 = indirect(argv[1]);
                    178:            if (cp1 == NULL) return(0);
                    179:        }
                    180:        while (*cp2++ = *cp1++) ;
                    181:        return(1);
                    182:     }
                    183: 
                    184:     return(0);
                    185: }
                    186: 
                    187: /*
                    188:  * Rewrite the instruction in (argc, argv) to store its
                    189:  * contents into arg instead of onto the stack. The new
                    190:  * instruction is placed in the buffer that is provided.
                    191:  */
                    192: rewrite(instbuf, argc, argv, target)
                    193:        char *instbuf;
                    194:        int argc;
                    195:        char *argv[];
                    196:        int target;
                    197: {
                    198: 
                    199:        switch (argc) {
                    200:        case 0:
                    201:                instbuf[0] = '\0';
                    202:                fprintf("blank line to rewrite?\n");
                    203:                return;
                    204:        case 1:
                    205:                sprintf(instbuf, "\t%s\n", argv[0]);
                    206:                fprintf(stderr, "rewrite?-> %s", instbuf);
                    207:                return;
                    208:        case 2:
                    209:                if (bcmp(argv[0], "push", 4) == 0) {
                    210:                        sprintf(instbuf, "\tmov%s\t%s,r%d\n",
                    211:                                &argv[0][4], argv[1], target);
                    212:                        return;
                    213:                }
                    214:                sprintf(instbuf, "\t%s\tr%d\n", argv[0], target);
                    215:                return;
                    216:        case 3:
                    217:                sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target);
                    218:                return;
                    219:        case 4:
                    220:                sprintf(instbuf, "\t%s\t%s,%s,r%d\n",
                    221:                        argv[0], argv[1], argv[2], target);
                    222:                return;
                    223:        case 5:
                    224:                sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n",
                    225:                        argv[0], argv[1], argv[2], argv[3], target);
                    226:                return;
                    227:        default:
                    228:                sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
                    229:                argc -= 2, argv += 2;
                    230:                while (argc-- > 0) {
                    231:                        strcat(instbuf, ",");
                    232:                        strcat(instbuf, *argv++);
                    233:                }
                    234:                strcat(instbuf, "\n");
                    235:                fprintf(stderr, "rewrite?-> %s", instbuf);
                    236:                return;
                    237:        }
                    238: }
                    239: 
                    240: /* Return indirect version of variable:
                    241:  *    $Lnn      -> Lnn
                    242:  *    rn        -> (rn)
                    243:  *    (rn)      -> *(rn)
                    244:  *    a(rn)     -> *a(rn)
                    245:  *    (rn)[rm]  -> *(rn)[rm]
                    246:  *    a(rn)[rm] -> *a(rn)[rm]
                    247:  *    _foo      -> *_foo
                    248:  *    _foo(rn)  -> *_foo(rn)
                    249:  *    _foo(rn)[rm] -> *_foo(rn)[rm]
                    250:  *    (rn)+     -> NULL
                    251:  *    -(rn)     -> NULL
                    252:  *    *<any>    -> NULL
                    253:  */
                    254: char *
                    255: indirect(cp)
                    256: register char *cp;
                    257: {
                    258:     static char newvar[16];
                    259:     register char *c;
                    260:     int neg = 0;
                    261:     int offset = 0;
                    262: 
                    263:     /* *<any> | -(rn) */
                    264:     if (*cp == '*' || (*cp == '-' && *(cp+1) == '(')) return(NULL);
                    265: 
                    266:     /* (rn)+ | (rn)x */
                    267:     if (*cp == '(') {
                    268:        c = cp;
                    269:        while (*++c != ')') ;
                    270:        if (*++c == '+') return(NULL);
                    271:        c = newvar;
                    272:        *c++ = '*';
                    273:        while (*c++ = *cp++);
                    274:        return(newvar);
                    275:     }
                    276: 
                    277:     /* $Lnn */
                    278:     if (*cp == '$' && *(cp+1) == 'L') {
                    279:        c = newvar;
                    280:        cp++;
                    281:        while (*c++ = *cp++) ;
                    282:        return(newvar);
                    283:     }
                    284: 
                    285:     /* rn */
                    286:     if (*cp == 'r') {
                    287:        c = newvar;
                    288:        *c++ = '(';
                    289:        while (*c++ = *cp++) ;
                    290:        *(c-1) = ')';
                    291:        *c = 0;
                    292:        return(newvar);
                    293:     }
                    294: 
                    295:     /* everything else */
                    296:     c = newvar;
                    297:     *c++ = '*';
                    298:     while (*c++ = *cp++) ;
                    299:     return(newvar);
                    300: }
                    301:     
                    302: output_replace(replace, oparg, argno, f)
                    303: register char *replace;
                    304: struct oparg oparg[];
                    305: int argno;
                    306: FILE *f;
                    307: {
                    308:     char newline[BUFSIZ];
                    309:     register int i;
                    310:     register int argc;
                    311:     char *argv[MAXARGS];
                    312:     char parsebuf[BUFSIZ];
                    313: 
                    314:     do {
                    315:        replace = copyline(replace, newline);
                    316:        argc = parseline(newline, argv, parsebuf);
                    317:        for (i = 0; i < argno; i++)
                    318:            replace_arg(argc, argv, oparg[i].reg, oparg[i].source);
                    319:        buildline(argc, argv, newline);
                    320:        fputs(newline, f);
                    321:     } while (*replace != '\0');
                    322: }
                    323: 
                    324: replace_arg(argc, argv, reg, source)
                    325: int argc;
                    326: char *argv[];
                    327: int reg;
                    328: char *source;
                    329: {
                    330:     register int i;
                    331:     register char *c;
                    332: 
                    333:     for (i = 1; i < argc; i++) {
                    334:        c = argv[i];
                    335:        if (*c == '(') c++;
                    336:        if (*c++ == 'r' && (*c++ - '0') == reg && !isdigit(*c)) {
                    337:            argv[i] = source;
                    338:        }
                    339:     }
                    340: }
                    341: 
                    342: buildline(argc, argv, newline)
                    343: register int argc;
                    344: register char *argv[];
                    345: register char *newline;
                    346: {
                    347:     register char *cp1;
                    348: 
                    349:     if (argc == 0) {
                    350:        *newline++ = '\n';
                    351:        *newline = '\0';
                    352:     } else if (argc == 1) {
                    353:        sprintf(newline, "%s\n", argv[0]);
                    354:     } else {
                    355:        sprintf(newline, "\t%s\t%s", argv[0], argv[1]);
                    356:        argc -= 2;
                    357:        argv += 2;
                    358:        while (argc-- > 0) {
                    359:            strcat(newline, ",");
                    360:            cp1 = *argv;
                    361:            cp1 += strlen(cp1) - 1;
                    362:            if (*cp1 == '$' || *cp1 == '*') *cp1 = '\0';
                    363:            strcat(newline, *argv++);
                    364:        }
                    365:        strcat(newline, "\n");
                    366:     }
                    367: }
                    368: 
                    369: 
                    370: 
                    371: /*
                    372:  * Do any necessary post expansion cleanup.
                    373:  */
                    374: cleanup(numargs)
                    375:        int numargs;
                    376: {
                    377: 
                    378:        return;
                    379: }
                    380: #endif vax
                    381: 
                    382: #ifdef mc68000
                    383: /*
                    384:  * Instruction stop table.
                    385:  * All instructions that implicitly modify any of the temporary
                    386:  * registers, change control flow, or implicitly loop must be
                    387:  * listed in this table. It is used to find the end of a basic
                    388:  * block when scanning backwards through the instruction stream
                    389:  * trying to merge the inline expansion.
                    390:  */
                    391: struct inststoptbl inststoptable[] = {
                    392:        { "" }
                    393: };
                    394: 
                    395: /*
                    396:  * Check to see if a line is a candidate for replacement.
                    397:  * Return pointer to name to be looked up in pattern table.
                    398:  */
                    399: char *
                    400: doreplaceon(cp)
                    401:        char *cp;
                    402: {
                    403: 
                    404:        if (bcmp(cp, "jbsr\t", 5) == 0)
                    405:                return (cp + 5);
                    406:        return (0);
                    407: }
                    408: 
                    409: /*
                    410:  * Find the next argument to the function being expanded.
                    411:  */
                    412: nextarg(argc, argv)
                    413:        int argc;
                    414:        char *argv[];
                    415: {
                    416:        register char *lastarg = argv[2];
                    417: 
                    418:        if (argc == 3 &&
                    419:            bcmp(argv[0], "movl", 5) == 0 &&
                    420:            bcmp(argv[1], "sp@+", 5) == 0 &&
                    421:            (lastarg[1] == '0' || lastarg[1] == '1') &&
                    422:            lastarg[2] == '\0') {
                    423:                if (lastarg[0] == 'd')
                    424:                        return (lastarg[1] - '0');
                    425:                return (lastarg[1] - '0' + 8);
                    426:        }
                    427:        return (-1);
                    428: }
                    429: 
                    430: /*
                    431:  * Determine whether the current line pushes an argument.
                    432:  */
                    433:  ispusharg(argc, argv)
                    434:        int argc;
                    435:        char *argv[];
                    436: {
                    437: 
                    438:        if (argc < 2)
                    439:                return (0);
                    440:        if (argc == 2 && bcmp(argv[0], "pea", 4) == 0)
                    441:                return (1);
                    442:        if (bcmp(argv[argc - 1], "sp@-", 5) == 0)
                    443:                return (1);
                    444:        return (0);
                    445: }
                    446: 
                    447: /*
                    448:  * Determine which (if any) registers are modified
                    449:  * Return register number that is modified, -1 if none are modified.
                    450:  */
                    451: modifies(argc, argv)
                    452:        int argc;
                    453:        char *argv[];
                    454: {
                    455:        /*
                    456:         * For the MC68000 all we care about are d0, d1, a0, and a1.
                    457:         */
                    458:        register char *lastarg = argv[argc - 1];
                    459: 
                    460:        if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0')
                    461:                return (lastarg[1] - '0');
                    462:        if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0')
                    463:                return (lastarg[1] - '0' + 8);
                    464:        return (-1);
                    465: }
                    466: 
                    467: /*
                    468:  * Rewrite the instruction in (argc, argv) to store its
                    469:  * contents into arg instead of onto the stack. The new
                    470:  * instruction is placed in the buffer that is provided.
                    471:  */
                    472: rewrite(instbuf, argc, argv, target)
                    473:        char *instbuf;
                    474:        int argc;
                    475:        char *argv[];
                    476:        int target;
                    477: {
                    478:        int regno;
                    479:        char regtype;
                    480: 
                    481:        if (target < 8) {
                    482:                regtype = 'd';
                    483:                regno = target;
                    484:        } else {
                    485:                regtype = 'a';
                    486:                regno = target - 8;
                    487:        }
                    488:        switch (argc) {
                    489:        case 0:
                    490:                instbuf[0] = '\0';
                    491:                fprintf("blank line to rewrite?\n");
                    492:                return;
                    493:        case 1:
                    494:                sprintf(instbuf, "\t%s\n", argv[0]);
                    495:                fprintf(stderr, "rewrite?-> %s", instbuf);
                    496:                return;
                    497:        case 2:
                    498:                if (bcmp(argv[0], "pea", 4) == 0) {
                    499:                        if (regtype == 'a') {
                    500:                                sprintf(instbuf, "\tlea\t%s,%c%d\n",
                    501:                                        argv[1], regtype, regno);
                    502:                                return;
                    503:                        }
                    504:                        if (argv[1][0] == '_' || isdigit(argv[1][0])) {
                    505:                                sprintf(instbuf, "\tmovl\t#%s,%c%d\n",
                    506:                                        argv[1], regtype, regno);
                    507:                                return;
                    508:                        }
                    509:                        sprintf(instbuf,
                    510:                                "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n",
                    511:                                regno, argv[1], regno);
                    512:                        return;
                    513:                }
                    514:                sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno);
                    515:                return;
                    516:        case 3:
                    517:                sprintf(instbuf, "\t%s\t%s,%c%d\n",
                    518:                        argv[0], argv[1], regtype, regno);
                    519:                return;
                    520:        default:
                    521:                sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
                    522:                argc -= 2, argv += 2;
                    523:                while (argc-- > 0) {
                    524:                        strcat(instbuf, ",");
                    525:                        strcat(instbuf, *argv++);
                    526:                }
                    527:                strcat(instbuf, "\n");
                    528:                fprintf(stderr, "rewrite?-> %s", instbuf);
                    529:                return;
                    530:        }
                    531: }
                    532: 
                    533: /*
                    534:  * Do any necessary post expansion cleanup.
                    535:  */
                    536: cleanup(numargs)
                    537:        int numargs;
                    538: {
                    539:        
                    540:        if (numargs == 0)
                    541:                return;
                    542:        /*
                    543:         * delete instruction to pop arguments.
                    544:         * TODO:
                    545:         *      CHECK FOR LABEL
                    546:         *      CHECK THAT INSTRUCTION IS A POP
                    547:         */
                    548:        fgets(line[bufhead], MAXLINELEN, stdin);
                    549: }
                    550: #endif mc68000

unix.superglobalmegacorp.com

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