cgg.y 22 KB

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