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