github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/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 "../../runtime/funcdata.h" 37 %} 38 %union { 39 Sym *sym; 40 vlong lval; 41 double dval; 42 char sval[8]; 43 Addr addr; 44 Addr2 addr2; 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 <addr> mem imm imm2 reg nam rel rem rim rom omem nmem 62 %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim 63 %type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 64 %type <addr2> 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 $$.offset = $2; 371 } 372 | LLAB offset 373 { 374 $$ = nullgen; 375 $$.type = D_BRANCH; 376 $$.offset = $1->value + $2; 377 } 378 379 reg: 380 LBREG 381 { 382 $$ = nullgen; 383 $$.type = $1; 384 } 385 | LFREG 386 { 387 $$ = nullgen; 388 $$.type = $1; 389 } 390 | LLREG 391 { 392 $$ = nullgen; 393 $$.type = $1; 394 } 395 | LMREG 396 { 397 $$ = nullgen; 398 $$.type = $1; 399 } 400 | LSP 401 { 402 $$ = nullgen; 403 $$.type = D_SP; 404 } 405 | LSREG 406 { 407 $$ = nullgen; 408 $$.type = $1; 409 } 410 | LXREG 411 { 412 $$ = nullgen; 413 $$.type = $1; 414 } 415 imm2: 416 '$' con2 417 { 418 $$ = nullgen; 419 $$.type = D_CONST; 420 $$.offset = $2; 421 } 422 423 imm: 424 '$' con 425 { 426 $$ = nullgen; 427 $$.type = D_CONST; 428 $$.offset = $2; 429 } 430 | '$' nam 431 { 432 $$ = $2; 433 $$.index = $2.type; 434 $$.type = D_ADDR; 435 /* 436 if($2.type == D_AUTO || $2.type == D_PARAM) 437 yyerror("constant cannot be automatic: %s", 438 $2.sym->name); 439 */ 440 } 441 | '$' LSCONST 442 { 443 $$ = nullgen; 444 $$.type = D_SCONST; 445 memcpy($$.u.sval, $2, sizeof($$.u.sval)); 446 } 447 | '$' LFCONST 448 { 449 $$ = nullgen; 450 $$.type = D_FCONST; 451 $$.u.dval = $2; 452 } 453 | '$' '(' LFCONST ')' 454 { 455 $$ = nullgen; 456 $$.type = D_FCONST; 457 $$.u.dval = $3; 458 } 459 | '$' '(' '-' LFCONST ')' 460 { 461 $$ = nullgen; 462 $$.type = D_FCONST; 463 $$.u.dval = -$4; 464 } 465 | '$' '-' LFCONST 466 { 467 $$ = nullgen; 468 $$.type = D_FCONST; 469 $$.u.dval = -$3; 470 } 471 472 mem: 473 omem 474 | nmem 475 476 omem: 477 con 478 { 479 $$ = nullgen; 480 $$.type = D_INDIR+D_NONE; 481 $$.offset = $1; 482 } 483 | con '(' LLREG ')' 484 { 485 $$ = nullgen; 486 $$.type = D_INDIR+$3; 487 $$.offset = $1; 488 } 489 | con '(' LSP ')' 490 { 491 $$ = nullgen; 492 $$.type = D_INDIR+D_SP; 493 $$.offset = $1; 494 } 495 | con '(' LSREG ')' 496 { 497 $$ = nullgen; 498 $$.type = D_INDIR+$3; 499 $$.offset = $1; 500 } 501 | con '(' LLREG '*' con ')' 502 { 503 $$ = nullgen; 504 $$.type = D_INDIR+D_NONE; 505 $$.offset = $1; 506 $$.index = $3; 507 $$.scale = $5; 508 checkscale($$.scale); 509 } 510 | con '(' LLREG ')' '(' LLREG '*' con ')' 511 { 512 $$ = nullgen; 513 $$.type = D_INDIR+$3; 514 $$.offset = $1; 515 $$.index = $6; 516 $$.scale = $8; 517 checkscale($$.scale); 518 } 519 | con '(' LLREG ')' '(' LSREG '*' con ')' 520 { 521 $$ = nullgen; 522 $$.type = D_INDIR+$3; 523 $$.offset = $1; 524 $$.index = $6; 525 $$.scale = $8; 526 checkscale($$.scale); 527 } 528 | '(' LLREG ')' 529 { 530 $$ = nullgen; 531 $$.type = D_INDIR+$2; 532 } 533 | '(' LSP ')' 534 { 535 $$ = nullgen; 536 $$.type = D_INDIR+D_SP; 537 } 538 | '(' LLREG '*' con ')' 539 { 540 $$ = nullgen; 541 $$.type = D_INDIR+D_NONE; 542 $$.index = $2; 543 $$.scale = $4; 544 checkscale($$.scale); 545 } 546 | '(' LLREG ')' '(' LLREG '*' con ')' 547 { 548 $$ = nullgen; 549 $$.type = D_INDIR+$2; 550 $$.index = $5; 551 $$.scale = $7; 552 checkscale($$.scale); 553 } 554 555 nmem: 556 nam 557 { 558 $$ = $1; 559 } 560 | nam '(' LLREG '*' con ')' 561 { 562 $$ = $1; 563 $$.index = $3; 564 $$.scale = $5; 565 checkscale($$.scale); 566 } 567 568 nam: 569 LNAME offset '(' pointer ')' 570 { 571 $$ = nullgen; 572 $$.type = $4; 573 $$.sym = linklookup(ctxt, $1->name, 0); 574 $$.offset = $2; 575 } 576 | LNAME '<' '>' offset '(' LSB ')' 577 { 578 $$ = nullgen; 579 $$.type = D_STATIC; 580 $$.sym = linklookup(ctxt, $1->name, 1); 581 $$.offset = $4; 582 } 583 584 offset: 585 { 586 $$ = 0; 587 } 588 | '+' con 589 { 590 $$ = $2; 591 } 592 | '-' con 593 { 594 $$ = -$2; 595 } 596 597 pointer: 598 LSB 599 | LSP 600 { 601 $$ = D_AUTO; 602 } 603 | LFP 604 605 con: 606 LCONST 607 | LVAR 608 { 609 $$ = $1->value; 610 } 611 | '-' con 612 { 613 $$ = -$2; 614 } 615 | '+' con 616 { 617 $$ = $2; 618 } 619 | '~' con 620 { 621 $$ = ~$2; 622 } 623 | '(' expr ')' 624 { 625 $$ = $2; 626 } 627 628 con2: 629 LCONST 630 { 631 $$ = ($1 & 0xffffffffLL) + 632 ((vlong)ArgsSizeUnknown << 32); 633 } 634 | '-' LCONST 635 { 636 $$ = (-$2 & 0xffffffffLL) + 637 ((vlong)ArgsSizeUnknown << 32); 638 } 639 | LCONST '-' LCONST 640 { 641 $$ = ($1 & 0xffffffffLL) + 642 (($3 & 0xffffLL) << 32); 643 } 644 | '-' LCONST '-' LCONST 645 { 646 $$ = (-$2 & 0xffffffffLL) + 647 (($4 & 0xffffLL) << 32); 648 } 649 650 expr: 651 con 652 | expr '+' expr 653 { 654 $$ = $1 + $3; 655 } 656 | expr '-' expr 657 { 658 $$ = $1 - $3; 659 } 660 | expr '*' expr 661 { 662 $$ = $1 * $3; 663 } 664 | expr '/' expr 665 { 666 $$ = $1 / $3; 667 } 668 | expr '%' expr 669 { 670 $$ = $1 % $3; 671 } 672 | expr '<' '<' expr 673 { 674 $$ = $1 << $4; 675 } 676 | expr '>' '>' expr 677 { 678 $$ = $1 >> $4; 679 } 680 | expr '&' expr 681 { 682 $$ = $1 & $3; 683 } 684 | expr '^' expr 685 { 686 $$ = $1 ^ $3; 687 } 688 | expr '|' expr 689 { 690 $$ = $1 | $3; 691 }