github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6a/a.y (about) 1 // Inferno utils/6a/a.y 2 // http://code.google.com/p/inferno-os/source/browse/utils/6a/a.y 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 %{ 32 #include <u.h> 33 #include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */ 34 #include <libc.h> 35 #include "a.h" 36 #include "../../pkg/runtime/funcdata.h" 37 %} 38 %union { 39 Sym *sym; 40 vlong lval; 41 double dval; 42 char sval[8]; 43 Gen gen; 44 Gen2 gen2; 45 } 46 %left '|' 47 %left '^' 48 %left '&' 49 %left '<' '>' 50 %left '+' '-' 51 %left '*' '/' '%' 52 %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 53 %token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC 54 %token <lval> LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF 55 %token <lval> LCONST LFP LPC LSB 56 %token <lval> LBREG LLREG LSREG LFREG LMREG LXREG 57 %token <dval> LFCONST 58 %token <sval> LSCONST LSP 59 %token <sym> LNAME LLAB LVAR 60 %type <lval> con con2 expr pointer offset 61 %type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem 62 %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim 63 %type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 64 %type <gen2> spec10 spec11 spec12 spec13 65 %% 66 prog: 67 | prog 68 { 69 stmtline = lineno; 70 } 71 line 72 73 line: 74 LLAB ':' 75 { 76 if($1->value != pc) 77 yyerror("redeclaration of %s", $1->name); 78 $1->value = pc; 79 } 80 line 81 | LNAME ':' 82 { 83 $1->type = LLAB; 84 $1->value = pc; 85 } 86 line 87 | ';' 88 | inst ';' 89 | error ';' 90 91 inst: 92 LNAME '=' expr 93 { 94 $1->type = LVAR; 95 $1->value = $3; 96 } 97 | LVAR '=' expr 98 { 99 if($1->value != $3) 100 yyerror("redeclaration of %s", $1->name); 101 $1->value = $3; 102 } 103 | LTYPE0 nonnon { outcode($1, &$2); } 104 | LTYPE1 nonrem { outcode($1, &$2); } 105 | LTYPE2 rimnon { outcode($1, &$2); } 106 | LTYPE3 rimrem { outcode($1, &$2); } 107 | LTYPE4 remrim { outcode($1, &$2); } 108 | LTYPER nonrel { outcode($1, &$2); } 109 | LTYPED spec1 { outcode($1, &$2); } 110 | LTYPET spec2 { outcode($1, &$2); } 111 | LTYPEC spec3 { outcode($1, &$2); } 112 | LTYPEN spec4 { outcode($1, &$2); } 113 | LTYPES spec5 { outcode($1, &$2); } 114 | LTYPEM spec6 { outcode($1, &$2); } 115 | LTYPEI spec7 { outcode($1, &$2); } 116 | LTYPEXC spec8 { outcode($1, &$2); } 117 | LTYPEX spec9 { outcode($1, &$2); } 118 | LTYPERT spec10 { outcode($1, &$2); } 119 | LTYPEG spec11 { outcode($1, &$2); } 120 | LTYPEPC spec12 { outcode($1, &$2); } 121 | LTYPEF spec13 { outcode($1, &$2); } 122 123 nonnon: 124 { 125 $$.from = nullgen; 126 $$.to = nullgen; 127 } 128 | ',' 129 { 130 $$.from = nullgen; 131 $$.to = nullgen; 132 } 133 134 rimrem: 135 rim ',' rem 136 { 137 $$.from = $1; 138 $$.to = $3; 139 } 140 141 remrim: 142 rem ',' rim 143 { 144 $$.from = $1; 145 $$.to = $3; 146 } 147 148 rimnon: 149 rim ',' 150 { 151 $$.from = $1; 152 $$.to = nullgen; 153 } 154 | rim 155 { 156 $$.from = $1; 157 $$.to = nullgen; 158 } 159 160 nonrem: 161 ',' rem 162 { 163 $$.from = nullgen; 164 $$.to = $2; 165 } 166 | rem 167 { 168 $$.from = nullgen; 169 $$.to = $1; 170 } 171 172 nonrel: 173 ',' rel 174 { 175 $$.from = nullgen; 176 $$.to = $2; 177 } 178 | rel 179 { 180 $$.from = nullgen; 181 $$.to = $1; 182 } 183 | imm ',' rel 184 { 185 $$.from = $1; 186 $$.to = $3; 187 } 188 189 spec1: /* DATA */ 190 nam '/' con ',' imm 191 { 192 $$.from = $1; 193 $$.from.scale = $3; 194 $$.to = $5; 195 } 196 197 spec2: /* TEXT */ 198 mem ',' imm2 199 { 200 $$.from = $1; 201 $$.to = $3; 202 } 203 | mem ',' con ',' imm2 204 { 205 $$.from = $1; 206 $$.from.scale = $3; 207 $$.to = $5; 208 } 209 210 spec3: /* JMP/CALL */ 211 ',' rom 212 { 213 $$.from = nullgen; 214 $$.to = $2; 215 } 216 | rom 217 { 218 $$.from = nullgen; 219 $$.to = $1; 220 } 221 222 spec4: /* NOP */ 223 nonnon 224 | nonrem 225 226 spec5: /* SHL/SHR */ 227 rim ',' rem 228 { 229 $$.from = $1; 230 $$.to = $3; 231 } 232 | rim ',' rem ':' LLREG 233 { 234 $$.from = $1; 235 $$.to = $3; 236 if($$.from.index != D_NONE) 237 yyerror("dp shift with lhs index"); 238 $$.from.index = $5; 239 } 240 241 spec6: /* MOVW/MOVL */ 242 rim ',' rem 243 { 244 $$.from = $1; 245 $$.to = $3; 246 } 247 | rim ',' rem ':' LSREG 248 { 249 $$.from = $1; 250 $$.to = $3; 251 if($$.to.index != D_NONE) 252 yyerror("dp move with lhs index"); 253 $$.to.index = $5; 254 } 255 256 spec7: 257 rim ',' 258 { 259 $$.from = $1; 260 $$.to = nullgen; 261 } 262 | rim 263 { 264 $$.from = $1; 265 $$.to = nullgen; 266 } 267 | rim ',' rem 268 { 269 $$.from = $1; 270 $$.to = $3; 271 } 272 273 spec8: /* CMPPS/CMPPD */ 274 reg ',' rem ',' con 275 { 276 $$.from = $1; 277 $$.to = $3; 278 $$.to.offset = $5; 279 } 280 281 spec9: /* shufl */ 282 imm ',' rem ',' reg 283 { 284 $$.from = $3; 285 $$.to = $5; 286 if($1.type != D_CONST) 287 yyerror("illegal constant"); 288 $$.to.offset = $1.offset; 289 } 290 291 spec10: /* RET/RETF */ 292 { 293 $$.from = nullgen; 294 $$.to = nullgen; 295 } 296 | imm 297 { 298 $$.from = $1; 299 $$.to = nullgen; 300 } 301 302 spec11: /* GLOBL */ 303 mem ',' imm 304 { 305 $$.from = $1; 306 $$.to = $3; 307 } 308 | mem ',' con ',' imm 309 { 310 $$.from = $1; 311 $$.from.scale = $3; 312 $$.to = $5; 313 } 314 315 spec12: /* PCDATA */ 316 rim ',' rim 317 { 318 if($1.type != D_CONST || $3.type != D_CONST) 319 yyerror("arguments to PCDATA must be integer constants"); 320 $$.from = $1; 321 $$.to = $3; 322 } 323 324 spec13: /* FUNCDATA */ 325 rim ',' rim 326 { 327 if($1.type != D_CONST) 328 yyerror("index for FUNCDATA must be integer constant"); 329 if($3.type != D_EXTERN && $3.type != D_STATIC) 330 yyerror("value for FUNCDATA must be symbol reference"); 331 $$.from = $1; 332 $$.to = $3; 333 } 334 335 rem: 336 reg 337 | mem 338 339 rom: 340 rel 341 | nmem 342 | '*' reg 343 { 344 $$ = $2; 345 } 346 | '*' omem 347 { 348 $$ = $2; 349 } 350 | reg 351 | omem 352 353 rim: 354 rem 355 | imm 356 357 rel: 358 con '(' LPC ')' 359 { 360 $$ = nullgen; 361 $$.type = D_BRANCH; 362 $$.offset = $1 + pc; 363 } 364 | LNAME offset 365 { 366 $$ = nullgen; 367 if(pass == 2) 368 yyerror("undefined label: %s", $1->name); 369 $$.type = D_BRANCH; 370 $$.sym = $1; 371 $$.offset = $2; 372 } 373 | LLAB offset 374 { 375 $$ = nullgen; 376 $$.type = D_BRANCH; 377 $$.sym = $1; 378 $$.offset = $1->value + $2; 379 } 380 381 reg: 382 LBREG 383 { 384 $$ = nullgen; 385 $$.type = $1; 386 } 387 | LFREG 388 { 389 $$ = nullgen; 390 $$.type = $1; 391 } 392 | LLREG 393 { 394 $$ = nullgen; 395 $$.type = $1; 396 } 397 | LMREG 398 { 399 $$ = nullgen; 400 $$.type = $1; 401 } 402 | LSP 403 { 404 $$ = nullgen; 405 $$.type = D_SP; 406 } 407 | LSREG 408 { 409 $$ = nullgen; 410 $$.type = $1; 411 } 412 | LXREG 413 { 414 $$ = nullgen; 415 $$.type = $1; 416 } 417 imm2: 418 '$' con2 419 { 420 $$ = nullgen; 421 $$.type = D_CONST; 422 $$.offset = $2; 423 } 424 425 imm: 426 '$' con 427 { 428 $$ = nullgen; 429 $$.type = D_CONST; 430 $$.offset = $2; 431 } 432 | '$' nam 433 { 434 $$ = $2; 435 $$.index = $2.type; 436 $$.type = D_ADDR; 437 /* 438 if($2.type == D_AUTO || $2.type == D_PARAM) 439 yyerror("constant cannot be automatic: %s", 440 $2.sym->name); 441 */ 442 } 443 | '$' LSCONST 444 { 445 $$ = nullgen; 446 $$.type = D_SCONST; 447 memcpy($$.sval, $2, sizeof($$.sval)); 448 } 449 | '$' LFCONST 450 { 451 $$ = nullgen; 452 $$.type = D_FCONST; 453 $$.dval = $2; 454 } 455 | '$' '(' LFCONST ')' 456 { 457 $$ = nullgen; 458 $$.type = D_FCONST; 459 $$.dval = $3; 460 } 461 | '$' '(' '-' LFCONST ')' 462 { 463 $$ = nullgen; 464 $$.type = D_FCONST; 465 $$.dval = -$4; 466 } 467 | '$' '-' LFCONST 468 { 469 $$ = nullgen; 470 $$.type = D_FCONST; 471 $$.dval = -$3; 472 } 473 474 mem: 475 omem 476 | nmem 477 478 omem: 479 con 480 { 481 $$ = nullgen; 482 $$.type = D_INDIR+D_NONE; 483 $$.offset = $1; 484 } 485 | con '(' LLREG ')' 486 { 487 $$ = nullgen; 488 $$.type = D_INDIR+$3; 489 $$.offset = $1; 490 } 491 | con '(' LSP ')' 492 { 493 $$ = nullgen; 494 $$.type = D_INDIR+D_SP; 495 $$.offset = $1; 496 } 497 | con '(' LSREG ')' 498 { 499 $$ = nullgen; 500 $$.type = D_INDIR+$3; 501 $$.offset = $1; 502 } 503 | con '(' LLREG '*' con ')' 504 { 505 $$ = nullgen; 506 $$.type = D_INDIR+D_NONE; 507 $$.offset = $1; 508 $$.index = $3; 509 $$.scale = $5; 510 checkscale($$.scale); 511 } 512 | con '(' LLREG ')' '(' LLREG '*' con ')' 513 { 514 $$ = nullgen; 515 $$.type = D_INDIR+$3; 516 $$.offset = $1; 517 $$.index = $6; 518 $$.scale = $8; 519 checkscale($$.scale); 520 } 521 | con '(' LLREG ')' '(' LSREG '*' con ')' 522 { 523 $$ = nullgen; 524 $$.type = D_INDIR+$3; 525 $$.offset = $1; 526 $$.index = $6; 527 $$.scale = $8; 528 checkscale($$.scale); 529 } 530 | '(' LLREG ')' 531 { 532 $$ = nullgen; 533 $$.type = D_INDIR+$2; 534 } 535 | '(' LSP ')' 536 { 537 $$ = nullgen; 538 $$.type = D_INDIR+D_SP; 539 } 540 | '(' LLREG '*' con ')' 541 { 542 $$ = nullgen; 543 $$.type = D_INDIR+D_NONE; 544 $$.index = $2; 545 $$.scale = $4; 546 checkscale($$.scale); 547 } 548 | '(' LLREG ')' '(' LLREG '*' con ')' 549 { 550 $$ = nullgen; 551 $$.type = D_INDIR+$2; 552 $$.index = $5; 553 $$.scale = $7; 554 checkscale($$.scale); 555 } 556 557 nmem: 558 nam 559 { 560 $$ = $1; 561 } 562 | nam '(' LLREG '*' con ')' 563 { 564 $$ = $1; 565 $$.index = $3; 566 $$.scale = $5; 567 checkscale($$.scale); 568 } 569 570 nam: 571 LNAME offset '(' pointer ')' 572 { 573 $$ = nullgen; 574 $$.type = $4; 575 $$.sym = $1; 576 $$.offset = $2; 577 } 578 | LNAME '<' '>' offset '(' LSB ')' 579 { 580 $$ = nullgen; 581 $$.type = D_STATIC; 582 $$.sym = $1; 583 $$.offset = $4; 584 } 585 586 offset: 587 { 588 $$ = 0; 589 } 590 | '+' con 591 { 592 $$ = $2; 593 } 594 | '-' con 595 { 596 $$ = -$2; 597 } 598 599 pointer: 600 LSB 601 | LSP 602 { 603 $$ = D_AUTO; 604 } 605 | LFP 606 607 con: 608 LCONST 609 | LVAR 610 { 611 $$ = $1->value; 612 } 613 | '-' con 614 { 615 $$ = -$2; 616 } 617 | '+' con 618 { 619 $$ = $2; 620 } 621 | '~' con 622 { 623 $$ = ~$2; 624 } 625 | '(' expr ')' 626 { 627 $$ = $2; 628 } 629 630 con2: 631 LCONST 632 { 633 $$ = ($1 & 0xffffffffLL) + 634 ((vlong)ArgsSizeUnknown << 32); 635 } 636 | '-' LCONST 637 { 638 $$ = (-$2 & 0xffffffffLL) + 639 ((vlong)ArgsSizeUnknown << 32); 640 } 641 | LCONST '-' LCONST 642 { 643 $$ = ($1 & 0xffffffffLL) + 644 (($3 & 0xffffLL) << 32); 645 } 646 | '-' LCONST '-' LCONST 647 { 648 $$ = (-$2 & 0xffffffffLL) + 649 (($4 & 0xffffLL) << 32); 650 } 651 652 expr: 653 con 654 | expr '+' expr 655 { 656 $$ = $1 + $3; 657 } 658 | expr '-' expr 659 { 660 $$ = $1 - $3; 661 } 662 | expr '*' expr 663 { 664 $$ = $1 * $3; 665 } 666 | expr '/' expr 667 { 668 $$ = $1 / $3; 669 } 670 | expr '%' expr 671 { 672 $$ = $1 % $3; 673 } 674 | expr '<' '<' expr 675 { 676 $$ = $1 << $4; 677 } 678 | expr '>' '>' expr 679 { 680 $$ = $1 >> $4; 681 } 682 | expr '&' expr 683 { 684 $$ = $1 & $3; 685 } 686 | expr '^' expr 687 { 688 $$ = $1 ^ $3; 689 } 690 | expr '|' expr 691 { 692 $$ = $1 | $3; 693 }