cgg.y 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. %{
  6. #include <stdio.h>
  7. #include "param.h"
  8. #include "varinfo.h"
  9. #include "lookup.h"
  10. #include "set.h"
  11. #include "iocc.h"
  12. #include "instruct.h"
  13. #include "expr.h"
  14. #include "output.h"
  15. #include "extern.h"
  16. #include "strlookup.h"
  17. #include <cgg_cg.h>
  18. #include <em_reg.h>
  19. #include "subr.h"
  20. #include "coerc.h"
  21. #include "hall.h"
  22. #include "error.h"
  23. #include "emlookup.h"
  24. extern int lineno;
  25. int instline,saveline;
  26. int startline;
  27. int npatterns;
  28. int att_type;
  29. int patindex[MAXPATTERNS];
  30. extern set_t l_sets[];
  31. void skipupto(int tok, char *str);
  32. int emhere=0; /* lexical analyzer flag */
  33. int optexact=0; /* Inside "with exact" rule */
  34. int optstack=0; /* Inside with <blah> STACK rule */
  35. int saferulefound=0;
  36. int maxrule=0;
  37. int in_em_repl=0; /* set when in EM replacement part */
  38. struct varinfo *defcost;
  39. int Xstackflag=0; /* set in coercions, moves, and tests. %1 means something
  40. different then.
  41. */
  42. /* From lexer */
  43. int yylex(void);
  44. struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
  45. struct varinfo *gen_label(), *make_erase();
  46. expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
  47. expr_t perc_ident_expr(),sum_expr(),regvar_expr();
  48. set_t ident_to_set(),setproduct(),setsum(),setdiff();
  49. iocc_t subr_iocc(),tokm_iocc(),ident_iocc(),all_iocc(),percident_iocc(), descr_iocc();
  50. extern int narexpr;
  51. extern expr_t arexp[];
  52. int niops;
  53. iocc_t iops[20];
  54. %}
  55. %union {
  56. int yy_int;
  57. char * yy_str;
  58. varinfo * yy_varinfo;
  59. set_t yy_set;
  60. operand *yy_oplist;
  61. expr_t yy_expr;
  62. iocc_t yy_iocc;
  63. }
  64. %token PROPERTIES
  65. %token REGISTERS
  66. %token TOKENS
  67. %token SETS
  68. %token MOVES
  69. %token TESTS
  70. %token STACKINGRULES COERCIONS
  71. %token INSTRUCTIONS
  72. %token TOPELTSIZE FALLTHROUGH LABELDEF
  73. %token PROC CALL EXAMPLE
  74. %token FROM TO
  75. %token TEST MOVE STACK RETURN
  76. %token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
  77. %token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW ISROM
  78. %token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
  79. %token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
  80. %token <yy_int> ADORNACCESS
  81. %token <yy_int> ADORNCC
  82. %token INT
  83. %token ADDR
  84. %token <yy_int> EMMNEM
  85. %token <yy_int> NUMBER
  86. %token <yy_int> DOLLAR PERCENT ALLREG
  87. %token <yy_str> IDENT PERC_IDENT
  88. %token <yy_str> STRING
  89. %token TIMEFACTOR SIZEFACTOR
  90. %token COST
  91. %type <yy_varinfo> prop_list property ident_list ident_list_el
  92. %type <yy_varinfo> att_list att_list_el att_list_el_list att_ident structdecl optcost optformat
  93. %type <yy_varinfo> kills allocates yields leaving
  94. %type <yy_varinfo> generates kill_list kill_list_el uselist uselist_el genlist yieldlist
  95. %type <yy_varinfo> leavelist leavelist_el gen_instruction
  96. %type <yy_varinfo> opt_erase_list erase_list erase_list_el
  97. %type <yy_str> opt_par_string optstring
  98. %type <yy_int> register propno att_list_el_type tokenset_no
  99. %type <yy_int> adornlist optstar optuses optregvar regvartype optregvartype
  100. %type <yy_int> emarg tokarg subreg allreg
  101. %type <yy_expr> expr regvarexpr
  102. %type <yy_iocc> tokeninstance
  103. %type <yy_int> optexpr optexact optstack
  104. %type <yy_set> tokenset
  105. %type <yy_oplist> oplist oplist_el
  106. %left OR2
  107. %left AND2
  108. %left '|'
  109. %left '^'
  110. %left '&'
  111. %left CMPEQ CMPNE
  112. %left CMPLT CMPLE CMPGT CMPGE
  113. %left RSHIFT LSHIFT
  114. %left '+' '-'
  115. %left '*' '/' '%'
  116. %nonassoc NOT COMP UMINUS
  117. %start machtable
  118. %%
  119. /*
  120. * The machine table consists of a number of sections, with their
  121. * own associated parsers.
  122. */
  123. machtable
  124. : constants
  125. properties
  126. registers
  127. tokens
  128. { make_std_sets(); }
  129. sets
  130. instructions
  131. moves
  132. tests
  133. stacks
  134. coercs
  135. code
  136. ;
  137. /*
  138. * Constants are parsed as name=value pairs
  139. */
  140. constants
  141. : constdeflist
  142. ;
  143. constdeflist
  144. : /* empty */
  145. | constdeflist constdef
  146. ;
  147. constdef
  148. : IDENT'=' NUMBER
  149. { n_const($1,$3); free($1); }
  150. | IDENT '=' STRING
  151. { n_sconst($1,$3); free($1); free($3); }
  152. | TIMEFACTOR '=' NUMBER '/' NUMBER
  153. { fc1 = $3; fc2 = $5; }
  154. | SIZEFACTOR '=' NUMBER '/' NUMBER
  155. { fc3 = $3; fc4 = $5; }
  156. | error
  157. ;
  158. /*
  159. * Properties are parsed as a list of names optionally followed by their size
  160. */
  161. properties
  162. : PROPERTIES { make_const(); } prdef_list
  163. ;
  164. prdef_list
  165. : prdef_list_el
  166. | prdef_list optcomma prdef_list_el
  167. ;
  168. prdef_list_el
  169. : IDENT
  170. { n_prop($1,wordsize); free($1); }
  171. | IDENT '(' NUMBER ')'
  172. { n_prop($1,$3); free($1); }
  173. ;
  174. /*
  175. * Registers are rows of reglist:proplist pairs
  176. */
  177. registers
  178. : REGISTERS regdef_list
  179. ;
  180. regdef_list
  181. : regdef_list_el
  182. | regdef_list regdef_list_el
  183. ;
  184. regdef_list_el
  185. : ident_list ':' prop_list optregvar '.'
  186. { regline($1,$3,$4); free((char *) $1); free((char *) $3); }
  187. | error '.'
  188. ;
  189. optregvar
  190. : /* empty */
  191. { $$ = -1; }
  192. | REGVAR
  193. { $$ = reg_any; }
  194. | REGVAR '(' regvartype ')'
  195. { $$ = $3; }
  196. ;
  197. regvartype
  198. : REG_ANY
  199. { $$ = reg_any;}
  200. | REG_FLOAT
  201. { $$ = reg_float;}
  202. | REG_LOOP
  203. { $$ = reg_loop;}
  204. | REG_POINTER
  205. { $$ = reg_pointer;}
  206. ;
  207. ident_list
  208. : ident_list_el
  209. | ident_list optcomma ident_list_el
  210. { $3->vi_next = $1; $$ = $3; }
  211. ;
  212. ident_list_el
  213. : IDENT opt_par_string
  214. { NEW($$,struct varinfo);
  215. $$->vi_next = 0;
  216. $$->vi_int[0] = n_reg($1,$2,0,0,0);
  217. free($1); if($2!=0) free($2);
  218. }
  219. | IDENT opt_par_string '=' register
  220. { NEW($$,struct varinfo);
  221. $$->vi_next = 0;
  222. $$->vi_int[0] = n_reg($1,$2,1,$4,0);
  223. free($1); if($2!=0) free($2);
  224. }
  225. | IDENT opt_par_string '=' register '+' register
  226. { NEW($$,struct varinfo);
  227. $$->vi_next = 0;
  228. $$->vi_int[0] = n_reg($1,$2,2,$4,$6);
  229. free($1); if($2!=0) free($2);
  230. }
  231. ;
  232. opt_par_string
  233. : /* empty */
  234. { $$ = 0; }
  235. | '(' STRING ')'
  236. { $$ = $2; }
  237. ;
  238. register
  239. : IDENT
  240. { register symbol *sy_p;
  241. sy_p = lookup($1,symreg,mustexist);
  242. $$ = sy_p->sy_value.syv_regno;
  243. free($1);
  244. }
  245. ;
  246. prop_list
  247. : property
  248. | prop_list optcomma property
  249. { $3->vi_next = $1; $$ = $3; }
  250. ;
  251. property
  252. : IDENT
  253. { register symbol *sy_p;
  254. sy_p = lookup($1,symprop,mustexist);
  255. NEW($$,struct varinfo);
  256. $$->vi_next=0;
  257. $$->vi_int[0]=sy_p->sy_value.syv_propno;
  258. free($1);
  259. }
  260. ;
  261. propno
  262. : IDENT
  263. { register symbol *sy_p;
  264. sy_p = lookup($1,symprop,mustexist);
  265. $$ = sy_p->sy_value.syv_propno;
  266. free($1);
  267. }
  268. ;
  269. /* tokens are parsed as struct definitions
  270. * types in the struct can be register properties, ADDR or INT
  271. */
  272. tokens
  273. : TOKENS tokdeflist
  274. ;
  275. tokdeflist
  276. : tokdeflist_el
  277. | tokdeflist tokdeflist_el
  278. ;
  279. tokdeflist_el
  280. : IDENT '=' structdecl NUMBER optcost optformat '.'
  281. { n_tok($1,$3,$4,$5,$6);
  282. free($1);
  283. freevi($3);
  284. freevi($5);
  285. freevi($6);
  286. }
  287. | error '.'
  288. ;
  289. structdecl
  290. : '{' att_list '}'
  291. { $$ = $2; }
  292. ;
  293. att_list
  294. : /* empty */
  295. { $$ = 0; }
  296. | att_list_el att_list
  297. { $$ = $1; while ($$->vi_next) $$ = $$->vi_next;
  298. $$->vi_next = $2; $$ = $1;
  299. }
  300. ;
  301. att_list_el
  302. : att_list_el_type
  303. { att_type = $1; }
  304. att_list_el_list
  305. ';'
  306. { $$ = $3; }
  307. ;
  308. att_list_el_list
  309. : att_ident
  310. | att_ident ',' att_list_el_list
  311. { $1->vi_next = $3; $$ = $1; }
  312. ;
  313. att_ident
  314. : IDENT
  315. { NEW($$, struct varinfo);
  316. $$->vi_next = 0;
  317. $$->vi_int[0] = att_type;
  318. $$->vi_str[0] = $1;
  319. }
  320. ;
  321. att_list_el_type
  322. : INT
  323. { $$ = -1; }
  324. | ADDR
  325. { $$ = -2; }
  326. | propno
  327. ;
  328. optcost
  329. :
  330. { if (defcost==VI_NULL)
  331. $$=VI_NULL;
  332. else {
  333. NEW($$,struct varinfo);
  334. *$$ = *defcost;
  335. }
  336. }
  337. | COST '(' NUMBER ',' NUMBER ')'
  338. { NEW ($$,struct varinfo);
  339. $$->vi_int[0] = $3;
  340. $$->vi_int[1] = $5;
  341. }
  342. ;
  343. optformat
  344. :
  345. { $$ = 0; }
  346. | STRING optformat
  347. { NEW($$,struct varinfo);
  348. $$->vi_next = $2;
  349. $$->vi_int[0] = 0;
  350. $$->vi_str[0] = $1;
  351. }
  352. | IDENT optformat
  353. { NEW($$,struct varinfo);
  354. $$->vi_next = $2;
  355. $$->vi_int[0] = 1;
  356. $$->vi_str[0] = $1;
  357. }
  358. ;
  359. optcomma
  360. : ','
  361. | /* empty */
  362. ;
  363. /* sets are parsed as ident = expression */
  364. sets
  365. : SETS setdeflist
  366. ;
  367. setdeflist
  368. : setdeflist_el
  369. | setdeflist setdeflist_el
  370. ;
  371. setdeflist_el
  372. : IDENT '=' tokenset_no '.'
  373. { n_set($1,$3); free($1); }
  374. | error '.'
  375. ;
  376. tokenset_no
  377. : tokenset
  378. { $$ = setlookup($1); }
  379. ;
  380. tokenset
  381. : IDENT
  382. { $$ = ident_to_set($1); free($1); }
  383. | tokenset '*' tokenset
  384. { $$ = setproduct($1,$3); }
  385. | tokenset '+' tokenset
  386. { $$ = setsum($1,$3); }
  387. | tokenset '-' tokenset
  388. { $$ = setdiff($1,$3); }
  389. | '(' tokenset ')'
  390. { $$ = $2; }
  391. ;
  392. instructions
  393. : INSTRUCTIONS optcost instdef_list
  394. { defcost = $2; }
  395. ;
  396. instdef_list
  397. : instdef_list_el
  398. | instdef_list instdef_list_el
  399. ;
  400. instdef_list_el
  401. : IDENT optstring oplist opt_erase_list optcost '.'
  402. { n_instr($1,$2,$3,$4,$5); freevi($5); }
  403. | error '.'
  404. ;
  405. oplist
  406. : /* empty */
  407. { $$ = 0; }
  408. | oplist_el
  409. | oplist_el ',' oplist
  410. { $$ = $1; $$->o_next = $3; }
  411. ;
  412. oplist_el
  413. : tokenset_no adornlist
  414. { NEW($$,struct operand);
  415. $$->o_next = 0 ;
  416. $$->o_setno = $1;
  417. $$->o_adorn = $2;
  418. checkprintformat($1);
  419. }
  420. ;
  421. adornlist
  422. : /* empty */
  423. { $$ = 0; }
  424. | ADORNACCESS adornlist
  425. { if ($2&AD_RWMASK)
  426. error("Only one of :ro,:wo,:rw allowed");
  427. $$ = $1 | $2;
  428. }
  429. | ADORNCC adornlist
  430. { $$ = $1|$2; }
  431. ;
  432. opt_erase_list
  433. : /* empty */
  434. { $$ = VI_NULL;}
  435. | KILLS erase_list
  436. { $$ = $2; }
  437. ;
  438. erase_list
  439. : erase_list_el
  440. { $$ = $1; }
  441. | erase_list_el erase_list
  442. { $1->vi_next = $2; $$ = $1; }
  443. ;
  444. erase_list_el
  445. : IDENT
  446. { $$ = make_erase($1); }
  447. | ADORNCC
  448. { NEW($$, struct varinfo);
  449. $$->vi_int[0] = -1;
  450. $$->vi_next = VI_NULL;
  451. }
  452. ;
  453. /* Now the moves */
  454. moves
  455. : MOVES
  456. movedeflist
  457. | /* empty */
  458. ;
  459. movedeflist
  460. : movedeflist_el
  461. | movedeflist movedeflist_el
  462. ;
  463. movedeflist_el
  464. : FROM
  465. {startline = lineno; }
  466. tokenset_no
  467. { Xstackflag = 1;
  468. cursetno = $3;
  469. }
  470. optexpr
  471. { Xstackflag = 0;
  472. cursetno = -1;
  473. }
  474. TO tokenset_no
  475. { cursetno = $8;
  476. tokpatlen=2;
  477. tokpatset[0] = $3;
  478. tokpatset[1] = $8;
  479. tokpatro[0] = 1;
  480. Xstackflag = 1;
  481. }
  482. optexpr
  483. { Xstackflag = 0;
  484. cursetno = -1;
  485. }
  486. GEN genlist
  487. { tokpatlen=0;
  488. tokpatro[0]=0;
  489. n_move($3,$5,$8,$10,$13);
  490. freevi($13);
  491. }
  492. | error
  493. ;
  494. /* Now the test part */
  495. tests
  496. : TESTS
  497. { Xstackflag = 1; }
  498. testdeflist
  499. { Xstackflag = 0; }
  500. | /* empty */
  501. ;
  502. testdeflist
  503. : testdeflist_el
  504. | testdeflist testdeflist_el
  505. ;
  506. testdeflist_el
  507. : TO
  508. { startline = lineno;}
  509. TEST tokenset_no
  510. { cursetno = $4;
  511. tokpatlen=1;
  512. tokpatset[0]=$4;
  513. tokpatro[0] = 1;
  514. }
  515. optexpr GEN genlist
  516. { tokpatlen=0;
  517. tokpatro[0] = 0;
  518. n_test($4,$6,$8);
  519. freevi($8);
  520. cursetno = -1;
  521. }
  522. | error
  523. ;
  524. /* Now the stacks */
  525. stacks
  526. : STACKINGRULES
  527. { Xstackflag = 1; }
  528. stackdeflist
  529. { Xstackflag = 0; }
  530. ;
  531. stackdeflist
  532. : stackdeflist_el
  533. | stackdeflist stackdeflist_el
  534. ;
  535. stackdeflist_el
  536. : FROM
  537. {startline = lineno;}
  538. tokenset_no
  539. { cursetno = $3;
  540. tokpatlen=1;
  541. tokpatset[0] = $3;
  542. tokpatro[0] = 1;
  543. }
  544. optexpr TO STACK optuses GEN genlist
  545. { tokpatro[0] = 0;
  546. n_stack($3,$5,$8,$10);
  547. freevi($10);
  548. cursetno = -1;
  549. }
  550. ;
  551. optuses
  552. : /* empty */
  553. { $$ = -1; nallreg=0;}
  554. | USES propno
  555. { $$ = $2; nallreg = 1; allreg[0] = $2; }
  556. ;
  557. /* Now the one-to-one coercion rules */
  558. coercs
  559. : COERCIONS
  560. { Xstackflag = 1; }
  561. coercdeflist
  562. { Xstackflag = 0; }
  563. ;
  564. coercdeflist
  565. : coercdeflist_el
  566. | coercdeflist coercdeflist_el
  567. ;
  568. coercdeflist_el
  569. : FROM
  570. {startline = lineno; tokpatlen=0; inithall();}
  571. STACK allocates generates YIELDS tokeninstance
  572. { checkhall();
  573. n_coerc(0,0,$4,$5,(struct varinfo *) 0,$7);
  574. freevi($4);
  575. freevi($5);
  576. }
  577. | FROM
  578. {startline = lineno;}
  579. tokenset_no
  580. { cursetno = $3;
  581. tokpatlen=1;
  582. tokpatset[0]=$3;
  583. tokpatro[0] = 1;
  584. inithall();
  585. }
  586. optexpr allocates generates yields
  587. {
  588. iocc_t empty; /* WARNING */
  589. tokpatro[0] = 0;
  590. checkhall();
  591. n_coerc($3,$5,$6,$7,$8, empty);
  592. freevi($6);
  593. freevi($7);
  594. cursetno = -1;
  595. }
  596. ;
  597. /* Now the code part */
  598. code
  599. : PATTERNS coderules
  600. ;
  601. coderules
  602. : coderule
  603. | coderules coderule
  604. ;
  605. coderule
  606. : PAT {emhere=1;} empattern {emhere=0;} optexpr
  607. { empatexpr = $5;
  608. npatterns = 0;
  609. saferulefound=0;
  610. if (empatlen>maxempatlen)
  611. maxempatlen=empatlen;
  612. }
  613. patterns
  614. { if (!saferulefound)
  615. error("Previous rule impossible on empty stack");
  616. outpatterns();
  617. }
  618. | PROC IDENT example
  619. { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); }
  620. patterns
  621. { if (!saferulefound)
  622. error("Previous rule impossible on empty stack");
  623. outpatterns(); inproc=0;
  624. }
  625. | error
  626. { skipupto(PAT,"pat"); yyerrok; yyclearin; }
  627. ;
  628. example
  629. : /* empty */
  630. { empatlen = 0; }
  631. | EXAMPLE {emhere=1;} empattern {emhere=0;}
  632. ;
  633. empattern
  634. : EMMNEM
  635. { empatlen = 1; emmnem[0] = $1; }
  636. | empattern EMMNEM
  637. { NEXT(empatlen,EMPATMAX,"Em pattern");
  638. emmnem[empatlen-1] = $2;
  639. }
  640. ;
  641. patterns
  642. : onepattern
  643. { saferulefound=1;
  644. callproc=0;
  645. }
  646. | morepatterns
  647. { callproc=0;
  648. if (npatterns>maxrule)
  649. maxrule=npatterns;
  650. }
  651. | CALL IDENT '(' stringlist ')'
  652. { register symbol *sy_p;
  653. saferulefound=1;
  654. sy_p=lookup($2,symproc,mustexist);
  655. callproc=sy_p->sy_value.syv_procoff;
  656. free($2);
  657. if (nprocargs > maxprocargs) maxprocargs = nprocargs;
  658. }
  659. ;
  660. stringlist
  661. : STRING
  662. { nprocargs = 1; procarg[0] = strlookup($1); free($1); }
  663. | stringlist ',' STRING
  664. { NEXT(nprocargs, MAXPROCARG, "Procedure argument list");
  665. procarg[nprocargs-1] = strlookup($3); free($3);
  666. }
  667. ;
  668. onepattern
  669. : { inithall(); startline=lineno;
  670. tokpatlen=0; optexact=0; optstack=0;
  671. }
  672. kills allocates generates yields leaving
  673. {
  674. patindex[npatterns++]=codeindex;
  675. checkhall();
  676. dopattern(0,$2,$3,$4,$5,$6);
  677. freevi($2);
  678. freevi($3);
  679. freevi($4);
  680. freevi($5);
  681. freevi($6);
  682. }
  683. ;
  684. morepatterns
  685. : { inithall(); } pattern
  686. | morepatterns { inithall(); } pattern
  687. ;
  688. pattern
  689. : stackpattern kills allocates generates yields leaving
  690. { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex;
  691. if (hall() && !optexact) saferulefound=1;
  692. dopattern(0,$2,$3,$4,$5,$6);
  693. freevi($2);
  694. freevi($3);
  695. freevi($4);
  696. freevi($5);
  697. freevi($6);
  698. }
  699. ;
  700. stackpattern
  701. : WITH optexact
  702. { startline = lineno; }
  703. setlist optstack
  704. { if (tokpatlen > maxtokpatlen) maxtokpatlen = tokpatlen; }
  705. ;
  706. optexact
  707. : /* empty */
  708. { $$ = optexact = 0; }
  709. | EXACT
  710. { $$ = optexact = 1; }
  711. ;
  712. optstack
  713. : /* empty */
  714. { $$ = optstack = 0; }
  715. | STACK
  716. { $$ = optstack = 1; }
  717. ;
  718. setlist
  719. : /* empty */
  720. { tokpatlen = 0; }
  721. | setlist tokenset_no
  722. { NEXT(tokpatlen,TOKPATMAX,"Stack pattern");
  723. tokpatset[tokpatlen-1] = $2;
  724. checkunstacking($2);
  725. if (l_sets[$2].set_size == 0) {
  726. error("Tokenset is empty or has elements with different sizes");
  727. }
  728. }
  729. ;
  730. kills
  731. : /* empty */
  732. { $$ = 0; }
  733. | KILLS kill_list
  734. { $$ = $2;
  735. }
  736. ;
  737. kill_list
  738. : kill_list_el
  739. | kill_list_el ',' kill_list
  740. { $$=$1; $$->vi_next = $3; }
  741. ;
  742. kill_list_el
  743. : tokenset_no { cursetno=$1; } optexpr
  744. { NEW($$,struct varinfo);
  745. $$->vi_next = 0;
  746. $$->vi_int[0]=$1;
  747. $$->vi_int[1]=$3;
  748. cursetno = -1;
  749. }
  750. | regvarexpr
  751. { NEW($$,struct varinfo);
  752. $$->vi_next = 0;
  753. $$->vi_int[0] = -($1.ex_index + 1);
  754. $$->vi_int[1] = 0;
  755. }
  756. ;
  757. allocates
  758. : /* empty */
  759. { $$ = 0; nallreg=0;}
  760. | USES uselist
  761. { $$ = $2; setallreg($2); }
  762. ;
  763. uselist
  764. : uselist_el
  765. { prophall($1->vi_int[0]); }
  766. | uselist_el ',' uselist
  767. { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; }
  768. ;
  769. uselist_el
  770. : property
  771. { $$=$1; $$->vi_int[1] = 0; }
  772. | property '=' tokeninstance
  773. { if (!existalmove($3,$$->vi_int[0]))
  774. error("No such move defined");
  775. $$=$1; $$->vi_int[1] = $3.in_index;
  776. }
  777. | REUSING tokeninstance
  778. { NEW($$,struct varinfo);
  779. $$->vi_next = 0;
  780. $$->vi_int[0] = -1;
  781. $$->vi_int[1] = $2.in_index;
  782. }
  783. ;
  784. generates
  785. : /* empty */
  786. { $$ = 0; }
  787. | GEN genlist
  788. { $$ = $2; }
  789. ;
  790. genlist
  791. : /* empty */
  792. { $$ = 0; }
  793. | gen_instruction genlist
  794. { if ($1!=0) {
  795. register struct varinfo *tvip;
  796. $$=tvip=$1;
  797. while (tvip->vi_next!=VI_NULL)
  798. tvip=tvip->vi_next;
  799. tvip->vi_next = $2;
  800. } else {
  801. $$ = $2;
  802. }
  803. }
  804. ;
  805. gen_instruction
  806. : {instline = lineno; } IDENT optstar gen_oplist
  807. { saveline =lineno; lineno=instline;
  808. $$ = gen_inst($2,$3); free($2);
  809. lineno = saveline;
  810. }
  811. | NUMBER ':'
  812. { $$ = gen_tlab($1); }
  813. | MOVE tokeninstance ',' tokeninstance
  814. { $$ = gen_move($2,$4); }
  815. | TEST tokeninstance
  816. { $$ = gen_test($2);}
  817. | LABELDEF emarg
  818. { $$ = gen_label($2-1); use_tes++; }
  819. | RETURN
  820. { $$ = gen_preturn(); }
  821. ;
  822. optstar
  823. : /* empty */
  824. { $$=0; }
  825. | '*'
  826. { $$=1; }
  827. | '[' NUMBER ']'
  828. { $$=$2; }
  829. ;
  830. gen_oplist
  831. : '.' /* empty gives conflicts */
  832. { niops=0; }
  833. | tokeninstance
  834. { niops=1;iops[0]=$1; }
  835. | gen_oplist ',' tokeninstance
  836. { iops[niops++] = $3; }
  837. ;
  838. yields
  839. : /* empty */
  840. { $$ = 0; }
  841. | YIELDS { tokrepllen = 0; } yieldlist
  842. { $$ = $3; if (tokrepllen > maxtokrepllen) maxtokrepllen = tokrepllen; }
  843. ;
  844. yieldlist
  845. : /* empty */
  846. { $$ = 0; }
  847. | tokeninstance yieldlist
  848. { checkstacking($1.in_set);
  849. NEW($$,struct varinfo);
  850. $$->vi_next = $2;
  851. $$->vi_int[0] = $1.in_index;
  852. tokrepllen++;
  853. }
  854. ;
  855. leaving
  856. : /* empty */
  857. { $$ = 0; }
  858. | LEAVING {emhere=1; in_em_repl=1; emrepllen = 0; } leavelist
  859. { emhere=0; in_em_repl=0; $$ = $3;
  860. if (emrepllen > maxemrepllen) maxemrepllen = emrepllen;
  861. }
  862. ;
  863. leavelist
  864. : leavelist_el
  865. | leavelist_el leavelist
  866. { $$=$1; $$->vi_next=$2; }
  867. ;
  868. leavelist_el
  869. : EMMNEM optexpr
  870. { NEW($$,struct varinfo);
  871. $$->vi_next=0;
  872. $$->vi_int[0] = $1;
  873. $$->vi_int[1] = $2;
  874. emrepllen++;
  875. }
  876. ;
  877. optstring
  878. : /* empty */
  879. { $$ = 0; }
  880. | STRING
  881. ;
  882. optexpr
  883. : /* empty */
  884. { $$ = 0; }
  885. | expr
  886. { $$ = $1.ex_index; } /* type checking ? */
  887. ;
  888. tokeninstance
  889. : tokarg subreg
  890. { $$ = subr_iocc($1,$2); }
  891. | tokarg '.' IDENT
  892. { $$ = tokm_iocc($1,$3); free($3); }
  893. | IDENT
  894. { $$ = ident_iocc($1); free($1);}
  895. | allreg subreg
  896. { $$ = all_iocc($1,$2); }
  897. | PERC_IDENT
  898. { if (cursetno < 0) {
  899. error("%%<ident> not allowed here");
  900. }
  901. $$ = percident_iocc($1);
  902. free($1);
  903. }
  904. | '{' IDENT attlist '}'
  905. { $$ = descr_iocc($2); free($2); }
  906. ;
  907. attlist
  908. : /* empty */
  909. { narexpr = 0; }
  910. | attlist ',' expr
  911. { arexp[narexpr++] = $3; }
  912. ;
  913. emarg
  914. : DOLLAR
  915. { if ($1<1 || $1>empatlen)
  916. error("Only %d instructions in pattern",empatlen);
  917. $$ = $1;
  918. }
  919. ;
  920. tokarg
  921. : PERCENT
  922. { $$ = $1;
  923. if (in_em_repl)
  924. error("No token references allowed in EM replacement part");
  925. if ($1<1 || $1>tokpatlen) {
  926. error("Only %d tokens in stackpattern",tokpatlen);
  927. $$ =1;
  928. }
  929. if (Xstackflag) $$ = 0;
  930. }
  931. ;
  932. subreg
  933. : /* empty */
  934. { $$ = 0; }
  935. | '.' NUMBER
  936. { if ($2<1 || $2>2) {
  937. error("Only 2 subregisters allowed");
  938. $$ = 1;
  939. } else {
  940. $$ = $2;
  941. }
  942. }
  943. ;
  944. allreg
  945. : ALLREG
  946. { if ($1>=nallreg)
  947. fatal("Only %d registers allocated",nallreg);
  948. $$ = $1;
  949. }
  950. ;
  951. expr
  952. : NUMBER
  953. { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16));
  954. }
  955. | emarg
  956. { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); }
  957. | STRING
  958. { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); }
  959. | IDENT
  960. { $$ = ident_expr($1); free($1); }
  961. | tokarg subreg
  962. { $$ = subreg_expr($1,$2); }
  963. | tokarg '.' IDENT
  964. { $$ = tokm_expr($1,$3); free($3); }
  965. | allreg subreg
  966. { $$ = all_expr($1,$2); }
  967. | PERC_IDENT
  968. { if (cursetno < 0) {
  969. error("%%<ident> not allowed here");
  970. }
  971. $$ = perc_ident_expr($1);
  972. free($1);
  973. }
  974. | DEFINED '(' expr ')'
  975. { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); }
  976. | SAMESIGN '(' expr ',' expr ')'
  977. { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); }
  978. | TOPELTSIZE '(' emarg ')'
  979. { $$ = make_expr(TYPINT,EX_TOPELTSIZE,$3-1,0); }
  980. | FALLTHROUGH '(' emarg ')'
  981. { $$ = make_expr(TYPBOOL,EX_FALLTHROUGH,$3-1,0); }
  982. | SFIT '(' expr ',' expr ')'
  983. { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); }
  984. | UFIT '(' expr ',' expr ')'
  985. { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); }
  986. | ROM '(' emarg ',' NUMBER ')'
  987. { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); }
  988. | ISROM '(' emarg ')'
  989. { $$ = make_expr(TYPBOOL,EX_ISROM,$3-1,0); }
  990. | LOWW '(' emarg ')'
  991. { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
  992. | HIGHW '(' emarg ')'
  993. { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
  994. /* Excluded, because it causes a shift-reduce conflict
  995. (problems with a tokenset_no followed by an optexpr)
  996. | '-' expr %prec UMINUS
  997. { $$ = make_expr(TYPINT,EX_CON, 0, 0);
  998. $$ = make_expr(TYPINT,EX_MINUS,i_expr($$),i_expr($2));
  999. }
  1000. */
  1001. | '(' expr ')'
  1002. { $$ = $2; }
  1003. | expr CMPEQ expr
  1004. { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); }
  1005. | expr CMPNE expr
  1006. { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); }
  1007. | expr CMPLT expr
  1008. { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); }
  1009. | expr CMPGT expr
  1010. { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); }
  1011. | expr CMPLE expr
  1012. { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); }
  1013. | expr CMPGE expr
  1014. { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); }
  1015. | expr OR2 expr
  1016. { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); }
  1017. | expr AND2 expr
  1018. { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); }
  1019. | expr '|' expr
  1020. { $$ = make_expr(TYPINT,EX_OR,i_expr($1),i_expr($3)); }
  1021. | expr '^' expr
  1022. { $$ = make_expr(TYPINT,EX_XOR,i_expr($1),i_expr($3)); }
  1023. | expr '&' expr
  1024. { $$ = make_expr(TYPINT,EX_AND,i_expr($1),i_expr($3)); }
  1025. | expr '+' expr
  1026. { $$ = sum_expr($1,$3); }
  1027. | expr '-' expr
  1028. { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); }
  1029. | expr '*' expr
  1030. { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); }
  1031. | expr '/' expr
  1032. { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); }
  1033. | expr '%' expr
  1034. { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); }
  1035. | expr LSHIFT expr
  1036. { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); }
  1037. | expr RSHIFT expr
  1038. { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); }
  1039. | NOT expr
  1040. { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); }
  1041. | COMP expr
  1042. { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); }
  1043. | INREG '(' expr ')'
  1044. { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); }
  1045. | regvartype
  1046. { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); }
  1047. | regvarexpr
  1048. ;
  1049. regvarexpr
  1050. : REGVAR '(' expr optregvartype ')'
  1051. { $$ = regvar_expr($3,$4); }
  1052. ;
  1053. optregvartype
  1054. : /* empty */
  1055. { $$ = reg_any; }
  1056. | ',' regvartype
  1057. { $$ = $2; }
  1058. ;
  1059. %%
  1060. #include "scan.c"