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