|
|
1.1 ! root 1: /* ! 2: Copyright (C) 1996-1997 Id Software, Inc. ! 3: ! 4: This program is free software; you can redistribute it and/or ! 5: modify it under the terms of the GNU General Public License ! 6: as published by the Free Software Foundation; either version 2 ! 7: of the License, or (at your option) any later version. ! 8: ! 9: This program is distributed in the hope that it will be useful, ! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! 12: ! 13: See the GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! 18: ! 19: */ ! 20: // ! 21: // gas to MASM source code converter ! 22: // ! 23: ! 24: #include <stdio.h> ! 25: #include <stdlib.h> ! 26: #include <string.h> ! 27: ! 28: #define MAX_TOKENS 100 ! 29: #define MAX_TOKEN_LENGTH 1024 ! 30: #define LF 0x0A ! 31: ! 32: typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat; ! 33: typedef enum {NOSEG, DATASEG, TEXTSEG} segtype; ! 34: ! 35: int tokennum; ! 36: int inline, outline; ! 37: ! 38: char *token; ! 39: char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1]; ! 40: ! 41: segtype currentseg = NOSEG; ! 42: ! 43: typedef struct { ! 44: char *text; ! 45: char *emit; ! 46: int numtokens; ! 47: void (*parsefunc) (void); ! 48: } parsefield; ! 49: ! 50: ! 51: void errorexit (void); ! 52: ! 53: ! 54: //============================================== ! 55: ! 56: typedef struct { ! 57: char *text; ! 58: char *emit; ! 59: int len; ! 60: } regdesc; ! 61: ! 62: regdesc reglist[] = { ! 63: {"%eax", "eax", 4}, ! 64: {"%ebx", "ebx", 4}, ! 65: {"%ecx", "ecx", 4}, ! 66: {"%edx", "edx", 4}, ! 67: {"%esi", "esi", 4}, ! 68: {"%edi", "edi", 4}, ! 69: {"%ebp", "ebp", 4}, ! 70: {"%esp", "esp", 4}, ! 71: {"%ax", "ax", 3}, ! 72: {"%bx", "bx", 3}, ! 73: {"%cx", "cx", 3}, ! 74: {"%dx", "dx", 3}, ! 75: {"%si", "si", 3}, ! 76: {"%di", "di", 3}, ! 77: {"%bp", "bp", 3}, ! 78: {"%sp", "sp", 3}, ! 79: {"%al", "al", 3}, ! 80: {"%bl", "bl", 3}, ! 81: {"%cl", "cl", 3}, ! 82: {"%dl", "dl", 3}, ! 83: {"%ah", "ah", 3}, ! 84: {"%bh", "bh", 3}, ! 85: {"%ch", "ch", 3}, ! 86: {"%dh", "dh", 3}, ! 87: {"%st(0)", "st(0)", 6}, ! 88: {"%st(1)", "st(1)", 6}, ! 89: {"%st(2)", "st(2)", 6}, ! 90: {"%st(3)", "st(3)", 6}, ! 91: {"%st(4)", "st(4)", 6}, ! 92: {"%st(5)", "st(5)", 6}, ! 93: {"%st(6)", "st(6)", 6}, ! 94: {"%st(7)", "st(7)", 6}, ! 95: }; ! 96: ! 97: int numregs = sizeof (reglist) / sizeof (reglist[0]); ! 98: ! 99: //============================================== ! 100: ! 101: ! 102: void emitanoperand (int tnum, char *type, int notdata) ! 103: { ! 104: int i, index, something_outside_parens, regfound; ! 105: int parencount; ! 106: char *pt; ! 107: char temp[MAX_TOKEN_LENGTH+1]; ! 108: ! 109: pt = tokens[tnum]; ! 110: ! 111: if (pt[0] == '%') ! 112: { ! 113: // register ! 114: for (i=0 ; i<numregs ; i++) ! 115: { ! 116: if (!strcmpi (pt, reglist[i].text)) ! 117: { ! 118: printf ("%s", reglist[i].emit); ! 119: return; ! 120: } ! 121: } ! 122: ! 123: fprintf (stderr, "Error: bad register %s\n", pt); ! 124: errorexit (); ! 125: } ! 126: else if (pt[0] == '$') ! 127: { ! 128: // constant ! 129: if (pt[1] == '(') ! 130: { ! 131: if ((pt[2] > '9') || (pt[2] < '0')) ! 132: { ! 133: i = 2; ! 134: printf ("offset "); ! 135: ! 136: parencount = 1; ! 137: ! 138: while ((pt[i] != ')') || (parencount > 1)) ! 139: { ! 140: if (!pt[i]) ! 141: { ! 142: fprintf (stderr, "mismatched parens"); ! 143: errorexit (); ! 144: } ! 145: ! 146: if (pt[i] == ')') ! 147: parencount--; ! 148: else if (pt[i] == '(') ! 149: parencount++; ! 150: ! 151: printf ("%c", pt[i]); ! 152: i++; ! 153: } ! 154: } ! 155: else ! 156: { ! 157: pt++; ! 158: ! 159: parencount = 1; ! 160: ! 161: for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++) ! 162: { ! 163: if (!pt[i]) ! 164: { ! 165: fprintf (stderr, "mismatched parens"); ! 166: errorexit (); ! 167: } ! 168: ! 169: if (pt[i] == ')') ! 170: parencount--; ! 171: else if (pt[i] == '(') ! 172: parencount++; ! 173: } ! 174: ! 175: pt[i] = 0; ! 176: ! 177: if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) ! 178: { ! 179: printf ("0%sh", &pt[3]); ! 180: } ! 181: else ! 182: { ! 183: printf ("%s", &pt[1]); ! 184: } ! 185: } ! 186: } ! 187: else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) ! 188: { ! 189: printf ("0%sh", &pt[3]); ! 190: } ! 191: else if ((pt[1] >= '0') && (pt[1] <= '9')) ! 192: { ! 193: printf ("%s", &pt[1]); ! 194: } ! 195: else ! 196: { ! 197: printf ("offset %s", &pt[1]); ! 198: } ! 199: } ! 200: else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9'))) ! 201: { ! 202: pt--; ! 203: ! 204: if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) ! 205: { ! 206: printf ("0%sh", &pt[3]); ! 207: } ! 208: else ! 209: { ! 210: printf ("%s", &pt[1]); ! 211: } ! 212: } ! 213: else ! 214: { ! 215: // must be a memory location ! 216: strcpy (temp, type); ! 217: index = strlen (temp); ! 218: ! 219: if (notdata) ! 220: temp[index++] = '['; ! 221: ! 222: something_outside_parens = 0; ! 223: ! 224: while (*pt) ! 225: { ! 226: if (index > (MAX_TOKEN_LENGTH - 10)) ! 227: { ! 228: fprintf (stderr, "Error: operand too long %s\n", ! 229: tokens[tnum]); ! 230: errorexit (); ! 231: } ! 232: ! 233: if (*pt != ')') ! 234: { ! 235: if (*pt == '(') ! 236: { ! 237: if (something_outside_parens) ! 238: temp[index++] = '+'; ! 239: } ! 240: else if (*pt == '%') ! 241: { ! 242: regfound = 0; ! 243: ! 244: for (i=0 ; i<numregs ; i++) ! 245: { ! 246: if (!strnicmp (pt, reglist[i].text, ! 247: reglist[i].len)) ! 248: { ! 249: strcpy (&temp[index], reglist[i].emit); ! 250: index += strlen (reglist[i].emit); ! 251: pt += strlen (reglist[i].text) - 1; ! 252: regfound = 1; ! 253: break; ! 254: } ! 255: } ! 256: ! 257: if (!regfound) ! 258: { ! 259: fprintf (stderr, "Error: bad register %s\n", pt); ! 260: errorexit (); ! 261: } ! 262: } ! 263: else if (*pt == ',') ! 264: { ! 265: pt++; ! 266: ! 267: if ((*pt >= '1') && (*pt <= '8')) ! 268: { ! 269: temp[index++] = '*'; ! 270: temp[index++] = *pt; ! 271: } ! 272: else if (*pt != ')') ! 273: { ! 274: if (temp[index-1] != '+') ! 275: temp[index++] = '+'; ! 276: } ! 277: } ! 278: else ! 279: { ! 280: something_outside_parens = 1; ! 281: ! 282: // handle hexadecimal constants in addresses ! 283: if ((*pt == '0') && ! 284: ((*(pt+1) == 'x') || (*(pt+1) == 'X'))) ! 285: { ! 286: pt += 2; ! 287: ! 288: do ! 289: { ! 290: temp[index++] = *pt++; ! 291: } while (((*pt >= '0') && (*pt <= '9')) || ! 292: ((*pt >= 'a') && (*pt <= 'f')) || ! 293: ((*pt >= 'A') && (*pt <= 'F'))); ! 294: ! 295: pt--; ! 296: temp[index++] = 'h'; ! 297: } ! 298: else ! 299: { ! 300: temp[index++] = *pt; ! 301: } ! 302: } ! 303: } ! 304: ! 305: pt++; ! 306: } ! 307: ! 308: if (notdata) ! 309: temp[index++] = ']'; ! 310: ! 311: temp[index] = 0; ! 312: printf ("%s", temp); ! 313: } ! 314: } ! 315: ! 316: ! 317: void datasegstart (void) ! 318: { ! 319: if (currentseg == DATASEG) ! 320: return; ! 321: ! 322: if (currentseg == TEXTSEG) ! 323: printf ("_TEXT ENDS\n"); ! 324: ! 325: printf ("_DATA SEGMENT"); ! 326: ! 327: currentseg = DATASEG; ! 328: } ! 329: ! 330: ! 331: void textsegstart (void) ! 332: { ! 333: if (currentseg == TEXTSEG) ! 334: return; ! 335: ! 336: if (currentseg == DATASEG) ! 337: printf ("_DATA ENDS\n"); ! 338: ! 339: printf ("_TEXT SEGMENT"); ! 340: ! 341: currentseg = TEXTSEG; ! 342: } ! 343: ! 344: ! 345: void emitdata (void) ! 346: { ! 347: int i; ! 348: ! 349: for (i=1 ; i<(tokennum-1) ; i++) ! 350: printf (" %s,", tokens[i]); ! 351: ! 352: printf (" %s", tokens[tokennum-1]); ! 353: } ! 354: ! 355: ! 356: void emitonedata (void) ! 357: { ! 358: ! 359: printf (" %s", tokens[1]); ! 360: } ! 361: ! 362: ! 363: void emitonecalldata (void) ! 364: { ! 365: int i, isaddr, len; ! 366: ! 367: if (tokens[1][0] == '*') ! 368: { ! 369: printf (" dword ptr[%s]", &tokens[1][1]); ! 370: } ! 371: else ! 372: { ! 373: isaddr = 0; ! 374: len = strlen(tokens[1]); ! 375: ! 376: for (i=0 ; i<len ; i++) ! 377: { ! 378: if (tokens[1][i] == '(') ! 379: { ! 380: isaddr = 1; ! 381: break; ! 382: } ! 383: } ! 384: ! 385: if (!isaddr) ! 386: { ! 387: printf (" near ptr %s", tokens[1]); ! 388: } ! 389: else ! 390: { ! 391: emitanoperand (1, " dword ptr", 1); ! 392: } ! 393: } ! 394: } ! 395: ! 396: ! 397: void emitonejumpdata (void) ! 398: { ! 399: int i, isaddr, len; ! 400: ! 401: if (tokens[1][0] == '*') ! 402: { ! 403: printf (" dword ptr[%s]", &tokens[1][1]); ! 404: } ! 405: else ! 406: { ! 407: isaddr = 0; ! 408: len = strlen(tokens[1]); ! 409: ! 410: for (i=0 ; i<len ; i++) ! 411: { ! 412: if (tokens[1][i] == '(') ! 413: { ! 414: isaddr = 1; ! 415: break; ! 416: } ! 417: } ! 418: ! 419: if (!isaddr) ! 420: { ! 421: printf (" %s", tokens[1]); ! 422: } ! 423: else ! 424: { ! 425: emitanoperand (1, " dword ptr", 1); ! 426: } ! 427: } ! 428: } ! 429: ! 430: ! 431: void emitexterndef (void) ! 432: { ! 433: ! 434: printf (" %s:dword", tokens[1]); ! 435: } ! 436: ! 437: ! 438: void nooperands (void) ! 439: { ! 440: ! 441: } ! 442: ! 443: ! 444: void emitoneoperandl (void) ! 445: { ! 446: ! 447: printf (" "); ! 448: emitanoperand (1, "ds:dword ptr", 1); ! 449: } ! 450: ! 451: ! 452: void emitoneoperandb (void) ! 453: { ! 454: ! 455: printf (" "); ! 456: emitanoperand (1, "ds:byte ptr", 1); ! 457: } ! 458: ! 459: ! 460: void emitoneoperandw (void) ! 461: { ! 462: ! 463: printf (" "); ! 464: emitanoperand (1, "ds:word ptr", 1); ! 465: } ! 466: ! 467: ! 468: void emittwooperandsl (void) ! 469: { ! 470: ! 471: printf (" "); ! 472: emitanoperand (2, "ds:dword ptr", 1); ! 473: printf (","); ! 474: emitanoperand (1, "ds:dword ptr", 1); ! 475: } ! 476: ! 477: ! 478: void emittwooperandsb (void) ! 479: { ! 480: ! 481: printf (" "); ! 482: emitanoperand (2, "ds:byte ptr", 1); ! 483: printf (","); ! 484: emitanoperand (1, "ds:byte ptr", 1); ! 485: } ! 486: ! 487: ! 488: void emittwooperandsw (void) ! 489: { ! 490: ! 491: printf (" "); ! 492: emitanoperand (2, "ds:word ptr", 1); ! 493: printf (","); ! 494: emitanoperand (1, "ds:word ptr", 1); ! 495: } ! 496: ! 497: ! 498: void emit_0_or_1_operandsl (void) ! 499: { ! 500: ! 501: if (tokennum == 2) ! 502: { ! 503: printf (" "); ! 504: emitanoperand (1, "ds:dword ptr", 1); ! 505: } ! 506: } ! 507: ! 508: ! 509: void emit_1_or_2_operandsl (void) ! 510: { ! 511: int j; ! 512: ! 513: if (tokennum == 2) ! 514: { ! 515: printf (" "); ! 516: emitanoperand (1, "ds:dword ptr", 1); ! 517: } ! 518: else if (tokennum == 3) ! 519: { ! 520: printf (" "); ! 521: emitanoperand (2, "ds:dword ptr", 1); ! 522: printf (","); ! 523: emitanoperand (1, "ds:dword ptr", 1); ! 524: } ! 525: else ! 526: { ! 527: ! 528: fprintf (stderr, "Error: too many operands\n"); ! 529: ! 530: for (j=0 ; j<tokennum ; j++) ! 531: fprintf (stderr, "%s\n", tokens[j]); ! 532: ! 533: fprintf (stderr, "\n"); ! 534: errorexit (); ! 535: } ! 536: } ! 537: ! 538: ! 539: void emit_1_or_2_operandsl_vartext (char *str0, char *str1) ! 540: { ! 541: int j; ! 542: ! 543: if (tokennum == 2) ! 544: { ! 545: printf (" %s ", str0); ! 546: emitanoperand (1, "ds:dword ptr", 1); ! 547: } ! 548: else if (tokennum == 3) ! 549: { ! 550: if (!strcmpi (tokens[2], "%st(0)")) ! 551: printf (" %s ", str0); ! 552: else ! 553: printf (" %s ", str1); ! 554: ! 555: emitanoperand (2, "ds:dword ptr", 1); ! 556: printf (","); ! 557: emitanoperand (1, "ds:dword ptr", 1); ! 558: } ! 559: else ! 560: { ! 561: ! 562: fprintf (stderr, "Error: too many operands\n"); ! 563: ! 564: for (j=0 ; j<tokennum ; j++) ! 565: fprintf (stderr, "%s\n", tokens[j]); ! 566: ! 567: fprintf (stderr, "\n"); ! 568: errorexit (); ! 569: } ! 570: } ! 571: ! 572: ! 573: void special_fdivl (void) ! 574: { ! 575: ! 576: emit_1_or_2_operandsl_vartext ("fdiv", "fdivr"); ! 577: } ! 578: ! 579: ! 580: void special_fdivpl (void) ! 581: { ! 582: ! 583: emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp"); ! 584: } ! 585: ! 586: ! 587: void special_fdivrl (void) ! 588: { ! 589: ! 590: emit_1_or_2_operandsl_vartext ("fdivr", "fdiv"); ! 591: } ! 592: ! 593: ! 594: void special_fdivrpl (void) ! 595: { ! 596: ! 597: emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp"); ! 598: } ! 599: ! 600: ! 601: void special_fsubl (void) ! 602: { ! 603: ! 604: emit_1_or_2_operandsl_vartext ("fsub", "fsubr"); ! 605: } ! 606: ! 607: ! 608: void special_fsubpl (void) ! 609: { ! 610: ! 611: emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp"); ! 612: } ! 613: ! 614: ! 615: void special_fsubrl (void) ! 616: { ! 617: ! 618: emit_1_or_2_operandsl_vartext ("fsubr", "fsub"); ! 619: } ! 620: ! 621: ! 622: void special_fsubrpl (void) ! 623: { ! 624: ! 625: emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp"); ! 626: } ! 627: ! 628: ! 629: void emit_multiple_data (void) ! 630: { ! 631: int i; ! 632: ! 633: printf (" "); ! 634: ! 635: for (i=1 ; i<(tokennum-1) ; i++) ! 636: { ! 637: emitanoperand (i, "", 0); ! 638: printf (", "); ! 639: } ! 640: ! 641: emitanoperand (i, "", 0); ! 642: } ! 643: ! 644: ! 645: //============================================== ! 646: ! 647: parsefield parsedata[] = { ! 648: {".align", " align", 2, emitonedata}, ! 649: {".byte", " db", -2, emit_multiple_data}, ! 650: {".data", "", 1, datasegstart}, ! 651: {".extern"," externdef", 2, emitexterndef}, ! 652: {".globl", " public", -2, emit_multiple_data}, ! 653: {".long", " dd", -2, emit_multiple_data}, ! 654: {".single"," dd", -2, emit_multiple_data}, ! 655: {".text", "", 1, textsegstart}, ! 656: {"adcl", " adc", 3, emittwooperandsl}, ! 657: {"addb", " add", 3, emittwooperandsb}, ! 658: {"addl", " add", 3, emittwooperandsl}, ! 659: {"andb", " and", 3, emittwooperandsb}, ! 660: {"andl", " and", 3, emittwooperandsl}, ! 661: {"call", " call", 2, emitonecalldata}, ! 662: {"cmpb", " cmp", 3, emittwooperandsb}, ! 663: {"cmpl", " cmp", 3, emittwooperandsl}, ! 664: {"cmpw", " cmp", 3, emittwooperandsw}, ! 665: {"decl", " dec", 2, emitoneoperandl}, ! 666: {"decw", " dec", 2, emitoneoperandw}, ! 667: {"divl", " div", 2, emitoneoperandl}, ! 668: {"fadd", " fadd", -2, emit_1_or_2_operandsl}, ! 669: {"faddp", " faddp", -2, emit_1_or_2_operandsl}, ! 670: {"faddps", " faddp", -2, emit_1_or_2_operandsl}, ! 671: {"fadds", " fadd", -2, emit_1_or_2_operandsl}, ! 672: {"fcom", " fcom", 2, emitoneoperandl}, ! 673: {"fcoms", " fcom", 2, emitoneoperandl}, ! 674: {"fcomp", " fcomp", 2, emitoneoperandl}, ! 675: {"fcomps", " fcomp", 2, emitoneoperandl}, ! 676: {"fdiv", "", -2, special_fdivl}, ! 677: {"fdivp", "", -2, special_fdivpl}, ! 678: {"fdivr", "", -2, special_fdivrl}, ! 679: {"fdivrp", "", -2, special_fdivrpl}, ! 680: {"fdivrs", "", -2, special_fdivrl}, ! 681: {"fildl", " fild", 2, emitoneoperandl}, ! 682: {"fistl", " fist", 2, emitoneoperandl}, ! 683: {"fistpl", " fistp", 2, emitoneoperandl}, ! 684: {"fld", " fld", 2, emitoneoperandl}, ! 685: {"fldcw", " fldcw", 2, emitoneoperandw}, ! 686: {"fldenv", " fldenv", 2, emitoneoperandl}, ! 687: {"flds", " fld", 2, emitoneoperandl}, ! 688: {"fmul", " fmul", -2, emit_1_or_2_operandsl}, ! 689: {"fmulp", " fmulp", -2, emit_1_or_2_operandsl}, ! 690: {"fmulps", " fmulp", -2, emit_1_or_2_operandsl}, ! 691: {"fmuls", " fmul", -2, emit_1_or_2_operandsl}, ! 692: {"fnstcw", " fnstcw", 2, emitoneoperandw}, ! 693: {"fnstenv"," fnstenv", 2, emitoneoperandl}, ! 694: {"fnstsw", " fnstsw", 2, emitoneoperandw}, ! 695: {"fstp", " fstp", 2, emitoneoperandl}, ! 696: {"fstps", " fstp", 2, emitoneoperandl}, ! 697: {"fsts", " fst", 2, emitoneoperandl}, ! 698: {"fsubr", "", -2, special_fsubrl}, ! 699: {"fsubrp", "", -2, special_fsubrpl}, ! 700: {"fsubrs", "", -2, special_fsubrl}, ! 701: {"fsub", "", -2, special_fsubl}, ! 702: {"fsubp", "", -2, special_fsubpl}, ! 703: {"fsubps", "", -2, special_fsubpl}, ! 704: {"fsubs", "", -2, special_fsubl}, ! 705: {"fxch", " fxch", 2, emitoneoperandl}, ! 706: {"imull", " imul", -2, emit_1_or_2_operandsl}, ! 707: {"incl", " inc", 2, emitoneoperandl}, ! 708: {"ja", " ja", 2, emitonedata}, ! 709: {"jae", " jae", 2, emitonedata}, ! 710: {"jb", " jb", 2, emitonedata}, ! 711: {"jbe", " jbe", 2, emitonedata}, ! 712: {"jc", " jc", 2, emitonedata}, ! 713: {"je", " je", 2, emitonedata}, ! 714: {"jg", " jg", 2, emitonedata}, ! 715: {"jge", " jge", 2, emitonedata}, ! 716: {"jl", " jl", 2, emitonedata}, ! 717: {"jle", " jle", 2, emitonedata}, ! 718: {"jmp", " jmp", 2, emitonejumpdata}, ! 719: {"jna", " jna", 2, emitonedata}, ! 720: {"jnae", " jnae", 2, emitonedata}, ! 721: {"jnb", " jnb", 2, emitonedata}, ! 722: {"jnbe", " jnbe", 2, emitonedata}, ! 723: {"jnc", " jnc", 2, emitonedata}, ! 724: {"jne", " jne", 2, emitonedata}, ! 725: {"jng", " jng", 2, emitonedata}, ! 726: {"jnge", " jnge", 2, emitonedata}, ! 727: {"jnl", " jnl", 2, emitonedata}, ! 728: {"jnle", " jnle", 2, emitonedata}, ! 729: {"jns", " jns", 2, emitonedata}, ! 730: {"jnz", " jnz", 2, emitonedata}, ! 731: {"js", " js", 2, emitonedata}, ! 732: {"jz", " jz", 2, emitonedata}, ! 733: {"leal", " lea", 3, emittwooperandsl}, ! 734: {"movb", " mov", 3, emittwooperandsb}, ! 735: {"movl", " mov", 3, emittwooperandsl}, ! 736: {"movw", " mov", 3, emittwooperandsw}, ! 737: {"negl", " neg", 2, emitoneoperandl}, ! 738: {"orb", " or", 3, emittwooperandsb}, ! 739: {"orl", " or", 3, emittwooperandsl}, ! 740: {"popl", " pop", 2, emitoneoperandl}, ! 741: {"pushl", " push", 2, emitoneoperandl}, ! 742: {"ret", " ret", -1, emit_0_or_1_operandsl}, ! 743: {"rorl", " ror", 3, emittwooperandsl}, ! 744: {"sarl", " sar", 3, emittwooperandsl}, ! 745: {"sbbl", " sbb", 3, emittwooperandsl}, ! 746: {"shll", " shl", 3, emittwooperandsl}, ! 747: {"shrl", " shr", 3, emittwooperandsl}, ! 748: {"subl", " sub", 3, emittwooperandsl}, ! 749: {"testb", " test", 3, emittwooperandsb}, ! 750: {"testl", " test", 3, emittwooperandsl}, ! 751: {"xorb", " xor", 3, emittwooperandsb}, ! 752: {"xorl", " xor", 3, emittwooperandsl}, ! 753: }; ! 754: ! 755: int numparse = sizeof (parsedata) / sizeof (parsedata[0]); ! 756: ! 757: //============================================== ! 758: ! 759: void errorexit (void) ! 760: { ! 761: fprintf (stderr, "In line: %d, out line: %d\n", inline, outline); ! 762: exit (1); ! 763: } ! 764: ! 765: ! 766: tokenstat whitespace (char c) ! 767: { ! 768: if (c == '\n') ! 769: return LINE_DONE; ! 770: ! 771: if ((c <= ' ') || ! 772: (c > 127) || ! 773: (c == ',')) ! 774: { ! 775: return WHITESPACE; ! 776: } ! 777: ! 778: return NOT_WHITESPACE; ! 779: } ! 780: ! 781: ! 782: int gettoken (void) ! 783: { ! 784: char c; ! 785: int count, parencount; ! 786: tokenstat stat; ! 787: ! 788: do ! 789: { ! 790: if ((c = getchar ()) == EOF) ! 791: return FILE_DONE; ! 792: ! 793: if ((stat = whitespace (c)) == LINE_DONE) ! 794: return LINE_DONE; ! 795: } while (stat == WHITESPACE); ! 796: ! 797: token[0] = c; ! 798: count = 1; ! 799: ! 800: if (c == '~') ! 801: { ! 802: count--; ! 803: token[count++] = 'n'; ! 804: token[count++] = 'o'; ! 805: token[count++] = 't'; ! 806: token[count++] = ' '; ! 807: } ! 808: ! 809: if (c == '(') ! 810: { ! 811: do ! 812: { ! 813: if ((c = getchar ()) == EOF) ! 814: { ! 815: fprintf (stderr, "EOF in middle of parentheses\n"); ! 816: errorexit (); ! 817: } ! 818: ! 819: token[count++] = c; ! 820: ! 821: } while (c != ')'); ! 822: } ! 823: ! 824: for ( ;; ) ! 825: { ! 826: if ((c = getchar ()) == EOF) ! 827: { ! 828: token[count] = 0; ! 829: return TOKEN_AVAILABLE; ! 830: } ! 831: ! 832: if (whitespace (c) == LINE_DONE) ! 833: { ! 834: if (ungetc (c, stdin) == EOF) ! 835: { ! 836: fprintf (stderr, "Couldn't unget character\n"); ! 837: errorexit (); ! 838: } ! 839: ! 840: token[count] = 0; ! 841: return TOKEN_AVAILABLE; ! 842: } ! 843: ! 844: if (whitespace (c) == WHITESPACE) ! 845: { ! 846: token[count] = 0; ! 847: return TOKEN_AVAILABLE; ! 848: } ! 849: ! 850: if (count >= MAX_TOKEN_LENGTH) ! 851: { ! 852: fprintf (stderr, "Error: token too long\n"); ! 853: errorexit (); ! 854: } ! 855: ! 856: token[count++] = c; ! 857: ! 858: if (c == '~') ! 859: { ! 860: count--; ! 861: token[count++] = 'n'; ! 862: token[count++] = 'o'; ! 863: token[count++] = 't'; ! 864: token[count++] = ' '; ! 865: } ! 866: else if (c == '(') ! 867: { ! 868: parencount = 1; ! 869: ! 870: do ! 871: { ! 872: if ((c = getchar ()) == EOF) ! 873: { ! 874: fprintf (stderr, "EOF in middle of parentheses\n"); ! 875: errorexit (); ! 876: } ! 877: ! 878: if (c == '(') ! 879: parencount++; ! 880: else if (c == ')') ! 881: parencount--; ! 882: ! 883: if (c == '~') ! 884: { ! 885: token[count++] = 'n'; ! 886: token[count++] = 'o'; ! 887: token[count++] = 't'; ! 888: token[count++] = ' '; ! 889: } ! 890: else ! 891: { ! 892: token[count++] = c; ! 893: } ! 894: ! 895: } while ((c != ')') || (parencount > 0)); ! 896: } ! 897: } ! 898: } ! 899: ! 900: ! 901: tokenstat parseline (void) ! 902: { ! 903: tokenstat stat; ! 904: int i, j, firsttoken, labelfound; ! 905: int mnemfound; ! 906: ! 907: firsttoken = 1; ! 908: tokennum = 0; ! 909: labelfound = 0; ! 910: ! 911: for ( ;; ) ! 912: { ! 913: token = tokens[tokennum]; ! 914: stat = gettoken (); ! 915: ! 916: switch (stat) ! 917: { ! 918: case FILE_DONE: ! 919: return FILE_DONE; ! 920: ! 921: case LINE_DONE: ! 922: if (!firsttoken && tokennum) ! 923: { ! 924: mnemfound = 0; ! 925: ! 926: for (i=0 ; i<numparse; i++) ! 927: { ! 928: if (!strcmpi (tokens[0], parsedata[i].text)) ! 929: { ! 930: if (((parsedata[i].numtokens > 0) && ! 931: (parsedata[i].numtokens != tokennum)) || ! 932: ((parsedata[i].numtokens < 0) && ! 933: (tokennum < -parsedata[i].numtokens))) ! 934: { ! 935: fprintf (stderr, "mismatched number of tokens\n"); ! 936: ! 937: for (j=0 ; j<tokennum ; j++) ! 938: fprintf (stderr, "%s\n", tokens[j]); ! 939: ! 940: fprintf (stderr, "\n"); ! 941: errorexit (); ! 942: } ! 943: ! 944: printf ("%s", parsedata[i].emit); ! 945: (*parsedata[i].parsefunc) (); ! 946: ! 947: mnemfound = 1; ! 948: break; ! 949: } ! 950: } ! 951: ! 952: if (!mnemfound) ! 953: { ! 954: fprintf (stderr, "Error: unknown mnemonic\n"); ! 955: ! 956: for (j=0 ; j<tokennum ; j++) ! 957: fprintf (stderr, "%s\n", tokens[j]); ! 958: ! 959: fprintf (stderr, "\n"); ! 960: errorexit (); ! 961: } ! 962: } ! 963: ! 964: if (!firsttoken) ! 965: { ! 966: if ((currentseg == DATASEG) && labelfound && !tokennum) ! 967: printf (":\n"); ! 968: else ! 969: printf ("\n"); ! 970: ! 971: outline++; ! 972: } ! 973: return PARSED_OKAY; ! 974: ! 975: case TOKEN_AVAILABLE: ! 976: if (firsttoken) ! 977: { ! 978: if (token[strlen(token) - 1] == ':') ! 979: { ! 980: labelfound = 1; ! 981: ! 982: if (currentseg == DATASEG) ! 983: { ! 984: token[strlen(token) - 1] = 0; ! 985: printf ("%s", token); ! 986: } ! 987: else if (currentseg == TEXTSEG) ! 988: { ! 989: printf ("%s", token); ! 990: } ! 991: else ! 992: { ! 993: fprintf (stderr, "Error: not in segment block\n"); ! 994: errorexit (); ! 995: } ! 996: ! 997: firsttoken = 0; ! 998: break; ! 999: } ! 1000: } ! 1001: ! 1002: firsttoken = 0; ! 1003: ! 1004: if (tokennum >= MAX_TOKENS) ! 1005: { ! 1006: fprintf (stderr, "Error: too many tokens\n"); ! 1007: exit (0); ! 1008: } ! 1009: ! 1010: tokennum++; ! 1011: ! 1012: break; ! 1013: ! 1014: default: ! 1015: fprintf (stderr, "Error: unknown tokenstat %d\n", stat); ! 1016: exit (0); ! 1017: } ! 1018: } ! 1019: } ! 1020: ! 1021: ! 1022: void main (int argc, char **argv) ! 1023: { ! 1024: tokenstat stat; ! 1025: ! 1026: printf (" .386P\n" ! 1027: " .model FLAT\n"); ! 1028: inline = 1; ! 1029: outline = 3; ! 1030: ! 1031: for ( ;; ) ! 1032: { ! 1033: stat = parseline (); ! 1034: inline++; ! 1035: ! 1036: switch (stat) ! 1037: { ! 1038: case FILE_DONE: ! 1039: if (currentseg == TEXTSEG) ! 1040: printf ("_TEXT ENDS\n"); ! 1041: else if (currentseg == DATASEG) ! 1042: printf ("_DATA ENDS\n"); ! 1043: ! 1044: printf (" END\n"); ! 1045: exit (0); ! 1046: ! 1047: case PARSED_OKAY: ! 1048: break; ! 1049: ! 1050: default: ! 1051: fprintf (stderr, "Error: unknown tokenstat %d\n", stat); ! 1052: exit (0); ! 1053: } ! 1054: } ! 1055: } ! 1056:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.