lex.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ctype.h>
  4. #include <bio.h>
  5. #include "../9c/9.out.h"
  6. #include "a.h"
  7. #include "y.tab.h"
  8. void
  9. main(int argc, char *argv[])
  10. {
  11. char *p;
  12. int nout, nproc, status, i, c;
  13. thechar = '9';
  14. thestring = "29000";
  15. memset(debug, 0, sizeof(debug));
  16. cinit();
  17. outfile = 0;
  18. include[ninclude++] = ".";
  19. ARGBEGIN {
  20. default:
  21. c = ARGC();
  22. if(c >= 0 || c < sizeof(debug))
  23. debug[c] = 1;
  24. break;
  25. case 'o':
  26. outfile = ARGF();
  27. break;
  28. case 'D':
  29. p = ARGF();
  30. if(p)
  31. Dlist[nDlist++] = p;
  32. break;
  33. case 'I':
  34. p = ARGF();
  35. setinclude(p);
  36. break;
  37. } ARGEND
  38. if(*argv == 0) {
  39. print("usage: %ca [-options] file.s\n", thechar);
  40. errorexit();
  41. }
  42. if(argc > 1 && systemtype(Windows)){
  43. print("can't assemble multiple files on windows\n");
  44. errorexit();
  45. }
  46. if(argc > 1 && !systemtype(Windows)) {
  47. nproc = 1;
  48. if(p = getenv("NPROC"))
  49. nproc = atol(p); /* */
  50. c = 0;
  51. nout = 0;
  52. for(;;) {
  53. while(nout < nproc && argc > 0) {
  54. i = myfork();
  55. if(i < 0) {
  56. i = mywait(&status);
  57. if(i < 0)
  58. errorexit();
  59. if(status)
  60. c++;
  61. nout--;
  62. continue;
  63. }
  64. if(i == 0) {
  65. print("%s:\n", *argv);
  66. if(assemble(*argv))
  67. errorexit();
  68. exits(0);
  69. }
  70. nout++;
  71. argc--;
  72. argv++;
  73. }
  74. i = mywait(&status);
  75. if(i < 0) {
  76. if(c)
  77. errorexit();
  78. exits(0);
  79. }
  80. if(status)
  81. c++;
  82. nout--;
  83. }
  84. }
  85. if(assemble(argv[0]))
  86. errorexit();
  87. exits(0);
  88. }
  89. int
  90. assemble(char *file)
  91. {
  92. char ofile[100], incfile[20], *p;
  93. int i, of;
  94. strcpy(ofile, file);
  95. p = utfrrune(ofile, pathchar());
  96. if(p) {
  97. include[0] = ofile;
  98. *p++ = 0;
  99. } else
  100. p = ofile;
  101. if(outfile == 0) {
  102. outfile = p;
  103. if(outfile){
  104. p = utfrrune(outfile, '.');
  105. if(p)
  106. if(p[1] == 's' && p[2] == 0)
  107. p[0] = 0;
  108. p = utfrune(outfile, 0);
  109. p[0] = '.';
  110. p[1] = thechar;
  111. p[2] = 0;
  112. } else
  113. outfile = "/dev/null";
  114. }
  115. p = getenv("INCLUDE");
  116. if(p) {
  117. setinclude(p);
  118. } else {
  119. if(systemtype(Plan9)) {
  120. sprint(incfile,"/%s/include", thestring);
  121. setinclude(strdup(incfile));
  122. }
  123. }
  124. of = mycreat(outfile, 0664);
  125. if(of < 0) {
  126. yyerror("%ca: cannot create %s", thechar, outfile);
  127. errorexit();
  128. }
  129. Binit(&obuf, of, OWRITE);
  130. pass = 1;
  131. pinit(file);
  132. for(i=0; i<nDlist; i++)
  133. dodefine(Dlist[i]);
  134. yyparse();
  135. if(nerrors) {
  136. cclean();
  137. return nerrors;
  138. }
  139. pass = 2;
  140. outhist();
  141. pinit(file);
  142. for(i=0; i<nDlist; i++)
  143. dodefine(Dlist[i]);
  144. yyparse();
  145. cclean();
  146. return nerrors;
  147. }
  148. struct
  149. {
  150. char *name;
  151. ushort type;
  152. ushort value;
  153. } itab[] =
  154. {
  155. "SP", LSP, D_AUTO,
  156. "SB", LSB, D_EXTERN,
  157. "FP", LFP, D_PARAM,
  158. "PC", LPC, D_BRANCH,
  159. "R", LR, 0,
  160. "R0", LREG, 0,
  161. "R1", LREG, 1,
  162. "R131", LREG, 131,
  163. "QREG", LREG, 131,
  164. "ADDL", LTYPE1, AADDL,
  165. "ADDUL", LTYPE1, AADDUL,
  166. "ADDSL", LTYPE1, AADDSL,
  167. "ADDCL", LTYPE1, AADDCL,
  168. "ADDCUL", LTYPE1, AADDCUL,
  169. "ADDCSL", LTYPE1, AADDCSL,
  170. "SUBL", LTYPE1, ASUBL,
  171. "SUBUL", LTYPE1, ASUBUL,
  172. "SUBSL", LTYPE1, ASUBSL,
  173. "SUBCL", LTYPE1, ASUBCL,
  174. "SUBCUL", LTYPE1, ASUBCUL,
  175. "SUBCSL", LTYPE1, ASUBCSL,
  176. "ISUBL", LTYPE1, AISUBL,
  177. "ISUBUL", LTYPE1, AISUBUL,
  178. "ISUBSL", LTYPE1, AISUBSL,
  179. "ISUBCL", LTYPE1, AISUBCL,
  180. "ISUBCUL", LTYPE1, AISUBCUL,
  181. "ISUBCSL", LTYPE1, AISUBCSL,
  182. "ANDL", LTYPE1, AANDL,
  183. "ANDNL", LTYPE1, AANDNL,
  184. "NANDL", LTYPE1, ANANDL,
  185. "NORL", LTYPE1, ANORL,
  186. "ORL", LTYPE1, AORL,
  187. "XNORL", LTYPE1, AXNORL,
  188. "XORL", LTYPE1, AXORL,
  189. "SRAL", LTYPE1, ASRAL,
  190. "SRLL", LTYPE1, ASRLL,
  191. "SLLL", LTYPE1, ASLLL,
  192. "ASEQ", LTYPE1, AASEQ,
  193. "ASGE", LTYPE1, AASGE,
  194. "ASGEU", LTYPE1, AASGEU,
  195. "ASGT", LTYPE1, AASGT,
  196. "ASGTU", LTYPE1, AASGTU,
  197. "ASLE", LTYPE1, AASLE,
  198. "ASLEU", LTYPE1, AASLEU,
  199. "ASLT", LTYPE1, AASLT,
  200. "ASLTU", LTYPE1, AASLTU,
  201. "ASNEQ", LTYPE1, AASNEQ,
  202. "CPEQL", LTYPE1, ACPEQL,
  203. "CPGEL", LTYPE1, ACPGEL,
  204. "CPGEUL", LTYPE1, ACPGEUL,
  205. "CPGTL", LTYPE1, ACPGTL,
  206. "CPGTUL", LTYPE1, ACPGTUL,
  207. "CPLEL", LTYPE1, ACPLEL,
  208. "CPLEUL", LTYPE1, ACPLEUL,
  209. "CPLTL", LTYPE1, ACPLTL,
  210. "CPLTUL", LTYPE1, ACPLTUL,
  211. "CPNEQL", LTYPE1, ACPNEQL,
  212. "LOCKL", LTYPE1, ALOCKL,
  213. "LOCKH", LTYPE1, ALOCKH,
  214. "LOCKHU", LTYPE1, ALOCKHU,
  215. "LOCKB", LTYPE1, ALOCKB,
  216. "LOCKBU", LTYPE1, ALOCKBU,
  217. "MOVL", LTYPE3, AMOVL,
  218. "MOVH", LTYPE3, AMOVH,
  219. "MOVHU", LTYPE3, AMOVHU,
  220. "MOVB", LTYPE3, AMOVB,
  221. "MOVBU", LTYPE3, AMOVBU,
  222. "MOVF", LTYPE3, AMOVF,
  223. "MOVD", LTYPE3, AMOVD,
  224. "MOVFL", LTYPE4, AMOVFL,
  225. "MOVDL", LTYPE4, AMOVDL,
  226. "MOVLF", LTYPE4, AMOVLF,
  227. "MOVLD", LTYPE4, AMOVLD,
  228. "MOVFD", LTYPE4, AMOVFD,
  229. "MOVDF", LTYPE4, AMOVDF,
  230. "MTSR", LTYPE9, AMTSR,
  231. "MFSR", LTYPE10, AMFSR,
  232. "CALL", LTYPE5, ACALL,
  233. "RET", LTYPEG, ARET,
  234. "END", LTYPEG, AEND,
  235. "JMP", LTYPE5, AJMP,
  236. "JMPF", LTYPE5, AJMPF,
  237. "JMPFDEC", LTYPE5, AJMPFDEC,
  238. "JMPT", LTYPE5, AJMPT,
  239. "DSTEPL", LTYPE1, ADSTEPL,
  240. "DSTEP0L", LTYPE1, ADSTEP0L,
  241. "DSTEPLL", LTYPE1, ADSTEPLL,
  242. "DSTEPRL", LTYPE1, ADSTEPRL,
  243. "DIVL", LTYPE1, ADIVL,
  244. "DIVUL", LTYPE1, ADIVUL,
  245. "MSTEPL", LTYPE1, AMSTEPL,
  246. "MSTEPUL", LTYPE1, AMSTEPUL,
  247. "MSTEPLL", LTYPE1, AMSTEPLL,
  248. "MULL", LTYPE1, AMULL,
  249. "MULUL", LTYPE1, AMULUL,
  250. "MULML", LTYPE1, AMULML,
  251. "MULMUL", LTYPE1, AMULMUL,
  252. "ADDD", LTYPE1, AADDD,
  253. "SUBD", LTYPE1, ASUBD,
  254. "DIVD", LTYPE1, ADIVD,
  255. "MULD", LTYPE1, AMULD,
  256. "SQRTD", LTYPE1, ASQRTD,
  257. "EQD", LTYPE1, AEQD,
  258. "GED", LTYPE1, AGED,
  259. "GTD", LTYPE1, AGTD,
  260. "ADDF", LTYPE1, AADDF,
  261. "SUBF", LTYPE1, ASUBF,
  262. "DIVF", LTYPE1, ADIVF,
  263. "MULF", LTYPE1, AMULF,
  264. "SQRTF", LTYPE1, ASQRTF,
  265. "EQF", LTYPE1, AEQF,
  266. "GEF", LTYPE1, AGEF,
  267. "GTF", LTYPE1, AGTF,
  268. "CLZ", LTYPE1, ACLZ,
  269. "CPBYTE", LTYPE1, ACPBYTE,
  270. "CLASS", LTYPE1, ACLASS,
  271. "EMULATE", LTYPEA, AEMULATE,
  272. "EXBYTE", LTYPE1, AEXBYTE,
  273. "EXHW", LTYPE1, AEXHW,
  274. "EXHWS", LTYPE1, AEXHWS,
  275. "EXTRACT", LTYPE1, AEXTRACT,
  276. "HALT", LTYPE1, AHALT,
  277. "INBYTE", LTYPE1, AINBYTE,
  278. "INHW", LTYPE1, AINHW,
  279. "IRETINV", LTYPE8, AIRETINV,
  280. "INV", LTYPE8, AINV,
  281. "IRET", LTYPEG, AIRET,
  282. "LOADM", LTYPE6, ALOADM,
  283. "LOADSET", LTYPE6, ALOADSET,
  284. "SETIP", LTYPE1, ASETIP,
  285. "STOREM", LTYPE7, ASTOREM,
  286. "TEXT", LTYPEB, ATEXT,
  287. "GLOBL", LTYPEB, AGLOBL,
  288. "DATA", LTYPEC, ADATA,
  289. "WORD", LTYPEH, AWORD,
  290. "NOP", LTYPEI, ANOP,
  291. "DELAY", LTYPEI, ADELAY,
  292. "SCHED", LSCHED, 0,
  293. "NOSCHED", LSCHED, 1,
  294. 0
  295. };
  296. void
  297. cinit(void)
  298. {
  299. Sym *s;
  300. char buf[32];
  301. int i;
  302. nullgen.sym = S;
  303. nullgen.offset = 0;
  304. nullgen.type = D_NONE;
  305. nullgen.name = D_NONE;
  306. nullgen.reg = NREG;
  307. if(FPCHIP)
  308. nullgen.dval = 0;
  309. for(i=0; i<sizeof(nullgen.sval); i++)
  310. nullgen.sval[i] = 0;
  311. nerrors = 0;
  312. iostack = I;
  313. iofree = I;
  314. peekc = IGN;
  315. nhunk = 0;
  316. for(i=0; i<NHASH; i++)
  317. hash[i] = S;
  318. for(i=0; itab[i].name; i++) {
  319. s = slookup(itab[i].name);
  320. s->type = itab[i].type;
  321. s->value = itab[i].value;
  322. }
  323. for(i = 64; i < 256; i++){
  324. sprint(buf, "R%d", i);
  325. s = slookup(buf);
  326. s->type = LREG;
  327. s->value = i;
  328. }
  329. ALLOCN(pathname, 0, 100);
  330. if(getwd(pathname, 99) == 0) {
  331. ALLOCN(pathname, 100, 900);
  332. if(getwd(pathname, 999) == 0)
  333. strcpy(pathname, "/???");
  334. }
  335. }
  336. void
  337. syminit(Sym *s)
  338. {
  339. s->type = LNAME;
  340. s->value = 0;
  341. }
  342. int
  343. isreg(Gen *g)
  344. {
  345. USED(g);
  346. return 1;
  347. }
  348. void
  349. cclean(void)
  350. {
  351. outcode(AEND, &nullgen, NREG, &nullgen);
  352. Bflush(&obuf);
  353. }
  354. void
  355. zname(char *n, int t, int s)
  356. {
  357. Bputc(&obuf, ANAME);
  358. Bputc(&obuf, t); /* type */
  359. Bputc(&obuf, s); /* sym */
  360. while(*n) {
  361. Bputc(&obuf, *n);
  362. n++;
  363. }
  364. Bputc(&obuf, 0);
  365. }
  366. void
  367. zaddr(Gen *a, int s)
  368. {
  369. long l;
  370. int i;
  371. char *n;
  372. Ieee e;
  373. Bputc(&obuf, a->type);
  374. Bputc(&obuf, a->reg);
  375. Bputc(&obuf, s);
  376. Bputc(&obuf, a->name);
  377. switch(a->type) {
  378. default:
  379. print("unknown type %d\n", a->type);
  380. exits("arg");
  381. case D_NONE:
  382. case D_REG:
  383. break;
  384. case D_OREG:
  385. case D_CONST:
  386. case D_OCONST:
  387. case D_BRANCH:
  388. l = a->offset;
  389. Bputc(&obuf, l);
  390. Bputc(&obuf, l>>8);
  391. Bputc(&obuf, l>>16);
  392. Bputc(&obuf, l>>24);
  393. break;
  394. case D_SCONST:
  395. n = a->sval;
  396. for(i=0; i<NSNAME; i++) {
  397. Bputc(&obuf, *n);
  398. n++;
  399. }
  400. break;
  401. case D_FCONST:
  402. ieeedtod(&e, a->dval);
  403. Bputc(&obuf, e.l);
  404. Bputc(&obuf, e.l>>8);
  405. Bputc(&obuf, e.l>>16);
  406. Bputc(&obuf, e.l>>24);
  407. Bputc(&obuf, e.h);
  408. Bputc(&obuf, e.h>>8);
  409. Bputc(&obuf, e.h>>16);
  410. Bputc(&obuf, e.h>>24);
  411. break;
  412. }
  413. }
  414. void
  415. outcode(int a, Gen *g1, int reg, Gen *g2)
  416. {
  417. int sf, st, t;
  418. Sym *s;
  419. if(pass == 1)
  420. goto out;
  421. jackpot:
  422. sf = 0;
  423. s = g1->sym;
  424. while(s != S) {
  425. sf = s->sym;
  426. if(sf < 0 || sf >= NSYM)
  427. sf = 0;
  428. t = g1->name;
  429. if(h[sf].type == t)
  430. if(h[sf].sym == s)
  431. break;
  432. zname(s->name, t, sym);
  433. s->sym = sym;
  434. h[sym].sym = s;
  435. h[sym].type = t;
  436. sf = sym;
  437. sym++;
  438. if(sym >= NSYM)
  439. sym = 1;
  440. break;
  441. }
  442. st = 0;
  443. s = g2->sym;
  444. while(s != S) {
  445. st = s->sym;
  446. if(st < 0 || st >= NSYM)
  447. st = 0;
  448. t = g2->name;
  449. if(h[st].type == t)
  450. if(h[st].sym == s)
  451. break;
  452. zname(s->name, t, sym);
  453. s->sym = sym;
  454. h[sym].sym = s;
  455. h[sym].type = t;
  456. st = sym;
  457. sym++;
  458. if(sym >= NSYM)
  459. sym = 1;
  460. if(st == sf)
  461. goto jackpot;
  462. break;
  463. }
  464. Bputc(&obuf, a);
  465. Bputc(&obuf, reg|nosched);
  466. Bputc(&obuf, lineno);
  467. Bputc(&obuf, lineno>>8);
  468. Bputc(&obuf, lineno>>16);
  469. Bputc(&obuf, lineno>>24);
  470. zaddr(g1, sf);
  471. zaddr(g2, st);
  472. out:
  473. if(a != AGLOBL && a != ADATA && a != ANOSCHED)
  474. pc++;
  475. }
  476. void
  477. outhist(void)
  478. {
  479. Gen g;
  480. Hist *h;
  481. char *p, *q, *op;
  482. int n;
  483. g = nullgen;
  484. for(h = hist; h != H; h = h->link) {
  485. p = h->name;
  486. op = 0;
  487. if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
  488. op = p;
  489. p = pathname;
  490. }
  491. while(p) {
  492. q = strchr(p, '/');
  493. if(q) {
  494. n = q-p;
  495. if(n == 0)
  496. n = 1; /* leading "/" */
  497. q++;
  498. } else {
  499. n = strlen(p);
  500. q = 0;
  501. }
  502. if(n) {
  503. Bputc(&obuf, ANAME);
  504. Bputc(&obuf, D_FILE); /* type */
  505. Bputc(&obuf, 1); /* sym */
  506. Bputc(&obuf, '<');
  507. Bwrite(&obuf, p, n);
  508. Bputc(&obuf, 0);
  509. }
  510. p = q;
  511. if(p == 0 && op) {
  512. p = op;
  513. op = 0;
  514. }
  515. }
  516. g.offset = h->offset;
  517. Bputc(&obuf, AHISTORY);
  518. Bputc(&obuf, 0);
  519. Bputc(&obuf, h->line);
  520. Bputc(&obuf, h->line>>8);
  521. Bputc(&obuf, h->line>>16);
  522. Bputc(&obuf, h->line>>24);
  523. zaddr(&nullgen, 0);
  524. zaddr(&g, 0);
  525. }
  526. }
  527. void
  528. praghjdicks(void)
  529. {
  530. while(getnsc() != '\n')
  531. ;
  532. }
  533. void
  534. pragvararg(void)
  535. {
  536. while(getnsc() != '\n')
  537. ;
  538. }
  539. void
  540. pragfpround(void)
  541. {
  542. while(getnsc() != '\n')
  543. ;
  544. }
  545. #include "../cc/lexbody"
  546. #include "../cc/macbody"
  547. #include "../cc/compat"