cgg.y 19 KB

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