a.y 6.4 KB

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