1 %{ 2 #include "a.h" 3 %} 4 %union { 5 Sym *sym; 6 long lval; 7 struct { 8 long v1; 9 long v2; 10 } con2; 11 double dval; 12 char sval[8]; 13 Gen gen; 14 Gen2 gen2; 15 } 16 %left '|' 17 %left '^' 18 %left '&' 19 %left '<' '>' 20 %left '+' '-' 21 %left '*' '/' '%' 22 %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 23 %token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG 24 %token <lval> LCONST LFP LPC LSB 25 %token <lval> LBREG LLREG LSREG LFREG 26 %token <dval> LFCONST 27 %token <sval> LSCONST LSP 28 %token <sym> LNAME LLAB LVAR 29 %type <lval> con expr pointer offset 30 %type <con2> con2 31 %type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem 32 %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim 33 %type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 34 %% 35 prog: 36 | prog line 37 38 line: 39 LLAB ':' 40 { 41 if($1->value != pc) 42 yyerror("redeclaration of %s", $1->name); 43 $1->value = pc; 44 } 45 line 46 | LNAME ':' 47 { 48 $1->type = LLAB; 49 $1->value = pc; 50 } 51 line 52 | ';' 53 | inst ';' 54 | error ';' 55 56 inst: 57 LNAME '=' expr 58 { 59 $1->type = LVAR; 60 $1->value = $3; 61 } 62 | LVAR '=' expr 63 { 64 if($1->value != $3) 65 yyerror("redeclaration of %s", $1->name); 66 $1->value = $3; 67 } 68 | LTYPE0 nonnon { outcode($1, &$2); } 69 | LTYPE1 nonrem { outcode($1, &$2); } 70 | LTYPE2 rimnon { outcode($1, &$2); } 71 | LTYPE3 rimrem { outcode($1, &$2); } 72 | LTYPE4 remrim { outcode($1, &$2); } 73 | LTYPER nonrel { outcode($1, &$2); } 74 | LTYPED spec1 { outcode($1, &$2); } 75 | LTYPET spec2 { outcode($1, &$2); } 76 | LTYPEC spec3 { outcode($1, &$2); } 77 | LTYPEN spec4 { outcode($1, &$2); } 78 | LTYPES spec5 { outcode($1, &$2); } 79 | LTYPEM spec6 { outcode($1, &$2); } 80 | LTYPEI spec7 { outcode($1, &$2); } 81 | LTYPEG spec8 { outcode($1, &$2); } 82 83 nonnon: 84 { 85 $$.from = nullgen; 86 $$.to = nullgen; 87 } 88 | ',' 89 { 90 $$.from = nullgen; 91 $$.to = nullgen; 92 } 93 94 rimrem: 95 rim ',' rem 96 { 97 $$.from = $1; 98 $$.to = $3; 99 } 100 101 remrim: 102 rem ',' rim 103 { 104 $$.from = $1; 105 $$.to = $3; 106 } 107 108 rimnon: 109 rim ',' 110 { 111 $$.from = $1; 112 $$.to = nullgen; 113 } 114 | rim 115 { 116 $$.from = $1; 117 $$.to = nullgen; 118 } 119 120 nonrem: 121 ',' rem 122 { 123 $$.from = nullgen; 124 $$.to = $2; 125 } 126 | rem 127 { 128 $$.from = nullgen; 129 $$.to = $1; 130 } 131 132 nonrel: 133 ',' rel 134 { 135 $$.from = nullgen; 136 $$.to = $2; 137 } 138 | rel 139 { 140 $$.from = nullgen; 141 $$.to = $1; 142 } 143 144 spec1: /* DATA */ 145 nam '/' con ',' imm 146 { 147 $$.from = $1; 148 $$.from.scale = $3; 149 $$.to = $5; 150 } 151 152 spec2: /* TEXT */ 153 mem ',' imm 154 { 155 $$.from = $1; 156 $$.to = $3; 157 } 158 | mem ',' con ',' imm 159 { 160 $$.from = $1; 161 $$.from.scale = $3; 162 $$.to = $5; 163 } 164 165 spec3: /* JMP/CALL */ 166 ',' rom 167 { 168 $$.from = nullgen; 169 $$.to = $2; 170 } 171 | rom 172 { 173 $$.from = nullgen; 174 $$.to = $1; 175 } 176 177 spec4: /* NOP */ 178 nonnon 179 | nonrem 180 181 spec5: /* SHL/SHR */ 182 rim ',' rem 183 { 184 $$.from = $1; 185 $$.to = $3; 186 } 187 | rim ',' rem ':' LLREG 188 { 189 $$.from = $1; 190 $$.to = $3; 191 if($$.from.index != D_NONE) 192 yyerror("dp shift with lhs index"); 193 $$.from.index = $5; 194 } 195 196 spec6: /* MOVW/MOVL */ 197 rim ',' rem 198 { 199 $$.from = $1; 200 $$.to = $3; 201 } 202 | rim ',' rem ':' LSREG 203 { 204 $$.from = $1; 205 $$.to = $3; 206 if($$.to.index != D_NONE) 207 yyerror("dp move with lhs index"); 208 $$.to.index = $5; 209 } 210 211 spec7: 212 rim ',' 213 { 214 $$.from = $1; 215 $$.to = nullgen; 216 } 217 | rim 218 { 219 $$.from = $1; 220 $$.to = nullgen; 221 } 222 | rim ',' rem 223 { 224 $$.from = $1; 225 $$.to = $3; 226 } 227 228 spec8: /* GLOBL */ 229 mem ',' imm 230 { 231 $$.from = $1; 232 $$.to = $3; 233 } 234 | mem ',' con ',' imm 235 { 236 $$.from = $1; 237 $$.from.scale = $3; 238 $$.to = $5; 239 } 240 241 rem: 242 reg 243 | mem 244 245 rom: 246 rel 247 | nmem 248 | '*' reg 249 { 250 $$ = $2; 251 } 252 | '*' omem 253 { 254 $$ = $2; 255 } 256 | reg 257 | omem 258 | imm 259 260 rim: 261 rem 262 | imm 263 264 rel: 265 con '(' LPC ')' 266 { 267 $$ = nullgen; 268 $$.type = D_BRANCH; 269 $$.offset = $1 + pc; 270 } 271 | LNAME offset 272 { 273 $$ = nullgen; 274 if(pass == 2) 275 yyerror("undefined label: %s", $1->name); 276 $$.type = D_BRANCH; 277 $$.sym = $1; 278 $$.offset = $2; 279 } 280 | LLAB offset 281 { 282 $$ = nullgen; 283 $$.type = D_BRANCH; 284 $$.sym = $1; 285 $$.offset = $1->value + $2; 286 } 287 288 reg: 289 LBREG 290 { 291 $$ = nullgen; 292 $$.type = $1; 293 } 294 | LFREG 295 { 296 $$ = nullgen; 297 $$.type = $1; 298 } 299 | LLREG 300 { 301 $$ = nullgen; 302 $$.type = $1; 303 } 304 | LSP 305 { 306 $$ = nullgen; 307 $$.type = D_SP; 308 } 309 | LSREG 310 { 311 $$ = nullgen; 312 $$.type = $1; 313 } 314 315 imm: 316 '$' con 317 { 318 $$ = nullgen; 319 $$.type = D_CONST; 320 $$.offset = $2; 321 } 322 | '$' nam 323 { 324 $$ = $2; 325 $$.index = $2.type; 326 $$.type = D_ADDR; 327 /* 328 if($2.type == D_AUTO || $2.type == D_PARAM) 329 yyerror("constant cannot be automatic: %s", 330 $2.sym->name); 331 */ 332 } 333 | '$' LSCONST 334 { 335 $$ = nullgen; 336 $$.type = D_SCONST; 337 memcpy($$.sval, $2, sizeof($$.sval)); 338 } 339 | '$' LFCONST 340 { 341 $$ = nullgen; 342 $$.type = D_FCONST; 343 $$.dval = $2; 344 } 345 | '$' '(' LFCONST ')' 346 { 347 $$ = nullgen; 348 $$.type = D_FCONST; 349 $$.dval = $3; 350 } 351 | '$' '-' LFCONST 352 { 353 $$ = nullgen; 354 $$.type = D_FCONST; 355 $$.dval = -$3; 356 } 357 358 imm2: 359 '$' con2 360 { 361 $$ = nullgen; 362 $$.type = D_CONST2; 363 $$.offset = $2.v1; 364 $$.offset2 = $2.v2; 365 } 366 367 con2: 368 LCONST 369 { 370 $$.v1 = $1; 371 $$.v2 = 0; 372 } 373 | '-' LCONST 374 { 375 $$.v1 = -$2; 376 $$.v2 = 0; 377 } 378 | LCONST '-' LCONST 379 { 380 $$.v1 = $1; 381 $$.v2 = $3; 382 } 383 | '-' LCONST '-' LCONST 384 { 385 $$.v1 = -$2; 386 $$.v2 = $4; 387 } 388 389 mem: 390 omem 391 | nmem 392 393 omem: 394 con 395 { 396 $$ = nullgen; 397 $$.type = D_INDIR+D_NONE; 398 $$.offset = $1; 399 } 400 | con '(' LLREG ')' 401 { 402 $$ = nullgen; 403 $$.type = D_INDIR+$3; 404 $$.offset = $1; 405 } 406 | con '(' LSP ')' 407 { 408 $$ = nullgen; 409 $$.type = D_INDIR+D_SP; 410 $$.offset = $1; 411 } 412 | con '(' LLREG '*' con ')' 413 { 414 $$ = nullgen; 415 $$.type = D_INDIR+D_NONE; 416 $$.offset = $1; 417 $$.index = $3; 418 $$.scale = $5; 419 checkscale($$.scale); 420 } 421 | con '(' LLREG ')' '(' LLREG '*' con ')' 422 { 423 $$ = nullgen; 424 $$.type = D_INDIR+$3; 425 $$.offset = $1; 426 $$.index = $6; 427 $$.scale = $8; 428 checkscale($$.scale); 429 } 430 | '(' LLREG ')' 431 { 432 $$ = nullgen; 433 $$.type = D_INDIR+$2; 434 } 435 | '(' LSP ')' 436 { 437 $$ = nullgen; 438 $$.type = D_INDIR+D_SP; 439 } 440 | con '(' LSREG ')' 441 { 442 $$ = nullgen; 443 $$.type = D_INDIR+$3; 444 $$.offset = $1; 445 } 446 | '(' LLREG '*' con ')' 447 { 448 $$ = nullgen; 449 $$.type = D_INDIR+D_NONE; 450 $$.index = $2; 451 $$.scale = $4; 452 checkscale($$.scale); 453 } 454 | '(' LLREG ')' '(' LLREG '*' con ')' 455 { 456 $$ = nullgen; 457 $$.type = D_INDIR+$2; 458 $$.index = $5; 459 $$.scale = $7; 460 checkscale($$.scale); 461 } 462 463 nmem: 464 nam 465 { 466 $$ = $1; 467 } 468 | nam '(' LLREG '*' con ')' 469 { 470 $$ = $1; 471 $$.index = $3; 472 $$.scale = $5; 473 checkscale($$.scale); 474 } 475 476 nam: 477 LNAME offset '(' pointer ')' 478 { 479 $$ = nullgen; 480 $$.type = $4; 481 $$.sym = $1; 482 $$.offset = $2; 483 } 484 | LNAME '<' '>' offset '(' LSB ')' 485 { 486 $$ = nullgen; 487 $$.type = D_STATIC; 488 $$.sym = $1; 489 $$.offset = $4; 490 } 491 492 offset: 493 { 494 $$ = 0; 495 } 496 | '+' con 497 { 498 $$ = $2; 499 } 500 | '-' con 501 { 502 $$ = -$2; 503 } 504 505 pointer: 506 LSB 507 | LSP 508 { 509 $$ = D_AUTO; 510 } 511 | LFP 512 513 con: 514 LCONST 515 | LVAR 516 { 517 $$ = $1->value; 518 } 519 | '-' con 520 { 521 $$ = -$2; 522 } 523 | '+' con 524 { 525 $$ = $2; 526 } 527 | '~' con 528 { 529 $$ = ~$2; 530 } 531 | '(' expr ')' 532 { 533 $$ = $2; 534 } 535 536 expr: 537 con 538 | expr '+' expr 539 { 540 $$ = $1 + $3; 541 } 542 | expr '-' expr 543 { 544 $$ = $1 - $3; 545 } 546 | expr '*' expr 547 { 548 $$ = $1 * $3; 549 } 550 | expr '/' expr 551 { 552 $$ = $1 / $3; 553 } 554 | expr '%' expr 555 { 556 $$ = $1 % $3; 557 } 558 | expr '<' '<' expr 559 { 560 $$ = $1 << $4; 561 } 562 | expr '>' '>' expr 563 { 564 $$ = $1 >> $4; 565 } 566 | expr '&' expr 567 { 568 $$ = $1 & $3; 569 } 570 | expr '^' expr 571 { 572 $$ = $1 ^ $3; 573 } 574 | expr '|' expr 575 { 576 $$ = $1 | $3; 577 } 578