a.y 7.0 KB

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