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