lex.c 11 KB

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