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