Annotation of coherent/b/bin/c/n3/i386/icode.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * n3/i386/icode.c
                      3:  * Machine dependent parts of the intermediate file printer.
                      4:  * Read and print encoded machine instructions and operands.
                      5:  * Includes tables of opcodes and register names.
                      6:  * i386.
                      7:  */
                      8: 
                      9: #ifdef vax
                     10: #include "INC$LIB:cc3.h"
                     11: #else
                     12: #include "cc3.h"
                     13: #endif
                     14: 
                     15: /*
                     16:  * Opcode names which depend on assembler format.
                     17:  */
                     18: 
                     19: #if    AS_FORMAT
                     20: #define        ICALL   "icall"
                     21: #define        IJMP    "ijmp"
                     22: #define        XICALL  "licall"
                     23: #define        XIJMP   "lijmp"
                     24: #define        XCALL   "lcall"
                     25: #define        XJMP    "ljmp"
                     26: #define        XRET    "lret"
                     27: #define        DBYTE   ".byte"
                     28: #define        DWORD   ".word"
                     29: #define        DLONG   ".long"
                     30: #else
                     31: #define        ICALL   "call"
                     32: #define        IJMP    "jmp"
                     33: #define        XICALL  "call"
                     34: #define        XIJMP   "jmp"
                     35: #define        XCALL   "call"
                     36: #define        XJMP    "jmp"
                     37: #define        XRET    "ret"
                     38: #define        DBYTE   ".db"
                     39: #define        DWORD   ".dw"
                     40: #define        DLONG   ".dd"
                     41: #endif
                     42: 
                     43: /*
                     44:  * Instruction names, sizes, and flags.
                     45:  * This table is ordered according to h/i8086/opcode.h
                     46:  * and thus parallel to n2/i8086/opcode.c.
                     47:  * Modifications to any of these require modifications to all of them.
                     48:  */
                     49: static struct ins {
                     50:        char *i_name;
                     51:        char  i_size;
                     52:        char  i_flag;
                     53: } ins[] = {
                     54:        "adc",          2,      0,
                     55:        "addl",         2,      0,
                     56:        "addb",         2,      OP_BYTE,
                     57:        "addw",         2,      OP_WORD,
                     58:        "andl",         2,      0,
                     59:        "andb",         2,      OP_BYTE,
                     60:        "andw",         2,      OP_WORD,
                     61:        "call",         1,      OP_NPTR,
                     62:        "cbw",          0,      OP_WORD,
                     63:        "cdq",          0,      0,
                     64:        "clc",          0,      0,
                     65:        "cld",          0,      0,
                     66:        "cli",          0,      0,
                     67:        "cmc",          0,      0,
                     68:        "cmpl",         2,      0,
                     69:        "cmpb",         2,      OP_BYTE,
                     70:        "cmpw",         2,      OP_WORD,
                     71:        "cmpsw",        0,      0,
                     72:        "cmpsb",        0,      0,
                     73:        "cmpsw",        0,      OP_WORD,
                     74:        "cwd",          0,      OP_WORD,
                     75:        "cwde",         0,      0,
                     76:        "decl",         1,      0,
                     77:        "decb",         1,      OP_BYTE,
                     78:        "decw",         1,      OP_WORD,
                     79:        "divl",         1,      0,
                     80:        "divb",         1,      OP_BYTE,
                     81:        "divw",         1,      OP_WORD,
                     82:        "enter",        2,      0,
                     83:        "hlt",          0,      0,
                     84:        ICALL,          1,      0,
                     85:        "idivl",        1,      0,
                     86:        "idivb",        1,      OP_BYTE,
                     87:        "idivw",        1,      OP_WORD,
                     88:        IJMP,           1,      0,
                     89:        "imull",        1,      0,
                     90:        "imulb",        1,      OP_BYTE,
                     91:        "imulw",        1,      OP_WORD,
                     92:        "imul",         3,      0,
                     93:        "incl",         1,      0,
                     94:        "incb",         1,      OP_BYTE,
                     95:        "incw",         1,      OP_WORD,
                     96:        "iret",         0,      0,
                     97:        XICALL,         1,      OP_DWORD,
                     98:        XIJMP,          1,      OP_NPTR,
                     99:        "ja",           1,      OP_JUMP,
                    100:        "jae",          1,      OP_JUMP,
                    101:        "jb",           1,      OP_JUMP,
                    102:        "jbe",          1,      OP_JUMP,
                    103:        "jcxz",         1,      OP_JUMP,
                    104:        "je",           1,      OP_JUMP,
                    105:        "jg",           1,      OP_JUMP,
                    106:        "jge",          1,      OP_JUMP,
                    107:        "jl",           1,      OP_JUMP,
                    108:        "jle",          1,      OP_JUMP,
                    109:        "jmp",          1,      OP_JUMP,
                    110:        "jne",          1,      OP_JUMP,
                    111:        "jno",          1,      OP_JUMP,
                    112:        "jns",          1,      OP_JUMP,
                    113:        "jo",           1,      OP_JUMP,
                    114:        "jpe",          1,      OP_JUMP,
                    115:        "jpo",          1,      OP_JUMP,
                    116:        "js",           1,      OP_JUMP,
                    117:        "lea",          2,      0,
                    118:        "leave",        0,      0,
                    119:        "lock",         0,      0,
                    120:        "lodsw",        0,      0,
                    121:        "lodsb",        0,      0,
                    122:        "loop",         1,      OP_JUMP,
                    123:        "loope",        1,      OP_JUMP,
                    124:        "loopne",       1,      OP_JUMP,
                    125:        "movl",         2,      0,
                    126:        "movb",         2,      OP_BYTE,
                    127:        "movw",         2,      OP_WORD,
                    128:        "movsw",        0,      0,
                    129:        "movsb",        0,      0,
                    130:        "movsxw",       2,      0,
                    131:        "movsxb",       2,      OP_BYTE,
                    132:        "movzxw",       2,      0,
                    133:        "movzxb",       2,      OP_BYTE,
                    134:        "mull",         1,      0,
                    135:        "mulb",         1,      OP_BYTE,
                    136:        "mulw",         1,      OP_WORD,
                    137:        "negl",         1,      0,
                    138:        "negb",         1,      OP_BYTE,
                    139:        "negw",         1,      OP_WORD,
                    140:        "notl",         1,      0,
                    141:        "notb",         1,      OP_BYTE,
                    142:        "notw",         1,      OP_WORD,
                    143:        "ret",          1,      OP_NPTR,
                    144:        "ret",          1,      OP_NPTR,
                    145:        "orl",          2,      0,
                    146:        "orb",          2,      OP_BYTE,
                    147:        "orw",          2,      OP_WORD,
                    148:        "pop",          1,      0,
                    149:        "popf",         0,      0,
                    150:        "push",         1,      0,
                    151:        "pushf",        0,      0,
                    152:        "rcl",          2,      0,
                    153:        "rclb",         2,      OP_BYTE,
                    154:        "rcr",          2,      0,
                    155:        "rcrb",         2,      OP_BYTE,
                    156:        "repe",         0,      0,
                    157:        "repne",        0,      0,
                    158:        "ret",          0,      0,
                    159:        "rol",          2,      0,
                    160:        "rolb",         2,      OP_BYTE,
                    161:        "ror",          2,      0,
                    162:        "rorb",         2,      OP_BYTE,
                    163:        "sall",         2,      0,
                    164:        "salb",         2,      OP_BYTE,
                    165:        "salw",         2,      OP_WORD,
                    166:        "sarl",         2,      0,
                    167:        "sarb",         2,      OP_BYTE,
                    168:        "sarw",         2,      OP_WORD,
                    169:        "sbb",          2,      0,
                    170:        "scasw",        0,      0,
                    171:        "scasb",        0,      0,
                    172:        "shll",         2,      0,
                    173:        "shlb",         2,      OP_BYTE,
                    174:        "shlw",         2,      OP_WORD,
                    175:        "shrl",         2,      0,
                    176:        "shrb",         2,      OP_BYTE,
                    177:        "shrw",         2,      OP_WORD,
                    178:        "stc",          0,      0,
                    179:        "std",          0,      0,
                    180:        "sti",          0,      0,
                    181:        "stosw",        0,      0,
                    182:        "stosb",        0,      0,
                    183:        "subl",         2,      0,
                    184:        "subb",         2,      OP_BYTE,
                    185:        "subw",         2,      OP_WORD,
                    186:        "testl",        2,      0,
                    187:        "testb",        2,      OP_BYTE,
                    188:        "testw",        2,      OP_WORD,
                    189:        "wait",         0,      0,
                    190:        XCALL,          1,      OP_NPTR,
                    191:        "xchg",         2,      0,
                    192:        "xchgb",        2,      OP_BYTE,
                    193:        XJMP,           1,      OP_NPTR,
                    194:        "xorl",         2,      0,
                    195:        "xorb",         2,      OP_BYTE,
                    196:        "xorw",         2,      OP_WORD,
                    197:        XRET,           0,      0,
                    198: 
                    199: /* Specials. */
                    200:        DBYTE,          1,      OP_DD|OP_NPTR,
                    201:        DWORD,          1,      OP_DD|OP_NPTR,
                    202:        DLONG,          1,      OP_DD|OP_NPTR,
                    203:        DLONG,          1,      OP_DD|OP_NPTR,
                    204:        DLONG,          1,      OP_DD|OP_NPTR,
                    205: 
                    206: /* Old, now unused. */
                    207: #if    0
                    208:        "aaa",          0,      0,
                    209:        "aad",          0,      0,
                    210:        "aam",          0,      0,
                    211:        "aas",          0,      0,
                    212:        "adcb",         2,      OP_BYTE,
                    213:        "daa",          0,      0,
                    214:        "das",          0,      0,
                    215:        "in",           1,      0,
                    216:        "inb",          1,      OP_BYTE,
                    217:        "int",          1,      OP_NPTR,
                    218:        "into",         0,      0,
                    219:        "lahf",         0,      0,
                    220:        "lds",          2,      OP_DWORD,
                    221:        "les",          2,      OP_DWORD,
                    222:        "out",          1,      0,
                    223:        "outb",         1,      OP_BYTE,
                    224:        "sahf",         0,      0,
                    225:        "sbbb",         2,      OP_BYTE,
                    226:        "xlat",         0,      0,
                    227: #endif
                    228: 
                    229: #if    1
                    230:        "faddl",        1,      0,
                    231:        "fadds",        1,      0,
                    232:        "fiaddl",       1,      0,
                    233:        "fiadds",       1,      0,
                    234:        "fsubl",        1,      0,
                    235:        "fsubs",        1,      0,
                    236:        "fisubl",       1,      0,
                    237:        "fisubs",       1,      0,
                    238:        "fsubrl",       1,      0,
                    239:        "fsubrs",       1,      0,
                    240:        "fisubrl",      1,      0,
                    241:        "fisubrs",      1,      0,
                    242:        "fcomp",        0,      0,
                    243:        "fcompl",       1,      0,
                    244:        "fcomps",       1,      0,
                    245:        "ficompl",      1,      0,
                    246:        "ficomps",      1,      0,
                    247:        "fmull",        1,      0,
                    248:        "fmuls",        1,      0,
                    249:        "fimull",       1,      0,
                    250:        "fimuls",       1,      0,
                    251:        "fdivl",        1,      0,
                    252:        "fdivs",        1,      0,
                    253:        "fidivl",       1,      0,
                    254:        "fidivs",       1,      0,
                    255:        "fdivrl",       1,      0,
                    256:        "fdivrs",       1,      0,
                    257:        "fidivrl",      1,      0,
                    258:        "fidivrs",      1,      0,
                    259:        "fchs",         0,      0,
                    260:        "ftst",         0,      0,
                    261:        "fldz",         0,      0,
                    262:        "fld1",         0,      0,
                    263:        "fstsw",        1,      0,
                    264:        "fldl",         1,      0,
                    265:        "flds",         1,      0,
                    266:        "fildl",        1,      0,
                    267:        "filds",        1,      0,
                    268:        "fldt",         1,      0,
                    269:        "fstl",         1,      0,
                    270:        "fsts",         1,      0,
                    271:        "fistl",        1,      0,
                    272:        "fists",        1,      0,
                    273:        "fstpl",        1,      0,
                    274:        "fstps",        1,      0,
                    275:        "fistpl",       1,      0,
                    276:        "fistps",       1,      0,
                    277:        "fstpt",        1,      0,
                    278:        "fwait",        0,      0,
                    279: #if    0
                    280:        "fdrop",        0,      0,
                    281: #else
                    282:        "fstp\t%st",    0,      0,
                    283: #endif
                    284: 
                    285: /* Old, now unused. */
                    286: #if    0
                    287:        "fadd",         0,      0,
                    288:        "fsub",         0,      0,
                    289:        "frsub",        0,      0,
                    290:        "fmul",         0,      0,
                    291:        "fdiv",         0,      0,
                    292:        "frdiv",        0,      0,
                    293: #endif
                    294: #endif
                    295: };
                    296: 
                    297: /*
                    298:  * Handle code nodes.
                    299:  */
                    300: icode()
                    301: {
                    302:        register int op, i, n;
                    303:        register struct ins *ip;
                    304: 
                    305:        op = bget();
                    306:        if (dotseg == SSTRN && op == ZBYTE) {
                    307:                istring();
                    308:                return;
                    309:        }
                    310:        ip = &ins[op];
                    311:        bput('\t');
                    312: #if    0
                    313:        if (ip->i_flag & OP_WORD)
                    314:                fprintf(ofp, "pfx16:\t");
                    315: #endif
                    316:        fputs(ip->i_name, ofp);
                    317:        n = ip->i_size;
                    318:        for (i = 0; i < n; i += 1) {
                    319:                if (i == 0) {
                    320:                        bput('\t');
                    321:                } else
                    322:                        fputs(", ", ofp);
                    323:                iafield(ip);
                    324:        }
                    325:        bput('\n');
                    326: }
                    327: 
                    328: /*
                    329:  * Print a string for the assembler.
                    330:  * The first ZBYTE op has already been read before the call.
                    331:  */
                    332: istring()
                    333: {
                    334:        register int imode, c, op;
                    335: 
                    336:        fputs("\t.byte\t\"", ofp);
                    337:        for(;;) {
                    338:                if (((imode = iget()) & A_AMOD) != A_DIR)
                    339:                        cbotch("istring: imode=%d\n", imode);
                    340:                c = ((imode & A_OFFS) != 0) ? iget() : 0;
                    341:                if (c == '\0') {
                    342:                        fprintf(ofp, "\", 0\n");
                    343:                        return;
                    344:                } else if (c == '\n')
                    345:                        fprintf(ofp, "\\n");
                    346:                else if (c < ' ' || c > 0x7F)
                    347:                        fprintf(ofp, "\\%03o", c);
                    348:                else
                    349:                        bput(c);
                    350:                if ((op = bget()) != CODE) {
                    351:                        unbget(op);
                    352:                        break;
                    353:                } else if ((op = bget()) != ZBYTE)
                    354:                        cbotch("istring: %x\n", op);
                    355:        }
                    356:        fputs("\"\n", ofp);
                    357: }
                    358: 
                    359: /*
                    360:  * These tables are indexed by the regm field of a mode.
                    361:  * They contain the ASCII strings used to print reg names in VASM mode.
                    362:  */
                    363: static char    *dregs[] = {
                    364:        "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
                    365: };
                    366: 
                    367: static char    *wregs[] = {
                    368:        "%ax",  "%cx",  "%dx",  "%bx",  "%sp",  "%bp",  "%si",  "%di"
                    369: };
                    370: 
                    371: static char    *bregs[] = {
                    372:        "%al",  "%cl",  "%dl",  "%bl",  "%ah",  "%ch",  "%dh",  "%bh"
                    373: };
                    374: 
                    375: static int     scale[] = {
                    376:        1,      2,      4,      8
                    377: };
                    378: 
                    379: /*
                    380:  * Read and print an address field.
                    381:  * The style of the address is determined by flag bits in the address mode.
                    382:  * These bits are cleared away when the mode is actually stored in the afield.
                    383:  */
                    384: iafield(ip)
                    385: register struct ins    *ip;
                    386: {
                    387:        register int    imode, mode, regm, flag;
                    388:        register ival_t offs;
                    389: 
                    390:        imode = iget();
                    391:        if ((imode & A_OFFS) != 0)
                    392:                offs = iget();
                    393:        else
                    394:                offs = (ival_t)0;
                    395:        if ((imode & A_LID) != 0)
                    396:                sprintf(id, ".L%d", (int)iget());
                    397:        else if ((imode & A_GID) != 0)
                    398:                sget(id, NCSYMB);
                    399:        mode = imode & A_AMOD;
                    400:        if ((mode & A_X) != 0)
                    401:                mode = A_X;                     /* indexed in some form */
                    402:        regm = imode & A_REGM;
                    403:        flag = ip->i_flag;
                    404:        switch (mode) {
                    405: 
                    406:        case A_IMM:
                    407: #if    AS_FORMAT
                    408:                bput('$');
                    409: #else
                    410:                if ((imode & (A_LID|A_GID)) != 0)
                    411:                        fprintf(ofp, "offset ");
                    412: #endif
                    413:                /* fall through... */
                    414:        case A_DIR:
                    415:        case A_X:
                    416:                /* Immediate, direct, indexed, all in one grungy case. */
                    417: #if    !AS_FORMAT
                    418:                if (mode!=A_IMM && (flag&OP_NPTR)==0) {
                    419:                        if ((flag&OP_BYTE) != 0)
                    420:                                fprintf(ofp, "byte");
                    421:                        else if ((flag&OP_WORD) != 0)
                    422:                                fprintf(ofp, "word");
                    423:                        else
                    424:                                fprintf(ofp, "dword");
                    425:                        fprintf(ofp, " ptr ");
                    426:                }
                    427:                if (mode == A_X) {
                    428:                        bput('[');
                    429:                        if ((imode & A_AMOD) == A_XB)
                    430:                                fprintf(ofp, "%s", dregs[regm]);
                    431:                        else if ((imode & A_AMOD) == A_XSIB) {
                    432:                                if (regm != 5)
                    433:                                        fprintf(ofp, "%s",  dregs[regm]);
                    434:                                fprintf(ofp, ", %s, %d",
                    435:                                        dregs[IREG(imode)],
                    436:                                        scale[SCALE(imode)]);
                    437:                        }
                    438:                }
                    439: #endif
                    440:                if ((imode & (A_LID|A_GID)) != 0) {
                    441:                        /* Symbol-relative. */
                    442: #if    !AS_FORMAT
                    443:                        if (mode == A_X)
                    444:                                bput('+');
                    445: #endif
                    446:                        fputs(id, ofp);
                    447:                        if ((SIGNEDADDRESS)offs > 0)
                    448:                                bput('+');
                    449:                }
                    450: #if    !AS_FORMAT
                    451:                else if (mode==A_X && (SIGNEDADDRESS)offs>0)
                    452:                        bput('+');
                    453: #endif
                    454:                if (offs!=0 || ((imode & (A_LID|A_GID))==0 && mode!=A_X)) {
                    455: #if    AS_FORMAT
                    456:                        fprintf(ofp, I_FMT, offs);
                    457: #else
                    458:                        if ((SIGNEDADDRESS)offs<0) {
                    459:                                bput('-');
                    460:                                offs = -(SIGNEDADDRESS)offs;
                    461:                        }
                    462:                        fprintf(ofp, "0" I_FMTX "h", offs);
                    463: #endif
                    464:                }
                    465:                if (mode == A_X) {
                    466: #if    AS_FORMAT
                    467:                        bput('(');
                    468:                        if ((imode & A_AMOD) == A_XB)
                    469:                                fprintf(ofp, "%s", dregs[regm]);
                    470:                        else if ((imode & A_AMOD) == A_XSIB) {
                    471:                                if (regm != 5)
                    472:                                        fprintf(ofp, "%s",  dregs[regm]);
                    473:                                fprintf(ofp, ", %s, %d",
                    474:                                        dregs[IREG(imode)],
                    475:                                        scale[SCALE(imode)]);
                    476:                        }
                    477:                        bput(')');
                    478: #else
                    479:                        bput(']');
                    480: #endif
                    481:                }
                    482:                break;
                    483: 
                    484:        case A_DR:
                    485:                fputs(dregs[regm], ofp);
                    486:                break;
                    487: 
                    488:        case A_WR:
                    489:                fputs(wregs[regm], ofp);
                    490:                break;
                    491: 
                    492:        case A_BR:
                    493:                fputs(bregs[regm], ofp);
                    494:                break;
                    495: 
                    496:        default:
                    497:                cbotch("ifield, mode=%d", mode);
                    498:        }
                    499: }
                    500: 
                    501: /* end of n3/i386/icode.c */

unix.superglobalmegacorp.com

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