lex.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #define EXTERN
  10. #include "a.h"
  11. #include "y.tab.h"
  12. #include <ctype.h>
  13. void
  14. main(int argc, char *argv[])
  15. {
  16. char *p;
  17. int nout, nproc, status, i, c;
  18. thechar = '5';
  19. thestring = "arm";
  20. memset(debug, 0, sizeof(debug));
  21. cinit();
  22. outfile = 0;
  23. include[ninclude++] = ".";
  24. ARGBEGIN {
  25. default:
  26. c = ARGC();
  27. if(c >= 0 || c < sizeof(debug))
  28. debug[c] = 1;
  29. break;
  30. case 'o':
  31. outfile = ARGF();
  32. break;
  33. case 'D':
  34. p = ARGF();
  35. if(p)
  36. Dlist[nDlist++] = p;
  37. break;
  38. case 'I':
  39. p = ARGF();
  40. setinclude(p);
  41. break;
  42. case 't':
  43. thechar = 't';
  44. thestring = "thumb";
  45. break;
  46. } ARGEND
  47. if(*argv == 0) {
  48. print("usage: %ca [-options] file.s\n", thechar);
  49. errorexit();
  50. }
  51. if(argc > 1 && systemtype(Windows)){
  52. print("can't assemble multiple files on windows\n");
  53. errorexit();
  54. }
  55. if(argc > 1 && !systemtype(Windows)) {
  56. nproc = 1;
  57. if(p = getenv("NPROC"))
  58. nproc = atol(p); /* */
  59. c = 0;
  60. nout = 0;
  61. for(;;) {
  62. while(nout < nproc && argc > 0) {
  63. i = myfork();
  64. if(i < 0) {
  65. i = mywait(&status);
  66. if(i < 0)
  67. errorexit();
  68. if(status)
  69. c++;
  70. nout--;
  71. continue;
  72. }
  73. if(i == 0) {
  74. print("%s:\n", *argv);
  75. if(assemble(*argv))
  76. errorexit();
  77. exits(0);
  78. }
  79. nout++;
  80. argc--;
  81. argv++;
  82. }
  83. i = mywait(&status);
  84. if(i < 0) {
  85. if(c)
  86. errorexit();
  87. exits(0);
  88. }
  89. if(status)
  90. c++;
  91. nout--;
  92. }
  93. }
  94. if(assemble(argv[0]))
  95. errorexit();
  96. exits(0);
  97. }
  98. int
  99. assemble(char *file)
  100. {
  101. char ofile[100], incfile[20], *p;
  102. int i, of;
  103. strcpy(ofile, file);
  104. p = utfrrune(ofile, pathchar());
  105. if(p) {
  106. include[0] = ofile;
  107. *p++ = 0;
  108. } else
  109. p = ofile;
  110. if(outfile == 0) {
  111. outfile = p;
  112. if(outfile){
  113. p = utfrrune(outfile, '.');
  114. if(p)
  115. if(p[1] == 's' && p[2] == 0)
  116. p[0] = 0;
  117. p = utfrune(outfile, 0);
  118. p[0] = '.';
  119. p[1] = thechar;
  120. p[2] = 0;
  121. } else
  122. outfile = "/dev/null";
  123. }
  124. p = getenv("INCLUDE");
  125. if(p) {
  126. setinclude(p);
  127. } else {
  128. if(systemtype(Plan9)) {
  129. sprint(incfile,"/%s/include", thestring);
  130. setinclude(strdup(incfile));
  131. }
  132. }
  133. of = mycreat(outfile, 0664);
  134. if(of < 0) {
  135. yyerror("%ca: cannot create %s", thechar, outfile);
  136. errorexit();
  137. }
  138. Binit(&obuf, of, OWRITE);
  139. pass = 1;
  140. pinit(file);
  141. for(i=0; i<nDlist; i++)
  142. dodefine(Dlist[i]);
  143. yyparse();
  144. if(nerrors) {
  145. cclean();
  146. return nerrors;
  147. }
  148. pass = 2;
  149. outhist();
  150. pinit(file);
  151. for(i=0; i<nDlist; i++)
  152. dodefine(Dlist[i]);
  153. yyparse();
  154. cclean();
  155. return nerrors;
  156. }
  157. struct
  158. {
  159. char *name;
  160. uint16_t type;
  161. uint16_t value;
  162. } itab[] =
  163. {
  164. "SP", LSP, D_AUTO,
  165. "SB", LSB, D_EXTERN,
  166. "FP", LFP, D_PARAM,
  167. "PC", LPC, D_BRANCH,
  168. "R", LR, 0,
  169. "R0", LREG, 0,
  170. "R1", LREG, 1,
  171. "R2", LREG, 2,
  172. "R3", LREG, 3,
  173. "R4", LREG, 4,
  174. "R5", LREG, 5,
  175. "R6", LREG, 6,
  176. "R7", LREG, 7,
  177. "R8", LREG, 8,
  178. "R9", LREG, 9,
  179. "R10", LREG, 10,
  180. "R11", LREG, 11,
  181. "R12", LREG, 12,
  182. "R13", LREG, 13,
  183. "R14", LREG, 14,
  184. "R15", LREG, 15,
  185. "F", LF, 0,
  186. "F0", LFREG, 0,
  187. "F1", LFREG, 1,
  188. "F2", LFREG, 2,
  189. "F3", LFREG, 3,
  190. "F4", LFREG, 4,
  191. "F5", LFREG, 5,
  192. "F6", LFREG, 6,
  193. "F7", LFREG, 7,
  194. "F8", LFREG, 8,
  195. "F9", LFREG, 9,
  196. "F10", LFREG, 10,
  197. "F11", LFREG, 11,
  198. "F12", LFREG, 12,
  199. "F13", LFREG, 13,
  200. "F14", LFREG, 14,
  201. "F15", LFREG, 15,
  202. "C", LC, 0,
  203. "C0", LCREG, 0,
  204. "C1", LCREG, 1,
  205. "C2", LCREG, 2,
  206. "C3", LCREG, 3,
  207. "C4", LCREG, 4,
  208. "C5", LCREG, 5,
  209. "C6", LCREG, 6,
  210. "C7", LCREG, 7,
  211. "C8", LCREG, 8,
  212. "C9", LCREG, 9,
  213. "C10", LCREG, 10,
  214. "C11", LCREG, 11,
  215. "C12", LCREG, 12,
  216. "C13", LCREG, 13,
  217. "C14", LCREG, 14,
  218. "C15", LCREG, 15,
  219. "CPSR", LPSR, 0,
  220. "SPSR", LPSR, 1,
  221. "FPSR", LFCR, 0,
  222. "FPCR", LFCR, 1,
  223. ".EQ", LCOND, 0,
  224. ".NE", LCOND, 1,
  225. ".CS", LCOND, 2,
  226. ".HS", LCOND, 2,
  227. ".CC", LCOND, 3,
  228. ".LO", LCOND, 3,
  229. ".MI", LCOND, 4,
  230. ".PL", LCOND, 5,
  231. ".VS", LCOND, 6,
  232. ".VC", LCOND, 7,
  233. ".HI", LCOND, 8,
  234. ".LS", LCOND, 9,
  235. ".GE", LCOND, 10,
  236. ".LT", LCOND, 11,
  237. ".GT", LCOND, 12,
  238. ".LE", LCOND, 13,
  239. ".AL", LCOND, Always,
  240. ".U", LS, C_UBIT,
  241. ".S", LS, C_SBIT,
  242. ".W", LS, C_WBIT,
  243. ".P", LS, C_PBIT,
  244. ".PW", LS, C_WBIT|C_PBIT,
  245. ".WP", LS, C_WBIT|C_PBIT,
  246. ".F", LS, C_FBIT,
  247. ".IBW", LS, C_WBIT|C_PBIT|C_UBIT,
  248. ".IAW", LS, C_WBIT|C_UBIT,
  249. ".DBW", LS, C_WBIT|C_PBIT,
  250. ".DAW", LS, C_WBIT,
  251. ".IB", LS, C_PBIT|C_UBIT,
  252. ".IA", LS, C_UBIT,
  253. ".DB", LS, C_PBIT,
  254. ".DA", LS, 0,
  255. "@", LAT, 0,
  256. "AND", LTYPE1, AAND,
  257. "EOR", LTYPE1, AEOR,
  258. "SUB", LTYPE1, ASUB,
  259. "RSB", LTYPE1, ARSB,
  260. "ADD", LTYPE1, AADD,
  261. "ADC", LTYPE1, AADC,
  262. "SBC", LTYPE1, ASBC,
  263. "RSC", LTYPE1, ARSC,
  264. "ORR", LTYPE1, AORR,
  265. "BIC", LTYPE1, ABIC,
  266. "SLL", LTYPE1, ASLL,
  267. "SRL", LTYPE1, ASRL,
  268. "SRA", LTYPE1, ASRA,
  269. "MUL", LTYPE1, AMUL,
  270. "MULA", LTYPEN, AMULA,
  271. "DIV", LTYPE1, ADIV,
  272. "MOD", LTYPE1, AMOD,
  273. "MULL", LTYPEM, AMULL,
  274. "MULAL", LTYPEM, AMULAL,
  275. "MULLU", LTYPEM, AMULLU,
  276. "MULALU", LTYPEM, AMULALU,
  277. "MVN", LTYPE2, AMVN, /* op2 ignored */
  278. "MOVB", LTYPE3, AMOVB,
  279. "MOVBU", LTYPE3, AMOVBU,
  280. "MOVH", LTYPE3, AMOVH,
  281. "MOVHU", LTYPE3, AMOVHU,
  282. "MOVW", LTYPE3, AMOVW,
  283. "MOVD", LTYPE3, AMOVD,
  284. "MOVDF", LTYPE3, AMOVDF,
  285. "MOVDW", LTYPE3, AMOVDW,
  286. "MOVF", LTYPE3, AMOVF,
  287. "MOVFD", LTYPE3, AMOVFD,
  288. "MOVFW", LTYPE3, AMOVFW,
  289. "MOVWD", LTYPE3, AMOVWD,
  290. "MOVWF", LTYPE3, AMOVWF,
  291. "LDREX", LTYPE3, ALDREX,
  292. "LDREXD", LTYPE3, ALDREXD,
  293. "STREX", LTYPE9, ASTREX,
  294. "STREXD", LTYPE9, ASTREXD,
  295. /*
  296. "ABSF", LTYPEI, AABSF,
  297. "ABSD", LTYPEI, AABSD,
  298. "NEGF", LTYPEI, ANEGF,
  299. "NEGD", LTYPEI, ANEGD,
  300. "SQTF", LTYPEI, ASQTF,
  301. "SQTD", LTYPEI, ASQTD,
  302. "RNDF", LTYPEI, ARNDF,
  303. "RNDD", LTYPEI, ARNDD,
  304. "URDF", LTYPEI, AURDF,
  305. "URDD", LTYPEI, AURDD,
  306. "NRMF", LTYPEI, ANRMF,
  307. "NRMD", LTYPEI, ANRMD,
  308. */
  309. "SQRTF", LTYPEI, ASQRTF,
  310. "SQRTD", LTYPEI, ASQRTD,
  311. "CMPF", LTYPEL, ACMPF,
  312. "CMPD", LTYPEL, ACMPD,
  313. "ADDF", LTYPEK, AADDF,
  314. "ADDD", LTYPEK, AADDD,
  315. "SUBF", LTYPEK, ASUBF,
  316. "SUBD", LTYPEK, ASUBD,
  317. "MULF", LTYPEK, AMULF,
  318. "MULD", LTYPEK, AMULD,
  319. "DIVF", LTYPEK, ADIVF,
  320. "DIVD", LTYPEK, ADIVD,
  321. "B", LTYPE4, AB,
  322. "BL", LTYPE4, ABL,
  323. "BX", LTYPEBX, ABX,
  324. "BEQ", LTYPE5, ABEQ,
  325. "BNE", LTYPE5, ABNE,
  326. "BCS", LTYPE5, ABCS,
  327. "BHS", LTYPE5, ABHS,
  328. "BCC", LTYPE5, ABCC,
  329. "BLO", LTYPE5, ABLO,
  330. "BMI", LTYPE5, ABMI,
  331. "BPL", LTYPE5, ABPL,
  332. "BVS", LTYPE5, ABVS,
  333. "BVC", LTYPE5, ABVC,
  334. "BHI", LTYPE5, ABHI,
  335. "BLS", LTYPE5, ABLS,
  336. "BGE", LTYPE5, ABGE,
  337. "BLT", LTYPE5, ABLT,
  338. "BGT", LTYPE5, ABGT,
  339. "BLE", LTYPE5, ABLE,
  340. "BCASE", LTYPE5, ABCASE,
  341. "SWI", LTYPE6, ASWI,
  342. "CMP", LTYPE7, ACMP,
  343. "TST", LTYPE7, ATST,
  344. "TEQ", LTYPE7, ATEQ,
  345. "CMN", LTYPE7, ACMN,
  346. "MOVM", LTYPE8, AMOVM,
  347. "SWPBU", LTYPE9, ASWPBU,
  348. "SWPW", LTYPE9, ASWPW,
  349. "RET", LTYPEA, ARET,
  350. "RFE", LTYPEA, ARFE,
  351. "TEXT", LTYPEB, ATEXT,
  352. "GLOBL", LTYPEB, AGLOBL,
  353. "DATA", LTYPEC, ADATA,
  354. "CASE", LTYPED, ACASE,
  355. "END", LTYPEE, AEND,
  356. "WORD", LTYPEH, AWORD,
  357. "NOP", LTYPEI, ANOP,
  358. "MCR", LTYPEJ, 0,
  359. "MRC", LTYPEJ, 1,
  360. 0
  361. };
  362. void
  363. cinit(void)
  364. {
  365. Sym *s;
  366. int i;
  367. nullgen.sym = S;
  368. nullgen.offset = 0;
  369. nullgen.type = D_NONE;
  370. nullgen.name = D_NONE;
  371. nullgen.reg = NREG;
  372. if(FPCHIP)
  373. nullgen.dval = 0;
  374. for(i=0; i<sizeof(nullgen.sval); i++)
  375. nullgen.sval[i] = 0;
  376. nerrors = 0;
  377. iostack = I;
  378. iofree = I;
  379. peekc = IGN;
  380. nhunk = 0;
  381. for(i=0; i<NHASH; i++)
  382. hash[i] = S;
  383. for(i=0; itab[i].name; i++) {
  384. s = slookup(itab[i].name);
  385. s->type = itab[i].type;
  386. s->value = itab[i].value;
  387. }
  388. pathname = allocn(pathname, 0, 100);
  389. if(getwd(pathname, 99) == 0) {
  390. pathname = allocn(pathname, 100, 900);
  391. if(getwd(pathname, 999) == 0)
  392. strcpy(pathname, "/???");
  393. }
  394. }
  395. void
  396. syminit(Sym *s)
  397. {
  398. s->type = LNAME;
  399. s->value = 0;
  400. }
  401. int
  402. isreg(Gen *g)
  403. {
  404. USED(g);
  405. return 1;
  406. }
  407. void
  408. cclean(void)
  409. {
  410. outcode(AEND, Always, &nullgen, NREG, &nullgen);
  411. Bflush(&obuf);
  412. }
  413. void
  414. zname(char *n, int t, int s)
  415. {
  416. Bputc(&obuf, ANAME);
  417. Bputc(&obuf, t); /* type */
  418. Bputc(&obuf, s); /* sym */
  419. while(*n) {
  420. Bputc(&obuf, *n);
  421. n++;
  422. }
  423. Bputc(&obuf, 0);
  424. }
  425. void
  426. zaddr(Gen *a, int s)
  427. {
  428. int32_t l;
  429. int i;
  430. char *n;
  431. Ieee e;
  432. Bputc(&obuf, a->type);
  433. Bputc(&obuf, a->reg);
  434. Bputc(&obuf, s);
  435. Bputc(&obuf, a->name);
  436. switch(a->type) {
  437. default:
  438. print("unknown type %d\n", a->type);
  439. exits("arg");
  440. case D_NONE:
  441. case D_REG:
  442. case D_FREG:
  443. case D_PSR:
  444. case D_FPCR:
  445. break;
  446. case D_REGREG:
  447. Bputc(&obuf, a->offset);
  448. break;
  449. case D_OREG:
  450. case D_CONST:
  451. case D_BRANCH:
  452. case D_SHIFT:
  453. l = a->offset;
  454. Bputc(&obuf, l);
  455. Bputc(&obuf, l>>8);
  456. Bputc(&obuf, l>>16);
  457. Bputc(&obuf, l>>24);
  458. break;
  459. case D_SCONST:
  460. n = a->sval;
  461. for(i=0; i<NSNAME; i++) {
  462. Bputc(&obuf, *n);
  463. n++;
  464. }
  465. break;
  466. case D_FCONST:
  467. ieeedtod(&e, a->dval);
  468. Bputc(&obuf, e.l);
  469. Bputc(&obuf, e.l>>8);
  470. Bputc(&obuf, e.l>>16);
  471. Bputc(&obuf, e.l>>24);
  472. Bputc(&obuf, e.h);
  473. Bputc(&obuf, e.h>>8);
  474. Bputc(&obuf, e.h>>16);
  475. Bputc(&obuf, e.h>>24);
  476. break;
  477. }
  478. }
  479. static int bcode[] =
  480. {
  481. ABEQ,
  482. ABNE,
  483. ABCS,
  484. ABCC,
  485. ABMI,
  486. ABPL,
  487. ABVS,
  488. ABVC,
  489. ABHI,
  490. ABLS,
  491. ABGE,
  492. ABLT,
  493. ABGT,
  494. ABLE,
  495. AB,
  496. ANOP,
  497. };
  498. void
  499. outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
  500. {
  501. int sf, st, t;
  502. Sym *s;
  503. /* hack to make B.NE etc. work: turn it into the corresponding conditional */
  504. if(a == AB){
  505. a = bcode[scond&0xf];
  506. scond = (scond & ~0xf) | Always;
  507. }
  508. if(pass == 1)
  509. goto out;
  510. jackpot:
  511. sf = 0;
  512. s = g1->sym;
  513. while(s != S) {
  514. sf = s->sym;
  515. if(sf < 0 || sf >= NSYM)
  516. sf = 0;
  517. t = g1->name;
  518. if(h[sf].type == t)
  519. if(h[sf].sym == s)
  520. break;
  521. zname(s->name, t, sym);
  522. s->sym = sym;
  523. h[sym].sym = s;
  524. h[sym].type = t;
  525. sf = sym;
  526. sym++;
  527. if(sym >= NSYM)
  528. sym = 1;
  529. break;
  530. }
  531. st = 0;
  532. s = g2->sym;
  533. while(s != S) {
  534. st = s->sym;
  535. if(st < 0 || st >= NSYM)
  536. st = 0;
  537. t = g2->name;
  538. if(h[st].type == t)
  539. if(h[st].sym == s)
  540. break;
  541. zname(s->name, t, sym);
  542. s->sym = sym;
  543. h[sym].sym = s;
  544. h[sym].type = t;
  545. st = sym;
  546. sym++;
  547. if(sym >= NSYM)
  548. sym = 1;
  549. if(st == sf)
  550. goto jackpot;
  551. break;
  552. }
  553. Bputc(&obuf, a);
  554. Bputc(&obuf, scond);
  555. Bputc(&obuf, reg);
  556. Bputc(&obuf, lineno);
  557. Bputc(&obuf, lineno>>8);
  558. Bputc(&obuf, lineno>>16);
  559. Bputc(&obuf, lineno>>24);
  560. zaddr(g1, sf);
  561. zaddr(g2, st);
  562. out:
  563. if(a != AGLOBL && a != ADATA)
  564. pc++;
  565. }
  566. void
  567. outhist(void)
  568. {
  569. Gen g;
  570. Hist *h;
  571. char *p, *q, *op, c;
  572. int n;
  573. g = nullgen;
  574. c = pathchar();
  575. for(h = hist; h != H; h = h->link) {
  576. p = h->name;
  577. op = 0;
  578. /* on windows skip drive specifier in pathname */
  579. if(systemtype(Windows) && p && p[1] == ':'){
  580. p += 2;
  581. c = *p;
  582. }
  583. if(p && p[0] != c && h->offset == 0 && pathname){
  584. /* on windows skip drive specifier in pathname */
  585. if(systemtype(Windows) && pathname[1] == ':') {
  586. op = p;
  587. p = pathname+2;
  588. c = *p;
  589. } else if(pathname[0] == c){
  590. op = p;
  591. p = pathname;
  592. }
  593. }
  594. while(p) {
  595. q = strchr(p, c);
  596. if(q) {
  597. n = q-p;
  598. if(n == 0){
  599. n = 1; /* leading "/" */
  600. *p = '/'; /* don't emit "\" on windows */
  601. }
  602. q++;
  603. } else {
  604. n = strlen(p);
  605. q = 0;
  606. }
  607. if(n) {
  608. Bputc(&obuf, ANAME);
  609. Bputc(&obuf, D_FILE); /* type */
  610. Bputc(&obuf, 1); /* sym */
  611. Bputc(&obuf, '<');
  612. Bwrite(&obuf, p, n);
  613. Bputc(&obuf, 0);
  614. }
  615. p = q;
  616. if(p == 0 && op) {
  617. p = op;
  618. op = 0;
  619. }
  620. }
  621. g.offset = h->offset;
  622. Bputc(&obuf, AHISTORY);
  623. Bputc(&obuf, Always);
  624. Bputc(&obuf, 0);
  625. Bputc(&obuf, h->line);
  626. Bputc(&obuf, h->line>>8);
  627. Bputc(&obuf, h->line>>16);
  628. Bputc(&obuf, h->line>>24);
  629. zaddr(&nullgen, 0);
  630. zaddr(&g, 0);
  631. }
  632. }
  633. #include "../cc/lexbody"
  634. #include "../cc/macbody"
  635. #include "../cc/compat"