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