lex.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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 = 'i';
  11. p = strrchr(argv[0], '/');
  12. if(p == nil)
  13. p = argv[0];
  14. else
  15. p++;
  16. if(*p == 'j')
  17. thechar = 'j';
  18. memset(debug, 0, sizeof(debug));
  19. cinit();
  20. outfile = 0;
  21. include[ninclude++] = ".";
  22. ARGBEGIN {
  23. default:
  24. c = ARGC();
  25. if(c >= 0 || c < sizeof(debug))
  26. debug[c] = 1;
  27. break;
  28. case 'o':
  29. outfile = ARGF();
  30. break;
  31. case 'D':
  32. p = ARGF();
  33. if(p)
  34. Dlist[nDlist++] = p;
  35. break;
  36. case 'I':
  37. p = ARGF();
  38. setinclude(p);
  39. break;
  40. } ARGEND
  41. if(*argv == 0) {
  42. print("usage: %ca [-options] file.s\n", thechar);
  43. errorexit();
  44. }
  45. if(debug['j'])
  46. thechar = 'j';
  47. thestring = (thechar == 'j'? "riscv64" : "riscv");
  48. if(argc > 1 && systemtype(Windows)){
  49. print("can't assemble multiple files on windows\n");
  50. errorexit();
  51. }
  52. if(argc > 1 && !systemtype(Windows)) {
  53. nproc = 1;
  54. if(p = getenv("NPROC"))
  55. nproc = atol(p); /* */
  56. c = 0;
  57. nout = 0;
  58. for(;;) {
  59. while(nout < nproc && argc > 0) {
  60. i = myfork();
  61. if(i < 0) {
  62. i = mywait(&status);
  63. if(i < 0)
  64. errorexit();
  65. if(status)
  66. c++;
  67. nout--;
  68. continue;
  69. }
  70. if(i == 0) {
  71. print("%s:\n", *argv);
  72. if(assemble(*argv))
  73. errorexit();
  74. exits(0);
  75. }
  76. nout++;
  77. argc--;
  78. argv++;
  79. }
  80. i = mywait(&status);
  81. if(i < 0) {
  82. if(c)
  83. errorexit();
  84. exits(0);
  85. }
  86. if(status)
  87. c++;
  88. nout--;
  89. }
  90. }
  91. if(assemble(argv[0]))
  92. errorexit();
  93. exits(0);
  94. }
  95. int
  96. assemble(char *file)
  97. {
  98. char ofile[100], incfile[20], *p;
  99. int i, of;
  100. strcpy(ofile, file);
  101. p = utfrrune(ofile, pathchar());
  102. if(p) {
  103. include[0] = ofile;
  104. *p++ = 0;
  105. } else
  106. p = ofile;
  107. if(outfile == 0) {
  108. outfile = p;
  109. if(outfile){
  110. p = utfrrune(outfile, '.');
  111. if(p)
  112. if(p[1] == 's' && p[2] == 0)
  113. p[0] = 0;
  114. p = utfrune(outfile, 0);
  115. p[0] = '.';
  116. p[1] = thechar;
  117. p[2] = 0;
  118. } else
  119. outfile = "/dev/null";
  120. }
  121. p = getenv("INCLUDE");
  122. if(p) {
  123. setinclude(p);
  124. } else {
  125. if(systemtype(Plan9)) {
  126. sprint(incfile,"/%s/include", thestring);
  127. setinclude(strdup(incfile));
  128. }
  129. }
  130. of = mycreat(outfile, 0664);
  131. if(of < 0) {
  132. yyerror("%ca: cannot create %s", thechar, outfile);
  133. errorexit();
  134. }
  135. Binit(&obuf, of, OWRITE);
  136. pass = 1;
  137. pinit(file);
  138. if(thechar == 'j')
  139. dodefine("XLEN=8");
  140. else
  141. dodefine("XLEN=4");
  142. for(i=0; i<nDlist; i++)
  143. dodefine(Dlist[i]);
  144. yyparse();
  145. if(nerrors) {
  146. cclean();
  147. return nerrors;
  148. }
  149. pass = 2;
  150. outhist();
  151. pinit(file);
  152. if(thechar == 'j')
  153. dodefine("XLEN=8");
  154. else
  155. dodefine("XLEN=4");
  156. for(i=0; i<nDlist; i++)
  157. dodefine(Dlist[i]);
  158. yyparse();
  159. cclean();
  160. return nerrors;
  161. }
  162. struct
  163. {
  164. char *name;
  165. ushort type;
  166. ushort value;
  167. } itab[] =
  168. {
  169. "SP", LSP, D_AUTO,
  170. "SB", LSB, D_EXTERN,
  171. "FP", LFP, D_PARAM,
  172. "PC", LPC, D_BRANCH,
  173. "R", LR, 0,
  174. "R0", LREG, 0,
  175. "R1", LREG, 1,
  176. "R2", LREG, 2,
  177. "R3", LREG, 3,
  178. "R4", LREG, 4,
  179. "R5", LREG, 5,
  180. "R6", LREG, 6,
  181. "R7", LREG, 7,
  182. "R8", LREG, 8,
  183. "R9", LREG, 9,
  184. "R10", LREG, 10,
  185. "R11", LREG, 11,
  186. "R12", LREG, 12,
  187. "R13", LREG, 13,
  188. "R14", LREG, 14,
  189. "R15", LREG, 15,
  190. "R16", LREG, 16,
  191. "R17", LREG, 17,
  192. "R18", LREG, 18,
  193. "R19", LREG, 19,
  194. "R20", LREG, 20,
  195. "R21", LREG, 21,
  196. "R22", LREG, 22,
  197. "R23", LREG, 23,
  198. "R24", LREG, 24,
  199. "R25", LREG, 25,
  200. "R26", LREG, 26,
  201. "R27", LREG, 27,
  202. "R28", LREG, 28,
  203. "R29", LREG, 29,
  204. "R30", LREG, 30,
  205. "R31", LREG, 31,
  206. "F", FR, 0,
  207. "F0", LFREG, 0,
  208. "F1", LFREG, 1,
  209. "F2", LFREG, 2,
  210. "F3", LFREG, 3,
  211. "F4", LFREG, 4,
  212. "F5", LFREG, 5,
  213. "F6", LFREG, 6,
  214. "F7", LFREG, 7,
  215. "F8", LFREG, 8,
  216. "F9", LFREG, 9,
  217. "F10", LFREG, 10,
  218. "F11", LFREG, 11,
  219. "F12", LFREG, 12,
  220. "F13", LFREG, 13,
  221. "F14", LFREG, 14,
  222. "F15", LFREG, 15,
  223. "F16", LFREG, 16,
  224. "F17", LFREG, 17,
  225. "F18", LFREG, 18,
  226. "F19", LFREG, 19,
  227. "F20", LFREG, 20,
  228. "F21", LFREG, 21,
  229. "F22", LFREG, 22,
  230. "F23", LFREG, 23,
  231. "F24", LFREG, 24,
  232. "F25", LFREG, 25,
  233. "F26", LFREG, 26,
  234. "F27", LFREG, 27,
  235. "F28", LFREG, 28,
  236. "F29", LFREG, 29,
  237. "F30", LFREG, 30,
  238. "F31", LFREG, 31,
  239. "CSR", LCTL, 0,
  240. "ADD", LADD, AADD,
  241. "SLL", LADD, ASLL,
  242. "SLT", LADD, ASLT,
  243. "SLTU", LADD, ASLTU,
  244. "XOR", LADD, AXOR,
  245. "SRL", LADD, ASRL,
  246. "OR", LADD, AOR,
  247. "AND", LADD, AAND,
  248. "SRA", LADD, ASRA,
  249. "ADDW", LADD, AADDW,
  250. "SLLW", LADD, ASLLW,
  251. "SRLW", LADD, ASRLW,
  252. "SRAW", LADD, ASRAW,
  253. "SUB", LADD, ASUB,
  254. "SUBW", LADD, ASUBW,
  255. "MUL", LMUL, AMUL,
  256. "MULH", LMUL, AMULH,
  257. "MULHSU", LMUL, AMULHSU,
  258. "MULHU", LMUL, AMULHU,
  259. "DIV", LMUL, ADIV,
  260. "DIVU", LMUL, ADIVU,
  261. "REM", LMUL, AREM,
  262. "REMU", LMUL, AREMU,
  263. "MULW", LMUL, AMULW,
  264. "DIVW", LMUL, ADIVW,
  265. "DIVUW", LMUL, ADIVUW,
  266. "REMW", LMUL, AREMW,
  267. "REMUW", LMUL, AREMUW,
  268. "BEQ", LBEQ, ABEQ,
  269. "BNE", LBEQ, ABNE,
  270. "BLT", LBEQ, ABLT,
  271. "BGE", LBEQ, ABGE,
  272. "BLTU", LBEQ, ABLTU,
  273. "BGEU", LBEQ, ABGEU,
  274. "BGT", LBEQ, ABGT,
  275. "BGTU", LBEQ, ABGTU,
  276. "BLE", LBEQ, ABLE,
  277. "BLEU", LBEQ, ABLEU,
  278. "JMP", LBR, AJMP,
  279. "RET", LBRET, ARET,
  280. "FENCE_I", LBRET, AFENCE_I,
  281. "NOP", LBRET, ANOP,
  282. "END", LBRET, AEND,
  283. "JAL", LCALL, AJAL,
  284. "JALR", LCALL, AJAL,
  285. "MOVB", LMOVB, AMOVB,
  286. "MOVH", LMOVB, AMOVH,
  287. "MOVF", LMOVF, AMOVF,
  288. "MOVD", LMOVF, AMOVD,
  289. "MOVBU", LMOVBU, AMOVBU,
  290. "MOVHU", LMOVBU, AMOVHU,
  291. "MOVW", LMOVW, AMOVW,
  292. "MOVFD", LFLT2, AMOVFD,
  293. "MOVDF", LFLT2, AMOVDF,
  294. "MOVWF", LFLT2, AMOVWF,
  295. "MOVUF", LFLT2, AMOVUF,
  296. "MOVFW", LFLT2, AMOVFW,
  297. "MOVWD", LFLT2, AMOVWD,
  298. "MOVUD", LFLT2, AMOVUD,
  299. "MOVDW", LFLT2, AMOVDW,
  300. "ADDF", LFLT3, AADDF,
  301. "ADDD", LFLT3, AADDD,
  302. "SUBF", LFLT3, ASUBF,
  303. "SUBD", LFLT3, ASUBD,
  304. "MULF", LFLT3, AMULF,
  305. "MULD", LFLT3, AMULD,
  306. "DIVF", LFLT3, ADIVF,
  307. "DIVD", LFLT3, ADIVD,
  308. "CMPLTF", LFLT3, ACMPLTF,
  309. "CMPLTD", LFLT3, ACMPLTD,
  310. "CMPEQF", LFLT3, ACMPEQF,
  311. "CMPEQD", LFLT3, ACMPEQD,
  312. "CMPLEF", LFLT3, ACMPLEF,
  313. "CMPLED", LFLT3, ACMPLED,
  314. "LUI", LLUI, ALUI,
  315. "SYS", LSYS, ASYS,
  316. "ECALL", LSYS0, 0,
  317. "EBREAK", LSYS0, 1,
  318. "CSRRW", LCSR, ACSRRW,
  319. "CSRRS", LCSR, ACSRRS,
  320. "CSRRC", LCSR, ACSRRC,
  321. "SWAP_W", LSWAP, ASWAP_W,
  322. "SWAP_D", LSWAP, ASWAP_D,
  323. "LR_W", LSWAP, ALR_W,
  324. "LR_D", LSWAP, ALR_D,
  325. "SC_W", LSWAP, ASC_W,
  326. "SC_D", LSWAP, ASC_D,
  327. "AMO_W", LAMO, AAMO_W,
  328. "AMO_D", LAMO, AAMO_D,
  329. "DATA", LDATA, ADATA,
  330. "GLOBL", LTEXT, AGLOBL,
  331. "TEXT", LTEXT, ATEXT,
  332. "WORD", LWORD, AWORD,
  333. "DWORD", LWORD, ADWORD,
  334. "MOV", LMOVW, AMOV,
  335. "MOVWU", LMOVBU, AMOVWU,
  336. 0
  337. };
  338. void
  339. cinit(void)
  340. {
  341. Sym *s;
  342. int i;
  343. nullgen.sym = S;
  344. nullgen.offset = 0;
  345. nullgen.type = D_NONE;
  346. nullgen.name = D_NONE;
  347. nullgen.reg = NREG;
  348. if(FPCHIP)
  349. nullgen.dval = 0;
  350. for(i=0; i<sizeof(nullgen.sval); i++)
  351. nullgen.sval[i] = 0;
  352. nerrors = 0;
  353. iostack = I;
  354. iofree = I;
  355. peekc = IGN;
  356. nhunk = 0;
  357. for(i=0; i<NHASH; i++)
  358. hash[i] = S;
  359. for(i=0; itab[i].name; i++) {
  360. s = slookup(itab[i].name);
  361. s->type = itab[i].type;
  362. s->value = itab[i].value;
  363. }
  364. pathname = allocn(pathname, 0, 100);
  365. if(mygetwd(pathname, 99) == 0) {
  366. pathname = allocn(pathname, 100, 900);
  367. if(mygetwd(pathname, 999) == 0)
  368. strcpy(pathname, "/???");
  369. }
  370. }
  371. void
  372. syminit(Sym *s)
  373. {
  374. s->type = LNAME;
  375. s->value = 0;
  376. }
  377. void
  378. cclean(void)
  379. {
  380. outcode(AEND, &nullgen, NREG, &nullgen);
  381. Bflush(&obuf);
  382. }
  383. void
  384. zname(char *n, int t, int s)
  385. {
  386. Bputc(&obuf, ANAME);
  387. Bputc(&obuf, t); /* type */
  388. Bputc(&obuf, s); /* sym */
  389. while(*n) {
  390. Bputc(&obuf, *n);
  391. n++;
  392. }
  393. Bputc(&obuf, 0);
  394. }
  395. void
  396. zaddr(Gen *a, int s)
  397. {
  398. vlong v;
  399. long l;
  400. int i;
  401. char *n;
  402. Ieee e;
  403. Bputc(&obuf, a->type);
  404. Bputc(&obuf, a->reg);
  405. Bputc(&obuf, s);
  406. Bputc(&obuf, a->name);
  407. switch(a->type) {
  408. default:
  409. print("unknown type %d\n", a->type);
  410. exits("arg");
  411. case D_NONE:
  412. case D_REG:
  413. case D_FREG:
  414. break;
  415. case D_CTLREG:
  416. case D_OREG:
  417. case D_CONST:
  418. case D_BRANCH:
  419. l = a->offset;
  420. Bputc(&obuf, l);
  421. Bputc(&obuf, l>>8);
  422. Bputc(&obuf, l>>16);
  423. Bputc(&obuf, l>>24);
  424. break;
  425. case D_VCONST:
  426. v = a->vval;
  427. Bputc(&obuf, v);
  428. Bputc(&obuf, v>>8);
  429. Bputc(&obuf, v>>16);
  430. Bputc(&obuf, v>>24);
  431. Bputc(&obuf, v>>32);
  432. Bputc(&obuf, v>>40);
  433. Bputc(&obuf, v>>48);
  434. Bputc(&obuf, v>>56);
  435. break;
  436. case D_SCONST:
  437. n = a->sval;
  438. for(i=0; i<NSNAME; i++) {
  439. Bputc(&obuf, *n);
  440. n++;
  441. }
  442. break;
  443. case D_FCONST:
  444. ieeedtod(&e, a->dval);
  445. Bputc(&obuf, e.l);
  446. Bputc(&obuf, e.l>>8);
  447. Bputc(&obuf, e.l>>16);
  448. Bputc(&obuf, e.l>>24);
  449. Bputc(&obuf, e.h);
  450. Bputc(&obuf, e.h>>8);
  451. Bputc(&obuf, e.h>>16);
  452. Bputc(&obuf, e.h>>24);
  453. break;
  454. }
  455. }
  456. void
  457. outcode(int a, Gen *g1, int reg, Gen *g2)
  458. {
  459. int sf, st, t;
  460. Sym *s;
  461. if(pass == 1)
  462. goto out;
  463. jackpot:
  464. sf = 0;
  465. s = g1->sym;
  466. while(s != S) {
  467. sf = s->sym;
  468. if(sf < 0 || sf >= NSYM)
  469. sf = 0;
  470. t = g1->name;
  471. if(h[sf].type == t)
  472. if(h[sf].sym == s)
  473. break;
  474. zname(s->name, t, sym);
  475. s->sym = sym;
  476. h[sym].sym = s;
  477. h[sym].type = t;
  478. sf = sym;
  479. sym++;
  480. if(sym >= NSYM)
  481. sym = 1;
  482. break;
  483. }
  484. st = 0;
  485. s = g2->sym;
  486. while(s != S) {
  487. st = s->sym;
  488. if(st < 0 || st >= NSYM)
  489. st = 0;
  490. t = g2->name;
  491. if(h[st].type == t)
  492. if(h[st].sym == s)
  493. break;
  494. zname(s->name, t, sym);
  495. s->sym = sym;
  496. h[sym].sym = s;
  497. h[sym].type = t;
  498. st = sym;
  499. sym++;
  500. if(sym >= NSYM)
  501. sym = 1;
  502. if(st == sf)
  503. goto jackpot;
  504. break;
  505. }
  506. Bputc(&obuf, a);
  507. Bputc(&obuf, reg);
  508. Bputc(&obuf, lineno);
  509. Bputc(&obuf, lineno>>8);
  510. Bputc(&obuf, lineno>>16);
  511. Bputc(&obuf, lineno>>24);
  512. zaddr(g1, sf);
  513. zaddr(g2, st);
  514. out:
  515. if(a != AGLOBL && a != ADATA)
  516. pc++;
  517. }
  518. void
  519. outhist(void)
  520. {
  521. Gen g;
  522. Hist *h;
  523. char *p, *q, *op, c;
  524. int n;
  525. g = nullgen;
  526. c = pathchar();
  527. for(h = hist; h != H; h = h->link) {
  528. p = h->name;
  529. op = 0;
  530. /* on windows skip drive specifier in pathname */
  531. if(systemtype(Windows) && p && p[1] == ':'){
  532. p += 2;
  533. c = *p;
  534. }
  535. if(p && p[0] != c && h->offset == 0 && pathname){
  536. /* on windows skip drive specifier in pathname */
  537. if(systemtype(Windows) && pathname[1] == ':') {
  538. op = p;
  539. p = pathname+2;
  540. c = *p;
  541. } else if(pathname[0] == c){
  542. op = p;
  543. p = pathname;
  544. }
  545. }
  546. while(p) {
  547. q = strchr(p, c);
  548. if(q) {
  549. n = q-p;
  550. if(n == 0){
  551. n = 1; /* leading "/" */
  552. *p = '/'; /* don't emit "\" on windows */
  553. }
  554. q++;
  555. } else {
  556. n = strlen(p);
  557. q = 0;
  558. }
  559. if(n) {
  560. Bputc(&obuf, ANAME);
  561. Bputc(&obuf, D_FILE); /* type */
  562. Bputc(&obuf, 1); /* sym */
  563. Bputc(&obuf, '<');
  564. Bwrite(&obuf, p, n);
  565. Bputc(&obuf, 0);
  566. }
  567. p = q;
  568. if(p == 0 && op) {
  569. p = op;
  570. op = 0;
  571. }
  572. }
  573. g.offset = h->offset;
  574. Bputc(&obuf, AHISTORY);
  575. Bputc(&obuf, 0);
  576. Bputc(&obuf, h->line);
  577. Bputc(&obuf, h->line>>8);
  578. Bputc(&obuf, h->line>>16);
  579. Bputc(&obuf, h->line>>24);
  580. zaddr(&nullgen, 0);
  581. zaddr(&g, 0);
  582. }
  583. }
  584. #include "../cc/lexbody"
  585. #include "../cc/macbody"
  586. #include "../cc/compat"