a.y 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. %{
  2. #include "a.h"
  3. %}
  4. %union {
  5. Sym *sym;
  6. vlong lval;
  7. double dval;
  8. char sval[8];
  9. Gen gen;
  10. Gen2 gen2;
  11. }
  12. %left '|'
  13. %left '^'
  14. %left '&'
  15. %left '<' '>'
  16. %left '+' '-'
  17. %left '*' '/' '%'
  18. %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
  19. %token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT
  20. %token <lval> LCONST LFP LPC LSB
  21. %token <lval> LBREG LLREG LSREG LFREG LMREG LXREG
  22. %token <dval> LFCONST
  23. %token <sval> LSCONST LSP
  24. %token <sym> LNAME LLAB LVAR
  25. %type <lval> con expr pointer offset
  26. %type <gen> mem imm reg nam rel rem rim rom omem nmem
  27. %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim spec10
  28. %type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
  29. %%
  30. prog:
  31. | prog line
  32. line:
  33. LLAB ':'
  34. {
  35. if($1->value != pc)
  36. yyerror("redeclaration of %s", $1->name);
  37. $1->value = pc;
  38. }
  39. line
  40. | LNAME ':'
  41. {
  42. $1->type = LLAB;
  43. $1->value = pc;
  44. }
  45. line
  46. | ';'
  47. | inst ';'
  48. | error ';'
  49. inst:
  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. | LTYPE0 nonnon { outcode($1, &$2); }
  62. | LTYPE1 nonrem { outcode($1, &$2); }
  63. | LTYPE2 rimnon { outcode($1, &$2); }
  64. | LTYPE3 rimrem { outcode($1, &$2); }
  65. | LTYPE4 remrim { outcode($1, &$2); }
  66. | LTYPER nonrel { outcode($1, &$2); }
  67. | LTYPED spec1 { outcode($1, &$2); }
  68. | LTYPET spec2 { outcode($1, &$2); }
  69. | LTYPEC spec3 { outcode($1, &$2); }
  70. | LTYPEN spec4 { outcode($1, &$2); }
  71. | LTYPES spec5 { outcode($1, &$2); }
  72. | LTYPEM spec6 { outcode($1, &$2); }
  73. | LTYPEI spec7 { outcode($1, &$2); }
  74. | LTYPEXC spec8 { outcode($1, &$2); }
  75. | LTYPEX spec9 { outcode($1, &$2); }
  76. | LTYPERT spec10 { outcode($1, &$2); }
  77. nonnon:
  78. {
  79. $$.from = nullgen;
  80. $$.to = nullgen;
  81. }
  82. | ','
  83. {
  84. $$.from = nullgen;
  85. $$.to = nullgen;
  86. }
  87. rimrem:
  88. rim ',' rem
  89. {
  90. $$.from = $1;
  91. $$.to = $3;
  92. }
  93. remrim:
  94. rem ',' rim
  95. {
  96. $$.from = $1;
  97. $$.to = $3;
  98. }
  99. rimnon:
  100. rim ','
  101. {
  102. $$.from = $1;
  103. $$.to = nullgen;
  104. }
  105. | rim
  106. {
  107. $$.from = $1;
  108. $$.to = nullgen;
  109. }
  110. nonrem:
  111. ',' rem
  112. {
  113. $$.from = nullgen;
  114. $$.to = $2;
  115. }
  116. | rem
  117. {
  118. $$.from = nullgen;
  119. $$.to = $1;
  120. }
  121. nonrel:
  122. ',' rel
  123. {
  124. $$.from = nullgen;
  125. $$.to = $2;
  126. }
  127. | rel
  128. {
  129. $$.from = nullgen;
  130. $$.to = $1;
  131. }
  132. spec1: /* DATA */
  133. nam '/' con ',' imm
  134. {
  135. $$.from = $1;
  136. $$.from.scale = $3;
  137. $$.to = $5;
  138. }
  139. spec2: /* TEXT */
  140. mem ',' imm
  141. {
  142. $$.from = $1;
  143. $$.to = $3;
  144. }
  145. | mem ',' con ',' imm
  146. {
  147. $$.from = $1;
  148. $$.from.scale = $3;
  149. $$.to = $5;
  150. }
  151. spec3: /* JMP/CALL */
  152. ',' rom
  153. {
  154. $$.from = nullgen;
  155. $$.to = $2;
  156. }
  157. | rom
  158. {
  159. $$.from = nullgen;
  160. $$.to = $1;
  161. }
  162. spec4: /* NOP */
  163. nonnon
  164. | nonrem
  165. spec5: /* SHL/SHR */
  166. rim ',' rem
  167. {
  168. $$.from = $1;
  169. $$.to = $3;
  170. }
  171. | rim ',' rem ':' LLREG
  172. {
  173. $$.from = $1;
  174. $$.to = $3;
  175. if($$.from.index != D_NONE)
  176. yyerror("dp shift with lhs index");
  177. $$.from.index = $5;
  178. }
  179. spec6: /* MOVW/MOVL */
  180. rim ',' rem
  181. {
  182. $$.from = $1;
  183. $$.to = $3;
  184. }
  185. | rim ',' rem ':' LSREG
  186. {
  187. $$.from = $1;
  188. $$.to = $3;
  189. if($$.to.index != D_NONE)
  190. yyerror("dp move with lhs index");
  191. $$.to.index = $5;
  192. }
  193. spec7:
  194. rim ','
  195. {
  196. $$.from = $1;
  197. $$.to = nullgen;
  198. }
  199. | rim
  200. {
  201. $$.from = $1;
  202. $$.to = nullgen;
  203. }
  204. | rim ',' rem
  205. {
  206. $$.from = $1;
  207. $$.to = $3;
  208. }
  209. spec8: /* CMPPS/CMPPD */
  210. reg ',' rem ',' con
  211. {
  212. $$.from = $1;
  213. $$.to = $3;
  214. $$.from.offset = $5;
  215. }
  216. spec9: /* shufl */
  217. imm ',' rem ',' reg
  218. {
  219. $$.from = $3;
  220. $$.to = $5;
  221. if($1.type != D_CONST)
  222. yyerror("illegal constant");
  223. $$.to.offset = $1.offset;
  224. }
  225. spec10: /* RET/RETF */
  226. {
  227. $$.from = nullgen;
  228. $$.to = nullgen;
  229. }
  230. | imm
  231. {
  232. $$.from = $1;
  233. $$.to = nullgen;
  234. }
  235. rem:
  236. reg
  237. | mem
  238. rom:
  239. rel
  240. | nmem
  241. | '*' reg
  242. {
  243. $$ = $2;
  244. }
  245. | '*' omem
  246. {
  247. $$ = $2;
  248. }
  249. | reg
  250. | omem
  251. rim:
  252. rem
  253. | imm
  254. rel:
  255. con '(' LPC ')'
  256. {
  257. $$ = nullgen;
  258. $$.type = D_BRANCH;
  259. $$.offset = $1 + pc;
  260. }
  261. | LNAME offset
  262. {
  263. $$ = nullgen;
  264. if(pass == 2)
  265. yyerror("undefined label: %s", $1->name);
  266. $$.type = D_BRANCH;
  267. $$.sym = $1;
  268. $$.offset = $2;
  269. }
  270. | LLAB offset
  271. {
  272. $$ = nullgen;
  273. $$.type = D_BRANCH;
  274. $$.sym = $1;
  275. $$.offset = $1->value + $2;
  276. }
  277. reg:
  278. LBREG
  279. {
  280. $$ = nullgen;
  281. $$.type = $1;
  282. }
  283. | LFREG
  284. {
  285. $$ = nullgen;
  286. $$.type = $1;
  287. }
  288. | LLREG
  289. {
  290. $$ = nullgen;
  291. $$.type = $1;
  292. }
  293. | LMREG
  294. {
  295. $$ = nullgen;
  296. $$.type = $1;
  297. }
  298. | LSP
  299. {
  300. $$ = nullgen;
  301. $$.type = D_SP;
  302. }
  303. | LSREG
  304. {
  305. $$ = nullgen;
  306. $$.type = $1;
  307. }
  308. | LXREG
  309. {
  310. $$ = nullgen;
  311. $$.type = $1;
  312. }
  313. imm:
  314. '$' con
  315. {
  316. $$ = nullgen;
  317. $$.type = D_CONST;
  318. $$.offset = $2;
  319. }
  320. | '$' nam
  321. {
  322. $$ = $2;
  323. $$.index = $2.type;
  324. $$.type = D_ADDR;
  325. /*
  326. if($2.type == D_AUTO || $2.type == D_PARAM)
  327. yyerror("constant cannot be automatic: %s",
  328. $2.sym->name);
  329. */
  330. }
  331. | '$' LSCONST
  332. {
  333. $$ = nullgen;
  334. $$.type = D_SCONST;
  335. memcpy($$.sval, $2, sizeof($$.sval));
  336. }
  337. | '$' LFCONST
  338. {
  339. $$ = nullgen;
  340. $$.type = D_FCONST;
  341. $$.dval = $2;
  342. }
  343. | '$' '(' LFCONST ')'
  344. {
  345. $$ = nullgen;
  346. $$.type = D_FCONST;
  347. $$.dval = $3;
  348. }
  349. | '$' '-' LFCONST
  350. {
  351. $$ = nullgen;
  352. $$.type = D_FCONST;
  353. $$.dval = -$3;
  354. }
  355. mem:
  356. omem
  357. | nmem
  358. omem:
  359. con
  360. {
  361. $$ = nullgen;
  362. $$.type = D_INDIR+D_NONE;
  363. $$.offset = $1;
  364. }
  365. | con '(' LLREG ')'
  366. {
  367. $$ = nullgen;
  368. $$.type = D_INDIR+$3;
  369. $$.offset = $1;
  370. }
  371. | con '(' LSP ')'
  372. {
  373. $$ = nullgen;
  374. $$.type = D_INDIR+D_SP;
  375. $$.offset = $1;
  376. }
  377. | con '(' LLREG '*' con ')'
  378. {
  379. $$ = nullgen;
  380. $$.type = D_INDIR+D_NONE;
  381. $$.offset = $1;
  382. $$.index = $3;
  383. $$.scale = $5;
  384. checkscale($$.scale);
  385. }
  386. | con '(' LLREG ')' '(' LLREG '*' con ')'
  387. {
  388. $$ = nullgen;
  389. $$.type = D_INDIR+$3;
  390. $$.offset = $1;
  391. $$.index = $6;
  392. $$.scale = $8;
  393. checkscale($$.scale);
  394. }
  395. | '(' LLREG ')'
  396. {
  397. $$ = nullgen;
  398. $$.type = D_INDIR+$2;
  399. }
  400. | '(' LSP ')'
  401. {
  402. $$ = nullgen;
  403. $$.type = D_INDIR+D_SP;
  404. }
  405. | '(' LLREG '*' con ')'
  406. {
  407. $$ = nullgen;
  408. $$.type = D_INDIR+D_NONE;
  409. $$.index = $2;
  410. $$.scale = $4;
  411. checkscale($$.scale);
  412. }
  413. | '(' LLREG ')' '(' LLREG '*' con ')'
  414. {
  415. $$ = nullgen;
  416. $$.type = D_INDIR+$2;
  417. $$.index = $5;
  418. $$.scale = $7;
  419. checkscale($$.scale);
  420. }
  421. nmem:
  422. nam
  423. {
  424. $$ = $1;
  425. }
  426. | nam '(' LLREG '*' con ')'
  427. {
  428. $$ = $1;
  429. $$.index = $3;
  430. $$.scale = $5;
  431. checkscale($$.scale);
  432. }
  433. nam:
  434. LNAME offset '(' pointer ')'
  435. {
  436. $$ = nullgen;
  437. $$.type = $4;
  438. $$.sym = $1;
  439. $$.offset = $2;
  440. }
  441. | LNAME '<' '>' offset '(' LSB ')'
  442. {
  443. $$ = nullgen;
  444. $$.type = D_STATIC;
  445. $$.sym = $1;
  446. $$.offset = $4;
  447. }
  448. offset:
  449. {
  450. $$ = 0;
  451. }
  452. | '+' con
  453. {
  454. $$ = $2;
  455. }
  456. | '-' con
  457. {
  458. $$ = -$2;
  459. }
  460. pointer:
  461. LSB
  462. | LSP
  463. {
  464. $$ = D_AUTO;
  465. }
  466. | LFP
  467. con:
  468. LCONST
  469. | LVAR
  470. {
  471. $$ = $1->value;
  472. }
  473. | '-' con
  474. {
  475. $$ = -$2;
  476. }
  477. | '+' con
  478. {
  479. $$ = $2;
  480. }
  481. | '~' con
  482. {
  483. $$ = ~$2;
  484. }
  485. | '(' expr ')'
  486. {
  487. $$ = $2;
  488. }
  489. expr:
  490. con
  491. | expr '+' expr
  492. {
  493. $$ = $1 + $3;
  494. }
  495. | expr '-' expr
  496. {
  497. $$ = $1 - $3;
  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. }
  511. | expr '<' '<' expr
  512. {
  513. $$ = $1 << $4;
  514. }
  515. | expr '>' '>' expr
  516. {
  517. $$ = $1 >> $4;
  518. }
  519. | expr '&' expr
  520. {
  521. $$ = $1 & $3;
  522. }
  523. | expr '^' expr
  524. {
  525. $$ = $1 ^ $3;
  526. }
  527. | expr '|' expr
  528. {
  529. $$ = $1 | $3;
  530. }