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