OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [bfin-parse.y] - Blame information for rev 277

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

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

powered by: WebSVN 2.1.0

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