github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/old9a/a.y (about) 1 // cmd/9a/a.y from Vita Nuova. 2 // 3 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 4 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 5 // Portions Copyright © 1997-1999 Vita Nuova Limited 6 // Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) 7 // Portions Copyright © 2004,2006 Bruce Ellis 8 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 9 // Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others 10 // Portions Copyright © 2009 The Go Authors. All rights reserved. 11 // 12 // Permission is hereby granted, free of charge, to any person obtaining a copy 13 // of this software and associated documentation files (the "Software"), to deal 14 // in the Software without restriction, including without limitation the rights 15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 // copies of the Software, and to permit persons to whom the Software is 17 // furnished to do so, subject to the following conditions: 18 // 19 // The above copyright notice and this permission notice shall be included in 20 // all copies or substantial portions of the Software. 21 // 22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 // THE SOFTWARE. 29 30 %{ 31 package main 32 33 import ( 34 "cmd/internal/asm" 35 "cmd/internal/obj" 36 . "cmd/internal/obj/ppc64" 37 ) 38 %} 39 40 %union 41 { 42 sym *asm.Sym 43 lval int64 44 dval float64 45 sval string 46 addr obj.Addr 47 } 48 49 %left '|' 50 %left '^' 51 %left '&' 52 %left '<' '>' 53 %left '+' '-' 54 %left '*' '/' '%' 55 %token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP 56 %token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW 57 %token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LGLOBL LRETRN 58 %token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH 59 %token <lval> LREG LFREG LR LCR LF LFPSCR 60 %token <lval> LLR LCTR LSPR LSPREG LSEG LMSR 61 %token <lval> LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV 62 %token <lval> LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA 63 %token <dval> LFCONST 64 %token <sval> LSCONST 65 %token <sym> LNAME LLAB LVAR 66 %type <lval> con expr pointer offset sreg 67 %type <addr> addr rreg regaddr name creg freg xlreg lr ctr textsize 68 %type <addr> imm ximm fimm rel psr lcr cbit fpscr msr mask 69 %% 70 prog: 71 | prog 72 { 73 stmtline = asm.Lineno 74 } 75 line 76 77 line: 78 LNAME ':' 79 { 80 $1 = asm.LabelLookup($1); 81 if $1.Type == LLAB && $1.Value != int64(asm.PC) { 82 yyerror("redeclaration of %s", $1.Labelname) 83 } 84 $1.Type = LLAB; 85 $1.Value = int64(asm.PC); 86 } 87 line 88 | LNAME '=' expr ';' 89 { 90 $1.Type = LVAR; 91 $1.Value = $3; 92 } 93 | LVAR '=' expr ';' 94 { 95 if $1.Value != $3 { 96 yyerror("redeclaration of %s", $1.Name) 97 } 98 $1.Value = $3; 99 } 100 | LSCHED ';' 101 { 102 nosched = int($1); 103 } 104 | ';' 105 | inst ';' 106 | error ';' 107 108 inst: 109 /* 110 * load ints and bytes 111 */ 112 LMOVW rreg ',' rreg 113 { 114 outcode(int($1), &$2, 0, &$4); 115 } 116 | LMOVW addr ',' rreg 117 { 118 outcode(int($1), &$2, 0, &$4); 119 } 120 | LMOVW regaddr ',' rreg 121 { 122 outcode(int($1), &$2, 0, &$4); 123 } 124 | LMOVB rreg ',' rreg 125 { 126 outcode(int($1), &$2, 0, &$4); 127 } 128 | LMOVB addr ',' rreg 129 { 130 outcode(int($1), &$2, 0, &$4); 131 } 132 | LMOVB regaddr ',' rreg 133 { 134 outcode(int($1), &$2, 0, &$4); 135 } 136 /* 137 * load floats 138 */ 139 | LFMOV addr ',' freg 140 { 141 outcode(int($1), &$2, 0, &$4); 142 } 143 | LFMOV regaddr ',' freg 144 { 145 outcode(int($1), &$2, 0, &$4); 146 } 147 | LFMOV fimm ',' freg 148 { 149 outcode(int($1), &$2, 0, &$4); 150 } 151 | LFMOV freg ',' freg 152 { 153 outcode(int($1), &$2, 0, &$4); 154 } 155 | LFMOV freg ',' addr 156 { 157 outcode(int($1), &$2, 0, &$4); 158 } 159 | LFMOV freg ',' regaddr 160 { 161 outcode(int($1), &$2, 0, &$4); 162 } 163 /* 164 * store ints and bytes 165 */ 166 | LMOVW rreg ',' addr 167 { 168 outcode(int($1), &$2, 0, &$4); 169 } 170 | LMOVW rreg ',' regaddr 171 { 172 outcode(int($1), &$2, 0, &$4); 173 } 174 | LMOVB rreg ',' addr 175 { 176 outcode(int($1), &$2, 0, &$4); 177 } 178 | LMOVB rreg ',' regaddr 179 { 180 outcode(int($1), &$2, 0, &$4); 181 } 182 /* 183 * store floats 184 */ 185 | LMOVW freg ',' addr 186 { 187 outcode(int($1), &$2, 0, &$4); 188 } 189 | LMOVW freg ',' regaddr 190 { 191 outcode(int($1), &$2, 0, &$4); 192 } 193 /* 194 * floating point status 195 */ 196 | LMOVW fpscr ',' freg 197 { 198 outcode(int($1), &$2, 0, &$4); 199 } 200 | LMOVW freg ',' fpscr 201 { 202 outcode(int($1), &$2, 0, &$4); 203 } 204 | LMOVW freg ',' imm ',' fpscr 205 { 206 outgcode(int($1), &$2, 0, &$4, &$6); 207 } 208 | LMOVW fpscr ',' creg 209 { 210 outcode(int($1), &$2, 0, &$4); 211 } 212 | LMTFSB imm ',' con 213 { 214 outcode(int($1), &$2, int($4), &nullgen); 215 } 216 /* 217 * field moves (mtcrf) 218 */ 219 | LMOVW rreg ',' imm ',' lcr 220 { 221 outgcode(int($1), &$2, 0, &$4, &$6); 222 } 223 | LMOVW rreg ',' creg 224 { 225 outcode(int($1), &$2, 0, &$4); 226 } 227 | LMOVW rreg ',' lcr 228 { 229 outcode(int($1), &$2, 0, &$4); 230 } 231 /* 232 * integer operations 233 * logical instructions 234 * shift instructions 235 * unary instructions 236 */ 237 | LADDW rreg ',' sreg ',' rreg 238 { 239 outcode(int($1), &$2, int($4), &$6); 240 } 241 | LADDW imm ',' sreg ',' rreg 242 { 243 outcode(int($1), &$2, int($4), &$6); 244 } 245 | LADDW rreg ',' imm ',' rreg 246 { 247 outgcode(int($1), &$2, 0, &$4, &$6); 248 } 249 | LADDW rreg ',' rreg 250 { 251 outcode(int($1), &$2, 0, &$4); 252 } 253 | LADDW imm ',' rreg 254 { 255 outcode(int($1), &$2, 0, &$4); 256 } 257 | LLOGW rreg ',' sreg ',' rreg 258 { 259 outcode(int($1), &$2, int($4), &$6); 260 } 261 | LLOGW rreg ',' rreg 262 { 263 outcode(int($1), &$2, 0, &$4); 264 } 265 | LSHW rreg ',' sreg ',' rreg 266 { 267 outcode(int($1), &$2, int($4), &$6); 268 } 269 | LSHW rreg ',' rreg 270 { 271 outcode(int($1), &$2, 0, &$4); 272 } 273 | LSHW imm ',' sreg ',' rreg 274 { 275 outcode(int($1), &$2, int($4), &$6); 276 } 277 | LSHW imm ',' rreg 278 { 279 outcode(int($1), &$2, 0, &$4); 280 } 281 | LABS rreg ',' rreg 282 { 283 outcode(int($1), &$2, 0, &$4); 284 } 285 | LABS rreg 286 { 287 outcode(int($1), &$2, 0, &$2); 288 } 289 /* 290 * multiply-accumulate 291 */ 292 | LMA rreg ',' sreg ',' rreg 293 { 294 outcode(int($1), &$2, int($4), &$6); 295 } 296 /* 297 * move immediate: macro for cau+or, addi, addis, and other combinations 298 */ 299 | LMOVW imm ',' rreg 300 { 301 outcode(int($1), &$2, 0, &$4); 302 } 303 | LMOVW ximm ',' rreg 304 { 305 outcode(int($1), &$2, 0, &$4); 306 } 307 /* 308 * condition register operations 309 */ 310 | LCROP cbit ',' cbit 311 { 312 outcode(int($1), &$2, int($4.Reg), &$4); 313 } 314 | LCROP cbit ',' con ',' cbit 315 { 316 outcode(int($1), &$2, int($4), &$6); 317 } 318 /* 319 * condition register moves 320 * move from machine state register 321 */ 322 | LMOVW creg ',' creg 323 { 324 outcode(int($1), &$2, 0, &$4); 325 } 326 | LMOVW psr ',' creg 327 { 328 outcode(int($1), &$2, 0, &$4); 329 } 330 | LMOVW lcr ',' rreg 331 { 332 outcode(int($1), &$2, 0, &$4); 333 } 334 | LMOVW psr ',' rreg 335 { 336 outcode(int($1), &$2, 0, &$4); 337 } 338 | LMOVW xlreg ',' rreg 339 { 340 outcode(int($1), &$2, 0, &$4); 341 } 342 | LMOVW rreg ',' xlreg 343 { 344 outcode(int($1), &$2, 0, &$4); 345 } 346 | LMOVW creg ',' psr 347 { 348 outcode(int($1), &$2, 0, &$4); 349 } 350 | LMOVW rreg ',' psr 351 { 352 outcode(int($1), &$2, 0, &$4); 353 } 354 /* 355 * branch, branch conditional 356 * branch conditional register 357 * branch conditional to count register 358 */ 359 | LBRA rel 360 { 361 outcode(int($1), &nullgen, 0, &$2); 362 } 363 | LBRA addr 364 { 365 outcode(int($1), &nullgen, 0, &$2); 366 } 367 | LBRA '(' xlreg ')' 368 { 369 outcode(int($1), &nullgen, 0, &$3); 370 } 371 | LBRA ',' rel 372 { 373 outcode(int($1), &nullgen, 0, &$3); 374 } 375 | LBRA ',' addr 376 { 377 outcode(int($1), &nullgen, 0, &$3); 378 } 379 | LBRA ',' '(' xlreg ')' 380 { 381 outcode(int($1), &nullgen, 0, &$4); 382 } 383 | LBRA creg ',' rel 384 { 385 outcode(int($1), &$2, 0, &$4); 386 } 387 | LBRA creg ',' addr 388 { 389 outcode(int($1), &$2, 0, &$4); 390 } 391 | LBRA creg ',' '(' xlreg ')' 392 { 393 outcode(int($1), &$2, 0, &$5); 394 } 395 | LBRA con ',' rel 396 { 397 outcode(int($1), &nullgen, int($2), &$4); 398 } 399 | LBRA con ',' addr 400 { 401 outcode(int($1), &nullgen, int($2), &$4); 402 } 403 | LBRA con ',' '(' xlreg ')' 404 { 405 outcode(int($1), &nullgen, int($2), &$5); 406 } 407 | LBRA con ',' con ',' rel 408 { 409 var g obj.Addr 410 g = nullgen; 411 g.Type = obj.TYPE_CONST; 412 g.Offset = $2; 413 outcode(int($1), &g, int(REG_R0+$4), &$6); 414 } 415 | LBRA con ',' con ',' addr 416 { 417 var g obj.Addr 418 g = nullgen; 419 g.Type = obj.TYPE_CONST; 420 g.Offset = $2; 421 outcode(int($1), &g, int(REG_R0+$4), &$6); 422 } 423 | LBRA con ',' con ',' '(' xlreg ')' 424 { 425 var g obj.Addr 426 g = nullgen; 427 g.Type = obj.TYPE_CONST; 428 g.Offset = $2; 429 outcode(int($1), &g, int(REG_R0+$4), &$7); 430 } 431 /* 432 * conditional trap 433 */ 434 | LTRAP rreg ',' sreg 435 { 436 outcode(int($1), &$2, int($4), &nullgen); 437 } 438 | LTRAP imm ',' sreg 439 { 440 outcode(int($1), &$2, int($4), &nullgen); 441 } 442 | LTRAP rreg comma 443 { 444 outcode(int($1), &$2, 0, &nullgen); 445 } 446 | LTRAP comma 447 { 448 outcode(int($1), &nullgen, 0, &nullgen); 449 } 450 /* 451 * floating point operate 452 */ 453 | LFCONV freg ',' freg 454 { 455 outcode(int($1), &$2, 0, &$4); 456 } 457 | LFADD freg ',' freg 458 { 459 outcode(int($1), &$2, 0, &$4); 460 } 461 | LFADD freg ',' freg ',' freg 462 { 463 outcode(int($1), &$2, int($4.Reg), &$6); 464 } 465 | LFMA freg ',' freg ',' freg ',' freg 466 { 467 outgcode(int($1), &$2, int($4.Reg), &$6, &$8); 468 } 469 | LFCMP freg ',' freg 470 { 471 outcode(int($1), &$2, 0, &$4); 472 } 473 | LFCMP freg ',' freg ',' creg 474 { 475 outcode(int($1), &$2, int($6.Reg), &$4); 476 } 477 /* 478 * CMP 479 */ 480 | LCMP rreg ',' rreg 481 { 482 outcode(int($1), &$2, 0, &$4); 483 } 484 | LCMP rreg ',' imm 485 { 486 outcode(int($1), &$2, 0, &$4); 487 } 488 | LCMP rreg ',' rreg ',' creg 489 { 490 outcode(int($1), &$2, int($6.Reg), &$4); 491 } 492 | LCMP rreg ',' imm ',' creg 493 { 494 outcode(int($1), &$2, int($6.Reg), &$4); 495 } 496 /* 497 * rotate and mask 498 */ 499 | LRLWM imm ',' rreg ',' imm ',' rreg 500 { 501 outgcode(int($1), &$2, int($4.Reg), &$6, &$8); 502 } 503 | LRLWM imm ',' rreg ',' mask ',' rreg 504 { 505 outgcode(int($1), &$2, int($4.Reg), &$6, &$8); 506 } 507 | LRLWM rreg ',' rreg ',' imm ',' rreg 508 { 509 outgcode(int($1), &$2, int($4.Reg), &$6, &$8); 510 } 511 | LRLWM rreg ',' rreg ',' mask ',' rreg 512 { 513 outgcode(int($1), &$2, int($4.Reg), &$6, &$8); 514 } 515 /* 516 * load/store multiple 517 */ 518 | LMOVMW addr ',' rreg 519 { 520 outcode(int($1), &$2, 0, &$4); 521 } 522 | LMOVMW rreg ',' addr 523 { 524 outcode(int($1), &$2, 0, &$4); 525 } 526 /* 527 * various indexed load/store 528 * indexed unary (eg, cache clear) 529 */ 530 | LXLD regaddr ',' rreg 531 { 532 outcode(int($1), &$2, 0, &$4); 533 } 534 | LXLD regaddr ',' imm ',' rreg 535 { 536 outgcode(int($1), &$2, 0, &$4, &$6); 537 } 538 | LXST rreg ',' regaddr 539 { 540 outcode(int($1), &$2, 0, &$4); 541 } 542 | LXST rreg ',' imm ',' regaddr 543 { 544 outgcode(int($1), &$2, 0, &$4, &$6); 545 } 546 | LXMV regaddr ',' rreg 547 { 548 outcode(int($1), &$2, 0, &$4); 549 } 550 | LXMV rreg ',' regaddr 551 { 552 outcode(int($1), &$2, 0, &$4); 553 } 554 | LXOP regaddr 555 { 556 outcode(int($1), &$2, 0, &nullgen); 557 } 558 /* 559 * NOP 560 */ 561 | LNOP comma 562 { 563 outcode(int($1), &nullgen, 0, &nullgen); 564 } 565 | LNOP rreg comma 566 { 567 outcode(int($1), &$2, 0, &nullgen); 568 } 569 | LNOP freg comma 570 { 571 outcode(int($1), &$2, 0, &nullgen); 572 } 573 | LNOP ',' rreg 574 { 575 outcode(int($1), &nullgen, 0, &$3); 576 } 577 | LNOP ',' freg 578 { 579 outcode(int($1), &nullgen, 0, &$3); 580 } 581 | LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */ 582 { 583 outcode(int($1), &$2, 0, &nullgen); 584 } 585 /* 586 * word 587 */ 588 | LWORD imm comma 589 { 590 outcode(int($1), &$2, 0, &nullgen); 591 } 592 | LWORD ximm comma 593 { 594 outcode(int($1), &$2, 0, &nullgen); 595 } 596 /* 597 * PCDATA 598 */ 599 | LPCDAT imm ',' imm 600 { 601 if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST { 602 yyerror("arguments to PCDATA must be integer constants") 603 } 604 outcode(int($1), &$2, 0, &$4); 605 } 606 /* 607 * FUNCDATA 608 */ 609 | LFUNCDAT imm ',' addr 610 { 611 if $2.Type != obj.TYPE_CONST { 612 yyerror("index for FUNCDATA must be integer constant") 613 } 614 if $4.Type != obj.TYPE_MEM || ($4.Name != obj.NAME_EXTERN && $4.Name != obj.NAME_STATIC) { 615 yyerror("value for FUNCDATA must be symbol reference") 616 } 617 outcode(int($1), &$2, 0, &$4); 618 } 619 /* 620 * END 621 */ 622 | LEND comma 623 { 624 outcode(int($1), &nullgen, 0, &nullgen); 625 } 626 /* 627 * TEXT 628 */ 629 | LTEXT name ',' '$' textsize 630 { 631 asm.Settext($2.Sym); 632 outcode(int($1), &$2, 0, &$5); 633 } 634 | LTEXT name ',' con ',' '$' textsize 635 { 636 asm.Settext($2.Sym); 637 outcode(int($1), &$2, int($4), &$7); 638 if asm.Pass > 1 { 639 lastpc.From3.Type = obj.TYPE_CONST 640 lastpc.From3.Offset = $4 641 } 642 } 643 /* 644 * GLOBL 645 */ 646 | LGLOBL name ',' imm 647 { 648 asm.Settext($2.Sym) 649 outcode(int($1), &$2, 0, &$4) 650 } 651 | LGLOBL name ',' con ',' imm 652 { 653 asm.Settext($2.Sym) 654 outcode(int($1), &$2, 0, &$6) 655 if asm.Pass > 1 { 656 lastpc.From3.Type = obj.TYPE_CONST 657 lastpc.From3.Offset = $4 658 } 659 } 660 661 /* 662 * DATA 663 */ 664 | LDATA name '/' con ',' imm 665 { 666 outcode(int($1), &$2, 0, &$6); 667 if asm.Pass > 1 { 668 lastpc.From3.Type = obj.TYPE_CONST 669 lastpc.From3.Offset = $4 670 } 671 } 672 | LDATA name '/' con ',' ximm 673 { 674 outcode(int($1), &$2, 0, &$6); 675 if asm.Pass > 1 { 676 lastpc.From3.Type = obj.TYPE_CONST 677 lastpc.From3.Offset = $4 678 } 679 } 680 | LDATA name '/' con ',' fimm 681 { 682 outcode(int($1), &$2, 0, &$6); 683 if asm.Pass > 1 { 684 lastpc.From3.Type = obj.TYPE_CONST 685 lastpc.From3.Offset = $4 686 } 687 } 688 /* 689 * RETURN 690 */ 691 | LRETRN comma 692 { 693 outcode(int($1), &nullgen, 0, &nullgen); 694 } 695 696 rel: 697 con '(' LPC ')' 698 { 699 $$ = nullgen; 700 $$.Type = obj.TYPE_BRANCH; 701 $$.Offset = $1 + int64(asm.PC); 702 } 703 | LNAME offset 704 { 705 $1 = asm.LabelLookup($1); 706 $$ = nullgen; 707 if asm.Pass == 2 && $1.Type != LLAB { 708 yyerror("undefined label: %s", $1.Labelname) 709 } 710 $$.Type = obj.TYPE_BRANCH; 711 $$.Offset = $1.Value + $2; 712 } 713 714 rreg: 715 sreg 716 { 717 $$ = nullgen; 718 $$.Type = obj.TYPE_REG; 719 $$.Reg = int16($1); 720 } 721 722 xlreg: 723 lr 724 | ctr 725 726 lr: 727 LLR 728 { 729 $$ = nullgen; 730 $$.Type = obj.TYPE_REG; 731 $$.Reg = int16($1); 732 } 733 734 lcr: 735 LCR 736 { 737 $$ = nullgen; 738 $$.Type = obj.TYPE_REG; 739 $$.Reg = int16($1); /* whole register */ 740 } 741 742 ctr: 743 LCTR 744 { 745 $$ = nullgen; 746 $$.Type = obj.TYPE_REG; 747 $$.Reg = int16($1); 748 } 749 750 msr: 751 LMSR 752 { 753 $$ = nullgen; 754 $$.Type = obj.TYPE_REG; 755 $$.Reg = int16($1) 756 } 757 758 psr: 759 LSPREG 760 { 761 $$ = nullgen; 762 $$.Type = obj.TYPE_REG; 763 $$.Reg = int16($1); 764 } 765 | LSPR '(' con ')' 766 { 767 if $3 < 0 || $3 >= 1024 { 768 yyerror("SPR/DCR out of range") 769 } 770 $$ = nullgen; 771 $$.Type = obj.TYPE_REG 772 $$.Reg = int16($1 + $3); 773 } 774 | msr 775 776 fpscr: 777 LFPSCR 778 { 779 $$ = nullgen; 780 $$.Type = obj.TYPE_REG; 781 $$.Reg = int16($1); 782 } 783 784 freg: 785 LFREG 786 { 787 $$ = nullgen; 788 $$.Type = obj.TYPE_REG; 789 $$.Reg = int16($1); 790 } 791 | LF '(' con ')' 792 { 793 $$ = nullgen; 794 $$.Type = obj.TYPE_REG; 795 $$.Reg = int16(REG_F0 + $3); 796 } 797 798 creg: 799 LCREG 800 { 801 $$ = nullgen; 802 $$.Type = obj.TYPE_REG; 803 $$.Reg = int16($1); 804 } 805 | LCR '(' con ')' 806 { 807 $$ = nullgen; 808 $$.Type = obj.TYPE_REG; 809 $$.Reg = int16(REG_CR0 + $3); 810 } 811 812 813 cbit: con 814 { 815 $$ = nullgen; 816 $$.Type = obj.TYPE_REG; 817 $$.Reg = int16($1); 818 } 819 820 mask: 821 con ',' con 822 { 823 var mb, me int 824 var v uint32 825 826 $$ = nullgen; 827 $$.Type = obj.TYPE_CONST; 828 mb = int($1); 829 me = int($3); 830 if(mb < 0 || mb > 31 || me < 0 || me > 31){ 831 yyerror("illegal mask start/end value(s)"); 832 mb = 0 833 me = 0; 834 } 835 if mb <= me { 836 v = (^uint32(0)>>uint(mb)) & (^uint32(0)<<uint(31-me)) 837 } else { 838 v = (^uint32(0)>>uint(me+1)) & (^uint32(0)<<uint(31-(mb-1))) 839 } 840 $$.Offset = int64(v); 841 } 842 843 textsize: 844 LCONST 845 { 846 $$ = nullgen; 847 $$.Type = obj.TYPE_TEXTSIZE; 848 $$.Offset = int64($1) 849 $$.Val = int32(obj.ArgsSizeUnknown); 850 } 851 | '-' LCONST 852 { 853 $$ = nullgen; 854 $$.Type = obj.TYPE_TEXTSIZE; 855 $$.Offset = -int64($2) 856 $$.Val = int32(obj.ArgsSizeUnknown); 857 } 858 | LCONST '-' LCONST 859 { 860 $$ = nullgen; 861 $$.Type = obj.TYPE_TEXTSIZE; 862 $$.Offset = int64($1) 863 $$.Val = int32($3); 864 } 865 | '-' LCONST '-' LCONST 866 { 867 $$ = nullgen; 868 $$.Type = obj.TYPE_TEXTSIZE; 869 $$.Offset = -int64($2) 870 $$.Val = int32($4); 871 } 872 873 ximm: 874 '$' addr 875 { 876 $$ = $2; 877 $$.Type = obj.TYPE_ADDR; 878 } 879 | '$' LSCONST 880 { 881 $$ = nullgen; 882 $$.Type = obj.TYPE_SCONST; 883 $$.Val = $2 884 } 885 886 fimm: 887 '$' LFCONST 888 { 889 $$ = nullgen; 890 $$.Type = obj.TYPE_FCONST; 891 $$.Val = $2; 892 } 893 | '$' '-' LFCONST 894 { 895 $$ = nullgen; 896 $$.Type = obj.TYPE_FCONST; 897 $$.Val = -$3; 898 } 899 900 imm: '$' con 901 { 902 $$ = nullgen; 903 $$.Type = obj.TYPE_CONST; 904 $$.Offset = $2; 905 } 906 907 sreg: 908 LREG 909 | LR '(' con ')' 910 { 911 if $$ < 0 || $$ >= NREG { 912 print("register value out of range\n") 913 } 914 $$ = REG_R0 + $3; 915 } 916 917 regaddr: 918 '(' sreg ')' 919 { 920 $$ = nullgen; 921 $$.Type = obj.TYPE_MEM; 922 $$.Reg = int16($2); 923 $$.Offset = 0; 924 } 925 | '(' sreg '+' sreg ')' 926 { 927 $$ = nullgen; 928 $$.Type = obj.TYPE_MEM; 929 $$.Reg = int16($2); 930 $$.Scale = int16($4); 931 $$.Offset = 0; 932 } 933 934 addr: 935 name 936 | con '(' sreg ')' 937 { 938 $$ = nullgen; 939 $$.Type = obj.TYPE_MEM; 940 $$.Reg = int16($3); 941 $$.Offset = $1; 942 } 943 944 name: 945 con '(' pointer ')' 946 { 947 $$ = nullgen; 948 $$.Type = obj.TYPE_MEM; 949 $$.Name = int8($3); 950 $$.Sym = nil; 951 $$.Offset = $1; 952 } 953 | LNAME offset '(' pointer ')' 954 { 955 $$ = nullgen; 956 $$.Type = obj.TYPE_MEM; 957 $$.Name = int8($4); 958 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); 959 $$.Offset = $2; 960 } 961 | LNAME '<' '>' offset '(' LSB ')' 962 { 963 $$ = nullgen; 964 $$.Type = obj.TYPE_MEM; 965 $$.Name = obj.NAME_STATIC; 966 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1); 967 $$.Offset = $4; 968 } 969 970 comma: 971 | ',' 972 973 offset: 974 { 975 $$ = 0; 976 } 977 | '+' con 978 { 979 $$ = $2; 980 } 981 | '-' con 982 { 983 $$ = -$2; 984 } 985 986 pointer: 987 LSB 988 | LSP 989 | LFP 990 991 con: 992 LCONST 993 | LVAR 994 { 995 $$ = $1.Value; 996 } 997 | '-' con 998 { 999 $$ = -$2; 1000 } 1001 | '+' con 1002 { 1003 $$ = $2; 1004 } 1005 | '~' con 1006 { 1007 $$ = ^$2; 1008 } 1009 | '(' expr ')' 1010 { 1011 $$ = $2; 1012 } 1013 1014 expr: 1015 con 1016 | expr '+' expr 1017 { 1018 $$ = $1 + $3; 1019 } 1020 | expr '-' expr 1021 { 1022 $$ = $1 - $3; 1023 } 1024 | expr '*' expr 1025 { 1026 $$ = $1 * $3; 1027 } 1028 | expr '/' expr 1029 { 1030 $$ = $1 / $3; 1031 } 1032 | expr '%' expr 1033 { 1034 $$ = $1 % $3; 1035 } 1036 | expr '<' '<' expr 1037 { 1038 $$ = $1 << uint($4); 1039 } 1040 | expr '>' '>' expr 1041 { 1042 $$ = $1 >> uint($4); 1043 } 1044 | expr '&' expr 1045 { 1046 $$ = $1 & $3; 1047 } 1048 | expr '^' expr 1049 { 1050 $$ = $1 ^ $3; 1051 } 1052 | expr '|' expr 1053 { 1054 $$ = $1 | $3; 1055 }