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