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