* elf.c (bfd_section_from_shdr): Check bfd_alloc return.
[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 }
1435 else
1436 return yyerror ("Register mismatch");
1437 }
1438
1439 | REG _STAR_ASSIGN REG
1440 {
1441 if (IS_DREG ($1) && IS_DREG ($3))
1442 {
1443 notethat ("ALU2op: dregs *= dregs\n");
1444 $$ = ALU2OP (&$1, &$3, 3);
1445 }
1446 else
1447 return yyerror ("Register mismatch");
1448 }
1449
1450 | SAA LPAREN REG COLON expr COMMA REG COLON expr RPAREN aligndir
1451 {
1452 if (!valid_dreg_pair (&$3, $5))
1453 return yyerror ("Bad dreg pair");
1454 else if (!valid_dreg_pair (&$7, $9))
1455 return yyerror ("Bad dreg pair");
1456 else
1457 {
1458 notethat ("dsp32alu: SAA (dregs_pair , dregs_pair ) (aligndir)\n");
1459 $$ = DSP32ALU (18, 0, 0, 0, &$3, &$7, $11.r0, 0, 0);
1460 }
1461 }
1462
1463 | a_assign REG_A LPAREN S RPAREN COMMA a_assign REG_A LPAREN S RPAREN
1464 {
1465 if (REG_SAME ($1, $2) && REG_SAME ($7, $8) && !REG_SAME ($1, $7))
1466 {
1467 notethat ("dsp32alu: A1 = A1 (S) , A0 = A0 (S)\n");
1468 $$ = DSP32ALU (8, 0, 0, 0, 0, 0, 1, 0, 2);
1469 }
1470 else
1471 return yyerror ("Register mismatch");
1472 }
1473
1474 | REG ASSIGN LPAREN REG PLUS REG RPAREN LESS_LESS expr
1475 {
1476 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG ($6)
1477 && REG_SAME ($1, $4))
1478 {
1479 if (EXPR_VALUE ($9) == 1)
1480 {
1481 notethat ("ALU2op: dregs = (dregs + dregs) << 1\n");
1482 $$ = ALU2OP (&$1, &$6, 4);
1483 }
1484 else if (EXPR_VALUE ($9) == 2)
1485 {
1486 notethat ("ALU2op: dregs = (dregs + dregs) << 2\n");
1487 $$ = ALU2OP (&$1, &$6, 5);
1488 }
1489 else
1490 return yyerror ("Bad shift value");
1491 }
1492 else if (IS_PREG ($1) && IS_PREG ($4) && IS_PREG ($6)
1493 && REG_SAME ($1, $4))
1494 {
1495 if (EXPR_VALUE ($9) == 1)
1496 {
1497 notethat ("PTR2op: pregs = (pregs + pregs) << 1\n");
1498 $$ = PTR2OP (&$1, &$6, 6);
1499 }
1500 else if (EXPR_VALUE ($9) == 2)
1501 {
1502 notethat ("PTR2op: pregs = (pregs + pregs) << 2\n");
1503 $$ = PTR2OP (&$1, &$6, 7);
1504 }
1505 else
1506 return yyerror ("Bad shift value");
1507 }
1508 else
1509 return yyerror ("Register mismatch");
1510 }
1511
1512/* COMP3 CCFLAG. */
1513 | REG ASSIGN REG BAR REG
1514 {
1515 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5))
1516 {
1517 notethat ("COMP3op: dregs = dregs | dregs\n");
1518 $$ = COMP3OP (&$1, &$3, &$5, 3);
1519 }
1520 else
1521 return yyerror ("Dregs expected");
1522 }
1523 | REG ASSIGN REG CARET REG
1524 {
1525 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5))
1526 {
1527 notethat ("COMP3op: dregs = dregs ^ dregs\n");
1528 $$ = COMP3OP (&$1, &$3, &$5, 4);
1529 }
1530 else
1531 return yyerror ("Dregs expected");
1532 }
1533 | REG ASSIGN REG PLUS LPAREN REG LESS_LESS expr RPAREN
1534 {
1535 if (IS_PREG ($1) && IS_PREG ($3) && IS_PREG ($6))
1536 {
1537 if (EXPR_VALUE ($8) == 1)
1538 {
1539 notethat ("COMP3op: pregs = pregs + (pregs << 1)\n");
1540 $$ = COMP3OP (&$1, &$3, &$6, 6);
1541 }
1542 else if (EXPR_VALUE ($8) == 2)
1543 {
1544 notethat ("COMP3op: pregs = pregs + (pregs << 2)\n");
1545 $$ = COMP3OP (&$1, &$3, &$6, 7);
1546 }
1547 else
1548 return yyerror ("Bad shift value");
1549 }
1550 else
1551 return yyerror ("Dregs expected");
1552 }
1553 | CCREG ASSIGN REG_A _ASSIGN_ASSIGN REG_A
1554 {
1555 if (!REG_SAME ($3, $5))
1556 {
1557 notethat ("CCflag: CC = A0 == A1\n");
1558 $$ = CCFLAG (0, 0, 5, 0, 0);
1559 }
1560 else
1561 return yyerror ("CC register expected");
1562 }
1563 | CCREG ASSIGN REG_A LESS_THAN REG_A
1564 {
1565 if (!REG_SAME ($3, $5))
1566 {
1567 notethat ("CCflag: CC = A0 < A1\n");
1568 $$ = CCFLAG (0, 0, 6, 0, 0);
1569 }
1570 else
1571 return yyerror ("Register mismatch");
1572 }
1573 | CCREG ASSIGN REG LESS_THAN REG iu_or_nothing
1574 {
1575 if (REG_CLASS($3) == REG_CLASS($5))
1576 {
1577 notethat ("CCflag: CC = dpregs < dpregs\n");
1578 $$ = CCFLAG (&$3, $5.regno & CODE_MASK, $6.r0, 0, IS_PREG ($3) ? 1 : 0);
1579 }
1580 else
1581 return yyerror ("Compare only of same register class");
1582 }
1583 | CCREG ASSIGN REG LESS_THAN expr iu_or_nothing
1584 {
1585 if (($6.r0 == 1 && IS_IMM ($5, 3))
1586 || ($6.r0 == 3 && IS_UIMM ($5, 3)))
1587 {
1588 notethat ("CCflag: CC = dpregs < (u)imm3\n");
1589 $$ = CCFLAG (&$3, imm3 ($5), $6.r0, 1, IS_PREG ($3) ? 1 : 0);
1590 }
1591 else
1592 return yyerror ("Bad constant value");
1593 }
1594 | CCREG ASSIGN REG _ASSIGN_ASSIGN REG
1595 {
1596 if (REG_CLASS($3) == REG_CLASS($5))
1597 {
1598 notethat ("CCflag: CC = dpregs == dpregs\n");
1599 $$ = CCFLAG (&$3, $5.regno & CODE_MASK, 0, 0, IS_PREG ($3) ? 1 : 0);
1600 }
1601 }
1602 | CCREG ASSIGN REG _ASSIGN_ASSIGN expr
1603 {
1604 if (IS_IMM ($5, 3))
1605 {
1606 notethat ("CCflag: CC = dpregs == imm3\n");
1607 $$ = CCFLAG (&$3, imm3 ($5), 0, 1, IS_PREG ($3) ? 1 : 0);
1608 }
1609 else
1610 return yyerror ("Bad constant range");
1611 }
1612 | CCREG ASSIGN REG_A _LESS_THAN_ASSIGN REG_A
1613 {
1614 if (!REG_SAME ($3, $5))
1615 {
1616 notethat ("CCflag: CC = A0 <= A1\n");
1617 $$ = CCFLAG (0, 0, 7, 0, 0);
1618 }
1619 else
1620 return yyerror ("CC register expected");
1621 }
1622 | CCREG ASSIGN REG _LESS_THAN_ASSIGN REG iu_or_nothing
1623 {
1624 if (REG_CLASS($3) == REG_CLASS($5))
1625 {
1626 notethat ("CCflag: CC = pregs <= pregs (..)\n");
1627 $$ = CCFLAG (&$3, $5.regno & CODE_MASK,
1628 1 + $6.r0, 0, IS_PREG ($3) ? 1 : 0);
1629 }
1630 else
1631 return yyerror ("Compare only of same register class");
1632 }
1633 | CCREG ASSIGN REG _LESS_THAN_ASSIGN expr iu_or_nothing
1634 {
1635 if (($6.r0 == 1 && IS_IMM ($5, 3))
1636 || ($6.r0 == 3 && IS_UIMM ($5, 3)))
1637 {
1638 if (IS_DREG ($3))
1639 {
1640 notethat ("CCflag: CC = dregs <= (u)imm3\n");
1641 /* x y opc I G */
1642 $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, 0);
1643 }
1644 else if (IS_PREG ($3))
1645 {
1646 notethat ("CCflag: CC = pregs <= (u)imm3\n");
1647 /* x y opc I G */
1648 $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, 1);
1649 }
1650 else
1651 return yyerror ("Dreg or Preg expected");
1652 }
1653 else
1654 return yyerror ("Bad constant value");
1655 }
1656
1657 | REG ASSIGN REG AMPERSAND REG
1658 {
1659 if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5))
1660 {
1661 notethat ("COMP3op: dregs = dregs & dregs\n");
1662 $$ = COMP3OP (&$1, &$3, &$5, 2);
1663 }
1664 else
1665 return yyerror ("Dregs expected");
1666 }
1667
1668 | ccstat
1669 {
1670 notethat ("CC2stat operation\n");
1671 $$ = bfin_gen_cc2stat ($1.r0, $1.x0, $1.s0);
1672 }
1673
1674 | REG ASSIGN REG
1675 {
1676 if (IS_ALLREG ($1) && IS_ALLREG ($3))
1677 {
1678 notethat ("REGMV: allregs = allregs\n");
1679 $$ = bfin_gen_regmv (&$3, &$1);
1680 }
1681 else
1682 return yyerror ("Register mismatch");
1683 }
1684
1685 | CCREG ASSIGN REG
1686 {
1687 if (IS_DREG ($3))
1688 {
1689 notethat ("CC2dreg: CC = dregs\n");
1690 $$ = bfin_gen_cc2dreg (1, &$3);
1691 }
1692 else
1693 return yyerror ("Register mismatch");
1694 }
1695
1696 | REG ASSIGN CCREG
1697 {
1698 if (IS_DREG ($1))
1699 {
1700 notethat ("CC2dreg: dregs = CC\n");
1701 $$ = bfin_gen_cc2dreg (0, &$1);
1702 }
1703 else
1704 return yyerror ("Register mismatch");
1705 }
1706
1707 | CCREG _ASSIGN_BANG CCREG
1708 {
1709 notethat ("CC2dreg: CC =! CC\n");
1710 $$ = bfin_gen_cc2dreg (3, 0);
1711 }
1712
1713/* DSPMULT. */
1714
1715 | HALF_REG ASSIGN multiply_halfregs opt_mode
1716 {
1717 notethat ("dsp32mult: dregs_half = multiply_halfregs (opt_mode)\n");
1718
1719 if (!IS_H ($1) && $4.MM)
1720 return yyerror ("(M) not allowed with MAC0");
1721
1722 if (IS_H ($1))
1723 {
1724 $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 0,
1725 IS_H ($3.s0), IS_H ($3.s1), 0, 0,
1726 &$1, 0, &$3.s0, &$3.s1, 0);
1727 }
1728 else
1729 {
1730 $$ = DSP32MULT (0, 0, $4.mod, 0, 0,
1731 0, 0, IS_H ($3.s0), IS_H ($3.s1),
1732 &$1, 0, &$3.s0, &$3.s1, 1);
a3205465 1733 }
07c1b327
CM
1734 }
1735
1736 | REG ASSIGN multiply_halfregs opt_mode
1737 {
1738 /* Odd registers can use (M). */
1739 if (!IS_DREG ($1))
1740 return yyerror ("Dreg expected");
1741
a3205465
JZ
1742 if (IS_EVEN ($1) && $4.MM)
1743 return yyerror ("(M) not allowed with MAC0");
1744
07c1b327
CM
1745 if (!IS_EVEN ($1))
1746 {
1747 notethat ("dsp32mult: dregs = multiply_halfregs (opt_mode)\n");
1748
1749 $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 1,
1750 IS_H ($3.s0), IS_H ($3.s1), 0, 0,
1751 &$1, 0, &$3.s0, &$3.s1, 0);
1752 }
a3205465 1753 else
07c1b327
CM
1754 {
1755 notethat ("dsp32mult: dregs = multiply_halfregs opt_mode\n");
1756 $$ = DSP32MULT (0, 0, $4.mod, 0, 1,
1757 0, 0, IS_H ($3.s0), IS_H ($3.s1),
1758 &$1, 0, &$3.s0, &$3.s1, 1);
1759 }
07c1b327
CM
1760 }
1761
1762 | HALF_REG ASSIGN multiply_halfregs opt_mode COMMA
1763 HALF_REG ASSIGN multiply_halfregs opt_mode
1764 {
1765 if (!IS_DREG ($1) || !IS_DREG ($6))
1766 return yyerror ("Dregs expected");
1767
a3205465
JZ
1768 if (!IS_HCOMPL($1, $6))
1769 return yyerror ("Dest registers mismatch");
1770
07c1b327
CM
1771 if (check_multiply_halfregs (&$3, &$8) < 0)
1772 return -1;
1773
a3205465
JZ
1774 if ((!IS_H ($1) && $4.MM)
1775 || (!IS_H ($6) && $9.MM))
1776 return yyerror ("(M) not allowed with MAC0");
1777
1778 notethat ("dsp32mult: dregs_hi = multiply_halfregs mxd_mod, "
1779 "dregs_lo = multiply_halfregs opt_mode\n");
1780
1781 if (IS_H ($1))
1782 $$ = DSP32MULT (0, $4.MM, $9.mod, 1, 0,
1783 IS_H ($3.s0), IS_H ($3.s1), IS_H ($8.s0), IS_H ($8.s1),
1784 &$1, 0, &$3.s0, &$3.s1, 1);
07c1b327 1785 else
a3205465
JZ
1786 $$ = DSP32MULT (0, $9.MM, $9.mod, 1, 0,
1787 IS_H ($8.s0), IS_H ($8.s1), IS_H ($3.s0), IS_H ($3.s1),
1788 &$1, 0, &$3.s0, &$3.s1, 1);
07c1b327
CM
1789 }
1790
a3205465 1791 | REG ASSIGN multiply_halfregs opt_mode COMMA REG ASSIGN multiply_halfregs opt_mode
07c1b327
CM
1792 {
1793 if (!IS_DREG ($1) || !IS_DREG ($6))
1794 return yyerror ("Dregs expected");
1795
a3205465
JZ
1796 if ((IS_EVEN ($1) && $6.regno - $1.regno != 1)
1797 || (IS_EVEN ($6) && $1.regno - $6.regno != 1))
1798 return yyerror ("Dest registers mismatch");
1799
07c1b327
CM
1800 if (check_multiply_halfregs (&$3, &$8) < 0)
1801 return -1;
1802
a3205465
JZ
1803 if ((IS_EVEN ($1) && $4.MM)
1804 || (IS_EVEN ($6) && $9.MM))
1805 return yyerror ("(M) not allowed with MAC0");
1806
07c1b327
CM
1807 notethat ("dsp32mult: dregs = multiply_halfregs mxd_mod, "
1808 "dregs = multiply_halfregs opt_mode\n");
07c1b327 1809
a3205465
JZ
1810 if (IS_EVEN ($1))
1811 $$ = DSP32MULT (0, $9.MM, $9.mod, 1, 1,
1812 IS_H ($8.s0), IS_H ($8.s1), IS_H ($3.s0), IS_H ($3.s1),
1813 &$1, 0, &$3.s0, &$3.s1, 1);
07c1b327 1814 else
a3205465
JZ
1815 $$ = DSP32MULT (0, $4.MM, $9.mod, 1, 1,
1816 IS_H ($3.s0), IS_H ($3.s1), IS_H ($8.s0), IS_H ($8.s1),
1817 &$1, 0, &$3.s0, &$3.s1, 1);
07c1b327
CM
1818 }
1819
1820\f
1821/* SHIFTs. */
1822 | a_assign ASHIFT REG_A BY HALF_REG
1823 {
1824 if (!REG_SAME ($1, $3))
1825 return yyerror ("Aregs must be same");
1826
1827 if (IS_DREG ($5) && !IS_H ($5))
1828 {
1829 notethat ("dsp32shift: A0 = ASHIFT A0 BY dregs_lo\n");
1830 $$ = DSP32SHIFT (3, 0, &$5, 0, 0, IS_A1 ($1));
1831 }
1832 else
1833 return yyerror ("Dregs expected");
1834 }
1835
1836 | HALF_REG ASSIGN ASHIFT HALF_REG BY HALF_REG smod
1837 {
1838 if (IS_DREG ($6) && !IS_H ($6))
1839 {
1840 notethat ("dsp32shift: dregs_half = ASHIFT dregs_half BY dregs_lo\n");
1841 $$ = DSP32SHIFT (0, &$1, &$6, &$4, $7.s0, HL2 ($1, $4));
1842 }
1843 else
1844 return yyerror ("Dregs expected");
1845 }
1846
1847 | a_assign REG_A LESS_LESS expr
1848 {
1849 if (!REG_SAME ($1, $2))
1850 return yyerror ("Aregs must be same");
1851
1852 if (IS_UIMM ($4, 5))
1853 {
1854 notethat ("dsp32shiftimm: A0 = A0 << uimm5\n");
1855 $$ = DSP32SHIFTIMM (3, 0, imm5 ($4), 0, 0, IS_A1 ($1));
1856 }
1857 else
1858 return yyerror ("Bad shift value");
1859 }
1860
1861 | REG ASSIGN REG LESS_LESS expr vsmod
1862 {
1863 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5))
1864 {
1865 if ($6.r0)
1866 {
1867 /* Vector? */
1868 notethat ("dsp32shiftimm: dregs = dregs << expr (V, .)\n");
1869 $$ = DSP32SHIFTIMM (1, &$1, imm4 ($5), &$3, $6.s0 ? 1 : 2, 0);
1870 }
1871 else
1872 {
1873 notethat ("dsp32shiftimm: dregs = dregs << uimm5 (.)\n");
1874 $$ = DSP32SHIFTIMM (2, &$1, imm6 ($5), &$3, $6.s0 ? 1 : 2, 0);
1875 }
1876 }
1877 else if ($6.s0 == 0 && IS_PREG ($1) && IS_PREG ($3))
1878 {
1879 if (EXPR_VALUE ($5) == 2)
1880 {
1881 notethat ("PTR2op: pregs = pregs << 2\n");
1882 $$ = PTR2OP (&$1, &$3, 1);
1883 }
1884 else if (EXPR_VALUE ($5) == 1)
1885 {
1886 notethat ("COMP3op: pregs = pregs << 1\n");
1887 $$ = COMP3OP (&$1, &$3, &$3, 5);
1888 }
1889 else
1890 return yyerror ("Bad shift value");
1891 }
1892 else
1893 return yyerror ("Bad shift value or register");
1894 }
1895 | HALF_REG ASSIGN HALF_REG LESS_LESS expr
1896 {
1897 if (IS_UIMM ($5, 4))
1898 {
1899 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
1900 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3));
1901 }
1902 else
1903 return yyerror ("Bad shift value");
1904 }
1905 | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod
1906 {
1907 if (IS_UIMM ($5, 4))
1908 {
1909 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
1910 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3));
1911 }
1912 else
1913 return yyerror ("Bad shift value");
1914 }
1915 | REG ASSIGN ASHIFT REG BY HALF_REG vsmod
1916 {
1917 int op;
1918
1919 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG ($6) && !IS_H ($6))
1920 {
1921 if ($7.r0)
1922 {
1923 op = 1;
1924 notethat ("dsp32shift: dregs = ASHIFT dregs BY "
1925 "dregs_lo (V, .)\n");
1926 }
1927 else
1928 {
1929
1930 op = 2;
1931 notethat ("dsp32shift: dregs = ASHIFT dregs BY dregs_lo (.)\n");
1932 }
1933 $$ = DSP32SHIFT (op, &$1, &$6, &$4, $7.s0, 0);
1934 }
1935 else
1936 return yyerror ("Dregs expected");
1937 }
1938
1939/* EXPADJ. */
1940 | HALF_REG ASSIGN EXPADJ LPAREN REG COMMA HALF_REG RPAREN vmod
1941 {
1942 if (IS_DREG_L ($1) && IS_DREG_L ($5) && IS_DREG_L ($7))
1943 {
1944 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs , dregs_lo )\n");
1945 $$ = DSP32SHIFT (7, &$1, &$7, &$5, $9.r0, 0);
1946 }
1947 else
1948 return yyerror ("Bad shift value or register");
1949 }
1950
1951
1952 | HALF_REG ASSIGN EXPADJ LPAREN HALF_REG COMMA HALF_REG RPAREN
1953 {
1954 if (IS_DREG_L ($1) && IS_DREG_L ($5) && IS_DREG_L ($7))
1955 {
1956 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs_lo, dregs_lo)\n");
1957 $$ = DSP32SHIFT (7, &$1, &$7, &$5, 2, 0);
1958 }
1959 else if (IS_DREG_L ($1) && IS_DREG_H ($5) && IS_DREG_L ($7))
1960 {
1961 notethat ("dsp32shift: dregs_lo = EXPADJ (dregs_hi, dregs_lo)\n");
1962 $$ = DSP32SHIFT (7, &$1, &$7, &$5, 3, 0);
1963 }
1964 else
1965 return yyerror ("Bad shift value or register");
1966 }
1967
1968/* DEPOSIT. */
1969
1970 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN
1971 {
1972 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7))
1973 {
1974 notethat ("dsp32shift: dregs = DEPOSIT (dregs , dregs )\n");
1975 $$ = DSP32SHIFT (10, &$1, &$7, &$5, 2, 0);
1976 }
1977 else
1978 return yyerror ("Register mismatch");
1979 }
1980
1981 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN LPAREN X RPAREN
1982 {
1983 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7))
1984 {
1985 notethat ("dsp32shift: dregs = DEPOSIT (dregs , dregs ) (X)\n");
1986 $$ = DSP32SHIFT (10, &$1, &$7, &$5, 3, 0);
1987 }
1988 else
1989 return yyerror ("Register mismatch");
1990 }
1991
1992 | REG ASSIGN EXTRACT LPAREN REG COMMA HALF_REG RPAREN xpmod
1993 {
1994 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG_L ($7))
1995 {
1996 notethat ("dsp32shift: dregs = EXTRACT (dregs, dregs_lo ) (.)\n");
1997 $$ = DSP32SHIFT (10, &$1, &$7, &$5, $9.r0, 0);
1998 }
1999 else
2000 return yyerror ("Register mismatch");
2001 }
2002
2003 | a_assign REG_A _GREATER_GREATER_GREATER expr
2004 {
2005 if (!REG_SAME ($1, $2))
2006 return yyerror ("Aregs must be same");
2007
2008 if (IS_UIMM ($4, 5))
2009 {
2010 notethat ("dsp32shiftimm: Ax = Ax >>> uimm5\n");
2011 $$ = DSP32SHIFTIMM (3, 0, -imm6 ($4), 0, 0, IS_A1 ($1));
2012 }
2013 else
2014 return yyerror ("Shift value range error");
2015 }
2016 | a_assign LSHIFT REG_A BY HALF_REG
2017 {
2018 if (REG_SAME ($1, $3) && IS_DREG_L ($5))
2019 {
2020 notethat ("dsp32shift: Ax = LSHIFT Ax BY dregs_lo\n");
2021 $$ = DSP32SHIFT (3, 0, &$5, 0, 1, IS_A1 ($1));
2022 }
2023 else
2024 return yyerror ("Register mismatch");
2025 }
2026
2027 | HALF_REG ASSIGN LSHIFT HALF_REG BY HALF_REG
2028 {
2029 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6))
2030 {
2031 notethat ("dsp32shift: dregs_lo = LSHIFT dregs_hi BY dregs_lo\n");
2032 $$ = DSP32SHIFT (0, &$1, &$6, &$4, 2, HL2 ($1, $4));
2033 }
2034 else
2035 return yyerror ("Register mismatch");
2036 }
2037
2038 | REG ASSIGN LSHIFT REG BY HALF_REG vmod
2039 {
2040 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6))
2041 {
2042 notethat ("dsp32shift: dregs = LSHIFT dregs BY dregs_lo (V )\n");
2043 $$ = DSP32SHIFT ($7.r0 ? 1: 2, &$1, &$6, &$4, 2, 0);
2044 }
2045 else
2046 return yyerror ("Register mismatch");
2047 }
2048
2049 | REG ASSIGN SHIFT REG BY HALF_REG
2050 {
2051 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6))
2052 {
2053 notethat ("dsp32shift: dregs = SHIFT dregs BY dregs_lo\n");
2054 $$ = DSP32SHIFT (2, &$1, &$6, &$4, 2, 0);
2055 }
2056 else
2057 return yyerror ("Register mismatch");
2058 }
2059
2060 | a_assign REG_A GREATER_GREATER expr
2061 {
2062 if (REG_SAME ($1, $2) && IS_IMM ($4, 6) >= 0)
2063 {
2064 notethat ("dsp32shiftimm: Ax = Ax >> imm6\n");
2065 $$ = DSP32SHIFTIMM (3, 0, -imm6 ($4), 0, 1, IS_A1 ($1));
2066 }
2067 else
2068 return yyerror ("Accu register expected");
2069 }
2070
2071 | REG ASSIGN REG GREATER_GREATER expr vmod
2072 {
2073 if ($6.r0 == 1)
2074 {
2075 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5))
2076 {
2077 notethat ("dsp32shiftimm: dregs = dregs >> uimm5 (V)\n");
2078 $$ = DSP32SHIFTIMM (1, &$1, -uimm5 ($5), &$3, 2, 0);
2079 }
2080 else
2081 return yyerror ("Register mismatch");
2082 }
2083 else
2084 {
2085 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5))
2086 {
2087 notethat ("dsp32shiftimm: dregs = dregs >> uimm5\n");
2088 $$ = DSP32SHIFTIMM (2, &$1, -imm6 ($5), &$3, 2, 0);
2089 }
2090 else if (IS_PREG ($1) && IS_PREG ($3) && EXPR_VALUE ($5) == 2)
2091 {
2092 notethat ("PTR2op: pregs = pregs >> 2\n");
2093 $$ = PTR2OP (&$1, &$3, 3);
2094 }
2095 else if (IS_PREG ($1) && IS_PREG ($3) && EXPR_VALUE ($5) == 1)
2096 {
2097 notethat ("PTR2op: pregs = pregs >> 1\n");
2098 $$ = PTR2OP (&$1, &$3, 4);
2099 }
2100 else
2101 return yyerror ("Register mismatch");
2102 }
2103 }
2104 | HALF_REG ASSIGN HALF_REG GREATER_GREATER expr
2105 {
2106 if (IS_UIMM ($5, 5))
2107 {
2108 notethat ("dsp32shiftimm: dregs_half = dregs_half >> uimm5\n");
2109 $$ = DSP32SHIFTIMM (0, &$1, -uimm5 ($5), &$3, 2, HL2 ($1, $3));
2110 }
2111 else
2112 return yyerror ("Register mismatch");
2113 }
2114 | HALF_REG ASSIGN HALF_REG _GREATER_GREATER_GREATER expr smod
2115 {
2116 if (IS_UIMM ($5, 5))
2117 {
2118 notethat ("dsp32shiftimm: dregs_half = dregs_half >>> uimm5\n");
2119 $$ = DSP32SHIFTIMM (0, &$1, -uimm5 ($5), &$3,
2120 $6.s0, HL2 ($1, $3));
2121 }
2122 else
2123 return yyerror ("Register or modifier mismatch");
2124 }
2125
2126
2127 | REG ASSIGN REG _GREATER_GREATER_GREATER expr vsmod
2128 {
2129 if (IS_DREG ($1) && IS_DREG ($3) && IS_UIMM ($5, 5))
2130 {
2131 if ($6.r0)
2132 {
2133 /* Vector? */
2134 notethat ("dsp32shiftimm: dregs = dregs >>> uimm5 (V, .)\n");
2135 $$ = DSP32SHIFTIMM (1, &$1, -uimm5 ($5), &$3, $6.s0, 0);
2136 }
2137 else
2138 {
2139 notethat ("dsp32shiftimm: dregs = dregs >>> uimm5 (.)\n");
2140 $$ = DSP32SHIFTIMM (2, &$1, -uimm5 ($5), &$3, $6.s0, 0);
2141 }
2142 }
2143 else
2144 return yyerror ("Register mismatch");
2145 }
2146
2147 | HALF_REG ASSIGN ONES REG
2148 {
2149 if (IS_DREG_L ($1) && IS_DREG ($4))
2150 {
2151 notethat ("dsp32shift: dregs_lo = ONES dregs\n");
2152 $$ = DSP32SHIFT (6, &$1, 0, &$4, 3, 0);
2153 }
2154 else
2155 return yyerror ("Register mismatch");
2156 }
2157
2158 | REG ASSIGN PACK LPAREN HALF_REG COMMA HALF_REG RPAREN
2159 {
2160 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7))
2161 {
2162 notethat ("dsp32shift: dregs = PACK (dregs_hi , dregs_hi )\n");
2163 $$ = DSP32SHIFT (4, &$1, &$7, &$5, HL2 ($5, $7), 0);
2164 }
2165 else
2166 return yyerror ("Register mismatch");
2167 }
2168
2169 | HALF_REG ASSIGN CCREG ASSIGN BXORSHIFT LPAREN REG_A COMMA REG RPAREN
2170 {
2171 if (IS_DREG ($1)
2172 && $7.regno == REG_A0
2173 && IS_DREG ($9) && !IS_H ($1) && !IS_A1 ($7))
2174 {
2175 notethat ("dsp32shift: dregs_lo = CC = BXORSHIFT (A0 , dregs )\n");
2176 $$ = DSP32SHIFT (11, &$1, &$9, 0, 0, 0);
2177 }
2178 else
2179 return yyerror ("Register mismatch");
2180 }
2181
2182 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG RPAREN
2183 {
2184 if (IS_DREG ($1)
2185 && $7.regno == REG_A0
2186 && IS_DREG ($9) && !IS_H ($1) && !IS_A1 ($7))
2187 {
2188 notethat ("dsp32shift: dregs_lo = CC = BXOR (A0 , dregs)\n");
2189 $$ = DSP32SHIFT (11, &$1, &$9, 0, 1, 0);
2190 }
2191 else
2192 return yyerror ("Register mismatch");
2193 }
2194
2195 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN
2196 {
2197 if (IS_DREG ($1) && !IS_H ($1) && !REG_SAME ($7, $9))
2198 {
2199 notethat ("dsp32shift: dregs_lo = CC = BXOR (A0 , A1 , CC)\n");
2200 $$ = DSP32SHIFT (12, &$1, 0, 0, 1, 0);
2201 }
2202 else
2203 return yyerror ("Register mismatch");
2204 }
2205
2206 | a_assign ROT REG_A BY HALF_REG
2207 {
2208 if (REG_SAME ($1, $3) && IS_DREG_L ($5))
2209 {
2210 notethat ("dsp32shift: Ax = ROT Ax BY dregs_lo\n");
2211 $$ = DSP32SHIFT (3, 0, &$5, 0, 2, IS_A1 ($1));
2212 }
2213 else
2214 return yyerror ("Register mismatch");
2215 }
2216
2217 | REG ASSIGN ROT REG BY HALF_REG
2218 {
2219 if (IS_DREG ($1) && IS_DREG ($4) && IS_DREG_L ($6))
2220 {
2221 notethat ("dsp32shift: dregs = ROT dregs BY dregs_lo\n");
2222 $$ = DSP32SHIFT (2, &$1, &$6, &$4, 3, 0);
2223 }
2224 else
2225 return yyerror ("Register mismatch");
2226 }
2227
2228 | a_assign ROT REG_A BY expr
2229 {
2230 if (IS_IMM ($5, 6))
2231 {
2232 notethat ("dsp32shiftimm: An = ROT An BY imm6\n");
2233 $$ = DSP32SHIFTIMM (3, 0, imm6 ($5), 0, 2, IS_A1 ($1));
2234 }
2235 else
2236 return yyerror ("Register mismatch");
2237 }
2238
2239 | REG ASSIGN ROT REG BY expr
2240 {
2241 if (IS_DREG ($1) && IS_DREG ($4) && IS_IMM ($6, 6))
2242 {
2243 $$ = DSP32SHIFTIMM (2, &$1, imm6 ($6), &$4, 3, IS_A1 ($1));
2244 }
2245 else
2246 return yyerror ("Register mismatch");
2247 }
2248
2249 | HALF_REG ASSIGN SIGNBITS REG_A
2250 {
2251 if (IS_DREG_L ($1))
2252 {
2253 notethat ("dsp32shift: dregs_lo = SIGNBITS An\n");
2254 $$ = DSP32SHIFT (6, &$1, 0, 0, IS_A1 ($4), 0);
2255 }
2256 else
2257 return yyerror ("Register mismatch");
2258 }
2259
2260 | HALF_REG ASSIGN SIGNBITS REG
2261 {
2262 if (IS_DREG_L ($1) && IS_DREG ($4))
2263 {
2264 notethat ("dsp32shift: dregs_lo = SIGNBITS dregs\n");
2265 $$ = DSP32SHIFT (5, &$1, 0, &$4, 0, 0);
2266 }
2267 else
2268 return yyerror ("Register mismatch");
2269 }
2270
2271 | HALF_REG ASSIGN SIGNBITS HALF_REG
2272 {
2273 if (IS_DREG_L ($1))
2274 {
2275 notethat ("dsp32shift: dregs_lo = SIGNBITS dregs_lo\n");
2276 $$ = DSP32SHIFT (5, &$1, 0, &$4, 1 + IS_H ($4), 0);
2277 }
2278 else
2279 return yyerror ("Register mismatch");
2280 }
2281
2282 /* The ASR bit is just inverted here. */
2283 | HALF_REG ASSIGN VIT_MAX LPAREN REG RPAREN asr_asl
2284 {
2285 if (IS_DREG_L ($1) && IS_DREG ($5))
2286 {
2287 notethat ("dsp32shift: dregs_lo = VIT_MAX (dregs) (..)\n");
2288 $$ = DSP32SHIFT (9, &$1, 0, &$5, ($7.r0 ? 0 : 1), 0);
2289 }
2290 else
2291 return yyerror ("Register mismatch");
2292 }
2293
2294 | REG ASSIGN VIT_MAX LPAREN REG COMMA REG RPAREN asr_asl
2295 {
2296 if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7))
2297 {
2298 notethat ("dsp32shift: dregs = VIT_MAX (dregs, dregs) (ASR)\n");
2299 $$ = DSP32SHIFT (9, &$1, &$7, &$5, 2 | ($9.r0 ? 0 : 1), 0);
2300 }
2301 else
2302 return yyerror ("Register mismatch");
2303 }
2304
2305 | BITMUX LPAREN REG COMMA REG COMMA REG_A RPAREN asr_asl
2306 {
2307 if (IS_DREG ($3) && IS_DREG ($5) && !IS_A1 ($7))
2308 {
2309 notethat ("dsp32shift: BITMUX (dregs , dregs , A0) (ASR)\n");
2310 $$ = DSP32SHIFT (8, 0, &$3, &$5, $9.r0, 0);
2311 }
2312 else
2313 return yyerror ("Register mismatch");
2314 }
2315
2316 | a_assign BXORSHIFT LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN
2317 {
2318 if (!IS_A1 ($1) && !IS_A1 ($4) && IS_A1 ($6))
2319 {
2320 notethat ("dsp32shift: A0 = BXORSHIFT (A0 , A1 , CC )\n");
2321 $$ = DSP32SHIFT (12, 0, 0, 0, 0, 0);
2322 }
2323 else
2324 return yyerror ("Dregs expected");
2325 }
2326
2327
2328/* LOGI2op: BITCLR (dregs, uimm5). */
2329 | BITCLR LPAREN REG COMMA expr RPAREN
2330 {
2331 if (IS_DREG ($3) && IS_UIMM ($5, 5))
2332 {
2333 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n");
2334 $$ = LOGI2OP ($3, uimm5 ($5), 4);
2335 }
2336 else
2337 return yyerror ("Register mismatch");
2338 }
2339
2340/* LOGI2op: BITSET (dregs, uimm5). */
2341 | BITSET LPAREN REG COMMA expr RPAREN
2342 {
2343 if (IS_DREG ($3) && IS_UIMM ($5, 5))
2344 {
2345 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n");
2346 $$ = LOGI2OP ($3, uimm5 ($5), 2);
2347 }
2348 else
2349 return yyerror ("Register mismatch");
2350 }
2351
2352/* LOGI2op: BITTGL (dregs, uimm5). */
2353 | BITTGL LPAREN REG COMMA expr RPAREN
2354 {
2355 if (IS_DREG ($3) && IS_UIMM ($5, 5))
2356 {
2357 notethat ("LOGI2op: BITCLR (dregs , uimm5 )\n");
2358 $$ = LOGI2OP ($3, uimm5 ($5), 3);
2359 }
2360 else
2361 return yyerror ("Register mismatch");
2362 }
2363
2364 | CCREG _ASSIGN_BANG BITTST LPAREN REG COMMA expr RPAREN
2365 {
2366 if (IS_DREG ($5) && IS_UIMM ($7, 5))
2367 {
2368 notethat ("LOGI2op: CC =! BITTST (dregs , uimm5 )\n");
2369 $$ = LOGI2OP ($5, uimm5 ($7), 0);
2370 }
2371 else
2372 return yyerror ("Register mismatch or value error");
2373 }
2374
2375 | CCREG ASSIGN BITTST LPAREN REG COMMA expr RPAREN
2376 {
2377 if (IS_DREG ($5) && IS_UIMM ($7, 5))
2378 {
2379 notethat ("LOGI2op: CC = BITTST (dregs , uimm5 )\n");
2380 $$ = LOGI2OP ($5, uimm5 ($7), 1);
2381 }
2382 else
2383 return yyerror ("Register mismatch or value error");
2384 }
2385
2386 | IF BANG CCREG REG ASSIGN REG
2387 {
2388 if ((IS_DREG ($4) || IS_PREG ($4))
2389 && (IS_DREG ($6) || IS_PREG ($6)))
2390 {
2391 notethat ("ccMV: IF ! CC gregs = gregs\n");
2392 $$ = CCMV (&$6, &$4, 0);
2393 }
2394 else
2395 return yyerror ("Register mismatch");
2396 }
2397
2398 | IF CCREG REG ASSIGN REG
2399 {
2400 if ((IS_DREG ($5) || IS_PREG ($5))
2401 && (IS_DREG ($3) || IS_PREG ($3)))
2402 {
2403 notethat ("ccMV: IF CC gregs = gregs\n");
2404 $$ = CCMV (&$5, &$3, 1);
2405 }
2406 else
2407 return yyerror ("Register mismatch");
2408 }
2409
2410 | IF BANG CCREG JUMP expr
2411 {
2412 if (IS_PCREL10 ($5))
2413 {
2414 notethat ("BRCC: IF !CC JUMP pcrel11m2\n");
2415 $$ = BRCC (0, 0, $5);
2416 }
2417 else
2418 return yyerror ("Bad jump offset");
2419 }
2420
2421 | IF BANG CCREG JUMP expr LPAREN BP RPAREN
2422 {
2423 if (IS_PCREL10 ($5))
2424 {
2425 notethat ("BRCC: IF !CC JUMP pcrel11m2\n");
2426 $$ = BRCC (0, 1, $5);
2427 }
2428 else
2429 return yyerror ("Bad jump offset");
2430 }
2431
2432 | IF CCREG JUMP expr
2433 {
2434 if (IS_PCREL10 ($4))
2435 {
2436 notethat ("BRCC: IF CC JUMP pcrel11m2\n");
2437 $$ = BRCC (1, 0, $4);
2438 }
2439 else
2440 return yyerror ("Bad jump offset");
2441 }
2442
2443 | IF CCREG JUMP expr LPAREN BP RPAREN
2444 {
2445 if (IS_PCREL10 ($4))
2446 {
2447 notethat ("BRCC: IF !CC JUMP pcrel11m2\n");
2448 $$ = BRCC (1, 1, $4);
2449 }
2450 else
2451 return yyerror ("Bad jump offset");
2452 }
2453 | NOP
2454 {
2455 notethat ("ProgCtrl: NOP\n");
2456 $$ = PROGCTRL (0, 0);
2457 }
2458
2459 | RTS
2460 {
2461 notethat ("ProgCtrl: RTS\n");
2462 $$ = PROGCTRL (1, 0);
2463 }
2464
2465 | RTI
2466 {
2467 notethat ("ProgCtrl: RTI\n");
2468 $$ = PROGCTRL (1, 1);
2469 }
2470
2471 | RTX
2472 {
2473 notethat ("ProgCtrl: RTX\n");
2474 $$ = PROGCTRL (1, 2);
2475 }
2476
2477 | RTN
2478 {
2479 notethat ("ProgCtrl: RTN\n");
2480 $$ = PROGCTRL (1, 3);
2481 }
2482
2483 | RTE
2484 {
2485 notethat ("ProgCtrl: RTE\n");
2486 $$ = PROGCTRL (1, 4);
2487 }
2488
2489 | IDLE
2490 {
2491 notethat ("ProgCtrl: IDLE\n");
2492 $$ = PROGCTRL (2, 0);
2493 }
2494
2495 | CSYNC
2496 {
2497 notethat ("ProgCtrl: CSYNC\n");
2498 $$ = PROGCTRL (2, 3);
2499 }
2500
2501 | SSYNC
2502 {
2503 notethat ("ProgCtrl: SSYNC\n");
2504 $$ = PROGCTRL (2, 4);
2505 }
2506
2507 | EMUEXCPT
2508 {
2509 notethat ("ProgCtrl: EMUEXCPT\n");
2510 $$ = PROGCTRL (2, 5);
2511 }
2512
2513 | CLI REG
2514 {
2515 if (IS_DREG ($2))
2516 {
2517 notethat ("ProgCtrl: CLI dregs\n");
2518 $$ = PROGCTRL (3, $2.regno & CODE_MASK);
2519 }
2520 else
2521 return yyerror ("Dreg expected for CLI");
2522 }
2523
2524 | STI REG
2525 {
2526 if (IS_DREG ($2))
2527 {
2528 notethat ("ProgCtrl: STI dregs\n");
2529 $$ = PROGCTRL (4, $2.regno & CODE_MASK);
2530 }
2531 else
2532 return yyerror ("Dreg expected for STI");
2533 }
2534
2535 | JUMP LPAREN REG RPAREN
2536 {
2537 if (IS_PREG ($3))
2538 {
2539 notethat ("ProgCtrl: JUMP (pregs )\n");
2540 $$ = PROGCTRL (5, $3.regno & CODE_MASK);
2541 }
2542 else
2543 return yyerror ("Bad register for indirect jump");
2544 }
2545
2546 | CALL LPAREN REG RPAREN
2547 {
2548 if (IS_PREG ($3))
2549 {
2550 notethat ("ProgCtrl: CALL (pregs )\n");
2551 $$ = PROGCTRL (6, $3.regno & CODE_MASK);
2552 }
2553 else
2554 return yyerror ("Bad register for indirect call");
2555 }
2556
2557 | CALL LPAREN PC PLUS REG RPAREN
2558 {
2559 if (IS_PREG ($5))
2560 {
2561 notethat ("ProgCtrl: CALL (PC + pregs )\n");
2562 $$ = PROGCTRL (7, $5.regno & CODE_MASK);
2563 }
2564 else
2565 return yyerror ("Bad register for indirect call");
2566 }
2567
2568 | JUMP LPAREN PC PLUS REG RPAREN
2569 {
2570 if (IS_PREG ($5))
2571 {
2572 notethat ("ProgCtrl: JUMP (PC + pregs )\n");
2573 $$ = PROGCTRL (8, $5.regno & CODE_MASK);
2574 }
2575 else
2576 return yyerror ("Bad register for indirect jump");
2577 }
2578
2579 | RAISE expr
2580 {
2581 if (IS_UIMM ($2, 4))
2582 {
2583 notethat ("ProgCtrl: RAISE uimm4\n");
2584 $$ = PROGCTRL (9, uimm4 ($2));
2585 }
2586 else
2587 return yyerror ("Bad value for RAISE");
2588 }
2589
2590 | EXCPT expr
2591 {
2592 notethat ("ProgCtrl: EMUEXCPT\n");
2593 $$ = PROGCTRL (10, uimm4 ($2));
2594 }
2595
2596 | TESTSET LPAREN REG RPAREN
2597 {
2598 if (IS_PREG ($3))
2599 {
2600 notethat ("ProgCtrl: TESTSET (pregs )\n");
2601 $$ = PROGCTRL (11, $3.regno & CODE_MASK);
2602 }
2603 else
2604 return yyerror ("Preg expected");
2605 }
2606
2607 | JUMP expr
2608 {
2609 if (IS_PCREL12 ($2))
2610 {
2611 notethat ("UJUMP: JUMP pcrel12\n");
2612 $$ = UJUMP ($2);
2613 }
2614 else
2615 return yyerror ("Bad value for relative jump");
2616 }
2617
2618 | JUMP_DOT_S expr
2619 {
2620 if (IS_PCREL12 ($2))
2621 {
2622 notethat ("UJUMP: JUMP_DOT_S pcrel12\n");
2623 $$ = UJUMP($2);
2624 }
2625 else
2626 return yyerror ("Bad value for relative jump");
2627 }
2628
2629 | JUMP_DOT_L expr
2630 {
2631 if (IS_PCREL24 ($2))
2632 {
2633 notethat ("CALLa: jump.l pcrel24\n");
2634 $$ = CALLA ($2, 0);
2635 }
2636 else
2637 return yyerror ("Bad value for long jump");
2638 }
2639
2640 | JUMP_DOT_L pltpc
2641 {
2642 if (IS_PCREL24 ($2))
2643 {
2644 notethat ("CALLa: jump.l pcrel24\n");
2645 $$ = CALLA ($2, 2);
2646 }
2647 else
2648 return yyerror ("Bad value for long jump");
2649 }
2650
2651 | CALL expr
2652 {
2653 if (IS_PCREL24 ($2))
2654 {
2655 notethat ("CALLa: CALL pcrel25m2\n");
2656 $$ = CALLA ($2, 1);
2657 }
2658 else
2659 return yyerror ("Bad call address");
2660 }
2661 | CALL pltpc
2662 {
2663 if (IS_PCREL24 ($2))
2664 {
2665 notethat ("CALLa: CALL pcrel25m2\n");
2666 $$ = CALLA ($2, 2);
2667 }
2668 else
2669 return yyerror ("Bad call address");
2670 }
2671
2672/* ALU2ops. */
2673/* ALU2op: DIVQ (dregs, dregs). */
2674 | DIVQ LPAREN REG COMMA REG RPAREN
2675 {
2676 if (IS_DREG ($3) && IS_DREG ($5))
2677 $$ = ALU2OP (&$3, &$5, 8);
2678 else
2679 return yyerror ("Bad registers for DIVQ");
2680 }
2681
2682 | DIVS LPAREN REG COMMA REG RPAREN
2683 {
2684 if (IS_DREG ($3) && IS_DREG ($5))
2685 $$ = ALU2OP (&$3, &$5, 9);
2686 else
2687 return yyerror ("Bad registers for DIVS");
2688 }
2689
2690 | REG ASSIGN MINUS REG vsmod
2691 {
2692 if (IS_DREG ($1) && IS_DREG ($4))
2693 {
2694 if ($5.r0 == 0 && $5.s0 == 0 && $5.aop == 0)
2695 {
2696 notethat ("ALU2op: dregs = - dregs\n");
2697 $$ = ALU2OP (&$1, &$4, 14);
2698 }
2699 else if ($5.r0 == 1 && $5.s0 == 0 && $5.aop == 3)
2700 {
2701 notethat ("dsp32alu: dregs = - dregs (.)\n");
2702 $$ = DSP32ALU (15, 0, 0, &$1, &$4, 0, $5.s0, 0, 3);
2703 }
2704 else
2705 {
2706 notethat ("dsp32alu: dregs = - dregs (.)\n");
2707 $$ = DSP32ALU (7, 0, 0, &$1, &$4, 0, $5.s0, 0, 3);
2708 }
2709 }
2710 else
2711 return yyerror ("Dregs expected");
2712 }
2713
2714 | REG ASSIGN TILDA REG
2715 {
2716 if (IS_DREG ($1) && IS_DREG ($4))
2717 {
2718 notethat ("ALU2op: dregs = ~dregs\n");
2719 $$ = ALU2OP (&$1, &$4, 15);
2720 }
2721 else
2722 return yyerror ("Dregs expected");
2723 }
2724
2725 | REG _GREATER_GREATER_ASSIGN REG
2726 {
2727 if (IS_DREG ($1) && IS_DREG ($3))
2728 {
2729 notethat ("ALU2op: dregs >>= dregs\n");
2730 $$ = ALU2OP (&$1, &$3, 1);
2731 }
2732 else
2733 return yyerror ("Dregs expected");
2734 }
2735
2736 | REG _GREATER_GREATER_ASSIGN expr
2737 {
2738 if (IS_DREG ($1) && IS_UIMM ($3, 5))
2739 {
2740 notethat ("LOGI2op: dregs >>= uimm5\n");
2741 $$ = LOGI2OP ($1, uimm5 ($3), 6);
2742 }
2743 else
2744 return yyerror ("Dregs expected or value error");
2745 }
2746
2747 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN REG
2748 {
2749 if (IS_DREG ($1) && IS_DREG ($3))
2750 {
2751 notethat ("ALU2op: dregs >>>= dregs\n");
2752 $$ = ALU2OP (&$1, &$3, 0);
2753 }
2754 else
2755 return yyerror ("Dregs expected");
2756 }
2757
2758 | REG _LESS_LESS_ASSIGN REG
2759 {
2760 if (IS_DREG ($1) && IS_DREG ($3))
2761 {
2762 notethat ("ALU2op: dregs <<= dregs\n");
2763 $$ = ALU2OP (&$1, &$3, 2);
2764 }
2765 else
2766 return yyerror ("Dregs expected");
2767 }
2768
2769 | REG _LESS_LESS_ASSIGN expr
2770 {
2771 if (IS_DREG ($1) && IS_UIMM ($3, 5))
2772 {
2773 notethat ("LOGI2op: dregs <<= uimm5\n");
2774 $$ = LOGI2OP ($1, uimm5 ($3), 7);
2775 }
2776 else
2777 return yyerror ("Dregs expected or const value error");
2778 }
2779
2780
2781 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN expr
2782 {
2783 if (IS_DREG ($1) && IS_UIMM ($3, 5))
2784 {
2785 notethat ("LOGI2op: dregs >>>= uimm5\n");
2786 $$ = LOGI2OP ($1, uimm5 ($3), 5);
2787 }
2788 else
2789 return yyerror ("Dregs expected");
2790 }
2791
2792/* Cache Control. */
2793
2794 | FLUSH LBRACK REG RBRACK
2795 {
2796 notethat ("CaCTRL: FLUSH [ pregs ]\n");
2797 if (IS_PREG ($3))
2798 $$ = CACTRL (&$3, 0, 2);
2799 else
2800 return yyerror ("Bad register(s) for FLUSH");
2801 }
2802
2803 | FLUSH reg_with_postinc
2804 {
2805 if (IS_PREG ($2))
2806 {
2807 notethat ("CaCTRL: FLUSH [ pregs ++ ]\n");
2808 $$ = CACTRL (&$2, 1, 2);
2809 }
2810 else
2811 return yyerror ("Bad register(s) for FLUSH");
2812 }
2813
2814 | FLUSHINV LBRACK REG RBRACK
2815 {
2816 if (IS_PREG ($3))
2817 {
2818 notethat ("CaCTRL: FLUSHINV [ pregs ]\n");
2819 $$ = CACTRL (&$3, 0, 1);
2820 }
2821 else
2822 return yyerror ("Bad register(s) for FLUSH");
2823 }
2824
2825 | FLUSHINV reg_with_postinc
2826 {
2827 if (IS_PREG ($2))
2828 {
2829 notethat ("CaCTRL: FLUSHINV [ pregs ++ ]\n");
2830 $$ = CACTRL (&$2, 1, 1);
2831 }
2832 else
2833 return yyerror ("Bad register(s) for FLUSH");
2834 }
2835
2836/* CaCTRL: IFLUSH [pregs]. */
2837 | IFLUSH LBRACK REG RBRACK
2838 {
2839 if (IS_PREG ($3))
2840 {
2841 notethat ("CaCTRL: IFLUSH [ pregs ]\n");
2842 $$ = CACTRL (&$3, 0, 3);
2843 }
2844 else
2845 return yyerror ("Bad register(s) for FLUSH");
2846 }
2847
2848 | IFLUSH reg_with_postinc
2849 {
2850 if (IS_PREG ($2))
2851 {
2852 notethat ("CaCTRL: IFLUSH [ pregs ++ ]\n");
2853 $$ = CACTRL (&$2, 1, 3);
2854 }
2855 else
2856 return yyerror ("Bad register(s) for FLUSH");
2857 }
2858
2859 | PREFETCH LBRACK REG RBRACK
2860 {
2861 if (IS_PREG ($3))
2862 {
2863 notethat ("CaCTRL: PREFETCH [ pregs ]\n");
2864 $$ = CACTRL (&$3, 0, 0);
2865 }
2866 else
2867 return yyerror ("Bad register(s) for PREFETCH");
2868 }
2869
2870 | PREFETCH reg_with_postinc
2871 {
2872 if (IS_PREG ($2))
2873 {
2874 notethat ("CaCTRL: PREFETCH [ pregs ++ ]\n");
2875 $$ = CACTRL (&$2, 1, 0);
2876 }
2877 else
2878 return yyerror ("Bad register(s) for PREFETCH");
2879 }
2880
2881/* LOAD/STORE. */
2882/* LDST: B [ pregs <post_op> ] = dregs. */
2883
2884 | B LBRACK REG post_op RBRACK ASSIGN REG
2885 {
2886 if (IS_PREG ($3) && IS_DREG ($7))
2887 {
2888 notethat ("LDST: B [ pregs <post_op> ] = dregs\n");
2889 $$ = LDST (&$3, &$7, $4.x0, 2, 0, 1);
2890 }
2891 else
2892 return yyerror ("Register mismatch");
2893 }
2894
2895/* LDSTidxI: B [ pregs + imm16 ] = dregs. */
2896 | B LBRACK REG plus_minus expr RBRACK ASSIGN REG
2897 {
2898 if (IS_PREG ($3) && IS_RANGE(16, $5, $4.r0, 1) && IS_DREG ($8))
2899 {
2900 notethat ("LDST: B [ pregs + imm16 ] = dregs\n");
2901 if ($4.r0)
2902 neg_value ($5);
2903 $$ = LDSTIDXI (&$3, &$8, 1, 2, 0, $5);
2904 }
2905 else
2906 return yyerror ("Register mismatch or const size wrong");
2907 }
2908
2909
2910/* LDSTii: W [ pregs + uimm4s2 ] = dregs. */
2911 | W LBRACK REG plus_minus expr RBRACK ASSIGN REG
2912 {
2913 if (IS_PREG ($3) && IS_URANGE (4, $5, $4.r0, 2) && IS_DREG ($8))
2914 {
2915 notethat ("LDSTii: W [ pregs +- uimm5m2 ] = dregs\n");
2916 $$ = LDSTII (&$3, &$8, $5, 1, 1);
2917 }
2918 else if (IS_PREG ($3) && IS_RANGE(16, $5, $4.r0, 2) && IS_DREG ($8))
2919 {
2920 notethat ("LDSTidxI: W [ pregs + imm17m2 ] = dregs\n");
2921 if ($4.r0)
2922 neg_value ($5);
2923 $$ = LDSTIDXI (&$3, &$8, 1, 1, 0, $5);
2924 }
2925 else
2926 return yyerror ("Bad register(s) or wrong constant size");
2927 }
2928
2929/* LDST: W [ pregs <post_op> ] = dregs. */
2930 | W LBRACK REG post_op RBRACK ASSIGN REG
2931 {
2932 if (IS_PREG ($3) && IS_DREG ($7))
2933 {
2934 notethat ("LDST: W [ pregs <post_op> ] = dregs\n");
2935 $$ = LDST (&$3, &$7, $4.x0, 1, 0, 1);
2936 }
2937 else
2938 return yyerror ("Bad register(s) for STORE");
2939 }
2940
2941 | W LBRACK REG post_op RBRACK ASSIGN HALF_REG
2942 {
2943 if (IS_IREG ($3))
2944 {
2945 notethat ("dspLDST: W [ iregs <post_op> ] = dregs_half\n");
2946 $$ = DSPLDST (&$3, 1 + IS_H ($7), &$7, $4.x0, 1);
2947 }
2948 else if ($4.x0 == 2 && IS_PREG ($3) && IS_DREG ($7))
2949 {
2950 notethat ("LDSTpmod: W [ pregs <post_op>] = dregs_half\n");
2951 $$ = LDSTPMOD (&$3, &$7, &$3, 1 + IS_H ($7), 1);
2952
2953 }
2954 else
2955 return yyerror ("Bad register(s) for STORE");
2956 }
2957
2958/* LDSTiiFP: [ FP - const ] = dpregs. */
2959 | LBRACK REG plus_minus expr RBRACK ASSIGN REG
2960 {
2961 Expr_Node *tmp = $4;
2962 int ispreg = IS_PREG ($7);
2963
2964 if (!IS_PREG ($2))
2965 return yyerror ("Preg expected for indirect");
2966
2967 if (!IS_DREG ($7) && !ispreg)
2968 return yyerror ("Bad source register for STORE");
2969
2970 if ($3.r0)
2971 tmp = unary (Expr_Op_Type_NEG, tmp);
2972
2973 if (in_range_p (tmp, 0, 63, 3))
2974 {
2975 notethat ("LDSTii: dpregs = [ pregs + uimm6m4 ]\n");
2976 $$ = LDSTII (&$2, &$7, tmp, 1, ispreg ? 3 : 0);
2977 }
2978 else if ($2.regno == REG_FP && in_range_p (tmp, -128, 0, 3))
2979 {
2980 notethat ("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n");
2981 tmp = unary (Expr_Op_Type_NEG, tmp);
2982 $$ = LDSTIIFP (tmp, &$7, 1);
2983 }
2984 else if (in_range_p (tmp, -131072, 131071, 3))
2985 {
2986 notethat ("LDSTidxI: [ pregs + imm18m4 ] = dpregs\n");
2987 $$ = LDSTIDXI (&$2, &$7, 1, 0, ispreg ? 1: 0, tmp);
2988 }
2989 else
2990 return yyerror ("Displacement out of range for store");
2991 }
2992
2993 | REG ASSIGN W LBRACK REG plus_minus expr RBRACK xpmod
2994 {
2995 if (IS_DREG ($1) && IS_PREG ($5) && IS_URANGE (4, $7, $6.r0, 2))
2996 {
2997 notethat ("LDSTii: dregs = W [ pregs + uimm4s2 ] (.)\n");
2998 $$ = LDSTII (&$5, &$1, $7, 0, 1 << $9.r0);
2999 }
3000 else if (IS_DREG ($1) && IS_PREG ($5) && IS_RANGE(16, $7, $6.r0, 2))
3001 {
3002 notethat ("LDSTidxI: dregs = W [ pregs + imm17m2 ] (.)\n");
3003 if ($6.r0)
3004 neg_value ($7);
3005 $$ = LDSTIDXI (&$5, &$1, 0, 1, $9.r0, $7);
3006 }
3007 else
3008 return yyerror ("Bad register or constant for LOAD");
3009 }
3010
3011 | HALF_REG ASSIGN W LBRACK REG post_op RBRACK
3012 {
3013 if (IS_IREG ($5))
3014 {
3015 notethat ("dspLDST: dregs_half = W [ iregs ]\n");
3016 $$ = DSPLDST(&$5, 1 + IS_H ($1), &$1, $6.x0, 0);
3017 }
3018 else if ($6.x0 == 2 && IS_DREG ($1) && IS_PREG ($5))
3019 {
3020 notethat ("LDSTpmod: dregs_half = W [ pregs ]\n");
3021 $$ = LDSTPMOD (&$5, &$1, &$5, 1 + IS_H ($1), 0);
3022 }
3023 else
3024 return yyerror ("Bad register or post_op for LOAD");
3025 }
3026
3027
3028 | REG ASSIGN W LBRACK REG post_op RBRACK xpmod
3029 {
3030 if (IS_DREG ($1) && IS_PREG ($5))
3031 {
3032 notethat ("LDST: dregs = W [ pregs <post_op> ] (.)\n");
3033 $$ = LDST (&$5, &$1, $6.x0, 1, $8.r0, 0);
3034 }
3035 else
3036 return yyerror ("Bad register for LOAD");
3037 }
3038
3039 | REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK xpmod
3040 {
3041 if (IS_DREG ($1) && IS_PREG ($5) && IS_PREG ($7))
3042 {
3043 notethat ("LDSTpmod: dregs = W [ pregs ++ pregs ] (.)\n");
3044 $$ = LDSTPMOD (&$5, &$1, &$7, 3, $9.r0);
3045 }
3046 else
3047 return yyerror ("Bad register for LOAD");
3048 }
3049
3050 | HALF_REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK
3051 {
3052 if (IS_DREG ($1) && IS_PREG ($5) && IS_PREG ($7))
3053 {
3054 notethat ("LDSTpmod: dregs_half = W [ pregs ++ pregs ]\n");
3055 $$ = LDSTPMOD (&$5, &$1, &$7, 1 + IS_H ($1), 0);
3056 }
3057 else
3058 return yyerror ("Bad register for LOAD");
3059 }
3060
3061 | LBRACK REG post_op RBRACK ASSIGN REG
3062 {
3063 if (IS_IREG ($2) && IS_DREG ($6))
3064 {
3065 notethat ("dspLDST: [ iregs <post_op> ] = dregs\n");
3066 $$ = DSPLDST(&$2, 0, &$6, $3.x0, 1);
3067 }
3068 else if (IS_PREG ($2) && IS_DREG ($6))
3069 {
3070 notethat ("LDST: [ pregs <post_op> ] = dregs\n");
3071 $$ = LDST (&$2, &$6, $3.x0, 0, 0, 1);
3072 }
3073 else if (IS_PREG ($2) && IS_PREG ($6))
3074 {
3075 notethat ("LDST: [ pregs <post_op> ] = pregs\n");
3076 $$ = LDST (&$2, &$6, $3.x0, 0, 1, 1);
3077 }
3078 else
3079 return yyerror ("Bad register for STORE");
3080 }
3081
3082 | LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN REG
3083 {
3084 if (! IS_DREG ($7))
3085 return yyerror ("Expected Dreg for last argument");
3086
3087 if (IS_IREG ($2) && IS_MREG ($4))
3088 {
3089 notethat ("dspLDST: [ iregs ++ mregs ] = dregs\n");
3090 $$ = DSPLDST(&$2, $4.regno & CODE_MASK, &$7, 3, 1);
3091 }
3092 else if (IS_PREG ($2) && IS_PREG ($4))
3093 {
3094 notethat ("LDSTpmod: [ pregs ++ pregs ] = dregs\n");
3095 $$ = LDSTPMOD (&$2, &$7, &$4, 0, 1);
3096 }
3097 else
3098 return yyerror ("Bad register for STORE");
3099 }
3100
3101 | W LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN HALF_REG
3102 {
3103 if (!IS_DREG ($8))
3104 return yyerror ("Expect Dreg as last argument");
3105 if (IS_PREG ($3) && IS_PREG ($5))
3106 {
3107 notethat ("LDSTpmod: W [ pregs ++ pregs ] = dregs_half\n");
3108 $$ = LDSTPMOD (&$3, &$8, &$5, 1 + IS_H ($8), 1);
3109 }
3110 else
3111 return yyerror ("Bad register for STORE");
3112 }
3113
3114 | REG ASSIGN B LBRACK REG plus_minus expr RBRACK xpmod
3115 {
3116 if (IS_DREG ($1) && IS_PREG ($5) && IS_RANGE(16, $7, $6.r0, 1))
3117 {
3118 notethat ("LDSTidxI: dregs = B [ pregs + imm16 ] (%c)\n",
3119 $9.r0 ? 'X' : 'Z');
3120 if ($6.r0)
3121 neg_value ($7);
3122 $$ = LDSTIDXI (&$5, &$1, 0, 2, $9.r0, $7);
3123 }
3124 else
3125 return yyerror ("Bad register or value for LOAD");
3126 }
3127
3128 | REG ASSIGN B LBRACK REG post_op RBRACK xpmod
3129 {
3130 if (IS_DREG ($1) && IS_PREG ($5))
3131 {
3132 notethat ("LDST: dregs = B [ pregs <post_op> ] (%c)\n",
3133 $8.r0 ? 'X' : 'Z');
3134 $$ = LDST (&$5, &$1, $6.x0, 2, $8.r0, 0);
3135 }
3136 else
3137 return yyerror ("Bad register for LOAD");
3138 }
3139
3140 | REG ASSIGN LBRACK REG _PLUS_PLUS REG RBRACK
3141 {
3142 if (IS_DREG ($1) && IS_IREG ($4) && IS_MREG ($6))
3143 {
3144 notethat ("dspLDST: dregs = [ iregs ++ mregs ]\n");
3145 $$ = DSPLDST(&$4, $6.regno & CODE_MASK, &$1, 3, 0);
3146 }
3147 else if (IS_DREG ($1) && IS_PREG ($4) && IS_PREG ($6))
3148 {
3149 notethat ("LDSTpmod: dregs = [ pregs ++ pregs ]\n");
3150 $$ = LDSTPMOD (&$4, &$1, &$6, 0, 0);
3151 }
3152 else
3153 return yyerror ("Bad register for LOAD");
3154 }
3155
3156 | REG ASSIGN LBRACK REG plus_minus got_or_expr RBRACK
3157 {
3158 Expr_Node *tmp = $6;
3159 int ispreg = IS_PREG ($1);
3160 int isgot = IS_RELOC($6);
3161
3162 if (!IS_PREG ($4))
3163 return yyerror ("Preg expected for indirect");
3164
3165 if (!IS_DREG ($1) && !ispreg)
3166 return yyerror ("Bad destination register for LOAD");
3167
3168 if ($5.r0)
3169 tmp = unary (Expr_Op_Type_NEG, tmp);
3170
3171 if(isgot){
3172 notethat ("LDSTidxI: dpregs = [ pregs + sym@got ]\n");
3173 $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1: 0, tmp);
3174 }
3175 else if (in_range_p (tmp, 0, 63, 3))
3176 {
3177 notethat ("LDSTii: dpregs = [ pregs + uimm7m4 ]\n");
3178 $$ = LDSTII (&$4, &$1, tmp, 0, ispreg ? 3 : 0);
3179 }
3180 else if ($4.regno == REG_FP && in_range_p (tmp, -128, 0, 3))
3181 {
3182 notethat ("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n");
3183 tmp = unary (Expr_Op_Type_NEG, tmp);
3184 $$ = LDSTIIFP (tmp, &$1, 0);
3185 }
3186 else if (in_range_p (tmp, -131072, 131071, 3))
3187 {
3188 notethat ("LDSTidxI: dpregs = [ pregs + imm18m4 ]\n");
3189 $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1: 0, tmp);
3190
3191 }
3192 else
3193 return yyerror ("Displacement out of range for load");
3194 }
3195
3196 | REG ASSIGN LBRACK REG post_op RBRACK
3197 {
3198 if (IS_DREG ($1) && IS_IREG ($4))
3199 {
3200 notethat ("dspLDST: dregs = [ iregs <post_op> ]\n");
3201 $$ = DSPLDST (&$4, 0, &$1, $5.x0, 0);
3202 }
3203 else if (IS_DREG ($1) && IS_PREG ($4))
3204 {
3205 notethat ("LDST: dregs = [ pregs <post_op> ]\n");
3206 $$ = LDST (&$4, &$1, $5.x0, 0, 0, 0);
3207 }
3208 else if (IS_PREG ($1) && IS_PREG ($4))
3209 {
3210 if (REG_SAME ($1, $4) && $5.x0 != 2)
3211 return yyerror ("Pregs can't be same");
3212
3213 notethat ("LDST: pregs = [ pregs <post_op> ]\n");
3214 $$ = LDST (&$4, &$1, $5.x0, 0, 1, 0);
3215 }
3216 else if ($4.regno == REG_SP && IS_ALLREG ($1) && $5.x0 == 0)
3217 {
3218 notethat ("PushPopReg: allregs = [ SP ++ ]\n");
3219 $$ = PUSHPOPREG (&$1, 0);
3220 }
3221 else
3222 return yyerror ("Bad register or value");
3223 }
3224
3225
07c1b327
CM
3226/* PushPopMultiple. */
3227 | reg_with_predec ASSIGN LPAREN REG COLON expr COMMA REG COLON expr RPAREN
3228 {
3229 if ($1.regno != REG_SP)
3230 yyerror ("Stack Pointer expected");
3231 if ($4.regno == REG_R7
3232 && IN_RANGE ($6, 0, 7)
3233 && $8.regno == REG_P5
3234 && IN_RANGE ($10, 0, 5))
3235 {
3236 notethat ("PushPopMultiple: [ -- SP ] = (R7 : reglim , P5 : reglim )\n");
3237 $$ = PUSHPOPMULTIPLE (imm5 ($6), imm5 ($10), 1, 1, 1);
3238 }
3239 else
3240 return yyerror ("Bad register for PushPopMultiple");
3241 }
3242
3243 | reg_with_predec ASSIGN LPAREN REG COLON expr RPAREN
3244 {
3245 if ($1.regno != REG_SP)
3246 yyerror ("Stack Pointer expected");
3247
3248 if ($4.regno == REG_R7 && IN_RANGE ($6, 0, 7))
3249 {
3250 notethat ("PushPopMultiple: [ -- SP ] = (R7 : reglim )\n");
3251 $$ = PUSHPOPMULTIPLE (imm5 ($6), 0, 1, 0, 1);
3252 }
3253 else if ($4.regno == REG_P5 && IN_RANGE ($6, 0, 6))
3254 {
3255 notethat ("PushPopMultiple: [ -- SP ] = (P5 : reglim )\n");
3256 $$ = PUSHPOPMULTIPLE (0, imm5 ($6), 0, 1, 1);
3257 }
3258 else
3259 return yyerror ("Bad register for PushPopMultiple");
3260 }
3261
3262 | LPAREN REG COLON expr COMMA REG COLON expr RPAREN ASSIGN reg_with_postinc
3263 {
3264 if ($11.regno != REG_SP)
3265 yyerror ("Stack Pointer expected");
3266 if ($2.regno == REG_R7 && (IN_RANGE ($4, 0, 7))
3267 && $6.regno == REG_P5 && (IN_RANGE ($8, 0, 6)))
3268 {
3269 notethat ("PushPopMultiple: (R7 : reglim , P5 : reglim ) = [ SP ++ ]\n");
3270 $$ = PUSHPOPMULTIPLE (imm5 ($4), imm5 ($8), 1, 1, 0);
3271 }
3272 else
3273 return yyerror ("Bad register range for PushPopMultiple");
3274 }
3275
3276 | LPAREN REG COLON expr RPAREN ASSIGN reg_with_postinc
3277 {
3278 if ($7.regno != REG_SP)
3279 yyerror ("Stack Pointer expected");
3280
3281 if ($2.regno == REG_R7 && IN_RANGE ($4, 0, 7))
3282 {
3283 notethat ("PushPopMultiple: (R7 : reglim ) = [ SP ++ ]\n");
3284 $$ = PUSHPOPMULTIPLE (imm5 ($4), 0, 1, 0, 0);
3285 }
3286 else if ($2.regno == REG_P5 && IN_RANGE ($4, 0, 6))
3287 {
3288 notethat ("PushPopMultiple: (P5 : reglim ) = [ SP ++ ]\n");
3289 $$ = PUSHPOPMULTIPLE (0, imm5 ($4), 0, 1, 0);
3290 }
3291 else
3292 return yyerror ("Bad register range for PushPopMultiple");
3293 }
3294
3295 | reg_with_predec ASSIGN REG
3296 {
3297 if ($1.regno != REG_SP)
3298 yyerror ("Stack Pointer expected");
3299
3300 if (IS_ALLREG ($3))
3301 {
3302 notethat ("PushPopReg: [ -- SP ] = allregs\n");
3303 $$ = PUSHPOPREG (&$3, 1);
3304 }
3305 else
3306 return yyerror ("Bad register for PushPopReg");
3307 }
3308
3309/* Linkage. */
3310
3311 | LINK expr
3312 {
3313 if (IS_URANGE (16, $2, 0, 4))
3314 $$ = LINKAGE (0, uimm16s4 ($2));
3315 else
3316 return yyerror ("Bad constant for LINK");
3317 }
3318
3319 | UNLINK
3320 {
3321 notethat ("linkage: UNLINK\n");
3322 $$ = LINKAGE (1, 0);
3323 }
3324
3325
3326/* LSETUP. */
3327
3328 | LSETUP LPAREN expr COMMA expr RPAREN REG
3329 {
3330 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5) && IS_CREG ($7))
3331 {
3332 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters\n");
3333 $$ = LOOPSETUP ($3, &$7, 0, $5, 0);
3334 }
3335 else
3336 return yyerror ("Bad register or values for LSETUP");
3337
3338 }
3339 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG
3340 {
3341 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5)
3342 && IS_PREG ($9) && IS_CREG ($7))
3343 {
3344 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs\n");
3345 $$ = LOOPSETUP ($3, &$7, 1, $5, &$9);
3346 }
3347 else
3348 return yyerror ("Bad register or values for LSETUP");
3349 }
3350
3351 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG GREATER_GREATER expr
3352 {
3353 if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5)
3354 && IS_PREG ($9) && IS_CREG ($7)
3355 && EXPR_VALUE ($11) == 1)
3356 {
3357 notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs >> 1\n");
3358 $$ = LOOPSETUP ($3, &$7, 3, $5, &$9);
3359 }
3360 else
3361 return yyerror ("Bad register or values for LSETUP");
3362 }
3363
3364/* LOOP. */
3365 | LOOP expr REG
3366 {
3367 if (!IS_RELOC ($2))
3368 return yyerror ("Invalid expression in loop statement");
3369 if (!IS_CREG ($3))
3370 return yyerror ("Invalid loop counter register");
3371 $$ = bfin_gen_loop ($2, &$3, 0, 0);
3372 }
3373 | LOOP expr REG ASSIGN REG
3374 {
3375 if (IS_RELOC ($2) && IS_PREG ($5) && IS_CREG ($3))
3376 {
3377 notethat ("Loop: LOOP expr counters = pregs\n");
3378 $$ = bfin_gen_loop ($2, &$3, 1, &$5);
3379 }
3380 else
3381 return yyerror ("Bad register or values for LOOP");
3382 }
3383 | LOOP expr REG ASSIGN REG GREATER_GREATER expr
3384 {
3385 if (IS_RELOC ($2) && IS_PREG ($5) && IS_CREG ($3) && EXPR_VALUE ($7) == 1)
3386 {
3387 notethat ("Loop: LOOP expr counters = pregs >> 1\n");
3388 $$ = bfin_gen_loop ($2, &$3, 3, &$5);
3389 }
3390 else
3391 return yyerror ("Bad register or values for LOOP");
3392 }
3393/* pseudoDEBUG. */
3394
3395 | DBG
3396 {
3397 notethat ("pseudoDEBUG: DBG\n");
3398 $$ = bfin_gen_pseudodbg (3, 7, 0);
3399 }
3400 | DBG REG_A
3401 {
3402 notethat ("pseudoDEBUG: DBG REG_A\n");
3403 $$ = bfin_gen_pseudodbg (3, IS_A1 ($2), 0);
3404 }
3405 | DBG REG
3406 {
3407 notethat ("pseudoDEBUG: DBG allregs\n");
3408 $$ = bfin_gen_pseudodbg (0, $2.regno & CODE_MASK, $2.regno & CLASS_MASK);
3409 }
3410
3411 | DBGCMPLX LPAREN REG RPAREN
3412 {
3413 if (!IS_DREG ($3))
3414 return yyerror ("Dregs expected");
3415 notethat ("pseudoDEBUG: DBGCMPLX (dregs )\n");
3416 $$ = bfin_gen_pseudodbg (3, 6, $3.regno & CODE_MASK);
3417 }
3418
3419 | DBGHALT
3420 {
3421 notethat ("psedoDEBUG: DBGHALT\n");
3422 $$ = bfin_gen_pseudodbg (3, 5, 0);
3423 }
3424
3425 | DBGA LPAREN HALF_REG COMMA expr RPAREN
3426 {
3427 notethat ("pseudodbg_assert: DBGA (dregs_lo , uimm16 )\n");
3428 $$ = bfin_gen_pseudodbg_assert (IS_H ($3), &$3, uimm16 ($5));
3429 }
3430
3431 | DBGAH LPAREN REG COMMA expr RPAREN
3432 {
3433 notethat ("pseudodbg_assert: DBGAH (dregs , uimm16 )\n");
3434 $$ = bfin_gen_pseudodbg_assert (3, &$3, uimm16 ($5));
3435 }
3436
3437 | DBGAL LPAREN REG COMMA expr RPAREN
3438 {
3439 notethat ("psedodbg_assert: DBGAL (dregs , uimm16 )\n");
3440 $$ = bfin_gen_pseudodbg_assert (2, &$3, uimm16 ($5));
3441 }
3442
3443
3444;
3445
3446/* AUX RULES. */
3447
3448/* Register rules. */
3449
3450REG_A: REG_A_DOUBLE_ZERO
3451 {
3452 $$ = $1;
3453 }
3454 | REG_A_DOUBLE_ONE
3455 {
3456 $$ = $1;
3457 }
3458 ;
3459
3460
3461/* Modifiers. */
3462
3463opt_mode:
3464 {
3465 $$.MM = 0;
3466 $$.mod = 0;
3467 }
3468 | LPAREN M COMMA MMOD RPAREN
3469 {
3470 $$.MM = 1;
3471 $$.mod = $4;
3472 }
3473 | LPAREN MMOD COMMA M RPAREN
3474 {
3475 $$.MM = 1;
3476 $$.mod = $2;
3477 }
3478 | LPAREN MMOD RPAREN
3479 {
3480 $$.MM = 0;
3481 $$.mod = $2;
3482 }
3483 | LPAREN M RPAREN
3484 {
3485 $$.MM = 1;
3486 $$.mod = 0;
3487 }
3488 ;
3489
3490asr_asl: LPAREN ASL RPAREN
3491 {
3492 $$.r0 = 1;
3493 }
3494 | LPAREN ASR RPAREN
3495 {
3496 $$.r0 = 0;
3497 }
3498 ;
3499
3500sco:
3501 {
3502 $$.s0 = 0;
3503 $$.x0 = 0;
3504 }
3505 | S
3506 {
3507 $$.s0 = 1;
3508 $$.x0 = 0;
3509 }
3510 | CO
3511 {
3512 $$.s0 = 0;
3513 $$.x0 = 1;
3514 }
3515 | SCO
3516 {
3517 $$.s0 = 1;
3518 $$.x0 = 1;
3519 }
3520 ;
3521
3522asr_asl_0:
3523 ASL
3524 {
3525 $$.r0 = 1;
3526 }
3527 | ASR
3528 {
3529 $$.r0 = 0;
3530 }
3531 ;
3532
3533amod0:
3534 {
3535 $$.s0 = 0;
3536 $$.x0 = 0;
3537 }
3538 | LPAREN sco RPAREN
3539 {
3540 $$.s0 = $2.s0;
3541 $$.x0 = $2.x0;
3542 }
3543 ;
3544
3545amod1:
3546 {
3547 $$.s0 = 0;
3548 $$.x0 = 0;
3549 $$.aop = 0;
3550 }
3551 | LPAREN NS RPAREN
3552 {
3553 $$.s0 = 0;
3554 $$.x0 = 0;
3555 $$.aop = 1;
3556 }
3557 | LPAREN S RPAREN
3558 {
3559 $$.s0 = 1;
3560 $$.x0 = 0;
3561 $$.aop = 1;
3562 }
3563 ;
3564
3565amod2:
3566 {
3567 $$.r0 = 0;
3568 $$.s0 = 0;
3569 $$.x0 = 0;
3570 }
3571 | LPAREN asr_asl_0 RPAREN
3572 {
3573 $$.r0 = 2 + $2.r0;
3574 $$.s0 = 0;
3575 $$.x0 = 0;
3576 }
3577 | LPAREN sco RPAREN
3578 {
3579 $$.r0 = 0;
3580 $$.s0 = $2.s0;
3581 $$.x0 = $2.x0;
3582 }
3583 | LPAREN asr_asl_0 COMMA sco RPAREN
3584 {
3585 $$.r0 = 2 + $2.r0;
3586 $$.s0 = $4.s0;
3587 $$.x0 = $4.x0;
3588 }
3589 | LPAREN sco COMMA asr_asl_0 RPAREN
3590 {
3591 $$.r0 = 2 + $4.r0;
3592 $$.s0 = $2.s0;
3593 $$.x0 = $2.x0;
3594 }
3595 ;
3596
3597xpmod:
3598 {
3599 $$.r0 = 0;
3600 }
3601 | LPAREN Z RPAREN
3602 {
3603 $$.r0 = 0;
3604 }
3605 | LPAREN X RPAREN
3606 {
3607 $$.r0 = 1;
3608 }
3609 ;
3610
3611xpmod1:
3612 {
3613 $$.r0 = 0;
3614 }
3615 | LPAREN X RPAREN
3616 {
3617 $$.r0 = 0;
3618 }
3619 | LPAREN Z RPAREN
3620 {
3621 $$.r0 = 1;
3622 }
3623 ;
3624
3625vsmod:
3626 {
3627 $$.r0 = 0;
3628 $$.s0 = 0;
3629 $$.aop = 0;
3630 }
3631 | LPAREN NS RPAREN
3632 {
3633 $$.r0 = 0;
3634 $$.s0 = 0;
3635 $$.aop = 3;
3636 }
3637 | LPAREN S RPAREN
3638 {
3639 $$.r0 = 0;
3640 $$.s0 = 1;
3641 $$.aop = 3;
3642 }
3643 | LPAREN V RPAREN
3644 {
3645 $$.r0 = 1;
3646 $$.s0 = 0;
3647 $$.aop = 3;
3648 }
3649 | LPAREN V COMMA S RPAREN
3650 {
3651 $$.r0 = 1;
3652 $$.s0 = 1;
3653 }
3654 | LPAREN S COMMA V RPAREN
3655 {
3656 $$.r0 = 1;
3657 $$.s0 = 1;
3658 }
3659 ;
3660
3661vmod:
3662 {
3663 $$.r0 = 0;
3664 }
3665 | LPAREN V RPAREN
3666 {
3667 $$.r0 = 1;
3668 }
3669 ;
3670
3671smod:
3672 {
3673 $$.s0 = 0;
3674 }
3675 | LPAREN S RPAREN
3676 {
3677 $$.s0 = 1;
3678 }
3679 ;
3680
3681searchmod:
3682 GE
3683 {
3684 $$.r0 = 1;
3685 }
3686 | GT
3687 {
3688 $$.r0 = 0;
3689 }
3690 | LE
3691 {
3692 $$.r0 = 3;
3693 }
3694 | LT
3695 {
3696 $$.r0 = 2;
3697 }
3698 ;
3699
3700aligndir:
3701 {
3702 $$.r0 = 0;
3703 }
3704 | LPAREN R RPAREN
3705 {
3706 $$.r0 = 1;
3707 }
3708 ;
3709
3710byteop_mod:
3711 LPAREN R RPAREN
3712 {
3713 $$.r0 = 0;
3714 $$.s0 = 1;
3715 }
3716 | LPAREN MMOD RPAREN
3717 {
3718 if ($2 != M_T)
3719 return yyerror ("Bad modifier");
3720 $$.r0 = 1;
3721 $$.s0 = 0;
3722 }
3723 | LPAREN MMOD COMMA R RPAREN
3724 {
3725 if ($2 != M_T)
3726 return yyerror ("Bad modifier");
3727 $$.r0 = 1;
3728 $$.s0 = 1;
3729 }
3730 | LPAREN R COMMA MMOD RPAREN
3731 {
3732 if ($4 != M_T)
3733 return yyerror ("Bad modifier");
3734 $$.r0 = 1;
3735 $$.s0 = 1;
3736 }
3737 ;
3738
3739
3740
3741c_align:
3742 ALIGN8
3743 {
3744 $$.r0 = 0;
3745 }
3746 | ALIGN16
3747 {
3748 $$.r0 = 1;
3749 }
3750 | ALIGN24
3751 {
3752 $$.r0 = 2;
3753 }
3754 ;
3755
3756w32_or_nothing:
3757 {
3758 $$.r0 = 0;
3759 }
3760 | LPAREN MMOD RPAREN
3761 {
3762 if ($2 == M_W32)
3763 $$.r0 = 1;
3764 else
3765 return yyerror ("Only (W32) allowed");
3766 }
3767 ;
3768
3769iu_or_nothing:
3770 {
3771 $$.r0 = 1;
3772 }
3773 | LPAREN MMOD RPAREN
3774 {
3775 if ($2 == M_IU)
3776 $$.r0 = 3;
3777 else
3778 return yyerror ("(IU) expected");
3779 }
3780 ;
3781
3782reg_with_predec: LBRACK _MINUS_MINUS REG RBRACK
3783 {
3784 $$ = $3;
3785 }
3786 ;
3787
3788reg_with_postinc: LBRACK REG _PLUS_PLUS RBRACK
3789 {
3790 $$ = $2;
3791 }
3792 ;
3793
3794/* Operators. */
3795
3796min_max:
3797 MIN
3798 {
3799 $$.r0 = 1;
3800 }
3801 | MAX
3802 {
3803 $$.r0 = 0;
3804 }
3805 ;
3806
3807op_bar_op:
3808 _PLUS_BAR_PLUS
3809 {
3810 $$.r0 = 0;
3811 }
3812 | _PLUS_BAR_MINUS
3813 {
3814 $$.r0 = 1;
3815 }
3816 | _MINUS_BAR_PLUS
3817 {
3818 $$.r0 = 2;
3819 }
3820 | _MINUS_BAR_MINUS
3821 {
3822 $$.r0 = 3;
3823 }
3824 ;
3825
3826plus_minus:
3827 PLUS
3828 {
3829 $$.r0 = 0;
3830 }
3831 | MINUS
3832 {
3833 $$.r0 = 1;
3834 }
3835 ;
3836
3837rnd_op:
3838 LPAREN RNDH RPAREN
3839 {
3840 $$.r0 = 1; /* HL. */
3841 $$.s0 = 0; /* s. */
3842 $$.x0 = 0; /* x. */
3843 $$.aop = 0; /* aop. */
3844 }
3845
3846 | LPAREN TH RPAREN
3847 {
3848 $$.r0 = 1; /* HL. */
3849 $$.s0 = 0; /* s. */
3850 $$.x0 = 0; /* x. */
3851 $$.aop = 1; /* aop. */
3852 }
3853
3854 | LPAREN RNDL RPAREN
3855 {
3856 $$.r0 = 0; /* HL. */
3857 $$.s0 = 0; /* s. */
3858 $$.x0 = 0; /* x. */
3859 $$.aop = 0; /* aop. */
3860 }
3861
3862 | LPAREN TL RPAREN
3863 {
3864 $$.r0 = 0; /* HL. */
3865 $$.s0 = 0; /* s. */
3866 $$.x0 = 0; /* x. */
3867 $$.aop = 1;
3868 }
3869
3870 | LPAREN RNDH COMMA R RPAREN
3871 {
3872 $$.r0 = 1; /* HL. */
3873 $$.s0 = 1; /* s. */
3874 $$.x0 = 0; /* x. */
3875 $$.aop = 0; /* aop. */
3876 }
3877 | LPAREN TH COMMA R RPAREN
3878 {
3879 $$.r0 = 1; /* HL. */
3880 $$.s0 = 1; /* s. */
3881 $$.x0 = 0; /* x. */
3882 $$.aop = 1; /* aop. */
3883 }
3884 | LPAREN RNDL COMMA R RPAREN
3885 {
3886 $$.r0 = 0; /* HL. */
3887 $$.s0 = 1; /* s. */
3888 $$.x0 = 0; /* x. */
3889 $$.aop = 0; /* aop. */
3890 }
3891
3892 | LPAREN TL COMMA R RPAREN
3893 {
3894 $$.r0 = 0; /* HL. */
3895 $$.s0 = 1; /* s. */
3896 $$.x0 = 0; /* x. */
3897 $$.aop = 1; /* aop. */
3898 }
3899 ;
3900
3901b3_op:
3902 LPAREN LO RPAREN
3903 {
3904 $$.s0 = 0; /* s. */
3905 $$.x0 = 0; /* HL. */
3906 }
3907 | LPAREN HI RPAREN
3908 {
3909 $$.s0 = 0; /* s. */
3910 $$.x0 = 1; /* HL. */
3911 }
3912 | LPAREN LO COMMA R RPAREN
3913 {
3914 $$.s0 = 1; /* s. */
3915 $$.x0 = 0; /* HL. */
3916 }
3917 | LPAREN HI COMMA R RPAREN
3918 {
3919 $$.s0 = 1; /* s. */
3920 $$.x0 = 1; /* HL. */
3921 }
3922 ;
3923
3924post_op:
3925 {
3926 $$.x0 = 2;
3927 }
3928 | _PLUS_PLUS
3929 {
3930 $$.x0 = 0;
3931 }
3932 | _MINUS_MINUS
3933 {
3934 $$.x0 = 1;
3935 }
3936 ;
3937
3938/* Assignments, Macfuncs. */
3939
3940a_assign:
3941 REG_A ASSIGN
3942 {
3943 $$ = $1;
3944 }
3945 ;
3946
3947a_minusassign:
3948 REG_A _MINUS_ASSIGN
3949 {
3950 $$ = $1;
3951 }
3952 ;
3953
3954a_plusassign:
3955 REG_A _PLUS_ASSIGN
3956 {
3957 $$ = $1;
3958 }
3959 ;
3960
3961assign_macfunc:
3962 REG ASSIGN REG_A
3963 {
3964 $$.w = 1;
3965 $$.P = 1;
3966 $$.n = IS_A1 ($3);
3967 $$.op = 3;
3968 $$.dst = $1;
3969 $$.s0.regno = 0;
3970 $$.s1.regno = 0;
3971
3972 if (IS_A1 ($3) && IS_EVEN ($1))
3973 return yyerror ("Cannot move A1 to even register");
3974 else if (!IS_A1 ($3) && !IS_EVEN ($1))
3975 return yyerror ("Cannot move A0 to odd register");
3976 }
3977 | a_macfunc
3978 {
3979 $$ = $1;
3980 $$.w = 0; $$.P = 0;
3981 $$.dst.regno = 0;
3982 }
3983 | REG ASSIGN LPAREN a_macfunc RPAREN
3984 {
3985 $$ = $4;
3986 $$.w = 1;
3987 $$.P = 1;
3988 $$.dst = $1;
3989 }
3990
3991 | HALF_REG ASSIGN LPAREN a_macfunc RPAREN
3992 {
3993 $$ = $4;
3994 $$.w = 1;
3995 $$.P = 0;
3996 $$.dst = $1;
3997 }
3998
3999 | HALF_REG ASSIGN REG_A
4000 {
4001 $$.w = 1;
4002 $$.P = 0;
4003 $$.n = IS_A1 ($3);
4004 $$.op = 3;
4005 $$.dst = $1;
4006 $$.s0.regno = 0;
4007 $$.s1.regno = 0;
4008
4009 if (IS_A1 ($3) && !IS_H ($1))
4010 return yyerror ("Cannot move A1 to low half of register");
4011 else if (!IS_A1 ($3) && IS_H ($1))
4012 return yyerror ("Cannot move A0 to high half of register");
4013 }
4014 ;
4015
4016a_macfunc:
4017 a_assign multiply_halfregs
4018 {
4019 $$.n = IS_A1 ($1);
4020 $$.op = 0;
4021 $$.s0 = $2.s0;
4022 $$.s1 = $2.s1;
4023 }
4024 | a_plusassign multiply_halfregs
4025 {
4026 $$.n = IS_A1 ($1);
4027 $$.op = 1;
4028 $$.s0 = $2.s0;
4029 $$.s1 = $2.s1;
4030 }
4031 | a_minusassign multiply_halfregs
4032 {
4033 $$.n = IS_A1 ($1);
4034 $$.op = 2;
4035 $$.s0 = $2.s0;
4036 $$.s1 = $2.s1;
4037 }
4038 ;
4039
4040multiply_halfregs:
4041 HALF_REG STAR HALF_REG
4042 {
4043 if (IS_DREG ($1) && IS_DREG ($3))
4044 {
4045 $$.s0 = $1;
4046 $$.s1 = $3;
4047 }
4048 else
4049 return yyerror ("Dregs expected");
4050 }
4051 ;
4052
4053cc_op:
4054 ASSIGN
4055 {
4056 $$.r0 = 0;
4057 }
4058 | _BAR_ASSIGN
4059 {
4060 $$.r0 = 1;
4061 }
4062 | _AMPERSAND_ASSIGN
4063 {
4064 $$.r0 = 2;
4065 }
4066 | _CARET_ASSIGN
4067 {
4068 $$.r0 = 3;
4069 }
4070 ;
4071
4072ccstat:
4073 CCREG cc_op STATUS_REG
4074 {
4075 $$.r0 = $3.regno;
4076 $$.x0 = $2.r0;
4077 $$.s0 = 0;
4078 }
4079 | CCREG cc_op V
4080 {
4081 $$.r0 = 0x18;
4082 $$.x0 = $2.r0;
4083 $$.s0 = 0;
4084 }
4085 | STATUS_REG cc_op CCREG
4086 {
4087 $$.r0 = $1.regno;
4088 $$.x0 = $2.r0;
4089 $$.s0 = 1;
4090 }
4091 | V cc_op CCREG
4092 {
4093 $$.r0 = 0x18;
4094 $$.x0 = $2.r0;
4095 $$.s0 = 1;
4096 }
4097 ;
4098
4099/* Expressions and Symbols. */
4100
4101symbol: SYMBOL
4102 {
4103 Expr_Node_Value val;
4104 val.s_value = S_GET_NAME($1);
4105 $$ = Expr_Node_Create (Expr_Node_Reloc, val, NULL, NULL);
4106 }
4107 ;
4108
1ac4baed
BS
4109any_gotrel:
4110 GOT
4111 { $$ = BFD_RELOC_BFIN_GOT; }
4112 | GOT17M4
4113 { $$ = BFD_RELOC_BFIN_GOT17M4; }
4114 | FUNCDESC_GOT17M4
4115 { $$ = BFD_RELOC_BFIN_FUNCDESC_GOT17M4; }
4116 ;
4117
4118got: symbol AT any_gotrel
07c1b327 4119 {
1ac4baed
BS
4120 Expr_Node_Value val;
4121 val.i_value = $3;
4122 $$ = Expr_Node_Create (Expr_Node_GOT_Reloc, val, $1, NULL);
07c1b327
CM
4123 }
4124 ;
4125
4126got_or_expr: got
4127 {
4128 $$ = $1;
4129 }
4130 | expr
4131 {
4132 $$ = $1;
4133 }
4134 ;
4135
4136pltpc :
4137 symbol AT PLTPC
4138 {
4139 $$ = $1;
4140 }
4141 ;
4142
4143eterm: NUMBER
4144 {
4145 Expr_Node_Value val;
4146 val.i_value = $1;
4147 $$ = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL);
4148 }
4149 | symbol
4150 {
4151 $$ = $1;
4152 }
4153 | LPAREN expr_1 RPAREN
4154 {
4155 $$ = $2;
4156 }
4157 | TILDA expr_1
4158 {
4159 $$ = unary (Expr_Op_Type_COMP, $2);
4160 }
4161 | MINUS expr_1 %prec TILDA
4162 {
4163 $$ = unary (Expr_Op_Type_NEG, $2);
4164 }
4165 ;
4166
4167expr: expr_1
4168 {
4169 $$ = $1;
4170 }
4171 ;
4172
4173expr_1: expr_1 STAR expr_1
4174 {
4175 $$ = binary (Expr_Op_Type_Mult, $1, $3);
4176 }
4177 | expr_1 SLASH expr_1
4178 {
4179 $$ = binary (Expr_Op_Type_Div, $1, $3);
4180 }
4181 | expr_1 PERCENT expr_1
4182 {
4183 $$ = binary (Expr_Op_Type_Mod, $1, $3);
4184 }
4185 | expr_1 PLUS expr_1
4186 {
4187 $$ = binary (Expr_Op_Type_Add, $1, $3);
4188 }
4189 | expr_1 MINUS expr_1
4190 {
4191 $$ = binary (Expr_Op_Type_Sub, $1, $3);
4192 }
4193 | expr_1 LESS_LESS expr_1
4194 {
4195 $$ = binary (Expr_Op_Type_Lshift, $1, $3);
4196 }
4197 | expr_1 GREATER_GREATER expr_1
4198 {
4199 $$ = binary (Expr_Op_Type_Rshift, $1, $3);
4200 }
4201 | expr_1 AMPERSAND expr_1
4202 {
4203 $$ = binary (Expr_Op_Type_BAND, $1, $3);
4204 }
4205 | expr_1 CARET expr_1
4206 {
4207 $$ = binary (Expr_Op_Type_LOR, $1, $3);
4208 }
4209 | expr_1 BAR expr_1
4210 {
4211 $$ = binary (Expr_Op_Type_BOR, $1, $3);
4212 }
4213 | eterm
4214 {
4215 $$ = $1;
4216 }
4217 ;
4218
4219
4220%%
4221
4222EXPR_T
4223mkexpr (int x, SYMBOL_T s)
4224{
4225 EXPR_T e = (EXPR_T) ALLOCATE (sizeof (struct expression_cell));
4226 e->value = x;
4227 EXPR_SYMBOL(e) = s;
4228 return e;
4229}
4230
4231static int
4232value_match (Expr_Node *expr, int sz, int sign, int mul, int issigned)
4233{
4234 long umax = (1L << sz) - 1;
4235 long min = -1L << (sz - 1);
4236 long max = (1L << (sz - 1)) - 1;
4237
4238 long v = EXPR_VALUE (expr);
4239
4240 if ((v % mul) != 0)
4241 {
39cd1c76 4242 error ("%s:%d: Value Error -- Must align to %d\n", __FILE__, __LINE__, mul);
07c1b327
CM
4243 return 0;
4244 }
4245
4246 v /= mul;
4247
4248 if (sign)
4249 v = -v;
4250
4251 if (issigned)
4252 {
4253 if (v >= min && v <= max) return 1;
4254
4255#ifdef DEBUG
4256 fprintf(stderr, "signed value %lx out of range\n", v * mul);
4257#endif
4258 return 0;
4259 }
4260 if (v <= umax && v >= 0)
4261 return 1;
4262#ifdef DEBUG
4263 fprintf(stderr, "unsigned value %lx out of range\n", v * mul);
4264#endif
4265 return 0;
4266}
4267
4268/* Return the expression structure that allows symbol operations.
4269 If the left and right children are constants, do the operation. */
4270static Expr_Node *
4271binary (Expr_Op_Type op, Expr_Node *x, Expr_Node *y)
4272{
c4ae04ce
BS
4273 Expr_Node_Value val;
4274
07c1b327
CM
4275 if (x->type == Expr_Node_Constant && y->type == Expr_Node_Constant)
4276 {
4277 switch (op)
4278 {
4279 case Expr_Op_Type_Add:
4280 x->value.i_value += y->value.i_value;
4281 break;
4282 case Expr_Op_Type_Sub:
4283 x->value.i_value -= y->value.i_value;
4284 break;
4285 case Expr_Op_Type_Mult:
4286 x->value.i_value *= y->value.i_value;
4287 break;
4288 case Expr_Op_Type_Div:
4289 if (y->value.i_value == 0)
4290 error ("Illegal Expression: Division by zero.");
4291 else
4292 x->value.i_value /= y->value.i_value;
4293 break;
4294 case Expr_Op_Type_Mod:
4295 x->value.i_value %= y->value.i_value;
4296 break;
4297 case Expr_Op_Type_Lshift:
4298 x->value.i_value <<= y->value.i_value;
4299 break;
4300 case Expr_Op_Type_Rshift:
4301 x->value.i_value >>= y->value.i_value;
4302 break;
4303 case Expr_Op_Type_BAND:
4304 x->value.i_value &= y->value.i_value;
4305 break;
4306 case Expr_Op_Type_BOR:
4307 x->value.i_value |= y->value.i_value;
4308 break;
4309 case Expr_Op_Type_BXOR:
4310 x->value.i_value ^= y->value.i_value;
4311 break;
4312 case Expr_Op_Type_LAND:
4313 x->value.i_value = x->value.i_value && y->value.i_value;
4314 break;
4315 case Expr_Op_Type_LOR:
4316 x->value.i_value = x->value.i_value || y->value.i_value;
4317 break;
4318
4319 default:
39cd1c76 4320 error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__);
07c1b327
CM
4321 }
4322 return x;
4323 }
c4ae04ce
BS
4324 /* Canonicalize order to EXPR OP CONSTANT. */
4325 if (x->type == Expr_Node_Constant)
4326 {
4327 Expr_Node *t = x;
4328 x = y;
4329 y = t;
4330 }
73332571
BS
4331 /* Canonicalize subtraction of const to addition of negated const. */
4332 if (op == Expr_Op_Type_Sub && y->type == Expr_Node_Constant)
4333 {
4334 op = Expr_Op_Type_Add;
4335 y->value.i_value = -y->value.i_value;
4336 }
c4ae04ce
BS
4337 if (y->type == Expr_Node_Constant && x->type == Expr_Node_Binop
4338 && x->Right_Child->type == Expr_Node_Constant)
07c1b327 4339 {
c4ae04ce
BS
4340 if (op == x->value.op_value && x->value.op_value == Expr_Op_Type_Add)
4341 {
4342 x->Right_Child->value.i_value += y->value.i_value;
4343 return x;
4344 }
4345 }
4346
4347 /* Create a new expression structure. */
4348 val.op_value = op;
4349 return Expr_Node_Create (Expr_Node_Binop, val, x, y);
07c1b327
CM
4350}
4351
4352static Expr_Node *
4353unary (Expr_Op_Type op, Expr_Node *x)
4354{
4355 if (x->type == Expr_Node_Constant)
4356 {
4357 switch (op)
4358 {
4359 case Expr_Op_Type_NEG:
4360 x->value.i_value = -x->value.i_value;
4361 break;
4362 case Expr_Op_Type_COMP:
4363 x->value.i_value = ~x->value.i_value;
4364 break;
4365 default:
39cd1c76 4366 error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__);
07c1b327
CM
4367 }
4368 return x;
4369 }
4370 else
4371 {
4372 /* Create a new expression structure. */
4373 Expr_Node_Value val;
4374 val.op_value = op;
4375 return Expr_Node_Create (Expr_Node_Unop, val, x, NULL);
4376 }
4377}
4378
4379int debug_codeselection = 0;
4380static void
4381notethat (char *format, ...)
4382{
4383 va_list ap;
4384 va_start (ap, format);
4385 if (debug_codeselection)
4386 {
4387 vfprintf (errorf, format, ap);
4388 }
4389 va_end (ap);
4390}
4391
4392#ifdef TEST
4393main (int argc, char **argv)
4394{
4395 yyparse();
4396}
4397#endif
4398
This page took 0.257134 seconds and 4 git commands to generate.