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