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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [bfin-parse.y] - Blame information for rev 853

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

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

powered by: WebSVN 2.1.0

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