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