Annotation of quakeworld/gas2masm/gas2masm.c, revision 1.1

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: 

unix.superglobalmegacorp.com

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