|
|
1.1 ! root 1: /* @(#) sty.y: 1.1 12/22/83 */ ! 2: %{ ! 3: static char SCCSID[] = "@(#) sty.y: 1.1 83/08/02"; ! 4: /* ! 5: This program turns machine descriptions into a table.c file ! 6: */ ! 7: %} ! 8: /* The input language uses many C conventions and notations */ ! 9: /* Types are represented as a shorthand: ! 10: c char ! 11: i int ! 12: s short ! 13: l long ! 14: p pointer ! 15: P alternate form of pointer ! 16: t structure ! 17: v void ! 18: ux unsigned x ! 19: f float ! 20: d double ! 21: /* There are a number of builtin cost names: ! 22: NONAME a constant with no name field (not an address) ! 23: CONVAL n the constant n ! 24: NCONVAL n the constant -n ! 25: POSRANGE n constants in the range [0,2**n -1] ! 26: SGRANGE n constants in the range [-2**n, 2**n - 1] ! 27: */ ! 28: /* There are also several incedental needs, etc, specified ! 29: 1,2,3 Number of needed registers ! 30: $P need pairs ! 31: $< share left ! 32: $> share right ! 33: $L result left ! 34: $R result right ! 35: $1,2,3 result in reg 1, 2, 3 ! 36: $C operation produces correct condition codes ! 37: $N no value produced: side effects only ! 38: $A need them all ! 39: $[ share left, RHS is preferred (if a temp register) ! 40: $] share right, RHS is preferred (if a temp register) ! 41: $l left side is referenced once more ! 42: $r right side is referenced once more ! 43: */ ! 44: ! 45: /* NOTE: ! 46: When several templates match with equal cost, the first is chosen. ! 47: Thus, when side-effects only are desired, the first template matching ! 48: is taken, if it is of lowest cost. ! 49: Moral: $N templates should be cheaper or should preceed $L, $1, etc. ! 50: */ ! 51: ! 52: %{ ! 53: # include "ctype.h" ! 54: # include "mfile2.h" ! 55: # include "dope.h" ! 56: ! 57: typedef struct { ! 58: int sha; /* shape */ ! 59: int ty; /* type */ ! 60: } SHTY; ! 61: SHTY lshty, /* left and right shape type */ ! 62: rshty; ! 63: static int dcost = 0; /* default cost */ ! 64: static int op, ! 65: tyop, ! 66: needs, ! 67: rewrite, ! 68: cost; ! 69: static int lcount, rcount; ! 70: static int opno; ! 71: static int ophd[DSIZE]; ! 72: static int optl[DSIZE]; ! 73: static int opsh[DSIZE]; ! 74: ! 75: struct optb { /* operation table */ ! 76: int op; /* what operation is to be matched */ ! 77: int tyop; /* the type associated with the op node */ ! 78: int nxop; /* index of the next op */ ! 79: int line; /* stin file line number */ ! 80: SHTY l, /* shapes of the left side */ ! 81: r; /* right side */ ! 82: int oneeds, /* needs */ ! 83: orew, /* rewrite info */ ! 84: ocost; /* op cost */ ! 85: char *string;/* the output */ ! 86: int strdef, ! 87: struse; ! 88: int olcount,/* usage count for left side */ ! 89: orcount;/* and right side */ ! 90: }; ! 91: typedef struct optb OPTB; ! 92: ! 93: # ifndef NOPTB ! 94: # define NOPTB 400 ! 95: # endif ! 96: ! 97: OPTB optb[NOPTB]; ! 98: ! 99: # ifndef NSTRING ! 100: # define NSTRING 10000 ! 101: # endif ! 102: ! 103: # ifndef NSTYSHPS ! 104: # define NSTYSHPS 4000 ! 105: # endif ! 106: ! 107: typedef struct { ! 108: int sop, ! 109: sleft, ! 110: sright, ! 111: ssh, ! 112: scset, /* ==1 after cost for shape has been set, else 0 */ ! 113: scost, ! 114: scnt; ! 115: char shname[8]; ! 116: } STYSHP; ! 117: ! 118: static int was_cost; /* set if a cost was actually specified */ ! 119: static int nshp = 0; ! 120: static int nmshp = NSTYSHPS - 1; ! 121: /*static*/ STYSHP shp[NSTYSHPS]; ! 122: static char strng[NSTRING]; ! 123: static char *string; ! 124: static char *pstring = strng; ! 125: static char *asstring; ! 126: ! 127: %} ! 128: ! 129: %union { ! 130: int ival; ! 131: char *str; ! 132: SHTY shh; ! 133: }; ! 134: ! 135: %token STR DEF LPRF RPRF LSHR RSHR GOODCC NOVAL PNEED LRES RRES LCOUNT RCOUNT ! 136: %token USERCOST CONVAL NCONVAL POSRANGE SGRANGE NONAME DCOST SHAPES OPCODES ! 137: %token <ival> OP NM DIG STYPE RREG ! 138: %left OP ! 139: %left STYPE ! 140: ! 141: %type <str> STR ! 142: %type <ival> opcost num slist nterm opop shape ! 143: %type <ival> costnexp nexp ! 144: %type <ival> cost cexpr cterm ! 145: %type <shh> sref ! 146: ! 147: /* ! 148: OP the ops <, <<, >, >>, <=, >=, +, -, *, /, %, &, ^, ~, ! ! 149: NM names (letter, followed by 0 or more letters or digits ! 150: STR a string in "" ! 151: DIG a digit, 0-9 ! 152: Other letters are returned: (, ), {, }, etc. ! 153: */ ! 154: ! 155: %% ! 156: ! 157: file : SHAPES lshapes OPCODES lops ! 158: { finished(); } ! 159: ; ! 160: ! 161: lshapes : /* EMPTY */ ! 162: | lshapes NM ':' slist ',' costnexp ';' ! 163: { shp[$2].sop = MANY; ! 164: shp[$2].sleft = $4; ! 165: shp[$2].sright = $6; ! 166: shp[$2].scost = 0; ! 167: shp[$2].scset = 1; ! 168: shp[$2].ssh = 0; ! 169: } ! 170: | lshapes NM ':' costnexp ';' ! 171: { ! 172: shp[$2].sop = MANY; ! 173: shp[$2].sleft = $4; ! 174: shp[$2].sright = -1; ! 175: shp[$2].scost = 0; ! 176: shp[$2].scset = 1; ! 177: shp[$2].ssh = 0; ! 178: } ! 179: | lshapes NM ':' opop shape opcost ';' ! 180: { shp[nshp].scost = $6; ! 181: shp[nshp].scset = was_cost; ! 182: shp[nshp].ssh = $5; ! 183: shp[nshp].sop = $4; ! 184: shp[nshp].sleft = -1; ! 185: shp[nshp].sright = -1; ! 186: ++nshp; ! 187: checkit( nshp-1 ); ! 188: shp[$2].sop = MANY; ! 189: shp[$2].sleft = nshp-1; ! 190: shp[$2].sright = -1; ! 191: shp[$2].scost = 0; ! 192: shp[$2].scset = 1; ! 193: shp[$2].ssh = 0; ! 194: if( nshp >= nmshp ) { ! 195: yyerror( "out of node space" ); ! 196: exit( 1 ); ! 197: } ! 198: } ! 199: ; ! 200: ! 201: opop : /* EMPTY */ ! 202: { $$ = ICON; } ! 203: | OP ! 204: ; ! 205: ! 206: lops : /* EMPTY */ ! 207: { needs = op = rewrite = cost = 0; ! 208: lcount = rcount = 1; ! 209: } ! 210: ! 211: | lops lop ! 212: ; ! 213: ! 214: lop : OP sref ',' sref ltail ! 215: { lshty = $2; ! 216: rshty = $4; ! 217: op = $1; ! 218: tyop = TANY; ! 219: output(); ! 220: tyop = needs = op = rewrite = cost = 0; ! 221: lcount = rcount = 1; ! 222: } ! 223: | OP STYPE sref ',' sref ltail ! 224: { lshty = $3; ! 225: rshty = $5; ! 226: op = $1; ! 227: tyop = $2; ! 228: output(); ! 229: tyop = needs = op = rewrite = cost = 0; ! 230: lcount = rcount = 1; ! 231: } ! 232: | OP sref ltail ! 233: { lshty = $2; ! 234: rshty.sha = -1; ! 235: rshty.ty = TANY; ! 236: op = $1; ! 237: tyop = TANY; ! 238: output(); ! 239: tyop = needs = op = rewrite = cost = 0; ! 240: lcount = rcount = 1; ! 241: } ! 242: | OP STYPE sref ltail ! 243: { lshty = $3; ! 244: rshty.sha = -1; ! 245: rshty.ty = $2; ! 246: op = $1; ! 247: tyop = TANY; ! 248: output(); ! 249: tyop = needs = op = rewrite = cost = 0; ! 250: lcount = rcount = 1; ! 251: } ! 252: | sref ltail ! 253: { rshty = $1; ! 254: lshty.sha = -1; ! 255: lshty.ty = TANY; ! 256: loutput(); ! 257: tyop = needs = op = rewrite = cost = 0; ! 258: lcount = rcount = 1; ! 259: } ! 260: | DCOST {dcost=0;} opcost ';' ! 261: { dcost = $3; } ! 262: ; ! 263: ! 264: ltail : needs STR opcost ';' ! 265: { ! 266: cost = $3; ! 267: asstring = $2; ! 268: } ! 269: ; ! 270: ! 271: needs : /* EMPTY */ ! 272: { needs = 0; } ! 273: | '{' nlist '}' ! 274: ; ! 275: ! 276: nlist : /* EMPTY */ ! 277: { needs = 0; } ! 278: | nlist DIG ! 279: { needs = (needs&~NCOUNT) | $2; } ! 280: | nlist RPRF ! 281: { needs |= RSHARE|RPREF; } ! 282: | nlist LPRF ! 283: { needs |= LSHARE|LPREF; } ! 284: | nlist RSHR ! 285: { needs |= RSHARE; } ! 286: | nlist LSHR ! 287: { needs |= LSHARE; } ! 288: | nlist PNEED ! 289: { needs |= NPAIR; } ! 290: | nlist GOODCC ! 291: { rewrite |= RESCC; } ! 292: | nlist NOVAL ! 293: { ! 294: if (rewrite) ! 295: yyerror("$N incompatible with other results"); ! 296: rewrite = RNULL; ! 297: } ! 298: | nlist LRES ! 299: { rewrite |= RLEFT; } ! 300: | nlist RRES ! 301: { rewrite |= RRIGHT; } ! 302: | nlist RREG ! 303: { if( !(needs&NCOUNT) ) needs |= $2; ! 304: rewrite |= (($2==1)?RESC1:(($2==2)?RESC2:RESC3)); ! 305: } ! 306: | nlist LCOUNT ! 307: { lcount += 1; } ! 308: | nlist RCOUNT ! 309: { rcount += 1; } ! 310: ; ! 311: ! 312: num : DIG ! 313: | num DIG ! 314: { $$ = 10*$1 + $2; } ! 315: ; ! 316: ! 317: opcost : cost ! 318: { was_cost = 1; } ! 319: | /* EMPTY */ ! 320: { was_cost = 0; $$ = dcost; } ! 321: ; ! 322: ! 323: cost : ':' cexpr ! 324: { $$ = $2; } ! 325: ; ! 326: ! 327: cexpr : cterm ! 328: | OP cterm ! 329: { $$ = uopcost( $1, $2 ); } ! 330: | cterm OP cterm ! 331: { $$ = bopcost( $2, $1, $3 ); } ! 332: ; ! 333: ! 334: cterm : '(' cexpr ')' ! 335: { $$ = $2; } ! 336: | num ! 337: ; ! 338: ! 339: shape : /* EMPTY */ ! 340: { $$ = 0; } ! 341: | NONAME ! 342: { $$ = NACON; /* constant with no name */ } ! 343: | USERCOST num ! 344: { $$ = $2|SUSER; /* user's cost ftn */ } ! 345: | CONVAL num ! 346: { $$ = $2|SVAL; /* positive constant value */ } ! 347: | NCONVAL num ! 348: { $$ = $2|SNVAL; /* negative constant value */ } ! 349: | POSRANGE num ! 350: { $$ = $2|SRANGE0; /* positive range */ } ! 351: | SGRANGE num ! 352: { $$ = $2|SSRANGE; /* signed range */ } ! 353: ; ! 354: ! 355: sref : nterm ! 356: { $$.ty = 0; ! 357: $$.sha = $1; ! 358: } ! 359: | nterm STYPE /* do this before doing in nterm */ ! 360: { $$.sha = $1; ! 361: $$.ty = $2; } ! 362: ; ! 363: ! 364: slist : costnexp ! 365: | slist ',' costnexp ! 366: { $$ = bop( MANY, $1, $3, 0 ); } ! 367: ; ! 368: ! 369: costnexp: nexp opcost ! 370: { $$ = sharecost($1, $2); } ! 371: ; ! 372: ! 373: nexp : nterm ! 374: | OP nterm ! 375: { $$ = uop( $1, $2 ); } ! 376: | nterm OP nterm ! 377: { $$ = bop( $2, $1, $3, 0 ); } ! 378: ; ! 379: ! 380: nterm : '(' nexp ')' ! 381: { $$ = $2; } ! 382: | NM ! 383: | nterm STYPE ! 384: { $$ = top( $1, $2 ); } ! 385: ; ! 386: ! 387: %% ! 388: static int lineno = 1; /* line number of stin file */ ! 389: static char filename[100] = "<stdin>"; ! 390: ! 391: main(argc, argv) ! 392: int argc; ! 393: char **argv; ! 394: { ! 395: register int i; ! 396: for( i=0; i<DSIZE; ++i ) { ! 397: opsh[i] = 0; ! 398: optl[i] = ophd[i] = -1; ! 399: } ! 400: mkdope(); ! 401: yyparse(); ! 402: exit( 0 ); ! 403: } ! 404: ! 405: ! 406: checkit( n ) ! 407: { ! 408: /* check a shape */ ! 409: STYSHP *p; ! 410: if( n<0 ) return; ! 411: if( n>=nshp && n<=nmshp || n>=NSTYSHPS ) { ! 412: yyerror( "out of range shape: %d", n ); ! 413: } ! 414: p = &shp[n]; ! 415: if( p->sop < 0 || p->sop > MANY ) { ! 416: yyerror( "out of range op: %d", p->sop ); ! 417: } ! 418: ! 419: switch( optype(p->sop) ) { ! 420: ! 421: case BITYPE: ! 422: if( p->sright < 0 && p->sop != MANY ) { ! 423: yyerror( "right side empty" ); ! 424: } ! 425: checkit( p->sright ); ! 426: case UTYPE: ! 427: if( p->sleft < 0 ) { ! 428: yyerror( "left side empty" ); ! 429: } ! 430: checkit( p->sleft ); ! 431: } ! 432: } ! 433: ! 434: /* VARARGS */ ! 435: yyerror( s, a ) ! 436: char *s; ! 437: { ! 438: fprintf( stderr, s, a ); ! 439: fprintf( stderr, ", file \"%s\", line %d\n", filename, lineno ); ! 440: abort(); ! 441: exit( 1 ); ! 442: } ! 443: ! 444: ! 445: static int otb[20]; /* ops that are part of the shape */ ! 446: static int notb; /* number of otb entries */ ! 447: ! 448: loutput() ! 449: { ! 450: /* ! 451: * rhs has a leaf: output templates for all interesting ! 452: * operators in this leaf. ! 453: * An interesting operator is one that is NOT MANY. ! 454: * This allows us to access the table for each operator ! 455: * that this leaf may implement. ! 456: */ ! 457: register int i; ! 458: register int s; ! 459: register int ocost = cost; ! 460: ! 461: notb = 0; ! 462: lout1( s = rshty.sha ); ! 463: if( !notb ) yyerror( "lout1() error" ); ! 464: for( i = notb-1; i >= 0; --i ) ! 465: { ! 466: op = otb[i]; ! 467: tyop = TANY; ! 468: if( optype(op) == LTYPE ) { ! 469: lcount = 0; ! 470: cost = ocost + (rcount * refine(s)); ! 471: } ! 472: else if( optype(op) == BITYPE ) { ! 473: yyerror( "binary op in shape not done right" ); ! 474: } ! 475: else { /* op is unary */ ! 476: lcount = rcount; ! 477: rcount = 0; ! 478: cost = ocost + (lcount * urefine(s)); ! 479: } ! 480: output(); ! 481: } ! 482: } ! 483: ! 484: urefine( s ) { /* construct an entry for a unary op matching shape s */ ! 485: /* for now, punt on the costs */ ! 486: rcount = lcount; ! 487: lcount = 0; ! 488: return( refine( s ) ); ! 489: } ! 490: ! 491: smat(s) ! 492: register s; ! 493: { ! 494: /* ! 495: * return 1 if we can find the op anyplace in the ! 496: * shape tree `s' ! 497: */ ! 498: if( s < 0 ) ! 499: return( 0 ); ! 500: if( shp[s].sop == MANY ) ! 501: { ! 502: if( shp[s].sleft>=0 && smat( shp[s].sleft ) ) return( 1 ); ! 503: if( shp[s].sright>=0 && smat( shp[s].sright ) ) return( 1 ); ! 504: return( 0 ); ! 505: } ! 506: return( shp[s].sop == op ); ! 507: } ! 508: ! 509: refine(s) ! 510: register s; ! 511: { ! 512: /* ! 513: * find the largest subshape of `s' that contains ! 514: * the operator `op' (op is global). ! 515: * We descend MANY nodes until we run out, ! 516: * or until the operator `op' is found in both descendents. ! 517: * Since we are throwing away costs buried in the MANY nodes ! 518: * on the way down, we must keep track of those, to ! 519: * adjust the costs appropriately in the operator table. ! 520: */ ! 521: register int bc = 0; ! 522: ! 523: while( shp[s].sop == MANY ) ! 524: { ! 525: bc += shp[s].scost; ! 526: if( smat( shp[s].sleft ) ) ! 527: { ! 528: if( smat( shp[s].sright ) ) break; ! 529: else s = shp[s].sleft; ! 530: } ! 531: else s = shp[s].sright; ! 532: } ! 533: lshty.sha = -1; ! 534: rshty.sha = mkshp(s); ! 535: return( bc + shp[s].scost ); ! 536: } ! 537: ! 538: lout1( n ) ! 539: register n; ! 540: { ! 541: register int i; ! 542: while( n >= 0 && shp[n].sop == MANY ) ! 543: { ! 544: lout1( shp[n].sleft ); ! 545: n = shp[n].sright; ! 546: } ! 547: if( n < 0 ) ! 548: return; ! 549: for( i=0; i<notb; ++i ) ! 550: { ! 551: if( otb[i] == shp[n].sop ) return; ! 552: } ! 553: otb[notb++] = shp[n].sop; ! 554: } ! 555: ! 556: mkshp(s) ! 557: { ! 558: /* make a shape that yields s */ ! 559: /* first, make s a MANY node */ ! 560: register i; ! 561: ! 562: if( s < 0 ) return( s ); ! 563: if( shp[s].sop == MANY ) i = s; ! 564: else { ! 565: /* look for a MANY node pointing to s */ ! 566: for( i= NSTYSHPS; i>nmshp; --i ) { ! 567: if( shp[i].sright >= 0 ) continue; ! 568: if( shp[i].sleft == s ) goto foundit; ! 569: } ! 570: /* must make a MANY node */ ! 571: i = bop( MANY, s, -1, 0 ); ! 572: } ! 573: ! 574: /* now, make sure that i has a name, so it will be output */ ! 575: ! 576: foundit: ; ! 577: ! 578: if( !shp[i].shname[0] ) { ! 579: strcpy( shp[i].shname, "mkshp" ); ! 580: } ! 581: return(i); ! 582: } ! 583: ! 584: onebit(x) ! 585: register x; ! 586: { ! 587: /* return 1 if x has at most 1 bit on, 0 otherwise */ ! 588: return( !(x&(x-1)) ); ! 589: } ! 590: ! 591: output() ! 592: { ! 593: register OPTB *q; ! 594: register int j; ! 595: ! 596: if( lshty.ty == 0 ) lshty.ty = TANY; ! 597: if( rshty.ty == 0 ) rshty.ty = TANY; ! 598: ! 599: switch( op ) ! 600: { ! 601: ! 602: case 0: ! 603: yyerror( "0 op" ); ! 604: ! 605: case STAR: ! 606: case REG: ! 607: case UNARY MINUS: ! 608: case UNARY AND: ! 609: case FLD: ! 610: if( needs&(LSHARE|RSHARE) ) needs |= (LSHARE|RSHARE); ! 611: break; ! 612: ! 613: case ASSIGN: ! 614: case ASG PLUS: ! 615: case ASG MINUS: ! 616: case ASG MUL: ! 617: case ASG DIV: ! 618: case ASG MOD: ! 619: case ASG AND: ! 620: case ASG OR: ! 621: case ASG ER: ! 622: case ASG LS: ! 623: case ASG RS: ! 624: if( !(rewrite & (RNULL|RESC1|RESC2|RESC3|RRIGHT)) ) ! 625: { ! 626: rewrite |= RLEFT; ! 627: } ! 628: } ! 629: if( !rewrite ) rewrite = RNULL; ! 630: ! 631: if( !onebit( rewrite & (RNULL|RLEFT|RRIGHT|RESC1|RESC2|RESC3) ) ) ! 632: { ! 633: yyerror( "multiple results -- illegal (%o)", rewrite ); ! 634: } ! 635: if( ((rewrite&RLEFT)&&(needs&LSHARE)) || ! 636: ((rewrite&RRIGHT)&&(needs&RSHARE)) ) ! 637: { ! 638: if( asstring[0] != 'Y' ) ! 639: yyerror( "don't share on result side of tree" ); ! 640: } ! 641: if( needs && (needs&(LSHARE|RSHARE)) == needs ) ! 642: { ! 643: yyerror( "don't share without allocating something" ); ! 644: } ! 645: checkout(asstring); ! 646: ! 647: q = &optb[opno]; ! 648: if( opno >= NOPTB ) yyerror( "too many templates" ); ! 649: q->line = lineno; ! 650: q->op = op; ! 651: q->tyop = tyop; ! 652: if( ophd[op]>=0 ) ! 653: { ! 654: optb[optl[op]].nxop = opno; ! 655: optl[op] = opno; ! 656: } ! 657: else ! 658: { ! 659: optl[op] = ophd[op] = opno; ! 660: } ! 661: q->nxop = -1; ! 662: q->l = lshty; ! 663: q->r = rshty; ! 664: q->oneeds = needs; ! 665: q->orew = rewrite; ! 666: q->ocost = cost; ! 667: q->string = asstring; ! 668: q->olcount = lcount; ! 669: q->orcount = rcount; ! 670: /* now, take care of special cases */ ! 671: if( optype(op) == LTYPE ) { /* leaf */ ! 672: int s; ! 673: if( (s=q->r.sha) >= 0 && trivial(s) ) { ! 674: q->r.sha = -1; /* clobber any right shape */ ! 675: } ! 676: } ! 677: else if( optype(op) == UTYPE ) { ! 678: if( q->r.sha >=0 ) { ! 679: /* someday, look for things below op */ ! 680: /* for now, we get the cost wrong so back up */ ! 681: } ! 682: } ! 683: ++opno; ! 684: } ! 685: ! 686: trivial( s ) { ! 687: /* is shape s a trivial match for op */ ! 688: if( shp[s].sop == MANY ) { ! 689: if( shp[s].sright >= 0 ) { ! 690: return( 0 ); /* nontrivial */ ! 691: } ! 692: s = shp[s].sleft; ! 693: } ! 694: if( shp[s].sop != op ) { ! 695: return( 0 ); ! 696: } ! 697: if( shp[s].ssh ) { ! 698: return( 0 ); ! 699: } ! 700: return( 1 ); /* ok to clobber */ ! 701: } ! 702: ! 703: checkout(string) ! 704: char *string; ! 705: { ! 706: /* check out the string, looking at rewrite and needs */ ! 707: /* look for {U,I,C,A}{L,R,1,2,3} and \n */ ! 708: /* complain about: ! 709: *** 1, 2, 3 used, not allocated ! 710: *** shared side after \n after temp used ! 711: *** AL or AR used, w. side effect possible, more than once ! 712: */ ! 713: ! 714: /* flagl and flagr are 1 if L and R legal, 0 if not, -1 if ! 715: /* they will be illegal after the next \n */ ! 716: ! 717: register int flagl, flagr, prn, min, cond; ! 718: register char *s; ! 719: ! 720: flagl = flagr = 1; ! 721: cond = 0; ! 722: ! 723: for( s=string; *s; ++s ) ! 724: { ! 725: switch( *s ) ! 726: { ! 727: ! 728: case '\\': ! 729: ++s; ! 730: if( *s == '\\' ) ++s; ! 731: else if( *s == 'n' ) ! 732: { ! 733: if( flagl<0 ) flagl=0; ! 734: if( flagr<0 ) flagr=0; ! 735: } ! 736: break; ! 737: ! 738: case 'Z': ! 739: ++s; ! 740: if( *s=='(' ) ! 741: { ! 742: while( *++s != ')' ) {;} ! 743: } ! 744: break; ! 745: ! 746: case 'Y': ! 747: /* this string is asserted to be good; don't check */ ! 748: return; ! 749: ! 750: case 'R': ! 751: case 'D': ! 752: /* conditional; a lot of stuff no longer is true */ ! 753: cond = 1; ! 754: break; ! 755: ! 756: case 'A': ! 757: case 'C': ! 758: case 'U': ! 759: case 'I': ! 760: ++s; ! 761: if( *s == '-' ) ! 762: { ! 763: ++s; ! 764: min = 1; ! 765: } ! 766: else min = 0; ! 767: if( *s == '(' ) ! 768: { ! 769: ++s; ! 770: prn = 1; ! 771: } ! 772: else prn = 0; ! 773: switch( *s ) ! 774: { ! 775: ! 776: case 'L': ! 777: if( !flagl && !cond ) ! 778: { ! 779: yyerror( "illegal L just at \"%s\"", ! 780: s ); ! 781: } ! 782: /* look for side-effects here */ ! 783: if( !min && seff(lshty.sha)) flagl = 0; ! 784: break; ! 785: ! 786: case 'R': ! 787: if( !flagr && !cond ) ! 788: { ! 789: yyerror( "illegal R just at \"%s\"", ! 790: s ); ! 791: } ! 792: /* look for side-effects here */ ! 793: if( !min && seff(rshty.sha)) flagr = 0; ! 794: break; ! 795: ! 796: case '1': ! 797: case '2': ! 798: case '3': ! 799: if( (*s - '0') > (needs&NCOUNT) ) ! 800: { ! 801: yyerror( "reg %c used, not allocated", ! 802: *s ); ! 803: } ! 804: if( (needs&LSHARE) && flagl ) flagl = -1; ! 805: if( (needs&RSHARE) && flagr ) flagr = -1; ! 806: ! 807: case '.': ! 808: break; ! 809: ! 810: default: ! 811: yyerror( "illegal qualifier just at \"%s\"", ! 812: s ); ! 813: } ! 814: if( prn ) while( *s != ')' ) ++s; ! 815: } ! 816: } ! 817: } ! 818: ! 819: seff( s ) ! 820: register s; ! 821: { ! 822: if( shp[s].sop == INCR || shp[s].sop == DECR ) return( 1 ); ! 823: if( shp[s].sleft >= 0 && seff( shp[s].sleft ) ) return( 1 ); ! 824: if( shp[s].sright >= 0 && seff( shp[s].sright ) ) return( 1 ); ! 825: return( 0 ); ! 826: } ! 827: ! 828: uop( o, a ) ! 829: register o,a; ! 830: { ! 831: if( o == MUL ) o = STAR; ! 832: else if( o == MINUS ) o = UNARY MINUS; ! 833: else if( o == AND ) o = UNARY AND; ! 834: return( bop( o, a, -1, 0 ) ); ! 835: } ! 836: ! 837: top( a, ty ) ! 838: register a,ty; ! 839: { ! 840: /* build a type node over a */ ! 841: /* must be done differently than uop, since types must be copied */ ! 842: register STYSHP *p; ! 843: ! 844: if( a < 0 ) ! 845: return( a ); ! 846: checkit( a ); ! 847: if( shp[a].sop == MANY ) ! 848: { ! 849: register l, r; ! 850: l = shp[a].sleft; ! 851: r = shp[a].sright; ! 852: if( l >= 0 ) ! 853: l = top( l, ty ); ! 854: if( r >= 0 ) ! 855: r = top( r, ty ); ! 856: return( bop( MANY, l, r, 0 ) ); ! 857: } ! 858: if( shp[a].ssh ) ! 859: { ! 860: yyerror( "can't type a special node" ); ! 861: } ! 862: shp[nshp] = shp[a]; ! 863: shp[nshp].shname[0] = '\0'; ! 864: shp[nshp].ssh = ty|SPTYPE; ! 865: shp[nshp].scset = 0; ! 866: nshp++; ! 867: checkit( nshp-1 ); ! 868: return( nshp-1 ); ! 869: } ! 870: ! 871: bop( o, a, b, cst ) ! 872: register o, a, b, cst; ! 873: { ! 874: register STYSHP *p; ! 875: register int l, r, ret; ! 876: ! 877: checkit( a ); ! 878: checkit( b ); ! 879: ! 880: if( o != MANY ) ! 881: { ! 882: while( shp[a].sop == MANY && shp[a].sright < 0 ) { ! 883: a = shp[a].sleft; ! 884: } ! 885: while( b >= 0 && shp[b].sop == MANY && shp[b].sright < 0 ) { ! 886: b = shp[b].sleft; ! 887: } ! 888: if( a>=0 && shp[a].sop == MANY ) ! 889: { ! 890: /* distribute MANY nodes to top */ ! 891: l = bop( o, shp[a].sleft, b, cst + shp[a].scost ); ! 892: r = bop( o, shp[a].sright, b, cst + shp[a].scost ); ! 893: return( bop( MANY, l, r, 0 ) ); ! 894: } ! 895: if( b>=0 && shp[b].sop == MANY ) ! 896: { ! 897: /* distribute MANY nodes to top */ ! 898: l = bop( o, a, shp[b].sleft, cst + shp[b].scost ); ! 899: r = bop( o, a, shp[b].sright, cst + shp[b].scost ); ! 900: return( bop( MANY, l, r, 0 ) ); ! 901: } ! 902: } ! 903: ! 904: if( o == MANY ) ! 905: /* MANY nodes go at the end */ ! 906: p = &shp[ ret = nmshp-- ]; ! 907: else ! 908: p = &shp[ ret = nshp++ ]; ! 909: if( nshp >= nmshp ) { ! 910: yyerror( "out of node space" ); ! 911: exit( 1 ); ! 912: } ! 913: ! 914: p->sop = o; ! 915: p->sleft = a; ! 916: p->sright =b; ! 917: p->scost = cst; ! 918: p->scset = 0; ! 919: p->ssh = 0; ! 920: p->shname[0] = '\0'; ! 921: checkit( ret ); ! 922: return( ret ); ! 923: } ! 924: ! 925: int olist[] = { PLUS, MINUS, MUL, DIV, MOD, LS, RS, OR, ER, AND, -1 }; ! 926: ! 927: struct nam ! 928: { ! 929: char *tntn; ! 930: int tnty; ! 931: }; ! 932: #define NameV(x) "x", x /* name-value pairs */ ! 933: struct nam Tnam[] = { ! 934: NameV(TANY), ! 935: NameV(TCHAR), ! 936: NameV(TSHORT), ! 937: NameV(TINT), ! 938: NameV(TLONG), ! 939: NameV(TFLOAT), ! 940: NameV(TDOUBLE), ! 941: NameV(TUCHAR), ! 942: NameV(TUSHORT), ! 943: NameV(TUNSIGNED), ! 944: NameV(TULONG), ! 945: NameV(TSTRUCT), ! 946: NameV(TPOINT), ! 947: NameV(TPOINT2), ! 948: NameV(TVOID), ! 949: NameV(urTINT), ! 950: NameV(urTUNSIGNED), ! 951: 0, 0, ! 952: }; ! 953: struct nam Rwnam[] = { ! 954: NameV(RLEFT), ! 955: NameV(RRIGHT), ! 956: NameV(RESC1), ! 957: NameV(RESC2), ! 958: NameV(RESC3), ! 959: NameV(RESCC), ! 960: NameV(RNOP), ! 961: NameV(RNULL), ! 962: 0, 0 ! 963: }; ! 964: struct nam Ndnam[] = { ! 965: NameV(LSHARE), ! 966: NameV(RSHARE), ! 967: NameV(NPAIR), ! 968: NameV(LPREF), ! 969: NameV(RPREF), ! 970: 0, 0, ! 971: }; ! 972: finished() ! 973: { ! 974: register STYSHP *p; ! 975: register OPTB *q, *q1; ! 976: register int i, j; ! 977: ! 978: /* terminate the templates */ ! 979: printf( "# include \"mfile2.h\"\n\n" ); ! 980: ! 981: /* chain binary ops together with the op= form */ ! 982: for( i=0; (op=olist[i])>=0; ++i ) ! 983: { ! 984: if( ophd[op]<0 ) ! 985: ophd[op] = ophd[ASG op]; ! 986: else ! 987: optb[optl[op]].nxop = ophd[ASG op]; ! 988: } ! 989: if( ophd[STCALL]<0 ) ! 990: ophd[STCALL] = ophd[CALL]; ! 991: if( ophd[UNARY STCALL]<0 ) ! 992: ophd[UNARY STCALL] = ophd[UNARY CALL]; ! 993: ! 994: optbck(); ! 995: ! 996: /* everything that gets used should be a MANY shape with name */ ! 997: /* mkshp is called to cause this to be true */ ! 998: ! 999: for( i=0; i<opno; ++i ) ! 1000: { ! 1001: q = &optb[i]; ! 1002: q->l.sha = mkshp(q->l.sha); ! 1003: q->r.sha = mkshp(q->r.sha); ! 1004: } ! 1005: ! 1006: /* avoid identical strings in optb[] by finding identical strings, ! 1007: giving them names and putting them at the front of table.c */ ! 1008: for( i=0; i<opno; ++i ) ! 1009: { ! 1010: q = &optb[i]; ! 1011: q->struse = 1; ! 1012: q->strdef = -1; ! 1013: for(j = 0; j < i; j++) ! 1014: { ! 1015: q1 = &optb[j]; ! 1016: if(!q1->struse) ! 1017: continue; ! 1018: if(strcmp(q->string,q1->string)==0) ! 1019: { ! 1020: q->strdef = j; ! 1021: q1->struse++; ! 1022: q->struse = 0; ! 1023: break; ! 1024: } ! 1025: } ! 1026: } ! 1027: for(i=0; i<opno; i++) ! 1028: { ! 1029: q = &optb[i]; ! 1030: if(q->struse>1) ! 1031: { ! 1032: printf("static char Str%d[] = \"%s\";\n", i, q->string); ! 1033: q->struse = 0; ! 1034: q->strdef = i; ! 1035: } ! 1036: } ! 1037: ! 1038: /* set the ssh flags in shp, but don't print yet */ ! 1039: ! 1040: for( j=0,i=NSTYSHPS-1; i>nmshp; --i ) { ! 1041: if( !shp[i].shname[0] ) continue; ! 1042: shp[i].ssh = j; ! 1043: j += manycount( i ); ! 1044: ++j; /* count the null */ ! 1045: } ! 1046: ! 1047: printf( "\n# define SHNL ((SHAPE *)0)\n" ); ! 1048: printf( "# define S(x) (&shapes[x])\n" ); ! 1049: ! 1050: printf( "\nSHAPE shapes[] = {\n" ); ! 1051: for( i=0, p=shp; i<nshp; ++i,++p ) ! 1052: { ! 1053: if( p->sop<0 ) ! 1054: yyerror( "undefined shape: %.8s", p->shname ); ! 1055: printf( "/*%4d */ ", i); ! 1056: printf( "%4d,\t",p->sop ); ! 1057: saaddr(p->sleft); ! 1058: saaddr(p->sright); ! 1059: printf( "%#o,\t%d,", p->ssh, p->scost ); ! 1060: if( p->shname[0] ) ! 1061: printf( "\t/* %.8s */\n", p->shname ); ! 1062: else ! 1063: putchar( '\n' ); ! 1064: if(p->shname[0]) ! 1065: chkdups(i); ! 1066: } ! 1067: printf( "\n};\n" ); ! 1068: ! 1069: printf( "\n# define PSHNL ((SHAPE **)0)\n" ); ! 1070: printf( "# define P(x) (&pshape[x])\n" ); ! 1071: ! 1072: printf( "\nSHAPE *pshape[] = {\n" ); ! 1073: for( j = 0, i = NSTYSHPS-1; i > nmshp; --i ) { ! 1074: if( !shp[i].shname[0] ) ! 1075: continue; ! 1076: if( shp[i].ssh != j ) { ! 1077: fprintf( stderr, "shape %d, ssh=%d, j=%d\n", ! 1078: i, shp[i].ssh, j ); ! 1079: } ! 1080: printf( "/*%4d %.8s */\t", j, shp[i].shname ); ! 1081: j = manylist( i, j ); ! 1082: printf( "SHNL,\n"); ! 1083: ++j; ! 1084: } ! 1085: printf( "};\n" ); ! 1086: ! 1087: printf( "struct optab table[] = {\n\n" ); ! 1088: for( i=0; i<opno; ++i ) ! 1089: { ! 1090: q = &optb[i]; ! 1091: printf( "/* # %d, line %d */\n", i, q->line ); ! 1092: prop( q->op ); ! 1093: prnam( q->tyop, Tnam ); ! 1094: if( q->nxop >= 0 ) ! 1095: printf( "\t&table[%d],\n", q->nxop ); ! 1096: else ! 1097: printf( "\t0,\n" ); ! 1098: ! 1099: shpprint(q->l.sha, q->l.ty); ! 1100: shpprint(q->r.sha, q->r.ty); ! 1101: printf("\t\t"); ! 1102: prnam(q->oneeds, Ndnam); ! 1103: printf("\t\t"); ! 1104: prnam(q->orew, Rwnam); ! 1105: if(q->strdef>=0) ! 1106: printf("\t\tStr%d,\n", q->strdef); ! 1107: else ! 1108: printf("\t\t\"%s\",\n", q->string); ! 1109: printf("\t\t%d,%d,%d,%d,\n", q->ocost, q->olcount, q->orcount, ! 1110: q->line ); ! 1111: } ! 1112: printf( "\n};\n" ); ! 1113: ! 1114: printf( "OPTAB *ophead[] = {\n" ); ! 1115: ! 1116: for( i=0; i<DSIZE; ++i ) ! 1117: { ! 1118: if( ophd[i] < 0 ) printf( " 0,\n" ); ! 1119: else printf( " &table[%d],\n", ophd[i] ); ! 1120: } ! 1121: printf( "};\n" ); ! 1122: } ! 1123: ! 1124: manycount( i ) ! 1125: { /* count the descendents of shp[i] */ ! 1126: int c; ! 1127: ! 1128: if( shp[i].sop == MANY ) { ! 1129: c = 0; ! 1130: if( shp[i].sleft >= 0 ) c += manycount( shp[i].sleft ); ! 1131: if( shp[i].sright >= 0 ) c += manycount( shp[i].sright ); ! 1132: return( c ); ! 1133: } ! 1134: return( 1 ); ! 1135: } ! 1136: ! 1137: manylist( i, j ) { ! 1138: /* put out a list of S(x) for shp[i], starting at j */ ! 1139: /* first, put out CCODES and FREE */ ! 1140: /* next, put out REG and TEMP */ ! 1141: /* next, everything else */ ! 1142: int k; ! 1143: int outcount = 0; ! 1144: ! 1145: if( i<0 ) return(j); ! 1146: ! 1147: setopsh( i ); /* set opsh[k] if op k is legal at head of i */ ! 1148: if( opsh[FREE] ) { ! 1149: j = manyop( i, j, FREE, &outcount ); ! 1150: opsh[FREE] = 0; ! 1151: } ! 1152: if( opsh[CCODES] ) { ! 1153: j = manyop( i, j, CCODES, &outcount ); ! 1154: opsh[CCODES] = 0; ! 1155: } ! 1156: if( opsh[REG] ) { ! 1157: j = manyop( i, j, REG, &outcount ); ! 1158: opsh[REG] = 0; ! 1159: } ! 1160: if( opsh[TEMP] ) { ! 1161: j = manyop( i, j, TEMP, &outcount ); ! 1162: opsh[TEMP] = 0; ! 1163: } ! 1164: for( k=0; k<DSIZE; ++k ) { ! 1165: if( opsh[k] ) { ! 1166: j = manyop( i, j, k, &outcount ); ! 1167: opsh[k] = 0; ! 1168: } ! 1169: } ! 1170: return( j ); ! 1171: } ! 1172: ! 1173: manyop( i, j, o, cp ) ! 1174: int *cp; ! 1175: { ! 1176: /* put out a list of S(x) for shapes matching op */ ! 1177: ! 1178: if( i<0 ) return( j ); ! 1179: if( shp[i].sop == MANY ) { ! 1180: j = manyop( shp[i].sleft, j, o, cp ); ! 1181: return( manyop( shp[i].sright, j, o, cp ) ); ! 1182: } ! 1183: if( shp[i].sop == o ) { ! 1184: printf( "S(%d), ", i ); ! 1185: if( !((++*cp)&07) ) printf( "\n\t\t" ); ! 1186: return( j+1 ); ! 1187: } ! 1188: return( j ); ! 1189: } ! 1190: ! 1191: setopsh( i ) { ! 1192: /* set opsh[k] to 1 for every op appearing in shp[i] */ ! 1193: int s; ! 1194: ! 1195: if( i<0 ) return; ! 1196: s = shp[i].sop; ! 1197: ! 1198: if( s == MANY ) { ! 1199: setopsh( shp[i].sleft ); ! 1200: setopsh( shp[i].sright ); ! 1201: } ! 1202: else opsh[s] = 1; ! 1203: } ! 1204: ! 1205: saaddr(sp) ! 1206: register sp; ! 1207: { ! 1208: if( sp < 0 ) printf( "SHNL,\t" ); ! 1209: else printf( "S(%d),\t", sp ); ! 1210: } ! 1211: ! 1212: ! 1213: int nodcnt; ! 1214: int treecnt; ! 1215: chkdups(ii) ! 1216: register ii; ! 1217: { ! 1218: treecnt = nodcnt = 0; ! 1219: chkdup1(ii); ! 1220: if(treecnt!=nodcnt) ! 1221: { ! 1222: fprintf(stderr,"DUPLICATE SHAPES IN TREE %s\n",shp[ii].shname); ! 1223: prtree("T",ii); ! 1224: } ! 1225: clrcnt(ii); ! 1226: } ! 1227: chkdup1(nn) ! 1228: register nn; ! 1229: { ! 1230: register STYSHP *p; ! 1231: ! 1232: p = &shp[nn]; ! 1233: if((p->sleft >= 0) && (p->sop==MANY)) chkdup1(p->sleft); ! 1234: if((p->sright >= 0) && (p->sop==MANY)) chkdup1(p->sright); ! 1235: p->scnt++; ! 1236: nodcnt++; ! 1237: treecnt += p->scnt; ! 1238: } ! 1239: clrcnt(nn) ! 1240: register nn; ! 1241: { ! 1242: register STYSHP *p; ! 1243: ! 1244: p = &shp[nn]; ! 1245: if(p->sleft >= 0) clrcnt(p->sleft); ! 1246: if(p->sright >= 0) clrcnt(p->sright); ! 1247: p->scnt = 0; ! 1248: } ! 1249: ! 1250: prtree(str,ii) ! 1251: register ii; ! 1252: char *str; ! 1253: { ! 1254: register STYSHP *p; ! 1255: p = &shp[ii]; ! 1256: fprintf(stderr,"%s.%d = %d",str,ii,p->scnt); ! 1257: if(p->shname[0]) fprintf(stderr," /* %s */",p->shname); ! 1258: fprintf(stderr,"\n"); ! 1259: if(p->sright>=0) prtree("R",p->sright); ! 1260: if(p->sleft>=0) prtree("L",p->sleft); ! 1261: } ! 1262: shpprint(sha, ty) ! 1263: register sha,ty; ! 1264: { ! 1265: if( sha < 0 ) printf( "\tPSHNL,\t"); ! 1266: else printf( "\tP(%d),\t", shp[sha].ssh ); ! 1267: prnam( ty, Tnam ); ! 1268: } ! 1269: ! 1270: prnam(ty,src) ! 1271: register struct nam *src; ! 1272: register ty; ! 1273: { ! 1274: register int ii,jj; ! 1275: register flag = 0; ! 1276: register struct nam *tn; ! 1277: ! 1278: if(!ty) ! 1279: { ! 1280: printf("0x0,\n"); ! 1281: return; ! 1282: } ! 1283: for(tn = src; tn->tntn; tn++) ! 1284: if( tn->tnty == ty ) ! 1285: { ! 1286: printf( "%s,\n", tn->tntn ); ! 1287: return; ! 1288: } ! 1289: for(ii = 0; ; ii++) ! 1290: { ! 1291: if((jj = (01<<ii))>ty) ! 1292: { ! 1293: printf(",\n"); ! 1294: return; ! 1295: } ! 1296: if(!(jj & ty)) ! 1297: continue; ! 1298: for(tn = src; tn->tntn; tn++) ! 1299: if(tn->tnty==jj) ! 1300: break; ! 1301: if(flag++) ! 1302: printf("|"); ! 1303: if(tn->tntn) ! 1304: printf("%s",tn->tntn); ! 1305: else ! 1306: printf("%#o",jj); ! 1307: } ! 1308: } ! 1309: ! 1310: static char name[100]; /* had better be long enough */ ! 1311: ! 1312: yylex() ! 1313: { ! 1314: register int c, i; ! 1315: ! 1316: for(;;) ! 1317: { ! 1318: ! 1319: c = getchar(); ! 1320: if( c<0 ) return( -1 ); ! 1321: switch( c ) ! 1322: { ! 1323: ! 1324: case '\n': ! 1325: ++lineno; ! 1326: case ' ': ! 1327: case '\b': ! 1328: case '\f': ! 1329: case '\v': ! 1330: case '\t': ! 1331: continue; ! 1332: ! 1333: case '<': ! 1334: case '>': ! 1335: case '+': ! 1336: case '-': ! 1337: case '=': ! 1338: case '*': ! 1339: case '%': ! 1340: case '/': ! 1341: case '&': ! 1342: case '|': ! 1343: case '^': ! 1344: case '!': ! 1345: name[0] = c; ! 1346: name[1] = getchar(); ! 1347: name[2] = '\0'; ! 1348: if( oplook() ) ! 1349: { ! 1350: if( yylval.ival == LS || yylval.ival == RS ) ! 1351: { ! 1352: if( (c=getchar()) == '=' ) ! 1353: yylval.ival = ASG yylval.ival; ! 1354: else ungetc( c, stdin ); ! 1355: } ! 1356: return( OP ); ! 1357: } ! 1358: ungetc( name[1], stdin ); ! 1359: name[1] = '\0'; ! 1360: if( oplook() ) return( OP ); ! 1361: yyerror( "cannot deal with %c", name[0] ); ! 1362: return( OP ); ! 1363: ! 1364: case '~': ! 1365: yylval.ival = COMPL; ! 1366: return( OP ); ! 1367: ! 1368: case '"': ! 1369: string = pstring; ! 1370: while( pstring < &strng[NSTRING-2] ) ! 1371: { ! 1372: switch( c = getchar() ) { ! 1373: case '\t': ! 1374: *pstring++ = '\\'; ! 1375: *pstring++ = 't'; ! 1376: break; ! 1377: case '\n': ! 1378: *pstring++ = '\\'; ! 1379: *pstring++ = 'n'; ! 1380: ++lineno; ! 1381: break; ! 1382: case '\\': /* escape */ ! 1383: *pstring++ = '\\'; ! 1384: c = getchar(); ! 1385: if( c == '\n' ) ! 1386: ++lineno; ! 1387: else if( c<0 ) ! 1388: yyerror( "missing \"" ); ! 1389: else if( isalpha(c) && isupper(c) ) ! 1390: *pstring++ = '\\'; ! 1391: *pstring++ = c; ! 1392: break; ! 1393: case '"': ! 1394: *pstring++ = '\0'; ! 1395: goto eos; ! 1396: default: ! 1397: if( c<0 ) ! 1398: yyerror( "missing \"" ); ! 1399: *pstring++ = c; ! 1400: } ! 1401: } ! 1402: eos: ! 1403: if( pstring >= &strng[NSTRING] ) ! 1404: yyerror( "s_table overflow" ); ! 1405: yylval.str = string; ! 1406: return( STR ); ! 1407: ! 1408: case '\'': ! 1409: for( i = 0; i < sizeof name - 1; ++i ) ! 1410: { ! 1411: c = getchar(); ! 1412: if( c == '\'' ) break; ! 1413: if( c == '\n' ) yyerror( "missing '" ); ! 1414: name[i] = c; ! 1415: } ! 1416: name[i] = '\0'; ! 1417: if( oplook() ) return( OP ); ! 1418: yyerror( "bad op name: '%s'", name ); ! 1419: ! 1420: case '[': ! 1421: for( i = 0; i < sizeof name - 1; ++i ) ! 1422: { ! 1423: c = getchar(); ! 1424: if( c == ']' ) break; ! 1425: if( c == '\n' ) yyerror( "missing ]" ); ! 1426: name[i] = c; ! 1427: } ! 1428: name[i] = '\0'; ! 1429: yylval.ival = tystr(name); ! 1430: return( STYPE ); ! 1431: ! 1432: case '#': /* comment */ ! 1433: while( (c = getchar()) != '\n' ) ! 1434: { ! 1435: if( c < 0 ) yyerror( "unexpected EOF" ); ! 1436: } ! 1437: ++lineno; ! 1438: continue; ! 1439: ! 1440: case '$': ! 1441: c = getchar(); ! 1442: if( isdigit(c) ) ! 1443: { ! 1444: yylval.ival = c-'0'; ! 1445: return( RREG ); ! 1446: } ! 1447: switch( c ) ! 1448: { ! 1449: case '[': return( LPRF ); ! 1450: case ']': return( RPRF ); ! 1451: case '<': return( LSHR ); ! 1452: case '>': return( RSHR ); ! 1453: case 'L': return( LRES ); ! 1454: case 'R': return( RRES ); ! 1455: case 'P': return( PNEED ); ! 1456: case 'C': return( GOODCC ); ! 1457: case 'N': return( NOVAL ); ! 1458: case 'r': return( RCOUNT ); ! 1459: case 'l': return( LCOUNT ); ! 1460: case 'A': yylval.ival = NRGS; ! 1461: return( DIG ); ! 1462: } ! 1463: yyerror( "$%c illegal", c ); ! 1464: ! 1465: default: ! 1466: if( isdigit(c) ) ! 1467: { ! 1468: yylval.ival = c-'0'; ! 1469: return( DIG ); ! 1470: } ! 1471: if( isalpha(c) ) ! 1472: { ! 1473: /* collect the name */ ! 1474: int i = 1; ! 1475: name[0] = c; ! 1476: while( isalpha( (c=getchar()) ) || isdigit(c) ) ! 1477: { ! 1478: name[i++] = c; ! 1479: } ! 1480: name[i] = '\0'; ! 1481: ungetc( c, stdin ); ! 1482: return( lookup() ); ! 1483: } ! 1484: return( c ); ! 1485: } ! 1486: } ! 1487: } ! 1488: ! 1489: struct nlist { ! 1490: char *shop; ! 1491: int vop; ! 1492: } ot[] = { ! 1493: ! 1494: "++", INCR, ! 1495: "+", PLUS, ! 1496: "--", DECR, ! 1497: "-", MINUS, ! 1498: "*", MUL, ! 1499: "%", MOD, ! 1500: "/", DIV, ! 1501: "&", AND, ! 1502: "^", ER, ! 1503: "!=", NE, ! 1504: "==", EQ, ! 1505: "UMINUS", UNARY MINUS, ! 1506: "UAND", UNARY AND, ! 1507: "STAR", STAR, ! 1508: "+=", ASG PLUS, ! 1509: "-=", ASG MINUS, ! 1510: "*=", ASG MUL, ! 1511: "/=", ASG DIV, ! 1512: "%=", ASG MOD, ! 1513: "&=", ASG AND, ! 1514: "|=", ASG OR, ! 1515: "|", OR, ! 1516: "^=", ASG ER, ! 1517: "=", ASSIGN, ! 1518: "<", LT, ! 1519: "<=", LE, ! 1520: "<<", LS, ! 1521: ">", GT, ! 1522: ">=", GE, ! 1523: ">>", RS, ! 1524: "FLD", FLD, ! 1525: "CMP", CMP, ! 1526: "COMOP", COMOP, ! 1527: "CM", CM, ! 1528: "GENLAB", GENLAB, ! 1529: "GENUBR", GENUBR, ! 1530: "GENBR", GENBR, ! 1531: "ARG", FUNARG, ! 1532: "STARG", STARG, ! 1533: "STASG", STASG, ! 1534: "INIT", INIT, ! 1535: "GOTO", GOTO, ! 1536: "CALL", CALL, ! 1537: "UCALL", UNARY CALL, ! 1538: "STCALL", STCALL, ! 1539: "USTCALL", UNARY STCALL, ! 1540: "CONV", CONV, ! 1541: "PDIV", PDIV, ! 1542: "PMUL", PMUL, ! 1543: "REG", REG, ! 1544: "CON", ICON, ! 1545: "TEMP", TEMP, ! 1546: "AUTO", VAUTO, ! 1547: "PARAM", VPARAM, ! 1548: "NAME", NAME, ! 1549: "RNODE", RNODE, ! 1550: "SNODE", SNODE, ! 1551: "QNODE", QNODE, ! 1552: "CC", CCODES, ! 1553: "FREE", FREE, ! 1554: "UOP0", UOP0, ! 1555: "UOP1", UOP1, ! 1556: "UOP2", UOP2, ! 1557: "UOP3", UOP3, ! 1558: "UOP4", UOP4, ! 1559: "UOP5", UOP5, ! 1560: "UOP6", UOP6, ! 1561: "UOP7", UOP7, ! 1562: "UOP8", UOP8, ! 1563: "UOP9", UOP9, ! 1564: "", -1 }; ! 1565: ! 1566: oplook() ! 1567: { ! 1568: /* look up the first n chars of name in the above table */ ! 1569: /* return 1 if it is an op, after setting yylval */ ! 1570: register int i; ! 1571: for( i=0; ot[i].vop >= 0; ++i ) ! 1572: { ! 1573: if( !strcmp( name, ot[i].shop ) ) ! 1574: { ! 1575: yylval.ival = ot[i].vop; ! 1576: return( 1 ); ! 1577: } ! 1578: } ! 1579: return( 0 ); ! 1580: } ! 1581: ! 1582: tystr( p ) ! 1583: register char *p; /* pointer to name */ ! 1584: { ! 1585: register i; ! 1586: ! 1587: /* lookup the types in name */ ! 1588: if( !*p ) ! 1589: return( TANY ); ! 1590: else ! 1591: i = 0; ! 1592: for(;;) ! 1593: { ! 1594: switch( *p++ ) ! 1595: { ! 1596: case '\0': ! 1597: return( i ); ! 1598: ! 1599: case 'c': ! 1600: i |= TCHAR; ! 1601: case ' ': ! 1602: case ',': ! 1603: continue; ! 1604: ! 1605: case 's': ! 1606: i |= TSHORT; ! 1607: continue; ! 1608: ! 1609: case 'i': ! 1610: i |= TINT; ! 1611: continue; ! 1612: ! 1613: case 'l': ! 1614: i |= TLONG; ! 1615: continue; ! 1616: ! 1617: case 'f': ! 1618: i |= TFLOAT; ! 1619: continue; ! 1620: ! 1621: case 'd': ! 1622: i |= TDOUBLE; ! 1623: continue; ! 1624: ! 1625: case 'P': ! 1626: i |= TPOINT2; ! 1627: continue; ! 1628: ! 1629: case 'p': ! 1630: i |= TPOINT; ! 1631: continue; ! 1632: ! 1633: case 't': ! 1634: i |= TSTRUCT; ! 1635: continue; ! 1636: ! 1637: case 'v': ! 1638: /* later.. ! 1639: i |= TVOID; ! 1640: */ ! 1641: continue; ! 1642: ! 1643: case 'u': ! 1644: switch( *p ) ! 1645: { ! 1646: case 'i': i |= TUNSIGNED; break; ! 1647: case 's': i |= TUSHORT; break; ! 1648: case 'c': i |= TUCHAR; break; ! 1649: case 'l': i |= TULONG; break; ! 1650: default: yyerror( "bad u%c type", *p ); ! 1651: } ! 1652: ++p; ! 1653: continue; ! 1654: ! 1655: default: ! 1656: yyerror( "illegal type: %c", p[-1] ); ! 1657: } ! 1658: } ! 1659: } ! 1660: ! 1661: struct nlist resw[] = { ! 1662: NameV(DCOST), ! 1663: NameV(SHAPES), ! 1664: NameV(OPCODES), ! 1665: NameV(USERCOST), ! 1666: NameV(CONVAL), ! 1667: NameV(NCONVAL), ! 1668: NameV(POSRANGE), ! 1669: NameV(SGRANGE), ! 1670: NameV(NONAME), ! 1671: "", -1, ! 1672: }; ! 1673: ! 1674: lookup() ! 1675: { ! 1676: /* look up the shape name in name, and return the index */ ! 1677: register STYSHP *p; ! 1678: register int i; ! 1679: for( i=0; resw[i].vop >= 0; ++i ) ! 1680: { ! 1681: if( !strcmp( name, resw[i].shop ) ) return( resw[i].vop ); ! 1682: } ! 1683: for( i=NSTYSHPS-1, p= &shp[NSTYSHPS-1]; i>nmshp; --i,--p ) ! 1684: { ! 1685: if( !strncmp( name, p->shname, 8 ) ) ! 1686: { ! 1687: /* match */ ! 1688: yylval.ival = i; ! 1689: return( NM ); ! 1690: } ! 1691: } ! 1692: /* new entry */ ! 1693: strncpy( p->shname, name, 8 ); ! 1694: p->scset = p->ssh = p->scost = 0; ! 1695: p->sleft = p->sright = -1; ! 1696: p->sop = -1; ! 1697: yylval.ival = nmshp--; ! 1698: if( nmshp <= nshp ) { ! 1699: yyerror( "out of node space" ); ! 1700: exit( 1 ); ! 1701: } ! 1702: return( NM ); ! 1703: } ! 1704: ! 1705: setcost ( sn, cst ) ! 1706: register int sn,cst; ! 1707: { ! 1708: /* set costs for shape at all reference points. ! 1709: /* reference points all are just below MANY ops ! 1710: */ ! 1711: if ( sn < 0 ) ! 1712: return; ! 1713: if ( shp[sn].sop == MANY ) ! 1714: { ! 1715: setcost( shp[sn].sleft, cst ); ! 1716: setcost( shp[sn].sright, cst ); ! 1717: } ! 1718: else if ( was_cost ) ! 1719: { ! 1720: if ( shp[sn].scset ) ! 1721: { ! 1722: if ( shp[sn].scost == cst ) ! 1723: return; ! 1724: yyerror( "Inconsistent cost values for shared shape" ); ! 1725: } ! 1726: else ! 1727: { ! 1728: shp[sn].scost = cst; ! 1729: shp[sn].scset = 1; ! 1730: } ! 1731: } ! 1732: else ! 1733: { ! 1734: shp[sn].scset = 1; ! 1735: } ! 1736: } ! 1737: ! 1738: sharecost ( sn, cst ) ! 1739: register int sn,cst; ! 1740: { ! 1741: if ( sn == nshp - 1 ) /* quick opt. there is only one choice */ ! 1742: { ! 1743: shp[sn].scost = cst; ! 1744: shp[sn].scset = 1; ! 1745: return(sn); ! 1746: } ! 1747: /* if ( cst == 0 ) ! 1748: /* return( sn ); ! 1749: */ ! 1750: ! 1751: setcost(sn, cst); ! 1752: return (sn); ! 1753: /* if (nshp >= NSTYSHPS) ! 1754: /* yyerror("too many shapes"); ! 1755: /* shp[nshp] = shp[sn]; ! 1756: /* shp[nshp].scost += cst; ! 1757: /* nshp++; ! 1758: /* checkit( nshp-1 ); ! 1759: /* return( nshp-1 ); ! 1760: */ ! 1761: } ! 1762: ! 1763: uopcost (o, a) ! 1764: register int o,a; ! 1765: { ! 1766: switch(o) ! 1767: { ! 1768: default: ! 1769: case MUL: ! 1770: case AND: yyerror("Illegal unary cost operator"); ! 1771: return(0); ! 1772: case MINUS: ! 1773: return(-a); ! 1774: } ! 1775: } ! 1776: ! 1777: bopcost (o, a, b) ! 1778: register int o,a,b; ! 1779: { ! 1780: switch(o) ! 1781: { ! 1782: case INCR: ! 1783: case PLUS: return(a+b); ! 1784: case DECR: ! 1785: case MINUS: return(a-b); ! 1786: case MUL: return(a*b); ! 1787: case DIV: return(a/b); ! 1788: case MOD: return(a%b); ! 1789: case LS: return(a>>b); ! 1790: case RS: return(a<<b); ! 1791: case OR: return(a|b); ! 1792: case ER: return(a^b); ! 1793: case AND: return(a&b); ! 1794: case LT: return(a<b); ! 1795: case GT: return(a>b); ! 1796: case LE: return(a<=b); ! 1797: case GE: return(a>=b); ! 1798: case NE: return(a!=b); ! 1799: case EQ: return(a==b); ! 1800: default: yyerror("Illegal binary operator"); ! 1801: return(0); ! 1802: } ! 1803: } ! 1804: ! 1805: /* print operator name ! 1806: */ ! 1807: static ! 1808: prop( op ) ! 1809: register int op; ! 1810: { ! 1811: register struct nam *np; ! 1812: static struct nam Opnam[] = { ! 1813: NameV(INCR), ! 1814: NameV(PLUS), ! 1815: NameV(DECR), ! 1816: NameV(MINUS), ! 1817: NameV(MUL), ! 1818: NameV(MOD), ! 1819: NameV(DIV), ! 1820: NameV(AND), ! 1821: NameV(ER), ! 1822: NameV(NE), ! 1823: NameV(EQ), ! 1824: NameV(UNARY MINUS), ! 1825: NameV(UNARY AND), ! 1826: NameV(STAR), ! 1827: NameV(ASG PLUS), ! 1828: NameV(ASG MINUS), ! 1829: NameV(ASG MUL), ! 1830: NameV(ASG DIV), ! 1831: NameV(ASG MOD), ! 1832: NameV(ASG AND), ! 1833: NameV(ASG OR), ! 1834: NameV(OR), ! 1835: NameV(ASG ER), ! 1836: NameV(ASSIGN), ! 1837: NameV(LT), ! 1838: NameV(LE), ! 1839: NameV(LS), ! 1840: NameV(GT), ! 1841: NameV(GE), ! 1842: NameV(RS), ! 1843: NameV(FLD), ! 1844: NameV(CMP), ! 1845: NameV(COMOP), ! 1846: NameV(CM), ! 1847: NameV(GENLAB), ! 1848: NameV(GENUBR), ! 1849: NameV(GENBR), ! 1850: NameV(FUNARG), ! 1851: NameV(STARG), ! 1852: NameV(STASG), ! 1853: NameV(INIT), ! 1854: NameV(GOTO), ! 1855: NameV(CALL), ! 1856: NameV(UNARY CALL), ! 1857: NameV(STCALL), ! 1858: NameV(UNARY STCALL), ! 1859: NameV(CONV), ! 1860: NameV(PDIV), ! 1861: NameV(PMUL), ! 1862: NameV(REG), ! 1863: NameV(ICON), ! 1864: NameV(TEMP), ! 1865: NameV(VAUTO), ! 1866: NameV(VPARAM), ! 1867: NameV(NAME), ! 1868: NameV(RNODE), ! 1869: NameV(SNODE), ! 1870: NameV(QNODE), ! 1871: NameV(CCODES), ! 1872: NameV(FREE), ! 1873: 0, 0, ! 1874: }; ! 1875: for( np = Opnam; np->tnty; np++ ) ! 1876: { ! 1877: if( op == np->tnty ) ! 1878: { ! 1879: printf( "%s,", np->tntn ); ! 1880: return; ! 1881: } ! 1882: } ! 1883: printf( "%d,", op ); ! 1884: } ! 1885: ! 1886: ! 1887: /* ! 1888: check the op table for duplicate or partially duplicate templates ! 1889: */ ! 1890: static ! 1891: optbck() ! 1892: { ! 1893: #define EqOptb(a) (q->a == q1->a) ! 1894: register int i; ! 1895: register int j; ! 1896: register OPTB *q; ! 1897: register OPTB *q1; ! 1898: ! 1899: for( i = 0; i < opno; i++ ) ! 1900: { ! 1901: q = &optb[i]; ! 1902: for( j = 0; j < i; j++ ) ! 1903: { ! 1904: q1 = &optb[j]; ! 1905: if( ! 1906: EqOptb(op) && ! 1907: EqOptb(l.ty) && ! 1908: EqOptb(r.ty) && ! 1909: EqOptb(orew) && ! 1910: EqOptb(oneeds) && ! 1911: shapeshr(q->l.sha, q1->l.sha) && ! 1912: shapeshr(q->r.sha, q1->r.sha) ! 1913: ) ! 1914: { ! 1915: fprintf( stderr, ! 1916: "line %d may be covered by line %d\n", ! 1917: q->line, q1->line ); ! 1918: break; ! 1919: } ! 1920: } ! 1921: } ! 1922: } ! 1923: ! 1924: ! 1925: /* do the shape trees starting at s1 and s2 share any elements? ! 1926: */ ! 1927: static ! 1928: shapeshr( s1, s2 ) ! 1929: register int s1; /* indexes into shape table */ ! 1930: register int s2; ! 1931: { ! 1932: register int i1; ! 1933: ! 1934: for( i1 = s1; shp[i1].sleft >= 0; i1 = shp[i1].sleft ) ! 1935: { ! 1936: if( i1 == s2 || shp[i1].sright == s2 ) ! 1937: return 1; ! 1938: } ! 1939: return 0; ! 1940: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.