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