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