Annotation of coherent/b/bin/c/n3/i386/icode.c, revision 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.