|
|
1.1 ! root 1: /* ! 2: * The routines in this file are ! 3: * the machine dependent parts of the intermediate ! 4: * file printer. They handle reading and printing ! 5: * encoded machine instructions and operands. ! 6: * Included are tables of opcodes, of register names, ! 7: * etc. ! 8: */ ! 9: #ifdef vax ! 10: #include "INC$LIB:cc3.h" ! 11: #else ! 12: #include "cc3.h" ! 13: #endif ! 14: ! 15: /* ! 16: * Instruction names, sizes, and flags. ! 17: * This table is ordered according to h/i8086/opcode.h ! 18: * and thus parallel to n2/i8086/opcode.c; modifications ! 19: * to any of these require modifications to all of them. ! 20: */ ! 21: static struct ins { ! 22: char *i_name; ! 23: char i_size; ! 24: char i_flag; ! 25: } ins[] = { ! 26: "aaa", 0, 0, ! 27: "aad", 0, 0, ! 28: "aam", 0, 0, ! 29: "aas", 0, 0, ! 30: "adc", 2, 0, ! 31: "adcb", 2, OP_BYTE, ! 32: "add", 2, 0, ! 33: "addb", 2, OP_BYTE, ! 34: "and", 2, 0, ! 35: "andb", 2, OP_BYTE, ! 36: "call", 1, OP_NPTR, ! 37: "cbw", 0, 0, ! 38: "clc", 0, 0, ! 39: "cld", 0, 0, ! 40: "cli", 0, 0, ! 41: "cmc", 0, 0, ! 42: "cmp", 2, 0, ! 43: "cmpb", 2, OP_BYTE, ! 44: "cmpsw", 0, 0, ! 45: "cmpsb", 0, 0, ! 46: "cwd", 0, 0, ! 47: "daa", 0, 0, ! 48: "das", 0, 0, ! 49: "dec", 1, 0, ! 50: "decb", 1, OP_BYTE, ! 51: "div", 1, 0, ! 52: "divb", 1, OP_BYTE, ! 53: "hlt", 0, 0, ! 54: #if AS_FORMAT ! 55: "icall", 1, 0, ! 56: #else ! 57: "call", 1, 0, ! 58: #endif ! 59: "idiv", 1, 0, ! 60: "idivb", 1, OP_BYTE, ! 61: #if AS_FORMAT ! 62: "ijmp", 1, 0, ! 63: #else ! 64: "jmp", 1, 0, ! 65: #endif ! 66: "imul", 1, 0, ! 67: "imulb", 1, OP_BYTE, ! 68: "in", 1, 0, ! 69: "inb", 1, OP_BYTE, ! 70: "inc", 1, 0, ! 71: "incb", 1, OP_BYTE, ! 72: "int", 1, OP_NPTR, ! 73: "into", 0, 0, ! 74: "iret", 0, 0, ! 75: #if AS_FORMAT ! 76: "xicall", 1, OP_DWORD, ! 77: "xijmp", 1, OP_NPTR, ! 78: #else ! 79: "call", 1, OP_DWORD, ! 80: "jmp", 1, OP_NPTR, ! 81: #endif ! 82: "ja", 1, OP_JUMP, ! 83: "jae", 1, OP_JUMP, ! 84: "jb", 1, OP_JUMP, ! 85: "jbe", 1, OP_JUMP, ! 86: "jcxz", 1, OP_JUMP, ! 87: "je", 1, OP_JUMP, ! 88: "jg", 1, OP_JUMP, ! 89: "jge", 1, OP_JUMP, ! 90: "jl", 1, OP_JUMP, ! 91: "jle", 1, OP_JUMP, ! 92: "jmp", 1, OP_JUMP, ! 93: "jne", 1, OP_JUMP, ! 94: "jno", 1, OP_JUMP, ! 95: "jns", 1, OP_JUMP, ! 96: "jo", 1, OP_JUMP, ! 97: "jpe", 1, OP_JUMP, ! 98: "jpo", 1, OP_JUMP, ! 99: "js", 1, OP_JUMP, ! 100: "lahf", 0, 0, ! 101: "lds", 2, OP_DWORD, ! 102: "lea", 2, 0, ! 103: "les", 2, OP_DWORD, ! 104: "lock", 0, 0, ! 105: "lodsw", 0, 0, ! 106: "lodsb", 0, 0, ! 107: "loop", 1, OP_JUMP, ! 108: "loope", 1, OP_JUMP, ! 109: "loopne", 1, OP_JUMP, ! 110: "mov", 2, 0, ! 111: "movb", 2, OP_BYTE, ! 112: "movsw", 0, 0, ! 113: "movsb", 0, 0, ! 114: "mul", 1, 0, ! 115: "mulb", 1, OP_BYTE, ! 116: "neg", 1, 0, ! 117: "negb", 1, OP_BYTE, ! 118: "not", 1, 0, ! 119: "notb", 1, OP_BYTE, ! 120: "ret", 1, OP_NPTR, ! 121: "ret", 1, OP_NPTR, ! 122: "or", 2, 0, ! 123: "orb", 2, OP_BYTE, ! 124: "out", 1, 0, ! 125: "outb", 1, OP_BYTE, ! 126: "pop", 1, 0, ! 127: "popf", 0, 0, ! 128: "push", 1, 0, ! 129: "pushf", 0, 0, ! 130: "rcl", 2, 0, ! 131: "rclb", 2, OP_BYTE, ! 132: "rcr", 2, 0, ! 133: "rcrb", 2, OP_BYTE, ! 134: "repe", 0, 0, ! 135: "repne", 0, 0, ! 136: "ret", 0, 0, ! 137: "rol", 2, 0, ! 138: "rolb", 2, OP_BYTE, ! 139: "ror", 2, 0, ! 140: "rorb", 2, OP_BYTE, ! 141: "sahf", 0, 0, ! 142: "sal", 2, 0, ! 143: "salb", 2, OP_BYTE, ! 144: "sar", 2, 0, ! 145: "sarb", 2, OP_BYTE, ! 146: "sbb", 2, 0, ! 147: "sbbb", 2, OP_BYTE, ! 148: "scasw", 0, 0, ! 149: "scasb", 0, 0, ! 150: "shl", 2, 0, ! 151: "shlb", 2, OP_BYTE, ! 152: "shr", 2, 0, ! 153: "shrb", 2, OP_BYTE, ! 154: "stc", 0, 0, ! 155: "std", 0, 0, ! 156: "sti", 0, 0, ! 157: "stosw", 0, 0, ! 158: "stosb", 0, 0, ! 159: "sub", 2, 0, ! 160: "subb", 2, OP_BYTE, ! 161: "test", 2, 0, ! 162: "testb", 2, OP_BYTE, ! 163: "wait", 0, 0, ! 164: #if AS_FORMAT ! 165: "xcall", 1, OP_NPTR, ! 166: #else ! 167: "call", 1, OP_NPTR, ! 168: #endif ! 169: "xchg", 2, 0, ! 170: "xchgb", 2, OP_BYTE, ! 171: #if AS_FORMAT ! 172: "xjmp", 1, OP_NPTR, ! 173: #else ! 174: "jmp", 1, OP_NPTR, ! 175: #endif ! 176: "xlat", 0, 0, ! 177: "xor", 2, 0, ! 178: "xorb", 2, OP_BYTE, ! 179: #if AS_FORMAT ! 180: "xret", 0, 0, ! 181: #else ! 182: "ret", 0, 0, ! 183: #endif ! 184: ! 185: #if AS_FORMAT ! 186: ".byte", 1, OP_DD|OP_NPTR, ! 187: ".word", 1, OP_DD|OP_NPTR, ! 188: ".word", 1, OP_DD|OP_NPTR, ! 189: ".long", 1, OP_DD|OP_NPTR, ! 190: #else ! 191: "db", 1, OP_DD|OP_NPTR, ! 192: "dw", 1, OP_DD|OP_NPTR, ! 193: "dw", 1, OP_DD|OP_NPTR, ! 194: "dd", 1, OP_DD|OP_NPTR, ! 195: #endif ! 196: ! 197: "fadd", 0, 0, ! 198: "faddf", 1, 0, ! 199: "faddd", 1, 0, ! 200: "faddi", 1, 0, ! 201: "faddl", 1, 0, ! 202: "fsub", 0, 0, ! 203: "fsubf", 1, 0, ! 204: "fsubd", 1, 0, ! 205: "fsubi", 1, 0, ! 206: "fsubl", 1, 0, ! 207: "frsub", 0, 0, ! 208: "frsubf", 1, 0, ! 209: "frsubd", 1, 0, ! 210: "frsubi", 1, 0, ! 211: "frsubl", 1, 0, ! 212: "fcompp", 0, 0, ! 213: "fcompf", 1, 0, ! 214: "fcompd", 1, 0, ! 215: "fcompi", 1, 0, ! 216: "fcompl", 1, 0, ! 217: "fmul", 0, 0, ! 218: "fmulf", 1, 0, ! 219: "fmuld", 1, 0, ! 220: "fmuli", 1, 0, ! 221: "fmull", 1, 0, ! 222: "fdiv", 0, 0, ! 223: "fdivf", 1, 0, ! 224: "fdivd", 1, 0, ! 225: "fdivi", 1, 0, ! 226: "fdivl", 1, 0, ! 227: "frdiv", 0, 0, ! 228: "frdivf", 1, 0, ! 229: "frdivd", 1, 0, ! 230: "frdivi", 1, 0, ! 231: "frdivl", 1, 0, ! 232: "fchs", 0, 0, ! 233: "ftst", 0, 0, ! 234: "fldz", 0, 0, ! 235: "fld1", 0, 0, ! 236: "fstsw", 1, 0, ! 237: "fldf", 1, 0, ! 238: "fldd", 1, 0, ! 239: "fldi", 1, 0, ! 240: "fldl", 1, 0, ! 241: "fldt", 1, 0, ! 242: "fstf", 1, 0, ! 243: "fstd", 1, 0, ! 244: "fsti", 1, 0, ! 245: "fstl", 1, 0, ! 246: "fstpf", 1, 0, ! 247: "fstpd", 1, 0, ! 248: "fstpi", 1, 0, ! 249: "fstpl", 1, 0, ! 250: "fstpt", 1, 0, ! 251: "fwait", 0, 0, ! 252: "fdrop", 0, 0, ! 253: "fsqrt", 0, 0, ! 254: "fabs", 0, 0, ! 255: "fprem", 0, 0, ! 256: "frnd", 0, 0, ! 257: "ldes", 0, 0, ! 258: "imul", 3, 0, ! 259: "enter", 2, 0, ! 260: "leave", 0, 0 ! 261: }; ! 262: ! 263: /* ! 264: * Handle code nodes. ! 265: */ ! 266: icode() ! 267: { ! 268: register int op, i, n; ! 269: register struct ins *ip; ! 270: ! 271: bput('\t'); ! 272: op = bget(); ! 273: ip = &ins[op]; ! 274: fprintf(ofp, "%s", ip->i_name); ! 275: n = ip->i_size; ! 276: for (i=0; i < n; i += 1) { ! 277: if (i == 0) ! 278: bput('\t'); ! 279: else ! 280: fprintf(ofp, ", "); ! 281: iafield(ip); ! 282: } ! 283: bput('\n'); ! 284: } ! 285: ! 286: /* ! 287: * These tables are indexed by the ! 288: * regm field of a mode. They contain the ascii ! 289: * strings used to print things in VASM mode. ! 290: */ ! 291: static char *wregs[] = { ! 292: "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" ! 293: }; ! 294: ! 295: static char *bregs[] = { ! 296: "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" ! 297: }; ! 298: ! 299: static char *sregs[] = { ! 300: "es", "cs", "ss", "ds" ! 301: }; ! 302: ! 303: static char *xregs[] = { ! 304: "bx, si", "bx, di", "bp, si", "bp, di", ! 305: "si", "di", "bp", "bx" ! 306: }; ! 307: ! 308: /* ! 309: * Read and print an address field. The style ! 310: * of the address is determined by flag bits that ! 311: * hide in the address mode. These bits are cleared away ! 312: * when the mode is actually stored in the afield. ! 313: */ ! 314: iafield(ip) ! 315: register struct ins *ip; ! 316: { ! 317: register int imode; ! 318: register int mode; ! 319: register int regm; ! 320: register int offs; ! 321: register int prefix; ! 322: ! 323: imode = iget(); ! 324: if ((imode&A_OFFS) != 0) ! 325: offs = iget(); ! 326: else ! 327: offs = 0; ! 328: if ((imode&A_LID) != 0) ! 329: sprintf(id, "L%d", iget()); ! 330: else if ((imode&A_GID) != 0) ! 331: sget(id, NCSYMB); ! 332: mode = imode&A_AMOD; ! 333: regm = imode&A_REGM; ! 334: switch (mode) { ! 335: ! 336: case A_IMM: ! 337: #if AS_FORMAT ! 338: bput('$'); ! 339: #else ! 340: if ((imode&(A_LID|A_GID)) != 0) ! 341: fprintf(ofp, "offset "); ! 342: #endif ! 343: case A_DIR: ! 344: case A_X: ! 345: if (mode!=A_IMM && (ip->i_flag&OP_NPTR)==0) { ! 346: if ((imode&A_PREFX) != 0) { ! 347: prefix = ((imode&A_PREFX)>>8)-1; ! 348: fprintf(ofp, "%s:", sregs[prefix]); ! 349: } ! 350: #if !AS_FORMAT ! 351: if ((ip->i_flag&OP_BYTE) != 0) ! 352: fprintf(ofp, "byte"); ! 353: else if ((ip->i_flag&OP_DWORD) != 0) ! 354: fprintf(ofp, "dword"); ! 355: else ! 356: fprintf(ofp, "word"); ! 357: fprintf(ofp, " ptr "); ! 358: #endif ! 359: } ! 360: #if !AS_FORMAT ! 361: if (mode == A_X) ! 362: fprintf(ofp, "[%s", xregs[regm]); ! 363: #endif ! 364: if ((imode&(A_LID|A_GID)) != 0) { ! 365: #if !AS_FORMAT ! 366: if (mode == A_X) ! 367: bput('+'); ! 368: #endif ! 369: fprintf(ofp, "%s", id); ! 370: if ((SIGNEDADDRESS)offs > 0) ! 371: bput('+'); ! 372: } ! 373: #if !AS_FORMAT ! 374: else if (mode==A_X && (SIGNEDADDRESS)offs>0) ! 375: bput('+'); ! 376: #endif ! 377: if (offs!=0 || ((imode&(A_LID|A_GID))==0 && mode!=A_X)) { ! 378: #if !AS_FORMAT ! 379: if ((SIGNEDADDRESS)offs<0) { ! 380: bput('-'); ! 381: offs = -(SIGNEDADDRESS)offs; ! 382: } ! 383: fprintf(ofp, "0%xh", offs); ! 384: #else ! 385: fprintf(ofp, "%d", offs); ! 386: #endif ! 387: } ! 388: if (mode == A_X) ! 389: #if AS_FORMAT ! 390: fprintf(ofp, "(%s)", xregs[regm]); ! 391: #else ! 392: bput(']'); ! 393: #endif ! 394: break; ! 395: ! 396: case A_WR: ! 397: fprintf(ofp, wregs[regm]); ! 398: break; ! 399: ! 400: case A_BR: ! 401: fprintf(ofp, bregs[regm]); ! 402: break; ! 403: ! 404: case A_SR: ! 405: fprintf(ofp, sregs[regm]); ! 406: break; ! 407: ! 408: default: ! 409: cbotch("ifield, mode=%d", mode); ! 410: } ! 411: } ! 412:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.