1 /* bfin-parse.y ADI Blackfin parser 2 Copyright (C) 2005-2016 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 %{ 21 22 #include "as.h" 23 24 #include "bfin-aux.h" /* Opcode generating auxiliaries. */ 25 #include "libbfd.h" 26 #include "elf/common.h" 27 #include "elf/bfin.h" 28 29 #define DSP32ALU(aopcde, HL, dst1, dst0, src0, src1, s, x, aop) \ 30 bfin_gen_dsp32alu (HL, aopcde, aop, s, x, dst0, dst1, src0, src1) 31 32 #define DSP32MAC(op1, MM, mmod, w1, P, h01, h11, h00, h10, dst, op0, src0, src1, w0) \ 33 bfin_gen_dsp32mac (op1, MM, mmod, w1, P, h01, h11, h00, h10, op0, \ 34 dst, src0, src1, w0) 35 36 #define DSP32MULT(op1, MM, mmod, w1, P, h01, h11, h00, h10, dst, op0, src0, src1, w0) \ 37 bfin_gen_dsp32mult (op1, MM, mmod, w1, P, h01, h11, h00, h10, op0, \ 38 dst, src0, src1, w0) 39 40 #define DSP32SHIFT(sopcde, dst0, src0, src1, sop, hls) \ 41 bfin_gen_dsp32shift (sopcde, dst0, src0, src1, sop, hls) 42 43 #define DSP32SHIFTIMM(sopcde, dst0, immag, src1, sop, hls) \ 44 bfin_gen_dsp32shiftimm (sopcde, dst0, immag, src1, sop, hls) 45 46 #define LDIMMHALF_R(reg, h, s, z, hword) \ 47 bfin_gen_ldimmhalf (reg, h, s, z, hword, 1) 48 49 #define LDIMMHALF_R5(reg, h, s, z, hword) \ 50 bfin_gen_ldimmhalf (reg, h, s, z, hword, 2) 51 52 #define LDSTIDXI(ptr, reg, w, sz, z, offset) \ 53 bfin_gen_ldstidxi (ptr, reg, w, sz, z, offset) 54 55 #define LDST(ptr, reg, aop, sz, z, w) \ 56 bfin_gen_ldst (ptr, reg, aop, sz, z, w) 57 58 #define LDSTII(ptr, reg, offset, w, op) \ 59 bfin_gen_ldstii (ptr, reg, offset, w, op) 60 61 #define DSPLDST(i, m, reg, aop, w) \ 62 bfin_gen_dspldst (i, reg, aop, w, m) 63 64 #define LDSTPMOD(ptr, reg, idx, aop, w) \ 65 bfin_gen_ldstpmod (ptr, reg, aop, w, idx) 66 67 #define LDSTIIFP(offset, reg, w) \ 68 bfin_gen_ldstiifp (reg, offset, w) 69 70 #define LOGI2OP(dst, src, opc) \ 71 bfin_gen_logi2op (opc, src, dst.regno & CODE_MASK) 72 73 #define ALU2OP(dst, src, opc) \ 74 bfin_gen_alu2op (dst, src, opc) 75 76 #define BRCC(t, b, offset) \ 77 bfin_gen_brcc (t, b, offset) 78 79 #define UJUMP(offset) \ 80 bfin_gen_ujump (offset) 81 82 #define PROGCTRL(prgfunc, poprnd) \ 83 bfin_gen_progctrl (prgfunc, poprnd) 84 85 #define PUSHPOPMULTIPLE(dr, pr, d, p, w) \ 86 bfin_gen_pushpopmultiple (dr, pr, d, p, w) 87 88 #define PUSHPOPREG(reg, w) \ 89 bfin_gen_pushpopreg (reg, w) 90 91 #define CALLA(addr, s) \ 92 bfin_gen_calla (addr, s) 93 94 #define LINKAGE(r, framesize) \ 95 bfin_gen_linkage (r, framesize) 96 97 #define COMPI2OPD(dst, src, op) \ 98 bfin_gen_compi2opd (dst, src, op) 99 100 #define COMPI2OPP(dst, src, op) \ 101 bfin_gen_compi2opp (dst, src, op) 102 103 #define DAGMODIK(i, op) \ 104 bfin_gen_dagmodik (i, op) 105 106 #define DAGMODIM(i, m, op, br) \ 107 bfin_gen_dagmodim (i, m, op, br) 108 109 #define COMP3OP(dst, src0, src1, opc) \ 110 bfin_gen_comp3op (src0, src1, dst, opc) 111 112 #define PTR2OP(dst, src, opc) \ 113 bfin_gen_ptr2op (dst, src, opc) 114 115 #define CCFLAG(x, y, opc, i, g) \ 116 bfin_gen_ccflag (x, y, opc, i, g) 117 118 #define CCMV(src, dst, t) \ 119 bfin_gen_ccmv (src, dst, t) 120 121 #define CACTRL(reg, a, op) \ 122 bfin_gen_cactrl (reg, a, op) 123 124 #define LOOPSETUP(soffset, c, rop, eoffset, reg) \ 125 bfin_gen_loopsetup (soffset, c, rop, eoffset, reg) 126 127 #define HL2(r1, r0) (IS_H (r1) << 1 | IS_H (r0)) 128 #define IS_RANGE(bits, expr, sign, mul) \ 129 value_match(expr, bits, sign, mul, 1) 130 #define IS_URANGE(bits, expr, sign, mul) \ 131 value_match(expr, bits, sign, mul, 0) 132 #define IS_CONST(expr) (expr->type == Expr_Node_Constant) 133 #define IS_RELOC(expr) (expr->type != Expr_Node_Constant) 134 #define IS_IMM(expr, bits) value_match (expr, bits, 0, 1, 1) 135 #define IS_UIMM(expr, bits) value_match (expr, bits, 0, 1, 0) 136 137 #define IS_PCREL4(expr) \ 138 (value_match (expr, 4, 0, 2, 0)) 139 140 #define IS_LPPCREL10(expr) \ 141 (value_match (expr, 10, 0, 2, 0)) 142 143 #define IS_PCREL10(expr) \ 144 (value_match (expr, 10, 0, 2, 1)) 145 146 #define IS_PCREL12(expr) \ 147 (value_match (expr, 12, 0, 2, 1)) 148 149 #define IS_PCREL24(expr) \ 150 (value_match (expr, 24, 0, 2, 1)) 151 152 153 static int value_match (Expr_Node *, int, int, int, int); 154 155 extern FILE *errorf; 156 extern INSTR_T insn; 157 158 static Expr_Node *binary (Expr_Op_Type, Expr_Node *, Expr_Node *); 159 static Expr_Node *unary (Expr_Op_Type, Expr_Node *); 160 161 static void notethat (const char *, ...); 162 163 extern char *yytext; 164 int yyerror (const char *); 165 166 /* Used to set SRCx fields to all 1s as described in the PRM. */ 167 static Register reg7 = {REG_R7, 0}; 168 169 void error (const char *format, ...) 170 { 171 va_list ap; 172 static char buffer[2000]; 173 174 va_start (ap, format); 175 vsprintf (buffer, format, ap); 176 va_end (ap); 177 178 as_bad ("%s", buffer); 179 } 180 181 int 182 yyerror (const char *msg) 183 { 184 if (msg[0] == '\0') 185 error ("%s", msg); 186 187 else if (yytext[0] != ';') 188 error ("%s. Input text was %s.", msg, yytext); 189 else 190 error ("%s.", msg); 191 192 return -1; 193 } 194 195 static int 196 in_range_p (Expr_Node *exp, int from, int to, unsigned int mask) 197 { 198 int val = EXPR_VALUE (exp); 199 if (exp->type != Expr_Node_Constant) 200 return 0; 201 if (val < from || val > to) 202 return 0; 203 return (val & mask) == 0; 204 } 205 206 extern int yylex (void); 207 208 #define imm3(x) EXPR_VALUE (x) 209 #define imm4(x) EXPR_VALUE (x) 210 #define uimm4(x) EXPR_VALUE (x) 211 #define imm5(x) EXPR_VALUE (x) 212 #define uimm5(x) EXPR_VALUE (x) 213 #define imm6(x) EXPR_VALUE (x) 214 #define imm7(x) EXPR_VALUE (x) 215 #define uimm8(x) EXPR_VALUE (x) 216 #define imm16(x) EXPR_VALUE (x) 217 #define uimm16s4(x) ((EXPR_VALUE (x)) >> 2) 218 #define uimm16(x) EXPR_VALUE (x) 219 220 /* Return true if a value is inside a range. */ 221 #define IN_RANGE(x, low, high) \ 222 (((EXPR_VALUE(x)) >= (low)) && (EXPR_VALUE(x)) <= ((high))) 223 224 /* Auxiliary functions. */ 225 226 static int 227 valid_dreg_pair (Register *reg1, Expr_Node *reg2) 228 { 229 if (!IS_DREG (*reg1)) 230 { 231 yyerror ("Dregs expected"); 232 return 0; 233 } 234 235 if (reg1->regno != 1 && reg1->regno != 3) 236 { 237 yyerror ("Bad register pair"); 238 return 0; 239 } 240 241 if (imm7 (reg2) != reg1->regno - 1) 242 { 243 yyerror ("Bad register pair"); 244 return 0; 245 } 246 247 reg1->regno--; 248 return 1; 249 } 250 251 static int 252 check_multiply_halfregs (Macfunc *aa, Macfunc *ab) 253 { 254 if ((!REG_EQUAL (aa->s0, ab->s0) && !REG_EQUAL (aa->s0, ab->s1)) 255 || (!REG_EQUAL (aa->s1, ab->s1) && !REG_EQUAL (aa->s1, ab->s0))) 256 return yyerror ("Source multiplication register mismatch"); 257 258 return 0; 259 } 260 261 262 /* Check mac option. */ 263 264 static int 265 check_macfunc_option (Macfunc *a, Opt_mode *opt) 266 { 267 /* Default option is always valid. */ 268 if (opt->mod == 0) 269 return 0; 270 271 if ((a->w == 1 && a->P == 1 272 && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU 273 && opt->mod != M_S2RND && opt->mod != M_ISS2) 274 || (a->w == 1 && a->P == 0 275 && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU 276 && opt->mod != M_T && opt->mod != M_TFU && opt->mod != M_S2RND 277 && opt->mod != M_ISS2 && opt->mod != M_IH) 278 || (a->w == 0 && a->P == 0 279 && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_W32)) 280 return -1; 281 282 return 0; 283 } 284 285 /* Check (vector) mac funcs and ops. */ 286 287 static int 288 check_macfuncs (Macfunc *aa, Opt_mode *opa, 289 Macfunc *ab, Opt_mode *opb) 290 { 291 /* Variables for swapping. */ 292 Macfunc mtmp; 293 Opt_mode otmp; 294 295 /* The option mode should be put at the end of the second instruction 296 of the vector except M, which should follow MAC1 instruction. */ 297 if (opa->mod != 0) 298 return yyerror ("Bad opt mode"); 299 300 /* If a0macfunc comes before a1macfunc, swap them. */ 301 302 if (aa->n == 0) 303 { 304 /* (M) is not allowed here. */ 305 if (opa->MM != 0) 306 return yyerror ("(M) not allowed with A0MAC"); 307 if (ab->n != 1) 308 return yyerror ("Vector AxMACs can't be same"); 309 310 mtmp = *aa; *aa = *ab; *ab = mtmp; 311 otmp = *opa; *opa = *opb; *opb = otmp; 312 } 313 else 314 { 315 if (opb->MM != 0) 316 return yyerror ("(M) not allowed with A0MAC"); 317 if (ab->n != 0) 318 return yyerror ("Vector AxMACs can't be same"); 319 } 320 321 /* If both ops are one of 0, 1, or 2, we have multiply_halfregs in both 322 assignment_or_macfuncs. */ 323 if ((aa->op == 0 || aa->op == 1 || aa->op == 2) 324 && (ab->op == 0 || ab->op == 1 || ab->op == 2)) 325 { 326 if (check_multiply_halfregs (aa, ab) < 0) 327 return -1; 328 } 329 else 330 { 331 /* Only one of the assign_macfuncs has a half reg multiply 332 Evil trick: Just 'OR' their source register codes: 333 We can do that, because we know they were initialized to 0 334 in the rules that don't use multiply_halfregs. */ 335 aa->s0.regno |= (ab->s0.regno & CODE_MASK); 336 aa->s1.regno |= (ab->s1.regno & CODE_MASK); 337 } 338 339 if (aa->w == ab->w && aa->P != ab->P) 340 return yyerror ("Destination Dreg sizes (full or half) must match"); 341 342 if (aa->w && ab->w) 343 { 344 if (aa->P && (aa->dst.regno - ab->dst.regno) != 1) 345 return yyerror ("Destination Dregs (full) must differ by one"); 346 if (!aa->P && aa->dst.regno != ab->dst.regno) 347 return yyerror ("Destination Dregs (half) must match"); 348 } 349 350 /* Make sure mod flags get ORed, too. */ 351 opb->mod |= opa->mod; 352 353 /* Check option. */ 354 if (check_macfunc_option (aa, opb) < 0 355 && check_macfunc_option (ab, opb) < 0) 356 return yyerror ("bad option"); 357 358 /* Make sure first macfunc has got both P flags ORed. */ 359 aa->P |= ab->P; 360 361 return 0; 362 } 363 364 365 static int 366 is_group1 (INSTR_T x) 367 { 368 /* Group1 is dpsLDST, LDSTpmod, LDST, LDSTiiFP, LDSTii. */ 369 if ((x->value & 0xc000) == 0x8000 || (x->value == 0x0000)) 370 return 1; 371 372 return 0; 373 } 374 375 static int 376 is_group2 (INSTR_T x) 377 { 378 if ((((x->value & 0xfc00) == 0x9c00) /* dspLDST. */ 379 && !((x->value & 0xfde0) == 0x9c60) /* dagMODim. */ 380 && !((x->value & 0xfde0) == 0x9ce0) /* dagMODim with bit rev. */ 381 && !((x->value & 0xfde0) == 0x9d60)) /* pick dagMODik. */ 382 || (x->value == 0x0000)) 383 return 1; 384 return 0; 385 } 386 387 static int 388 is_store (INSTR_T x) 389 { 390 if (!x) 391 return 0; 392 393 if ((x->value & 0xf000) == 0x8000) 394 { 395 int aop = ((x->value >> 9) & 0x3); 396 int w = ((x->value >> 11) & 0x1); 397 if (!w || aop == 3) 398 return 0; 399 return 1; 400 } 401 402 if (((x->value & 0xFF60) == 0x9E60) || /* dagMODim_0 */ 403 ((x->value & 0xFFF0) == 0x9F60)) /* dagMODik_0 */ 404 return 0; 405 406 /* decode_dspLDST_0 */ 407 if ((x->value & 0xFC00) == 0x9C00) 408 { 409 int w = ((x->value >> 9) & 0x1); 410 if (w) 411 return 1; 412 } 413 414 return 0; 415 } 416 417 static INSTR_T 418 gen_multi_instr_1 (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2) 419 { 420 int mask1 = dsp32 ? insn_regmask (dsp32->value, dsp32->next->value) : 0; 421 int mask2 = dsp16_grp1 ? insn_regmask (dsp16_grp1->value, 0) : 0; 422 int mask3 = dsp16_grp2 ? insn_regmask (dsp16_grp2->value, 0) : 0; 423 424 if ((mask1 & mask2) || (mask1 & mask3) || (mask2 & mask3)) 425 yyerror ("resource conflict in multi-issue instruction"); 426 427 /* Anomaly 05000074 */ 428 if (ENABLE_AC_05000074 429 && dsp32 != NULL && dsp16_grp1 != NULL 430 && (dsp32->value & 0xf780) == 0xc680 431 && ((dsp16_grp1->value & 0xfe40) == 0x9240 432 || (dsp16_grp1->value & 0xfe08) == 0xba08 433 || (dsp16_grp1->value & 0xfc00) == 0xbc00)) 434 yyerror ("anomaly 05000074 - Multi-Issue Instruction with \ 435 dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported"); 436 437 if (is_store (dsp16_grp1) && is_store (dsp16_grp2)) 438 yyerror ("Only one instruction in multi-issue instruction can be a store"); 439 440 return bfin_gen_multi_instr (dsp32, dsp16_grp1, dsp16_grp2); 441 } 442 443 %} 444 445 %union { 446 INSTR_T instr; 447 Expr_Node *expr; 448 SYMBOL_T symbol; 449 long value; 450 Register reg; 451 Macfunc macfunc; 452 struct { int r0; int s0; int x0; int aop; } modcodes; 453 struct { int r0; } r0; 454 Opt_mode mod; 455 } 456 457 458 /* Tokens. */ 459 460 /* Vector Specific. */ 461 %token BYTEOP16P BYTEOP16M 462 %token BYTEOP1P BYTEOP2P BYTEOP3P 463 %token BYTEUNPACK BYTEPACK 464 %token PACK 465 %token SAA 466 %token ALIGN8 ALIGN16 ALIGN24 467 %token VIT_MAX 468 %token EXTRACT DEPOSIT EXPADJ SEARCH 469 %token ONES SIGN SIGNBITS 470 471 /* Stack. */ 472 %token LINK UNLINK 473 474 /* Registers. */ 475 %token REG 476 %token PC 477 %token CCREG BYTE_DREG 478 %token REG_A_DOUBLE_ZERO REG_A_DOUBLE_ONE 479 %token A_ZERO_DOT_L A_ZERO_DOT_H A_ONE_DOT_L A_ONE_DOT_H 480 %token HALF_REG 481 482 /* Progctrl. */ 483 %token NOP 484 %token RTI RTS RTX RTN RTE 485 %token HLT IDLE 486 %token STI CLI 487 %token CSYNC SSYNC 488 %token EMUEXCPT 489 %token RAISE EXCPT 490 %token LSETUP 491 %token LOOP 492 %token LOOP_BEGIN 493 %token LOOP_END 494 %token DISALGNEXCPT 495 %token JUMP JUMP_DOT_S JUMP_DOT_L 496 %token CALL 497 498 /* Emulator only. */ 499 %token ABORT 500 501 /* Operators. */ 502 %token NOT TILDA BANG 503 %token AMPERSAND BAR 504 %token PERCENT 505 %token CARET 506 %token BXOR 507 508 %token MINUS PLUS STAR SLASH 509 %token NEG 510 %token MIN MAX ABS 511 %token DOUBLE_BAR 512 %token _PLUS_BAR_PLUS _PLUS_BAR_MINUS _MINUS_BAR_PLUS _MINUS_BAR_MINUS 513 %token _MINUS_MINUS _PLUS_PLUS 514 515 /* Shift/rotate ops. */ 516 %token SHIFT LSHIFT ASHIFT BXORSHIFT 517 %token _GREATER_GREATER_GREATER_THAN_ASSIGN 518 %token ROT 519 %token LESS_LESS GREATER_GREATER 520 %token _GREATER_GREATER_GREATER 521 %token _LESS_LESS_ASSIGN _GREATER_GREATER_ASSIGN 522 %token DIVS DIVQ 523 524 /* In place operators. */ 525 %token ASSIGN _STAR_ASSIGN 526 %token _BAR_ASSIGN _CARET_ASSIGN _AMPERSAND_ASSIGN 527 %token _MINUS_ASSIGN _PLUS_ASSIGN 528 529 /* Assignments, comparisons. */ 530 %token _ASSIGN_BANG _LESS_THAN_ASSIGN _ASSIGN_ASSIGN 531 %token GE LT LE GT 532 %token LESS_THAN 533 534 /* Cache. */ 535 %token FLUSHINV FLUSH 536 %token IFLUSH PREFETCH 537 538 /* Misc. */ 539 %token PRNT 540 %token OUTC 541 %token WHATREG 542 %token TESTSET 543 544 /* Modifiers. */ 545 %token ASL ASR 546 %token B W 547 %token NS S CO SCO 548 %token TH TL 549 %token BP 550 %token BREV 551 %token X Z 552 %token M MMOD 553 %token R RND RNDL RNDH RND12 RND20 554 %token V 555 %token LO HI 556 557 /* Bit ops. */ 558 %token BITTGL BITCLR BITSET BITTST BITMUX 559 560 /* Debug. */ 561 %token DBGAL DBGAH DBGHALT DBG DBGA DBGCMPLX 562 563 /* Semantic auxiliaries. */ 564 565 %token IF COMMA BY 566 %token COLON SEMICOLON 567 %token RPAREN LPAREN LBRACK RBRACK 568 %token STATUS_REG 569 %token MNOP 570 %token SYMBOL NUMBER 571 %token GOT GOT17M4 FUNCDESC_GOT17M4 572 %token AT PLTPC 573 574 /* Types. */ 575 %type <instr> asm 576 %type <value> MMOD 577 %type <mod> opt_mode 578 579 %type <value> NUMBER 580 %type <r0> aligndir 581 %type <modcodes> byteop_mod 582 %type <reg> a_assign 583 %type <reg> a_plusassign 584 %type <reg> a_minusassign 585 %type <macfunc> multiply_halfregs 586 %type <macfunc> assign_macfunc 587 %type <macfunc> a_macfunc 588 %type <expr> expr_1 589 %type <instr> asm_1 590 %type <r0> vmod 591 %type <modcodes> vsmod 592 %type <modcodes> ccstat 593 %type <r0> cc_op 594 %type <reg> CCREG 595 %type <reg> reg_with_postinc 596 %type <reg> reg_with_predec 597 598 %type <r0> searchmod 599 %type <expr> symbol 600 %type <symbol> SYMBOL 601 %type <expr> eterm 602 %type <reg> REG 603 %type <reg> BYTE_DREG 604 %type <reg> REG_A_DOUBLE_ZERO 605 %type <reg> REG_A_DOUBLE_ONE 606 %type <reg> REG_A 607 %type <reg> STATUS_REG 608 %type <expr> expr 609 %type <r0> xpmod 610 %type <r0> xpmod1 611 %type <modcodes> smod 612 %type <modcodes> b3_op 613 %type <modcodes> rnd_op 614 %type <modcodes> post_op 615 %type <reg> HALF_REG 616 %type <r0> iu_or_nothing 617 %type <r0> plus_minus 618 %type <r0> asr_asl 619 %type <r0> asr_asl_0 620 %type <modcodes> sco 621 %type <modcodes> amod0 622 %type <modcodes> amod1 623 %type <modcodes> amod2 624 %type <r0> op_bar_op 625 %type <r0> w32_or_nothing 626 %type <r0> c_align 627 %type <r0> min_max 628 %type <expr> got 629 %type <expr> got_or_expr 630 %type <expr> pltpc 631 %type <value> any_gotrel GOT GOT17M4 FUNCDESC_GOT17M4 632 633 /* Precedence rules. */ 634 %left BAR 635 %left CARET 636 %left AMPERSAND 637 %left LESS_LESS GREATER_GREATER 638 %left PLUS MINUS 639 %left STAR SLASH PERCENT 640 641 %right ASSIGN 642 643 %right TILDA BANG 644 %start statement 645 %% 646 statement: 647 | asm 648 { 649 insn = $1; 650 if (insn == (INSTR_T) 0) 651 return NO_INSN_GENERATED; 652 else if (insn == (INSTR_T) - 1) 653 return SEMANTIC_ERROR; 654 else 655 return INSN_GENERATED; 656 } 657 ; 658 659 asm: asm_1 SEMICOLON 660 /* Parallel instructions. */ 661 | asm_1 DOUBLE_BAR asm_1 DOUBLE_BAR asm_1 SEMICOLON 662 { 663 if (($1->value & 0xf800) == 0xc000) 664 { 665 if (is_group1 ($3) && is_group2 ($5)) 666 $$ = gen_multi_instr_1 ($1, $3, $5); 667 else if (is_group2 ($3) && is_group1 ($5)) 668 $$ = gen_multi_instr_1 ($1, $5, $3); 669 else 670 return yyerror ("Wrong 16 bit instructions groups, slot 2 and slot 3 must be 16-bit instrution group"); 671 } 672 else if (($3->value & 0xf800) == 0xc000) 673 { 674 if (is_group1 ($1) && is_group2 ($5)) 675 $$ = gen_multi_instr_1 ($3, $1, $5); 676 else if (is_group2 ($1) && is_group1 ($5)) 677 $$ = gen_multi_instr_1 ($3, $5, $1); 678 else 679 return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 3 must be 16-bit instrution group"); 680 } 681 else if (($5->value & 0xf800) == 0xc000) 682 { 683 if (is_group1 ($1) && is_group2 ($3)) 684 $$ = gen_multi_instr_1 ($5, $1, $3); 685 else if (is_group2 ($1) && is_group1 ($3)) 686 $$ = gen_multi_instr_1 ($5, $3, $1); 687 else 688 return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be 16-bit instrution group"); 689 } 690 else 691 error ("\nIllegal Multi Issue Construct, at least any one of the slot must be DSP32 instruction group\n"); 692 } 693 694 | asm_1 DOUBLE_BAR asm_1 SEMICOLON 695 { 696 if (($1->value & 0xf800) == 0xc000) 697 { 698 if (is_group1 ($3)) 699 $$ = gen_multi_instr_1 ($1, $3, 0); 700 else if (is_group2 ($3)) 701 $$ = gen_multi_instr_1 ($1, 0, $3); 702 else 703 return yyerror ("Wrong 16 bit instructions groups, slot 2 must be the 16-bit instruction group"); 704 } 705 else if (($3->value & 0xf800) == 0xc000) 706 { 707 if (is_group1 ($1)) 708 $$ = gen_multi_instr_1 ($3, $1, 0); 709 else if (is_group2 ($1)) 710 $$ = gen_multi_instr_1 ($3, 0, $1); 711 else 712 return yyerror ("Wrong 16 bit instructions groups, slot 1 must be the 16-bit instruction group"); 713 } 714 else if (is_group1 ($1) && is_group2 ($3)) 715 $$ = gen_multi_instr_1 (0, $1, $3); 716 else if (is_group2 ($1) && is_group1 ($3)) 717 $$ = gen_multi_instr_1 (0, $3, $1); 718 else 719 return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be the 16-bit instruction group"); 720 } 721 | error 722 { 723 $$ = 0; 724 yyerror (""); 725 yyerrok; 726 } 727 ; 728 729 /* DSPMAC. */ 730 731 asm_1: 732 MNOP 733 { 734 $$ = DSP32MAC (3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); 735 } 736 | assign_macfunc opt_mode 737 { 738 int op0, op1; 739 int w0 = 0, w1 = 0; 740 int h00, h10, h01, h11; 741 742 if (check_macfunc_option (&$1, &$2) < 0) 743 return yyerror ("bad option"); 744 745 if ($1.n == 0) 746 { 747 if ($2.MM) 748 return yyerror ("(m) not allowed with a0 unit"); 749 op1 = 3; 750 op0 = $1.op; 751 w1 = 0; 752 w0 = $1.w; 753 h00 = IS_H ($1.s0); 754 h10 = IS_H ($1.s1); 755 h01 = h11 = 0; 756 } 757 else 758 { 759 op1 = $1.op; 760 op0 = 3; 761 w1 = $1.w; 762 w0 = 0; 763 h00 = h10 = 0; 764 h01 = IS_H ($1.s0); 765 h11 = IS_H ($1.s1); 766 } 767 $$ = DSP32MAC (op1, $2.MM, $2.mod, w1, $1.P, h01, h11, h00, h10, 768 &$1.dst, op0, &$1.s0, &$1.s1, w0); 769 } 770 771 772 /* VECTOR MACs. */ 773 774 | assign_macfunc opt_mode COMMA assign_macfunc opt_mode 775 { 776 Register *dst; 777 778 if (check_macfuncs (&$1, &$2, &$4, &$5) < 0) 779 return -1; 780 notethat ("assign_macfunc (.), assign_macfunc (.)\n"); 781 782 if ($1.w) 783 dst = &$1.dst; 784 else 785 dst = &$4.dst; 786 787 $$ = DSP32MAC ($1.op, $2.MM, $5.mod, $1.w, $1.P, 788 IS_H ($1.s0), IS_H ($1.s1), IS_H ($4.s0), IS_H ($4.s1), 789 dst, $4.op, &$1.s0, &$1.s1, $4.w); 790 } 791 792 /* DSPALU. */ 793 794 | DISALGNEXCPT 795 { 796 notethat ("dsp32alu: DISALGNEXCPT\n"); 797 $$ = DSP32ALU (18, 0, 0, 0, 0, 0, 0, 0, 3); 798 } 799 | REG ASSIGN LPAREN a_plusassign REG_A RPAREN 800 { 801 if (IS_DREG ($1) && !IS_A1 ($4) && IS_A1 ($5)) 802 { 803 notethat ("dsp32alu: dregs = ( A0 += A1 )\n"); 804 $$ = DSP32ALU (11, 0, 0, &$1, ®7, ®7, 0, 0, 0); 805 } 806 else 807 return yyerror ("Register mismatch"); 808 } 809 | HALF_REG ASSIGN LPAREN a_plusassign REG_A RPAREN 810 { 811 if (!IS_A1 ($4) && IS_A1 ($5)) 812 { 813 notethat ("dsp32alu: dregs_half = ( A0 += A1 )\n"); 814 $$ = DSP32ALU (11, IS_H ($1), 0, &$1, ®7, ®7, 0, 0, 1); 815 } 816 else 817 return yyerror ("Register mismatch"); 818 } 819 | A_ZERO_DOT_H ASSIGN HALF_REG 820 { 821 notethat ("dsp32alu: A_ZERO_DOT_H = dregs_hi\n"); 822 $$ = DSP32ALU (9, IS_H ($3), 0, 0, &$3, 0, 0, 0, 0); 823 } 824 | A_ONE_DOT_H ASSIGN HALF_REG 825 { 826 notethat ("dsp32alu: A_ZERO_DOT_H = dregs_hi\n"); 827 $$ = DSP32ALU (9, IS_H ($3), 0, 0, &$3, 0, 0, 0, 2); 828 } 829 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEOP16P LPAREN REG 830 COLON expr COMMA REG COLON expr RPAREN aligndir 831 { 832 if (!IS_DREG ($2) || !IS_DREG ($4)) 833 return yyerror ("Dregs expected"); 834 else if (REG_SAME ($2, $4)) 835 return yyerror ("Illegal dest register combination"); 836 else if (!valid_dreg_pair (&$9, $11)) 837 return yyerror ("Bad dreg pair"); 838 else if (!valid_dreg_pair (&$13, $15)) 839 return yyerror ("Bad dreg pair"); 840 else 841 { 842 notethat ("dsp32alu: (dregs , dregs ) = BYTEOP16P (dregs_pair , dregs_pair ) (aligndir)\n"); 843 $$ = DSP32ALU (21, 0, &$2, &$4, &$9, &$13, $17.r0, 0, 0); 844 } 845 } 846 847 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEOP16M LPAREN REG COLON expr COMMA 848 REG COLON expr RPAREN aligndir 849 { 850 if (!IS_DREG ($2) || !IS_DREG ($4)) 851 return yyerror ("Dregs expected"); 852 else if (REG_SAME ($2, $4)) 853 return yyerror ("Illegal dest register combination"); 854 else if (!valid_dreg_pair (&$9, $11)) 855 return yyerror ("Bad dreg pair"); 856 else if (!valid_dreg_pair (&$13, $15)) 857 return yyerror ("Bad dreg pair"); 858 else 859 { 860 notethat ("dsp32alu: (dregs , dregs ) = BYTEOP16M (dregs_pair , dregs_pair ) (aligndir)\n"); 861 $$ = DSP32ALU (21, 0, &$2, &$4, &$9, &$13, $17.r0, 0, 1); 862 } 863 } 864 865 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEUNPACK REG COLON expr aligndir 866 { 867 if (!IS_DREG ($2) || !IS_DREG ($4)) 868 return yyerror ("Dregs expected"); 869 else if (REG_SAME ($2, $4)) 870 return yyerror ("Illegal dest register combination"); 871 else if (!valid_dreg_pair (&$8, $10)) 872 return yyerror ("Bad dreg pair"); 873 else 874 { 875 notethat ("dsp32alu: (dregs , dregs ) = BYTEUNPACK dregs_pair (aligndir)\n"); 876 $$ = DSP32ALU (24, 0, &$2, &$4, &$8, 0, $11.r0, 0, 1); 877 } 878 } 879 | LPAREN REG COMMA REG RPAREN ASSIGN SEARCH REG LPAREN searchmod RPAREN 880 { 881 if (REG_SAME ($2, $4)) 882 return yyerror ("Illegal dest register combination"); 883 884 if (IS_DREG ($2) && IS_DREG ($4) && IS_DREG ($8)) 885 { 886 notethat ("dsp32alu: (dregs , dregs ) = SEARCH dregs (searchmod)\n"); 887 $$ = DSP32ALU (13, 0, &$2, &$4, &$8, 0, 0, 0, $10.r0); 888 } 889 else 890 return yyerror ("Register mismatch"); 891 } 892 | REG ASSIGN A_ONE_DOT_L PLUS A_ONE_DOT_H COMMA 893 REG ASSIGN A_ZERO_DOT_L PLUS A_ZERO_DOT_H 894 { 895 if (REG_SAME ($1, $7)) 896 return yyerror ("Illegal dest register combination"); 897 898 if (IS_DREG ($1) && IS_DREG ($7)) 899 { 900 notethat ("dsp32alu: dregs = A1.l + A1.h, dregs = A0.l + A0.h \n"); 901 $$ = DSP32ALU (12, 0, &$1, &$7, ®7, ®7, 0, 0, 1); 902 } 903 else 904 return yyerror ("Register mismatch"); 905 } 906 907 908 | REG ASSIGN REG_A PLUS REG_A COMMA REG ASSIGN REG_A MINUS REG_A amod1 909 { 910 if (REG_SAME ($1, $7)) 911 return yyerror ("Resource conflict in dest reg"); 912 913 if (IS_DREG ($1) && IS_DREG ($7) && !REG_SAME ($3, $5) 914 && IS_A1 ($9) && !IS_A1 ($11)) 915 { 916 notethat ("dsp32alu: dregs = A1 + A0 , dregs = A1 - A0 (amod1)\n"); 917 $$ = DSP32ALU (17, 0, &$1, &$7, ®7, ®7, $12.s0, $12.x0, 0); 918 919 } 920 else if (IS_DREG ($1) && IS_DREG ($7) && !REG_SAME ($3, $5) 921 && !IS_A1 ($9) && IS_A1 ($11)) 922 { 923 notethat ("dsp32alu: dregs = A0 + A1 , dregs = A0 - A1 (amod1)\n"); 924 $$ = DSP32ALU (17, 0, &$1, &$7, ®7, ®7, $12.s0, $12.x0, 1); 925 } 926 else 927 return yyerror ("Register mismatch"); 928 } 929 930 | REG ASSIGN REG plus_minus REG COMMA REG ASSIGN REG plus_minus REG amod1 931 { 932 if ($4.r0 == $10.r0) 933 return yyerror ("Operators must differ"); 934 935 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5) 936 && REG_SAME ($3, $9) && REG_SAME ($5, $11)) 937 { 938 notethat ("dsp32alu: dregs = dregs + dregs," 939 "dregs = dregs - dregs (amod1)\n"); 940 $$ = DSP32ALU (4, 0, &$1, &$7, &$3, &$5, $12.s0, $12.x0, 2); 941 } 942 else 943 return yyerror ("Register mismatch"); 944 } 945 946 /* Bar Operations. */ 947 948 | REG ASSIGN REG op_bar_op REG COMMA REG ASSIGN REG op_bar_op REG amod2 949 { 950 if (!REG_SAME ($3, $9) || !REG_SAME ($5, $11)) 951 return yyerror ("Differing source registers"); 952 953 if (!IS_DREG ($1) || !IS_DREG ($3) || !IS_DREG ($5) || !IS_DREG ($7)) 954 return yyerror ("Dregs expected"); 955 956 if (REG_SAME ($1, $7)) 957 return yyerror ("Resource conflict in dest reg"); 958 959 if ($4.r0 == 1 && $10.r0 == 2) 960 { 961 notethat ("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n"); 962 $$ = DSP32ALU (1, 1, &$1, &$7, &$3, &$5, $12.s0, $12.x0, $12.r0); 963 } 964 else if ($4.r0 == 0 && $10.r0 == 3) 965 { 966 notethat ("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n"); 967 $$ = DSP32ALU (1, 0, &$1, &$7, &$3, &$5, $12.s0, $12.x0, $12.r0); 968 } 969 else 970 return yyerror ("Bar operand mismatch"); 971 } 972 973 | REG ASSIGN ABS REG vmod 974 { 975 int op; 976 977 if (IS_DREG ($1) && IS_DREG ($4)) 978 { 979 if ($5.r0) 980 { 981 notethat ("dsp32alu: dregs = ABS dregs (v)\n"); 982 op = 6; 983 } 984 else 985 { 986 /* Vector version of ABS. */ 987 notethat ("dsp32alu: dregs = ABS dregs\n"); 988 op = 7; 989 } 990 $$ = DSP32ALU (op, 0, 0, &$1, &$4, 0, 0, 0, 2); 991 } 992 else 993 return yyerror ("Dregs expected"); 994 } 995 | a_assign ABS REG_A 996 { 997 notethat ("dsp32alu: Ax = ABS Ax\n"); 998 $$ = DSP32ALU (16, IS_A1 ($1), 0, 0, ®7, ®7, 0, 0, IS_A1 ($3)); 999 } 1000 | A_ZERO_DOT_L ASSIGN HALF_REG 1001 { 1002 if (IS_DREG_L ($3)) 1003 { 1004 notethat ("dsp32alu: A0.l = reg_half\n"); 1005 $$ = DSP32ALU (9, IS_H ($3), 0, 0, &$3, 0, 0, 0, 0); 1006 } 1007 else 1008 return yyerror ("A0.l = Rx.l expected"); 1009 } 1010 | A_ONE_DOT_L ASSIGN HALF_REG 1011 { 1012 if (IS_DREG_L ($3)) 1013 { 1014 notethat ("dsp32alu: A1.l = reg_half\n"); 1015 $$ = DSP32ALU (9, IS_H ($3), 0, 0, &$3, 0, 0, 0, 2); 1016 } 1017 else 1018 return yyerror ("A1.l = Rx.l expected"); 1019 } 1020 1021 | REG ASSIGN c_align LPAREN REG COMMA REG RPAREN 1022 { 1023 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 1024 { 1025 notethat ("dsp32shift: dregs = ALIGN8 (dregs , dregs )\n"); 1026 $$ = DSP32SHIFT (13, &$1, &$7, &$5, $3.r0, 0); 1027 } 1028 else 1029 return yyerror ("Dregs expected"); 1030 } 1031 1032 | REG ASSIGN BYTEOP1P LPAREN REG COLON expr COMMA REG COLON expr RPAREN byteop_mod 1033 { 1034 if (!IS_DREG ($1)) 1035 return yyerror ("Dregs expected"); 1036 else if (!valid_dreg_pair (&$5, $7)) 1037 return yyerror ("Bad dreg pair"); 1038 else if (!valid_dreg_pair (&$9, $11)) 1039 return yyerror ("Bad dreg pair"); 1040 else 1041 { 1042 notethat ("dsp32alu: dregs = BYTEOP1P (dregs_pair , dregs_pair ) (T)\n"); 1043 $$ = DSP32ALU (20, 0, 0, &$1, &$5, &$9, $13.s0, 0, $13.r0); 1044 } 1045 } 1046 | REG ASSIGN BYTEOP1P LPAREN REG COLON expr COMMA REG COLON expr RPAREN 1047 { 1048 if (!IS_DREG ($1)) 1049 return yyerror ("Dregs expected"); 1050 else if (!valid_dreg_pair (&$5, $7)) 1051 return yyerror ("Bad dreg pair"); 1052 else if (!valid_dreg_pair (&$9, $11)) 1053 return yyerror ("Bad dreg pair"); 1054 else 1055 { 1056 notethat ("dsp32alu: dregs = BYTEOP1P (dregs_pair , dregs_pair ) (T)\n"); 1057 $$ = DSP32ALU (20, 0, 0, &$1, &$5, &$9, 0, 0, 0); 1058 } 1059 } 1060 1061 | REG ASSIGN BYTEOP2P LPAREN REG COLON expr COMMA REG COLON expr RPAREN 1062 rnd_op 1063 { 1064 if (!IS_DREG ($1)) 1065 return yyerror ("Dregs expected"); 1066 else if (!valid_dreg_pair (&$5, $7)) 1067 return yyerror ("Bad dreg pair"); 1068 else if (!valid_dreg_pair (&$9, $11)) 1069 return yyerror ("Bad dreg pair"); 1070 else 1071 { 1072 notethat ("dsp32alu: dregs = BYTEOP2P (dregs_pair , dregs_pair ) (rnd_op)\n"); 1073 $$ = DSP32ALU (22, $13.r0, 0, &$1, &$5, &$9, $13.s0, $13.x0, $13.aop); 1074 } 1075 } 1076 1077 | REG ASSIGN BYTEOP3P LPAREN REG COLON expr COMMA REG COLON expr RPAREN 1078 b3_op 1079 { 1080 if (!IS_DREG ($1)) 1081 return yyerror ("Dregs expected"); 1082 else if (!valid_dreg_pair (&$5, $7)) 1083 return yyerror ("Bad dreg pair"); 1084 else if (!valid_dreg_pair (&$9, $11)) 1085 return yyerror ("Bad dreg pair"); 1086 else 1087 { 1088 notethat ("dsp32alu: dregs = BYTEOP3P (dregs_pair , dregs_pair ) (b3_op)\n"); 1089 $$ = DSP32ALU (23, $13.x0, 0, &$1, &$5, &$9, $13.s0, 0, 0); 1090 } 1091 } 1092 1093 | REG ASSIGN BYTEPACK LPAREN REG COMMA REG RPAREN 1094 { 1095 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 1096 { 1097 notethat ("dsp32alu: dregs = BYTEPACK (dregs , dregs )\n"); 1098 $$ = DSP32ALU (24, 0, 0, &$1, &$5, &$7, 0, 0, 0); 1099 } 1100 else 1101 return yyerror ("Dregs expected"); 1102 } 1103 1104 | HALF_REG ASSIGN HALF_REG ASSIGN SIGN LPAREN HALF_REG RPAREN STAR 1105 HALF_REG PLUS SIGN LPAREN HALF_REG RPAREN STAR HALF_REG 1106 { 1107 if (IS_HCOMPL ($1, $3) && IS_HCOMPL ($7, $14) && IS_HCOMPL ($10, $17)) 1108 { 1109 notethat ("dsp32alu: dregs_hi = dregs_lo =" 1110 "SIGN (dregs_hi) * dregs_hi + " 1111 "SIGN (dregs_lo) * dregs_lo \n"); 1112 1113 $$ = DSP32ALU (12, 0, 0, &$1, &$7, &$10, 0, 0, 0); 1114 } 1115 else 1116 return yyerror ("Dregs expected"); 1117 } 1118 | REG ASSIGN REG plus_minus REG amod1 1119 { 1120 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)) 1121 { 1122 if ($6.aop == 0) 1123 { 1124 /* No saturation flag specified, generate the 16 bit variant. */ 1125 notethat ("COMP3op: dregs = dregs +- dregs\n"); 1126 $$ = COMP3OP (&$1, &$3, &$5, $4.r0); 1127 } 1128 else 1129 { 1130 /* Saturation flag specified, generate the 32 bit variant. */ 1131 notethat ("dsp32alu: dregs = dregs +- dregs (amod1)\n"); 1132 $$ = DSP32ALU (4, 0, 0, &$1, &$3, &$5, $6.s0, $6.x0, $4.r0); 1133 } 1134 } 1135 else 1136 if (IS_PREG ($1) && IS_PREG ($3) && IS_PREG ($5) && $4.r0 == 0) 1137 { 1138 notethat ("COMP3op: pregs = pregs + pregs\n"); 1139 $$ = COMP3OP (&$1, &$3, &$5, 5); 1140 } 1141 else 1142 return yyerror ("Dregs expected"); 1143 } 1144 | REG ASSIGN min_max LPAREN REG COMMA REG RPAREN vmod 1145 { 1146 int op; 1147 1148 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 1149 { 1150 if ($9.r0) 1151 op = 6; 1152 else 1153 op = 7; 1154 1155 notethat ("dsp32alu: dregs = {MIN|MAX} (dregs, dregs)\n"); 1156 $$ = DSP32ALU (op, 0, 0, &$1, &$5, &$7, 0, 0, $3.r0); 1157 } 1158 else 1159 return yyerror ("Dregs expected"); 1160 } 1161 1162 | a_assign MINUS REG_A 1163 { 1164 notethat ("dsp32alu: Ax = - Ax\n"); 1165 $$ = DSP32ALU (14, IS_A1 ($1), 0, 0, ®7, ®7, 0, 0, IS_A1 ($3)); 1166 } 1167 | HALF_REG ASSIGN HALF_REG plus_minus HALF_REG amod1 1168 { 1169 notethat ("dsp32alu: dregs_lo = dregs_lo +- dregs_lo (amod1)\n"); 1170 $$ = DSP32ALU (2 | $4.r0, IS_H ($1), 0, &$1, &$3, &$5, 1171 $6.s0, $6.x0, HL2 ($3, $5)); 1172 } 1173 | a_assign a_assign expr 1174 { 1175 if (EXPR_VALUE ($3) == 0 && !REG_SAME ($1, $2)) 1176 { 1177 notethat ("dsp32alu: A1 = A0 = 0\n"); 1178 $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 0, 0, 2); 1179 } 1180 else 1181 return yyerror ("Bad value, 0 expected"); 1182 } 1183 1184 /* Saturating. */ 1185 | a_assign REG_A LPAREN S RPAREN 1186 { 1187 if (REG_SAME ($1, $2)) 1188 { 1189 notethat ("dsp32alu: Ax = Ax (S)\n"); 1190 $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 1, 0, IS_A1 ($1)); 1191 } 1192 else 1193 return yyerror ("Registers must be equal"); 1194 } 1195 1196 | HALF_REG ASSIGN REG LPAREN RND RPAREN 1197 { 1198 if (IS_DREG ($3)) 1199 { 1200 notethat ("dsp32alu: dregs_half = dregs (RND)\n"); 1201 $$ = DSP32ALU (12, IS_H ($1), 0, &$1, &$3, 0, 0, 0, 3); 1202 } 1203 else 1204 return yyerror ("Dregs expected"); 1205 } 1206 1207 | HALF_REG ASSIGN REG plus_minus REG LPAREN RND12 RPAREN 1208 { 1209 if (IS_DREG ($3) && IS_DREG ($5)) 1210 { 1211 notethat ("dsp32alu: dregs_half = dregs (+-) dregs (RND12)\n"); 1212 $$ = DSP32ALU (5, IS_H ($1), 0, &$1, &$3, &$5, 0, 0, $4.r0); 1213 } 1214 else 1215 return yyerror ("Dregs expected"); 1216 } 1217 1218 | HALF_REG ASSIGN REG plus_minus REG LPAREN RND20 RPAREN 1219 { 1220 if (IS_DREG ($3) && IS_DREG ($5)) 1221 { 1222 notethat ("dsp32alu: dregs_half = dregs -+ dregs (RND20)\n"); 1223 $$ = DSP32ALU (5, IS_H ($1), 0, &$1, &$3, &$5, 0, 1, $4.r0 | 2); 1224 } 1225 else 1226 return yyerror ("Dregs expected"); 1227 } 1228 1229 | a_assign REG_A 1230 { 1231 if (!REG_SAME ($1, $2)) 1232 { 1233 notethat ("dsp32alu: An = Am\n"); 1234 $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, IS_A1 ($1), 0, 3); 1235 } 1236 else 1237 return yyerror ("Accu reg arguments must differ"); 1238 } 1239 1240 | a_assign REG 1241 { 1242 if (IS_DREG ($2)) 1243 { 1244 notethat ("dsp32alu: An = dregs\n"); 1245 $$ = DSP32ALU (9, 0, 0, 0, &$2, 0, 1, 0, IS_A1 ($1) << 1); 1246 } 1247 else 1248 return yyerror ("Dregs expected"); 1249 } 1250 1251 | REG ASSIGN HALF_REG xpmod 1252 { 1253 if (!IS_H ($3)) 1254 { 1255 if ($1.regno == REG_A0x && IS_DREG ($3)) 1256 { 1257 notethat ("dsp32alu: A0.x = dregs_lo\n"); 1258 $$ = DSP32ALU (9, 0, 0, 0, &$3, 0, 0, 0, 1); 1259 } 1260 else if ($1.regno == REG_A1x && IS_DREG ($3)) 1261 { 1262 notethat ("dsp32alu: A1.x = dregs_lo\n"); 1263 $$ = DSP32ALU (9, 0, 0, 0, &$3, 0, 0, 0, 3); 1264 } 1265 else if (IS_DREG ($1) && IS_DREG ($3)) 1266 { 1267 notethat ("ALU2op: dregs = dregs_lo\n"); 1268 $$ = ALU2OP (&$1, &$3, 10 | ($4.r0 ? 0: 1)); 1269 } 1270 else 1271 return yyerror ("Register mismatch"); 1272 } 1273 else 1274 return yyerror ("Low reg expected"); 1275 } 1276 1277 | HALF_REG ASSIGN expr 1278 { 1279 notethat ("LDIMMhalf: pregs_half = imm16\n"); 1280 1281 if (!IS_DREG ($1) && !IS_PREG ($1) && !IS_IREG ($1) 1282 && !IS_MREG ($1) && !IS_BREG ($1) && !IS_LREG ($1)) 1283 return yyerror ("Wrong register for load immediate"); 1284 1285 if (!IS_IMM ($3, 16) && !IS_UIMM ($3, 16)) 1286 return yyerror ("Constant out of range"); 1287 1288 $$ = LDIMMHALF_R (&$1, IS_H ($1), 0, 0, $3); 1289 } 1290 1291 | a_assign expr 1292 { 1293 notethat ("dsp32alu: An = 0\n"); 1294 1295 if (imm7 ($2) != 0) 1296 return yyerror ("0 expected"); 1297 1298 $$ = DSP32ALU (8, 0, 0, 0, 0, 0, 0, 0, IS_A1 ($1)); 1299 } 1300 1301 | REG ASSIGN expr xpmod1 1302 { 1303 if (!IS_DREG ($1) && !IS_PREG ($1) && !IS_IREG ($1) 1304 && !IS_MREG ($1) && !IS_BREG ($1) && !IS_LREG ($1)) 1305 return yyerror ("Wrong register for load immediate"); 1306 1307 if ($4.r0 == 0) 1308 { 1309 /* 7 bit immediate value if possible. 1310 We will check for that constant value for efficiency 1311 If it goes to reloc, it will be 16 bit. */ 1312 if (IS_CONST ($3) && IS_IMM ($3, 7) && IS_DREG ($1)) 1313 { 1314 notethat ("COMPI2opD: dregs = imm7 (x) \n"); 1315 $$ = COMPI2OPD (&$1, imm7 ($3), 0); 1316 } 1317 else if (IS_CONST ($3) && IS_IMM ($3, 7) && IS_PREG ($1)) 1318 { 1319 notethat ("COMPI2opP: pregs = imm7 (x)\n"); 1320 $$ = COMPI2OPP (&$1, imm7 ($3), 0); 1321 } 1322 else 1323 { 1324 if (IS_CONST ($3) && !IS_IMM ($3, 16)) 1325 return yyerror ("Immediate value out of range"); 1326 1327 notethat ("LDIMMhalf: regs = luimm16 (x)\n"); 1328 /* reg, H, S, Z. */ 1329 $$ = LDIMMHALF_R5 (&$1, 0, 1, 0, $3); 1330 } 1331 } 1332 else 1333 { 1334 /* (z) There is no 7 bit zero extended instruction. 1335 If the expr is a relocation, generate it. */ 1336 1337 if (IS_CONST ($3) && !IS_UIMM ($3, 16)) 1338 return yyerror ("Immediate value out of range"); 1339 1340 notethat ("LDIMMhalf: regs = luimm16 (x)\n"); 1341 /* reg, H, S, Z. */ 1342 $$ = LDIMMHALF_R5 (&$1, 0, 0, 1, $3); 1343 } 1344 } 1345 1346 | HALF_REG ASSIGN REG 1347 { 1348 if (IS_H ($1)) 1349 return yyerror ("Low reg expected"); 1350 1351 if (IS_DREG ($1) && $3.regno == REG_A0x) 1352 { 1353 notethat ("dsp32alu: dregs_lo = A0.x\n"); 1354 $$ = DSP32ALU (10, 0, 0, &$1, ®7, ®7, 0, 0, 0); 1355 } 1356 else if (IS_DREG ($1) && $3.regno == REG_A1x) 1357 { 1358 notethat ("dsp32alu: dregs_lo = A1.x\n"); 1359 $$ = DSP32ALU (10, 0, 0, &$1, ®7, ®7, 0, 0, 1); 1360 } 1361 else 1362 return yyerror ("Register mismatch"); 1363 } 1364 1365 | REG ASSIGN REG op_bar_op REG amod0 1366 { 1367 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)) 1368 { 1369 notethat ("dsp32alu: dregs = dregs .|. dregs (amod0)\n"); 1370 $$ = DSP32ALU (0, 0, 0, &$1, &$3, &$5, $6.s0, $6.x0, $4.r0); 1371 } 1372 else 1373 return yyerror ("Register mismatch"); 1374 } 1375 1376 | REG ASSIGN BYTE_DREG xpmod 1377 { 1378 if (IS_DREG ($1) && IS_DREG ($3)) 1379 { 1380 notethat ("ALU2op: dregs = dregs_byte\n"); 1381 $$ = ALU2OP (&$1, &$3, 12 | ($4.r0 ? 0: 1)); 1382 } 1383 else 1384 return yyerror ("Register mismatch"); 1385 } 1386 1387 | a_assign ABS REG_A COMMA a_assign ABS REG_A 1388 { 1389 if (REG_SAME ($1, $3) && REG_SAME ($5, $7) && !REG_SAME ($1, $5)) 1390 { 1391 notethat ("dsp32alu: A1 = ABS A1 , A0 = ABS A0\n"); 1392 $$ = DSP32ALU (16, 0, 0, 0, ®7, ®7, 0, 0, 3); 1393 } 1394 else 1395 return yyerror ("Register mismatch"); 1396 } 1397 1398 | a_assign MINUS REG_A COMMA a_assign MINUS REG_A 1399 { 1400 if (REG_SAME ($1, $3) && REG_SAME ($5, $7) && !REG_SAME ($1, $5)) 1401 { 1402 notethat ("dsp32alu: A1 = - A1 , A0 = - A0\n"); 1403 $$ = DSP32ALU (14, 0, 0, 0, ®7, ®7, 0, 0, 3); 1404 } 1405 else 1406 return yyerror ("Register mismatch"); 1407 } 1408 1409 | a_minusassign REG_A w32_or_nothing 1410 { 1411 if (!IS_A1 ($1) && IS_A1 ($2)) 1412 { 1413 notethat ("dsp32alu: A0 -= A1\n"); 1414 $$ = DSP32ALU (11, 0, 0, 0, ®7, ®7, $3.r0, 0, 3); 1415 } 1416 else 1417 return yyerror ("Register mismatch"); 1418 } 1419 1420 | REG _MINUS_ASSIGN expr 1421 { 1422 if (IS_IREG ($1) && EXPR_VALUE ($3) == 4) 1423 { 1424 notethat ("dagMODik: iregs -= 4\n"); 1425 $$ = DAGMODIK (&$1, 3); 1426 } 1427 else if (IS_IREG ($1) && EXPR_VALUE ($3) == 2) 1428 { 1429 notethat ("dagMODik: iregs -= 2\n"); 1430 $$ = DAGMODIK (&$1, 1); 1431 } 1432 else 1433 return yyerror ("Register or value mismatch"); 1434 } 1435 1436 | REG _PLUS_ASSIGN REG LPAREN BREV RPAREN 1437 { 1438 if (IS_IREG ($1) && IS_MREG ($3)) 1439 { 1440 notethat ("dagMODim: iregs += mregs (opt_brev)\n"); 1441 /* i, m, op, br. */ 1442 $$ = DAGMODIM (&$1, &$3, 0, 1); 1443 } 1444 else if (IS_PREG ($1) && IS_PREG ($3)) 1445 { 1446 notethat ("PTR2op: pregs += pregs (BREV )\n"); 1447 $$ = PTR2OP (&$1, &$3, 5); 1448 } 1449 else 1450 return yyerror ("Register mismatch"); 1451 } 1452 1453 | REG _MINUS_ASSIGN REG 1454 { 1455 if (IS_IREG ($1) && IS_MREG ($3)) 1456 { 1457 notethat ("dagMODim: iregs -= mregs\n"); 1458 $$ = DAGMODIM (&$1, &$3, 1, 0); 1459 } 1460 else if (IS_PREG ($1) && IS_PREG ($3)) 1461 { 1462 notethat ("PTR2op: pregs -= pregs\n"); 1463 $$ = PTR2OP (&$1, &$3, 0); 1464 } 1465 else 1466 return yyerror ("Register mismatch"); 1467 } 1468 1469 | REG_A _PLUS_ASSIGN REG_A w32_or_nothing 1470 { 1471 if (!IS_A1 ($1) && IS_A1 ($3)) 1472 { 1473 notethat ("dsp32alu: A0 += A1 (W32)\n"); 1474 $$ = DSP32ALU (11, 0, 0, 0, ®7, ®7, $4.r0, 0, 2); 1475 } 1476 else 1477 return yyerror ("Register mismatch"); 1478 } 1479 1480 | REG _PLUS_ASSIGN REG 1481 { 1482 if (IS_IREG ($1) && IS_MREG ($3)) 1483 { 1484 notethat ("dagMODim: iregs += mregs\n"); 1485 $$ = DAGMODIM (&$1, &$3, 0, 0); 1486 } 1487 else 1488 return yyerror ("iregs += mregs expected"); 1489 } 1490 1491 | REG _PLUS_ASSIGN expr 1492 { 1493 if (IS_IREG ($1)) 1494 { 1495 if (EXPR_VALUE ($3) == 4) 1496 { 1497 notethat ("dagMODik: iregs += 4\n"); 1498 $$ = DAGMODIK (&$1, 2); 1499 } 1500 else if (EXPR_VALUE ($3) == 2) 1501 { 1502 notethat ("dagMODik: iregs += 2\n"); 1503 $$ = DAGMODIK (&$1, 0); 1504 } 1505 else 1506 return yyerror ("iregs += [ 2 | 4 "); 1507 } 1508 else if (IS_PREG ($1) && IS_IMM ($3, 7)) 1509 { 1510 notethat ("COMPI2opP: pregs += imm7\n"); 1511 $$ = COMPI2OPP (&$1, imm7 ($3), 1); 1512 } 1513 else if (IS_DREG ($1) && IS_IMM ($3, 7)) 1514 { 1515 notethat ("COMPI2opD: dregs += imm7\n"); 1516 $$ = COMPI2OPD (&$1, imm7 ($3), 1); 1517 } 1518 else if ((IS_DREG ($1) || IS_PREG ($1)) && IS_CONST ($3)) 1519 return yyerror ("Immediate value out of range"); 1520 else 1521 return yyerror ("Register mismatch"); 1522 } 1523 1524 | REG _STAR_ASSIGN REG 1525 { 1526 if (IS_DREG ($1) && IS_DREG ($3)) 1527 { 1528 notethat ("ALU2op: dregs *= dregs\n"); 1529 $$ = ALU2OP (&$1, &$3, 3); 1530 } 1531 else 1532 return yyerror ("Register mismatch"); 1533 } 1534 1535 | SAA LPAREN REG COLON expr COMMA REG COLON expr RPAREN aligndir 1536 { 1537 if (!valid_dreg_pair (&$3, $5)) 1538 return yyerror ("Bad dreg pair"); 1539 else if (!valid_dreg_pair (&$7, $9)) 1540 return yyerror ("Bad dreg pair"); 1541 else 1542 { 1543 notethat ("dsp32alu: SAA (dregs_pair , dregs_pair ) (aligndir)\n"); 1544 $$ = DSP32ALU (18, 0, 0, 0, &$3, &$7, $11.r0, 0, 0); 1545 } 1546 } 1547 1548 | a_assign REG_A LPAREN S RPAREN COMMA a_assign REG_A LPAREN S RPAREN 1549 { 1550 if (REG_SAME ($1, $2) && REG_SAME ($7, $8) && !REG_SAME ($1, $7)) 1551 { 1552 notethat ("dsp32alu: A1 = A1 (S) , A0 = A0 (S)\n"); 1553 $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 1, 0, 2); 1554 } 1555 else 1556 return yyerror ("Register mismatch"); 1557 } 1558 1559 | REG ASSIGN LPAREN REG PLUS REG RPAREN LESS_LESS expr 1560 { 1561 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG ($6) 1562 && REG_SAME ($1, $4)) 1563 { 1564 if (EXPR_VALUE ($9) == 1) 1565 { 1566 notethat ("ALU2op: dregs = (dregs + dregs) << 1\n"); 1567 $$ = ALU2OP (&$1, &$6, 4); 1568 } 1569 else if (EXPR_VALUE ($9) == 2) 1570 { 1571 notethat ("ALU2op: dregs = (dregs + dregs) << 2\n"); 1572 $$ = ALU2OP (&$1, &$6, 5); 1573 } 1574 else 1575 return yyerror ("Bad shift value"); 1576 } 1577 else if (IS_PREG ($1) && IS_PREG ($4) && IS_PREG ($6) 1578 && REG_SAME ($1, $4)) 1579 { 1580 if (EXPR_VALUE ($9) == 1) 1581 { 1582 notethat ("PTR2op: pregs = (pregs + pregs) << 1\n"); 1583 $$ = PTR2OP (&$1, &$6, 6); 1584 } 1585 else if (EXPR_VALUE ($9) == 2) 1586 { 1587 notethat ("PTR2op: pregs = (pregs + pregs) << 2\n"); 1588 $$ = PTR2OP (&$1, &$6, 7); 1589 } 1590 else 1591 return yyerror ("Bad shift value"); 1592 } 1593 else 1594 return yyerror ("Register mismatch"); 1595 } 1596 1597 /* COMP3 CCFLAG. */ 1598 | REG ASSIGN REG BAR REG 1599 { 1600 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)) 1601 { 1602 notethat ("COMP3op: dregs = dregs | dregs\n"); 1603 $$ = COMP3OP (&$1, &$3, &$5, 3); 1604 } 1605 else 1606 return yyerror ("Dregs expected"); 1607 } 1608 | REG ASSIGN REG CARET REG 1609 { 1610 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)) 1611 { 1612 notethat ("COMP3op: dregs = dregs ^ dregs\n"); 1613 $$ = COMP3OP (&$1, &$3, &$5, 4); 1614 } 1615 else 1616 return yyerror ("Dregs expected"); 1617 } 1618 | REG ASSIGN REG PLUS LPAREN REG LESS_LESS expr RPAREN 1619 { 1620 if (IS_PREG ($1) && IS_PREG ($3) && IS_PREG ($6)) 1621 { 1622 if (EXPR_VALUE ($8) == 1) 1623 { 1624 notethat ("COMP3op: pregs = pregs + (pregs << 1)\n"); 1625 $$ = COMP3OP (&$1, &$3, &$6, 6); 1626 } 1627 else if (EXPR_VALUE ($8) == 2) 1628 { 1629 notethat ("COMP3op: pregs = pregs + (pregs << 2)\n"); 1630 $$ = COMP3OP (&$1, &$3, &$6, 7); 1631 } 1632 else 1633 return yyerror ("Bad shift value"); 1634 } 1635 else 1636 return yyerror ("Dregs expected"); 1637 } 1638 | CCREG ASSIGN REG_A _ASSIGN_ASSIGN REG_A 1639 { 1640 if ($3.regno == REG_A0 && $5.regno == REG_A1) 1641 { 1642 notethat ("CCflag: CC = A0 == A1\n"); 1643 $$ = CCFLAG (0, 0, 5, 0, 0); 1644 } 1645 else 1646 return yyerror ("AREGs are in bad order or same"); 1647 } 1648 | CCREG ASSIGN REG_A LESS_THAN REG_A 1649 { 1650 if ($3.regno == REG_A0 && $5.regno == REG_A1) 1651 { 1652 notethat ("CCflag: CC = A0 < A1\n"); 1653 $$ = CCFLAG (0, 0, 6, 0, 0); 1654 } 1655 else 1656 return yyerror ("AREGs are in bad order or same"); 1657 } 1658 | CCREG ASSIGN REG LESS_THAN REG iu_or_nothing 1659 { 1660 if ((IS_DREG ($3) && IS_DREG ($5)) 1661 || (IS_PREG ($3) && IS_PREG ($5))) 1662 { 1663 notethat ("CCflag: CC = dpregs < dpregs\n"); 1664 $$ = CCFLAG (&$3, $5.regno & CODE_MASK, $6.r0, 0, IS_PREG ($3) ? 1 : 0); 1665 } 1666 else 1667 return yyerror ("Bad register in comparison"); 1668 } 1669 | CCREG ASSIGN REG LESS_THAN expr iu_or_nothing 1670 { 1671 if (!IS_DREG ($3) && !IS_PREG ($3)) 1672 return yyerror ("Bad register in comparison"); 1673 1674 if (($6.r0 == 1 && IS_IMM ($5, 3)) 1675 || ($6.r0 == 3 && IS_UIMM ($5, 3))) 1676 { 1677 notethat ("CCflag: CC = dpregs < (u)imm3\n"); 1678 $$ = CCFLAG (&$3, imm3 ($5), $6.r0, 1, IS_PREG ($3) ? 1 : 0); 1679 } 1680 else 1681 return yyerror ("Bad constant value"); 1682 } 1683 | CCREG ASSIGN REG _ASSIGN_ASSIGN REG 1684 { 1685 if ((IS_DREG ($3) && IS_DREG ($5)) 1686 || (IS_PREG ($3) && IS_PREG ($5))) 1687 { 1688 notethat ("CCflag: CC = dpregs == dpregs\n"); 1689 $$ = CCFLAG (&$3, $5.regno & CODE_MASK, 0, 0, IS_PREG ($3) ? 1 : 0); 1690 } 1691 else 1692 return yyerror ("Bad register in comparison"); 1693 } 1694 | CCREG ASSIGN REG _ASSIGN_ASSIGN expr 1695 { 1696 if (!IS_DREG ($3) && !IS_PREG ($3)) 1697 return yyerror ("Bad register in comparison"); 1698 1699 if (IS_IMM ($5, 3)) 1700 { 1701 notethat ("CCflag: CC = dpregs == imm3\n"); 1702 $$ = CCFLAG (&$3, imm3 ($5), 0, 1, IS_PREG ($3) ? 1 : 0); 1703 } 1704 else 1705 return yyerror ("Bad constant range"); 1706 } 1707 | CCREG ASSIGN REG_A _LESS_THAN_ASSIGN REG_A 1708 { 1709 if ($3.regno == REG_A0 && $5.regno == REG_A1) 1710 { 1711 notethat ("CCflag: CC = A0 <= A1\n"); 1712 $$ = CCFLAG (0, 0, 7, 0, 0); 1713 } 1714 else 1715 return yyerror ("AREGs are in bad order or same"); 1716 } 1717 | CCREG ASSIGN REG _LESS_THAN_ASSIGN REG iu_or_nothing 1718 { 1719 if ((IS_DREG ($3) && IS_DREG ($5)) 1720 || (IS_PREG ($3) && IS_PREG ($5))) 1721 { 1722 notethat ("CCflag: CC = dpregs <= dpregs (..)\n"); 1723 $$ = CCFLAG (&$3, $5.regno & CODE_MASK, 1724 1 + $6.r0, 0, IS_PREG ($3) ? 1 : 0); 1725 } 1726 else 1727 return yyerror ("Bad register in comparison"); 1728 } 1729 | CCREG ASSIGN REG _LESS_THAN_ASSIGN expr iu_or_nothing 1730 { 1731 if (!IS_DREG ($3) && !IS_PREG ($3)) 1732 return yyerror ("Bad register in comparison"); 1733 1734 if (($6.r0 == 1 && IS_IMM ($5, 3)) 1735 || ($6.r0 == 3 && IS_UIMM ($5, 3))) 1736 { 1737 notethat ("CCflag: CC = dpregs <= (u)imm3\n"); 1738 $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, IS_PREG ($3) ? 1 : 0); 1739 } 1740 else 1741 return yyerror ("Bad constant value"); 1742 } 1743 1744 | REG ASSIGN REG AMPERSAND REG 1745 { 1746 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)) 1747 { 1748 notethat ("COMP3op: dregs = dregs & dregs\n"); 1749 $$ = COMP3OP (&$1, &$3, &$5, 2); 1750 } 1751 else 1752 return yyerror ("Dregs expected"); 1753 } 1754 1755 | ccstat 1756 { 1757 notethat ("CC2stat operation\n"); 1758 $$ = bfin_gen_cc2stat ($1.r0, $1.x0, $1.s0); 1759 } 1760 1761 | REG ASSIGN REG 1762 { 1763 if ((IS_GENREG ($1) && IS_GENREG ($3)) 1764 || (IS_GENREG ($1) && IS_DAGREG ($3)) 1765 || (IS_DAGREG ($1) && IS_GENREG ($3)) 1766 || (IS_DAGREG ($1) && IS_DAGREG ($3)) 1767 || (IS_GENREG ($1) && $3.regno == REG_USP) 1768 || ($1.regno == REG_USP && IS_GENREG ($3)) 1769 || ($1.regno == REG_USP && $3.regno == REG_USP) 1770 || (IS_DREG ($1) && IS_SYSREG ($3)) 1771 || (IS_PREG ($1) && IS_SYSREG ($3)) 1772 || (IS_SYSREG ($1) && IS_GENREG ($3)) 1773 || (IS_ALLREG ($1) && IS_EMUDAT ($3)) 1774 || (IS_EMUDAT ($1) && IS_ALLREG ($3)) 1775 || (IS_SYSREG ($1) && $3.regno == REG_USP)) 1776 { 1777 $$ = bfin_gen_regmv (&$3, &$1); 1778 } 1779 else 1780 return yyerror ("Unsupported register move"); 1781 } 1782 1783 | CCREG ASSIGN REG 1784 { 1785 if (IS_DREG ($3)) 1786 { 1787 notethat ("CC2dreg: CC = dregs\n"); 1788 $$ = bfin_gen_cc2dreg (1, &$3); 1789 } 1790 else 1791 return yyerror ("Only 'CC = Dreg' supported"); 1792 } 1793 1794 | REG ASSIGN CCREG 1795 { 1796 if (IS_DREG ($1)) 1797 { 1798 notethat ("CC2dreg: dregs = CC\n"); 1799 $$ = bfin_gen_cc2dreg (0, &$1); 1800 } 1801 else 1802 return yyerror ("Only 'Dreg = CC' supported"); 1803 } 1804 1805 | CCREG _ASSIGN_BANG CCREG 1806 { 1807 notethat ("CC2dreg: CC =! CC\n"); 1808 $$ = bfin_gen_cc2dreg (3, 0); 1809 } 1810 1811 /* DSPMULT. */ 1812 1813 | HALF_REG ASSIGN multiply_halfregs opt_mode 1814 { 1815 notethat ("dsp32mult: dregs_half = multiply_halfregs (opt_mode)\n"); 1816 1817 if (!IS_H ($1) && $4.MM) 1818 return yyerror ("(M) not allowed with MAC0"); 1819 1820 if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS 1821 && $4.mod != M_IU && $4.mod != M_T && $4.mod != M_TFU 1822 && $4.mod != M_S2RND && $4.mod != M_ISS2 && $4.mod != M_IH) 1823 return yyerror ("bad option."); 1824 1825 if (IS_H ($1)) 1826 { 1827 $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 0, 1828 IS_H ($3.s0), IS_H ($3.s1), 0, 0, 1829 &$1, 0, &$3.s0, &$3.s1, 0); 1830 } 1831 else 1832 { 1833 $$ = DSP32MULT (0, 0, $4.mod, 0, 0, 1834 0, 0, IS_H ($3.s0), IS_H ($3.s1), 1835 &$1, 0, &$3.s0, &$3.s1, 1); 1836 } 1837 } 1838 1839 | REG ASSIGN multiply_halfregs opt_mode 1840 { 1841 /* Odd registers can use (M). */ 1842 if (!IS_DREG ($1)) 1843 return yyerror ("Dreg expected"); 1844 1845 if (IS_EVEN ($1) && $4.MM) 1846 return yyerror ("(M) not allowed with MAC0"); 1847 1848 if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS 1849 && $4.mod != M_S2RND && $4.mod != M_ISS2) 1850 return yyerror ("bad option"); 1851 1852 if (!IS_EVEN ($1)) 1853 { 1854 notethat ("dsp32mult: dregs = multiply_halfregs (opt_mode)\n"); 1855 1856 $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 1, 1857 IS_H ($3.s0), IS_H ($3.s1), 0, 0, 1858 &$1, 0, &$3.s0, &$3.s1, 0); 1859 } 1860 else 1861 { 1862 notethat ("dsp32mult: dregs = multiply_halfregs opt_mode\n"); 1863 $$ = DSP32MULT (0, 0, $4.mod, 0, 1, 1864 0, 0, IS_H ($3.s0), IS_H ($3.s1), 1865 &$1, 0, &$3.s0, &$3.s1, 1); 1866 } 1867 } 1868 1869 | HALF_REG ASSIGN multiply_halfregs opt_mode COMMA 1870 HALF_REG ASSIGN multiply_halfregs opt_mode 1871 { 1872 if (!IS_DREG ($1) || !IS_DREG ($6)) 1873 return yyerror ("Dregs expected"); 1874 1875 if (!IS_HCOMPL($1, $6)) 1876 return yyerror ("Dest registers mismatch"); 1877 1878 if (check_multiply_halfregs (&$3, &$8) < 0) 1879 return -1; 1880 1881 if ((!IS_H ($1) && $4.MM) 1882 || (!IS_H ($6) && $9.MM)) 1883 return yyerror ("(M) not allowed with MAC0"); 1884 1885 notethat ("dsp32mult: dregs_hi = multiply_halfregs mxd_mod, " 1886 "dregs_lo = multiply_halfregs opt_mode\n"); 1887 1888 if (IS_H ($1)) 1889 $$ = DSP32MULT (0, $4.MM, $9.mod, 1, 0, 1890 IS_H ($3.s0), IS_H ($3.s1), IS_H ($8.s0), IS_H ($8.s1), 1891 &$1, 0, &$3.s0, &$3.s1, 1); 1892 else 1893 $$ = DSP32MULT (0, $9.MM, $9.mod, 1, 0, 1894 IS_H ($8.s0), IS_H ($8.s1), IS_H ($3.s0), IS_H ($3.s1), 1895 &$1, 0, &$3.s0, &$3.s1, 1); 1896 } 1897 1898 | REG ASSIGN multiply_halfregs opt_mode COMMA REG ASSIGN multiply_halfregs opt_mode 1899 { 1900 if (!IS_DREG ($1) || !IS_DREG ($6)) 1901 return yyerror ("Dregs expected"); 1902 1903 if ((IS_EVEN ($1) && $6.regno - $1.regno != 1) 1904 || (IS_EVEN ($6) && $1.regno - $6.regno != 1)) 1905 return yyerror ("Dest registers mismatch"); 1906 1907 if (check_multiply_halfregs (&$3, &$8) < 0) 1908 return -1; 1909 1910 if ((IS_EVEN ($1) && $4.MM) 1911 || (IS_EVEN ($6) && $9.MM)) 1912 return yyerror ("(M) not allowed with MAC0"); 1913 1914 notethat ("dsp32mult: dregs = multiply_halfregs mxd_mod, " 1915 "dregs = multiply_halfregs opt_mode\n"); 1916 1917 if (IS_EVEN ($1)) 1918 $$ = DSP32MULT (0, $9.MM, $9.mod, 1, 1, 1919 IS_H ($8.s0), IS_H ($8.s1), IS_H ($3.s0), IS_H ($3.s1), 1920 &$1, 0, &$3.s0, &$3.s1, 1); 1921 else 1922 $$ = DSP32MULT (0, $4.MM, $9.mod, 1, 1, 1923 IS_H ($3.s0), IS_H ($3.s1), IS_H ($8.s0), IS_H ($8.s1), 1924 &$1, 0, &$3.s0, &$3.s1, 1); 1925 } 1926 1927 1928 /* SHIFTs. */ 1929 | a_assign ASHIFT REG_A BY HALF_REG 1930 { 1931 if (!REG_SAME ($1, $3)) 1932 return yyerror ("Aregs must be same"); 1933 1934 if (IS_DREG ($5) && !IS_H ($5)) 1935 { 1936 notethat ("dsp32shift: A0 = ASHIFT A0 BY dregs_lo\n"); 1937 $$ = DSP32SHIFT (3, 0, &$5, 0, 0, IS_A1 ($1)); 1938 } 1939 else 1940 return yyerror ("Dregs expected"); 1941 } 1942 1943 | HALF_REG ASSIGN ASHIFT HALF_REG BY HALF_REG smod 1944 { 1945 if (IS_DREG ($6) && !IS_H ($6)) 1946 { 1947 notethat ("dsp32shift: dregs_half = ASHIFT dregs_half BY dregs_lo\n"); 1948 $$ = DSP32SHIFT (0, &$1, &$6, &$4, $7.s0, HL2 ($1, $4)); 1949 } 1950 else 1951 return yyerror ("Dregs expected"); 1952 } 1953 1954 | a_assign REG_A LESS_LESS expr 1955 { 1956 if (!REG_SAME ($1, $2)) 1957 return yyerror ("Aregs must be same"); 1958 1959 if (IS_UIMM ($4, 5)) 1960 { 1961 notethat ("dsp32shiftimm: A0 = A0 << uimm5\n"); 1962 $$ = DSP32SHIFTIMM (3, 0, imm5 ($4), 0, 0, IS_A1 ($1)); 1963 } 1964 else 1965 return yyerror ("Bad shift value"); 1966 } 1967 1968 | REG ASSIGN REG LESS_LESS expr vsmod 1969 { 1970 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5)) 1971 { 1972 if ($6.r0) 1973 { 1974 /* Vector? */ 1975 notethat ("dsp32shiftimm: dregs = dregs << expr (V, .)\n"); 1976 $$ = DSP32SHIFTIMM (1, &$1, imm4 ($5), &$3, $6.s0 ? 1 : 2, 0); 1977 } 1978 else 1979 { 1980 notethat ("dsp32shiftimm: dregs = dregs << uimm5 (.)\n"); 1981 $$ = DSP32SHIFTIMM (2, &$1, imm6 ($5), &$3, $6.s0 ? 1 : 2, 0); 1982 } 1983 } 1984 else if ($6.s0 == 0 && IS_PREG ($1) && IS_PREG ($3)) 1985 { 1986 if (EXPR_VALUE ($5) == 2) 1987 { 1988 notethat ("PTR2op: pregs = pregs << 2\n"); 1989 $$ = PTR2OP (&$1, &$3, 1); 1990 } 1991 else if (EXPR_VALUE ($5) == 1) 1992 { 1993 notethat ("COMP3op: pregs = pregs << 1\n"); 1994 $$ = COMP3OP (&$1, &$3, &$3, 5); 1995 } 1996 else 1997 return yyerror ("Bad shift value"); 1998 } 1999 else 2000 return yyerror ("Bad shift value or register"); 2001 } 2002 | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod 2003 { 2004 if (IS_UIMM ($5, 4)) 2005 { 2006 if ($6.s0) 2007 { 2008 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4 (S)\n"); 2009 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3)); 2010 } 2011 else 2012 { 2013 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n"); 2014 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3)); 2015 } 2016 } 2017 else 2018 return yyerror ("Bad shift value"); 2019 } 2020 | REG ASSIGN ASHIFT REG BY HALF_REG vsmod 2021 { 2022 int op; 2023 2024 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG ($6) && !IS_H ($6)) 2025 { 2026 if ($7.r0) 2027 { 2028 op = 1; 2029 notethat ("dsp32shift: dregs = ASHIFT dregs BY " 2030 "dregs_lo (V, .)\n"); 2031 } 2032 else 2033 { 2034 2035 op = 2; 2036 notethat ("dsp32shift: dregs = ASHIFT dregs BY dregs_lo (.)\n"); 2037 } 2038 $$ = DSP32SHIFT (op, &$1, &$6, &$4, $7.s0, 0); 2039 } 2040 else 2041 return yyerror ("Dregs expected"); 2042 } 2043 2044 /* EXPADJ. */ 2045 | HALF_REG ASSIGN EXPADJ LPAREN REG COMMA HALF_REG RPAREN vmod 2046 { 2047 if (IS_DREG_L ($1) && IS_DREG_L ($5) && IS_DREG_L ($7)) 2048 { 2049 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs , dregs_lo )\n"); 2050 $$ = DSP32SHIFT (7, &$1, &$7, &$5, $9.r0, 0); 2051 } 2052 else 2053 return yyerror ("Bad shift value or register"); 2054 } 2055 2056 2057 | HALF_REG ASSIGN EXPADJ LPAREN HALF_REG COMMA HALF_REG RPAREN 2058 { 2059 if (IS_DREG_L ($1) && IS_DREG_L ($5) && IS_DREG_L ($7)) 2060 { 2061 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs_lo, dregs_lo)\n"); 2062 $$ = DSP32SHIFT (7, &$1, &$7, &$5, 2, 0); 2063 } 2064 else if (IS_DREG_L ($1) && IS_DREG_H ($5) && IS_DREG_L ($7)) 2065 { 2066 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs_hi, dregs_lo)\n"); 2067 $$ = DSP32SHIFT (7, &$1, &$7, &$5, 3, 0); 2068 } 2069 else 2070 return yyerror ("Bad shift value or register"); 2071 } 2072 2073 /* DEPOSIT. */ 2074 2075 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN 2076 { 2077 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 2078 { 2079 notethat ("dsp32shift: dregs = DEPOSIT (dregs , dregs )\n"); 2080 $$ = DSP32SHIFT (10, &$1, &$7, &$5, 2, 0); 2081 } 2082 else 2083 return yyerror ("Register mismatch"); 2084 } 2085 2086 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN LPAREN X RPAREN 2087 { 2088 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 2089 { 2090 notethat ("dsp32shift: dregs = DEPOSIT (dregs , dregs ) (X)\n"); 2091 $$ = DSP32SHIFT (10, &$1, &$7, &$5, 3, 0); 2092 } 2093 else 2094 return yyerror ("Register mismatch"); 2095 } 2096 2097 | REG ASSIGN EXTRACT LPAREN REG COMMA HALF_REG RPAREN xpmod 2098 { 2099 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG_L ($7)) 2100 { 2101 notethat ("dsp32shift: dregs = EXTRACT (dregs, dregs_lo ) (.)\n"); 2102 $$ = DSP32SHIFT (10, &$1, &$7, &$5, $9.r0, 0); 2103 } 2104 else 2105 return yyerror ("Register mismatch"); 2106 } 2107 2108 | a_assign REG_A _GREATER_GREATER_GREATER expr 2109 { 2110 if (!REG_SAME ($1, $2)) 2111 return yyerror ("Aregs must be same"); 2112 2113 if (IS_UIMM ($4, 5)) 2114 { 2115 notethat ("dsp32shiftimm: Ax = Ax >>> uimm5\n"); 2116 $$ = DSP32SHIFTIMM (3, 0, -imm6 ($4), 0, 0, IS_A1 ($1)); 2117 } 2118 else 2119 return yyerror ("Shift value range error"); 2120 } 2121 | a_assign LSHIFT REG_A BY HALF_REG 2122 { 2123 if (REG_SAME ($1, $3) && IS_DREG_L ($5)) 2124 { 2125 notethat ("dsp32shift: Ax = LSHIFT Ax BY dregs_lo\n"); 2126 $$ = DSP32SHIFT (3, 0, &$5, 0, 1, IS_A1 ($1)); 2127 } 2128 else 2129 return yyerror ("Register mismatch"); 2130 } 2131 2132 | HALF_REG ASSIGN LSHIFT HALF_REG BY HALF_REG 2133 { 2134 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6)) 2135 { 2136 notethat ("dsp32shift: dregs_lo = LSHIFT dregs_hi BY dregs_lo\n"); 2137 $$ = DSP32SHIFT (0, &$1, &$6, &$4, 2, HL2 ($1, $4)); 2138 } 2139 else 2140 return yyerror ("Register mismatch"); 2141 } 2142 2143 | REG ASSIGN LSHIFT REG BY HALF_REG vmod 2144 { 2145 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6)) 2146 { 2147 notethat ("dsp32shift: dregs = LSHIFT dregs BY dregs_lo (V )\n"); 2148 $$ = DSP32SHIFT ($7.r0 ? 1: 2, &$1, &$6, &$4, 2, 0); 2149 } 2150 else 2151 return yyerror ("Register mismatch"); 2152 } 2153 2154 | REG ASSIGN SHIFT REG BY HALF_REG 2155 { 2156 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6)) 2157 { 2158 notethat ("dsp32shift: dregs = SHIFT dregs BY dregs_lo\n"); 2159 $$ = DSP32SHIFT (2, &$1, &$6, &$4, 2, 0); 2160 } 2161 else 2162 return yyerror ("Register mismatch"); 2163 } 2164 2165 | a_assign REG_A GREATER_GREATER expr 2166 { 2167 if (REG_SAME ($1, $2) && IS_IMM ($4, 6) >= 0) 2168 { 2169 notethat ("dsp32shiftimm: Ax = Ax >> imm6\n"); 2170 $$ = DSP32SHIFTIMM (3, 0, -imm6 ($4), 0, 1, IS_A1 ($1)); 2171 } 2172 else 2173 return yyerror ("Accu register expected"); 2174 } 2175 2176 | REG ASSIGN REG GREATER_GREATER expr vmod 2177 { 2178 if ($6.r0 == 1) 2179 { 2180 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5)) 2181 { 2182 notethat ("dsp32shiftimm: dregs = dregs >> uimm5 (V)\n"); 2183 $$ = DSP32SHIFTIMM (1, &$1, -uimm5 ($5), &$3, 2, 0); 2184 } 2185 else 2186 return yyerror ("Register mismatch"); 2187 } 2188 else 2189 { 2190 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5)) 2191 { 2192 notethat ("dsp32shiftimm: dregs = dregs >> uimm5\n"); 2193 $$ = DSP32SHIFTIMM (2, &$1, -imm6 ($5), &$3, 2, 0); 2194 } 2195 else if (IS_PREG ($1) && IS_PREG ($3) && EXPR_VALUE ($5) == 2) 2196 { 2197 notethat ("PTR2op: pregs = pregs >> 2\n"); 2198 $$ = PTR2OP (&$1, &$3, 3); 2199 } 2200 else if (IS_PREG ($1) && IS_PREG ($3) && EXPR_VALUE ($5) == 1) 2201 { 2202 notethat ("PTR2op: pregs = pregs >> 1\n"); 2203 $$ = PTR2OP (&$1, &$3, 4); 2204 } 2205 else 2206 return yyerror ("Register mismatch"); 2207 } 2208 } 2209 | HALF_REG ASSIGN HALF_REG GREATER_GREATER expr 2210 { 2211 if (IS_UIMM ($5, 5)) 2212 { 2213 notethat ("dsp32shiftimm: dregs_half = dregs_half >> uimm5\n"); 2214 $$ = DSP32SHIFTIMM (0, &$1, -uimm5 ($5), &$3, 2, HL2 ($1, $3)); 2215 } 2216 else 2217 return yyerror ("Register mismatch"); 2218 } 2219 | HALF_REG ASSIGN HALF_REG _GREATER_GREATER_GREATER expr smod 2220 { 2221 if (IS_UIMM ($5, 5)) 2222 { 2223 notethat ("dsp32shiftimm: dregs_half = dregs_half >>> uimm5\n"); 2224 $$ = DSP32SHIFTIMM (0, &$1, -uimm5 ($5), &$3, 2225 $6.s0, HL2 ($1, $3)); 2226 } 2227 else 2228 return yyerror ("Register or modifier mismatch"); 2229 } 2230 2231 2232 | REG ASSIGN REG _GREATER_GREATER_GREATER expr vsmod 2233 { 2234 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5)) 2235 { 2236 if ($6.r0) 2237 { 2238 /* Vector? */ 2239 notethat ("dsp32shiftimm: dregs = dregs >>> uimm5 (V, .)\n"); 2240 $$ = DSP32SHIFTIMM (1, &$1, -uimm5 ($5), &$3, $6.s0, 0); 2241 } 2242 else 2243 { 2244 notethat ("dsp32shiftimm: dregs = dregs >>> uimm5 (.)\n"); 2245 $$ = DSP32SHIFTIMM (2, &$1, -uimm5 ($5), &$3, $6.s0, 0); 2246 } 2247 } 2248 else 2249 return yyerror ("Register mismatch"); 2250 } 2251 2252 | HALF_REG ASSIGN ONES REG 2253 { 2254 if (IS_DREG_L ($1) && IS_DREG ($4)) 2255 { 2256 notethat ("dsp32shift: dregs_lo = ONES dregs\n"); 2257 $$ = DSP32SHIFT (6, &$1, 0, &$4, 3, 0); 2258 } 2259 else 2260 return yyerror ("Register mismatch"); 2261 } 2262 2263 | REG ASSIGN PACK LPAREN HALF_REG COMMA HALF_REG RPAREN 2264 { 2265 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 2266 { 2267 notethat ("dsp32shift: dregs = PACK (dregs_hi , dregs_hi )\n"); 2268 $$ = DSP32SHIFT (4, &$1, &$7, &$5, HL2 ($5, $7), 0); 2269 } 2270 else 2271 return yyerror ("Register mismatch"); 2272 } 2273 2274 | HALF_REG ASSIGN CCREG ASSIGN BXORSHIFT LPAREN REG_A COMMA REG RPAREN 2275 { 2276 if (IS_DREG ($1) 2277 && $7.regno == REG_A0 2278 && IS_DREG ($9) && !IS_H ($1) && !IS_A1 ($7)) 2279 { 2280 notethat ("dsp32shift: dregs_lo = CC = BXORSHIFT (A0 , dregs )\n"); 2281 $$ = DSP32SHIFT (11, &$1, &$9, 0, 0, 0); 2282 } 2283 else 2284 return yyerror ("Register mismatch"); 2285 } 2286 2287 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG RPAREN 2288 { 2289 if (IS_DREG ($1) 2290 && $7.regno == REG_A0 2291 && IS_DREG ($9) && !IS_H ($1) && !IS_A1 ($7)) 2292 { 2293 notethat ("dsp32shift: dregs_lo = CC = BXOR (A0 , dregs)\n"); 2294 $$ = DSP32SHIFT (11, &$1, &$9, 0, 1, 0); 2295 } 2296 else 2297 return yyerror ("Register mismatch"); 2298 } 2299 2300 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN 2301 { 2302 if (IS_DREG ($1) && !IS_H ($1) && !REG_SAME ($7, $9)) 2303 { 2304 notethat ("dsp32shift: dregs_lo = CC = BXOR (A0 , A1 , CC)\n"); 2305 $$ = DSP32SHIFT (12, &$1, 0, 0, 1, 0); 2306 } 2307 else 2308 return yyerror ("Register mismatch"); 2309 } 2310 2311 | a_assign ROT REG_A BY HALF_REG 2312 { 2313 if (REG_SAME ($1, $3) && IS_DREG_L ($5)) 2314 { 2315 notethat ("dsp32shift: Ax = ROT Ax BY dregs_lo\n"); 2316 $$ = DSP32SHIFT (3, 0, &$5, 0, 2, IS_A1 ($1)); 2317 } 2318 else 2319 return yyerror ("Register mismatch"); 2320 } 2321 2322 | REG ASSIGN ROT REG BY HALF_REG 2323 { 2324 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6)) 2325 { 2326 notethat ("dsp32shift: dregs = ROT dregs BY dregs_lo\n"); 2327 $$ = DSP32SHIFT (2, &$1, &$6, &$4, 3, 0); 2328 } 2329 else 2330 return yyerror ("Register mismatch"); 2331 } 2332 2333 | a_assign ROT REG_A BY expr 2334 { 2335 if (IS_IMM ($5, 6)) 2336 { 2337 notethat ("dsp32shiftimm: An = ROT An BY imm6\n"); 2338 $$ = DSP32SHIFTIMM (3, 0, imm6 ($5), 0, 2, IS_A1 ($1)); 2339 } 2340 else 2341 return yyerror ("Register mismatch"); 2342 } 2343 2344 | REG ASSIGN ROT REG BY expr 2345 { 2346 if (IS_DREG ($1) && IS_DREG ($4) && IS_IMM ($6, 6)) 2347 { 2348 $$ = DSP32SHIFTIMM (2, &$1, imm6 ($6), &$4, 3, IS_A1 ($1)); 2349 } 2350 else 2351 return yyerror ("Register mismatch"); 2352 } 2353 2354 | HALF_REG ASSIGN SIGNBITS REG_A 2355 { 2356 if (IS_DREG_L ($1)) 2357 { 2358 notethat ("dsp32shift: dregs_lo = SIGNBITS An\n"); 2359 $$ = DSP32SHIFT (6, &$1, 0, 0, IS_A1 ($4), 0); 2360 } 2361 else 2362 return yyerror ("Register mismatch"); 2363 } 2364 2365 | HALF_REG ASSIGN SIGNBITS REG 2366 { 2367 if (IS_DREG_L ($1) && IS_DREG ($4)) 2368 { 2369 notethat ("dsp32shift: dregs_lo = SIGNBITS dregs\n"); 2370 $$ = DSP32SHIFT (5, &$1, 0, &$4, 0, 0); 2371 } 2372 else 2373 return yyerror ("Register mismatch"); 2374 } 2375 2376 | HALF_REG ASSIGN SIGNBITS HALF_REG 2377 { 2378 if (IS_DREG_L ($1)) 2379 { 2380 notethat ("dsp32shift: dregs_lo = SIGNBITS dregs_lo\n"); 2381 $$ = DSP32SHIFT (5, &$1, 0, &$4, 1 + IS_H ($4), 0); 2382 } 2383 else 2384 return yyerror ("Register mismatch"); 2385 } 2386 2387 /* The ASR bit is just inverted here. */ 2388 | HALF_REG ASSIGN VIT_MAX LPAREN REG RPAREN asr_asl 2389 { 2390 if (IS_DREG_L ($1) && IS_DREG ($5)) 2391 { 2392 notethat ("dsp32shift: dregs_lo = VIT_MAX (dregs) (..)\n"); 2393 $$ = DSP32SHIFT (9, &$1, 0, &$5, ($7.r0 ? 0 : 1), 0); 2394 } 2395 else 2396 return yyerror ("Register mismatch"); 2397 } 2398 2399 | REG ASSIGN VIT_MAX LPAREN REG COMMA REG RPAREN asr_asl 2400 { 2401 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7)) 2402 { 2403 notethat ("dsp32shift: dregs = VIT_MAX (dregs, dregs) (ASR)\n"); 2404 $$ = DSP32SHIFT (9, &$1, &$7, &$5, 2 | ($9.r0 ? 0 : 1), 0); 2405 } 2406 else 2407 return yyerror ("Register mismatch"); 2408 } 2409 2410 | BITMUX LPAREN REG COMMA REG COMMA REG_A RPAREN asr_asl 2411 { 2412 if (REG_SAME ($3, $5)) 2413 return yyerror ("Illegal source register combination"); 2414 2415 if (IS_DREG ($3) && IS_DREG ($5) && !IS_A1 ($7)) 2416 { 2417 notethat ("dsp32shift: BITMUX (dregs , dregs , A0) (ASR)\n"); 2418 $$ = DSP32SHIFT (8, 0, &$3, &$5, $9.r0, 0); 2419 } 2420 else 2421 return yyerror ("Register mismatch"); 2422 } 2423 2424 | a_assign BXORSHIFT LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN 2425 { 2426 if (!IS_A1 ($1) && !IS_A1 ($4) && IS_A1 ($6)) 2427 { 2428 notethat ("dsp32shift: A0 = BXORSHIFT (A0 , A1 , CC )\n"); 2429 $$ = DSP32SHIFT (12, 0, 0, 0, 0, 0); 2430 } 2431 else 2432 return yyerror ("Dregs expected"); 2433 } 2434 2435 2436 /* LOGI2op: BITCLR (dregs, uimm5). */ 2437 | BITCLR LPAREN REG COMMA expr RPAREN 2438 { 2439 if (IS_DREG ($3) && IS_UIMM ($5, 5)) 2440 { 2441 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n"); 2442 $$ = LOGI2OP ($3, uimm5 ($5), 4); 2443 } 2444 else 2445 return yyerror ("Register mismatch"); 2446 } 2447 2448 /* LOGI2op: BITSET (dregs, uimm5). */ 2449 | BITSET LPAREN REG COMMA expr RPAREN 2450 { 2451 if (IS_DREG ($3) && IS_UIMM ($5, 5)) 2452 { 2453 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n"); 2454 $$ = LOGI2OP ($3, uimm5 ($5), 2); 2455 } 2456 else 2457 return yyerror ("Register mismatch"); 2458 } 2459 2460 /* LOGI2op: BITTGL (dregs, uimm5). */ 2461 | BITTGL LPAREN REG COMMA expr RPAREN 2462 { 2463 if (IS_DREG ($3) && IS_UIMM ($5, 5)) 2464 { 2465 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n"); 2466 $$ = LOGI2OP ($3, uimm5 ($5), 3); 2467 } 2468 else 2469 return yyerror ("Register mismatch"); 2470 } 2471 2472 | CCREG _ASSIGN_BANG BITTST LPAREN REG COMMA expr RPAREN 2473 { 2474 if (IS_DREG ($5) && IS_UIMM ($7, 5)) 2475 { 2476 notethat ("LOGI2op: CC =! BITTST (dregs , uimm5 )\n"); 2477 $$ = LOGI2OP ($5, uimm5 ($7), 0); 2478 } 2479 else 2480 return yyerror ("Register mismatch or value error"); 2481 } 2482 2483 | CCREG ASSIGN BITTST LPAREN REG COMMA expr RPAREN 2484 { 2485 if (IS_DREG ($5) && IS_UIMM ($7, 5)) 2486 { 2487 notethat ("LOGI2op: CC = BITTST (dregs , uimm5 )\n"); 2488 $$ = LOGI2OP ($5, uimm5 ($7), 1); 2489 } 2490 else 2491 return yyerror ("Register mismatch or value error"); 2492 } 2493 2494 | IF BANG CCREG REG ASSIGN REG 2495 { 2496 if ((IS_DREG ($4) || IS_PREG ($4)) 2497 && (IS_DREG ($6) || IS_PREG ($6))) 2498 { 2499 notethat ("ccMV: IF ! CC gregs = gregs\n"); 2500 $$ = CCMV (&$6, &$4, 0); 2501 } 2502 else 2503 return yyerror ("Register mismatch"); 2504 } 2505 2506 | IF CCREG REG ASSIGN REG 2507 { 2508 if ((IS_DREG ($5) || IS_PREG ($5)) 2509 && (IS_DREG ($3) || IS_PREG ($3))) 2510 { 2511 notethat ("ccMV: IF CC gregs = gregs\n"); 2512 $$ = CCMV (&$5, &$3, 1); 2513 } 2514 else 2515 return yyerror ("Register mismatch"); 2516 } 2517 2518 | IF BANG CCREG JUMP expr 2519 { 2520 if (IS_PCREL10 ($5)) 2521 { 2522 notethat ("BRCC: IF !CC JUMP pcrel11m2\n"); 2523 $$ = BRCC (0, 0, $5); 2524 } 2525 else 2526 return yyerror ("Bad jump offset"); 2527 } 2528 2529 | IF BANG CCREG JUMP expr LPAREN BP RPAREN 2530 { 2531 if (IS_PCREL10 ($5)) 2532 { 2533 notethat ("BRCC: IF !CC JUMP pcrel11m2\n"); 2534 $$ = BRCC (0, 1, $5); 2535 } 2536 else 2537 return yyerror ("Bad jump offset"); 2538 } 2539 2540 | IF CCREG JUMP expr 2541 { 2542 if (IS_PCREL10 ($4)) 2543 { 2544 notethat ("BRCC: IF CC JUMP pcrel11m2\n"); 2545 $$ = BRCC (1, 0, $4); 2546 } 2547 else 2548 return yyerror ("Bad jump offset"); 2549 } 2550 2551 | IF CCREG JUMP expr LPAREN BP RPAREN 2552 { 2553 if (IS_PCREL10 ($4)) 2554 { 2555 notethat ("BRCC: IF !CC JUMP pcrel11m2\n"); 2556 $$ = BRCC (1, 1, $4); 2557 } 2558 else 2559 return yyerror ("Bad jump offset"); 2560 } 2561 | NOP 2562 { 2563 notethat ("ProgCtrl: NOP\n"); 2564 $$ = PROGCTRL (0, 0); 2565 } 2566 2567 | RTS 2568 { 2569 notethat ("ProgCtrl: RTS\n"); 2570 $$ = PROGCTRL (1, 0); 2571 } 2572 2573 | RTI 2574 { 2575 notethat ("ProgCtrl: RTI\n"); 2576 $$ = PROGCTRL (1, 1); 2577 } 2578 2579 | RTX 2580 { 2581 notethat ("ProgCtrl: RTX\n"); 2582 $$ = PROGCTRL (1, 2); 2583 } 2584 2585 | RTN 2586 { 2587 notethat ("ProgCtrl: RTN\n"); 2588 $$ = PROGCTRL (1, 3); 2589 } 2590 2591 | RTE 2592 { 2593 notethat ("ProgCtrl: RTE\n"); 2594 $$ = PROGCTRL (1, 4); 2595 } 2596 2597 | IDLE 2598 { 2599 notethat ("ProgCtrl: IDLE\n"); 2600 $$ = PROGCTRL (2, 0); 2601 } 2602 2603 | CSYNC 2604 { 2605 notethat ("ProgCtrl: CSYNC\n"); 2606 $$ = PROGCTRL (2, 3); 2607 } 2608 2609 | SSYNC 2610 { 2611 notethat ("ProgCtrl: SSYNC\n"); 2612 $$ = PROGCTRL (2, 4); 2613 } 2614 2615 | EMUEXCPT 2616 { 2617 notethat ("ProgCtrl: EMUEXCPT\n"); 2618 $$ = PROGCTRL (2, 5); 2619 } 2620 2621 | CLI REG 2622 { 2623 if (IS_DREG ($2)) 2624 { 2625 notethat ("ProgCtrl: CLI dregs\n"); 2626 $$ = PROGCTRL (3, $2.regno & CODE_MASK); 2627 } 2628 else 2629 return yyerror ("Dreg expected for CLI"); 2630 } 2631 2632 | STI REG 2633 { 2634 if (IS_DREG ($2)) 2635 { 2636 notethat ("ProgCtrl: STI dregs\n"); 2637 $$ = PROGCTRL (4, $2.regno & CODE_MASK); 2638 } 2639 else 2640 return yyerror ("Dreg expected for STI"); 2641 } 2642 2643 | JUMP LPAREN REG RPAREN 2644 { 2645 if (IS_PREG ($3)) 2646 { 2647 notethat ("ProgCtrl: JUMP (pregs )\n"); 2648 $$ = PROGCTRL (5, $3.regno & CODE_MASK); 2649 } 2650 else 2651 return yyerror ("Bad register for indirect jump"); 2652 } 2653 2654 | CALL LPAREN REG RPAREN 2655 { 2656 if (IS_PREG ($3)) 2657 { 2658 notethat ("ProgCtrl: CALL (pregs )\n"); 2659 $$ = PROGCTRL (6, $3.regno & CODE_MASK); 2660 } 2661 else 2662 return yyerror ("Bad register for indirect call"); 2663 } 2664 2665 | CALL LPAREN PC PLUS REG RPAREN 2666 { 2667 if (IS_PREG ($5)) 2668 { 2669 notethat ("ProgCtrl: CALL (PC + pregs )\n"); 2670 $$ = PROGCTRL (7, $5.regno & CODE_MASK); 2671 } 2672 else 2673 return yyerror ("Bad register for indirect call"); 2674 } 2675 2676 | JUMP LPAREN PC PLUS REG RPAREN 2677 { 2678 if (IS_PREG ($5)) 2679 { 2680 notethat ("ProgCtrl: JUMP (PC + pregs )\n"); 2681 $$ = PROGCTRL (8, $5.regno & CODE_MASK); 2682 } 2683 else 2684 return yyerror ("Bad register for indirect jump"); 2685 } 2686 2687 | RAISE expr 2688 { 2689 if (IS_UIMM ($2, 4)) 2690 { 2691 notethat ("ProgCtrl: RAISE uimm4\n"); 2692 $$ = PROGCTRL (9, uimm4 ($2)); 2693 } 2694 else 2695 return yyerror ("Bad value for RAISE"); 2696 } 2697 2698 | EXCPT expr 2699 { 2700 notethat ("ProgCtrl: EMUEXCPT\n"); 2701 $$ = PROGCTRL (10, uimm4 ($2)); 2702 } 2703 2704 | TESTSET LPAREN REG RPAREN 2705 { 2706 if (IS_PREG ($3)) 2707 { 2708 if ($3.regno == REG_SP || $3.regno == REG_FP) 2709 return yyerror ("Bad register for TESTSET"); 2710 2711 notethat ("ProgCtrl: TESTSET (pregs )\n"); 2712 $$ = PROGCTRL (11, $3.regno & CODE_MASK); 2713 } 2714 else 2715 return yyerror ("Preg expected"); 2716 } 2717 2718 | JUMP expr 2719 { 2720 if (IS_PCREL12 ($2)) 2721 { 2722 notethat ("UJUMP: JUMP pcrel12\n"); 2723 $$ = UJUMP ($2); 2724 } 2725 else 2726 return yyerror ("Bad value for relative jump"); 2727 } 2728 2729 | JUMP_DOT_S expr 2730 { 2731 if (IS_PCREL12 ($2)) 2732 { 2733 notethat ("UJUMP: JUMP_DOT_S pcrel12\n"); 2734 $$ = UJUMP($2); 2735 } 2736 else 2737 return yyerror ("Bad value for relative jump"); 2738 } 2739 2740 | JUMP_DOT_L expr 2741 { 2742 if (IS_PCREL24 ($2)) 2743 { 2744 notethat ("CALLa: jump.l pcrel24\n"); 2745 $$ = CALLA ($2, 0); 2746 } 2747 else 2748 return yyerror ("Bad value for long jump"); 2749 } 2750 2751 | JUMP_DOT_L pltpc 2752 { 2753 if (IS_PCREL24 ($2)) 2754 { 2755 notethat ("CALLa: jump.l pcrel24\n"); 2756 $$ = CALLA ($2, 2); 2757 } 2758 else 2759 return yyerror ("Bad value for long jump"); 2760 } 2761 2762 | CALL expr 2763 { 2764 if (IS_PCREL24 ($2)) 2765 { 2766 notethat ("CALLa: CALL pcrel25m2\n"); 2767 $$ = CALLA ($2, 1); 2768 } 2769 else 2770 return yyerror ("Bad call address"); 2771 } 2772 | CALL pltpc 2773 { 2774 if (IS_PCREL24 ($2)) 2775 { 2776 notethat ("CALLa: CALL pcrel25m2\n"); 2777 $$ = CALLA ($2, 2); 2778 } 2779 else 2780 return yyerror ("Bad call address"); 2781 } 2782 2783 /* ALU2ops. */ 2784 /* ALU2op: DIVQ (dregs, dregs). */ 2785 | DIVQ LPAREN REG COMMA REG RPAREN 2786 { 2787 if (IS_DREG ($3) && IS_DREG ($5)) 2788 $$ = ALU2OP (&$3, &$5, 8); 2789 else 2790 return yyerror ("Bad registers for DIVQ"); 2791 } 2792 2793 | DIVS LPAREN REG COMMA REG RPAREN 2794 { 2795 if (IS_DREG ($3) && IS_DREG ($5)) 2796 $$ = ALU2OP (&$3, &$5, 9); 2797 else 2798 return yyerror ("Bad registers for DIVS"); 2799 } 2800 2801 | REG ASSIGN MINUS REG vsmod 2802 { 2803 if (IS_DREG ($1) && IS_DREG ($4)) 2804 { 2805 if ($5.r0 == 0 && $5.s0 == 0 && $5.aop == 0) 2806 { 2807 notethat ("ALU2op: dregs = - dregs\n"); 2808 $$ = ALU2OP (&$1, &$4, 14); 2809 } 2810 else if ($5.r0 == 1 && $5.s0 == 0 && $5.aop == 3) 2811 { 2812 notethat ("dsp32alu: dregs = - dregs (.)\n"); 2813 $$ = DSP32ALU (15, 0, 0, &$1, &$4, 0, $5.s0, 0, 3); 2814 } 2815 else 2816 { 2817 notethat ("dsp32alu: dregs = - dregs (.)\n"); 2818 $$ = DSP32ALU (7, 0, 0, &$1, &$4, 0, $5.s0, 0, 3); 2819 } 2820 } 2821 else 2822 return yyerror ("Dregs expected"); 2823 } 2824 2825 | REG ASSIGN TILDA REG 2826 { 2827 if (IS_DREG ($1) && IS_DREG ($4)) 2828 { 2829 notethat ("ALU2op: dregs = ~dregs\n"); 2830 $$ = ALU2OP (&$1, &$4, 15); 2831 } 2832 else 2833 return yyerror ("Dregs expected"); 2834 } 2835 2836 | REG _GREATER_GREATER_ASSIGN REG 2837 { 2838 if (IS_DREG ($1) && IS_DREG ($3)) 2839 { 2840 notethat ("ALU2op: dregs >>= dregs\n"); 2841 $$ = ALU2OP (&$1, &$3, 1); 2842 } 2843 else 2844 return yyerror ("Dregs expected"); 2845 } 2846 2847 | REG _GREATER_GREATER_ASSIGN expr 2848 { 2849 if (IS_DREG ($1) && IS_UIMM ($3, 5)) 2850 { 2851 notethat ("LOGI2op: dregs >>= uimm5\n"); 2852 $$ = LOGI2OP ($1, uimm5 ($3), 6); 2853 } 2854 else 2855 return yyerror ("Dregs expected or value error"); 2856 } 2857 2858 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN REG 2859 { 2860 if (IS_DREG ($1) && IS_DREG ($3)) 2861 { 2862 notethat ("ALU2op: dregs >>>= dregs\n"); 2863 $$ = ALU2OP (&$1, &$3, 0); 2864 } 2865 else 2866 return yyerror ("Dregs expected"); 2867 } 2868 2869 | REG _LESS_LESS_ASSIGN REG 2870 { 2871 if (IS_DREG ($1) && IS_DREG ($3)) 2872 { 2873 notethat ("ALU2op: dregs <<= dregs\n"); 2874 $$ = ALU2OP (&$1, &$3, 2); 2875 } 2876 else 2877 return yyerror ("Dregs expected"); 2878 } 2879 2880 | REG _LESS_LESS_ASSIGN expr 2881 { 2882 if (IS_DREG ($1) && IS_UIMM ($3, 5)) 2883 { 2884 notethat ("LOGI2op: dregs <<= uimm5\n"); 2885 $$ = LOGI2OP ($1, uimm5 ($3), 7); 2886 } 2887 else 2888 return yyerror ("Dregs expected or const value error"); 2889 } 2890 2891 2892 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN expr 2893 { 2894 if (IS_DREG ($1) && IS_UIMM ($3, 5)) 2895 { 2896 notethat ("LOGI2op: dregs >>>= uimm5\n"); 2897 $$ = LOGI2OP ($1, uimm5 ($3), 5); 2898 } 2899 else 2900 return yyerror ("Dregs expected"); 2901 } 2902 2903 /* Cache Control. */ 2904 2905 | FLUSH LBRACK REG RBRACK 2906 { 2907 notethat ("CaCTRL: FLUSH [ pregs ]\n"); 2908 if (IS_PREG ($3)) 2909 $$ = CACTRL (&$3, 0, 2); 2910 else 2911 return yyerror ("Bad register(s) for FLUSH"); 2912 } 2913 2914 | FLUSH reg_with_postinc 2915 { 2916 if (IS_PREG ($2)) 2917 { 2918 notethat ("CaCTRL: FLUSH [ pregs ++ ]\n"); 2919 $$ = CACTRL (&$2, 1, 2); 2920 } 2921 else 2922 return yyerror ("Bad register(s) for FLUSH"); 2923 } 2924 2925 | FLUSHINV LBRACK REG RBRACK 2926 { 2927 if (IS_PREG ($3)) 2928 { 2929 notethat ("CaCTRL: FLUSHINV [ pregs ]\n"); 2930 $$ = CACTRL (&$3, 0, 1); 2931 } 2932 else 2933 return yyerror ("Bad register(s) for FLUSH"); 2934 } 2935 2936 | FLUSHINV reg_with_postinc 2937 { 2938 if (IS_PREG ($2)) 2939 { 2940 notethat ("CaCTRL: FLUSHINV [ pregs ++ ]\n"); 2941 $$ = CACTRL (&$2, 1, 1); 2942 } 2943 else 2944 return yyerror ("Bad register(s) for FLUSH"); 2945 } 2946 2947 /* CaCTRL: IFLUSH [pregs]. */ 2948 | IFLUSH LBRACK REG RBRACK 2949 { 2950 if (IS_PREG ($3)) 2951 { 2952 notethat ("CaCTRL: IFLUSH [ pregs ]\n"); 2953 $$ = CACTRL (&$3, 0, 3); 2954 } 2955 else 2956 return yyerror ("Bad register(s) for FLUSH"); 2957 } 2958 2959 | IFLUSH reg_with_postinc 2960 { 2961 if (IS_PREG ($2)) 2962 { 2963 notethat ("CaCTRL: IFLUSH [ pregs ++ ]\n"); 2964 $$ = CACTRL (&$2, 1, 3); 2965 } 2966 else 2967 return yyerror ("Bad register(s) for FLUSH"); 2968 } 2969 2970 | PREFETCH LBRACK REG RBRACK 2971 { 2972 if (IS_PREG ($3)) 2973 { 2974 notethat ("CaCTRL: PREFETCH [ pregs ]\n"); 2975 $$ = CACTRL (&$3, 0, 0); 2976 } 2977 else 2978 return yyerror ("Bad register(s) for PREFETCH"); 2979 } 2980 2981 | PREFETCH reg_with_postinc 2982 { 2983 if (IS_PREG ($2)) 2984 { 2985 notethat ("CaCTRL: PREFETCH [ pregs ++ ]\n"); 2986 $$ = CACTRL (&$2, 1, 0); 2987 } 2988 else 2989 return yyerror ("Bad register(s) for PREFETCH"); 2990 } 2991 2992 /* LOAD/STORE. */ 2993 /* LDST: B [ pregs <post_op> ] = dregs. */ 2994 2995 | B LBRACK REG post_op RBRACK ASSIGN REG 2996 { 2997 if (!IS_DREG ($7)) 2998 return yyerror ("Dreg expected for source operand"); 2999 if (!IS_PREG ($3)) 3000 return yyerror ("Preg expected in address"); 3001 3002 notethat ("LDST: B [ pregs <post_op> ] = dregs\n"); 3003 $$ = LDST (&$3, &$7, $4.x0, 2, 0, 1); 3004 } 3005 3006 /* LDSTidxI: B [ pregs + imm16 ] = dregs. */ 3007 | B LBRACK REG plus_minus expr RBRACK ASSIGN REG 3008 { 3009 Expr_Node *tmp = $5; 3010 3011 if (!IS_DREG ($8)) 3012 return yyerror ("Dreg expected for source operand"); 3013 if (!IS_PREG ($3)) 3014 return yyerror ("Preg expected in address"); 3015 3016 if (IS_RELOC ($5)) 3017 return yyerror ("Plain symbol used as offset"); 3018 3019 if ($4.r0) 3020 tmp = unary (Expr_Op_Type_NEG, tmp); 3021 3022 if (in_range_p (tmp, -32768, 32767, 0)) 3023 { 3024 notethat ("LDST: B [ pregs + imm16 ] = dregs\n"); 3025 $$ = LDSTIDXI (&$3, &$8, 1, 2, 0, $5); 3026 } 3027 else 3028 return yyerror ("Displacement out of range"); 3029 } 3030 3031 3032 /* LDSTii: W [ pregs + uimm4s2 ] = dregs. */ 3033 | W LBRACK REG plus_minus expr RBRACK ASSIGN REG 3034 { 3035 Expr_Node *tmp = $5; 3036 3037 if (!IS_DREG ($8)) 3038 return yyerror ("Dreg expected for source operand"); 3039 if (!IS_PREG ($3)) 3040 return yyerror ("Preg expected in address"); 3041 3042 if ($4.r0) 3043 tmp = unary (Expr_Op_Type_NEG, tmp); 3044 3045 if (IS_RELOC ($5)) 3046 return yyerror ("Plain symbol used as offset"); 3047 3048 if (in_range_p (tmp, 0, 30, 1)) 3049 { 3050 notethat ("LDSTii: W [ pregs +- uimm5m2 ] = dregs\n"); 3051 $$ = LDSTII (&$3, &$8, tmp, 1, 1); 3052 } 3053 else if (in_range_p (tmp, -65536, 65535, 1)) 3054 { 3055 notethat ("LDSTidxI: W [ pregs + imm17m2 ] = dregs\n"); 3056 $$ = LDSTIDXI (&$3, &$8, 1, 1, 0, tmp); 3057 } 3058 else 3059 return yyerror ("Displacement out of range"); 3060 } 3061 3062 /* LDST: W [ pregs <post_op> ] = dregs. */ 3063 | W LBRACK REG post_op RBRACK ASSIGN REG 3064 { 3065 if (!IS_DREG ($7)) 3066 return yyerror ("Dreg expected for source operand"); 3067 if (!IS_PREG ($3)) 3068 return yyerror ("Preg expected in address"); 3069 3070 notethat ("LDST: W [ pregs <post_op> ] = dregs\n"); 3071 $$ = LDST (&$3, &$7, $4.x0, 1, 0, 1); 3072 } 3073 3074 | W LBRACK REG post_op RBRACK ASSIGN HALF_REG 3075 { 3076 if (!IS_DREG ($7)) 3077 return yyerror ("Dreg expected for source operand"); 3078 if ($4.x0 == 2) 3079 { 3080 if (!IS_IREG ($3) && !IS_PREG ($3)) 3081 return yyerror ("Ireg or Preg expected in address"); 3082 } 3083 else if (!IS_IREG ($3)) 3084 return yyerror ("Ireg expected in address"); 3085 3086 if (IS_IREG ($3)) 3087 { 3088 notethat ("dspLDST: W [ iregs <post_op> ] = dregs_half\n"); 3089 $$ = DSPLDST (&$3, 1 + IS_H ($7), &$7, $4.x0, 1); 3090 } 3091 else 3092 { 3093 notethat ("LDSTpmod: W [ pregs ] = dregs_half\n"); 3094 $$ = LDSTPMOD (&$3, &$7, &$3, 1 + IS_H ($7), 1); 3095 } 3096 } 3097 3098 /* LDSTiiFP: [ FP - const ] = dpregs. */ 3099 | LBRACK REG plus_minus expr RBRACK ASSIGN REG 3100 { 3101 Expr_Node *tmp = $4; 3102 int ispreg = IS_PREG ($7); 3103 3104 if (!IS_PREG ($2)) 3105 return yyerror ("Preg expected in address"); 3106 3107 if (!IS_DREG ($7) && !ispreg) 3108 return yyerror ("Preg expected for source operand"); 3109 3110 if ($3.r0) 3111 tmp = unary (Expr_Op_Type_NEG, tmp); 3112 3113 if (IS_RELOC ($4)) 3114 return yyerror ("Plain symbol used as offset"); 3115 3116 if (in_range_p (tmp, 0, 63, 3)) 3117 { 3118 notethat ("LDSTii: dpregs = [ pregs + uimm6m4 ]\n"); 3119 $$ = LDSTII (&$2, &$7, tmp, 1, ispreg ? 3 : 0); 3120 } 3121 else if ($2.regno == REG_FP && in_range_p (tmp, -128, 0, 3)) 3122 { 3123 notethat ("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n"); 3124 tmp = unary (Expr_Op_Type_NEG, tmp); 3125 $$ = LDSTIIFP (tmp, &$7, 1); 3126 } 3127 else if (in_range_p (tmp, -131072, 131071, 3)) 3128 { 3129 notethat ("LDSTidxI: [ pregs + imm18m4 ] = dpregs\n"); 3130 $$ = LDSTIDXI (&$2, &$7, 1, 0, ispreg ? 1 : 0, tmp); 3131 } 3132 else 3133 return yyerror ("Displacement out of range"); 3134 } 3135 3136 | REG ASSIGN W LBRACK REG plus_minus expr RBRACK xpmod 3137 { 3138 Expr_Node *tmp = $7; 3139 if (!IS_DREG ($1)) 3140 return yyerror ("Dreg expected for destination operand"); 3141 if (!IS_PREG ($5)) 3142 return yyerror ("Preg expected in address"); 3143 3144 if ($6.r0) 3145 tmp = unary (Expr_Op_Type_NEG, tmp); 3146 3147 if (IS_RELOC ($7)) 3148 return yyerror ("Plain symbol used as offset"); 3149 3150 if (in_range_p (tmp, 0, 30, 1)) 3151 { 3152 notethat ("LDSTii: dregs = W [ pregs + uimm5m2 ] (.)\n"); 3153 $$ = LDSTII (&$5, &$1, tmp, 0, 1 << $9.r0); 3154 } 3155 else if (in_range_p (tmp, -65536, 65535, 1)) 3156 { 3157 notethat ("LDSTidxI: dregs = W [ pregs + imm17m2 ] (.)\n"); 3158 $$ = LDSTIDXI (&$5, &$1, 0, 1, $9.r0, tmp); 3159 } 3160 else 3161 return yyerror ("Displacement out of range"); 3162 } 3163 3164 | HALF_REG ASSIGN W LBRACK REG post_op RBRACK 3165 { 3166 if (!IS_DREG ($1)) 3167 return yyerror ("Dreg expected for source operand"); 3168 if ($6.x0 == 2) 3169 { 3170 if (!IS_IREG ($5) && !IS_PREG ($5)) 3171 return yyerror ("Ireg or Preg expected in address"); 3172 } 3173 else if (!IS_IREG ($5)) 3174 return yyerror ("Ireg expected in address"); 3175 3176 if (IS_IREG ($5)) 3177 { 3178 notethat ("dspLDST: dregs_half = W [ iregs <post_op> ]\n"); 3179 $$ = DSPLDST(&$5, 1 + IS_H ($1), &$1, $6.x0, 0); 3180 } 3181 else 3182 { 3183 notethat ("LDSTpmod: dregs_half = W [ pregs <post_op> ]\n"); 3184 $$ = LDSTPMOD (&$5, &$1, &$5, 1 + IS_H ($1), 0); 3185 } 3186 } 3187 3188 3189 | REG ASSIGN W LBRACK REG post_op RBRACK xpmod 3190 { 3191 if (!IS_DREG ($1)) 3192 return yyerror ("Dreg expected for destination operand"); 3193 if (!IS_PREG ($5)) 3194 return yyerror ("Preg expected in address"); 3195 3196 notethat ("LDST: dregs = W [ pregs <post_op> ] (.)\n"); 3197 $$ = LDST (&$5, &$1, $6.x0, 1, $8.r0, 0); 3198 } 3199 3200 | REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK xpmod 3201 { 3202 if (!IS_DREG ($1)) 3203 return yyerror ("Dreg expected for destination operand"); 3204 if (!IS_PREG ($5) || !IS_PREG ($7)) 3205 return yyerror ("Preg expected in address"); 3206 3207 notethat ("LDSTpmod: dregs = W [ pregs ++ pregs ] (.)\n"); 3208 $$ = LDSTPMOD (&$5, &$1, &$7, 3, $9.r0); 3209 } 3210 3211 | HALF_REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK 3212 { 3213 if (!IS_DREG ($1)) 3214 return yyerror ("Dreg expected for destination operand"); 3215 if (!IS_PREG ($5) || !IS_PREG ($7)) 3216 return yyerror ("Preg expected in address"); 3217 3218 notethat ("LDSTpmod: dregs_half = W [ pregs ++ pregs ]\n"); 3219 $$ = LDSTPMOD (&$5, &$1, &$7, 1 + IS_H ($1), 0); 3220 } 3221 3222 | LBRACK REG post_op RBRACK ASSIGN REG 3223 { 3224 if (!IS_IREG ($2) && !IS_PREG ($2)) 3225 return yyerror ("Ireg or Preg expected in address"); 3226 else if (IS_IREG ($2) && !IS_DREG ($6)) 3227 return yyerror ("Dreg expected for source operand"); 3228 else if (IS_PREG ($2) && !IS_DREG ($6) && !IS_PREG ($6)) 3229 return yyerror ("Dreg or Preg expected for source operand"); 3230 3231 if (IS_IREG ($2)) 3232 { 3233 notethat ("dspLDST: [ iregs <post_op> ] = dregs\n"); 3234 $$ = DSPLDST(&$2, 0, &$6, $3.x0, 1); 3235 } 3236 else if (IS_DREG ($6)) 3237 { 3238 notethat ("LDST: [ pregs <post_op> ] = dregs\n"); 3239 $$ = LDST (&$2, &$6, $3.x0, 0, 0, 1); 3240 } 3241 else 3242 { 3243 notethat ("LDST: [ pregs <post_op> ] = pregs\n"); 3244 $$ = LDST (&$2, &$6, $3.x0, 0, 1, 1); 3245 } 3246 } 3247 3248 | LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN REG 3249 { 3250 if (!IS_DREG ($7)) 3251 return yyerror ("Dreg expected for source operand"); 3252 3253 if (IS_IREG ($2) && IS_MREG ($4)) 3254 { 3255 notethat ("dspLDST: [ iregs ++ mregs ] = dregs\n"); 3256 $$ = DSPLDST(&$2, $4.regno & CODE_MASK, &$7, 3, 1); 3257 } 3258 else if (IS_PREG ($2) && IS_PREG ($4)) 3259 { 3260 notethat ("LDSTpmod: [ pregs ++ pregs ] = dregs\n"); 3261 $$ = LDSTPMOD (&$2, &$7, &$4, 0, 1); 3262 } 3263 else 3264 return yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address"); 3265 } 3266 3267 | W LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN HALF_REG 3268 { 3269 if (!IS_DREG ($8)) 3270 return yyerror ("Dreg expected for source operand"); 3271 3272 if (IS_PREG ($3) && IS_PREG ($5)) 3273 { 3274 notethat ("LDSTpmod: W [ pregs ++ pregs ] = dregs_half\n"); 3275 $$ = LDSTPMOD (&$3, &$8, &$5, 1 + IS_H ($8), 1); 3276 } 3277 else 3278 return yyerror ("Preg ++ Preg expected in address"); 3279 } 3280 3281 | REG ASSIGN B LBRACK REG plus_minus expr RBRACK xpmod 3282 { 3283 Expr_Node *tmp = $7; 3284 if (!IS_DREG ($1)) 3285 return yyerror ("Dreg expected for destination operand"); 3286 if (!IS_PREG ($5)) 3287 return yyerror ("Preg expected in address"); 3288 3289 if ($6.r0) 3290 tmp = unary (Expr_Op_Type_NEG, tmp); 3291 3292 if (IS_RELOC ($7)) 3293 return yyerror ("Plain symbol used as offset"); 3294 3295 if (in_range_p (tmp, -32768, 32767, 0)) 3296 { 3297 notethat ("LDSTidxI: dregs = B [ pregs + imm16 ] (%c)\n", 3298 $9.r0 ? 'X' : 'Z'); 3299 $$ = LDSTIDXI (&$5, &$1, 0, 2, $9.r0, tmp); 3300 } 3301 else 3302 return yyerror ("Displacement out of range"); 3303 } 3304 3305 | REG ASSIGN B LBRACK REG post_op RBRACK xpmod 3306 { 3307 if (!IS_DREG ($1)) 3308 return yyerror ("Dreg expected for destination operand"); 3309 if (!IS_PREG ($5)) 3310 return yyerror ("Preg expected in address"); 3311 3312 notethat ("LDST: dregs = B [ pregs <post_op> ] (%c)\n", 3313 $8.r0 ? 'X' : 'Z'); 3314 $$ = LDST (&$5, &$1, $6.x0, 2, $8.r0, 0); 3315 } 3316 3317 | REG ASSIGN LBRACK REG _PLUS_PLUS REG RBRACK 3318 { 3319 if (!IS_DREG ($1)) 3320 return yyerror ("Dreg expected for destination operand"); 3321 3322 if (IS_IREG ($4) && IS_MREG ($6)) 3323 { 3324 notethat ("dspLDST: dregs = [ iregs ++ mregs ]\n"); 3325 $$ = DSPLDST(&$4, $6.regno & CODE_MASK, &$1, 3, 0); 3326 } 3327 else if (IS_PREG ($4) && IS_PREG ($6)) 3328 { 3329 notethat ("LDSTpmod: dregs = [ pregs ++ pregs ]\n"); 3330 $$ = LDSTPMOD (&$4, &$1, &$6, 0, 0); 3331 } 3332 else 3333 return yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address"); 3334 } 3335 3336 | REG ASSIGN LBRACK REG plus_minus got_or_expr RBRACK 3337 { 3338 Expr_Node *tmp = $6; 3339 int ispreg = IS_PREG ($1); 3340 int isgot = IS_RELOC($6); 3341 3342 if (!IS_PREG ($4)) 3343 return yyerror ("Preg expected in address"); 3344 3345 if (!IS_DREG ($1) && !ispreg) 3346 return yyerror ("Dreg or Preg expected for destination operand"); 3347 3348 if (tmp->type == Expr_Node_Reloc 3349 && strcmp (tmp->value.s_value, 3350 "_current_shared_library_p5_offset_") != 0) 3351 return yyerror ("Plain symbol used as offset"); 3352 3353 if ($5.r0) 3354 tmp = unary (Expr_Op_Type_NEG, tmp); 3355 3356 if (isgot) 3357 { 3358 notethat ("LDSTidxI: dpregs = [ pregs + sym@got ]\n"); 3359 $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1 : 0, tmp); 3360 } 3361 else if (in_range_p (tmp, 0, 63, 3)) 3362 { 3363 notethat ("LDSTii: dpregs = [ pregs + uimm7m4 ]\n"); 3364 $$ = LDSTII (&$4, &$1, tmp, 0, ispreg ? 3 : 0); 3365 } 3366 else if ($4.regno == REG_FP && in_range_p (tmp, -128, 0, 3)) 3367 { 3368 notethat ("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n"); 3369 tmp = unary (Expr_Op_Type_NEG, tmp); 3370 $$ = LDSTIIFP (tmp, &$1, 0); 3371 } 3372 else if (in_range_p (tmp, -131072, 131071, 3)) 3373 { 3374 notethat ("LDSTidxI: dpregs = [ pregs + imm18m4 ]\n"); 3375 $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1 : 0, tmp); 3376 3377 } 3378 else 3379 return yyerror ("Displacement out of range"); 3380 } 3381 3382 | REG ASSIGN LBRACK REG post_op RBRACK 3383 { 3384 if (!IS_IREG ($4) && !IS_PREG ($4)) 3385 return yyerror ("Ireg or Preg expected in address"); 3386 else if (IS_IREG ($4) && !IS_DREG ($1)) 3387 return yyerror ("Dreg expected in destination operand"); 3388 else if (IS_PREG ($4) && !IS_DREG ($1) && !IS_PREG ($1) 3389 && ($4.regno != REG_SP || !IS_ALLREG ($1) || $5.x0 != 0)) 3390 return yyerror ("Dreg or Preg expected in destination operand"); 3391 3392 if (IS_IREG ($4)) 3393 { 3394 notethat ("dspLDST: dregs = [ iregs <post_op> ]\n"); 3395 $$ = DSPLDST (&$4, 0, &$1, $5.x0, 0); 3396 } 3397 else if (IS_DREG ($1)) 3398 { 3399 notethat ("LDST: dregs = [ pregs <post_op> ]\n"); 3400 $$ = LDST (&$4, &$1, $5.x0, 0, 0, 0); 3401 } 3402 else if (IS_PREG ($1)) 3403 { 3404 if (REG_SAME ($1, $4) && $5.x0 != 2) 3405 return yyerror ("Pregs can't be same"); 3406 3407 notethat ("LDST: pregs = [ pregs <post_op> ]\n"); 3408 $$ = LDST (&$4, &$1, $5.x0, 0, 1, 0); 3409 } 3410 else 3411 { 3412 notethat ("PushPopReg: allregs = [ SP ++ ]\n"); 3413 $$ = PUSHPOPREG (&$1, 0); 3414 } 3415 } 3416 3417 3418 /* PushPopMultiple. */ 3419 | reg_with_predec ASSIGN LPAREN REG COLON expr COMMA REG COLON expr RPAREN 3420 { 3421 if ($1.regno != REG_SP) 3422 yyerror ("Stack Pointer expected"); 3423 if ($4.regno == REG_R7 3424 && IN_RANGE ($6, 0, 7) 3425 && $8.regno == REG_P5 3426 && IN_RANGE ($10, 0, 5)) 3427 { 3428 notethat ("PushPopMultiple: [ -- SP ] = (R7 : reglim , P5 : reglim )\n"); 3429 $$ = PUSHPOPMULTIPLE (imm5 ($6), imm5 ($10), 1, 1, 1); 3430 } 3431 else 3432 return yyerror ("Bad register for PushPopMultiple"); 3433 } 3434 3435 | reg_with_predec ASSIGN LPAREN REG COLON expr RPAREN 3436 { 3437 if ($1.regno != REG_SP) 3438 yyerror ("Stack Pointer expected"); 3439 3440 if ($4.regno == REG_R7 && IN_RANGE ($6, 0, 7)) 3441 { 3442 notethat ("PushPopMultiple: [ -- SP ] = (R7 : reglim )\n"); 3443 $$ = PUSHPOPMULTIPLE (imm5 ($6), 0, 1, 0, 1); 3444 } 3445 else if ($4.regno == REG_P5 && IN_RANGE ($6, 0, 6)) 3446 { 3447 notethat ("PushPopMultiple: [ -- SP ] = (P5 : reglim )\n"); 3448 $$ = PUSHPOPMULTIPLE (0, imm5 ($6), 0, 1, 1); 3449 } 3450 else 3451 return yyerror ("Bad register for PushPopMultiple"); 3452 } 3453 3454 | LPAREN REG COLON expr COMMA REG COLON expr RPAREN ASSIGN reg_with_postinc 3455 { 3456 if ($11.regno != REG_SP) 3457 yyerror ("Stack Pointer expected"); 3458 if ($2.regno == REG_R7 && (IN_RANGE ($4, 0, 7)) 3459 && $6.regno == REG_P5 && (IN_RANGE ($8, 0, 6))) 3460 { 3461 notethat ("PushPopMultiple: (R7 : reglim , P5 : reglim ) = [ SP ++ ]\n"); 3462 $$ = PUSHPOPMULTIPLE (imm5 ($4), imm5 ($8), 1, 1, 0); 3463 } 3464 else 3465 return yyerror ("Bad register range for PushPopMultiple"); 3466 } 3467 3468 | LPAREN REG COLON expr RPAREN ASSIGN reg_with_postinc 3469 { 3470 if ($7.regno != REG_SP) 3471 yyerror ("Stack Pointer expected"); 3472 3473 if ($2.regno == REG_R7 && IN_RANGE ($4, 0, 7)) 3474 { 3475 notethat ("PushPopMultiple: (R7 : reglim ) = [ SP ++ ]\n"); 3476 $$ = PUSHPOPMULTIPLE (imm5 ($4), 0, 1, 0, 0); 3477 } 3478 else if ($2.regno == REG_P5 && IN_RANGE ($4, 0, 6)) 3479 { 3480 notethat ("PushPopMultiple: (P5 : reglim ) = [ SP ++ ]\n"); 3481 $$ = PUSHPOPMULTIPLE (0, imm5 ($4), 0, 1, 0); 3482 } 3483 else 3484 return yyerror ("Bad register range for PushPopMultiple"); 3485 } 3486 3487 | reg_with_predec ASSIGN REG 3488 { 3489 if ($1.regno != REG_SP) 3490 yyerror ("Stack Pointer expected"); 3491 3492 if (IS_ALLREG ($3)) 3493 { 3494 notethat ("PushPopReg: [ -- SP ] = allregs\n"); 3495 $$ = PUSHPOPREG (&$3, 1); 3496 } 3497 else 3498 return yyerror ("Bad register for PushPopReg"); 3499 } 3500 3501 /* Linkage. */ 3502 3503 | LINK expr 3504 { 3505 if (IS_URANGE (16, $2, 0, 4)) 3506 $$ = LINKAGE (0, uimm16s4 ($2)); 3507 else 3508 return yyerror ("Bad constant for LINK"); 3509 } 3510 3511 | UNLINK 3512 { 3513 notethat ("linkage: UNLINK\n"); 3514 $$ = LINKAGE (1, 0); 3515 } 3516 3517 3518 /* LSETUP. */ 3519 3520 | LSETUP LPAREN expr COMMA expr RPAREN REG 3521 { 3522 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5) && IS_CREG ($7)) 3523 { 3524 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters\n"); 3525 $$ = LOOPSETUP ($3, &$7, 0, $5, 0); 3526 } 3527 else 3528 return yyerror ("Bad register or values for LSETUP"); 3529 3530 } 3531 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG 3532 { 3533 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5) 3534 && IS_PREG ($9) && IS_CREG ($7)) 3535 { 3536 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs\n"); 3537 $$ = LOOPSETUP ($3, &$7, 1, $5, &$9); 3538 } 3539 else 3540 return yyerror ("Bad register or values for LSETUP"); 3541 } 3542 3543 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG GREATER_GREATER expr 3544 { 3545 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5) 3546 && IS_PREG ($9) && IS_CREG ($7) 3547 && EXPR_VALUE ($11) == 1) 3548 { 3549 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs >> 1\n"); 3550 $$ = LOOPSETUP ($3, &$7, 3, $5, &$9); 3551 } 3552 else 3553 return yyerror ("Bad register or values for LSETUP"); 3554 } 3555 3556 /* LOOP. */ 3557 | LOOP expr REG 3558 { 3559 if (!IS_RELOC ($2)) 3560 return yyerror ("Invalid expression in loop statement"); 3561 if (!IS_CREG ($3)) 3562 return yyerror ("Invalid loop counter register"); 3563 $$ = bfin_gen_loop ($2, &$3, 0, 0); 3564 } 3565 | LOOP expr REG ASSIGN REG 3566 { 3567 if (IS_RELOC ($2) && IS_PREG ($5) && IS_CREG ($3)) 3568 { 3569 notethat ("Loop: LOOP expr counters = pregs\n"); 3570 $$ = bfin_gen_loop ($2, &$3, 1, &$5); 3571 } 3572 else 3573 return yyerror ("Bad register or values for LOOP"); 3574 } 3575 | LOOP expr REG ASSIGN REG GREATER_GREATER expr 3576 { 3577 if (IS_RELOC ($2) && IS_PREG ($5) && IS_CREG ($3) && EXPR_VALUE ($7) == 1) 3578 { 3579 notethat ("Loop: LOOP expr counters = pregs >> 1\n"); 3580 $$ = bfin_gen_loop ($2, &$3, 3, &$5); 3581 } 3582 else 3583 return yyerror ("Bad register or values for LOOP"); 3584 } 3585 3586 /* LOOP_BEGIN. */ 3587 | LOOP_BEGIN NUMBER 3588 { 3589 Expr_Node_Value val; 3590 val.i_value = $2; 3591 Expr_Node *tmp = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL); 3592 bfin_loop_attempt_create_label (tmp, 1); 3593 if (!IS_RELOC (tmp)) 3594 return yyerror ("Invalid expression in LOOP_BEGIN statement"); 3595 bfin_loop_beginend (tmp, 1); 3596 $$ = 0; 3597 } 3598 | LOOP_BEGIN expr 3599 { 3600 if (!IS_RELOC ($2)) 3601 return yyerror ("Invalid expression in LOOP_BEGIN statement"); 3602 3603 bfin_loop_beginend ($2, 1); 3604 $$ = 0; 3605 } 3606 3607 /* LOOP_END. */ 3608 | LOOP_END NUMBER 3609 { 3610 Expr_Node_Value val; 3611 val.i_value = $2; 3612 Expr_Node *tmp = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL); 3613 bfin_loop_attempt_create_label (tmp, 1); 3614 if (!IS_RELOC (tmp)) 3615 return yyerror ("Invalid expression in LOOP_END statement"); 3616 bfin_loop_beginend (tmp, 0); 3617 $$ = 0; 3618 } 3619 | LOOP_END expr 3620 { 3621 if (!IS_RELOC ($2)) 3622 return yyerror ("Invalid expression in LOOP_END statement"); 3623 3624 bfin_loop_beginend ($2, 0); 3625 $$ = 0; 3626 } 3627 3628 /* pseudoDEBUG. */ 3629 3630 | ABORT 3631 { 3632 notethat ("psedoDEBUG: ABORT\n"); 3633 $$ = bfin_gen_pseudodbg (3, 3, 0); 3634 } 3635 3636 | DBG 3637 { 3638 notethat ("pseudoDEBUG: DBG\n"); 3639 $$ = bfin_gen_pseudodbg (3, 7, 0); 3640 } 3641 | DBG REG_A 3642 { 3643 notethat ("pseudoDEBUG: DBG REG_A\n"); 3644 $$ = bfin_gen_pseudodbg (3, IS_A1 ($2), 0); 3645 } 3646 | DBG REG 3647 { 3648 notethat ("pseudoDEBUG: DBG allregs\n"); 3649 $$ = bfin_gen_pseudodbg (0, $2.regno & CODE_MASK, ($2.regno & CLASS_MASK) >> 4); 3650 } 3651 3652 | DBGCMPLX LPAREN REG RPAREN 3653 { 3654 if (!IS_DREG ($3)) 3655 return yyerror ("Dregs expected"); 3656 notethat ("pseudoDEBUG: DBGCMPLX (dregs )\n"); 3657 $$ = bfin_gen_pseudodbg (3, 6, ($3.regno & CODE_MASK) >> 4); 3658 } 3659 3660 | DBGHALT 3661 { 3662 notethat ("psedoDEBUG: DBGHALT\n"); 3663 $$ = bfin_gen_pseudodbg (3, 5, 0); 3664 } 3665 3666 | HLT 3667 { 3668 notethat ("psedoDEBUG: HLT\n"); 3669 $$ = bfin_gen_pseudodbg (3, 4, 0); 3670 } 3671 3672 | DBGA LPAREN HALF_REG COMMA expr RPAREN 3673 { 3674 notethat ("pseudodbg_assert: DBGA (regs_lo/hi , uimm16 )\n"); 3675 $$ = bfin_gen_pseudodbg_assert (IS_H ($3), &$3, uimm16 ($5)); 3676 } 3677 3678 | DBGAH LPAREN REG COMMA expr RPAREN 3679 { 3680 notethat ("pseudodbg_assert: DBGAH (regs , uimm16 )\n"); 3681 $$ = bfin_gen_pseudodbg_assert (3, &$3, uimm16 ($5)); 3682 } 3683 3684 | DBGAL LPAREN REG COMMA expr RPAREN 3685 { 3686 notethat ("psedodbg_assert: DBGAL (regs , uimm16 )\n"); 3687 $$ = bfin_gen_pseudodbg_assert (2, &$3, uimm16 ($5)); 3688 } 3689 3690 | OUTC expr 3691 { 3692 if (!IS_UIMM ($2, 8)) 3693 return yyerror ("Constant out of range"); 3694 notethat ("psedodbg_assert: OUTC uimm8\n"); 3695 $$ = bfin_gen_pseudochr (uimm8 ($2)); 3696 } 3697 3698 | OUTC REG 3699 { 3700 if (!IS_DREG ($2)) 3701 return yyerror ("Dregs expected"); 3702 notethat ("psedodbg_assert: OUTC dreg\n"); 3703 $$ = bfin_gen_pseudodbg (2, $2.regno & CODE_MASK, 0); 3704 } 3705 3706 ; 3707 3708 /* AUX RULES. */ 3709 3710 /* Register rules. */ 3711 3712 REG_A: REG_A_DOUBLE_ZERO 3713 { 3714 $$ = $1; 3715 } 3716 | REG_A_DOUBLE_ONE 3717 { 3718 $$ = $1; 3719 } 3720 ; 3721 3722 3723 /* Modifiers. */ 3724 3725 opt_mode: 3726 { 3727 $$.MM = 0; 3728 $$.mod = 0; 3729 } 3730 | LPAREN M COMMA MMOD RPAREN 3731 { 3732 $$.MM = 1; 3733 $$.mod = $4; 3734 } 3735 | LPAREN MMOD COMMA M RPAREN 3736 { 3737 $$.MM = 1; 3738 $$.mod = $2; 3739 } 3740 | LPAREN MMOD RPAREN 3741 { 3742 $$.MM = 0; 3743 $$.mod = $2; 3744 } 3745 | LPAREN M RPAREN 3746 { 3747 $$.MM = 1; 3748 $$.mod = 0; 3749 } 3750 ; 3751 3752 asr_asl: LPAREN ASL RPAREN 3753 { 3754 $$.r0 = 1; 3755 } 3756 | LPAREN ASR RPAREN 3757 { 3758 $$.r0 = 0; 3759 } 3760 ; 3761 3762 sco: 3763 { 3764 $$.s0 = 0; 3765 $$.x0 = 0; 3766 } 3767 | S 3768 { 3769 $$.s0 = 1; 3770 $$.x0 = 0; 3771 } 3772 | CO 3773 { 3774 $$.s0 = 0; 3775 $$.x0 = 1; 3776 } 3777 | SCO 3778 { 3779 $$.s0 = 1; 3780 $$.x0 = 1; 3781 } 3782 ; 3783 3784 asr_asl_0: 3785 ASL 3786 { 3787 $$.r0 = 1; 3788 } 3789 | ASR 3790 { 3791 $$.r0 = 0; 3792 } 3793 ; 3794 3795 amod0: 3796 { 3797 $$.s0 = 0; 3798 $$.x0 = 0; 3799 } 3800 | LPAREN sco RPAREN 3801 { 3802 $$.s0 = $2.s0; 3803 $$.x0 = $2.x0; 3804 } 3805 ; 3806 3807 amod1: 3808 { 3809 $$.s0 = 0; 3810 $$.x0 = 0; 3811 $$.aop = 0; 3812 } 3813 | LPAREN NS RPAREN 3814 { 3815 $$.s0 = 0; 3816 $$.x0 = 0; 3817 $$.aop = 1; 3818 } 3819 | LPAREN S RPAREN 3820 { 3821 $$.s0 = 1; 3822 $$.x0 = 0; 3823 $$.aop = 1; 3824 } 3825 ; 3826 3827 amod2: 3828 { 3829 $$.r0 = 0; 3830 $$.s0 = 0; 3831 $$.x0 = 0; 3832 } 3833 | LPAREN asr_asl_0 RPAREN 3834 { 3835 $$.r0 = 2 + $2.r0; 3836 $$.s0 = 0; 3837 $$.x0 = 0; 3838 } 3839 | LPAREN sco RPAREN 3840 { 3841 $$.r0 = 0; 3842 $$.s0 = $2.s0; 3843 $$.x0 = $2.x0; 3844 } 3845 | LPAREN asr_asl_0 COMMA sco RPAREN 3846 { 3847 $$.r0 = 2 + $2.r0; 3848 $$.s0 = $4.s0; 3849 $$.x0 = $4.x0; 3850 } 3851 | LPAREN sco COMMA asr_asl_0 RPAREN 3852 { 3853 $$.r0 = 2 + $4.r0; 3854 $$.s0 = $2.s0; 3855 $$.x0 = $2.x0; 3856 } 3857 ; 3858 3859 xpmod: 3860 { 3861 $$.r0 = 0; 3862 } 3863 | LPAREN Z RPAREN 3864 { 3865 $$.r0 = 0; 3866 } 3867 | LPAREN X RPAREN 3868 { 3869 $$.r0 = 1; 3870 } 3871 ; 3872 3873 xpmod1: 3874 { 3875 $$.r0 = 0; 3876 } 3877 | LPAREN X RPAREN 3878 { 3879 $$.r0 = 0; 3880 } 3881 | LPAREN Z RPAREN 3882 { 3883 $$.r0 = 1; 3884 } 3885 ; 3886 3887 vsmod: 3888 { 3889 $$.r0 = 0; 3890 $$.s0 = 0; 3891 $$.aop = 0; 3892 } 3893 | LPAREN NS RPAREN 3894 { 3895 $$.r0 = 0; 3896 $$.s0 = 0; 3897 $$.aop = 3; 3898 } 3899 | LPAREN S RPAREN 3900 { 3901 $$.r0 = 0; 3902 $$.s0 = 1; 3903 $$.aop = 3; 3904 } 3905 | LPAREN V RPAREN 3906 { 3907 $$.r0 = 1; 3908 $$.s0 = 0; 3909 $$.aop = 3; 3910 } 3911 | LPAREN V COMMA S RPAREN 3912 { 3913 $$.r0 = 1; 3914 $$.s0 = 1; 3915 } 3916 | LPAREN S COMMA V RPAREN 3917 { 3918 $$.r0 = 1; 3919 $$.s0 = 1; 3920 } 3921 ; 3922 3923 vmod: 3924 { 3925 $$.r0 = 0; 3926 } 3927 | LPAREN V RPAREN 3928 { 3929 $$.r0 = 1; 3930 } 3931 ; 3932 3933 smod: 3934 { 3935 $$.s0 = 0; 3936 } 3937 | LPAREN S RPAREN 3938 { 3939 $$.s0 = 1; 3940 } 3941 ; 3942 3943 searchmod: 3944 GE 3945 { 3946 $$.r0 = 1; 3947 } 3948 | GT 3949 { 3950 $$.r0 = 0; 3951 } 3952 | LE 3953 { 3954 $$.r0 = 3; 3955 } 3956 | LT 3957 { 3958 $$.r0 = 2; 3959 } 3960 ; 3961 3962 aligndir: 3963 { 3964 $$.r0 = 0; 3965 } 3966 | LPAREN R RPAREN 3967 { 3968 $$.r0 = 1; 3969 } 3970 ; 3971 3972 byteop_mod: 3973 LPAREN R RPAREN 3974 { 3975 $$.r0 = 0; 3976 $$.s0 = 1; 3977 } 3978 | LPAREN MMOD RPAREN 3979 { 3980 if ($2 != M_T) 3981 return yyerror ("Bad modifier"); 3982 $$.r0 = 1; 3983 $$.s0 = 0; 3984 } 3985 | LPAREN MMOD COMMA R RPAREN 3986 { 3987 if ($2 != M_T) 3988 return yyerror ("Bad modifier"); 3989 $$.r0 = 1; 3990 $$.s0 = 1; 3991 } 3992 | LPAREN R COMMA MMOD RPAREN 3993 { 3994 if ($4 != M_T) 3995 return yyerror ("Bad modifier"); 3996 $$.r0 = 1; 3997 $$.s0 = 1; 3998 } 3999 ; 4000 4001 4002 4003 c_align: 4004 ALIGN8 4005 { 4006 $$.r0 = 0; 4007 } 4008 | ALIGN16 4009 { 4010 $$.r0 = 1; 4011 } 4012 | ALIGN24 4013 { 4014 $$.r0 = 2; 4015 } 4016 ; 4017 4018 w32_or_nothing: 4019 { 4020 $$.r0 = 0; 4021 } 4022 | LPAREN MMOD RPAREN 4023 { 4024 if ($2 == M_W32) 4025 $$.r0 = 1; 4026 else 4027 return yyerror ("Only (W32) allowed"); 4028 } 4029 ; 4030 4031 iu_or_nothing: 4032 { 4033 $$.r0 = 1; 4034 } 4035 | LPAREN MMOD RPAREN 4036 { 4037 if ($2 == M_IU) 4038 $$.r0 = 3; 4039 else 4040 return yyerror ("(IU) expected"); 4041 } 4042 ; 4043 4044 reg_with_predec: LBRACK _MINUS_MINUS REG RBRACK 4045 { 4046 $$ = $3; 4047 } 4048 ; 4049 4050 reg_with_postinc: LBRACK REG _PLUS_PLUS RBRACK 4051 { 4052 $$ = $2; 4053 } 4054 ; 4055 4056 /* Operators. */ 4057 4058 min_max: 4059 MIN 4060 { 4061 $$.r0 = 1; 4062 } 4063 | MAX 4064 { 4065 $$.r0 = 0; 4066 } 4067 ; 4068 4069 op_bar_op: 4070 _PLUS_BAR_PLUS 4071 { 4072 $$.r0 = 0; 4073 } 4074 | _PLUS_BAR_MINUS 4075 { 4076 $$.r0 = 1; 4077 } 4078 | _MINUS_BAR_PLUS 4079 { 4080 $$.r0 = 2; 4081 } 4082 | _MINUS_BAR_MINUS 4083 { 4084 $$.r0 = 3; 4085 } 4086 ; 4087 4088 plus_minus: 4089 PLUS 4090 { 4091 $$.r0 = 0; 4092 } 4093 | MINUS 4094 { 4095 $$.r0 = 1; 4096 } 4097 ; 4098 4099 rnd_op: 4100 LPAREN RNDH RPAREN 4101 { 4102 $$.r0 = 1; /* HL. */ 4103 $$.s0 = 0; /* s. */ 4104 $$.x0 = 0; /* x. */ 4105 $$.aop = 0; /* aop. */ 4106 } 4107 4108 | LPAREN TH RPAREN 4109 { 4110 $$.r0 = 1; /* HL. */ 4111 $$.s0 = 0; /* s. */ 4112 $$.x0 = 0; /* x. */ 4113 $$.aop = 1; /* aop. */ 4114 } 4115 4116 | LPAREN RNDL RPAREN 4117 { 4118 $$.r0 = 0; /* HL. */ 4119 $$.s0 = 0; /* s. */ 4120 $$.x0 = 0; /* x. */ 4121 $$.aop = 0; /* aop. */ 4122 } 4123 4124 | LPAREN TL RPAREN 4125 { 4126 $$.r0 = 0; /* HL. */ 4127 $$.s0 = 0; /* s. */ 4128 $$.x0 = 0; /* x. */ 4129 $$.aop = 1; 4130 } 4131 4132 | LPAREN RNDH COMMA R RPAREN 4133 { 4134 $$.r0 = 1; /* HL. */ 4135 $$.s0 = 1; /* s. */ 4136 $$.x0 = 0; /* x. */ 4137 $$.aop = 0; /* aop. */ 4138 } 4139 | LPAREN TH COMMA R RPAREN 4140 { 4141 $$.r0 = 1; /* HL. */ 4142 $$.s0 = 1; /* s. */ 4143 $$.x0 = 0; /* x. */ 4144 $$.aop = 1; /* aop. */ 4145 } 4146 | LPAREN RNDL COMMA R RPAREN 4147 { 4148 $$.r0 = 0; /* HL. */ 4149 $$.s0 = 1; /* s. */ 4150 $$.x0 = 0; /* x. */ 4151 $$.aop = 0; /* aop. */ 4152 } 4153 4154 | LPAREN TL COMMA R RPAREN 4155 { 4156 $$.r0 = 0; /* HL. */ 4157 $$.s0 = 1; /* s. */ 4158 $$.x0 = 0; /* x. */ 4159 $$.aop = 1; /* aop. */ 4160 } 4161 ; 4162 4163 b3_op: 4164 LPAREN LO RPAREN 4165 { 4166 $$.s0 = 0; /* s. */ 4167 $$.x0 = 0; /* HL. */ 4168 } 4169 | LPAREN HI RPAREN 4170 { 4171 $$.s0 = 0; /* s. */ 4172 $$.x0 = 1; /* HL. */ 4173 } 4174 | LPAREN LO COMMA R RPAREN 4175 { 4176 $$.s0 = 1; /* s. */ 4177 $$.x0 = 0; /* HL. */ 4178 } 4179 | LPAREN HI COMMA R RPAREN 4180 { 4181 $$.s0 = 1; /* s. */ 4182 $$.x0 = 1; /* HL. */ 4183 } 4184 ; 4185 4186 post_op: 4187 { 4188 $$.x0 = 2; 4189 } 4190 | _PLUS_PLUS 4191 { 4192 $$.x0 = 0; 4193 } 4194 | _MINUS_MINUS 4195 { 4196 $$.x0 = 1; 4197 } 4198 ; 4199 4200 /* Assignments, Macfuncs. */ 4201 4202 a_assign: 4203 REG_A ASSIGN 4204 { 4205 $$ = $1; 4206 } 4207 ; 4208 4209 a_minusassign: 4210 REG_A _MINUS_ASSIGN 4211 { 4212 $$ = $1; 4213 } 4214 ; 4215 4216 a_plusassign: 4217 REG_A _PLUS_ASSIGN 4218 { 4219 $$ = $1; 4220 } 4221 ; 4222 4223 assign_macfunc: 4224 REG ASSIGN REG_A 4225 { 4226 if (IS_A1 ($3) && IS_EVEN ($1)) 4227 return yyerror ("Cannot move A1 to even register"); 4228 else if (!IS_A1 ($3) && !IS_EVEN ($1)) 4229 return yyerror ("Cannot move A0 to odd register"); 4230 4231 $$.w = 1; 4232 $$.P = 1; 4233 $$.n = IS_A1 ($3); 4234 $$.op = 3; 4235 $$.dst = $1; 4236 $$.s0.regno = 0; 4237 $$.s1.regno = 0; 4238 } 4239 | a_macfunc 4240 { 4241 $$ = $1; 4242 $$.w = 0; $$.P = 0; 4243 $$.dst.regno = 0; 4244 } 4245 | REG ASSIGN LPAREN a_macfunc RPAREN 4246 { 4247 if ($4.n && IS_EVEN ($1)) 4248 return yyerror ("Cannot move A1 to even register"); 4249 else if (!$4.n && !IS_EVEN ($1)) 4250 return yyerror ("Cannot move A0 to odd register"); 4251 4252 $$ = $4; 4253 $$.w = 1; 4254 $$.P = 1; 4255 $$.dst = $1; 4256 } 4257 4258 | HALF_REG ASSIGN LPAREN a_macfunc RPAREN 4259 { 4260 if ($4.n && !IS_H ($1)) 4261 return yyerror ("Cannot move A1 to low half of register"); 4262 else if (!$4.n && IS_H ($1)) 4263 return yyerror ("Cannot move A0 to high half of register"); 4264 4265 $$ = $4; 4266 $$.w = 1; 4267 $$.P = 0; 4268 $$.dst = $1; 4269 } 4270 4271 | HALF_REG ASSIGN REG_A 4272 { 4273 if (IS_A1 ($3) && !IS_H ($1)) 4274 return yyerror ("Cannot move A1 to low half of register"); 4275 else if (!IS_A1 ($3) && IS_H ($1)) 4276 return yyerror ("Cannot move A0 to high half of register"); 4277 4278 $$.w = 1; 4279 $$.P = 0; 4280 $$.n = IS_A1 ($3); 4281 $$.op = 3; 4282 $$.dst = $1; 4283 $$.s0.regno = 0; 4284 $$.s1.regno = 0; 4285 } 4286 ; 4287 4288 a_macfunc: 4289 a_assign multiply_halfregs 4290 { 4291 $$.n = IS_A1 ($1); 4292 $$.op = 0; 4293 $$.s0 = $2.s0; 4294 $$.s1 = $2.s1; 4295 } 4296 | a_plusassign multiply_halfregs 4297 { 4298 $$.n = IS_A1 ($1); 4299 $$.op = 1; 4300 $$.s0 = $2.s0; 4301 $$.s1 = $2.s1; 4302 } 4303 | a_minusassign multiply_halfregs 4304 { 4305 $$.n = IS_A1 ($1); 4306 $$.op = 2; 4307 $$.s0 = $2.s0; 4308 $$.s1 = $2.s1; 4309 } 4310 ; 4311 4312 multiply_halfregs: 4313 HALF_REG STAR HALF_REG 4314 { 4315 if (IS_DREG ($1) && IS_DREG ($3)) 4316 { 4317 $$.s0 = $1; 4318 $$.s1 = $3; 4319 } 4320 else 4321 return yyerror ("Dregs expected"); 4322 } 4323 ; 4324 4325 cc_op: 4326 ASSIGN 4327 { 4328 $$.r0 = 0; 4329 } 4330 | _BAR_ASSIGN 4331 { 4332 $$.r0 = 1; 4333 } 4334 | _AMPERSAND_ASSIGN 4335 { 4336 $$.r0 = 2; 4337 } 4338 | _CARET_ASSIGN 4339 { 4340 $$.r0 = 3; 4341 } 4342 ; 4343 4344 ccstat: 4345 CCREG cc_op STATUS_REG 4346 { 4347 $$.r0 = $3.regno; 4348 $$.x0 = $2.r0; 4349 $$.s0 = 0; 4350 } 4351 | CCREG cc_op V 4352 { 4353 $$.r0 = 0x18; 4354 $$.x0 = $2.r0; 4355 $$.s0 = 0; 4356 } 4357 | STATUS_REG cc_op CCREG 4358 { 4359 $$.r0 = $1.regno; 4360 $$.x0 = $2.r0; 4361 $$.s0 = 1; 4362 } 4363 | V cc_op CCREG 4364 { 4365 $$.r0 = 0x18; 4366 $$.x0 = $2.r0; 4367 $$.s0 = 1; 4368 } 4369 ; 4370 4371 /* Expressions and Symbols. */ 4372 4373 symbol: SYMBOL 4374 { 4375 Expr_Node_Value val; 4376 val.s_value = S_GET_NAME($1); 4377 $$ = Expr_Node_Create (Expr_Node_Reloc, val, NULL, NULL); 4378 } 4379 ; 4380 4381 any_gotrel: 4382 GOT 4383 { $$ = BFD_RELOC_BFIN_GOT; } 4384 | GOT17M4 4385 { $$ = BFD_RELOC_BFIN_GOT17M4; } 4386 | FUNCDESC_GOT17M4 4387 { $$ = BFD_RELOC_BFIN_FUNCDESC_GOT17M4; } 4388 ; 4389 4390 got: symbol AT any_gotrel 4391 { 4392 Expr_Node_Value val; 4393 val.i_value = $3; 4394 $$ = Expr_Node_Create (Expr_Node_GOT_Reloc, val, $1, NULL); 4395 } 4396 ; 4397 4398 got_or_expr: got 4399 { 4400 $$ = $1; 4401 } 4402 | expr 4403 { 4404 $$ = $1; 4405 } 4406 ; 4407 4408 pltpc : 4409 symbol AT PLTPC 4410 { 4411 $$ = $1; 4412 } 4413 ; 4414 4415 eterm: NUMBER 4416 { 4417 Expr_Node_Value val; 4418 val.i_value = $1; 4419 $$ = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL); 4420 } 4421 | symbol 4422 { 4423 $$ = $1; 4424 } 4425 | LPAREN expr_1 RPAREN 4426 { 4427 $$ = $2; 4428 } 4429 | TILDA expr_1 4430 { 4431 $$ = unary (Expr_Op_Type_COMP, $2); 4432 } 4433 | MINUS expr_1 %prec TILDA 4434 { 4435 $$ = unary (Expr_Op_Type_NEG, $2); 4436 } 4437 ; 4438 4439 expr: expr_1 4440 { 4441 $$ = $1; 4442 } 4443 ; 4444 4445 expr_1: expr_1 STAR expr_1 4446 { 4447 $$ = binary (Expr_Op_Type_Mult, $1, $3); 4448 } 4449 | expr_1 SLASH expr_1 4450 { 4451 $$ = binary (Expr_Op_Type_Div, $1, $3); 4452 } 4453 | expr_1 PERCENT expr_1 4454 { 4455 $$ = binary (Expr_Op_Type_Mod, $1, $3); 4456 } 4457 | expr_1 PLUS expr_1 4458 { 4459 $$ = binary (Expr_Op_Type_Add, $1, $3); 4460 } 4461 | expr_1 MINUS expr_1 4462 { 4463 $$ = binary (Expr_Op_Type_Sub, $1, $3); 4464 } 4465 | expr_1 LESS_LESS expr_1 4466 { 4467 $$ = binary (Expr_Op_Type_Lshift, $1, $3); 4468 } 4469 | expr_1 GREATER_GREATER expr_1 4470 { 4471 $$ = binary (Expr_Op_Type_Rshift, $1, $3); 4472 } 4473 | expr_1 AMPERSAND expr_1 4474 { 4475 $$ = binary (Expr_Op_Type_BAND, $1, $3); 4476 } 4477 | expr_1 CARET expr_1 4478 { 4479 $$ = binary (Expr_Op_Type_LOR, $1, $3); 4480 } 4481 | expr_1 BAR expr_1 4482 { 4483 $$ = binary (Expr_Op_Type_BOR, $1, $3); 4484 } 4485 | eterm 4486 { 4487 $$ = $1; 4488 } 4489 ; 4490 4491 4492 %% 4493 4494 EXPR_T 4495 mkexpr (int x, SYMBOL_T s) 4496 { 4497 EXPR_T e = XNEW (struct expression_cell); 4498 e->value = x; 4499 EXPR_SYMBOL(e) = s; 4500 return e; 4501 } 4502 4503 static int 4504 value_match (Expr_Node *exp, int sz, int sign, int mul, int issigned) 4505 { 4506 int umax = (1 << sz) - 1; 4507 int min = -(1 << (sz - 1)); 4508 int max = (1 << (sz - 1)) - 1; 4509 4510 int v = (EXPR_VALUE (exp)) & 0xffffffff; 4511 4512 if ((v % mul) != 0) 4513 { 4514 error ("%s:%d: Value Error -- Must align to %d\n", __FILE__, __LINE__, mul); 4515 return 0; 4516 } 4517 4518 v /= mul; 4519 4520 if (sign) 4521 v = -v; 4522 4523 if (issigned) 4524 { 4525 if (v >= min && v <= max) return 1; 4526 4527 #ifdef DEBUG 4528 fprintf(stderr, "signed value %lx out of range\n", v * mul); 4529 #endif 4530 return 0; 4531 } 4532 if (v <= umax && v >= 0) 4533 return 1; 4534 #ifdef DEBUG 4535 fprintf(stderr, "unsigned value %lx out of range\n", v * mul); 4536 #endif 4537 return 0; 4538 } 4539 4540 /* Return the expression structure that allows symbol operations. 4541 If the left and right children are constants, do the operation. */ 4542 static Expr_Node * 4543 binary (Expr_Op_Type op, Expr_Node *x, Expr_Node *y) 4544 { 4545 Expr_Node_Value val; 4546 4547 if (x->type == Expr_Node_Constant && y->type == Expr_Node_Constant) 4548 { 4549 switch (op) 4550 { 4551 case Expr_Op_Type_Add: 4552 x->value.i_value += y->value.i_value; 4553 break; 4554 case Expr_Op_Type_Sub: 4555 x->value.i_value -= y->value.i_value; 4556 break; 4557 case Expr_Op_Type_Mult: 4558 x->value.i_value *= y->value.i_value; 4559 break; 4560 case Expr_Op_Type_Div: 4561 if (y->value.i_value == 0) 4562 error ("Illegal Expression: Division by zero."); 4563 else 4564 x->value.i_value /= y->value.i_value; 4565 break; 4566 case Expr_Op_Type_Mod: 4567 x->value.i_value %= y->value.i_value; 4568 break; 4569 case Expr_Op_Type_Lshift: 4570 x->value.i_value <<= y->value.i_value; 4571 break; 4572 case Expr_Op_Type_Rshift: 4573 x->value.i_value >>= y->value.i_value; 4574 break; 4575 case Expr_Op_Type_BAND: 4576 x->value.i_value &= y->value.i_value; 4577 break; 4578 case Expr_Op_Type_BOR: 4579 x->value.i_value |= y->value.i_value; 4580 break; 4581 case Expr_Op_Type_BXOR: 4582 x->value.i_value ^= y->value.i_value; 4583 break; 4584 case Expr_Op_Type_LAND: 4585 x->value.i_value = x->value.i_value && y->value.i_value; 4586 break; 4587 case Expr_Op_Type_LOR: 4588 x->value.i_value = x->value.i_value || y->value.i_value; 4589 break; 4590 4591 default: 4592 error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__); 4593 } 4594 return x; 4595 } 4596 /* Canonicalize order to EXPR OP CONSTANT. */ 4597 if (x->type == Expr_Node_Constant) 4598 { 4599 Expr_Node *t = x; 4600 x = y; 4601 y = t; 4602 } 4603 /* Canonicalize subtraction of const to addition of negated const. */ 4604 if (op == Expr_Op_Type_Sub && y->type == Expr_Node_Constant) 4605 { 4606 op = Expr_Op_Type_Add; 4607 y->value.i_value = -y->value.i_value; 4608 } 4609 if (y->type == Expr_Node_Constant && x->type == Expr_Node_Binop 4610 && x->Right_Child->type == Expr_Node_Constant) 4611 { 4612 if (op == x->value.op_value && x->value.op_value == Expr_Op_Type_Add) 4613 { 4614 x->Right_Child->value.i_value += y->value.i_value; 4615 return x; 4616 } 4617 } 4618 4619 /* Create a new expression structure. */ 4620 val.op_value = op; 4621 return Expr_Node_Create (Expr_Node_Binop, val, x, y); 4622 } 4623 4624 static Expr_Node * 4625 unary (Expr_Op_Type op, Expr_Node *x) 4626 { 4627 if (x->type == Expr_Node_Constant) 4628 { 4629 switch (op) 4630 { 4631 case Expr_Op_Type_NEG: 4632 x->value.i_value = -x->value.i_value; 4633 break; 4634 case Expr_Op_Type_COMP: 4635 x->value.i_value = ~x->value.i_value; 4636 break; 4637 default: 4638 error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__); 4639 } 4640 return x; 4641 } 4642 else 4643 { 4644 /* Create a new expression structure. */ 4645 Expr_Node_Value val; 4646 val.op_value = op; 4647 return Expr_Node_Create (Expr_Node_Unop, val, x, NULL); 4648 } 4649 } 4650 4651 int debug_codeselection = 0; 4652 static void 4653 notethat (const char *format, ...) 4654 { 4655 va_list ap; 4656 va_start (ap, format); 4657 if (debug_codeselection) 4658 { 4659 vfprintf (errorf, format, ap); 4660 } 4661 va_end (ap); 4662 } 4663 4664 #ifdef TEST 4665 main (int argc, char **argv) 4666 { 4667 yyparse(); 4668 } 4669 #endif 4670 4671