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