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