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