a.y 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  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> LTYPEL LTYPEM LTYPEN LTYPEBX
  23. %token <lval> LCONST LSP LSB LFP LPC
  24. %token <lval> LTYPEX LR LREG LF LFREG LC LCREG LPSR LFCR
  25. %token <lval> LCOND LS LAT
  26. %token <dval> LFCONST
  27. %token <sval> LSCONST
  28. %token <sym> LNAME LLAB LVAR
  29. %type <lval> con expr oexpr pointer offset sreg spreg creg
  30. %type <lval> rcon cond reglist
  31. %type <gen> gen rel reg regreg freg shift fcon frcon
  32. %type <gen> imm ximm name oreg ireg nireg ioreg imsr
  33. %%
  34. prog:
  35. | prog line
  36. line:
  37. LLAB ':'
  38. {
  39. if($1->value != pc)
  40. yyerror("redeclaration of %s", $1->name);
  41. $1->value = pc;
  42. }
  43. line
  44. | LNAME ':'
  45. {
  46. $1->type = LLAB;
  47. $1->value = pc;
  48. }
  49. line
  50. | LNAME '=' expr ';'
  51. {
  52. $1->type = LVAR;
  53. $1->value = $3;
  54. }
  55. | LVAR '=' expr ';'
  56. {
  57. if($1->value != $3)
  58. yyerror("redeclaration of %s", $1->name);
  59. $1->value = $3;
  60. }
  61. | ';'
  62. | inst ';'
  63. | error ';'
  64. inst:
  65. /*
  66. * ADD
  67. */
  68. LTYPE1 cond imsr ',' spreg ',' reg
  69. {
  70. outcode($1, $2, &$3, $5, &$7);
  71. }
  72. | LTYPE1 cond imsr ',' spreg ','
  73. {
  74. outcode($1, $2, &$3, $5, &nullgen);
  75. }
  76. | LTYPE1 cond imsr ',' reg
  77. {
  78. outcode($1, $2, &$3, NREG, &$5);
  79. }
  80. /*
  81. * MVN
  82. */
  83. | LTYPE2 cond imsr ',' reg
  84. {
  85. outcode($1, $2, &$3, NREG, &$5);
  86. }
  87. /*
  88. * MOVW
  89. */
  90. | LTYPE3 cond gen ',' gen
  91. {
  92. outcode($1, $2, &$3, NREG, &$5);
  93. }
  94. /*
  95. * B/BL
  96. */
  97. | LTYPE4 cond comma rel
  98. {
  99. outcode($1, $2, &nullgen, NREG, &$4);
  100. }
  101. | LTYPE4 cond comma nireg
  102. {
  103. outcode($1, $2, &nullgen, NREG, &$4);
  104. }
  105. /*
  106. * BX
  107. */
  108. | LTYPEBX comma ireg
  109. {
  110. outcode($1, Always, &nullgen, NREG, &$3);
  111. }
  112. /*
  113. * BEQ
  114. */
  115. | LTYPE5 comma rel
  116. {
  117. outcode($1, Always, &nullgen, NREG, &$3);
  118. }
  119. /*
  120. * SWI
  121. */
  122. | LTYPE6 cond comma gen
  123. {
  124. outcode($1, $2, &nullgen, NREG, &$4);
  125. }
  126. /*
  127. * CMP
  128. */
  129. | LTYPE7 cond imsr ',' spreg comma
  130. {
  131. outcode($1, $2, &$3, $5, &nullgen);
  132. }
  133. /*
  134. * MOVM
  135. */
  136. | LTYPE8 cond ioreg ',' '[' reglist ']'
  137. {
  138. Gen g;
  139. g = nullgen;
  140. g.type = D_CONST;
  141. g.offset = $6;
  142. outcode($1, $2, &$3, NREG, &g);
  143. }
  144. | LTYPE8 cond '[' reglist ']' ',' ioreg
  145. {
  146. Gen g;
  147. g = nullgen;
  148. g.type = D_CONST;
  149. g.offset = $4;
  150. outcode($1, $2, &g, NREG, &$7);
  151. }
  152. /*
  153. * SWAP
  154. */
  155. | LTYPE9 cond reg ',' ireg ',' reg
  156. {
  157. outcode($1, $2, &$5, $3.reg, &$7);
  158. }
  159. | LTYPE9 cond reg ',' ireg comma
  160. {
  161. outcode($1, $2, &$5, $3.reg, &$3);
  162. }
  163. | LTYPE9 cond comma ireg ',' reg
  164. {
  165. outcode($1, $2, &$4, $6.reg, &$6);
  166. }
  167. /*
  168. * RET
  169. */
  170. | LTYPEA cond comma
  171. {
  172. outcode($1, $2, &nullgen, NREG, &nullgen);
  173. }
  174. /*
  175. * TEXT/GLOBL
  176. */
  177. | LTYPEB name ',' imm
  178. {
  179. outcode($1, Always, &$2, NREG, &$4);
  180. }
  181. | LTYPEB name ',' con ',' imm
  182. {
  183. outcode($1, Always, &$2, $4, &$6);
  184. }
  185. /*
  186. * DATA
  187. */
  188. | LTYPEC name '/' con ',' ximm
  189. {
  190. outcode($1, Always, &$2, $4, &$6);
  191. }
  192. /*
  193. * CASE
  194. */
  195. | LTYPED cond reg comma
  196. {
  197. outcode($1, $2, &$3, NREG, &nullgen);
  198. }
  199. /*
  200. * word
  201. */
  202. | LTYPEH comma ximm
  203. {
  204. outcode($1, Always, &nullgen, NREG, &$3);
  205. }
  206. /*
  207. * floating-point coprocessor
  208. */
  209. | LTYPEI cond freg ',' freg
  210. {
  211. outcode($1, $2, &$3, NREG, &$5);
  212. }
  213. | LTYPEK cond frcon ',' freg
  214. {
  215. outcode($1, $2, &$3, NREG, &$5);
  216. }
  217. | LTYPEK cond frcon ',' LFREG ',' freg
  218. {
  219. outcode($1, $2, &$3, $5, &$7);
  220. }
  221. | LTYPEL cond freg ',' freg comma
  222. {
  223. outcode($1, $2, &$3, $5.reg, &nullgen);
  224. }
  225. /*
  226. * MCR MRC
  227. */
  228. | LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
  229. {
  230. Gen g;
  231. g = nullgen;
  232. g.type = D_CONST;
  233. g.offset =
  234. (0xe << 24) | /* opcode */
  235. ($1 << 20) | /* MCR/MRC */
  236. ($2 << 28) | /* scond */
  237. (($3 & 15) << 8) | /* coprocessor number */
  238. (($5 & 7) << 21) | /* coprocessor operation */
  239. (($7 & 15) << 12) | /* arm register */
  240. (($9 & 15) << 16) | /* Crn */
  241. (($11 & 15) << 0) | /* Crm */
  242. (($12 & 7) << 5) | /* coprocessor information */
  243. (1<<4); /* must be set */
  244. outcode(AWORD, Always, &nullgen, NREG, &g);
  245. }
  246. /*
  247. * MULL hi,lo,r1,r2
  248. */
  249. | LTYPEM cond reg ',' reg ',' regreg
  250. {
  251. outcode($1, $2, &$3, $5.reg, &$7);
  252. }
  253. /*
  254. * MULA hi,lo,r1,r2
  255. */
  256. | LTYPEN cond reg ',' reg ',' reg ',' spreg
  257. {
  258. $7.type = D_REGREG;
  259. $7.offset = $9;
  260. outcode($1, $2, &$3, $5.reg, &$7);
  261. }
  262. /*
  263. * END
  264. */
  265. | LTYPEE comma
  266. {
  267. outcode($1, Always, &nullgen, NREG, &nullgen);
  268. }
  269. cond:
  270. {
  271. $$ = Always;
  272. }
  273. | cond LCOND
  274. {
  275. $$ = ($1 & ~C_SCOND) | $2;
  276. }
  277. | cond LS
  278. {
  279. $$ = $1 | $2;
  280. }
  281. comma:
  282. | ',' comma
  283. rel:
  284. con '(' LPC ')'
  285. {
  286. $$ = nullgen;
  287. $$.type = D_BRANCH;
  288. $$.offset = $1 + pc;
  289. }
  290. | LNAME offset
  291. {
  292. $$ = nullgen;
  293. if(pass == 2)
  294. yyerror("undefined label: %s", $1->name);
  295. $$.type = D_BRANCH;
  296. $$.sym = $1;
  297. $$.offset = $2;
  298. }
  299. | LLAB offset
  300. {
  301. $$ = nullgen;
  302. $$.type = D_BRANCH;
  303. $$.sym = $1;
  304. $$.offset = $1->value + $2;
  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. | '$' '*' '$' oreg
  318. {
  319. $$ = $4;
  320. $$.type = D_OCONST;
  321. }
  322. | '$' LSCONST
  323. {
  324. $$ = nullgen;
  325. $$.type = D_SCONST;
  326. memcpy($$.sval, $2, sizeof($$.sval));
  327. }
  328. | fcon
  329. fcon:
  330. '$' LFCONST
  331. {
  332. $$ = nullgen;
  333. $$.type = D_FCONST;
  334. $$.dval = $2;
  335. }
  336. | '$' '-' LFCONST
  337. {
  338. $$ = nullgen;
  339. $$.type = D_FCONST;
  340. $$.dval = -$3;
  341. }
  342. reglist:
  343. spreg
  344. {
  345. $$ = 1 << $1;
  346. }
  347. | spreg '-' spreg
  348. {
  349. int i;
  350. $$=0;
  351. for(i=$1; i<=$3; i++)
  352. $$ |= 1<<i;
  353. for(i=$3; i<=$1; i++)
  354. $$ |= 1<<i;
  355. }
  356. | spreg comma reglist
  357. {
  358. $$ = (1<<$1) | $3;
  359. }
  360. gen:
  361. reg
  362. | ximm
  363. | shift
  364. | shift '(' spreg ')'
  365. {
  366. $$ = $1;
  367. $$.reg = $3;
  368. }
  369. | LPSR
  370. {
  371. $$ = nullgen;
  372. $$.type = D_PSR;
  373. $$.reg = $1;
  374. }
  375. | LFCR
  376. {
  377. $$ = nullgen;
  378. $$.type = D_FPCR;
  379. $$.reg = $1;
  380. }
  381. | con
  382. {
  383. $$ = nullgen;
  384. $$.type = D_OREG;
  385. $$.offset = $1;
  386. }
  387. | oreg
  388. | freg
  389. nireg:
  390. ireg
  391. | name
  392. {
  393. $$ = $1;
  394. if($1.name != D_EXTERN && $1.name != D_STATIC) {
  395. }
  396. }
  397. ireg:
  398. '(' spreg ')'
  399. {
  400. $$ = nullgen;
  401. $$.type = D_OREG;
  402. $$.reg = $2;
  403. $$.offset = 0;
  404. }
  405. ioreg:
  406. ireg
  407. | con '(' sreg ')'
  408. {
  409. $$ = nullgen;
  410. $$.type = D_OREG;
  411. $$.reg = $3;
  412. $$.offset = $1;
  413. }
  414. oreg:
  415. name
  416. | name '(' sreg ')'
  417. {
  418. $$ = $1;
  419. $$.type = D_OREG;
  420. $$.reg = $3;
  421. }
  422. | ioreg
  423. imsr:
  424. reg
  425. | imm
  426. | shift
  427. imm: '$' con
  428. {
  429. $$ = nullgen;
  430. $$.type = D_CONST;
  431. $$.offset = $2;
  432. }
  433. reg:
  434. spreg
  435. {
  436. $$ = nullgen;
  437. $$.type = D_REG;
  438. $$.reg = $1;
  439. }
  440. regreg:
  441. '(' spreg ',' spreg ')'
  442. {
  443. $$ = nullgen;
  444. $$.type = D_REGREG;
  445. $$.reg = $2;
  446. $$.offset = $4;
  447. }
  448. shift:
  449. spreg '<' '<' rcon
  450. {
  451. $$ = nullgen;
  452. $$.type = D_SHIFT;
  453. $$.offset = $1 | $4 | (0 << 5);
  454. }
  455. | spreg '>' '>' rcon
  456. {
  457. $$ = nullgen;
  458. $$.type = D_SHIFT;
  459. $$.offset = $1 | $4 | (1 << 5);
  460. }
  461. | spreg '-' '>' rcon
  462. {
  463. $$ = nullgen;
  464. $$.type = D_SHIFT;
  465. $$.offset = $1 | $4 | (2 << 5);
  466. }
  467. | spreg LAT '>' rcon
  468. {
  469. $$ = nullgen;
  470. $$.type = D_SHIFT;
  471. $$.offset = $1 | $4 | (3 << 5);
  472. }
  473. rcon:
  474. spreg
  475. {
  476. if($$ < 0 || $$ >= 16)
  477. print("register value out of range\n");
  478. $$ = (($1&15) << 8) | (1 << 4);
  479. }
  480. | con
  481. {
  482. if($$ < 0 || $$ >= 32)
  483. print("shift value out of range\n");
  484. $$ = ($1&31) << 7;
  485. }
  486. sreg:
  487. LREG
  488. | LPC
  489. {
  490. $$ = REGPC;
  491. }
  492. | LR '(' expr ')'
  493. {
  494. if($3 < 0 || $3 >= NREG)
  495. print("register value out of range\n");
  496. $$ = $3;
  497. }
  498. spreg:
  499. sreg
  500. | LSP
  501. {
  502. $$ = REGSP;
  503. }
  504. creg:
  505. LCREG
  506. | LC '(' expr ')'
  507. {
  508. if($3 < 0 || $3 >= NREG)
  509. print("register value out of range\n");
  510. $$ = $3;
  511. }
  512. frcon:
  513. freg
  514. | fcon
  515. freg:
  516. LFREG
  517. {
  518. $$ = nullgen;
  519. $$.type = D_FREG;
  520. $$.reg = $1;
  521. }
  522. | LF '(' con ')'
  523. {
  524. $$ = nullgen;
  525. $$.type = D_FREG;
  526. $$.reg = $3;
  527. }
  528. name:
  529. con '(' pointer ')'
  530. {
  531. $$ = nullgen;
  532. $$.type = D_OREG;
  533. $$.name = $3;
  534. $$.sym = S;
  535. $$.offset = $1;
  536. }
  537. | LNAME offset '(' pointer ')'
  538. {
  539. $$ = nullgen;
  540. $$.type = D_OREG;
  541. $$.name = $4;
  542. $$.sym = $1;
  543. $$.offset = $2;
  544. }
  545. | LNAME '<' '>' offset '(' LSB ')'
  546. {
  547. $$ = nullgen;
  548. $$.type = D_OREG;
  549. $$.name = D_STATIC;
  550. $$.sym = $1;
  551. $$.offset = $4;
  552. }
  553. offset:
  554. {
  555. $$ = 0;
  556. }
  557. | '+' con
  558. {
  559. $$ = $2;
  560. }
  561. | '-' con
  562. {
  563. $$ = -$2;
  564. }
  565. pointer:
  566. LSB
  567. | LSP
  568. | LFP
  569. con:
  570. LCONST
  571. | LVAR
  572. {
  573. $$ = $1->value;
  574. }
  575. | '-' con
  576. {
  577. $$ = -$2;
  578. }
  579. | '+' con
  580. {
  581. $$ = $2;
  582. }
  583. | '~' con
  584. {
  585. $$ = ~$2;
  586. }
  587. | '(' expr ')'
  588. {
  589. $$ = $2;
  590. }
  591. oexpr:
  592. {
  593. $$ = 0;
  594. }
  595. | ',' expr
  596. {
  597. $$ = $2;
  598. }
  599. expr:
  600. con
  601. | expr '+' expr
  602. {
  603. $$ = $1 + $3;
  604. }
  605. | expr '-' expr
  606. {
  607. $$ = $1 - $3;
  608. }
  609. | expr '*' expr
  610. {
  611. $$ = $1 * $3;
  612. }
  613. | expr '/' expr
  614. {
  615. $$ = $1 / $3;
  616. }
  617. | expr '%' expr
  618. {
  619. $$ = $1 % $3;
  620. }
  621. | expr '<' '<' expr
  622. {
  623. $$ = $1 << $4;
  624. }
  625. | expr '>' '>' expr
  626. {
  627. $$ = $1 >> $4;
  628. }
  629. | expr '&' expr
  630. {
  631. $$ = $1 & $3;
  632. }
  633. | expr '^' expr
  634. {
  635. $$ = $1 ^ $3;
  636. }
  637. | expr '|' expr
  638. {
  639. $$ = $1 | $3;
  640. }