1 /* bfin-parse.y ADI Blackfin parser
2 Copyright (C) 2005-2019 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24 #include "bfin-aux.h" /* Opcode generating auxiliaries. */
25 #include "elf/common.h"
28 #define DSP32ALU(aopcde, HL, dst1, dst0, src0, src1, s, x, aop) \
29 bfin_gen_dsp32alu
(HL
, aopcde
, aop
, s
, x
, dst0
, dst1
, src0
, src1
)
31 #define DSP32MAC(op1, MM, mmod, w1, P, h01, h11, h00, h10, dst, op0, src0, src1, w0) \
32 bfin_gen_dsp32mac
(op1
, MM
, mmod
, w1
, P
, h01
, h11
, h00
, h10
, op0
, \
35 #define DSP32MULT(op1, MM, mmod, w1, P, h01, h11, h00, h10, dst, op0, src0, src1, w0) \
36 bfin_gen_dsp32mult
(op1
, MM
, mmod
, w1
, P
, h01
, h11
, h00
, h10
, op0
, \
39 #define DSP32SHIFT(sopcde, dst0, src0, src1, sop, hls) \
40 bfin_gen_dsp32shift
(sopcde
, dst0
, src0
, src1
, sop
, hls
)
42 #define DSP32SHIFTIMM(sopcde, dst0, immag, src1, sop, hls) \
43 bfin_gen_dsp32shiftimm
(sopcde
, dst0
, immag
, src1
, sop
, hls
)
45 #define LDIMMHALF_R(reg, h, s, z, hword) \
46 bfin_gen_ldimmhalf
(reg
, h
, s
, z
, hword
, 1)
48 #define LDIMMHALF_R5(reg, h, s, z, hword) \
49 bfin_gen_ldimmhalf
(reg
, h
, s
, z
, hword
, 2)
51 #define LDSTIDXI(ptr, reg, w, sz, z, offset) \
52 bfin_gen_ldstidxi
(ptr
, reg
, w
, sz
, z
, offset
)
54 #define LDST(ptr, reg, aop, sz, z, w) \
55 bfin_gen_ldst
(ptr
, reg
, aop
, sz
, z
, w
)
57 #define LDSTII(ptr, reg, offset, w, op) \
58 bfin_gen_ldstii
(ptr
, reg
, offset
, w
, op
)
60 #define DSPLDST(i, m, reg, aop, w) \
61 bfin_gen_dspldst
(i
, reg
, aop
, w
, m
)
63 #define LDSTPMOD(ptr, reg, idx, aop, w) \
64 bfin_gen_ldstpmod
(ptr
, reg
, aop
, w
, idx
)
66 #define LDSTIIFP(offset, reg, w) \
67 bfin_gen_ldstiifp
(reg
, offset
, w
)
69 #define LOGI2OP(dst, src, opc) \
70 bfin_gen_logi2op
(opc
, src
, dst.regno
& CODE_MASK
)
72 #define ALU2OP(dst, src, opc) \
73 bfin_gen_alu2op
(dst
, src
, opc
)
75 #define BRCC(t, b, offset) \
76 bfin_gen_brcc
(t
, b
, offset
)
78 #define UJUMP(offset) \
79 bfin_gen_ujump
(offset
)
81 #define PROGCTRL(prgfunc, poprnd) \
82 bfin_gen_progctrl
(prgfunc
, poprnd
)
84 #define PUSHPOPMULTIPLE(dr, pr, d, p, w) \
85 bfin_gen_pushpopmultiple
(dr
, pr
, d
, p
, w
)
87 #define PUSHPOPREG(reg, w) \
88 bfin_gen_pushpopreg
(reg
, w
)
90 #define CALLA(addr, s) \
91 bfin_gen_calla
(addr
, s
)
93 #define LINKAGE(r, framesize) \
94 bfin_gen_linkage
(r
, framesize
)
96 #define COMPI2OPD(dst, src, op) \
97 bfin_gen_compi2opd
(dst
, src
, op
)
99 #define COMPI2OPP(dst, src, op) \
100 bfin_gen_compi2opp
(dst
, src
, op
)
102 #define DAGMODIK(i, op) \
103 bfin_gen_dagmodik
(i
, op
)
105 #define DAGMODIM(i, m, op, br) \
106 bfin_gen_dagmodim
(i
, m
, op
, br
)
108 #define COMP3OP(dst, src0, src1, opc) \
109 bfin_gen_comp3op
(src0
, src1
, dst
, opc
)
111 #define PTR2OP(dst, src, opc) \
112 bfin_gen_ptr2op
(dst
, src
, opc
)
114 #define CCFLAG(x, y, opc, i, g) \
115 bfin_gen_ccflag
(x
, y
, opc
, i
, g
)
117 #define CCMV(src, dst, t) \
118 bfin_gen_ccmv
(src
, dst
, t
)
120 #define CACTRL(reg, a, op) \
121 bfin_gen_cactrl
(reg
, a
, op
)
123 #define LOOPSETUP(soffset, c, rop, eoffset, reg) \
124 bfin_gen_loopsetup
(soffset
, c
, rop
, eoffset
, reg
)
126 #define HL2(r1, r0) (IS_H (r1) << 1 | IS_H (r0))
127 #define IS_RANGE(bits, expr, sign, mul) \
128 value_match
(expr
, bits
, sign
, mul
, 1)
129 #define IS_URANGE(bits, expr, sign, mul) \
130 value_match
(expr
, bits
, sign
, mul
, 0)
131 #define IS_CONST(expr) (expr->type == Expr_Node_Constant)
132 #define IS_RELOC(expr) (expr->type != Expr_Node_Constant)
133 #define IS_IMM(expr, bits) value_match (expr, bits, 0, 1, 1)
134 #define IS_UIMM(expr, bits) value_match (expr, bits, 0, 1, 0)
136 #define IS_PCREL4(expr) \
137 (value_match
(expr
, 4, 0, 2, 0))
139 #define IS_LPPCREL10(expr) \
140 (value_match
(expr
, 10, 0, 2, 0))
142 #define IS_PCREL10(expr) \
143 (value_match
(expr
, 10, 0, 2, 1))
145 #define IS_PCREL12(expr) \
146 (value_match
(expr
, 12, 0, 2, 1))
148 #define IS_PCREL24(expr) \
149 (value_match
(expr
, 24, 0, 2, 1))
152 static int value_match
(Expr_Node
*, int, int, int, int);
157 static Expr_Node
*binary
(Expr_Op_Type
, Expr_Node
*, Expr_Node
*);
158 static Expr_Node
*unary
(Expr_Op_Type
, Expr_Node
*);
160 static void notethat
(const char *, ...
);
163 int yyerror (const char *);
165 /* Used to set SRCx fields to all 1s as described in the PRM. */
166 static Register reg7
= {REG_R7
, 0};
168 void error (const char *format
, ...
)
171 static char buffer
[2000];
173 va_start
(ap
, format
);
174 vsprintf
(buffer
, format
, ap
);
177 as_bad
("%s", buffer
);
181 yyerror (const char *msg
)
186 else if
(yytext
[0] != ';')
187 error ("%s. Input text was %s.", msg
, yytext
);
195 in_range_p
(Expr_Node
*exp
, int from
, int to
, unsigned int mask
)
197 int val
= EXPR_VALUE
(exp
);
198 if
(exp
->type
!= Expr_Node_Constant
)
200 if
(val
< from || val
> to
)
202 return
(val
& mask
) == 0;
205 extern
int yylex (void);
207 #define imm3(x) EXPR_VALUE (x)
208 #define imm4(x) EXPR_VALUE (x)
209 #define uimm4(x) EXPR_VALUE (x)
210 #define imm5(x) EXPR_VALUE (x)
211 #define uimm5(x) EXPR_VALUE (x)
212 #define imm6(x) EXPR_VALUE (x)
213 #define imm7(x) EXPR_VALUE (x)
214 #define uimm8(x) EXPR_VALUE (x)
215 #define imm16(x) EXPR_VALUE (x)
216 #define uimm16s4(x) ((EXPR_VALUE (x)) >> 2)
217 #define uimm16(x) EXPR_VALUE (x)
219 /* Return true if a value is inside a range. */
220 #define IN_RANGE(x, low, high) \
221 (((EXPR_VALUE
(x
)) >= (low
)) && (EXPR_VALUE
(x
)) <= ((high
)))
223 /* Auxiliary functions. */
226 valid_dreg_pair
(Register
*reg1
, Expr_Node
*reg2
)
228 if
(!IS_DREG
(*reg1
))
230 yyerror ("Dregs expected");
234 if
(reg1
->regno
!= 1 && reg1
->regno
!= 3)
236 yyerror ("Bad register pair");
240 if
(imm7
(reg2
) != reg1
->regno
- 1)
242 yyerror ("Bad register pair");
251 check_multiply_halfregs
(Macfunc
*aa
, Macfunc
*ab
)
253 if
((!REG_EQUAL
(aa
->s0
, ab
->s0
) && !REG_EQUAL
(aa
->s0
, ab
->s1
))
254 ||
(!REG_EQUAL
(aa
->s1
, ab
->s1
) && !REG_EQUAL
(aa
->s1
, ab
->s0
)))
255 return
yyerror ("Source multiplication register mismatch");
261 /* Check mac option. */
264 check_macfunc_option
(Macfunc
*a
, Opt_mode
*opt
)
266 /* Default option is always valid. */
270 if
((a
->w
== 1 && a
->P
== 1
271 && opt
->mod
!= M_FU
&& opt
->mod
!= M_IS
&& opt
->mod
!= M_IU
272 && opt
->mod
!= M_S2RND
&& opt
->mod
!= M_ISS2
)
273 ||
(a
->w
== 1 && a
->P
== 0
274 && opt
->mod
!= M_FU
&& opt
->mod
!= M_IS
&& opt
->mod
!= M_IU
275 && opt
->mod
!= M_T
&& opt
->mod
!= M_TFU
&& opt
->mod
!= M_S2RND
276 && opt
->mod
!= M_ISS2
&& opt
->mod
!= M_IH
)
277 ||
(a
->w
== 0 && a
->P
== 0
278 && opt
->mod
!= M_FU
&& opt
->mod
!= M_IS
&& opt
->mod
!= M_W32
))
284 /* Check (vector) mac funcs and ops. */
287 check_macfuncs
(Macfunc
*aa
, Opt_mode
*opa
,
288 Macfunc
*ab
, Opt_mode
*opb
)
290 /* Variables for swapping. */
294 /* The option mode should be put at the end of the second instruction
295 of the vector except M, which should follow MAC1 instruction. */
297 return
yyerror ("Bad opt mode");
299 /* If a0macfunc comes before a1macfunc, swap them. */
303 /* (M) is not allowed here. */
305 return
yyerror ("(M) not allowed with A0MAC");
307 return
yyerror ("Vector AxMACs can't be same");
309 mtmp
= *aa
; *aa
= *ab
; *ab
= mtmp
;
310 otmp
= *opa
; *opa
= *opb
; *opb
= otmp
;
315 return
yyerror ("(M) not allowed with A0MAC");
317 return
yyerror ("Vector AxMACs can't be same");
320 /* If both ops are one of 0, 1, or 2, we have multiply_halfregs in both
321 assignment_or_macfuncs. */
322 if
((aa
->op
== 0 || aa
->op
== 1 || aa
->op
== 2)
323 && (ab
->op
== 0 || ab
->op
== 1 || ab
->op
== 2))
325 if
(check_multiply_halfregs
(aa
, ab
) < 0)
330 /* Only one of the assign_macfuncs has a half reg multiply
331 Evil trick: Just 'OR' their source register codes:
332 We can do that, because we know they were initialized to 0
333 in the rules that don't use multiply_halfregs. */
334 aa
->s0.regno |
= (ab
->s0.regno
& CODE_MASK
);
335 aa
->s1.regno |
= (ab
->s1.regno
& CODE_MASK
);
338 if
(aa
->w
== ab
->w
&& aa
->P
!= ab
->P
)
339 return
yyerror ("Destination Dreg sizes (full or half) must match");
343 if
(aa
->P
&& (aa
->dst.regno
- ab
->dst.regno
) != 1)
344 return
yyerror ("Destination Dregs (full) must differ by one");
345 if
(!aa
->P
&& aa
->dst.regno
!= ab
->dst.regno
)
346 return
yyerror ("Destination Dregs (half) must match");
349 /* Make sure mod flags get ORed, too. */
350 opb
->mod |
= opa
->mod
;
353 if
(check_macfunc_option
(aa
, opb
) < 0
354 && check_macfunc_option
(ab
, opb
) < 0)
355 return
yyerror ("bad option");
357 /* Make sure first macfunc has got both P flags ORed. */
365 is_group1
(INSTR_T x
)
367 /* Group1 is dpsLDST, LDSTpmod, LDST, LDSTiiFP, LDSTii. */
368 if
((x
->value
& 0xc000) == 0x8000 ||
(x
->value
== 0x0000))
375 is_group2
(INSTR_T x
)
377 if
((((x
->value
& 0xfc00) == 0x9c00) /* dspLDST. */
378 && !((x
->value
& 0xfde0) == 0x9c60) /* dagMODim. */
379 && !((x
->value
& 0xfde0) == 0x9ce0) /* dagMODim with bit rev. */
380 && !((x
->value
& 0xfde0) == 0x9d60)) /* pick dagMODik. */
381 ||
(x
->value
== 0x0000))
392 if
((x
->value
& 0xf000) == 0x8000)
394 int aop
= ((x
->value
>> 9) & 0x3);
395 int w
= ((x
->value
>> 11) & 0x1);
401 if
(((x
->value
& 0xFF60) == 0x9E60) ||
/* dagMODim_0 */
402 ((x
->value
& 0xFFF0) == 0x9F60)) /* dagMODik_0 */
405 /* decode_dspLDST_0 */
406 if
((x
->value
& 0xFC00) == 0x9C00)
408 int w
= ((x
->value
>> 9) & 0x1);
417 gen_multi_instr_1
(INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
419 int mask1
= dsp32 ? insn_regmask
(dsp32
->value
, dsp32
->next
->value
) : 0;
420 int mask2
= dsp16_grp1 ? insn_regmask
(dsp16_grp1
->value
, 0) : 0;
421 int mask3
= dsp16_grp2 ? insn_regmask
(dsp16_grp2
->value
, 0) : 0;
423 if
((mask1
& mask2
) ||
(mask1
& mask3
) ||
(mask2
& mask3
))
424 yyerror ("resource conflict in multi-issue instruction");
426 /* Anomaly 05000074 */
427 if
(ENABLE_AC_05000074
428 && dsp32
!= NULL
&& dsp16_grp1
!= NULL
429 && (dsp32
->value
& 0xf780) == 0xc680
430 && ((dsp16_grp1
->value
& 0xfe40) == 0x9240
431 ||
(dsp16_grp1
->value
& 0xfe08) == 0xba08
432 ||
(dsp16_grp1
->value
& 0xfc00) == 0xbc00))
433 yyerror ("anomaly 05000074 - Multi-Issue Instruction with \
434 dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported");
436 if
(is_store
(dsp16_grp1
) && is_store
(dsp16_grp2
))
437 yyerror ("Only one instruction in multi-issue instruction can be a store");
439 return bfin_gen_multi_instr
(dsp32
, dsp16_grp1
, dsp16_grp2
);
451 struct { int r0
; int s0
; int x0
; int aop
; } modcodes
;
452 struct { int r0
; } r0
;
459 /* Vector Specific. */
460 %token BYTEOP16P BYTEOP16M
461 %token BYTEOP1P BYTEOP2P BYTEOP3P
462 %token BYTEUNPACK BYTEPACK
465 %token ALIGN8 ALIGN16 ALIGN24
467 %token EXTRACT DEPOSIT EXPADJ SEARCH
468 %token ONES SIGN SIGNBITS
476 %token CCREG BYTE_DREG
477 %token REG_A_DOUBLE_ZERO REG_A_DOUBLE_ONE
478 %token A_ZERO_DOT_L A_ZERO_DOT_H A_ONE_DOT_L A_ONE_DOT_H
483 %token RTI RTS RTX RTN RTE
494 %token JUMP JUMP_DOT_S JUMP_DOT_L
501 %token NOT TILDA BANG
507 %token MINUS PLUS STAR SLASH
511 %token _PLUS_BAR_PLUS _PLUS_BAR_MINUS _MINUS_BAR_PLUS _MINUS_BAR_MINUS
512 %token _MINUS_MINUS _PLUS_PLUS
514 /* Shift/rotate ops. */
515 %token SHIFT LSHIFT ASHIFT BXORSHIFT
516 %token _GREATER_GREATER_GREATER_THAN_ASSIGN
518 %token LESS_LESS GREATER_GREATER
519 %token _GREATER_GREATER_GREATER
520 %token _LESS_LESS_ASSIGN _GREATER_GREATER_ASSIGN
523 /* In place operators. */
524 %token ASSIGN _STAR_ASSIGN
525 %token _BAR_ASSIGN _CARET_ASSIGN _AMPERSAND_ASSIGN
526 %token _MINUS_ASSIGN _PLUS_ASSIGN
528 /* Assignments, comparisons. */
529 %token _ASSIGN_BANG _LESS_THAN_ASSIGN _ASSIGN_ASSIGN
534 %token FLUSHINV FLUSH
535 %token IFLUSH PREFETCH
552 %token R RND RNDL RNDH RND12 RND20
557 %token BITTGL BITCLR BITSET BITTST BITMUX
560 %token DBGAL DBGAH DBGHALT DBG DBGA DBGCMPLX
562 /* Semantic auxiliaries. */
565 %token COLON SEMICOLON
566 %token RPAREN LPAREN LBRACK RBRACK
570 %token GOT GOT17M4 FUNCDESC_GOT17M4
580 %type
<modcodes
> byteop_mod
582 %type
<reg
> a_plusassign
583 %type
<reg
> a_minusassign
584 %type
<macfunc
> multiply_halfregs
585 %type
<macfunc
> assign_macfunc
586 %type
<macfunc
> a_macfunc
590 %type
<modcodes
> vsmod
591 %type
<modcodes
> ccstat
594 %type
<reg
> reg_with_postinc
595 %type
<reg
> reg_with_predec
599 %type
<symbol
> SYMBOL
602 %type
<reg
> BYTE_DREG
603 %type
<reg
> REG_A_DOUBLE_ZERO
604 %type
<reg
> REG_A_DOUBLE_ONE
606 %type
<reg
> STATUS_REG
610 %type
<modcodes
> smod
611 %type
<modcodes
> b3_op
612 %type
<modcodes
> rnd_op
613 %type
<modcodes
> post_op
615 %type
<r0
> iu_or_nothing
616 %type
<r0
> plus_minus
620 %type
<modcodes
> amod0
621 %type
<modcodes
> amod1
622 %type
<modcodes
> amod2
624 %type
<r0
> w32_or_nothing
628 %type
<expr
> got_or_expr
630 %type
<value
> any_gotrel GOT GOT17M4 FUNCDESC_GOT17M4
632 /* Precedence rules. */
636 %left LESS_LESS GREATER_GREATER
638 %left STAR SLASH PERCENT
649 if
(insn
== (INSTR_T
) 0)
650 return NO_INSN_GENERATED
;
651 else if
(insn
== (INSTR_T
) - 1)
652 return SEMANTIC_ERROR
;
654 return INSN_GENERATED
;
659 /* Parallel instructions. */
660 | asm_1 DOUBLE_BAR asm_1 DOUBLE_BAR asm_1 SEMICOLON
662 if
(($1->value
& 0xf800) == 0xc000)
664 if
(is_group1
($3) && is_group2
($5))
665 $$
= gen_multi_instr_1
($1, $3, $5);
666 else if
(is_group2
($3) && is_group1
($5))
667 $$
= gen_multi_instr_1
($1, $5, $3);
669 return
yyerror ("Wrong 16 bit instructions groups, slot 2 and slot 3 must be 16-bit instruction group");
671 else if
(($3->value
& 0xf800) == 0xc000)
673 if
(is_group1
($1) && is_group2
($5))
674 $$
= gen_multi_instr_1
($3, $1, $5);
675 else if
(is_group2
($1) && is_group1
($5))
676 $$
= gen_multi_instr_1
($3, $5, $1);
678 return
yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 3 must be 16-bit instruction group");
680 else if
(($5->value
& 0xf800) == 0xc000)
682 if
(is_group1
($1) && is_group2
($3))
683 $$
= gen_multi_instr_1
($5, $1, $3);
684 else if
(is_group2
($1) && is_group1
($3))
685 $$
= gen_multi_instr_1
($5, $3, $1);
687 return
yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be 16-bit instruction group");
690 error ("\nIllegal Multi Issue Construct, at least any one of the slot must be DSP32 instruction group\n");
693 | asm_1 DOUBLE_BAR asm_1 SEMICOLON
695 if
(($1->value
& 0xf800) == 0xc000)
698 $$
= gen_multi_instr_1
($1, $3, 0);
699 else if
(is_group2
($3))
700 $$
= gen_multi_instr_1
($1, 0, $3);
702 return
yyerror ("Wrong 16 bit instructions groups, slot 2 must be the 16-bit instruction group");
704 else if
(($3->value
& 0xf800) == 0xc000)
707 $$
= gen_multi_instr_1
($3, $1, 0);
708 else if
(is_group2
($1))
709 $$
= gen_multi_instr_1
($3, 0, $1);
711 return
yyerror ("Wrong 16 bit instructions groups, slot 1 must be the 16-bit instruction group");
713 else if
(is_group1
($1) && is_group2
($3))
714 $$
= gen_multi_instr_1
(0, $1, $3);
715 else if
(is_group2
($1) && is_group1
($3))
716 $$
= gen_multi_instr_1
(0, $3, $1);
718 return
yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be the 16-bit instruction group");
733 $$
= DSP32MAC
(3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
735 | assign_macfunc opt_mode
739 int h00
, h10
, h01
, h11
;
741 if
(check_macfunc_option
(&$1, &$2) < 0)
742 return
yyerror ("bad option");
747 return
yyerror ("(m) not allowed with a0 unit");
766 $$
= DSP32MAC
(op1
, $2.MM
, $2.mod
, w1
, $1.P
, h01
, h11
, h00
, h10
,
767 &$1.dst
, op0
, &$1.s0
, &$1.s1
, w0
);
773 | assign_macfunc opt_mode COMMA assign_macfunc opt_mode
777 if
(check_macfuncs
(&$1, &$2, &$4, &$5) < 0)
779 notethat
("assign_macfunc (.), assign_macfunc (.)\n");
786 $$
= DSP32MAC
($1.op
, $2.MM
, $5.mod
, $1.w
, $1.P
,
787 IS_H
($1.s0
), IS_H
($1.s1
), IS_H
($4.s0
), IS_H
($4.s1
),
788 dst
, $4.op
, &$1.s0
, &$1.s1
, $4.w
);
795 notethat
("dsp32alu: DISALGNEXCPT\n");
796 $$
= DSP32ALU
(18, 0, 0, 0, 0, 0, 0, 0, 3);
798 | REG ASSIGN LPAREN a_plusassign REG_A RPAREN
800 if
(IS_DREG
($1) && !IS_A1
($4) && IS_A1
($5))
802 notethat
("dsp32alu: dregs = ( A0 += A1 )\n");
803 $$
= DSP32ALU
(11, 0, 0, &$1, ®7
, ®7
, 0, 0, 0);
806 return
yyerror ("Register mismatch");
808 | HALF_REG ASSIGN LPAREN a_plusassign REG_A RPAREN
810 if
(!IS_A1
($4) && IS_A1
($5))
812 notethat
("dsp32alu: dregs_half = ( A0 += A1 )\n");
813 $$
= DSP32ALU
(11, IS_H
($1), 0, &$1, ®7
, ®7
, 0, 0, 1);
816 return
yyerror ("Register mismatch");
818 | A_ZERO_DOT_H ASSIGN HALF_REG
820 notethat
("dsp32alu: A_ZERO_DOT_H = dregs_hi\n");
821 $$
= DSP32ALU
(9, IS_H
($3), 0, 0, &$3, 0, 0, 0, 0);
823 | A_ONE_DOT_H ASSIGN HALF_REG
825 notethat
("dsp32alu: A_ZERO_DOT_H = dregs_hi\n");
826 $$
= DSP32ALU
(9, IS_H
($3), 0, 0, &$3, 0, 0, 0, 2);
828 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEOP16P LPAREN REG
829 COLON expr COMMA REG COLON expr RPAREN aligndir
831 if
(!IS_DREG
($2) ||
!IS_DREG
($4))
832 return
yyerror ("Dregs expected");
833 else if
(REG_SAME
($2, $4))
834 return
yyerror ("Illegal dest register combination");
835 else if
(!valid_dreg_pair
(&$9, $11))
836 return
yyerror ("Bad dreg pair");
837 else if
(!valid_dreg_pair
(&$13, $15))
838 return
yyerror ("Bad dreg pair");
841 notethat
("dsp32alu: (dregs , dregs ) = BYTEOP16P (dregs_pair , dregs_pair ) (aligndir)\n");
842 $$
= DSP32ALU
(21, 0, &$2, &$4, &$9, &$13, $17.r0
, 0, 0);
846 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEOP16M LPAREN REG COLON expr COMMA
847 REG COLON expr RPAREN aligndir
849 if
(!IS_DREG
($2) ||
!IS_DREG
($4))
850 return
yyerror ("Dregs expected");
851 else if
(REG_SAME
($2, $4))
852 return
yyerror ("Illegal dest register combination");
853 else if
(!valid_dreg_pair
(&$9, $11))
854 return
yyerror ("Bad dreg pair");
855 else if
(!valid_dreg_pair
(&$13, $15))
856 return
yyerror ("Bad dreg pair");
859 notethat
("dsp32alu: (dregs , dregs ) = BYTEOP16M (dregs_pair , dregs_pair ) (aligndir)\n");
860 $$
= DSP32ALU
(21, 0, &$2, &$4, &$9, &$13, $17.r0
, 0, 1);
864 | LPAREN REG COMMA REG RPAREN ASSIGN BYTEUNPACK REG COLON expr aligndir
866 if
(!IS_DREG
($2) ||
!IS_DREG
($4))
867 return
yyerror ("Dregs expected");
868 else if
(REG_SAME
($2, $4))
869 return
yyerror ("Illegal dest register combination");
870 else if
(!valid_dreg_pair
(&$8, $10))
871 return
yyerror ("Bad dreg pair");
874 notethat
("dsp32alu: (dregs , dregs ) = BYTEUNPACK dregs_pair (aligndir)\n");
875 $$
= DSP32ALU
(24, 0, &$2, &$4, &$8, 0, $11.r0
, 0, 1);
878 | LPAREN REG COMMA REG RPAREN ASSIGN SEARCH REG LPAREN searchmod RPAREN
880 if
(REG_SAME
($2, $4))
881 return
yyerror ("Illegal dest register combination");
883 if
(IS_DREG
($2) && IS_DREG
($4) && IS_DREG
($8))
885 notethat
("dsp32alu: (dregs , dregs ) = SEARCH dregs (searchmod)\n");
886 $$
= DSP32ALU
(13, 0, &$2, &$4, &$8, 0, 0, 0, $10.r0
);
889 return
yyerror ("Register mismatch");
891 | REG ASSIGN A_ONE_DOT_L PLUS A_ONE_DOT_H COMMA
892 REG ASSIGN A_ZERO_DOT_L PLUS A_ZERO_DOT_H
894 if
(REG_SAME
($1, $7))
895 return
yyerror ("Illegal dest register combination");
897 if
(IS_DREG
($1) && IS_DREG
($7))
899 notethat
("dsp32alu: dregs = A1.l + A1.h, dregs = A0.l + A0.h \n");
900 $$
= DSP32ALU
(12, 0, &$1, &$7, ®7
, ®7
, 0, 0, 1);
903 return
yyerror ("Register mismatch");
907 | REG ASSIGN REG_A PLUS REG_A COMMA REG ASSIGN REG_A MINUS REG_A amod1
909 if
(REG_SAME
($1, $7))
910 return
yyerror ("Resource conflict in dest reg");
912 if
(IS_DREG
($1) && IS_DREG
($7) && !REG_SAME
($3, $5)
913 && IS_A1
($9) && !IS_A1
($11))
915 notethat
("dsp32alu: dregs = A1 + A0 , dregs = A1 - A0 (amod1)\n");
916 $$
= DSP32ALU
(17, 0, &$1, &$7, ®7
, ®7
, $12.s0
, $12.x0
, 0);
919 else if
(IS_DREG
($1) && IS_DREG
($7) && !REG_SAME
($3, $5)
920 && !IS_A1
($9) && IS_A1
($11))
922 notethat
("dsp32alu: dregs = A0 + A1 , dregs = A0 - A1 (amod1)\n");
923 $$
= DSP32ALU
(17, 0, &$1, &$7, ®7
, ®7
, $12.s0
, $12.x0
, 1);
926 return
yyerror ("Register mismatch");
929 | REG ASSIGN REG plus_minus REG COMMA REG ASSIGN REG plus_minus REG amod1
932 return
yyerror ("Operators must differ");
934 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5)
935 && REG_SAME
($3, $9) && REG_SAME
($5, $11))
937 notethat
("dsp32alu: dregs = dregs + dregs,"
938 "dregs = dregs - dregs (amod1)\n");
939 $$
= DSP32ALU
(4, 0, &$1, &$7, &$3, &$5, $12.s0
, $12.x0
, 2);
942 return
yyerror ("Register mismatch");
945 /* Bar Operations. */
947 | REG ASSIGN REG op_bar_op REG COMMA REG ASSIGN REG op_bar_op REG amod2
949 if
(!REG_SAME
($3, $9) ||
!REG_SAME
($5, $11))
950 return
yyerror ("Differing source registers");
952 if
(!IS_DREG
($1) ||
!IS_DREG
($3) ||
!IS_DREG
($5) ||
!IS_DREG
($7))
953 return
yyerror ("Dregs expected");
955 if
(REG_SAME
($1, $7))
956 return
yyerror ("Resource conflict in dest reg");
958 if
($4.r0
== 1 && $10.r0
== 2)
960 notethat
("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n");
961 $$
= DSP32ALU
(1, 1, &$1, &$7, &$3, &$5, $12.s0
, $12.x0
, $12.r0
);
963 else if
($4.r0
== 0 && $10.r0
== 3)
965 notethat
("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n");
966 $$
= DSP32ALU
(1, 0, &$1, &$7, &$3, &$5, $12.s0
, $12.x0
, $12.r0
);
969 return
yyerror ("Bar operand mismatch");
972 | REG ASSIGN ABS REG vmod
976 if
(IS_DREG
($1) && IS_DREG
($4))
980 notethat
("dsp32alu: dregs = ABS dregs (v)\n");
985 /* Vector version of ABS. */
986 notethat
("dsp32alu: dregs = ABS dregs\n");
989 $$
= DSP32ALU
(op
, 0, 0, &$1, &$4, 0, 0, 0, 2);
992 return
yyerror ("Dregs expected");
996 notethat
("dsp32alu: Ax = ABS Ax\n");
997 $$
= DSP32ALU
(16, IS_A1
($1), 0, 0, ®7
, ®7
, 0, 0, IS_A1
($3));
999 | A_ZERO_DOT_L ASSIGN HALF_REG
1003 notethat
("dsp32alu: A0.l = reg_half\n");
1004 $$
= DSP32ALU
(9, IS_H
($3), 0, 0, &$3, 0, 0, 0, 0);
1007 return
yyerror ("A0.l = Rx.l expected");
1009 | A_ONE_DOT_L ASSIGN HALF_REG
1013 notethat
("dsp32alu: A1.l = reg_half\n");
1014 $$
= DSP32ALU
(9, IS_H
($3), 0, 0, &$3, 0, 0, 0, 2);
1017 return
yyerror ("A1.l = Rx.l expected");
1020 | REG ASSIGN c_align LPAREN REG COMMA REG RPAREN
1022 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
1024 notethat
("dsp32shift: dregs = ALIGN8 (dregs , dregs )\n");
1025 $$
= DSP32SHIFT
(13, &$1, &$7, &$5, $3.r0
, 0);
1028 return
yyerror ("Dregs expected");
1031 | REG ASSIGN BYTEOP1P LPAREN REG COLON expr COMMA REG COLON expr RPAREN byteop_mod
1034 return
yyerror ("Dregs expected");
1035 else if
(!valid_dreg_pair
(&$5, $7))
1036 return
yyerror ("Bad dreg pair");
1037 else if
(!valid_dreg_pair
(&$9, $11))
1038 return
yyerror ("Bad dreg pair");
1041 notethat
("dsp32alu: dregs = BYTEOP1P (dregs_pair , dregs_pair ) (T)\n");
1042 $$
= DSP32ALU
(20, 0, 0, &$1, &$5, &$9, $13.s0
, 0, $13.r0
);
1045 | REG ASSIGN BYTEOP1P LPAREN REG COLON expr COMMA REG COLON expr RPAREN
1048 return
yyerror ("Dregs expected");
1049 else if
(!valid_dreg_pair
(&$5, $7))
1050 return
yyerror ("Bad dreg pair");
1051 else if
(!valid_dreg_pair
(&$9, $11))
1052 return
yyerror ("Bad dreg pair");
1055 notethat
("dsp32alu: dregs = BYTEOP1P (dregs_pair , dregs_pair ) (T)\n");
1056 $$
= DSP32ALU
(20, 0, 0, &$1, &$5, &$9, 0, 0, 0);
1060 | REG ASSIGN BYTEOP2P LPAREN REG COLON expr COMMA REG COLON expr RPAREN
1064 return
yyerror ("Dregs expected");
1065 else if
(!valid_dreg_pair
(&$5, $7))
1066 return
yyerror ("Bad dreg pair");
1067 else if
(!valid_dreg_pair
(&$9, $11))
1068 return
yyerror ("Bad dreg pair");
1071 notethat
("dsp32alu: dregs = BYTEOP2P (dregs_pair , dregs_pair ) (rnd_op)\n");
1072 $$
= DSP32ALU
(22, $13.r0
, 0, &$1, &$5, &$9, $13.s0
, $13.x0
, $13.aop
);
1076 | REG ASSIGN BYTEOP3P LPAREN REG COLON expr COMMA REG COLON expr RPAREN
1080 return
yyerror ("Dregs expected");
1081 else if
(!valid_dreg_pair
(&$5, $7))
1082 return
yyerror ("Bad dreg pair");
1083 else if
(!valid_dreg_pair
(&$9, $11))
1084 return
yyerror ("Bad dreg pair");
1087 notethat
("dsp32alu: dregs = BYTEOP3P (dregs_pair , dregs_pair ) (b3_op)\n");
1088 $$
= DSP32ALU
(23, $13.x0
, 0, &$1, &$5, &$9, $13.s0
, 0, 0);
1092 | REG ASSIGN BYTEPACK LPAREN REG COMMA REG RPAREN
1094 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
1096 notethat
("dsp32alu: dregs = BYTEPACK (dregs , dregs )\n");
1097 $$
= DSP32ALU
(24, 0, 0, &$1, &$5, &$7, 0, 0, 0);
1100 return
yyerror ("Dregs expected");
1103 | HALF_REG ASSIGN HALF_REG ASSIGN SIGN LPAREN HALF_REG RPAREN STAR
1104 HALF_REG PLUS SIGN LPAREN HALF_REG RPAREN STAR HALF_REG
1106 if
(IS_HCOMPL
($1, $3) && IS_HCOMPL
($7, $14) && IS_HCOMPL
($10, $17))
1108 notethat
("dsp32alu: dregs_hi = dregs_lo ="
1109 "SIGN (dregs_hi) * dregs_hi + "
1110 "SIGN (dregs_lo) * dregs_lo \n");
1112 $$
= DSP32ALU
(12, 0, 0, &$1, &$7, &$10, 0, 0, 0);
1115 return
yyerror ("Dregs expected");
1117 | REG ASSIGN REG plus_minus REG amod1
1119 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5))
1123 /* No saturation flag specified, generate the 16 bit variant. */
1124 notethat
("COMP3op: dregs = dregs +- dregs\n");
1125 $$
= COMP3OP
(&$1, &$3, &$5, $4.r0
);
1129 /* Saturation flag specified, generate the 32 bit variant. */
1130 notethat
("dsp32alu: dregs = dregs +- dregs (amod1)\n");
1131 $$
= DSP32ALU
(4, 0, 0, &$1, &$3, &$5, $6.s0
, $6.x0
, $4.r0
);
1135 if
(IS_PREG
($1) && IS_PREG
($3) && IS_PREG
($5) && $4.r0
== 0)
1137 notethat
("COMP3op: pregs = pregs + pregs\n");
1138 $$
= COMP3OP
(&$1, &$3, &$5, 5);
1141 return
yyerror ("Dregs expected");
1143 | REG ASSIGN min_max LPAREN REG COMMA REG RPAREN vmod
1147 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
1154 notethat
("dsp32alu: dregs = {MIN|MAX} (dregs, dregs)\n");
1155 $$
= DSP32ALU
(op
, 0, 0, &$1, &$5, &$7, 0, 0, $3.r0
);
1158 return
yyerror ("Dregs expected");
1161 | a_assign MINUS REG_A
1163 notethat
("dsp32alu: Ax = - Ax\n");
1164 $$
= DSP32ALU
(14, IS_A1
($1), 0, 0, ®7
, ®7
, 0, 0, IS_A1
($3));
1166 | HALF_REG ASSIGN HALF_REG plus_minus HALF_REG amod1
1168 notethat
("dsp32alu: dregs_lo = dregs_lo +- dregs_lo (amod1)\n");
1169 $$
= DSP32ALU
(2 |
$4.r0
, IS_H
($1), 0, &$1, &$3, &$5,
1170 $6.s0
, $6.x0
, HL2
($3, $5));
1172 | a_assign a_assign expr
1174 if
(EXPR_VALUE
($3) == 0 && !REG_SAME
($1, $2))
1176 notethat
("dsp32alu: A1 = A0 = 0\n");
1177 $$
= DSP32ALU
(8, 0, 0, 0, ®7
, ®7
, 0, 0, 2);
1180 return
yyerror ("Bad value, 0 expected");
1184 | a_assign REG_A LPAREN S RPAREN
1186 if
(REG_SAME
($1, $2))
1188 notethat
("dsp32alu: Ax = Ax (S)\n");
1189 $$
= DSP32ALU
(8, 0, 0, 0, ®7
, ®7
, 1, 0, IS_A1
($1));
1192 return
yyerror ("Registers must be equal");
1195 | HALF_REG ASSIGN REG LPAREN RND RPAREN
1199 notethat
("dsp32alu: dregs_half = dregs (RND)\n");
1200 $$
= DSP32ALU
(12, IS_H
($1), 0, &$1, &$3, 0, 0, 0, 3);
1203 return
yyerror ("Dregs expected");
1206 | HALF_REG ASSIGN REG plus_minus REG LPAREN RND12 RPAREN
1208 if
(IS_DREG
($3) && IS_DREG
($5))
1210 notethat
("dsp32alu: dregs_half = dregs (+-) dregs (RND12)\n");
1211 $$
= DSP32ALU
(5, IS_H
($1), 0, &$1, &$3, &$5, 0, 0, $4.r0
);
1214 return
yyerror ("Dregs expected");
1217 | HALF_REG ASSIGN REG plus_minus REG LPAREN RND20 RPAREN
1219 if
(IS_DREG
($3) && IS_DREG
($5))
1221 notethat
("dsp32alu: dregs_half = dregs -+ dregs (RND20)\n");
1222 $$
= DSP32ALU
(5, IS_H
($1), 0, &$1, &$3, &$5, 0, 1, $4.r0 |
2);
1225 return
yyerror ("Dregs expected");
1230 if
(!REG_SAME
($1, $2))
1232 notethat
("dsp32alu: An = Am\n");
1233 $$
= DSP32ALU
(8, 0, 0, 0, ®7
, ®7
, IS_A1
($1), 0, 3);
1236 return
yyerror ("Accu reg arguments must differ");
1243 notethat
("dsp32alu: An = dregs\n");
1244 $$
= DSP32ALU
(9, 0, 0, 0, &$2, 0, 1, 0, IS_A1
($1) << 1);
1247 return
yyerror ("Dregs expected");
1250 | REG ASSIGN HALF_REG xpmod
1254 if
($1.regno
== REG_A0x
&& IS_DREG
($3))
1256 notethat
("dsp32alu: A0.x = dregs_lo\n");
1257 $$
= DSP32ALU
(9, 0, 0, 0, &$3, 0, 0, 0, 1);
1259 else if
($1.regno
== REG_A1x
&& IS_DREG
($3))
1261 notethat
("dsp32alu: A1.x = dregs_lo\n");
1262 $$
= DSP32ALU
(9, 0, 0, 0, &$3, 0, 0, 0, 3);
1264 else if
(IS_DREG
($1) && IS_DREG
($3))
1266 notethat
("ALU2op: dregs = dregs_lo\n");
1267 $$
= ALU2OP
(&$1, &$3, 10 |
($4.r0 ?
0: 1));
1270 return
yyerror ("Register mismatch");
1273 return
yyerror ("Low reg expected");
1276 | HALF_REG ASSIGN expr
1278 notethat
("LDIMMhalf: pregs_half = imm16\n");
1280 if
(!IS_DREG
($1) && !IS_PREG
($1) && !IS_IREG
($1)
1281 && !IS_MREG
($1) && !IS_BREG
($1) && !IS_LREG
($1))
1282 return
yyerror ("Wrong register for load immediate");
1284 if
(!IS_IMM
($3, 16) && !IS_UIMM
($3, 16))
1285 return
yyerror ("Constant out of range");
1287 $$
= LDIMMHALF_R
(&$1, IS_H
($1), 0, 0, $3);
1292 notethat
("dsp32alu: An = 0\n");
1295 return
yyerror ("0 expected");
1297 $$
= DSP32ALU
(8, 0, 0, 0, 0, 0, 0, 0, IS_A1
($1));
1300 | REG ASSIGN expr xpmod1
1302 if
(!IS_DREG
($1) && !IS_PREG
($1) && !IS_IREG
($1)
1303 && !IS_MREG
($1) && !IS_BREG
($1) && !IS_LREG
($1))
1304 return
yyerror ("Wrong register for load immediate");
1308 /* 7 bit immediate value if possible.
1309 We will check for that constant value for efficiency
1310 If it goes to reloc, it will be 16 bit. */
1311 if
(IS_CONST
($3) && IS_IMM
($3, 7) && IS_DREG
($1))
1313 notethat
("COMPI2opD: dregs = imm7 (x) \n");
1314 $$
= COMPI2OPD
(&$1, imm7
($3), 0);
1316 else if
(IS_CONST
($3) && IS_IMM
($3, 7) && IS_PREG
($1))
1318 notethat
("COMPI2opP: pregs = imm7 (x)\n");
1319 $$
= COMPI2OPP
(&$1, imm7
($3), 0);
1323 if
(IS_CONST
($3) && !IS_IMM
($3, 16))
1324 return
yyerror ("Immediate value out of range");
1326 notethat
("LDIMMhalf: regs = luimm16 (x)\n");
1328 $$
= LDIMMHALF_R5
(&$1, 0, 1, 0, $3);
1333 /* (z) There is no 7 bit zero extended instruction.
1334 If the expr is a relocation, generate it. */
1336 if
(IS_CONST
($3) && !IS_UIMM
($3, 16))
1337 return
yyerror ("Immediate value out of range");
1339 notethat
("LDIMMhalf: regs = luimm16 (x)\n");
1341 $$
= LDIMMHALF_R5
(&$1, 0, 0, 1, $3);
1345 | HALF_REG ASSIGN REG
1348 return
yyerror ("Low reg expected");
1350 if
(IS_DREG
($1) && $3.regno
== REG_A0x
)
1352 notethat
("dsp32alu: dregs_lo = A0.x\n");
1353 $$
= DSP32ALU
(10, 0, 0, &$1, ®7
, ®7
, 0, 0, 0);
1355 else if
(IS_DREG
($1) && $3.regno
== REG_A1x
)
1357 notethat
("dsp32alu: dregs_lo = A1.x\n");
1358 $$
= DSP32ALU
(10, 0, 0, &$1, ®7
, ®7
, 0, 0, 1);
1361 return
yyerror ("Register mismatch");
1364 | REG ASSIGN REG op_bar_op REG amod0
1366 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5))
1368 notethat
("dsp32alu: dregs = dregs .|. dregs (amod0)\n");
1369 $$
= DSP32ALU
(0, 0, 0, &$1, &$3, &$5, $6.s0
, $6.x0
, $4.r0
);
1372 return
yyerror ("Register mismatch");
1375 | REG ASSIGN BYTE_DREG xpmod
1377 if
(IS_DREG
($1) && IS_DREG
($3))
1379 notethat
("ALU2op: dregs = dregs_byte\n");
1380 $$
= ALU2OP
(&$1, &$3, 12 |
($4.r0 ?
0: 1));
1383 return
yyerror ("Register mismatch");
1386 | a_assign ABS REG_A COMMA a_assign ABS REG_A
1388 if
(REG_SAME
($1, $3) && REG_SAME
($5, $7) && !REG_SAME
($1, $5))
1390 notethat
("dsp32alu: A1 = ABS A1 , A0 = ABS A0\n");
1391 $$
= DSP32ALU
(16, 0, 0, 0, ®7
, ®7
, 0, 0, 3);
1394 return
yyerror ("Register mismatch");
1397 | a_assign MINUS REG_A COMMA a_assign MINUS REG_A
1399 if
(REG_SAME
($1, $3) && REG_SAME
($5, $7) && !REG_SAME
($1, $5))
1401 notethat
("dsp32alu: A1 = - A1 , A0 = - A0\n");
1402 $$
= DSP32ALU
(14, 0, 0, 0, ®7
, ®7
, 0, 0, 3);
1405 return
yyerror ("Register mismatch");
1408 | a_minusassign REG_A w32_or_nothing
1410 if
(!IS_A1
($1) && IS_A1
($2))
1412 notethat
("dsp32alu: A0 -= A1\n");
1413 $$
= DSP32ALU
(11, 0, 0, 0, ®7
, ®7
, $3.r0
, 0, 3);
1416 return
yyerror ("Register mismatch");
1419 | REG _MINUS_ASSIGN expr
1421 if
(IS_IREG
($1) && EXPR_VALUE
($3) == 4)
1423 notethat
("dagMODik: iregs -= 4\n");
1424 $$
= DAGMODIK
(&$1, 3);
1426 else if
(IS_IREG
($1) && EXPR_VALUE
($3) == 2)
1428 notethat
("dagMODik: iregs -= 2\n");
1429 $$
= DAGMODIK
(&$1, 1);
1432 return
yyerror ("Register or value mismatch");
1435 | REG _PLUS_ASSIGN REG LPAREN BREV RPAREN
1437 if
(IS_IREG
($1) && IS_MREG
($3))
1439 notethat
("dagMODim: iregs += mregs (opt_brev)\n");
1441 $$
= DAGMODIM
(&$1, &$3, 0, 1);
1443 else if
(IS_PREG
($1) && IS_PREG
($3))
1445 notethat
("PTR2op: pregs += pregs (BREV )\n");
1446 $$
= PTR2OP
(&$1, &$3, 5);
1449 return
yyerror ("Register mismatch");
1452 | REG _MINUS_ASSIGN REG
1454 if
(IS_IREG
($1) && IS_MREG
($3))
1456 notethat
("dagMODim: iregs -= mregs\n");
1457 $$
= DAGMODIM
(&$1, &$3, 1, 0);
1459 else if
(IS_PREG
($1) && IS_PREG
($3))
1461 notethat
("PTR2op: pregs -= pregs\n");
1462 $$
= PTR2OP
(&$1, &$3, 0);
1465 return
yyerror ("Register mismatch");
1468 | REG_A _PLUS_ASSIGN REG_A w32_or_nothing
1470 if
(!IS_A1
($1) && IS_A1
($3))
1472 notethat
("dsp32alu: A0 += A1 (W32)\n");
1473 $$
= DSP32ALU
(11, 0, 0, 0, ®7
, ®7
, $4.r0
, 0, 2);
1476 return
yyerror ("Register mismatch");
1479 | REG _PLUS_ASSIGN REG
1481 if
(IS_IREG
($1) && IS_MREG
($3))
1483 notethat
("dagMODim: iregs += mregs\n");
1484 $$
= DAGMODIM
(&$1, &$3, 0, 0);
1487 return
yyerror ("iregs += mregs expected");
1490 | REG _PLUS_ASSIGN expr
1494 if
(EXPR_VALUE
($3) == 4)
1496 notethat
("dagMODik: iregs += 4\n");
1497 $$
= DAGMODIK
(&$1, 2);
1499 else if
(EXPR_VALUE
($3) == 2)
1501 notethat
("dagMODik: iregs += 2\n");
1502 $$
= DAGMODIK
(&$1, 0);
1505 return
yyerror ("iregs += [ 2 | 4 ");
1507 else if
(IS_PREG
($1) && IS_IMM
($3, 7))
1509 notethat
("COMPI2opP: pregs += imm7\n");
1510 $$
= COMPI2OPP
(&$1, imm7
($3), 1);
1512 else if
(IS_DREG
($1) && IS_IMM
($3, 7))
1514 notethat
("COMPI2opD: dregs += imm7\n");
1515 $$
= COMPI2OPD
(&$1, imm7
($3), 1);
1517 else if
((IS_DREG
($1) || IS_PREG
($1)) && IS_CONST
($3))
1518 return
yyerror ("Immediate value out of range");
1520 return
yyerror ("Register mismatch");
1523 | REG _STAR_ASSIGN REG
1525 if
(IS_DREG
($1) && IS_DREG
($3))
1527 notethat
("ALU2op: dregs *= dregs\n");
1528 $$
= ALU2OP
(&$1, &$3, 3);
1531 return
yyerror ("Register mismatch");
1534 | SAA LPAREN REG COLON expr COMMA REG COLON expr RPAREN aligndir
1536 if
(!valid_dreg_pair
(&$3, $5))
1537 return
yyerror ("Bad dreg pair");
1538 else if
(!valid_dreg_pair
(&$7, $9))
1539 return
yyerror ("Bad dreg pair");
1542 notethat
("dsp32alu: SAA (dregs_pair , dregs_pair ) (aligndir)\n");
1543 $$
= DSP32ALU
(18, 0, 0, 0, &$3, &$7, $11.r0
, 0, 0);
1547 | a_assign REG_A LPAREN S RPAREN COMMA a_assign REG_A LPAREN S RPAREN
1549 if
(REG_SAME
($1, $2) && REG_SAME
($7, $8) && !REG_SAME
($1, $7))
1551 notethat
("dsp32alu: A1 = A1 (S) , A0 = A0 (S)\n");
1552 $$
= DSP32ALU
(8, 0, 0, 0, ®7
, ®7
, 1, 0, 2);
1555 return
yyerror ("Register mismatch");
1558 | REG ASSIGN LPAREN REG PLUS REG RPAREN LESS_LESS expr
1560 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG
($6)
1561 && REG_SAME
($1, $4))
1563 if
(EXPR_VALUE
($9) == 1)
1565 notethat
("ALU2op: dregs = (dregs + dregs) << 1\n");
1566 $$
= ALU2OP
(&$1, &$6, 4);
1568 else if
(EXPR_VALUE
($9) == 2)
1570 notethat
("ALU2op: dregs = (dregs + dregs) << 2\n");
1571 $$
= ALU2OP
(&$1, &$6, 5);
1574 return
yyerror ("Bad shift value");
1576 else if
(IS_PREG
($1) && IS_PREG
($4) && IS_PREG
($6)
1577 && REG_SAME
($1, $4))
1579 if
(EXPR_VALUE
($9) == 1)
1581 notethat
("PTR2op: pregs = (pregs + pregs) << 1\n");
1582 $$
= PTR2OP
(&$1, &$6, 6);
1584 else if
(EXPR_VALUE
($9) == 2)
1586 notethat
("PTR2op: pregs = (pregs + pregs) << 2\n");
1587 $$
= PTR2OP
(&$1, &$6, 7);
1590 return
yyerror ("Bad shift value");
1593 return
yyerror ("Register mismatch");
1597 | REG ASSIGN REG BAR REG
1599 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5))
1601 notethat
("COMP3op: dregs = dregs | dregs\n");
1602 $$
= COMP3OP
(&$1, &$3, &$5, 3);
1605 return
yyerror ("Dregs expected");
1607 | REG ASSIGN REG CARET REG
1609 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5))
1611 notethat
("COMP3op: dregs = dregs ^ dregs\n");
1612 $$
= COMP3OP
(&$1, &$3, &$5, 4);
1615 return
yyerror ("Dregs expected");
1617 | REG ASSIGN REG PLUS LPAREN REG LESS_LESS expr RPAREN
1619 if
(IS_PREG
($1) && IS_PREG
($3) && IS_PREG
($6))
1621 if
(EXPR_VALUE
($8) == 1)
1623 notethat
("COMP3op: pregs = pregs + (pregs << 1)\n");
1624 $$
= COMP3OP
(&$1, &$3, &$6, 6);
1626 else if
(EXPR_VALUE
($8) == 2)
1628 notethat
("COMP3op: pregs = pregs + (pregs << 2)\n");
1629 $$
= COMP3OP
(&$1, &$3, &$6, 7);
1632 return
yyerror ("Bad shift value");
1635 return
yyerror ("Dregs expected");
1637 | CCREG ASSIGN REG_A _ASSIGN_ASSIGN REG_A
1639 if
($3.regno
== REG_A0
&& $5.regno
== REG_A1
)
1641 notethat
("CCflag: CC = A0 == A1\n");
1642 $$
= CCFLAG
(0, 0, 5, 0, 0);
1645 return
yyerror ("AREGs are in bad order or same");
1647 | CCREG ASSIGN REG_A LESS_THAN REG_A
1649 if
($3.regno
== REG_A0
&& $5.regno
== REG_A1
)
1651 notethat
("CCflag: CC = A0 < A1\n");
1652 $$
= CCFLAG
(0, 0, 6, 0, 0);
1655 return
yyerror ("AREGs are in bad order or same");
1657 | CCREG ASSIGN REG LESS_THAN REG iu_or_nothing
1659 if
((IS_DREG
($3) && IS_DREG
($5))
1660 ||
(IS_PREG
($3) && IS_PREG
($5)))
1662 notethat
("CCflag: CC = dpregs < dpregs\n");
1663 $$
= CCFLAG
(&$3, $5.regno
& CODE_MASK
, $6.r0
, 0, IS_PREG
($3) ?
1 : 0);
1666 return
yyerror ("Bad register in comparison");
1668 | CCREG ASSIGN REG LESS_THAN expr iu_or_nothing
1670 if
(!IS_DREG
($3) && !IS_PREG
($3))
1671 return
yyerror ("Bad register in comparison");
1673 if
(($6.r0
== 1 && IS_IMM
($5, 3))
1674 ||
($6.r0
== 3 && IS_UIMM
($5, 3)))
1676 notethat
("CCflag: CC = dpregs < (u)imm3\n");
1677 $$
= CCFLAG
(&$3, imm3
($5), $6.r0
, 1, IS_PREG
($3) ?
1 : 0);
1680 return
yyerror ("Bad constant value");
1682 | CCREG ASSIGN REG _ASSIGN_ASSIGN REG
1684 if
((IS_DREG
($3) && IS_DREG
($5))
1685 ||
(IS_PREG
($3) && IS_PREG
($5)))
1687 notethat
("CCflag: CC = dpregs == dpregs\n");
1688 $$
= CCFLAG
(&$3, $5.regno
& CODE_MASK
, 0, 0, IS_PREG
($3) ?
1 : 0);
1691 return
yyerror ("Bad register in comparison");
1693 | CCREG ASSIGN REG _ASSIGN_ASSIGN expr
1695 if
(!IS_DREG
($3) && !IS_PREG
($3))
1696 return
yyerror ("Bad register in comparison");
1700 notethat
("CCflag: CC = dpregs == imm3\n");
1701 $$
= CCFLAG
(&$3, imm3
($5), 0, 1, IS_PREG
($3) ?
1 : 0);
1704 return
yyerror ("Bad constant range");
1706 | CCREG ASSIGN REG_A _LESS_THAN_ASSIGN REG_A
1708 if
($3.regno
== REG_A0
&& $5.regno
== REG_A1
)
1710 notethat
("CCflag: CC = A0 <= A1\n");
1711 $$
= CCFLAG
(0, 0, 7, 0, 0);
1714 return
yyerror ("AREGs are in bad order or same");
1716 | CCREG ASSIGN REG _LESS_THAN_ASSIGN REG iu_or_nothing
1718 if
((IS_DREG
($3) && IS_DREG
($5))
1719 ||
(IS_PREG
($3) && IS_PREG
($5)))
1721 notethat
("CCflag: CC = dpregs <= dpregs (..)\n");
1722 $$
= CCFLAG
(&$3, $5.regno
& CODE_MASK
,
1723 1 + $6.r0
, 0, IS_PREG
($3) ?
1 : 0);
1726 return
yyerror ("Bad register in comparison");
1728 | CCREG ASSIGN REG _LESS_THAN_ASSIGN expr iu_or_nothing
1730 if
(!IS_DREG
($3) && !IS_PREG
($3))
1731 return
yyerror ("Bad register in comparison");
1733 if
(($6.r0
== 1 && IS_IMM
($5, 3))
1734 ||
($6.r0
== 3 && IS_UIMM
($5, 3)))
1736 notethat
("CCflag: CC = dpregs <= (u)imm3\n");
1737 $$
= CCFLAG
(&$3, imm3
($5), 1 + $6.r0
, 1, IS_PREG
($3) ?
1 : 0);
1740 return
yyerror ("Bad constant value");
1743 | REG ASSIGN REG AMPERSAND REG
1745 if
(IS_DREG
($1) && IS_DREG
($3) && IS_DREG
($5))
1747 notethat
("COMP3op: dregs = dregs & dregs\n");
1748 $$
= COMP3OP
(&$1, &$3, &$5, 2);
1751 return
yyerror ("Dregs expected");
1756 notethat
("CC2stat operation\n");
1757 $$
= bfin_gen_cc2stat
($1.r0
, $1.x0
, $1.s0
);
1762 if
((IS_GENREG
($1) && IS_GENREG
($3))
1763 ||
(IS_GENREG
($1) && IS_DAGREG
($3))
1764 ||
(IS_DAGREG
($1) && IS_GENREG
($3))
1765 ||
(IS_DAGREG
($1) && IS_DAGREG
($3))
1766 ||
(IS_GENREG
($1) && $3.regno
== REG_USP
)
1767 ||
($1.regno
== REG_USP
&& IS_GENREG
($3))
1768 ||
($1.regno
== REG_USP
&& $3.regno
== REG_USP
)
1769 ||
(IS_DREG
($1) && IS_SYSREG
($3))
1770 ||
(IS_PREG
($1) && IS_SYSREG
($3))
1771 ||
(IS_SYSREG
($1) && IS_GENREG
($3))
1772 ||
(IS_ALLREG
($1) && IS_EMUDAT
($3))
1773 ||
(IS_EMUDAT
($1) && IS_ALLREG
($3))
1774 ||
(IS_SYSREG
($1) && $3.regno
== REG_USP
))
1776 $$
= bfin_gen_regmv
(&$3, &$1);
1779 return
yyerror ("Unsupported register move");
1786 notethat
("CC2dreg: CC = dregs\n");
1787 $$
= bfin_gen_cc2dreg
(1, &$3);
1790 return
yyerror ("Only 'CC = Dreg' supported");
1797 notethat
("CC2dreg: dregs = CC\n");
1798 $$
= bfin_gen_cc2dreg
(0, &$1);
1801 return
yyerror ("Only 'Dreg = CC' supported");
1804 | CCREG _ASSIGN_BANG CCREG
1806 notethat
("CC2dreg: CC =! CC\n");
1807 $$
= bfin_gen_cc2dreg
(3, 0);
1812 | HALF_REG ASSIGN multiply_halfregs opt_mode
1814 notethat
("dsp32mult: dregs_half = multiply_halfregs (opt_mode)\n");
1816 if
(!IS_H
($1) && $4.MM
)
1817 return
yyerror ("(M) not allowed with MAC0");
1819 if
($4.mod
!= 0 && $4.mod
!= M_FU
&& $4.mod
!= M_IS
1820 && $4.mod
!= M_IU
&& $4.mod
!= M_T
&& $4.mod
!= M_TFU
1821 && $4.mod
!= M_S2RND
&& $4.mod
!= M_ISS2
&& $4.mod
!= M_IH
)
1822 return
yyerror ("bad option.");
1826 $$
= DSP32MULT
(0, $4.MM
, $4.mod
, 1, 0,
1827 IS_H
($3.s0
), IS_H
($3.s1
), 0, 0,
1828 &$1, 0, &$3.s0
, &$3.s1
, 0);
1832 $$
= DSP32MULT
(0, 0, $4.mod
, 0, 0,
1833 0, 0, IS_H
($3.s0
), IS_H
($3.s1
),
1834 &$1, 0, &$3.s0
, &$3.s1
, 1);
1838 | REG ASSIGN multiply_halfregs opt_mode
1840 /* Odd registers can use (M). */
1842 return
yyerror ("Dreg expected");
1844 if
(IS_EVEN
($1) && $4.MM
)
1845 return
yyerror ("(M) not allowed with MAC0");
1847 if
($4.mod
!= 0 && $4.mod
!= M_FU
&& $4.mod
!= M_IS
1848 && $4.mod
!= M_S2RND
&& $4.mod
!= M_ISS2
)
1849 return
yyerror ("bad option");
1853 notethat
("dsp32mult: dregs = multiply_halfregs (opt_mode)\n");
1855 $$
= DSP32MULT
(0, $4.MM
, $4.mod
, 1, 1,
1856 IS_H
($3.s0
), IS_H
($3.s1
), 0, 0,
1857 &$1, 0, &$3.s0
, &$3.s1
, 0);
1861 notethat
("dsp32mult: dregs = multiply_halfregs opt_mode\n");
1862 $$
= DSP32MULT
(0, 0, $4.mod
, 0, 1,
1863 0, 0, IS_H
($3.s0
), IS_H
($3.s1
),
1864 &$1, 0, &$3.s0
, &$3.s1
, 1);
1868 | HALF_REG ASSIGN multiply_halfregs opt_mode COMMA
1869 HALF_REG ASSIGN multiply_halfregs opt_mode
1871 if
(!IS_DREG
($1) ||
!IS_DREG
($6))
1872 return
yyerror ("Dregs expected");
1874 if
(!IS_HCOMPL
($1, $6))
1875 return
yyerror ("Dest registers mismatch");
1877 if
(check_multiply_halfregs
(&$3, &$8) < 0)
1880 if
((!IS_H
($1) && $4.MM
)
1881 ||
(!IS_H
($6) && $9.MM
))
1882 return
yyerror ("(M) not allowed with MAC0");
1884 notethat
("dsp32mult: dregs_hi = multiply_halfregs mxd_mod, "
1885 "dregs_lo = multiply_halfregs opt_mode\n");
1888 $$
= DSP32MULT
(0, $4.MM
, $9.mod
, 1, 0,
1889 IS_H
($3.s0
), IS_H
($3.s1
), IS_H
($8.s0
), IS_H
($8.s1
),
1890 &$1, 0, &$3.s0
, &$3.s1
, 1);
1892 $$
= DSP32MULT
(0, $9.MM
, $9.mod
, 1, 0,
1893 IS_H
($8.s0
), IS_H
($8.s1
), IS_H
($3.s0
), IS_H
($3.s1
),
1894 &$1, 0, &$3.s0
, &$3.s1
, 1);
1897 | REG ASSIGN multiply_halfregs opt_mode COMMA REG ASSIGN multiply_halfregs opt_mode
1899 if
(!IS_DREG
($1) ||
!IS_DREG
($6))
1900 return
yyerror ("Dregs expected");
1902 if
((IS_EVEN
($1) && $6.regno
- $1.regno
!= 1)
1903 ||
(IS_EVEN
($6) && $1.regno
- $6.regno
!= 1))
1904 return
yyerror ("Dest registers mismatch");
1906 if
(check_multiply_halfregs
(&$3, &$8) < 0)
1909 if
((IS_EVEN
($1) && $4.MM
)
1910 ||
(IS_EVEN
($6) && $9.MM
))
1911 return
yyerror ("(M) not allowed with MAC0");
1913 notethat
("dsp32mult: dregs = multiply_halfregs mxd_mod, "
1914 "dregs = multiply_halfregs opt_mode\n");
1917 $$
= DSP32MULT
(0, $9.MM
, $9.mod
, 1, 1,
1918 IS_H
($8.s0
), IS_H
($8.s1
), IS_H
($3.s0
), IS_H
($3.s1
),
1919 &$1, 0, &$3.s0
, &$3.s1
, 1);
1921 $$
= DSP32MULT
(0, $4.MM
, $9.mod
, 1, 1,
1922 IS_H
($3.s0
), IS_H
($3.s1
), IS_H
($8.s0
), IS_H
($8.s1
),
1923 &$1, 0, &$3.s0
, &$3.s1
, 1);
1928 | a_assign ASHIFT REG_A BY HALF_REG
1930 if
(!REG_SAME
($1, $3))
1931 return
yyerror ("Aregs must be same");
1933 if
(IS_DREG
($5) && !IS_H
($5))
1935 notethat
("dsp32shift: A0 = ASHIFT A0 BY dregs_lo\n");
1936 $$
= DSP32SHIFT
(3, 0, &$5, 0, 0, IS_A1
($1));
1939 return
yyerror ("Dregs expected");
1942 | HALF_REG ASSIGN ASHIFT HALF_REG BY HALF_REG smod
1944 if
(IS_DREG
($6) && !IS_H
($6))
1946 notethat
("dsp32shift: dregs_half = ASHIFT dregs_half BY dregs_lo\n");
1947 $$
= DSP32SHIFT
(0, &$1, &$6, &$4, $7.s0
, HL2
($1, $4));
1950 return
yyerror ("Dregs expected");
1953 | a_assign REG_A LESS_LESS expr
1955 if
(!REG_SAME
($1, $2))
1956 return
yyerror ("Aregs must be same");
1958 if
(IS_UIMM
($4, 5))
1960 notethat
("dsp32shiftimm: A0 = A0 << uimm5\n");
1961 $$
= DSP32SHIFTIMM
(3, 0, imm5
($4), 0, 0, IS_A1
($1));
1964 return
yyerror ("Bad shift value");
1967 | REG ASSIGN REG LESS_LESS expr vsmod
1969 if
(IS_DREG
($1) && IS_DREG
($3) && IS_UIMM
($5, 5))
1974 notethat
("dsp32shiftimm: dregs = dregs << expr (V, .)\n");
1975 $$
= DSP32SHIFTIMM
(1, &$1, imm4
($5), &$3, $6.s0 ?
1 : 2, 0);
1979 notethat
("dsp32shiftimm: dregs = dregs << uimm5 (.)\n");
1980 $$
= DSP32SHIFTIMM
(2, &$1, imm6
($5), &$3, $6.s0 ?
1 : 2, 0);
1983 else if
($6.s0
== 0 && IS_PREG
($1) && IS_PREG
($3))
1985 if
(EXPR_VALUE
($5) == 2)
1987 notethat
("PTR2op: pregs = pregs << 2\n");
1988 $$
= PTR2OP
(&$1, &$3, 1);
1990 else if
(EXPR_VALUE
($5) == 1)
1992 notethat
("COMP3op: pregs = pregs << 1\n");
1993 $$
= COMP3OP
(&$1, &$3, &$3, 5);
1996 return
yyerror ("Bad shift value");
1999 return
yyerror ("Bad shift value or register");
2001 | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod
2003 if
(IS_UIMM
($5, 4))
2007 notethat
("dsp32shiftimm: dregs_half = dregs_half << uimm4 (S)\n");
2008 $$
= DSP32SHIFTIMM
(0x0, &$1, imm5
($5), &$3, $6.s0
, HL2
($1, $3));
2012 notethat
("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
2013 $$
= DSP32SHIFTIMM
(0x0, &$1, imm5
($5), &$3, 2, HL2
($1, $3));
2017 return
yyerror ("Bad shift value");
2019 | REG ASSIGN ASHIFT REG BY HALF_REG vsmod
2023 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG
($6) && !IS_H
($6))
2028 notethat
("dsp32shift: dregs = ASHIFT dregs BY "
2029 "dregs_lo (V, .)\n");
2035 notethat
("dsp32shift: dregs = ASHIFT dregs BY dregs_lo (.)\n");
2037 $$
= DSP32SHIFT
(op
, &$1, &$6, &$4, $7.s0
, 0);
2040 return
yyerror ("Dregs expected");
2044 | HALF_REG ASSIGN EXPADJ LPAREN REG COMMA HALF_REG RPAREN vmod
2046 if
(IS_DREG_L
($1) && IS_DREG_L
($5) && IS_DREG_L
($7))
2048 notethat
("dsp32shift: dregs_lo = EXPADJ (dregs , dregs_lo )\n");
2049 $$
= DSP32SHIFT
(7, &$1, &$7, &$5, $9.r0
, 0);
2052 return
yyerror ("Bad shift value or register");
2056 | HALF_REG ASSIGN EXPADJ LPAREN HALF_REG COMMA HALF_REG RPAREN
2058 if
(IS_DREG_L
($1) && IS_DREG_L
($5) && IS_DREG_L
($7))
2060 notethat
("dsp32shift: dregs_lo = EXPADJ (dregs_lo, dregs_lo)\n");
2061 $$
= DSP32SHIFT
(7, &$1, &$7, &$5, 2, 0);
2063 else if
(IS_DREG_L
($1) && IS_DREG_H
($5) && IS_DREG_L
($7))
2065 notethat
("dsp32shift: dregs_lo = EXPADJ (dregs_hi, dregs_lo)\n");
2066 $$
= DSP32SHIFT
(7, &$1, &$7, &$5, 3, 0);
2069 return
yyerror ("Bad shift value or register");
2074 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN
2076 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
2078 notethat
("dsp32shift: dregs = DEPOSIT (dregs , dregs )\n");
2079 $$
= DSP32SHIFT
(10, &$1, &$7, &$5, 2, 0);
2082 return
yyerror ("Register mismatch");
2085 | REG ASSIGN DEPOSIT LPAREN REG COMMA REG RPAREN LPAREN X RPAREN
2087 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
2089 notethat
("dsp32shift: dregs = DEPOSIT (dregs , dregs ) (X)\n");
2090 $$
= DSP32SHIFT
(10, &$1, &$7, &$5, 3, 0);
2093 return
yyerror ("Register mismatch");
2096 | REG ASSIGN EXTRACT LPAREN REG COMMA HALF_REG RPAREN xpmod
2098 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG_L
($7))
2100 notethat
("dsp32shift: dregs = EXTRACT (dregs, dregs_lo ) (.)\n");
2101 $$
= DSP32SHIFT
(10, &$1, &$7, &$5, $9.r0
, 0);
2104 return
yyerror ("Register mismatch");
2107 | a_assign REG_A _GREATER_GREATER_GREATER expr
2109 if
(!REG_SAME
($1, $2))
2110 return
yyerror ("Aregs must be same");
2112 if
(IS_UIMM
($4, 5))
2114 notethat
("dsp32shiftimm: Ax = Ax >>> uimm5\n");
2115 $$
= DSP32SHIFTIMM
(3, 0, -imm6
($4), 0, 0, IS_A1
($1));
2118 return
yyerror ("Shift value range error");
2120 | a_assign LSHIFT REG_A BY HALF_REG
2122 if
(REG_SAME
($1, $3) && IS_DREG_L
($5))
2124 notethat
("dsp32shift: Ax = LSHIFT Ax BY dregs_lo\n");
2125 $$
= DSP32SHIFT
(3, 0, &$5, 0, 1, IS_A1
($1));
2128 return
yyerror ("Register mismatch");
2131 | HALF_REG ASSIGN LSHIFT HALF_REG BY HALF_REG
2133 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG_L
($6))
2135 notethat
("dsp32shift: dregs_lo = LSHIFT dregs_hi BY dregs_lo\n");
2136 $$
= DSP32SHIFT
(0, &$1, &$6, &$4, 2, HL2
($1, $4));
2139 return
yyerror ("Register mismatch");
2142 | REG ASSIGN LSHIFT REG BY HALF_REG vmod
2144 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG_L
($6))
2146 notethat
("dsp32shift: dregs = LSHIFT dregs BY dregs_lo (V )\n");
2147 $$
= DSP32SHIFT
($7.r0 ?
1: 2, &$1, &$6, &$4, 2, 0);
2150 return
yyerror ("Register mismatch");
2153 | REG ASSIGN SHIFT REG BY HALF_REG
2155 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG_L
($6))
2157 notethat
("dsp32shift: dregs = SHIFT dregs BY dregs_lo\n");
2158 $$
= DSP32SHIFT
(2, &$1, &$6, &$4, 2, 0);
2161 return
yyerror ("Register mismatch");
2164 | a_assign REG_A GREATER_GREATER expr
2166 if
(REG_SAME
($1, $2) && IS_IMM
($4, 6) >= 0)
2168 notethat
("dsp32shiftimm: Ax = Ax >> imm6\n");
2169 $$
= DSP32SHIFTIMM
(3, 0, -imm6
($4), 0, 1, IS_A1
($1));
2172 return
yyerror ("Accu register expected");
2175 | REG ASSIGN REG GREATER_GREATER expr vmod
2179 if
(IS_DREG
($1) && IS_DREG
($3) && IS_UIMM
($5, 5))
2181 notethat
("dsp32shiftimm: dregs = dregs >> uimm5 (V)\n");
2182 $$
= DSP32SHIFTIMM
(1, &$1, -uimm5
($5), &$3, 2, 0);
2185 return
yyerror ("Register mismatch");
2189 if
(IS_DREG
($1) && IS_DREG
($3) && IS_UIMM
($5, 5))
2191 notethat
("dsp32shiftimm: dregs = dregs >> uimm5\n");
2192 $$
= DSP32SHIFTIMM
(2, &$1, -imm6
($5), &$3, 2, 0);
2194 else if
(IS_PREG
($1) && IS_PREG
($3) && EXPR_VALUE
($5) == 2)
2196 notethat
("PTR2op: pregs = pregs >> 2\n");
2197 $$
= PTR2OP
(&$1, &$3, 3);
2199 else if
(IS_PREG
($1) && IS_PREG
($3) && EXPR_VALUE
($5) == 1)
2201 notethat
("PTR2op: pregs = pregs >> 1\n");
2202 $$
= PTR2OP
(&$1, &$3, 4);
2205 return
yyerror ("Register mismatch");
2208 | HALF_REG ASSIGN HALF_REG GREATER_GREATER expr
2210 if
(IS_UIMM
($5, 5))
2212 notethat
("dsp32shiftimm: dregs_half = dregs_half >> uimm5\n");
2213 $$
= DSP32SHIFTIMM
(0, &$1, -uimm5
($5), &$3, 2, HL2
($1, $3));
2216 return
yyerror ("Register mismatch");
2218 | HALF_REG ASSIGN HALF_REG _GREATER_GREATER_GREATER expr smod
2220 if
(IS_UIMM
($5, 5))
2222 notethat
("dsp32shiftimm: dregs_half = dregs_half >>> uimm5\n");
2223 $$
= DSP32SHIFTIMM
(0, &$1, -uimm5
($5), &$3,
2224 $6.s0
, HL2
($1, $3));
2227 return
yyerror ("Register or modifier mismatch");
2231 | REG ASSIGN REG _GREATER_GREATER_GREATER expr vsmod
2233 if
(IS_DREG
($1) && IS_DREG
($3) && IS_UIMM
($5, 5))
2238 notethat
("dsp32shiftimm: dregs = dregs >>> uimm5 (V, .)\n");
2239 $$
= DSP32SHIFTIMM
(1, &$1, -uimm5
($5), &$3, $6.s0
, 0);
2243 notethat
("dsp32shiftimm: dregs = dregs >>> uimm5 (.)\n");
2244 $$
= DSP32SHIFTIMM
(2, &$1, -uimm5
($5), &$3, $6.s0
, 0);
2248 return
yyerror ("Register mismatch");
2251 | HALF_REG ASSIGN ONES REG
2253 if
(IS_DREG_L
($1) && IS_DREG
($4))
2255 notethat
("dsp32shift: dregs_lo = ONES dregs\n");
2256 $$
= DSP32SHIFT
(6, &$1, 0, &$4, 3, 0);
2259 return
yyerror ("Register mismatch");
2262 | REG ASSIGN PACK LPAREN HALF_REG COMMA HALF_REG RPAREN
2264 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
2266 notethat
("dsp32shift: dregs = PACK (dregs_hi , dregs_hi )\n");
2267 $$
= DSP32SHIFT
(4, &$1, &$7, &$5, HL2
($5, $7), 0);
2270 return
yyerror ("Register mismatch");
2273 | HALF_REG ASSIGN CCREG ASSIGN BXORSHIFT LPAREN REG_A COMMA REG RPAREN
2276 && $7.regno
== REG_A0
2277 && IS_DREG
($9) && !IS_H
($1) && !IS_A1
($7))
2279 notethat
("dsp32shift: dregs_lo = CC = BXORSHIFT (A0 , dregs )\n");
2280 $$
= DSP32SHIFT
(11, &$1, &$9, 0, 0, 0);
2283 return
yyerror ("Register mismatch");
2286 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG RPAREN
2289 && $7.regno
== REG_A0
2290 && IS_DREG
($9) && !IS_H
($1) && !IS_A1
($7))
2292 notethat
("dsp32shift: dregs_lo = CC = BXOR (A0 , dregs)\n");
2293 $$
= DSP32SHIFT
(11, &$1, &$9, 0, 1, 0);
2296 return
yyerror ("Register mismatch");
2299 | HALF_REG ASSIGN CCREG ASSIGN BXOR LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN
2301 if
(IS_DREG
($1) && !IS_H
($1) && !REG_SAME
($7, $9))
2303 notethat
("dsp32shift: dregs_lo = CC = BXOR (A0 , A1 , CC)\n");
2304 $$
= DSP32SHIFT
(12, &$1, 0, 0, 1, 0);
2307 return
yyerror ("Register mismatch");
2310 | a_assign ROT REG_A BY HALF_REG
2312 if
(REG_SAME
($1, $3) && IS_DREG_L
($5))
2314 notethat
("dsp32shift: Ax = ROT Ax BY dregs_lo\n");
2315 $$
= DSP32SHIFT
(3, 0, &$5, 0, 2, IS_A1
($1));
2318 return
yyerror ("Register mismatch");
2321 | REG ASSIGN ROT REG BY HALF_REG
2323 if
(IS_DREG
($1) && IS_DREG
($4) && IS_DREG_L
($6))
2325 notethat
("dsp32shift: dregs = ROT dregs BY dregs_lo\n");
2326 $$
= DSP32SHIFT
(2, &$1, &$6, &$4, 3, 0);
2329 return
yyerror ("Register mismatch");
2332 | a_assign ROT REG_A BY expr
2336 notethat
("dsp32shiftimm: An = ROT An BY imm6\n");
2337 $$
= DSP32SHIFTIMM
(3, 0, imm6
($5), 0, 2, IS_A1
($1));
2340 return
yyerror ("Register mismatch");
2343 | REG ASSIGN ROT REG BY expr
2345 if
(IS_DREG
($1) && IS_DREG
($4) && IS_IMM
($6, 6))
2347 $$
= DSP32SHIFTIMM
(2, &$1, imm6
($6), &$4, 3, IS_A1
($1));
2350 return
yyerror ("Register mismatch");
2353 | HALF_REG ASSIGN SIGNBITS REG_A
2357 notethat
("dsp32shift: dregs_lo = SIGNBITS An\n");
2358 $$
= DSP32SHIFT
(6, &$1, 0, 0, IS_A1
($4), 0);
2361 return
yyerror ("Register mismatch");
2364 | HALF_REG ASSIGN SIGNBITS REG
2366 if
(IS_DREG_L
($1) && IS_DREG
($4))
2368 notethat
("dsp32shift: dregs_lo = SIGNBITS dregs\n");
2369 $$
= DSP32SHIFT
(5, &$1, 0, &$4, 0, 0);
2372 return
yyerror ("Register mismatch");
2375 | HALF_REG ASSIGN SIGNBITS HALF_REG
2379 notethat
("dsp32shift: dregs_lo = SIGNBITS dregs_lo\n");
2380 $$
= DSP32SHIFT
(5, &$1, 0, &$4, 1 + IS_H
($4), 0);
2383 return
yyerror ("Register mismatch");
2386 /* The ASR bit is just inverted here. */
2387 | HALF_REG ASSIGN VIT_MAX LPAREN REG RPAREN asr_asl
2389 if
(IS_DREG_L
($1) && IS_DREG
($5))
2391 notethat
("dsp32shift: dregs_lo = VIT_MAX (dregs) (..)\n");
2392 $$
= DSP32SHIFT
(9, &$1, 0, &$5, ($7.r0 ?
0 : 1), 0);
2395 return
yyerror ("Register mismatch");
2398 | REG ASSIGN VIT_MAX LPAREN REG COMMA REG RPAREN asr_asl
2400 if
(IS_DREG
($1) && IS_DREG
($5) && IS_DREG
($7))
2402 notethat
("dsp32shift: dregs = VIT_MAX (dregs, dregs) (ASR)\n");
2403 $$
= DSP32SHIFT
(9, &$1, &$7, &$5, 2 |
($9.r0 ?
0 : 1), 0);
2406 return
yyerror ("Register mismatch");
2409 | BITMUX LPAREN REG COMMA REG COMMA REG_A RPAREN asr_asl
2411 if
(REG_SAME
($3, $5))
2412 return
yyerror ("Illegal source register combination");
2414 if
(IS_DREG
($3) && IS_DREG
($5) && !IS_A1
($7))
2416 notethat
("dsp32shift: BITMUX (dregs , dregs , A0) (ASR)\n");
2417 $$
= DSP32SHIFT
(8, 0, &$3, &$5, $9.r0
, 0);
2420 return
yyerror ("Register mismatch");
2423 | a_assign BXORSHIFT LPAREN REG_A COMMA REG_A COMMA CCREG RPAREN
2425 if
(!IS_A1
($1) && !IS_A1
($4) && IS_A1
($6))
2427 notethat
("dsp32shift: A0 = BXORSHIFT (A0 , A1 , CC )\n");
2428 $$
= DSP32SHIFT
(12, 0, 0, 0, 0, 0);
2431 return
yyerror ("Dregs expected");
2435 /* LOGI2op: BITCLR (dregs, uimm5). */
2436 | BITCLR LPAREN REG COMMA expr RPAREN
2438 if
(IS_DREG
($3) && IS_UIMM
($5, 5))
2440 notethat
("LOGI2op: BITCLR (dregs , uimm5 )\n");
2441 $$
= LOGI2OP
($3, uimm5
($5), 4);
2444 return
yyerror ("Register mismatch");
2447 /* LOGI2op: BITSET (dregs, uimm5). */
2448 | BITSET LPAREN REG COMMA expr RPAREN
2450 if
(IS_DREG
($3) && IS_UIMM
($5, 5))
2452 notethat
("LOGI2op: BITCLR (dregs , uimm5 )\n");
2453 $$
= LOGI2OP
($3, uimm5
($5), 2);
2456 return
yyerror ("Register mismatch");
2459 /* LOGI2op: BITTGL (dregs, uimm5). */
2460 | BITTGL LPAREN REG COMMA expr RPAREN
2462 if
(IS_DREG
($3) && IS_UIMM
($5, 5))
2464 notethat
("LOGI2op: BITCLR (dregs , uimm5 )\n");
2465 $$
= LOGI2OP
($3, uimm5
($5), 3);
2468 return
yyerror ("Register mismatch");
2471 | CCREG _ASSIGN_BANG BITTST LPAREN REG COMMA expr RPAREN
2473 if
(IS_DREG
($5) && IS_UIMM
($7, 5))
2475 notethat
("LOGI2op: CC =! BITTST (dregs , uimm5 )\n");
2476 $$
= LOGI2OP
($5, uimm5
($7), 0);
2479 return
yyerror ("Register mismatch or value error");
2482 | CCREG ASSIGN BITTST LPAREN REG COMMA expr RPAREN
2484 if
(IS_DREG
($5) && IS_UIMM
($7, 5))
2486 notethat
("LOGI2op: CC = BITTST (dregs , uimm5 )\n");
2487 $$
= LOGI2OP
($5, uimm5
($7), 1);
2490 return
yyerror ("Register mismatch or value error");
2493 | IF BANG CCREG REG ASSIGN REG
2495 if
((IS_DREG
($4) || IS_PREG
($4))
2496 && (IS_DREG
($6) || IS_PREG
($6)))
2498 notethat
("ccMV: IF ! CC gregs = gregs\n");
2499 $$
= CCMV
(&$6, &$4, 0);
2502 return
yyerror ("Register mismatch");
2505 | IF CCREG REG ASSIGN REG
2507 if
((IS_DREG
($5) || IS_PREG
($5))
2508 && (IS_DREG
($3) || IS_PREG
($3)))
2510 notethat
("ccMV: IF CC gregs = gregs\n");
2511 $$
= CCMV
(&$5, &$3, 1);
2514 return
yyerror ("Register mismatch");
2517 | IF BANG CCREG JUMP expr
2519 if
(IS_PCREL10
($5))
2521 notethat
("BRCC: IF !CC JUMP pcrel11m2\n");
2522 $$
= BRCC
(0, 0, $5);
2525 return
yyerror ("Bad jump offset");
2528 | IF BANG CCREG JUMP expr LPAREN BP RPAREN
2530 if
(IS_PCREL10
($5))
2532 notethat
("BRCC: IF !CC JUMP pcrel11m2\n");
2533 $$
= BRCC
(0, 1, $5);
2536 return
yyerror ("Bad jump offset");
2539 | IF CCREG JUMP expr
2541 if
(IS_PCREL10
($4))
2543 notethat
("BRCC: IF CC JUMP pcrel11m2\n");
2544 $$
= BRCC
(1, 0, $4);
2547 return
yyerror ("Bad jump offset");
2550 | IF CCREG JUMP expr LPAREN BP RPAREN
2552 if
(IS_PCREL10
($4))
2554 notethat
("BRCC: IF !CC JUMP pcrel11m2\n");
2555 $$
= BRCC
(1, 1, $4);
2558 return
yyerror ("Bad jump offset");
2562 notethat
("ProgCtrl: NOP\n");
2563 $$
= PROGCTRL
(0, 0);
2568 notethat
("ProgCtrl: RTS\n");
2569 $$
= PROGCTRL
(1, 0);
2574 notethat
("ProgCtrl: RTI\n");
2575 $$
= PROGCTRL
(1, 1);
2580 notethat
("ProgCtrl: RTX\n");
2581 $$
= PROGCTRL
(1, 2);
2586 notethat
("ProgCtrl: RTN\n");
2587 $$
= PROGCTRL
(1, 3);
2592 notethat
("ProgCtrl: RTE\n");
2593 $$
= PROGCTRL
(1, 4);
2598 notethat
("ProgCtrl: IDLE\n");
2599 $$
= PROGCTRL
(2, 0);
2604 notethat
("ProgCtrl: CSYNC\n");
2605 $$
= PROGCTRL
(2, 3);
2610 notethat
("ProgCtrl: SSYNC\n");
2611 $$
= PROGCTRL
(2, 4);
2616 notethat
("ProgCtrl: EMUEXCPT\n");
2617 $$
= PROGCTRL
(2, 5);
2624 notethat
("ProgCtrl: CLI dregs\n");
2625 $$
= PROGCTRL
(3, $2.regno
& CODE_MASK
);
2628 return
yyerror ("Dreg expected for CLI");
2635 notethat
("ProgCtrl: STI dregs\n");
2636 $$
= PROGCTRL
(4, $2.regno
& CODE_MASK
);
2639 return
yyerror ("Dreg expected for STI");
2642 | JUMP LPAREN REG RPAREN
2646 notethat
("ProgCtrl: JUMP (pregs )\n");
2647 $$
= PROGCTRL
(5, $3.regno
& CODE_MASK
);
2650 return
yyerror ("Bad register for indirect jump");
2653 | CALL LPAREN REG RPAREN
2657 notethat
("ProgCtrl: CALL (pregs )\n");
2658 $$
= PROGCTRL
(6, $3.regno
& CODE_MASK
);
2661 return
yyerror ("Bad register for indirect call");
2664 | CALL LPAREN PC PLUS REG RPAREN
2668 notethat
("ProgCtrl: CALL (PC + pregs )\n");
2669 $$
= PROGCTRL
(7, $5.regno
& CODE_MASK
);
2672 return
yyerror ("Bad register for indirect call");
2675 | JUMP LPAREN PC PLUS REG RPAREN
2679 notethat
("ProgCtrl: JUMP (PC + pregs )\n");
2680 $$
= PROGCTRL
(8, $5.regno
& CODE_MASK
);
2683 return
yyerror ("Bad register for indirect jump");
2688 if
(IS_UIMM
($2, 4))
2690 notethat
("ProgCtrl: RAISE uimm4\n");
2691 $$
= PROGCTRL
(9, uimm4
($2));
2694 return
yyerror ("Bad value for RAISE");
2699 notethat
("ProgCtrl: EMUEXCPT\n");
2700 $$
= PROGCTRL
(10, uimm4
($2));
2703 | TESTSET LPAREN REG RPAREN
2707 if
($3.regno
== REG_SP ||
$3.regno
== REG_FP
)
2708 return
yyerror ("Bad register for TESTSET");
2710 notethat
("ProgCtrl: TESTSET (pregs )\n");
2711 $$
= PROGCTRL
(11, $3.regno
& CODE_MASK
);
2714 return
yyerror ("Preg expected");
2719 if
(IS_PCREL12
($2))
2721 notethat
("UJUMP: JUMP pcrel12\n");
2725 return
yyerror ("Bad value for relative jump");
2730 if
(IS_PCREL12
($2))
2732 notethat
("UJUMP: JUMP_DOT_S pcrel12\n");
2736 return
yyerror ("Bad value for relative jump");
2741 if
(IS_PCREL24
($2))
2743 notethat
("CALLa: jump.l pcrel24\n");
2747 return
yyerror ("Bad value for long jump");
2752 if
(IS_PCREL24
($2))
2754 notethat
("CALLa: jump.l pcrel24\n");
2758 return
yyerror ("Bad value for long jump");
2763 if
(IS_PCREL24
($2))
2765 notethat
("CALLa: CALL pcrel25m2\n");
2769 return
yyerror ("Bad call address");
2773 if
(IS_PCREL24
($2))
2775 notethat
("CALLa: CALL pcrel25m2\n");
2779 return
yyerror ("Bad call address");
2783 /* ALU2op: DIVQ (dregs, dregs). */
2784 | DIVQ LPAREN REG COMMA REG RPAREN
2786 if
(IS_DREG
($3) && IS_DREG
($5))
2787 $$
= ALU2OP
(&$3, &$5, 8);
2789 return
yyerror ("Bad registers for DIVQ");
2792 | DIVS LPAREN REG COMMA REG RPAREN
2794 if
(IS_DREG
($3) && IS_DREG
($5))
2795 $$
= ALU2OP
(&$3, &$5, 9);
2797 return
yyerror ("Bad registers for DIVS");
2800 | REG ASSIGN MINUS REG vsmod
2802 if
(IS_DREG
($1) && IS_DREG
($4))
2804 if
($5.r0
== 0 && $5.s0
== 0 && $5.aop
== 0)
2806 notethat
("ALU2op: dregs = - dregs\n");
2807 $$
= ALU2OP
(&$1, &$4, 14);
2809 else if
($5.r0
== 1 && $5.s0
== 0 && $5.aop
== 3)
2811 notethat
("dsp32alu: dregs = - dregs (.)\n");
2812 $$
= DSP32ALU
(15, 0, 0, &$1, &$4, 0, $5.s0
, 0, 3);
2816 notethat
("dsp32alu: dregs = - dregs (.)\n");
2817 $$
= DSP32ALU
(7, 0, 0, &$1, &$4, 0, $5.s0
, 0, 3);
2821 return
yyerror ("Dregs expected");
2824 | REG ASSIGN TILDA REG
2826 if
(IS_DREG
($1) && IS_DREG
($4))
2828 notethat
("ALU2op: dregs = ~dregs\n");
2829 $$
= ALU2OP
(&$1, &$4, 15);
2832 return
yyerror ("Dregs expected");
2835 | REG _GREATER_GREATER_ASSIGN REG
2837 if
(IS_DREG
($1) && IS_DREG
($3))
2839 notethat
("ALU2op: dregs >>= dregs\n");
2840 $$
= ALU2OP
(&$1, &$3, 1);
2843 return
yyerror ("Dregs expected");
2846 | REG _GREATER_GREATER_ASSIGN expr
2848 if
(IS_DREG
($1) && IS_UIMM
($3, 5))
2850 notethat
("LOGI2op: dregs >>= uimm5\n");
2851 $$
= LOGI2OP
($1, uimm5
($3), 6);
2854 return
yyerror ("Dregs expected or value error");
2857 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN REG
2859 if
(IS_DREG
($1) && IS_DREG
($3))
2861 notethat
("ALU2op: dregs >>>= dregs\n");
2862 $$
= ALU2OP
(&$1, &$3, 0);
2865 return
yyerror ("Dregs expected");
2868 | REG _LESS_LESS_ASSIGN REG
2870 if
(IS_DREG
($1) && IS_DREG
($3))
2872 notethat
("ALU2op: dregs <<= dregs\n");
2873 $$
= ALU2OP
(&$1, &$3, 2);
2876 return
yyerror ("Dregs expected");
2879 | REG _LESS_LESS_ASSIGN expr
2881 if
(IS_DREG
($1) && IS_UIMM
($3, 5))
2883 notethat
("LOGI2op: dregs <<= uimm5\n");
2884 $$
= LOGI2OP
($1, uimm5
($3), 7);
2887 return
yyerror ("Dregs expected or const value error");
2891 | REG _GREATER_GREATER_GREATER_THAN_ASSIGN expr
2893 if
(IS_DREG
($1) && IS_UIMM
($3, 5))
2895 notethat
("LOGI2op: dregs >>>= uimm5\n");
2896 $$
= LOGI2OP
($1, uimm5
($3), 5);
2899 return
yyerror ("Dregs expected");
2902 /* Cache Control. */
2904 | FLUSH LBRACK REG RBRACK
2906 notethat
("CaCTRL: FLUSH [ pregs ]\n");
2908 $$
= CACTRL
(&$3, 0, 2);
2910 return
yyerror ("Bad register(s) for FLUSH");
2913 | FLUSH reg_with_postinc
2917 notethat
("CaCTRL: FLUSH [ pregs ++ ]\n");
2918 $$
= CACTRL
(&$2, 1, 2);
2921 return
yyerror ("Bad register(s) for FLUSH");
2924 | FLUSHINV LBRACK REG RBRACK
2928 notethat
("CaCTRL: FLUSHINV [ pregs ]\n");
2929 $$
= CACTRL
(&$3, 0, 1);
2932 return
yyerror ("Bad register(s) for FLUSH");
2935 | FLUSHINV reg_with_postinc
2939 notethat
("CaCTRL: FLUSHINV [ pregs ++ ]\n");
2940 $$
= CACTRL
(&$2, 1, 1);
2943 return
yyerror ("Bad register(s) for FLUSH");
2946 /* CaCTRL: IFLUSH [pregs]. */
2947 | IFLUSH LBRACK REG RBRACK
2951 notethat
("CaCTRL: IFLUSH [ pregs ]\n");
2952 $$
= CACTRL
(&$3, 0, 3);
2955 return
yyerror ("Bad register(s) for FLUSH");
2958 | IFLUSH reg_with_postinc
2962 notethat
("CaCTRL: IFLUSH [ pregs ++ ]\n");
2963 $$
= CACTRL
(&$2, 1, 3);
2966 return
yyerror ("Bad register(s) for FLUSH");
2969 | PREFETCH LBRACK REG RBRACK
2973 notethat
("CaCTRL: PREFETCH [ pregs ]\n");
2974 $$
= CACTRL
(&$3, 0, 0);
2977 return
yyerror ("Bad register(s) for PREFETCH");
2980 | PREFETCH reg_with_postinc
2984 notethat
("CaCTRL: PREFETCH [ pregs ++ ]\n");
2985 $$
= CACTRL
(&$2, 1, 0);
2988 return
yyerror ("Bad register(s) for PREFETCH");
2992 /* LDST: B [ pregs <post_op> ] = dregs. */
2994 | B LBRACK REG post_op RBRACK ASSIGN REG
2997 return
yyerror ("Dreg expected for source operand");
2999 return
yyerror ("Preg expected in address");
3001 notethat
("LDST: B [ pregs <post_op> ] = dregs\n");
3002 $$
= LDST
(&$3, &$7, $4.x0
, 2, 0, 1);
3005 /* LDSTidxI: B [ pregs + imm16 ] = dregs. */
3006 | B LBRACK REG plus_minus expr RBRACK ASSIGN REG
3008 Expr_Node
*tmp
= $5;
3011 return
yyerror ("Dreg expected for source operand");
3013 return
yyerror ("Preg expected in address");
3016 return
yyerror ("Plain symbol used as offset");
3019 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3021 if
(in_range_p
(tmp
, -32768, 32767, 0))
3023 notethat
("LDST: B [ pregs + imm16 ] = dregs\n");
3024 $$
= LDSTIDXI
(&$3, &$8, 1, 2, 0, $5);
3027 return
yyerror ("Displacement out of range");
3031 /* LDSTii: W [ pregs + uimm4s2 ] = dregs. */
3032 | W LBRACK REG plus_minus expr RBRACK ASSIGN REG
3034 Expr_Node
*tmp
= $5;
3037 return
yyerror ("Dreg expected for source operand");
3039 return
yyerror ("Preg expected in address");
3042 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3045 return
yyerror ("Plain symbol used as offset");
3047 if
(in_range_p
(tmp
, 0, 30, 1))
3049 notethat
("LDSTii: W [ pregs +- uimm5m2 ] = dregs\n");
3050 $$
= LDSTII
(&$3, &$8, tmp
, 1, 1);
3052 else if
(in_range_p
(tmp
, -65536, 65535, 1))
3054 notethat
("LDSTidxI: W [ pregs + imm17m2 ] = dregs\n");
3055 $$
= LDSTIDXI
(&$3, &$8, 1, 1, 0, tmp
);
3058 return
yyerror ("Displacement out of range");
3061 /* LDST: W [ pregs <post_op> ] = dregs. */
3062 | W LBRACK REG post_op RBRACK ASSIGN REG
3065 return
yyerror ("Dreg expected for source operand");
3067 return
yyerror ("Preg expected in address");
3069 notethat
("LDST: W [ pregs <post_op> ] = dregs\n");
3070 $$
= LDST
(&$3, &$7, $4.x0
, 1, 0, 1);
3073 | W LBRACK REG post_op RBRACK ASSIGN HALF_REG
3076 return
yyerror ("Dreg expected for source operand");
3079 if
(!IS_IREG
($3) && !IS_PREG
($3))
3080 return
yyerror ("Ireg or Preg expected in address");
3082 else if
(!IS_IREG
($3))
3083 return
yyerror ("Ireg expected in address");
3087 notethat
("dspLDST: W [ iregs <post_op> ] = dregs_half\n");
3088 $$
= DSPLDST
(&$3, 1 + IS_H
($7), &$7, $4.x0
, 1);
3092 notethat
("LDSTpmod: W [ pregs ] = dregs_half\n");
3093 $$
= LDSTPMOD
(&$3, &$7, &$3, 1 + IS_H
($7), 1);
3097 /* LDSTiiFP: [ FP - const ] = dpregs. */
3098 | LBRACK REG plus_minus expr RBRACK ASSIGN REG
3100 Expr_Node
*tmp
= $4;
3101 int ispreg
= IS_PREG
($7);
3104 return
yyerror ("Preg expected in address");
3106 if
(!IS_DREG
($7) && !ispreg
)
3107 return
yyerror ("Preg expected for source operand");
3110 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3113 return
yyerror ("Plain symbol used as offset");
3115 if
(in_range_p
(tmp
, 0, 63, 3))
3117 notethat
("LDSTii: dpregs = [ pregs + uimm6m4 ]\n");
3118 $$
= LDSTII
(&$2, &$7, tmp
, 1, ispreg ?
3 : 0);
3120 else if
($2.regno
== REG_FP
&& in_range_p
(tmp
, -128, 0, 3))
3122 notethat
("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n");
3123 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3124 $$
= LDSTIIFP
(tmp
, &$7, 1);
3126 else if
(in_range_p
(tmp
, -131072, 131071, 3))
3128 notethat
("LDSTidxI: [ pregs + imm18m4 ] = dpregs\n");
3129 $$
= LDSTIDXI
(&$2, &$7, 1, 0, ispreg ?
1 : 0, tmp
);
3132 return
yyerror ("Displacement out of range");
3135 | REG ASSIGN W LBRACK REG plus_minus expr RBRACK xpmod
3137 Expr_Node
*tmp
= $7;
3139 return
yyerror ("Dreg expected for destination operand");
3141 return
yyerror ("Preg expected in address");
3144 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3147 return
yyerror ("Plain symbol used as offset");
3149 if
(in_range_p
(tmp
, 0, 30, 1))
3151 notethat
("LDSTii: dregs = W [ pregs + uimm5m2 ] (.)\n");
3152 $$
= LDSTII
(&$5, &$1, tmp
, 0, 1 << $9.r0
);
3154 else if
(in_range_p
(tmp
, -65536, 65535, 1))
3156 notethat
("LDSTidxI: dregs = W [ pregs + imm17m2 ] (.)\n");
3157 $$
= LDSTIDXI
(&$5, &$1, 0, 1, $9.r0
, tmp
);
3160 return
yyerror ("Displacement out of range");
3163 | HALF_REG ASSIGN W LBRACK REG post_op RBRACK
3166 return
yyerror ("Dreg expected for source operand");
3169 if
(!IS_IREG
($5) && !IS_PREG
($5))
3170 return
yyerror ("Ireg or Preg expected in address");
3172 else if
(!IS_IREG
($5))
3173 return
yyerror ("Ireg expected in address");
3177 notethat
("dspLDST: dregs_half = W [ iregs <post_op> ]\n");
3178 $$
= DSPLDST
(&$5, 1 + IS_H
($1), &$1, $6.x0
, 0);
3182 notethat
("LDSTpmod: dregs_half = W [ pregs <post_op> ]\n");
3183 $$
= LDSTPMOD
(&$5, &$1, &$5, 1 + IS_H
($1), 0);
3188 | REG ASSIGN W LBRACK REG post_op RBRACK xpmod
3191 return
yyerror ("Dreg expected for destination operand");
3193 return
yyerror ("Preg expected in address");
3195 notethat
("LDST: dregs = W [ pregs <post_op> ] (.)\n");
3196 $$
= LDST
(&$5, &$1, $6.x0
, 1, $8.r0
, 0);
3199 | REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK xpmod
3202 return
yyerror ("Dreg expected for destination operand");
3203 if
(!IS_PREG
($5) ||
!IS_PREG
($7))
3204 return
yyerror ("Preg expected in address");
3206 notethat
("LDSTpmod: dregs = W [ pregs ++ pregs ] (.)\n");
3207 $$
= LDSTPMOD
(&$5, &$1, &$7, 3, $9.r0
);
3210 | HALF_REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK
3213 return
yyerror ("Dreg expected for destination operand");
3214 if
(!IS_PREG
($5) ||
!IS_PREG
($7))
3215 return
yyerror ("Preg expected in address");
3217 notethat
("LDSTpmod: dregs_half = W [ pregs ++ pregs ]\n");
3218 $$
= LDSTPMOD
(&$5, &$1, &$7, 1 + IS_H
($1), 0);
3221 | LBRACK REG post_op RBRACK ASSIGN REG
3223 if
(!IS_IREG
($2) && !IS_PREG
($2))
3224 return
yyerror ("Ireg or Preg expected in address");
3225 else if
(IS_IREG
($2) && !IS_DREG
($6))
3226 return
yyerror ("Dreg expected for source operand");
3227 else if
(IS_PREG
($2) && !IS_DREG
($6) && !IS_PREG
($6))
3228 return
yyerror ("Dreg or Preg expected for source operand");
3232 notethat
("dspLDST: [ iregs <post_op> ] = dregs\n");
3233 $$
= DSPLDST
(&$2, 0, &$6, $3.x0
, 1);
3235 else if
(IS_DREG
($6))
3237 notethat
("LDST: [ pregs <post_op> ] = dregs\n");
3238 $$
= LDST
(&$2, &$6, $3.x0
, 0, 0, 1);
3242 notethat
("LDST: [ pregs <post_op> ] = pregs\n");
3243 $$
= LDST
(&$2, &$6, $3.x0
, 0, 1, 1);
3247 | LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN REG
3250 return
yyerror ("Dreg expected for source operand");
3252 if
(IS_IREG
($2) && IS_MREG
($4))
3254 notethat
("dspLDST: [ iregs ++ mregs ] = dregs\n");
3255 $$
= DSPLDST
(&$2, $4.regno
& CODE_MASK
, &$7, 3, 1);
3257 else if
(IS_PREG
($2) && IS_PREG
($4))
3259 notethat
("LDSTpmod: [ pregs ++ pregs ] = dregs\n");
3260 $$
= LDSTPMOD
(&$2, &$7, &$4, 0, 1);
3263 return
yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address");
3266 | W LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN HALF_REG
3269 return
yyerror ("Dreg expected for source operand");
3271 if
(IS_PREG
($3) && IS_PREG
($5))
3273 notethat
("LDSTpmod: W [ pregs ++ pregs ] = dregs_half\n");
3274 $$
= LDSTPMOD
(&$3, &$8, &$5, 1 + IS_H
($8), 1);
3277 return
yyerror ("Preg ++ Preg expected in address");
3280 | REG ASSIGN B LBRACK REG plus_minus expr RBRACK xpmod
3282 Expr_Node
*tmp
= $7;
3284 return
yyerror ("Dreg expected for destination operand");
3286 return
yyerror ("Preg expected in address");
3289 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3292 return
yyerror ("Plain symbol used as offset");
3294 if
(in_range_p
(tmp
, -32768, 32767, 0))
3296 notethat
("LDSTidxI: dregs = B [ pregs + imm16 ] (%c)\n",
3298 $$
= LDSTIDXI
(&$5, &$1, 0, 2, $9.r0
, tmp
);
3301 return
yyerror ("Displacement out of range");
3304 | REG ASSIGN B LBRACK REG post_op RBRACK xpmod
3307 return
yyerror ("Dreg expected for destination operand");
3309 return
yyerror ("Preg expected in address");
3311 notethat
("LDST: dregs = B [ pregs <post_op> ] (%c)\n",
3313 $$
= LDST
(&$5, &$1, $6.x0
, 2, $8.r0
, 0);
3316 | REG ASSIGN LBRACK REG _PLUS_PLUS REG RBRACK
3319 return
yyerror ("Dreg expected for destination operand");
3321 if
(IS_IREG
($4) && IS_MREG
($6))
3323 notethat
("dspLDST: dregs = [ iregs ++ mregs ]\n");
3324 $$
= DSPLDST
(&$4, $6.regno
& CODE_MASK
, &$1, 3, 0);
3326 else if
(IS_PREG
($4) && IS_PREG
($6))
3328 notethat
("LDSTpmod: dregs = [ pregs ++ pregs ]\n");
3329 $$
= LDSTPMOD
(&$4, &$1, &$6, 0, 0);
3332 return
yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address");
3335 | REG ASSIGN LBRACK REG plus_minus got_or_expr RBRACK
3337 Expr_Node
*tmp
= $6;
3338 int ispreg
= IS_PREG
($1);
3339 int isgot
= IS_RELOC
($6);
3342 return
yyerror ("Preg expected in address");
3344 if
(!IS_DREG
($1) && !ispreg
)
3345 return
yyerror ("Dreg or Preg expected for destination operand");
3347 if
(tmp
->type
== Expr_Node_Reloc
3348 && strcmp
(tmp
->value.s_value
,
3349 "_current_shared_library_p5_offset_") != 0)
3350 return
yyerror ("Plain symbol used as offset");
3353 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3357 notethat
("LDSTidxI: dpregs = [ pregs + sym@got ]\n");
3358 $$
= LDSTIDXI
(&$4, &$1, 0, 0, ispreg ?
1 : 0, tmp
);
3360 else if
(in_range_p
(tmp
, 0, 63, 3))
3362 notethat
("LDSTii: dpregs = [ pregs + uimm7m4 ]\n");
3363 $$
= LDSTII
(&$4, &$1, tmp
, 0, ispreg ?
3 : 0);
3365 else if
($4.regno
== REG_FP
&& in_range_p
(tmp
, -128, 0, 3))
3367 notethat
("LDSTiiFP: dpregs = [ FP - uimm7m4 ]\n");
3368 tmp
= unary
(Expr_Op_Type_NEG
, tmp
);
3369 $$
= LDSTIIFP
(tmp
, &$1, 0);
3371 else if
(in_range_p
(tmp
, -131072, 131071, 3))
3373 notethat
("LDSTidxI: dpregs = [ pregs + imm18m4 ]\n");
3374 $$
= LDSTIDXI
(&$4, &$1, 0, 0, ispreg ?
1 : 0, tmp
);
3378 return
yyerror ("Displacement out of range");
3381 | REG ASSIGN LBRACK REG post_op RBRACK
3383 if
(!IS_IREG
($4) && !IS_PREG
($4))
3384 return
yyerror ("Ireg or Preg expected in address");
3385 else if
(IS_IREG
($4) && !IS_DREG
($1))
3386 return
yyerror ("Dreg expected in destination operand");
3387 else if
(IS_PREG
($4) && !IS_DREG
($1) && !IS_PREG
($1)
3388 && ($4.regno
!= REG_SP ||
!IS_ALLREG
($1) ||
$5.x0
!= 0))
3389 return
yyerror ("Dreg or Preg expected in destination operand");
3393 notethat
("dspLDST: dregs = [ iregs <post_op> ]\n");
3394 $$
= DSPLDST
(&$4, 0, &$1, $5.x0
, 0);
3396 else if
(IS_DREG
($1))
3398 notethat
("LDST: dregs = [ pregs <post_op> ]\n");
3399 $$
= LDST
(&$4, &$1, $5.x0
, 0, 0, 0);
3401 else if
(IS_PREG
($1))
3403 if
(REG_SAME
($1, $4) && $5.x0
!= 2)
3404 return
yyerror ("Pregs can't be same");
3406 notethat
("LDST: pregs = [ pregs <post_op> ]\n");
3407 $$
= LDST
(&$4, &$1, $5.x0
, 0, 1, 0);
3411 notethat
("PushPopReg: allregs = [ SP ++ ]\n");
3412 $$
= PUSHPOPREG
(&$1, 0);
3417 /* PushPopMultiple. */
3418 | reg_with_predec ASSIGN LPAREN REG COLON expr COMMA REG COLON expr RPAREN
3420 if
($1.regno
!= REG_SP
)
3421 yyerror ("Stack Pointer expected");
3422 if
($4.regno
== REG_R7
3423 && IN_RANGE
($6, 0, 7)
3424 && $8.regno
== REG_P5
3425 && IN_RANGE
($10, 0, 5))
3427 notethat
("PushPopMultiple: [ -- SP ] = (R7 : reglim , P5 : reglim )\n");
3428 $$
= PUSHPOPMULTIPLE
(imm5
($6), imm5
($10), 1, 1, 1);
3431 return
yyerror ("Bad register for PushPopMultiple");
3434 | reg_with_predec ASSIGN LPAREN REG COLON expr RPAREN
3436 if
($1.regno
!= REG_SP
)
3437 yyerror ("Stack Pointer expected");
3439 if
($4.regno
== REG_R7
&& IN_RANGE
($6, 0, 7))
3441 notethat
("PushPopMultiple: [ -- SP ] = (R7 : reglim )\n");
3442 $$
= PUSHPOPMULTIPLE
(imm5
($6), 0, 1, 0, 1);
3444 else if
($4.regno
== REG_P5
&& IN_RANGE
($6, 0, 6))
3446 notethat
("PushPopMultiple: [ -- SP ] = (P5 : reglim )\n");
3447 $$
= PUSHPOPMULTIPLE
(0, imm5
($6), 0, 1, 1);
3450 return
yyerror ("Bad register for PushPopMultiple");
3453 | LPAREN REG COLON expr COMMA REG COLON expr RPAREN ASSIGN reg_with_postinc
3455 if
($11.regno
!= REG_SP
)
3456 yyerror ("Stack Pointer expected");
3457 if
($2.regno
== REG_R7
&& (IN_RANGE
($4, 0, 7))
3458 && $6.regno
== REG_P5
&& (IN_RANGE
($8, 0, 6)))
3460 notethat
("PushPopMultiple: (R7 : reglim , P5 : reglim ) = [ SP ++ ]\n");
3461 $$
= PUSHPOPMULTIPLE
(imm5
($4), imm5
($8), 1, 1, 0);
3464 return
yyerror ("Bad register range for PushPopMultiple");
3467 | LPAREN REG COLON expr RPAREN ASSIGN reg_with_postinc
3469 if
($7.regno
!= REG_SP
)
3470 yyerror ("Stack Pointer expected");
3472 if
($2.regno
== REG_R7
&& IN_RANGE
($4, 0, 7))
3474 notethat
("PushPopMultiple: (R7 : reglim ) = [ SP ++ ]\n");
3475 $$
= PUSHPOPMULTIPLE
(imm5
($4), 0, 1, 0, 0);
3477 else if
($2.regno
== REG_P5
&& IN_RANGE
($4, 0, 6))
3479 notethat
("PushPopMultiple: (P5 : reglim ) = [ SP ++ ]\n");
3480 $$
= PUSHPOPMULTIPLE
(0, imm5
($4), 0, 1, 0);
3483 return
yyerror ("Bad register range for PushPopMultiple");
3486 | reg_with_predec ASSIGN REG
3488 if
($1.regno
!= REG_SP
)
3489 yyerror ("Stack Pointer expected");
3493 notethat
("PushPopReg: [ -- SP ] = allregs\n");
3494 $$
= PUSHPOPREG
(&$3, 1);
3497 return
yyerror ("Bad register for PushPopReg");
3504 if
(IS_URANGE
(16, $2, 0, 4))
3505 $$
= LINKAGE
(0, uimm16s4
($2));
3507 return
yyerror ("Bad constant for LINK");
3512 notethat
("linkage: UNLINK\n");
3513 $$
= LINKAGE
(1, 0);
3519 | LSETUP LPAREN expr COMMA expr RPAREN REG
3521 if
(IS_PCREL4
($3) && IS_LPPCREL10
($5) && IS_CREG
($7))
3523 notethat
("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters\n");
3524 $$
= LOOPSETUP
($3, &$7, 0, $5, 0);
3527 return
yyerror ("Bad register or values for LSETUP");
3530 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG
3532 if
(IS_PCREL4
($3) && IS_LPPCREL10
($5)
3533 && IS_PREG
($9) && IS_CREG
($7))
3535 notethat
("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs\n");
3536 $$
= LOOPSETUP
($3, &$7, 1, $5, &$9);
3539 return
yyerror ("Bad register or values for LSETUP");
3542 | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG GREATER_GREATER expr
3544 if
(IS_PCREL4
($3) && IS_LPPCREL10
($5)
3545 && IS_PREG
($9) && IS_CREG
($7)
3546 && EXPR_VALUE
($11) == 1)
3548 notethat
("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs >> 1\n");
3549 $$
= LOOPSETUP
($3, &$7, 3, $5, &$9);
3552 return
yyerror ("Bad register or values for LSETUP");
3559 return
yyerror ("Invalid expression in loop statement");
3561 return
yyerror ("Invalid loop counter register");
3562 $$
= bfin_gen_loop
($2, &$3, 0, 0);
3564 | LOOP expr REG ASSIGN REG
3566 if
(IS_RELOC
($2) && IS_PREG
($5) && IS_CREG
($3))
3568 notethat
("Loop: LOOP expr counters = pregs\n");
3569 $$
= bfin_gen_loop
($2, &$3, 1, &$5);
3572 return
yyerror ("Bad register or values for LOOP");
3574 | LOOP expr REG ASSIGN REG GREATER_GREATER expr
3576 if
(IS_RELOC
($2) && IS_PREG
($5) && IS_CREG
($3) && EXPR_VALUE
($7) == 1)
3578 notethat
("Loop: LOOP expr counters = pregs >> 1\n");
3579 $$
= bfin_gen_loop
($2, &$3, 3, &$5);
3582 return
yyerror ("Bad register or values for LOOP");
3588 Expr_Node_Value val
;
3590 Expr_Node
*tmp
= Expr_Node_Create
(Expr_Node_Constant
, val
, NULL
, NULL
);
3591 bfin_loop_attempt_create_label
(tmp
, 1);
3592 if
(!IS_RELOC
(tmp
))
3593 return
yyerror ("Invalid expression in LOOP_BEGIN statement");
3594 bfin_loop_beginend
(tmp
, 1);
3600 return
yyerror ("Invalid expression in LOOP_BEGIN statement");
3602 bfin_loop_beginend
($2, 1);
3609 Expr_Node_Value val
;
3611 Expr_Node
*tmp
= Expr_Node_Create
(Expr_Node_Constant
, val
, NULL
, NULL
);
3612 bfin_loop_attempt_create_label
(tmp
, 1);
3613 if
(!IS_RELOC
(tmp
))
3614 return
yyerror ("Invalid expression in LOOP_END statement");
3615 bfin_loop_beginend
(tmp
, 0);
3621 return
yyerror ("Invalid expression in LOOP_END statement");
3623 bfin_loop_beginend
($2, 0);
3631 notethat
("psedoDEBUG: ABORT\n");
3632 $$
= bfin_gen_pseudodbg
(3, 3, 0);
3637 notethat
("pseudoDEBUG: DBG\n");
3638 $$
= bfin_gen_pseudodbg
(3, 7, 0);
3642 notethat
("pseudoDEBUG: DBG REG_A\n");
3643 $$
= bfin_gen_pseudodbg
(3, IS_A1
($2), 0);
3647 notethat
("pseudoDEBUG: DBG allregs\n");
3648 $$
= bfin_gen_pseudodbg
(0, $2.regno
& CODE_MASK
, ($2.regno
& CLASS_MASK
) >> 4);
3651 | DBGCMPLX LPAREN REG RPAREN
3654 return
yyerror ("Dregs expected");
3655 notethat
("pseudoDEBUG: DBGCMPLX (dregs )\n");
3656 $$
= bfin_gen_pseudodbg
(3, 6, ($3.regno
& CODE_MASK
) >> 4);
3661 notethat
("psedoDEBUG: DBGHALT\n");
3662 $$
= bfin_gen_pseudodbg
(3, 5, 0);
3667 notethat
("psedoDEBUG: HLT\n");
3668 $$
= bfin_gen_pseudodbg
(3, 4, 0);
3671 | DBGA LPAREN HALF_REG COMMA expr RPAREN
3673 notethat
("pseudodbg_assert: DBGA (regs_lo/hi , uimm16 )\n");
3674 $$
= bfin_gen_pseudodbg_assert
(IS_H
($3), &$3, uimm16
($5));
3677 | DBGAH LPAREN REG COMMA expr RPAREN
3679 notethat
("pseudodbg_assert: DBGAH (regs , uimm16 )\n");
3680 $$
= bfin_gen_pseudodbg_assert
(3, &$3, uimm16
($5));
3683 | DBGAL LPAREN REG COMMA expr RPAREN
3685 notethat
("psedodbg_assert: DBGAL (regs , uimm16 )\n");
3686 $$
= bfin_gen_pseudodbg_assert
(2, &$3, uimm16
($5));
3691 if
(!IS_UIMM
($2, 8))
3692 return
yyerror ("Constant out of range");
3693 notethat
("psedodbg_assert: OUTC uimm8\n");
3694 $$
= bfin_gen_pseudochr
(uimm8
($2));
3700 return
yyerror ("Dregs expected");
3701 notethat
("psedodbg_assert: OUTC dreg\n");
3702 $$
= bfin_gen_pseudodbg
(2, $2.regno
& CODE_MASK
, 0);
3709 /* Register rules. */
3711 REG_A: REG_A_DOUBLE_ZERO
3729 | LPAREN M COMMA MMOD RPAREN
3734 | LPAREN MMOD COMMA M RPAREN
3739 | LPAREN MMOD RPAREN
3751 asr_asl: LPAREN ASL RPAREN
3832 | LPAREN asr_asl_0 RPAREN
3844 | LPAREN asr_asl_0 COMMA sco RPAREN
3850 | LPAREN sco COMMA asr_asl_0 RPAREN
3910 | LPAREN V COMMA S RPAREN
3915 | LPAREN S COMMA V RPAREN
3977 | LPAREN MMOD RPAREN
3980 return
yyerror ("Bad modifier");
3984 | LPAREN MMOD COMMA R RPAREN
3987 return
yyerror ("Bad modifier");
3991 | LPAREN R COMMA MMOD RPAREN
3994 return
yyerror ("Bad modifier");
4021 | LPAREN MMOD RPAREN
4026 return
yyerror ("Only (W32) allowed");
4034 | LPAREN MMOD RPAREN
4039 return
yyerror ("(IU) expected");
4043 reg_with_predec: LBRACK _MINUS_MINUS REG RBRACK
4049 reg_with_postinc: LBRACK REG _PLUS_PLUS RBRACK
4101 $$.r0
= 1; /* HL. */
4104 $$.aop
= 0; /* aop. */
4109 $$.r0
= 1; /* HL. */
4112 $$.aop
= 1; /* aop. */
4115 | LPAREN RNDL RPAREN
4117 $$.r0
= 0; /* HL. */
4120 $$.aop
= 0; /* aop. */
4125 $$.r0
= 0; /* HL. */
4131 | LPAREN RNDH COMMA R RPAREN
4133 $$.r0
= 1; /* HL. */
4136 $$.aop
= 0; /* aop. */
4138 | LPAREN TH COMMA R RPAREN
4140 $$.r0
= 1; /* HL. */
4143 $$.aop
= 1; /* aop. */
4145 | LPAREN RNDL COMMA R RPAREN
4147 $$.r0
= 0; /* HL. */
4150 $$.aop
= 0; /* aop. */
4153 | LPAREN TL COMMA R RPAREN
4155 $$.r0
= 0; /* HL. */
4158 $$.aop
= 1; /* aop. */
4166 $$.x0
= 0; /* HL. */
4171 $$.x0
= 1; /* HL. */
4173 | LPAREN LO COMMA R RPAREN
4176 $$.x0
= 0; /* HL. */
4178 | LPAREN HI COMMA R RPAREN
4181 $$.x0
= 1; /* HL. */
4199 /* Assignments, Macfuncs. */
4225 if
(IS_A1
($3) && IS_EVEN
($1))
4226 return
yyerror ("Cannot move A1 to even register");
4227 else if
(!IS_A1
($3) && !IS_EVEN
($1))
4228 return
yyerror ("Cannot move A0 to odd register");
4244 | REG ASSIGN LPAREN a_macfunc RPAREN
4246 if
($4.n
&& IS_EVEN
($1))
4247 return
yyerror ("Cannot move A1 to even register");
4248 else if
(!$4.n
&& !IS_EVEN
($1))
4249 return
yyerror ("Cannot move A0 to odd register");
4257 | HALF_REG ASSIGN LPAREN a_macfunc RPAREN
4259 if
($4.n
&& !IS_H
($1))
4260 return
yyerror ("Cannot move A1 to low half of register");
4261 else if
(!$4.n
&& IS_H
($1))
4262 return
yyerror ("Cannot move A0 to high half of register");
4270 | HALF_REG ASSIGN REG_A
4272 if
(IS_A1
($3) && !IS_H
($1))
4273 return
yyerror ("Cannot move A1 to low half of register");
4274 else if
(!IS_A1
($3) && IS_H
($1))
4275 return
yyerror ("Cannot move A0 to high half of register");
4288 a_assign multiply_halfregs
4295 | a_plusassign multiply_halfregs
4302 | a_minusassign multiply_halfregs
4312 HALF_REG STAR HALF_REG
4314 if
(IS_DREG
($1) && IS_DREG
($3))
4320 return
yyerror ("Dregs expected");
4344 CCREG cc_op STATUS_REG
4356 | STATUS_REG cc_op CCREG
4370 /* Expressions and Symbols. */
4374 Expr_Node_Value val
;
4375 val.s_value
= S_GET_NAME
($1);
4376 $$
= Expr_Node_Create
(Expr_Node_Reloc
, val
, NULL
, NULL
);
4382 { $$
= BFD_RELOC_BFIN_GOT
; }
4384 { $$
= BFD_RELOC_BFIN_GOT17M4
; }
4386 { $$
= BFD_RELOC_BFIN_FUNCDESC_GOT17M4
; }
4389 got: symbol AT any_gotrel
4391 Expr_Node_Value val
;
4393 $$
= Expr_Node_Create
(Expr_Node_GOT_Reloc
, val
, $1, NULL
);
4416 Expr_Node_Value val
;
4418 $$
= Expr_Node_Create
(Expr_Node_Constant
, val
, NULL
, NULL
);
4424 | LPAREN expr_1 RPAREN
4430 $$
= unary
(Expr_Op_Type_COMP
, $2);
4432 | MINUS expr_1 %prec TILDA
4434 $$
= unary
(Expr_Op_Type_NEG
, $2);
4444 expr_1: expr_1 STAR expr_1
4446 $$
= binary
(Expr_Op_Type_Mult
, $1, $3);
4448 | expr_1 SLASH expr_1
4450 $$
= binary
(Expr_Op_Type_Div
, $1, $3);
4452 | expr_1 PERCENT expr_1
4454 $$
= binary
(Expr_Op_Type_Mod
, $1, $3);
4456 | expr_1 PLUS expr_1
4458 $$
= binary
(Expr_Op_Type_Add
, $1, $3);
4460 | expr_1 MINUS expr_1
4462 $$
= binary
(Expr_Op_Type_Sub
, $1, $3);
4464 | expr_1 LESS_LESS expr_1
4466 $$
= binary
(Expr_Op_Type_Lshift
, $1, $3);
4468 | expr_1 GREATER_GREATER expr_1
4470 $$
= binary
(Expr_Op_Type_Rshift
, $1, $3);
4472 | expr_1 AMPERSAND expr_1
4474 $$
= binary
(Expr_Op_Type_BAND
, $1, $3);
4476 | expr_1 CARET expr_1
4478 $$
= binary
(Expr_Op_Type_LOR
, $1, $3);
4482 $$
= binary
(Expr_Op_Type_BOR
, $1, $3);
4494 mkexpr
(int x
, SYMBOL_T s
)
4496 EXPR_T e
= XNEW
(struct expression_cell
);
4503 value_match
(Expr_Node
*exp
, int sz
, int sign
, int mul
, int issigned
)
4505 int umax
= (1 << sz
) - 1;
4506 int min
= -(1 << (sz
- 1));
4507 int max
= (1 << (sz
- 1)) - 1;
4509 int v
= (EXPR_VALUE
(exp
)) & 0xffffffff;
4513 error ("%s:%d: Value Error -- Must align to %d\n", __FILE__
, __LINE__
, mul
);
4524 if
(v
>= min
&& v
<= max
) return
1;
4527 fprintf
(stderr
, "signed value %lx out of range\n", v
* mul
);
4531 if
(v
<= umax
&& v
>= 0)
4534 fprintf
(stderr
, "unsigned value %lx out of range\n", v
* mul
);
4539 /* Return the expression structure that allows symbol operations.
4540 If the left and right children are constants, do the operation. */
4542 binary
(Expr_Op_Type op
, Expr_Node
*x
, Expr_Node
*y
)
4544 Expr_Node_Value val
;
4546 if
(x
->type
== Expr_Node_Constant
&& y
->type
== Expr_Node_Constant
)
4550 case Expr_Op_Type_Add
:
4551 x
->value.i_value
+= y
->value.i_value
;
4553 case Expr_Op_Type_Sub
:
4554 x
->value.i_value
-= y
->value.i_value
;
4556 case Expr_Op_Type_Mult
:
4557 x
->value.i_value
*= y
->value.i_value
;
4559 case Expr_Op_Type_Div
:
4560 if
(y
->value.i_value
== 0)
4561 error ("Illegal Expression: Division by zero.");
4563 x
->value.i_value
/= y
->value.i_value
;
4565 case Expr_Op_Type_Mod
:
4566 x
->value.i_value %
= y
->value.i_value
;
4568 case Expr_Op_Type_Lshift
:
4569 x
->value.i_value
<<= y
->value.i_value
;
4571 case Expr_Op_Type_Rshift
:
4572 x
->value.i_value
>>= y
->value.i_value
;
4574 case Expr_Op_Type_BAND
:
4575 x
->value.i_value
&= y
->value.i_value
;
4577 case Expr_Op_Type_BOR
:
4578 x
->value.i_value |
= y
->value.i_value
;
4580 case Expr_Op_Type_BXOR
:
4581 x
->value.i_value ^
= y
->value.i_value
;
4583 case Expr_Op_Type_LAND
:
4584 x
->value.i_value
= x
->value.i_value
&& y
->value.i_value
;
4586 case Expr_Op_Type_LOR
:
4587 x
->value.i_value
= x
->value.i_value || y
->value.i_value
;
4591 error ("%s:%d: Internal assembler error\n", __FILE__
, __LINE__
);
4595 /* Canonicalize order to EXPR OP CONSTANT. */
4596 if
(x
->type
== Expr_Node_Constant
)
4602 /* Canonicalize subtraction of const to addition of negated const. */
4603 if
(op
== Expr_Op_Type_Sub
&& y
->type
== Expr_Node_Constant
)
4605 op
= Expr_Op_Type_Add
;
4606 y
->value.i_value
= -y
->value.i_value
;
4608 if
(y
->type
== Expr_Node_Constant
&& x
->type
== Expr_Node_Binop
4609 && x
->Right_Child
->type
== Expr_Node_Constant
)
4611 if
(op
== x
->value.op_value
&& x
->value.op_value
== Expr_Op_Type_Add
)
4613 x
->Right_Child
->value.i_value
+= y
->value.i_value
;
4618 /* Create a new expression structure. */
4620 return Expr_Node_Create
(Expr_Node_Binop
, val
, x
, y
);
4624 unary
(Expr_Op_Type op
, Expr_Node
*x
)
4626 if
(x
->type
== Expr_Node_Constant
)
4630 case Expr_Op_Type_NEG
:
4631 x
->value.i_value
= -x
->value.i_value
;
4633 case Expr_Op_Type_COMP
:
4634 x
->value.i_value
= ~x
->value.i_value
;
4637 error ("%s:%d: Internal assembler error\n", __FILE__
, __LINE__
);
4643 /* Create a new expression structure. */
4644 Expr_Node_Value val
;
4646 return Expr_Node_Create
(Expr_Node_Unop
, val
, x
, NULL
);
4650 int debug_codeselection
= 0;
4652 notethat
(const char *format
, ...
)
4655 va_start
(ap
, format
);
4656 if
(debug_codeselection
)
4658 vfprintf
(errorf
, format
, ap
);
4664 main
(int argc
, char **argv
)