github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/5a/a.y (about) 1 // Inferno utils/5a/a.y 2 // http://code.google.com/p/inferno-os/source/browse/utils/5a/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 { 40 Sym *sym; 41 int32 lval; 42 double dval; 43 char sval[8]; 44 Gen gen; 45 } 46 %left '|' 47 %left '^' 48 %left '&' 49 %left '<' '>' 50 %left '+' '-' 51 %left '*' '/' '%' 52 %token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5 53 %token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA 54 %token <lval> LTYPEB LTYPEC LTYPED LTYPEE 55 %token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK 56 %token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD 57 %token <lval> LCONST LSP LSB LFP LPC 58 %token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR 59 %token <lval> LCOND LS LAT 60 %token <dval> LFCONST 61 %token <sval> LSCONST 62 %token <sym> LNAME LLAB LVAR 63 %type <lval> con expr oexpr pointer offset sreg spreg creg 64 %type <lval> rcon cond reglist 65 %type <gen> gen rel reg regreg freg shift fcon frcon 66 %type <gen> imm ximm name oreg ireg nireg ioreg imsr 67 %% 68 prog: 69 | prog 70 { 71 stmtline = lineno; 72 } 73 line 74 75 line: 76 LLAB ':' 77 { 78 if($1->value != pc) 79 yyerror("redeclaration of %s", $1->name); 80 $1->value = pc; 81 } 82 line 83 | LNAME ':' 84 { 85 $1->type = LLAB; 86 $1->value = pc; 87 } 88 line 89 | LNAME '=' expr ';' 90 { 91 $1->type = LVAR; 92 $1->value = $3; 93 } 94 | LVAR '=' expr ';' 95 { 96 if($1->value != $3) 97 yyerror("redeclaration of %s", $1->name); 98 $1->value = $3; 99 } 100 | ';' 101 | inst ';' 102 | error ';' 103 104 inst: 105 /* 106 * ADD 107 */ 108 LTYPE1 cond imsr ',' spreg ',' reg 109 { 110 outcode($1, $2, &$3, $5, &$7); 111 } 112 | LTYPE1 cond imsr ',' spreg ',' 113 { 114 outcode($1, $2, &$3, $5, &nullgen); 115 } 116 | LTYPE1 cond imsr ',' reg 117 { 118 outcode($1, $2, &$3, NREG, &$5); 119 } 120 /* 121 * MVN 122 */ 123 | LTYPE2 cond imsr ',' reg 124 { 125 outcode($1, $2, &$3, NREG, &$5); 126 } 127 /* 128 * MOVW 129 */ 130 | LTYPE3 cond gen ',' gen 131 { 132 outcode($1, $2, &$3, NREG, &$5); 133 } 134 /* 135 * B/BL 136 */ 137 | LTYPE4 cond comma rel 138 { 139 outcode($1, $2, &nullgen, NREG, &$4); 140 } 141 | LTYPE4 cond comma nireg 142 { 143 outcode($1, $2, &nullgen, NREG, &$4); 144 } 145 /* 146 * BX 147 */ 148 | LTYPEBX comma ireg 149 { 150 outcode($1, Always, &nullgen, NREG, &$3); 151 } 152 /* 153 * BEQ 154 */ 155 | LTYPE5 comma rel 156 { 157 outcode($1, Always, &nullgen, NREG, &$3); 158 } 159 /* 160 * SWI 161 */ 162 | LTYPE6 cond comma gen 163 { 164 outcode($1, $2, &nullgen, NREG, &$4); 165 } 166 /* 167 * CMP 168 */ 169 | LTYPE7 cond imsr ',' spreg comma 170 { 171 outcode($1, $2, &$3, $5, &nullgen); 172 } 173 /* 174 * MOVM 175 */ 176 | LTYPE8 cond ioreg ',' '[' reglist ']' 177 { 178 Gen g; 179 180 g = nullgen; 181 g.type = D_CONST; 182 g.offset = $6; 183 outcode($1, $2, &$3, NREG, &g); 184 } 185 | LTYPE8 cond '[' reglist ']' ',' ioreg 186 { 187 Gen g; 188 189 g = nullgen; 190 g.type = D_CONST; 191 g.offset = $4; 192 outcode($1, $2, &g, NREG, &$7); 193 } 194 /* 195 * SWAP 196 */ 197 | LTYPE9 cond reg ',' ireg ',' reg 198 { 199 outcode($1, $2, &$5, $3.reg, &$7); 200 } 201 | LTYPE9 cond reg ',' ireg comma 202 { 203 outcode($1, $2, &$5, $3.reg, &$3); 204 } 205 | LTYPE9 cond comma ireg ',' reg 206 { 207 outcode($1, $2, &$4, $6.reg, &$6); 208 } 209 /* 210 * RET 211 */ 212 | LTYPEA cond comma 213 { 214 outcode($1, $2, &nullgen, NREG, &nullgen); 215 } 216 /* 217 * TEXT/GLOBL 218 */ 219 | LTYPEB name ',' imm 220 { 221 $4.type = D_CONST2; 222 $4.offset2 = ArgsSizeUnknown; 223 outcode($1, Always, &$2, 0, &$4); 224 } 225 | LTYPEB name ',' con ',' imm 226 { 227 $6.type = D_CONST2; 228 $6.offset2 = ArgsSizeUnknown; 229 outcode($1, Always, &$2, $4, &$6); 230 } 231 | LTYPEB name ',' con ',' imm '-' con 232 { 233 $6.type = D_CONST2; 234 $6.offset2 = $8; 235 outcode($1, Always, &$2, $4, &$6); 236 } 237 /* 238 * DATA 239 */ 240 | LTYPEC name '/' con ',' ximm 241 { 242 outcode($1, Always, &$2, $4, &$6); 243 } 244 /* 245 * CASE 246 */ 247 | LTYPED cond reg comma 248 { 249 outcode($1, $2, &$3, NREG, &nullgen); 250 } 251 /* 252 * word 253 */ 254 | LTYPEH comma ximm 255 { 256 outcode($1, Always, &nullgen, NREG, &$3); 257 } 258 /* 259 * floating-point coprocessor 260 */ 261 | LTYPEI cond freg ',' freg 262 { 263 outcode($1, $2, &$3, NREG, &$5); 264 } 265 | LTYPEK cond frcon ',' freg 266 { 267 outcode($1, $2, &$3, NREG, &$5); 268 } 269 | LTYPEK cond frcon ',' LFREG ',' freg 270 { 271 outcode($1, $2, &$3, $5, &$7); 272 } 273 | LTYPEL cond freg ',' freg comma 274 { 275 outcode($1, $2, &$3, $5.reg, &nullgen); 276 } 277 /* 278 * MCR MRC 279 */ 280 | LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr 281 { 282 Gen g; 283 284 g = nullgen; 285 g.type = D_CONST; 286 g.offset = 287 (0xe << 24) | /* opcode */ 288 ($1 << 20) | /* MCR/MRC */ 289 ($2 << 28) | /* scond */ 290 (($3 & 15) << 8) | /* coprocessor number */ 291 (($5 & 7) << 21) | /* coprocessor operation */ 292 (($7 & 15) << 12) | /* arm register */ 293 (($9 & 15) << 16) | /* Crn */ 294 (($11 & 15) << 0) | /* Crm */ 295 (($12 & 7) << 5) | /* coprocessor information */ 296 (1<<4); /* must be set */ 297 outcode(AWORD, Always, &nullgen, NREG, &g); 298 } 299 /* 300 * MULL r1,r2,(hi,lo) 301 */ 302 | LTYPEM cond reg ',' reg ',' regreg 303 { 304 outcode($1, $2, &$3, $5.reg, &$7); 305 } 306 /* 307 * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4 308 * MULAW{T,B} r1,r2,r3,r4 309 */ 310 | LTYPEN cond reg ',' reg ',' reg ',' spreg 311 { 312 $7.type = D_REGREG2; 313 $7.offset = $9; 314 outcode($1, $2, &$3, $5.reg, &$7); 315 } 316 /* 317 * PLD 318 */ 319 | LTYPEPLD oreg 320 { 321 outcode($1, Always, &$2, NREG, &nullgen); 322 } 323 /* 324 * PCDATA 325 */ 326 | LTYPEPC gen ',' gen 327 { 328 if($2.type != D_CONST || $4.type != D_CONST) 329 yyerror("arguments to PCDATA must be integer constants"); 330 outcode($1, Always, &$2, NREG, &$4); 331 } 332 /* 333 * FUNCDATA 334 */ 335 | LTYPEF gen ',' gen 336 { 337 if($2.type != D_CONST) 338 yyerror("index for FUNCDATA must be integer constant"); 339 if($4.type != D_EXTERN && $4.type != D_STATIC) 340 yyerror("value for FUNCDATA must be symbol reference"); 341 outcode($1, Always, &$2, NREG, &$4); 342 } 343 /* 344 * END 345 */ 346 | LTYPEE comma 347 { 348 outcode($1, Always, &nullgen, NREG, &nullgen); 349 } 350 351 cond: 352 { 353 $$ = Always; 354 } 355 | cond LCOND 356 { 357 $$ = ($1 & ~C_SCOND) | $2; 358 } 359 | cond LS 360 { 361 $$ = $1 | $2; 362 } 363 364 comma: 365 | ',' comma 366 367 rel: 368 con '(' LPC ')' 369 { 370 $$ = nullgen; 371 $$.type = D_BRANCH; 372 $$.offset = $1 + pc; 373 } 374 | LNAME offset 375 { 376 $$ = nullgen; 377 if(pass == 2) 378 yyerror("undefined label: %s", $1->name); 379 $$.type = D_BRANCH; 380 $$.sym = $1; 381 $$.offset = $2; 382 } 383 | LLAB offset 384 { 385 $$ = nullgen; 386 $$.type = D_BRANCH; 387 $$.sym = $1; 388 $$.offset = $1->value + $2; 389 } 390 391 ximm: '$' con 392 { 393 $$ = nullgen; 394 $$.type = D_CONST; 395 $$.offset = $2; 396 } 397 | '$' oreg 398 { 399 $$ = $2; 400 $$.type = D_CONST; 401 } 402 | '$' '*' '$' oreg 403 { 404 $$ = $4; 405 $$.type = D_OCONST; 406 } 407 | '$' LSCONST 408 { 409 $$ = nullgen; 410 $$.type = D_SCONST; 411 memcpy($$.sval, $2, sizeof($$.sval)); 412 } 413 | fcon 414 415 fcon: 416 '$' LFCONST 417 { 418 $$ = nullgen; 419 $$.type = D_FCONST; 420 $$.dval = $2; 421 } 422 | '$' '-' LFCONST 423 { 424 $$ = nullgen; 425 $$.type = D_FCONST; 426 $$.dval = -$3; 427 } 428 429 reglist: 430 spreg 431 { 432 $$ = 1 << $1; 433 } 434 | spreg '-' spreg 435 { 436 int i; 437 $$=0; 438 for(i=$1; i<=$3; i++) 439 $$ |= 1<<i; 440 for(i=$3; i<=$1; i++) 441 $$ |= 1<<i; 442 } 443 | spreg comma reglist 444 { 445 $$ = (1<<$1) | $3; 446 } 447 448 gen: 449 reg 450 | ximm 451 | shift 452 | shift '(' spreg ')' 453 { 454 $$ = $1; 455 $$.reg = $3; 456 } 457 | LPSR 458 { 459 $$ = nullgen; 460 $$.type = D_PSR; 461 $$.reg = $1; 462 } 463 | LFCR 464 { 465 $$ = nullgen; 466 $$.type = D_FPCR; 467 $$.reg = $1; 468 } 469 | con 470 { 471 $$ = nullgen; 472 $$.type = D_OREG; 473 $$.offset = $1; 474 } 475 | oreg 476 | freg 477 478 nireg: 479 ireg 480 | name 481 { 482 $$ = $1; 483 if($1.name != D_EXTERN && $1.name != D_STATIC) { 484 } 485 } 486 487 ireg: 488 '(' spreg ')' 489 { 490 $$ = nullgen; 491 $$.type = D_OREG; 492 $$.reg = $2; 493 $$.offset = 0; 494 } 495 496 ioreg: 497 ireg 498 | con '(' sreg ')' 499 { 500 $$ = nullgen; 501 $$.type = D_OREG; 502 $$.reg = $3; 503 $$.offset = $1; 504 } 505 506 oreg: 507 name 508 | name '(' sreg ')' 509 { 510 $$ = $1; 511 $$.type = D_OREG; 512 $$.reg = $3; 513 } 514 | ioreg 515 516 imsr: 517 reg 518 | imm 519 | shift 520 521 imm: '$' con 522 { 523 $$ = nullgen; 524 $$.type = D_CONST; 525 $$.offset = $2; 526 } 527 528 reg: 529 spreg 530 { 531 $$ = nullgen; 532 $$.type = D_REG; 533 $$.reg = $1; 534 } 535 536 regreg: 537 '(' spreg ',' spreg ')' 538 { 539 $$ = nullgen; 540 $$.type = D_REGREG; 541 $$.reg = $2; 542 $$.offset = $4; 543 } 544 545 shift: 546 spreg '<' '<' rcon 547 { 548 $$ = nullgen; 549 $$.type = D_SHIFT; 550 $$.offset = $1 | $4 | (0 << 5); 551 } 552 | spreg '>' '>' rcon 553 { 554 $$ = nullgen; 555 $$.type = D_SHIFT; 556 $$.offset = $1 | $4 | (1 << 5); 557 } 558 | spreg '-' '>' rcon 559 { 560 $$ = nullgen; 561 $$.type = D_SHIFT; 562 $$.offset = $1 | $4 | (2 << 5); 563 } 564 | spreg LAT '>' rcon 565 { 566 $$ = nullgen; 567 $$.type = D_SHIFT; 568 $$.offset = $1 | $4 | (3 << 5); 569 } 570 571 rcon: 572 spreg 573 { 574 if($$ < 0 || $$ >= 16) 575 print("register value out of range\n"); 576 $$ = (($1&15) << 8) | (1 << 4); 577 } 578 | con 579 { 580 if($$ < 0 || $$ >= 32) 581 print("shift value out of range\n"); 582 $$ = ($1&31) << 7; 583 } 584 585 sreg: 586 LREG 587 | LPC 588 { 589 $$ = REGPC; 590 } 591 | LR '(' expr ')' 592 { 593 if($3 < 0 || $3 >= NREG) 594 print("register value out of range\n"); 595 $$ = $3; 596 } 597 598 spreg: 599 sreg 600 | LSP 601 { 602 $$ = REGSP; 603 } 604 605 creg: 606 LCREG 607 | LC '(' expr ')' 608 { 609 if($3 < 0 || $3 >= NREG) 610 print("register value out of range\n"); 611 $$ = $3; 612 } 613 614 frcon: 615 freg 616 | fcon 617 618 freg: 619 LFREG 620 { 621 $$ = nullgen; 622 $$.type = D_FREG; 623 $$.reg = $1; 624 } 625 | LF '(' con ')' 626 { 627 $$ = nullgen; 628 $$.type = D_FREG; 629 $$.reg = $3; 630 } 631 632 name: 633 con '(' pointer ')' 634 { 635 $$ = nullgen; 636 $$.type = D_OREG; 637 $$.name = $3; 638 $$.sym = S; 639 $$.offset = $1; 640 } 641 | LNAME offset '(' pointer ')' 642 { 643 $$ = nullgen; 644 $$.type = D_OREG; 645 $$.name = $4; 646 $$.sym = $1; 647 $$.offset = $2; 648 } 649 | LNAME '<' '>' offset '(' LSB ')' 650 { 651 $$ = nullgen; 652 $$.type = D_OREG; 653 $$.name = D_STATIC; 654 $$.sym = $1; 655 $$.offset = $4; 656 } 657 658 offset: 659 { 660 $$ = 0; 661 } 662 | '+' con 663 { 664 $$ = $2; 665 } 666 | '-' con 667 { 668 $$ = -$2; 669 } 670 671 pointer: 672 LSB 673 | LSP 674 | LFP 675 676 con: 677 LCONST 678 | LVAR 679 { 680 $$ = $1->value; 681 } 682 | '-' con 683 { 684 $$ = -$2; 685 } 686 | '+' con 687 { 688 $$ = $2; 689 } 690 | '~' con 691 { 692 $$ = ~$2; 693 } 694 | '(' expr ')' 695 { 696 $$ = $2; 697 } 698 699 oexpr: 700 { 701 $$ = 0; 702 } 703 | ',' expr 704 { 705 $$ = $2; 706 } 707 708 expr: 709 con 710 | expr '+' expr 711 { 712 $$ = $1 + $3; 713 } 714 | expr '-' expr 715 { 716 $$ = $1 - $3; 717 } 718 | expr '*' expr 719 { 720 $$ = $1 * $3; 721 } 722 | expr '/' expr 723 { 724 $$ = $1 / $3; 725 } 726 | expr '%' expr 727 { 728 $$ = $1 % $3; 729 } 730 | expr '<' '<' expr 731 { 732 $$ = $1 << $4; 733 } 734 | expr '>' '>' expr 735 { 736 $$ = $1 >> $4; 737 } 738 | expr '&' expr 739 { 740 $$ = $1 & $3; 741 } 742 | expr '^' expr 743 { 744 $$ = $1 ^ $3; 745 } 746 | expr '|' expr 747 { 748 $$ = $1 | $3; 749 }