lex.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. #include <ctype.h>
  2. #define EXTERN
  3. #include "a.h"
  4. #include "y.tab.h"
  5. void
  6. main(int argc, char *argv[])
  7. {
  8. char *p;
  9. int nout, nproc, status, i, c;
  10. thechar = 'v';
  11. thestring = "mips";
  12. memset(debug, 0, sizeof(debug));
  13. cinit();
  14. outfile = 0;
  15. include[ninclude++] = ".";
  16. ARGBEGIN {
  17. default:
  18. c = ARGC();
  19. if(c >= 0 || c < sizeof(debug))
  20. debug[c] = 1;
  21. break;
  22. case 'o':
  23. outfile = ARGF();
  24. break;
  25. case 'D':
  26. p = ARGF();
  27. if(p)
  28. Dlist[nDlist++] = p;
  29. break;
  30. case 'I':
  31. p = ARGF();
  32. setinclude(p);
  33. break;
  34. } ARGEND
  35. if(*argv == 0) {
  36. print("usage: %ca [-options] file.s\n", thechar);
  37. errorexit();
  38. }
  39. if(argc > 1 && systemtype(Windows)){
  40. print("can't assemble multiple files on windows\n");
  41. errorexit();
  42. }
  43. if(argc > 1 && !systemtype(Windows)) {
  44. nproc = 1;
  45. if(p = getenv("NPROC"))
  46. nproc = atol(p); /* */
  47. c = 0;
  48. nout = 0;
  49. for(;;) {
  50. while(nout < nproc && argc > 0) {
  51. i = myfork();
  52. if(i < 0) {
  53. i = mywait(&status);
  54. if(i < 0)
  55. errorexit();
  56. if(status)
  57. c++;
  58. nout--;
  59. continue;
  60. }
  61. if(i == 0) {
  62. print("%s:\n", *argv);
  63. if(assemble(*argv))
  64. errorexit();
  65. exits(0);
  66. }
  67. nout++;
  68. argc--;
  69. argv++;
  70. }
  71. i = mywait(&status);
  72. if(i < 0) {
  73. if(c)
  74. errorexit();
  75. exits(0);
  76. }
  77. if(status)
  78. c++;
  79. nout--;
  80. }
  81. }
  82. if(assemble(argv[0]))
  83. errorexit();
  84. exits(0);
  85. }
  86. int
  87. assemble(char *file)
  88. {
  89. char ofile[100], incfile[20], *p;
  90. int i, of;
  91. strcpy(ofile, file);
  92. p = utfrrune(ofile, pathchar());
  93. if(p) {
  94. include[0] = ofile;
  95. *p++ = 0;
  96. } else
  97. p = ofile;
  98. if(outfile == 0) {
  99. outfile = p;
  100. if(outfile){
  101. p = utfrrune(outfile, '.');
  102. if(p)
  103. if(p[1] == 's' && p[2] == 0)
  104. p[0] = 0;
  105. p = utfrune(outfile, 0);
  106. p[0] = '.';
  107. p[1] = thechar;
  108. p[2] = 0;
  109. } else
  110. outfile = "/dev/null";
  111. }
  112. p = getenv("INCLUDE");
  113. if(p) {
  114. setinclude(p);
  115. } else {
  116. if(systemtype(Plan9)) {
  117. sprint(incfile,"/%s/include", thestring);
  118. setinclude(strdup(incfile));
  119. }
  120. }
  121. of = mycreat(outfile, 0664);
  122. if(of < 0) {
  123. yyerror("%ca: cannot create %s", thechar, outfile);
  124. errorexit();
  125. }
  126. Binit(&obuf, of, OWRITE);
  127. pass = 1;
  128. pinit(file);
  129. for(i=0; i<nDlist; i++)
  130. dodefine(Dlist[i]);
  131. yyparse();
  132. if(nerrors) {
  133. cclean();
  134. return nerrors;
  135. }
  136. pass = 2;
  137. outhist();
  138. pinit(file);
  139. for(i=0; i<nDlist; i++)
  140. dodefine(Dlist[i]);
  141. yyparse();
  142. cclean();
  143. return nerrors;
  144. }
  145. struct
  146. {
  147. char *name;
  148. ushort type;
  149. ushort value;
  150. } itab[] =
  151. {
  152. "SP", LSP, D_AUTO,
  153. "SB", LSB, D_EXTERN,
  154. "FP", LFP, D_PARAM,
  155. "PC", LPC, D_BRANCH,
  156. "HI", LHI, D_HI,
  157. "LO", LLO, D_LO,
  158. "R", LR, 0,
  159. "R0", LREG, 0,
  160. "R1", LREG, 1,
  161. "R2", LREG, 2,
  162. "R3", LREG, 3,
  163. "R4", LREG, 4,
  164. "R5", LREG, 5,
  165. "R6", LREG, 6,
  166. "R7", LREG, 7,
  167. "R8", LREG, 8,
  168. "R9", LREG, 9,
  169. "R10", LREG, 10,
  170. "R11", LREG, 11,
  171. "R12", LREG, 12,
  172. "R13", LREG, 13,
  173. "R14", LREG, 14,
  174. "R15", LREG, 15,
  175. "R16", LREG, 16,
  176. "R17", LREG, 17,
  177. "R18", LREG, 18,
  178. "R19", LREG, 19,
  179. "R20", LREG, 20,
  180. "R21", LREG, 21,
  181. "R22", LREG, 22,
  182. "R23", LREG, 23,
  183. "R24", LREG, 24,
  184. "R25", LREG, 25,
  185. "R26", LREG, 26,
  186. "R27", LREG, 27,
  187. "R28", LREG, 28,
  188. "R29", LREG, 29,
  189. "R30", LREG, 30,
  190. "R31", LREG, 31,
  191. "M", LM, 0,
  192. "M0", LMREG, 0,
  193. "M1", LMREG, 1,
  194. "M2", LMREG, 2,
  195. "M3", LMREG, 3,
  196. "M4", LMREG, 4,
  197. "M5", LMREG, 5,
  198. "M6", LMREG, 6,
  199. "M7", LMREG, 7,
  200. "M8", LMREG, 8,
  201. "M9", LMREG, 9,
  202. "M10", LMREG, 10,
  203. "M11", LMREG, 11,
  204. "M12", LMREG, 12,
  205. "M13", LMREG, 13,
  206. "M14", LMREG, 14,
  207. "M15", LMREG, 15,
  208. "M16", LMREG, 16,
  209. "M17", LMREG, 17,
  210. "M18", LMREG, 18,
  211. "M19", LMREG, 19,
  212. "M20", LMREG, 20,
  213. "M21", LMREG, 21,
  214. "M22", LMREG, 22,
  215. "M23", LMREG, 23,
  216. "M24", LMREG, 24,
  217. "M25", LMREG, 25,
  218. "M26", LMREG, 26,
  219. "M27", LMREG, 27,
  220. "M28", LMREG, 28,
  221. "M29", LMREG, 29,
  222. "M30", LMREG, 30,
  223. "M31", LMREG, 31,
  224. "F", LF, 0,
  225. "F0", LFREG, 0,
  226. "F1", LFREG, 1,
  227. "F2", LFREG, 2,
  228. "F3", LFREG, 3,
  229. "F4", LFREG, 4,
  230. "F5", LFREG, 5,
  231. "F6", LFREG, 6,
  232. "F7", LFREG, 7,
  233. "F8", LFREG, 8,
  234. "F9", LFREG, 9,
  235. "F10", LFREG, 10,
  236. "F11", LFREG, 11,
  237. "F12", LFREG, 12,
  238. "F13", LFREG, 13,
  239. "F14", LFREG, 14,
  240. "F15", LFREG, 15,
  241. "F16", LFREG, 16,
  242. "F17", LFREG, 17,
  243. "F18", LFREG, 18,
  244. "F19", LFREG, 19,
  245. "F20", LFREG, 20,
  246. "F21", LFREG, 21,
  247. "F22", LFREG, 22,
  248. "F23", LFREG, 23,
  249. "F24", LFREG, 24,
  250. "F25", LFREG, 25,
  251. "F26", LFREG, 26,
  252. "F27", LFREG, 27,
  253. "F28", LFREG, 28,
  254. "F29", LFREG, 29,
  255. "F30", LFREG, 30,
  256. "F31", LFREG, 31,
  257. "FCR", LFCR, 0,
  258. "FCR0", LFCREG, 0,
  259. "FCR1", LFCREG, 1,
  260. "FCR2", LFCREG, 2,
  261. "FCR3", LFCREG, 3,
  262. "FCR4", LFCREG, 4,
  263. "FCR5", LFCREG, 5,
  264. "FCR6", LFCREG, 6,
  265. "FCR7", LFCREG, 7,
  266. "FCR8", LFCREG, 8,
  267. "FCR9", LFCREG, 9,
  268. "FCR10", LFCREG, 10,
  269. "FCR11", LFCREG, 11,
  270. "FCR12", LFCREG, 12,
  271. "FCR13", LFCREG, 13,
  272. "FCR14", LFCREG, 14,
  273. "FCR15", LFCREG, 15,
  274. "FCR16", LFCREG, 16,
  275. "FCR17", LFCREG, 17,
  276. "FCR18", LFCREG, 18,
  277. "FCR19", LFCREG, 19,
  278. "FCR20", LFCREG, 20,
  279. "FCR21", LFCREG, 21,
  280. "FCR22", LFCREG, 22,
  281. "FCR23", LFCREG, 23,
  282. "FCR24", LFCREG, 24,
  283. "FCR25", LFCREG, 25,
  284. "FCR26", LFCREG, 26,
  285. "FCR27", LFCREG, 27,
  286. "FCR28", LFCREG, 28,
  287. "FCR29", LFCREG, 29,
  288. "FCR30", LFCREG, 30,
  289. "FCR31", LFCREG, 31,
  290. "ADD", LTYPE1, AADD,
  291. "ADDU", LTYPE1, AADDU,
  292. "SUB", LTYPE1, ASUB, /* converted to ADD(-) in loader */
  293. "SUBU", LTYPE1, ASUBU,
  294. "SGT", LTYPE1, ASGT,
  295. "SGTU", LTYPE1, ASGTU,
  296. "AND", LTYPE1, AAND,
  297. "OR", LTYPE1, AOR,
  298. "XOR", LTYPE1, AXOR,
  299. "SLL", LTYPE1, ASLL,
  300. "SRL", LTYPE1, ASRL,
  301. "SRA", LTYPE1, ASRA,
  302. "ADDV", LTYPE1, AADDV,
  303. "ADDVU", LTYPE1, AADDVU,
  304. "SUBV", LTYPE1, ASUBV, /* converted to ADD(-) in loader */
  305. "SUBVU", LTYPE1, ASUBVU,
  306. "SLLV", LTYPE1, ASLLV,
  307. "SRLV", LTYPE1, ASRLV,
  308. "SRAV", LTYPE1, ASRAV,
  309. "NOR", LTYPE2, ANOR,
  310. "MOVB", LTYPE3, AMOVB,
  311. "MOVBU", LTYPE3, AMOVBU,
  312. "MOVH", LTYPE3, AMOVH,
  313. "MOVHU", LTYPE3, AMOVHU,
  314. "MOVWL", LTYPE3, AMOVWL,
  315. "MOVWR", LTYPE3, AMOVWR,
  316. "MOVVL", LTYPE3, AMOVVL,
  317. "MOVVR", LTYPE3, AMOVVR,
  318. "BREAK", LTYPEJ, ABREAK, /* overloaded CACHE opcode */
  319. "END", LTYPE4, AEND,
  320. "REM", LTYPE6, AREM,
  321. "REMU", LTYPE6, AREMU,
  322. "RET", LTYPE4, ARET,
  323. "SYSCALL", LTYPE4, ASYSCALL,
  324. "TLBP", LTYPE4, ATLBP,
  325. "TLBR", LTYPE4, ATLBR,
  326. "TLBWI", LTYPE4, ATLBWI,
  327. "TLBWR", LTYPE4, ATLBWR,
  328. "MOVW", LTYPE5, AMOVW,
  329. "MOVV", LTYPE5, AMOVV,
  330. "MOVD", LTYPE5, AMOVD,
  331. "MOVF", LTYPE5, AMOVF,
  332. "DIV", LTYPE6, ADIV,
  333. "DIVU", LTYPE6, ADIVU,
  334. "MUL", LTYPE6, AMUL,
  335. "MULU", LTYPE6, AMULU,
  336. "DIVV", LTYPE6, ADIVV,
  337. "DIVVU", LTYPE6, ADIVVU,
  338. "MULV", LTYPE6, AMULV,
  339. "MULVU", LTYPE6, AMULVU,
  340. "RFE", LTYPE7, ARFE,
  341. "JMP", LTYPE7, AJMP,
  342. "JAL", LTYPE8, AJAL,
  343. "BEQ", LTYPE9, ABEQ,
  344. "BNE", LTYPE9, ABNE,
  345. "BGEZ", LTYPEA, ABGEZ,
  346. "BGEZAL", LTYPEA, ABGEZAL,
  347. "BGTZ", LTYPEA, ABGTZ,
  348. "BLEZ", LTYPEA, ABLEZ,
  349. "BLTZ", LTYPEA, ABLTZ,
  350. "BLTZAL", LTYPEA, ABLTZAL,
  351. "TEXT", LTYPEB, ATEXT,
  352. "GLOBL", LTYPEB, AGLOBL,
  353. "DATA", LTYPEC, ADATA,
  354. "MOVDF", LTYPE5, AMOVDF,
  355. "MOVDW", LTYPE5, AMOVDW,
  356. "MOVFD", LTYPE5, AMOVFD,
  357. "MOVFW", LTYPE5, AMOVFW,
  358. "MOVWD", LTYPE5, AMOVWD,
  359. "MOVWF", LTYPE5, AMOVWF,
  360. "ABSD", LTYPED, AABSD,
  361. "ABSF", LTYPED, AABSF,
  362. "ABSW", LTYPED, AABSW,
  363. "NEGD", LTYPED, ANEGD,
  364. "NEGF", LTYPED, ANEGF,
  365. "NEGW", LTYPED, ANEGW,
  366. "CMPEQD", LTYPEF, ACMPEQD,
  367. "CMPEQF", LTYPEF, ACMPEQF,
  368. "CMPGED", LTYPEF, ACMPGED,
  369. "CMPGEF", LTYPEF, ACMPGEF,
  370. "CMPGTD", LTYPEF, ACMPGTD,
  371. "CMPGTF", LTYPEF, ACMPGTF,
  372. "ADDD", LTYPEE, AADDD,
  373. "ADDF", LTYPEE, AADDF,
  374. "ADDW", LTYPEE, AADDW,
  375. "DIVD", LTYPEE, ADIVD,
  376. "DIVF", LTYPEE, ADIVF,
  377. "DIVW", LTYPEE, ADIVW,
  378. "MULD", LTYPEE, AMULD,
  379. "MULF", LTYPEE, AMULF,
  380. "MULW", LTYPEE, AMULW,
  381. "SUBD", LTYPEE, ASUBD,
  382. "SUBF", LTYPEE, ASUBF,
  383. "SUBW", LTYPEE, ASUBW,
  384. "BFPT", LTYPEG, ABFPT,
  385. "BFPF", LTYPEG, ABFPF,
  386. "WORD", LTYPEH, AWORD,
  387. "NOP", LTYPEI, ANOP,
  388. "SCHED", LSCHED, 0,
  389. "NOSCHED", LSCHED, 0x80,
  390. 0
  391. };
  392. void
  393. cinit(void)
  394. {
  395. Sym *s;
  396. int i;
  397. nullgen.sym = S;
  398. nullgen.offset = 0;
  399. nullgen.type = D_NONE;
  400. nullgen.name = D_NONE;
  401. nullgen.reg = NREG;
  402. if(FPCHIP)
  403. nullgen.dval = 0;
  404. for(i=0; i<sizeof(nullgen.sval); i++)
  405. nullgen.sval[i] = 0;
  406. nerrors = 0;
  407. iostack = I;
  408. iofree = I;
  409. peekc = IGN;
  410. nhunk = 0;
  411. for(i=0; i<NHASH; i++)
  412. hash[i] = S;
  413. for(i=0; itab[i].name; i++) {
  414. s = slookup(itab[i].name);
  415. s->type = itab[i].type;
  416. s->value = itab[i].value;
  417. }
  418. pathname = allocn(pathname, 0, 100);
  419. if(mygetwd(pathname, 99) == 0) {
  420. pathname = allocn(pathname, 100, 900);
  421. if(mygetwd(pathname, 999) == 0)
  422. strcpy(pathname, "/???");
  423. }
  424. }
  425. void
  426. syminit(Sym *s)
  427. {
  428. s->type = LNAME;
  429. s->value = 0;
  430. }
  431. int
  432. isreg(Gen *g)
  433. {
  434. USED(g);
  435. return 1;
  436. }
  437. void
  438. cclean(void)
  439. {
  440. outcode(AEND, &nullgen, NREG, &nullgen);
  441. Bflush(&obuf);
  442. }
  443. void
  444. zname(char *n, int t, int s)
  445. {
  446. Bputc(&obuf, ANAME);
  447. Bputc(&obuf, t); /* type */
  448. Bputc(&obuf, s); /* sym */
  449. while(*n) {
  450. Bputc(&obuf, *n);
  451. n++;
  452. }
  453. Bputc(&obuf, 0);
  454. }
  455. void
  456. zaddr(Gen *a, int s)
  457. {
  458. long l;
  459. int i;
  460. char *n;
  461. Ieee e;
  462. Bputc(&obuf, a->type);
  463. Bputc(&obuf, a->reg);
  464. Bputc(&obuf, s);
  465. Bputc(&obuf, a->name);
  466. switch(a->type) {
  467. default:
  468. print("unknown type %d\n", a->type);
  469. exits("arg");
  470. case D_NONE:
  471. case D_REG:
  472. case D_FREG:
  473. case D_MREG:
  474. case D_FCREG:
  475. case D_LO:
  476. case D_HI:
  477. break;
  478. case D_OREG:
  479. case D_CONST:
  480. case D_OCONST:
  481. case D_BRANCH:
  482. l = a->offset;
  483. Bputc(&obuf, l);
  484. Bputc(&obuf, l>>8);
  485. Bputc(&obuf, l>>16);
  486. Bputc(&obuf, l>>24);
  487. break;
  488. case D_SCONST:
  489. n = a->sval;
  490. for(i=0; i<NSNAME; i++) {
  491. Bputc(&obuf, *n);
  492. n++;
  493. }
  494. break;
  495. case D_FCONST:
  496. ieeedtod(&e, a->dval);
  497. Bputc(&obuf, e.l);
  498. Bputc(&obuf, e.l>>8);
  499. Bputc(&obuf, e.l>>16);
  500. Bputc(&obuf, e.l>>24);
  501. Bputc(&obuf, e.h);
  502. Bputc(&obuf, e.h>>8);
  503. Bputc(&obuf, e.h>>16);
  504. Bputc(&obuf, e.h>>24);
  505. break;
  506. }
  507. }
  508. void
  509. outcode(int a, Gen *g1, int reg, Gen *g2)
  510. {
  511. int sf, st, t;
  512. Sym *s;
  513. if(pass == 1)
  514. goto out;
  515. jackpot:
  516. sf = 0;
  517. s = g1->sym;
  518. while(s != S) {
  519. sf = s->sym;
  520. if(sf < 0 || sf >= NSYM)
  521. sf = 0;
  522. t = g1->name;
  523. if(h[sf].type == t)
  524. if(h[sf].sym == s)
  525. break;
  526. zname(s->name, t, sym);
  527. s->sym = sym;
  528. h[sym].sym = s;
  529. h[sym].type = t;
  530. sf = sym;
  531. sym++;
  532. if(sym >= NSYM)
  533. sym = 1;
  534. break;
  535. }
  536. st = 0;
  537. s = g2->sym;
  538. while(s != S) {
  539. st = s->sym;
  540. if(st < 0 || st >= NSYM)
  541. st = 0;
  542. t = g2->name;
  543. if(h[st].type == t)
  544. if(h[st].sym == s)
  545. break;
  546. zname(s->name, t, sym);
  547. s->sym = sym;
  548. h[sym].sym = s;
  549. h[sym].type = t;
  550. st = sym;
  551. sym++;
  552. if(sym >= NSYM)
  553. sym = 1;
  554. if(st == sf)
  555. goto jackpot;
  556. break;
  557. }
  558. Bputc(&obuf, a);
  559. Bputc(&obuf, reg|nosched);
  560. Bputc(&obuf, lineno);
  561. Bputc(&obuf, lineno>>8);
  562. Bputc(&obuf, lineno>>16);
  563. Bputc(&obuf, lineno>>24);
  564. zaddr(g1, sf);
  565. zaddr(g2, st);
  566. out:
  567. if(a != AGLOBL && a != ADATA)
  568. pc++;
  569. }
  570. void
  571. outhist(void)
  572. {
  573. Gen g;
  574. Hist *h;
  575. char *p, *q, *op, c;
  576. int n;
  577. g = nullgen;
  578. c = pathchar();
  579. for(h = hist; h != H; h = h->link) {
  580. p = h->name;
  581. op = 0;
  582. if(p && p[0] != c && h->offset == 0 && pathname){
  583. /* on windows skip drive specifier in pathname */
  584. if(systemtype(Windows) && pathname[2] == c) {
  585. op = p;
  586. p = pathname+2;
  587. *p = '/';
  588. } else if(pathname[0] == c){
  589. op = p;
  590. p = pathname;
  591. }
  592. }
  593. while(p) {
  594. q = strchr(p, c);
  595. if(q) {
  596. n = q-p;
  597. if(n == 0)
  598. n = 1; /* leading "/" */
  599. q++;
  600. } else {
  601. n = strlen(p);
  602. q = 0;
  603. }
  604. if(n) {
  605. Bputc(&obuf, ANAME);
  606. Bputc(&obuf, D_FILE); /* type */
  607. Bputc(&obuf, 1); /* sym */
  608. Bputc(&obuf, '<');
  609. Bwrite(&obuf, p, n);
  610. Bputc(&obuf, 0);
  611. }
  612. p = q;
  613. if(p == 0 && op) {
  614. p = op;
  615. op = 0;
  616. }
  617. }
  618. g.offset = h->offset;
  619. Bputc(&obuf, AHISTORY);
  620. Bputc(&obuf, 0);
  621. Bputc(&obuf, h->line);
  622. Bputc(&obuf, h->line>>8);
  623. Bputc(&obuf, h->line>>16);
  624. Bputc(&obuf, h->line>>24);
  625. zaddr(&nullgen, 0);
  626. zaddr(&g, 0);
  627. }
  628. }
  629. void
  630. praghjdicks(void)
  631. {
  632. while(getnsc() != '\n')
  633. ;
  634. }
  635. void
  636. pragvararg(void)
  637. {
  638. while(getnsc() != '\n')
  639. ;
  640. }
  641. void
  642. pragfpround(void)
  643. {
  644. while(getnsc() != '\n')
  645. ;
  646. }
  647. #include "../cc/lexbody"
  648. #include "../cc/macbody"
  649. #include "../cc/compat"