lex.c 12 KB

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