github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8a/a.y (about) 1 // Inferno utils/8a/a.y 2 // http://code.google.com/p/inferno-os/source/browse/utils/8a/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 int32 lval; 41 struct { 42 int32 v1; 43 int32 v2; 44 } con2; 45 double dval; 46 char sval[8]; 47 Gen gen; 48 Gen2 gen2; 49 } 50 %left '|' 51 %left '^' 52 %left '&' 53 %left '<' '>' 54 %left '+' '-' 55 %left '*' '/' '%' 56 %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 57 %token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC 58 %token <lval> LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB 59 %token <lval> LBREG LLREG LSREG LFREG LXREG 60 %token <dval> LFCONST 61 %token <sval> LSCONST LSP 62 %token <sym> LNAME LLAB LVAR 63 %type <lval> con expr pointer offset 64 %type <con2> con2 65 %type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem 66 %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim 67 %type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 68 %% 69 prog: 70 | prog 71 { 72 stmtline = lineno; 73 } 74 line 75 76 line: 77 LLAB ':' 78 { 79 if($1->value != pc) 80 yyerror("redeclaration of %s", $1->name); 81 $1->value = pc; 82 } 83 line 84 | LNAME ':' 85 { 86 $1->type = LLAB; 87 $1->value = pc; 88 } 89 line 90 | ';' 91 | inst ';' 92 | error ';' 93 94 inst: 95 LNAME '=' expr 96 { 97 $1->type = LVAR; 98 $1->value = $3; 99 } 100 | LVAR '=' expr 101 { 102 if($1->value != $3) 103 yyerror("redeclaration of %s", $1->name); 104 $1->value = $3; 105 } 106 | LTYPE0 nonnon { outcode($1, &$2); } 107 | LTYPE1 nonrem { outcode($1, &$2); } 108 | LTYPE2 rimnon { outcode($1, &$2); } 109 | LTYPE3 rimrem { outcode($1, &$2); } 110 | LTYPE4 remrim { outcode($1, &$2); } 111 | LTYPER nonrel { outcode($1, &$2); } 112 | LTYPED spec1 { outcode($1, &$2); } 113 | LTYPET spec2 { outcode($1, &$2); } 114 | LTYPEC spec3 { outcode($1, &$2); } 115 | LTYPEN spec4 { outcode($1, &$2); } 116 | LTYPES spec5 { outcode($1, &$2); } 117 | LTYPEM spec6 { outcode($1, &$2); } 118 | LTYPEI spec7 { outcode($1, &$2); } 119 | LTYPEG spec8 { outcode($1, &$2); } 120 | LTYPEXC spec9 { outcode($1, &$2); } 121 | LTYPEX spec10 { outcode($1, &$2); } 122 | LTYPEPC spec11 { outcode($1, &$2); } 123 | LTYPEF spec12 { outcode($1, &$2); } 124 125 nonnon: 126 { 127 $$.from = nullgen; 128 $$.to = nullgen; 129 } 130 | ',' 131 { 132 $$.from = nullgen; 133 $$.to = nullgen; 134 } 135 136 rimrem: 137 rim ',' rem 138 { 139 $$.from = $1; 140 $$.to = $3; 141 } 142 143 remrim: 144 rem ',' rim 145 { 146 $$.from = $1; 147 $$.to = $3; 148 } 149 150 rimnon: 151 rim ',' 152 { 153 $$.from = $1; 154 $$.to = nullgen; 155 } 156 | rim 157 { 158 $$.from = $1; 159 $$.to = nullgen; 160 } 161 162 nonrem: 163 ',' rem 164 { 165 $$.from = nullgen; 166 $$.to = $2; 167 } 168 | rem 169 { 170 $$.from = nullgen; 171 $$.to = $1; 172 } 173 174 nonrel: 175 ',' rel 176 { 177 $$.from = nullgen; 178 $$.to = $2; 179 } 180 | rel 181 { 182 $$.from = nullgen; 183 $$.to = $1; 184 } 185 | imm ',' rel 186 { 187 $$.from = $1; 188 $$.to = $3; 189 } 190 191 spec1: /* DATA */ 192 nam '/' con ',' imm 193 { 194 $$.from = $1; 195 $$.from.scale = $3; 196 $$.to = $5; 197 } 198 199 spec2: /* TEXT */ 200 mem ',' imm2 201 { 202 $$.from = $1; 203 $$.to = $3; 204 } 205 | mem ',' con ',' imm2 206 { 207 $$.from = $1; 208 $$.from.scale = $3; 209 $$.to = $5; 210 } 211 212 spec3: /* JMP/CALL */ 213 ',' rom 214 { 215 $$.from = nullgen; 216 $$.to = $2; 217 } 218 | rom 219 { 220 $$.from = nullgen; 221 $$.to = $1; 222 } 223 | '*' nam 224 { 225 $$.from = nullgen; 226 $$.to = $2; 227 $$.to.index = $2.type; 228 $$.to.type = D_INDIR+D_ADDR; 229 } 230 231 spec4: /* NOP */ 232 nonnon 233 | nonrem 234 235 spec5: /* SHL/SHR */ 236 rim ',' rem 237 { 238 $$.from = $1; 239 $$.to = $3; 240 } 241 | rim ',' rem ':' LLREG 242 { 243 $$.from = $1; 244 $$.to = $3; 245 if($$.from.index != D_NONE) 246 yyerror("dp shift with lhs index"); 247 $$.from.index = $5; 248 } 249 250 spec6: /* MOVW/MOVL */ 251 rim ',' rem 252 { 253 $$.from = $1; 254 $$.to = $3; 255 } 256 | rim ',' rem ':' LSREG 257 { 258 $$.from = $1; 259 $$.to = $3; 260 if($$.to.index != D_NONE) 261 yyerror("dp move with lhs index"); 262 $$.to.index = $5; 263 } 264 265 spec7: 266 rim ',' 267 { 268 $$.from = $1; 269 $$.to = nullgen; 270 } 271 | rim 272 { 273 $$.from = $1; 274 $$.to = nullgen; 275 } 276 | rim ',' rem 277 { 278 $$.from = $1; 279 $$.to = $3; 280 } 281 282 spec8: /* GLOBL */ 283 mem ',' imm 284 { 285 $$.from = $1; 286 $$.to = $3; 287 } 288 | mem ',' con ',' imm 289 { 290 $$.from = $1; 291 $$.from.scale = $3; 292 $$.to = $5; 293 } 294 295 spec9: /* CMPPS/CMPPD */ 296 reg ',' rem ',' con 297 { 298 $$.from = $1; 299 $$.to = $3; 300 $$.to.offset = $5; 301 } 302 303 spec10: /* PINSRD */ 304 imm ',' rem ',' reg 305 { 306 $$.from = $3; 307 $$.to = $5; 308 if($1.type != D_CONST) 309 yyerror("illegal constant"); 310 $$.to.offset = $1.offset; 311 } 312 313 spec11: /* PCDATA */ 314 rim ',' rim 315 { 316 if($1.type != D_CONST || $3.type != D_CONST) 317 yyerror("arguments to PCDATA must be integer constants"); 318 $$.from = $1; 319 $$.to = $3; 320 } 321 322 spec12: /* FUNCDATA */ 323 rim ',' rim 324 { 325 if($1.type != D_CONST) 326 yyerror("index for FUNCDATA must be integer constant"); 327 if($3.type != D_EXTERN && $3.type != D_STATIC) 328 yyerror("value for FUNCDATA must be symbol reference"); 329 $$.from = $1; 330 $$.to = $3; 331 } 332 333 rem: 334 reg 335 | mem 336 337 rom: 338 rel 339 | nmem 340 | '*' reg 341 { 342 $$ = $2; 343 } 344 | '*' omem 345 { 346 $$ = $2; 347 } 348 | reg 349 | omem 350 | imm 351 352 rim: 353 rem 354 | imm 355 356 rel: 357 con '(' LPC ')' 358 { 359 $$ = nullgen; 360 $$.type = D_BRANCH; 361 $$.offset = $1 + pc; 362 } 363 | LNAME offset 364 { 365 $$ = nullgen; 366 if(pass == 2) 367 yyerror("undefined label: %s", $1->name); 368 $$.type = D_BRANCH; 369 $$.sym = $1; 370 $$.offset = $2; 371 } 372 | LLAB offset 373 { 374 $$ = nullgen; 375 $$.type = D_BRANCH; 376 $$.sym = $1; 377 $$.offset = $1->value + $2; 378 } 379 380 reg: 381 LBREG 382 { 383 $$ = nullgen; 384 $$.type = $1; 385 } 386 | LFREG 387 { 388 $$ = nullgen; 389 $$.type = $1; 390 } 391 | LLREG 392 { 393 $$ = nullgen; 394 $$.type = $1; 395 } 396 | LXREG 397 { 398 $$ = nullgen; 399 $$.type = $1; 400 } 401 | LSP 402 { 403 $$ = nullgen; 404 $$.type = D_SP; 405 } 406 | LSREG 407 { 408 $$ = nullgen; 409 $$.type = $1; 410 } 411 412 imm: 413 '$' con 414 { 415 $$ = nullgen; 416 $$.type = D_CONST; 417 $$.offset = $2; 418 } 419 | '$' nam 420 { 421 $$ = $2; 422 $$.index = $2.type; 423 $$.type = D_ADDR; 424 /* 425 if($2.type == D_AUTO || $2.type == D_PARAM) 426 yyerror("constant cannot be automatic: %s", 427 $2.sym->name); 428 */ 429 } 430 | '$' LSCONST 431 { 432 $$ = nullgen; 433 $$.type = D_SCONST; 434 memcpy($$.sval, $2, sizeof($$.sval)); 435 } 436 | '$' LFCONST 437 { 438 $$ = nullgen; 439 $$.type = D_FCONST; 440 $$.dval = $2; 441 } 442 | '$' '(' LFCONST ')' 443 { 444 $$ = nullgen; 445 $$.type = D_FCONST; 446 $$.dval = $3; 447 } 448 | '$' '(' '-' LFCONST ')' 449 { 450 $$ = nullgen; 451 $$.type = D_FCONST; 452 $$.dval = -$4; 453 } 454 | '$' '-' LFCONST 455 { 456 $$ = nullgen; 457 $$.type = D_FCONST; 458 $$.dval = -$3; 459 } 460 461 imm2: 462 '$' con2 463 { 464 $$ = nullgen; 465 $$.type = D_CONST2; 466 $$.offset = $2.v1; 467 $$.offset2 = $2.v2; 468 } 469 470 con2: 471 LCONST 472 { 473 $$.v1 = $1; 474 $$.v2 = ArgsSizeUnknown; 475 } 476 | '-' LCONST 477 { 478 $$.v1 = -$2; 479 $$.v2 = ArgsSizeUnknown; 480 } 481 | LCONST '-' LCONST 482 { 483 $$.v1 = $1; 484 $$.v2 = $3; 485 } 486 | '-' LCONST '-' LCONST 487 { 488 $$.v1 = -$2; 489 $$.v2 = $4; 490 } 491 492 mem: 493 omem 494 | nmem 495 496 omem: 497 con 498 { 499 $$ = nullgen; 500 $$.type = D_INDIR+D_NONE; 501 $$.offset = $1; 502 } 503 | con '(' LLREG ')' 504 { 505 $$ = nullgen; 506 $$.type = D_INDIR+$3; 507 $$.offset = $1; 508 } 509 | con '(' LSP ')' 510 { 511 $$ = nullgen; 512 $$.type = D_INDIR+D_SP; 513 $$.offset = $1; 514 } 515 | con '(' LLREG '*' con ')' 516 { 517 $$ = nullgen; 518 $$.type = D_INDIR+D_NONE; 519 $$.offset = $1; 520 $$.index = $3; 521 $$.scale = $5; 522 checkscale($$.scale); 523 } 524 | con '(' LLREG ')' '(' LLREG '*' con ')' 525 { 526 $$ = nullgen; 527 $$.type = D_INDIR+$3; 528 $$.offset = $1; 529 $$.index = $6; 530 $$.scale = $8; 531 checkscale($$.scale); 532 } 533 | con '(' LLREG ')' '(' LSREG '*' con ')' 534 { 535 $$ = nullgen; 536 $$.type = D_INDIR+$3; 537 $$.offset = $1; 538 $$.index = $6; 539 $$.scale = $8; 540 checkscale($$.scale); 541 } 542 | '(' LLREG ')' 543 { 544 $$ = nullgen; 545 $$.type = D_INDIR+$2; 546 } 547 | '(' LSP ')' 548 { 549 $$ = nullgen; 550 $$.type = D_INDIR+D_SP; 551 } 552 | con '(' LSREG ')' 553 { 554 $$ = nullgen; 555 $$.type = D_INDIR+$3; 556 $$.offset = $1; 557 } 558 | '(' LLREG '*' con ')' 559 { 560 $$ = nullgen; 561 $$.type = D_INDIR+D_NONE; 562 $$.index = $2; 563 $$.scale = $4; 564 checkscale($$.scale); 565 } 566 | '(' LLREG ')' '(' LLREG '*' con ')' 567 { 568 $$ = nullgen; 569 $$.type = D_INDIR+$2; 570 $$.index = $5; 571 $$.scale = $7; 572 checkscale($$.scale); 573 } 574 575 nmem: 576 nam 577 { 578 $$ = $1; 579 } 580 | nam '(' LLREG '*' con ')' 581 { 582 $$ = $1; 583 $$.index = $3; 584 $$.scale = $5; 585 checkscale($$.scale); 586 } 587 588 nam: 589 LNAME offset '(' pointer ')' 590 { 591 $$ = nullgen; 592 $$.type = $4; 593 $$.sym = $1; 594 $$.offset = $2; 595 } 596 | LNAME '<' '>' offset '(' LSB ')' 597 { 598 $$ = nullgen; 599 $$.type = D_STATIC; 600 $$.sym = $1; 601 $$.offset = $4; 602 } 603 604 offset: 605 { 606 $$ = 0; 607 } 608 | '+' con 609 { 610 $$ = $2; 611 } 612 | '-' con 613 { 614 $$ = -$2; 615 } 616 617 pointer: 618 LSB 619 | LSP 620 { 621 $$ = D_AUTO; 622 } 623 | LFP 624 625 con: 626 LCONST 627 | LVAR 628 { 629 $$ = $1->value; 630 } 631 | '-' con 632 { 633 $$ = -$2; 634 } 635 | '+' con 636 { 637 $$ = $2; 638 } 639 | '~' con 640 { 641 $$ = ~$2; 642 } 643 | '(' expr ')' 644 { 645 $$ = $2; 646 } 647 648 expr: 649 con 650 | expr '+' expr 651 { 652 $$ = $1 + $3; 653 } 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 << $4; 673 } 674 | expr '>' '>' expr 675 { 676 $$ = $1 >> $4; 677 } 678 | expr '&' expr 679 { 680 $$ = $1 & $3; 681 } 682 | expr '^' expr 683 { 684 $$ = $1 ^ $3; 685 } 686 | expr '|' expr 687 { 688 $$ = $1 | $3; 689 }