Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 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 |
||
25 | #include |
||
26 | #include |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 | }>>=>(tokennum-1)>(tokennum-1)>=>=>=>=>=>=>> |
||
1056 |