OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [config/] [bfin-parse.y] - Blame information for rev 13

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.