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