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 299

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

powered by: WebSVN 2.1.0

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