lex.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  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 = '5';
  11. thestring = "arm";
  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 't':
  35. thechar = 't';
  36. thestring = "thumb";
  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. "R", LR, 0,
  161. "R0", LREG, 0,
  162. "R1", LREG, 1,
  163. "R2", LREG, 2,
  164. "R3", LREG, 3,
  165. "R4", LREG, 4,
  166. "R5", LREG, 5,
  167. "R6", LREG, 6,
  168. "R7", LREG, 7,
  169. "R8", LREG, 8,
  170. "R9", LREG, 9,
  171. "R10", LREG, 10,
  172. "R11", LREG, 11,
  173. "R12", LREG, 12,
  174. "R13", LREG, 13,
  175. "R14", LREG, 14,
  176. "R15", LREG, 15,
  177. "F", LF, 0,
  178. "F0", LFREG, 0,
  179. "F1", LFREG, 1,
  180. "F2", LFREG, 2,
  181. "F3", LFREG, 3,
  182. "F4", LFREG, 4,
  183. "F5", LFREG, 5,
  184. "F6", LFREG, 6,
  185. "F7", LFREG, 7,
  186. "F8", LFREG, 8,
  187. "F9", LFREG, 9,
  188. "F10", LFREG, 10,
  189. "F11", LFREG, 11,
  190. "F12", LFREG, 12,
  191. "F13", LFREG, 13,
  192. "F14", LFREG, 14,
  193. "F15", LFREG, 15,
  194. "C", LC, 0,
  195. "C0", LCREG, 0,
  196. "C1", LCREG, 1,
  197. "C2", LCREG, 2,
  198. "C3", LCREG, 3,
  199. "C4", LCREG, 4,
  200. "C5", LCREG, 5,
  201. "C6", LCREG, 6,
  202. "C7", LCREG, 7,
  203. "C8", LCREG, 8,
  204. "C9", LCREG, 9,
  205. "C10", LCREG, 10,
  206. "C11", LCREG, 11,
  207. "C12", LCREG, 12,
  208. "C13", LCREG, 13,
  209. "C14", LCREG, 14,
  210. "C15", LCREG, 15,
  211. "CPSR", LPSR, 0,
  212. "SPSR", LPSR, 1,
  213. "FPSR", LFCR, 0,
  214. "FPCR", LFCR, 1,
  215. ".EQ", LCOND, 0,
  216. ".NE", LCOND, 1,
  217. ".CS", LCOND, 2,
  218. ".HS", LCOND, 2,
  219. ".CC", LCOND, 3,
  220. ".LO", LCOND, 3,
  221. ".MI", LCOND, 4,
  222. ".PL", LCOND, 5,
  223. ".VS", LCOND, 6,
  224. ".VC", LCOND, 7,
  225. ".HI", LCOND, 8,
  226. ".LS", LCOND, 9,
  227. ".GE", LCOND, 10,
  228. ".LT", LCOND, 11,
  229. ".GT", LCOND, 12,
  230. ".LE", LCOND, 13,
  231. ".AL", LCOND, Always,
  232. ".U", LS, C_UBIT,
  233. ".S", LS, C_SBIT,
  234. ".W", LS, C_WBIT,
  235. ".P", LS, C_PBIT,
  236. ".PW", LS, C_WBIT|C_PBIT,
  237. ".WP", LS, C_WBIT|C_PBIT,
  238. ".F", LS, C_FBIT,
  239. ".IBW", LS, C_WBIT|C_PBIT|C_UBIT,
  240. ".IAW", LS, C_WBIT|C_UBIT,
  241. ".DBW", LS, C_WBIT|C_PBIT,
  242. ".DAW", LS, C_WBIT,
  243. ".IB", LS, C_PBIT|C_UBIT,
  244. ".IA", LS, C_UBIT,
  245. ".DB", LS, C_PBIT,
  246. ".DA", LS, 0,
  247. "@", LAT, 0,
  248. "AND", LTYPE1, AAND,
  249. "EOR", LTYPE1, AEOR,
  250. "SUB", LTYPE1, ASUB,
  251. "RSB", LTYPE1, ARSB,
  252. "ADD", LTYPE1, AADD,
  253. "ADC", LTYPE1, AADC,
  254. "SBC", LTYPE1, ASBC,
  255. "RSC", LTYPE1, ARSC,
  256. "ORR", LTYPE1, AORR,
  257. "BIC", LTYPE1, ABIC,
  258. "SLL", LTYPE1, ASLL,
  259. "SRL", LTYPE1, ASRL,
  260. "SRA", LTYPE1, ASRA,
  261. "MUL", LTYPE1, AMUL,
  262. "MULA", LTYPEN, AMULA,
  263. "DIV", LTYPE1, ADIV,
  264. "MOD", LTYPE1, AMOD,
  265. "MULL", LTYPEM, AMULL,
  266. "MULAL", LTYPEM, AMULAL,
  267. "MULLU", LTYPEM, AMULLU,
  268. "MULALU", LTYPEM, AMULALU,
  269. "MVN", LTYPE2, AMVN, /* op2 ignored */
  270. "MOVB", LTYPE3, AMOVB,
  271. "MOVBU", LTYPE3, AMOVBU,
  272. "MOVH", LTYPE3, AMOVH,
  273. "MOVHU", LTYPE3, AMOVHU,
  274. "MOVW", LTYPE3, AMOVW,
  275. "MOVD", LTYPE3, AMOVD,
  276. "MOVDF", LTYPE3, AMOVDF,
  277. "MOVDW", LTYPE3, AMOVDW,
  278. "MOVF", LTYPE3, AMOVF,
  279. "MOVFD", LTYPE3, AMOVFD,
  280. "MOVFW", LTYPE3, AMOVFW,
  281. "MOVWD", LTYPE3, AMOVWD,
  282. "MOVWF", LTYPE3, AMOVWF,
  283. /*
  284. "ABSF", LTYPEI, AABSF,
  285. "ABSD", LTYPEI, AABSD,
  286. "NEGF", LTYPEI, ANEGF,
  287. "NEGD", LTYPEI, ANEGD,
  288. "SQTF", LTYPEI, ASQTF,
  289. "SQTD", LTYPEI, ASQTD,
  290. "RNDF", LTYPEI, ARNDF,
  291. "RNDD", LTYPEI, ARNDD,
  292. "URDF", LTYPEI, AURDF,
  293. "URDD", LTYPEI, AURDD,
  294. "NRMF", LTYPEI, ANRMF,
  295. "NRMD", LTYPEI, ANRMD,
  296. */
  297. "CMPF", LTYPEL, ACMPF,
  298. "CMPD", LTYPEL, ACMPD,
  299. "ADDF", LTYPEK, AADDF,
  300. "ADDD", LTYPEK, AADDD,
  301. "SUBF", LTYPEK, ASUBF,
  302. "SUBD", LTYPEK, ASUBD,
  303. "MULF", LTYPEK, AMULF,
  304. "MULD", LTYPEK, AMULD,
  305. "DIVF", LTYPEK, ADIVF,
  306. "DIVD", LTYPEK, ADIVD,
  307. "B", LTYPE4, AB,
  308. "BL", LTYPE4, ABL,
  309. "BX", LTYPEBX, ABX,
  310. "BEQ", LTYPE5, ABEQ,
  311. "BNE", LTYPE5, ABNE,
  312. "BCS", LTYPE5, ABCS,
  313. "BHS", LTYPE5, ABHS,
  314. "BCC", LTYPE5, ABCC,
  315. "BLO", LTYPE5, ABLO,
  316. "BMI", LTYPE5, ABMI,
  317. "BPL", LTYPE5, ABPL,
  318. "BVS", LTYPE5, ABVS,
  319. "BVC", LTYPE5, ABVC,
  320. "BHI", LTYPE5, ABHI,
  321. "BLS", LTYPE5, ABLS,
  322. "BGE", LTYPE5, ABGE,
  323. "BLT", LTYPE5, ABLT,
  324. "BGT", LTYPE5, ABGT,
  325. "BLE", LTYPE5, ABLE,
  326. "BCASE", LTYPE5, ABCASE,
  327. "SWI", LTYPE6, ASWI,
  328. "CMP", LTYPE7, ACMP,
  329. "TST", LTYPE7, ATST,
  330. "TEQ", LTYPE7, ATEQ,
  331. "CMN", LTYPE7, ACMN,
  332. "MOVM", LTYPE8, AMOVM,
  333. "SWPBU", LTYPE9, ASWPBU,
  334. "SWPW", LTYPE9, ASWPW,
  335. "RET", LTYPEA, ARET,
  336. "RFE", LTYPEA, ARFE,
  337. "TEXT", LTYPEB, ATEXT,
  338. "GLOBL", LTYPEB, AGLOBL,
  339. "DATA", LTYPEC, ADATA,
  340. "CASE", LTYPED, ACASE,
  341. "END", LTYPEE, AEND,
  342. "WORD", LTYPEH, AWORD,
  343. "NOP", LTYPEI, ANOP,
  344. "MCR", LTYPEJ, 0,
  345. "MRC", LTYPEJ, 1,
  346. 0
  347. };
  348. void
  349. cinit(void)
  350. {
  351. Sym *s;
  352. int i;
  353. nullgen.sym = S;
  354. nullgen.offset = 0;
  355. nullgen.type = D_NONE;
  356. nullgen.name = D_NONE;
  357. nullgen.reg = NREG;
  358. if(FPCHIP)
  359. nullgen.dval = 0;
  360. for(i=0; i<sizeof(nullgen.sval); i++)
  361. nullgen.sval[i] = 0;
  362. nerrors = 0;
  363. iostack = I;
  364. iofree = I;
  365. peekc = IGN;
  366. nhunk = 0;
  367. for(i=0; i<NHASH; i++)
  368. hash[i] = S;
  369. for(i=0; itab[i].name; i++) {
  370. s = slookup(itab[i].name);
  371. s->type = itab[i].type;
  372. s->value = itab[i].value;
  373. }
  374. pathname = allocn(pathname, 0, 100);
  375. if(mygetwd(pathname, 99) == 0) {
  376. pathname = allocn(pathname, 100, 900);
  377. if(mygetwd(pathname, 999) == 0)
  378. strcpy(pathname, "/???");
  379. }
  380. }
  381. void
  382. syminit(Sym *s)
  383. {
  384. s->type = LNAME;
  385. s->value = 0;
  386. }
  387. int
  388. isreg(Gen *g)
  389. {
  390. USED(g);
  391. return 1;
  392. }
  393. void
  394. cclean(void)
  395. {
  396. outcode(AEND, Always, &nullgen, NREG, &nullgen);
  397. Bflush(&obuf);
  398. }
  399. void
  400. zname(char *n, int t, int s)
  401. {
  402. Bputc(&obuf, ANAME);
  403. Bputc(&obuf, t); /* type */
  404. Bputc(&obuf, s); /* sym */
  405. while(*n) {
  406. Bputc(&obuf, *n);
  407. n++;
  408. }
  409. Bputc(&obuf, 0);
  410. }
  411. void
  412. zaddr(Gen *a, int s)
  413. {
  414. long l;
  415. int i;
  416. char *n;
  417. Ieee e;
  418. Bputc(&obuf, a->type);
  419. Bputc(&obuf, a->reg);
  420. Bputc(&obuf, s);
  421. Bputc(&obuf, a->name);
  422. switch(a->type) {
  423. default:
  424. print("unknown type %d\n", a->type);
  425. exits("arg");
  426. case D_NONE:
  427. case D_REG:
  428. case D_FREG:
  429. case D_PSR:
  430. case D_FPCR:
  431. break;
  432. case D_REGREG:
  433. Bputc(&obuf, a->offset);
  434. break;
  435. case D_OREG:
  436. case D_CONST:
  437. case D_BRANCH:
  438. case D_SHIFT:
  439. l = a->offset;
  440. Bputc(&obuf, l);
  441. Bputc(&obuf, l>>8);
  442. Bputc(&obuf, l>>16);
  443. Bputc(&obuf, l>>24);
  444. break;
  445. case D_SCONST:
  446. n = a->sval;
  447. for(i=0; i<NSNAME; i++) {
  448. Bputc(&obuf, *n);
  449. n++;
  450. }
  451. break;
  452. case D_FCONST:
  453. ieeedtod(&e, a->dval);
  454. Bputc(&obuf, e.l);
  455. Bputc(&obuf, e.l>>8);
  456. Bputc(&obuf, e.l>>16);
  457. Bputc(&obuf, e.l>>24);
  458. Bputc(&obuf, e.h);
  459. Bputc(&obuf, e.h>>8);
  460. Bputc(&obuf, e.h>>16);
  461. Bputc(&obuf, e.h>>24);
  462. break;
  463. }
  464. }
  465. static int bcode[] =
  466. {
  467. ABEQ,
  468. ABNE,
  469. ABCS,
  470. ABCC,
  471. ABMI,
  472. ABPL,
  473. ABVS,
  474. ABVC,
  475. ABHI,
  476. ABLS,
  477. ABGE,
  478. ABLT,
  479. ABGT,
  480. ABLE,
  481. AB,
  482. ANOP,
  483. };
  484. void
  485. outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
  486. {
  487. int sf, st, t;
  488. Sym *s;
  489. /* hack to make B.NE etc. work: turn it into the corresponding conditional */
  490. if(a == AB){
  491. a = bcode[scond&0xf];
  492. scond = (scond & ~0xf) | Always;
  493. }
  494. if(pass == 1)
  495. goto out;
  496. jackpot:
  497. sf = 0;
  498. s = g1->sym;
  499. while(s != S) {
  500. sf = s->sym;
  501. if(sf < 0 || sf >= NSYM)
  502. sf = 0;
  503. t = g1->name;
  504. if(h[sf].type == t)
  505. if(h[sf].sym == s)
  506. break;
  507. zname(s->name, t, sym);
  508. s->sym = sym;
  509. h[sym].sym = s;
  510. h[sym].type = t;
  511. sf = sym;
  512. sym++;
  513. if(sym >= NSYM)
  514. sym = 1;
  515. break;
  516. }
  517. st = 0;
  518. s = g2->sym;
  519. while(s != S) {
  520. st = s->sym;
  521. if(st < 0 || st >= NSYM)
  522. st = 0;
  523. t = g2->name;
  524. if(h[st].type == t)
  525. if(h[st].sym == s)
  526. break;
  527. zname(s->name, t, sym);
  528. s->sym = sym;
  529. h[sym].sym = s;
  530. h[sym].type = t;
  531. st = sym;
  532. sym++;
  533. if(sym >= NSYM)
  534. sym = 1;
  535. if(st == sf)
  536. goto jackpot;
  537. break;
  538. }
  539. Bputc(&obuf, a);
  540. Bputc(&obuf, scond);
  541. Bputc(&obuf, reg);
  542. Bputc(&obuf, lineno);
  543. Bputc(&obuf, lineno>>8);
  544. Bputc(&obuf, lineno>>16);
  545. Bputc(&obuf, lineno>>24);
  546. zaddr(g1, sf);
  547. zaddr(g2, st);
  548. out:
  549. if(a != AGLOBL && a != ADATA)
  550. pc++;
  551. }
  552. void
  553. outhist(void)
  554. {
  555. Gen g;
  556. Hist *h;
  557. char *p, *q, *op, c;
  558. int n;
  559. g = nullgen;
  560. c = pathchar();
  561. for(h = hist; h != H; h = h->link) {
  562. p = h->name;
  563. op = 0;
  564. /* on windows skip drive specifier in pathname */
  565. if(systemtype(Windows) && p && p[1] == ':'){
  566. p += 2;
  567. c = *p;
  568. }
  569. if(p && p[0] != c && h->offset == 0 && pathname){
  570. /* on windows skip drive specifier in pathname */
  571. if(systemtype(Windows) && pathname[1] == ':') {
  572. op = p;
  573. p = pathname+2;
  574. c = *p;
  575. } else if(pathname[0] == c){
  576. op = p;
  577. p = pathname;
  578. }
  579. }
  580. while(p) {
  581. q = strchr(p, c);
  582. if(q) {
  583. n = q-p;
  584. if(n == 0){
  585. n = 1; /* leading "/" */
  586. *p = '/'; /* don't emit "\" on windows */
  587. }
  588. q++;
  589. } else {
  590. n = strlen(p);
  591. q = 0;
  592. }
  593. if(n) {
  594. Bputc(&obuf, ANAME);
  595. Bputc(&obuf, D_FILE); /* type */
  596. Bputc(&obuf, 1); /* sym */
  597. Bputc(&obuf, '<');
  598. Bwrite(&obuf, p, n);
  599. Bputc(&obuf, 0);
  600. }
  601. p = q;
  602. if(p == 0 && op) {
  603. p = op;
  604. op = 0;
  605. }
  606. }
  607. g.offset = h->offset;
  608. Bputc(&obuf, AHISTORY);
  609. Bputc(&obuf, Always);
  610. Bputc(&obuf, 0);
  611. Bputc(&obuf, h->line);
  612. Bputc(&obuf, h->line>>8);
  613. Bputc(&obuf, h->line>>16);
  614. Bputc(&obuf, h->line>>24);
  615. zaddr(&nullgen, 0);
  616. zaddr(&g, 0);
  617. }
  618. }
  619. #include "../cc/lexbody"
  620. #include "../cc/macbody"
  621. #include "../cc/compat"