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