a.y 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. %{
  2. #include <u.h>
  3. #include <libc.h>
  4. #include <bio.h>
  5. #include "../9c/9.out.h"
  6. #include "a.h"
  7. %}
  8. %union
  9. {
  10. Sym *sym;
  11. long lval;
  12. double dval;
  13. char sval[8];
  14. Gen gen;
  15. }
  16. %left '|'
  17. %left '^'
  18. %left '&'
  19. %left '<' '>'
  20. %left '+' '-'
  21. %left '*' '/' '%'
  22. %token <lval> LTYPE1 LTYPE3 LTYPE4 LTYPE5 LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPE10
  23. %token <lval> LTYPEA LTYPEB LTYPEC
  24. %token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
  25. %token <lval> LCONST LSP LSB LFP LPC LMREG
  26. %token <lval> LTYPEX LREG LFREG LR
  27. %token <lval> LFCR LSCHED
  28. %token <dval> LFCONST
  29. %token <sval> LSCONST
  30. %token <sym> LNAME LLAB LVAR
  31. %type <lval> con expr pointer offset sreg
  32. %type <gen> gen rel reg abs zoreg
  33. %type <gen> imm ximm ireg name oreg imr nireg
  34. %%
  35. prog:
  36. | prog line
  37. line:
  38. LLAB ':'
  39. {
  40. if($1->value != pc)
  41. yyerror("redeclaration of %s", $1->name);
  42. $1->value = pc;
  43. }
  44. line
  45. | LNAME ':'
  46. {
  47. $1->type = LLAB;
  48. $1->value = pc;
  49. }
  50. line
  51. | LNAME '=' expr ';'
  52. {
  53. $1->type = LVAR;
  54. $1->value = $3;
  55. }
  56. | LVAR '=' expr ';'
  57. {
  58. if($1->value != $3)
  59. yyerror("redeclaration of %s", $1->name);
  60. $1->value = $3;
  61. }
  62. | ';'
  63. | inst ';'
  64. | error ';'
  65. inst:
  66. /*
  67. * rrr
  68. */
  69. LTYPE1 imr ',' sreg ',' reg
  70. {
  71. outcode($1, &$2, $4, &$6);
  72. }
  73. | LTYPE1 imr ',' reg
  74. {
  75. outcode($1, &$2, NREG, &$4);
  76. }
  77. | LTYPE1 ',' reg
  78. {
  79. outcode($1, &nullgen, NREG, &$3);
  80. }
  81. /*
  82. * LOAD/STORE
  83. */
  84. | LTYPE3 gen ',' gen
  85. {
  86. if(!isreg(&$2) && !isreg(&$4))
  87. print("one side must be register\n");
  88. outcode($1, &$2, NREG, &$4);
  89. }
  90. | LTYPE3 ximm ',' reg
  91. {
  92. if(!isreg(&$2) && !isreg(&$4))
  93. print("one side must be register\n");
  94. outcode($1, &$2, NREG, &$4);
  95. }
  96. /*
  97. * LOAD/STORE
  98. */
  99. | LTYPE4 reg ',' reg
  100. {
  101. outcode($1, &$2, NREG, &$4);
  102. }
  103. /*
  104. * JMP/CALL
  105. */
  106. | LTYPE5 comma rel
  107. {
  108. outcode($1, &nullgen, NREG, &$3);
  109. }
  110. | LTYPE5 comma nireg
  111. {
  112. outcode($1, &nullgen, NREG, &$3);
  113. }
  114. | LTYPE5 reg comma rel
  115. {
  116. outcode($1, &$2, NREG, &$4);
  117. }
  118. | LTYPE5 reg comma nireg
  119. {
  120. outcode($1, &$2, NREG, &$4);
  121. }
  122. /*
  123. * LOAD special
  124. */
  125. | LTYPE6 zoreg ',' reg
  126. {
  127. outcode($1, &$2, NREG, &$4);
  128. }
  129. /*
  130. * STORE special
  131. */
  132. | LTYPE7 reg ',' zoreg
  133. {
  134. outcode($1, &$2, NREG, &$4);
  135. }
  136. /*
  137. * INV
  138. */
  139. | LTYPE8 imm
  140. {
  141. if((ulong)$2.offset > 3)
  142. yyerror("inv constant too large");
  143. outcode($1, &nullgen, NREG, &$2);
  144. }
  145. /*
  146. * MTSR special
  147. */
  148. | LTYPE9 reg ',' reg
  149. {
  150. outcode($1, &$2, NREG, &$4);
  151. }
  152. | LTYPE9 imm ',' reg
  153. {
  154. outcode($1, &$2, NREG, &$4);
  155. }
  156. /*
  157. * MFSR special
  158. */
  159. | LTYPE10 reg ',' reg
  160. {
  161. outcode($1, &$2, NREG, &$4);
  162. }
  163. /*
  164. * emulate
  165. */
  166. | LTYPEA abs ',' abs
  167. {
  168. outcode($1, &$2, NREG, &$4);
  169. }
  170. | LTYPEA abs
  171. {
  172. outcode($1, &nullgen, NREG, &$2);
  173. }
  174. | LTYPEA
  175. {
  176. outcode($1, &nullgen, NREG, &nullgen);
  177. }
  178. /*
  179. * TEXT/GLOBL
  180. */
  181. | LTYPEB name ',' imm
  182. {
  183. outcode($1, &$2, NREG, &$4);
  184. }
  185. | LTYPEB name ',' con ',' imm
  186. {
  187. outcode($1, &$2, $4, &$6);
  188. }
  189. /*
  190. * DATA
  191. */
  192. | LTYPEC name '/' con ',' ximm
  193. {
  194. outcode($1, &$2, $4, &$6);
  195. }
  196. /*
  197. * ret
  198. */
  199. | LTYPEG comma
  200. {
  201. outcode($1, &nullgen, NREG, &nullgen);
  202. }
  203. /*
  204. * word
  205. */
  206. | LTYPEH comma ximm
  207. {
  208. outcode($1, &nullgen, NREG, &$3);
  209. }
  210. /*
  211. * nop
  212. */
  213. | LTYPEI comma
  214. {
  215. outcode($1, &nullgen, NREG, &nullgen);
  216. }
  217. | LTYPEI comma reg
  218. {
  219. outcode($1, &nullgen, NREG, &$3);
  220. }
  221. /*
  222. * scheduling on/off
  223. */
  224. | LSCHED
  225. {
  226. outcode(ANOSCHED, &nullgen, $1, &nullgen);
  227. }
  228. comma:
  229. | ','
  230. rel:
  231. con '(' LPC ')'
  232. {
  233. $$ = nullgen;
  234. $$.type = D_BRANCH;
  235. $$.offset = $1 + pc;
  236. }
  237. | LNAME offset
  238. {
  239. $$ = nullgen;
  240. if(pass == 2)
  241. yyerror("undefined label: %s", $1->name);
  242. $$.type = D_BRANCH;
  243. $$.sym = $1;
  244. $$.offset = $2;
  245. }
  246. | LLAB offset
  247. {
  248. $$ = nullgen;
  249. $$.type = D_BRANCH;
  250. $$.sym = $1;
  251. $$.offset = $1->value + $2;
  252. }
  253. ximm: '$' con
  254. {
  255. $$ = nullgen;
  256. $$.type = D_CONST;
  257. $$.offset = $2;
  258. }
  259. | '$' oreg
  260. {
  261. $$ = $2;
  262. $$.type = D_CONST;
  263. }
  264. | '$' '*' '$' oreg
  265. {
  266. $$ = $4;
  267. $$.type = D_OCONST;
  268. }
  269. | '$' LSCONST
  270. {
  271. $$ = nullgen;
  272. $$.type = D_SCONST;
  273. memcpy($$.sval, $2, sizeof($$.sval));
  274. }
  275. | '$' LFCONST
  276. {
  277. $$ = nullgen;
  278. $$.type = D_FCONST;
  279. $$.dval = $2;
  280. }
  281. | '$' '-' LFCONST
  282. {
  283. $$ = nullgen;
  284. $$.type = D_FCONST;
  285. $$.dval = -$3;
  286. }
  287. nireg:
  288. ireg
  289. | name
  290. {
  291. $$ = $1;
  292. if($1.name != D_EXTERN && $1.name != D_STATIC) {
  293. }
  294. }
  295. ireg:
  296. '(' sreg ')'
  297. {
  298. $$ = nullgen;
  299. $$.type = D_OREG;
  300. $$.reg = $2;
  301. $$.offset = 0;
  302. }
  303. gen:
  304. reg
  305. | abs
  306. | oreg
  307. abs:
  308. con
  309. {
  310. $$ = nullgen;
  311. $$.type = D_OREG;
  312. $$.offset = $1;
  313. }
  314. zoreg : '(' sreg ')'
  315. {
  316. $$ = nullgen;
  317. $$.type = D_OREG;
  318. $$.reg = $2;
  319. $$.offset = 0;
  320. }
  321. oreg:
  322. name
  323. | name '(' sreg ')'
  324. {
  325. $$ = $1;
  326. $$.type = D_OREG;
  327. $$.reg = $3;
  328. }
  329. | '(' sreg ')'
  330. {
  331. $$ = nullgen;
  332. $$.type = D_OREG;
  333. $$.reg = $2;
  334. $$.offset = 0;
  335. }
  336. | con '(' sreg ')'
  337. {
  338. $$ = nullgen;
  339. $$.type = D_OREG;
  340. $$.reg = $3;
  341. $$.offset = $1;
  342. }
  343. imr:
  344. reg
  345. | imm
  346. imm: '$' con
  347. {
  348. $$ = nullgen;
  349. $$.type = D_CONST;
  350. $$.offset = $2;
  351. }
  352. reg:
  353. sreg
  354. {
  355. $$ = nullgen;
  356. $$.type = D_REG;
  357. $$.reg = $1;
  358. }
  359. sreg:
  360. LREG
  361. | LR '(' expr ')'
  362. {
  363. if($$ < 0 || $$ >= NREG)
  364. print("register value out of range\n");
  365. $$ = $3;
  366. }
  367. name:
  368. con '(' pointer ')'
  369. {
  370. $$ = nullgen;
  371. $$.type = D_OREG;
  372. $$.name = $3;
  373. $$.sym = S;
  374. $$.offset = $1;
  375. }
  376. | LNAME offset '(' pointer ')'
  377. {
  378. $$ = nullgen;
  379. $$.type = D_OREG;
  380. $$.name = $4;
  381. $$.sym = $1;
  382. $$.offset = $2;
  383. }
  384. | LNAME '<' '>' offset '(' LSB ')'
  385. {
  386. $$ = nullgen;
  387. $$.type = D_OREG;
  388. $$.name = D_STATIC;
  389. $$.sym = $1;
  390. $$.offset = $4;
  391. }
  392. offset:
  393. {
  394. $$ = 0;
  395. }
  396. | '+' con
  397. {
  398. $$ = $2;
  399. }
  400. | '-' con
  401. {
  402. $$ = -$2;
  403. }
  404. pointer:
  405. LSB
  406. | LSP
  407. | LFP
  408. con:
  409. LCONST
  410. | LVAR
  411. {
  412. $$ = $1->value;
  413. }
  414. | '-' con
  415. {
  416. $$ = -$2;
  417. }
  418. | '+' con
  419. {
  420. $$ = $2;
  421. }
  422. | '~' con
  423. {
  424. $$ = ~$2;
  425. }
  426. | '(' expr ')'
  427. {
  428. $$ = $2;
  429. }
  430. expr:
  431. con
  432. | expr '+' expr
  433. {
  434. $$ = $1 + $3;
  435. }
  436. | expr '-' expr
  437. {
  438. $$ = $1 - $3;
  439. }
  440. | expr '*' expr
  441. {
  442. $$ = $1 * $3;
  443. }
  444. | expr '/' expr
  445. {
  446. $$ = $1 / $3;
  447. }
  448. | expr '%' expr
  449. {
  450. $$ = $1 % $3;
  451. }
  452. | expr '<' '<' expr
  453. {
  454. $$ = $1 << $4;
  455. }
  456. | expr '>' '>' expr
  457. {
  458. $$ = $1 >> $4;
  459. }
  460. | expr '&' expr
  461. {
  462. $$ = $1 & $3;
  463. }
  464. | expr '^' expr
  465. {
  466. $$ = $1 ^ $3;
  467. }
  468. | expr '|' expr
  469. {
  470. $$ = $1 | $3;
  471. }