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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [bfin-parse.y] - Blame information for rev 81

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

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

powered by: WebSVN 2.1.0

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