PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/quakeforge/trunk/tools/gas2masm/gas2masm.c

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