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