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