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