Home | History | Annotate | Line # | Download | only in config
rx-parse.y revision 1.1.1.3
      1      1.1  christos /* rx-parse.y  Renesas RX parser
      2  1.1.1.3  christos    Copyright (C) 2008-2016 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 #include "safe-ctype.h"
     24      1.1  christos #include "rx-defs.h"
     25      1.1  christos 
     26      1.1  christos static int rx_lex (void);
     27      1.1  christos 
     28      1.1  christos #define COND_EQ	0
     29      1.1  christos #define COND_NE	1
     30      1.1  christos 
     31      1.1  christos #define MEMEX 0x06
     32      1.1  christos 
     33      1.1  christos #define BSIZE 0
     34      1.1  christos #define WSIZE 1
     35      1.1  christos #define LSIZE 2
     36      1.1  christos 
     37      1.1  christos /*                       .sb    .sw    .l     .uw   */
     38      1.1  christos static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE };
     39      1.1  christos 
     40      1.1  christos /* Ok, here are the rules for using these macros...
     41      1.1  christos 
     42      1.1  christos    B*() is used to specify the base opcode bytes.  Fields to be filled
     43      1.1  christos         in later, leave zero.  Call this first.
     44      1.1  christos 
     45      1.1  christos    F() and FE() are used to fill in fields within the base opcode bytes.  You MUST
     46      1.1  christos         call B*() before any F() or FE().
     47      1.1  christos 
     48      1.1  christos    [UN]*O*(), PC*() appends operands to the end of the opcode.  You
     49      1.1  christos         must call P() and B*() before any of these, so that the fixups
     50      1.1  christos         have the right byte location.
     51      1.1  christos         O = signed, UO = unsigned, NO = negated, PC = pcrel
     52      1.1  christos 
     53      1.1  christos    IMM() adds an immediate and fills in the field for it.
     54      1.1  christos    NIMM() same, but negates the immediate.
     55      1.1  christos    NBIMM() same, but negates the immediate, for sbb.
     56      1.1  christos    DSP() adds a displacement, and fills in the field for it.
     57      1.1  christos 
     58      1.1  christos    Note that order is significant for the O, IMM, and DSP macros, as
     59      1.1  christos    they append their data to the operand buffer in the order that you
     60      1.1  christos    call them.
     61      1.1  christos 
     62      1.1  christos    Use "disp" for displacements whenever possible; this handles the
     63      1.1  christos    "0" case properly.  */
     64      1.1  christos 
     65      1.1  christos #define B1(b1)             rx_base1 (b1)
     66      1.1  christos #define B2(b1, b2)         rx_base2 (b1, b2)
     67      1.1  christos #define B3(b1, b2, b3)     rx_base3 (b1, b2, b3)
     68      1.1  christos #define B4(b1, b2, b3, b4) rx_base4 (b1, b2, b3, b4)
     69      1.1  christos 
     70      1.1  christos /* POS is bits from the MSB of the first byte to the LSB of the last byte.  */
     71      1.1  christos #define F(val,pos,sz)      rx_field (val, pos, sz)
     72      1.1  christos #define FE(exp,pos,sz)	   rx_field (exp_val (exp), pos, sz);
     73      1.1  christos 
     74      1.1  christos #define O1(v)              rx_op (v, 1, RXREL_SIGNED); rx_range (v, -128, 255)
     75      1.1  christos #define O2(v)              rx_op (v, 2, RXREL_SIGNED); rx_range (v, -32768, 65536)
     76      1.1  christos #define O3(v)              rx_op (v, 3, RXREL_SIGNED); rx_range (v, -8388608, 16777216)
     77      1.1  christos #define O4(v)              rx_op (v, 4, RXREL_SIGNED)
     78      1.1  christos 
     79      1.1  christos #define UO1(v)             rx_op (v, 1, RXREL_UNSIGNED); rx_range (v, 0, 255)
     80      1.1  christos #define UO2(v)             rx_op (v, 2, RXREL_UNSIGNED); rx_range (v, 0, 65536)
     81      1.1  christos #define UO3(v)             rx_op (v, 3, RXREL_UNSIGNED); rx_range (v, 0, 16777216)
     82      1.1  christos #define UO4(v)             rx_op (v, 4, RXREL_UNSIGNED)
     83      1.1  christos 
     84      1.1  christos #define NO1(v)             rx_op (v, 1, RXREL_NEGATIVE)
     85      1.1  christos #define NO2(v)             rx_op (v, 2, RXREL_NEGATIVE)
     86      1.1  christos #define NO3(v)             rx_op (v, 3, RXREL_NEGATIVE)
     87      1.1  christos #define NO4(v)             rx_op (v, 4, RXREL_NEGATIVE)
     88      1.1  christos 
     89      1.1  christos #define PC1(v)             rx_op (v, 1, RXREL_PCREL)
     90      1.1  christos #define PC2(v)             rx_op (v, 2, RXREL_PCREL)
     91      1.1  christos #define PC3(v)             rx_op (v, 3, RXREL_PCREL)
     92      1.1  christos 
     93      1.1  christos #define IMM_(v,pos,size)   F (immediate (v, RXREL_SIGNED, pos, size), pos, 2); \
     94      1.1  christos 			   if (v.X_op != O_constant && v.X_op != O_big) rx_linkrelax_imm (pos)
     95      1.1  christos #define IMM(v,pos)	   IMM_ (v, pos, 32)
     96      1.1  christos #define IMMW(v,pos)	   IMM_ (v, pos, 16); rx_range (v, -32768, 65536)
     97      1.1  christos #define IMMB(v,pos)	   IMM_ (v, pos, 8); rx_range (v, -128, 255)
     98      1.1  christos #define NIMM(v,pos)	   F (immediate (v, RXREL_NEGATIVE, pos, 32), pos, 2)
     99      1.1  christos #define NBIMM(v,pos)	   F (immediate (v, RXREL_NEGATIVE_BORROW, pos, 32), pos, 2)
    100      1.1  christos #define DSP(v,pos,msz)	   if (!v.X_md) rx_relax (RX_RELAX_DISP, pos); \
    101      1.1  christos 			   else rx_linkrelax_dsp (pos); \
    102      1.1  christos 			   F (displacement (v, msz), pos, 2)
    103      1.1  christos 
    104  1.1.1.3  christos #define id24(a,b2,b3)	   B3 (0xfb + a, b2, b3)
    105      1.1  christos 
    106  1.1.1.2  christos static void	   rx_check_float_support (void);
    107      1.1  christos static int         rx_intop (expressionS, int, int);
    108      1.1  christos static int         rx_uintop (expressionS, int);
    109      1.1  christos static int         rx_disp3op (expressionS);
    110      1.1  christos static int         rx_disp5op (expressionS *, int);
    111      1.1  christos static int         rx_disp5op0 (expressionS *, int);
    112      1.1  christos static int         exp_val (expressionS exp);
    113      1.1  christos static expressionS zero_expr (void);
    114      1.1  christos static int         immediate (expressionS, int, int, int);
    115      1.1  christos static int         displacement (expressionS, int);
    116      1.1  christos static void        rtsd_immediate (expressionS);
    117      1.1  christos static void	   rx_range (expressionS, int, int);
    118  1.1.1.3  christos static void        rx_check_v2 (void);
    119      1.1  christos 
    120      1.1  christos static int    need_flag = 0;
    121      1.1  christos static int    rx_in_brackets = 0;
    122      1.1  christos static int    rx_last_token = 0;
    123      1.1  christos static char * rx_init_start;
    124      1.1  christos static char * rx_last_exp_start = 0;
    125      1.1  christos static int    sub_op;
    126      1.1  christos static int    sub_op2;
    127      1.1  christos 
    128      1.1  christos #define YYDEBUG 1
    129      1.1  christos #define YYERROR_VERBOSE 1
    130      1.1  christos 
    131      1.1  christos %}
    132      1.1  christos 
    133      1.1  christos %name-prefix="rx_"
    134      1.1  christos 
    135      1.1  christos %union {
    136      1.1  christos   int regno;
    137      1.1  christos   expressionS exp;
    138      1.1  christos }
    139      1.1  christos 
    140  1.1.1.3  christos %type <regno> REG FLAG CREG BCND BMCND SCCND ACC
    141      1.1  christos %type <regno> flag bwl bw memex
    142      1.1  christos %type <exp> EXPR disp
    143      1.1  christos 
    144  1.1.1.3  christos %token REG FLAG CREG ACC
    145      1.1  christos 
    146      1.1  christos %token EXPR UNKNOWN_OPCODE IS_OPCODE
    147      1.1  christos 
    148      1.1  christos %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
    149      1.1  christos 
    150      1.1  christos %token ABS ADC ADD AND_
    151      1.1  christos %token BCLR BCND BMCND BNOT BRA BRK BSET BSR BTST
    152      1.1  christos %token CLRPSW CMP
    153      1.1  christos %token DBT DIV DIVU
    154  1.1.1.3  christos %token EDIV EDIVU EMACA EMSBA EMUL EMULA EMULU
    155  1.1.1.3  christos %token FADD FCMP FDIV FMUL FREIT FSUB FSQRT FTOI FTOU
    156      1.1  christos %token INT ITOF
    157      1.1  christos %token JMP JSR
    158  1.1.1.3  christos %token MACHI MACLH MACLO MAX MIN MOV MOVCO MOVLI MOVU MSBHI MSBLH MSBLO MUL
    159  1.1.1.3  christos %token   MULHI MULLH MULLO MULU MVFACHI MVFACGU MVFACMI MVFACLO MVFC MVTACGU
    160  1.1.1.3  christos %token     MVTACHI MVTACLO MVTC MVTIPL
    161      1.1  christos %token NEG NOP NOT
    162      1.1  christos %token OR
    163      1.1  christos %token POP POPC POPM PUSH PUSHA PUSHC PUSHM
    164  1.1.1.3  christos %token RACL RACW RDACL RDACW REIT REVL REVW RMPA ROLC RORC ROTL ROTR ROUND
    165  1.1.1.3  christos %token   RTE RTFI RTS RTSD
    166      1.1  christos %token SAT SATR SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF
    167      1.1  christos %token   SMOVU SSTR STNZ STOP STZ SUB SUNTIL SWHILE
    168      1.1  christos %token TST
    169  1.1.1.3  christos %token UTOF
    170      1.1  christos %token WAIT
    171      1.1  christos %token XCHG XOR
    172      1.1  christos 
    173      1.1  christos %%
    174      1.1  christos /* ====================================================================== */
    175      1.1  christos 
    176      1.1  christos statement :
    177      1.1  christos 
    178      1.1  christos 	  UNKNOWN_OPCODE
    179      1.1  christos 	  { as_bad (_("Unknown opcode: %s"), rx_init_start); }
    180      1.1  christos 
    181      1.1  christos /* ---------------------------------------------------------------------- */
    182      1.1  christos 
    183      1.1  christos 	| BRK
    184      1.1  christos 	  { B1 (0x00); }
    185      1.1  christos 
    186      1.1  christos 	| DBT
    187      1.1  christos 	  { B1 (0x01); }
    188      1.1  christos 
    189      1.1  christos 	| RTS
    190      1.1  christos 	  { B1 (0x02); }
    191      1.1  christos 
    192      1.1  christos 	| NOP
    193      1.1  christos 	  { B1 (0x03); }
    194      1.1  christos 
    195      1.1  christos /* ---------------------------------------------------------------------- */
    196      1.1  christos 
    197      1.1  christos 	| BRA EXPR
    198      1.1  christos 	  { if (rx_disp3op ($2))
    199      1.1  christos 	      { B1 (0x08); rx_disp3 ($2, 5); }
    200      1.1  christos 	    else if (rx_intop ($2, 8, 8))
    201      1.1  christos 	      { B1 (0x2e); PC1 ($2); }
    202      1.1  christos 	    else if (rx_intop ($2, 16, 16))
    203      1.1  christos 	      { B1 (0x38); PC2 ($2); }
    204      1.1  christos 	    else if (rx_intop ($2, 24, 24))
    205      1.1  christos 	      { B1 (0x04); PC3 ($2); }
    206      1.1  christos 	    else
    207      1.1  christos 	      { rx_relax (RX_RELAX_BRANCH, 0);
    208      1.1  christos 		rx_linkrelax_branch ();
    209      1.1  christos 		/* We'll convert this to a longer one later if needed.  */
    210      1.1  christos 		B1 (0x08); rx_disp3 ($2, 5); } }
    211      1.1  christos 
    212      1.1  christos 	| BRA DOT_A EXPR
    213      1.1  christos 	  { B1 (0x04); PC3 ($3); }
    214      1.1  christos 
    215      1.1  christos 	| BRA DOT_S EXPR
    216      1.1  christos 	  { B1 (0x08); rx_disp3 ($3, 5); }
    217      1.1  christos 
    218      1.1  christos /* ---------------------------------------------------------------------- */
    219      1.1  christos 
    220      1.1  christos 	| BSR EXPR
    221      1.1  christos 	  { if (rx_intop ($2, 16, 16))
    222      1.1  christos 	      { B1 (0x39); PC2 ($2); }
    223      1.1  christos 	    else if (rx_intop ($2, 24, 24))
    224      1.1  christos 	      { B1 (0x05); PC3 ($2); }
    225      1.1  christos 	    else
    226      1.1  christos 	      { rx_relax (RX_RELAX_BRANCH, 0);
    227      1.1  christos 		rx_linkrelax_branch ();
    228      1.1  christos 		B1 (0x39); PC2 ($2); } }
    229      1.1  christos 	| BSR DOT_A EXPR
    230      1.1  christos 	  { B1 (0x05), PC3 ($3); }
    231      1.1  christos 
    232      1.1  christos /* ---------------------------------------------------------------------- */
    233      1.1  christos 
    234      1.1  christos 	| BCND DOT_S EXPR
    235      1.1  christos 	  { if ($1 == COND_EQ || $1 == COND_NE)
    236      1.1  christos 	      { B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($3, 5); }
    237      1.1  christos 	    else
    238      1.1  christos 	      as_bad (_("Only BEQ and BNE may have .S")); }
    239      1.1  christos 
    240      1.1  christos /* ---------------------------------------------------------------------- */
    241      1.1  christos 
    242      1.1  christos 	| BCND DOT_B EXPR
    243      1.1  christos 	  { B1 (0x20); F ($1, 4, 4); PC1 ($3); }
    244      1.1  christos 
    245      1.1  christos 	| BRA DOT_B EXPR
    246      1.1  christos 	  { B1 (0x2e), PC1 ($3); }
    247      1.1  christos 
    248      1.1  christos /* ---------------------------------------------------------------------- */
    249      1.1  christos 
    250      1.1  christos 	| BRA DOT_W EXPR
    251      1.1  christos 	  { B1 (0x38), PC2 ($3); }
    252      1.1  christos 	| BSR DOT_W EXPR
    253      1.1  christos 	  { B1 (0x39), PC2 ($3); }
    254      1.1  christos 	| BCND DOT_W EXPR
    255      1.1  christos 	  { if ($1 == COND_EQ || $1 == COND_NE)
    256      1.1  christos 	      { B1 ($1 == COND_EQ ? 0x3a : 0x3b); PC2 ($3); }
    257      1.1  christos 	    else
    258      1.1  christos 	      as_bad (_("Only BEQ and BNE may have .W")); }
    259      1.1  christos 	| BCND EXPR
    260      1.1  christos 	  { if ($1 == COND_EQ || $1 == COND_NE)
    261      1.1  christos 	      {
    262      1.1  christos 		rx_relax (RX_RELAX_BRANCH, 0);
    263      1.1  christos 		rx_linkrelax_branch ();
    264      1.1  christos 		B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($2, 5);
    265      1.1  christos 	      }
    266      1.1  christos 	    else
    267      1.1  christos 	      {
    268      1.1  christos 		rx_relax (RX_RELAX_BRANCH, 0);
    269      1.1  christos 		/* This is because we might turn it into a
    270      1.1  christos 		   jump-over-jump long branch.  */
    271      1.1  christos 		rx_linkrelax_branch ();
    272      1.1  christos 	        B1 (0x20); F ($1, 4, 4); PC1 ($2);
    273      1.1  christos 	      } }
    274      1.1  christos 
    275      1.1  christos /* ---------------------------------------------------------------------- */
    276      1.1  christos 
    277  1.1.1.3  christos 	| MOV DOT_B '#' EXPR ',' '[' REG ']'
    278  1.1.1.3  christos 	  { B2 (0xf8, 0x04); F ($7, 8, 4); IMMB ($4, 12);}
    279  1.1.1.3  christos 
    280  1.1.1.3  christos 	| MOV DOT_W '#' EXPR ',' '[' REG ']'
    281  1.1.1.3  christos           { B2 (0xf8, 0x01); F ($7, 8, 4); IMMW ($4, 12);}
    282  1.1.1.3  christos 
    283  1.1.1.3  christos 	| MOV DOT_L '#' EXPR ',' '[' REG ']'
    284  1.1.1.3  christos 	  { B2 (0xf8, 0x02); F ($7, 8, 4); IMM ($4, 12);}
    285  1.1.1.3  christos 
    286      1.1  christos 	| MOV DOT_B '#' EXPR ',' disp '[' REG ']'
    287      1.1  christos 	  /* rx_disp5op changes the value if it succeeds, so keep it last.  */
    288      1.1  christos 	  { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, BSIZE))
    289      1.1  christos 	      { B2 (0x3c, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
    290      1.1  christos 	    else
    291      1.1  christos 	      { B2 (0xf8, 0x04); F ($8, 8, 4); DSP ($6, 6, BSIZE); O1 ($4);
    292      1.1  christos 	      if ($4.X_op != O_constant && $4.X_op != O_big) rx_linkrelax_imm (12); } }
    293      1.1  christos 
    294      1.1  christos 	| MOV DOT_W '#' EXPR ',' disp '[' REG ']'
    295      1.1  christos 	  { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, WSIZE))
    296      1.1  christos 	      { B2 (0x3d, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
    297      1.1  christos 	    else
    298      1.1  christos 	      { B2 (0xf8, 0x01); F ($8, 8, 4); DSP ($6, 6, WSIZE); IMMW ($4, 12); } }
    299      1.1  christos 
    300      1.1  christos 	| MOV DOT_L '#' EXPR ',' disp '[' REG ']'
    301      1.1  christos 	  { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, LSIZE))
    302      1.1  christos 	      { B2 (0x3e, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
    303      1.1  christos 	    else
    304      1.1  christos 	      { B2 (0xf8, 0x02); F ($8, 8, 4); DSP ($6, 6, LSIZE); IMM ($4, 12); } }
    305      1.1  christos 
    306      1.1  christos /* ---------------------------------------------------------------------- */
    307      1.1  christos 
    308      1.1  christos 	| RTSD '#' EXPR ',' REG '-' REG
    309      1.1  christos 	  { B2 (0x3f, 0); F ($5, 8, 4); F ($7, 12, 4); rtsd_immediate ($3);
    310      1.1  christos 	    if ($5 == 0)
    311      1.1  christos 	      rx_error (_("RTSD cannot pop R0"));
    312      1.1  christos 	    if ($5 > $7)
    313      1.1  christos 	      rx_error (_("RTSD first reg must be <= second reg")); }
    314      1.1  christos 
    315      1.1  christos /* ---------------------------------------------------------------------- */
    316      1.1  christos 
    317      1.1  christos 	| CMP REG ',' REG
    318      1.1  christos 	  { B2 (0x47, 0); F ($2, 8, 4); F ($4, 12, 4); }
    319      1.1  christos 
    320      1.1  christos /* ---------------------------------------------------------------------- */
    321      1.1  christos 
    322      1.1  christos 	| CMP disp '[' REG ']' DOT_UB ',' REG
    323      1.1  christos 	  { B2 (0x44, 0); F ($4, 8, 4); F ($8, 12, 4); DSP ($2, 6, BSIZE); }
    324      1.1  christos 
    325      1.1  christos 	| CMP disp '[' REG ']' memex ',' REG
    326      1.1  christos 	  { B3 (MEMEX, 0x04, 0); F ($6, 8, 2);  F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, sizemap[$6]); }
    327      1.1  christos 
    328      1.1  christos /* ---------------------------------------------------------------------- */
    329      1.1  christos 
    330      1.1  christos 	| MOVU bw REG ',' REG
    331      1.1  christos 	  { B2 (0x5b, 0x00); F ($2, 5, 1); F ($3, 8, 4); F ($5, 12, 4); }
    332      1.1  christos 
    333      1.1  christos /* ---------------------------------------------------------------------- */
    334      1.1  christos 
    335      1.1  christos 	| MOVU bw '[' REG ']' ',' REG
    336      1.1  christos 	  { B2 (0x58, 0x00); F ($2, 5, 1); F ($4, 8, 4); F ($7, 12, 4); }
    337      1.1  christos 
    338      1.1  christos 	| MOVU bw EXPR '[' REG ']' ',' REG
    339      1.1  christos 	  { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2))
    340      1.1  christos 	      { B2 (0xb0, 0); F ($2, 4, 1); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); }
    341      1.1  christos 	    else
    342      1.1  christos 	      { B2 (0x58, 0x00); F ($2, 5, 1); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } }
    343      1.1  christos 
    344      1.1  christos /* ---------------------------------------------------------------------- */
    345      1.1  christos 
    346      1.1  christos 	| SUB '#' EXPR ',' REG
    347      1.1  christos 	  { if (rx_uintop ($3, 4))
    348      1.1  christos 	      { B2 (0x60, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    349      1.1  christos 	    else
    350      1.1  christos 	      /* This is really an add, but we negate the immediate.  */
    351      1.1  christos 	      { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); NIMM ($3, 6); } }
    352      1.1  christos 
    353      1.1  christos 	| CMP '#' EXPR ',' REG
    354      1.1  christos 	  { if (rx_uintop ($3, 4))
    355      1.1  christos 	      { B2 (0x61, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    356      1.1  christos 	    else if (rx_uintop ($3, 8))
    357      1.1  christos 	      { B2 (0x75, 0x50); F ($5, 12, 4); UO1 ($3); }
    358      1.1  christos 	    else
    359      1.1  christos 	      { B2 (0x74, 0x00); F ($5, 12, 4); IMM ($3, 6); } }
    360      1.1  christos 
    361      1.1  christos 	| ADD '#' EXPR ',' REG
    362      1.1  christos 	  { if (rx_uintop ($3, 4))
    363      1.1  christos 	      { B2 (0x62, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    364      1.1  christos 	    else
    365      1.1  christos 	      { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); IMM ($3, 6); } }
    366      1.1  christos 
    367      1.1  christos 	| MUL '#' EXPR ',' REG
    368      1.1  christos 	  { if (rx_uintop ($3, 4))
    369      1.1  christos 	      { B2 (0x63, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    370      1.1  christos 	    else
    371      1.1  christos 	      { B2 (0x74, 0x10); F ($5, 12, 4); IMM ($3, 6); } }
    372      1.1  christos 
    373      1.1  christos 	| AND_ '#' EXPR ',' REG
    374      1.1  christos 	  { if (rx_uintop ($3, 4))
    375      1.1  christos 	      { B2 (0x64, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    376      1.1  christos 	    else
    377      1.1  christos 	      { B2 (0x74, 0x20); F ($5, 12, 4); IMM ($3, 6); } }
    378      1.1  christos 
    379      1.1  christos 	| OR '#' EXPR ',' REG
    380      1.1  christos 	  { if (rx_uintop ($3, 4))
    381      1.1  christos 	      { B2 (0x65, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    382      1.1  christos 	    else
    383      1.1  christos 	      { B2 (0x74, 0x30); F ($5, 12, 4); IMM ($3, 6); } }
    384      1.1  christos 
    385      1.1  christos 	| MOV DOT_L '#' EXPR ',' REG
    386      1.1  christos 	  { if (rx_uintop ($4, 4))
    387      1.1  christos 	      { B2 (0x66, 0); FE ($4, 8, 4); F ($6, 12, 4); }
    388      1.1  christos 	    else if (rx_uintop ($4, 8))
    389      1.1  christos 	      { B2 (0x75, 0x40); F ($6, 12, 4); UO1 ($4); }
    390      1.1  christos 	    else
    391      1.1  christos 	      { B2 (0xfb, 0x02); F ($6, 8, 4); IMM ($4, 12); } }
    392      1.1  christos 
    393      1.1  christos 	| MOV '#' EXPR ',' REG
    394      1.1  christos 	  { if (rx_uintop ($3, 4))
    395      1.1  christos 	      { B2 (0x66, 0); FE ($3, 8, 4); F ($5, 12, 4); }
    396      1.1  christos 	    else if (rx_uintop ($3, 8))
    397      1.1  christos 	      { B2 (0x75, 0x40); F ($5, 12, 4); UO1 ($3); }
    398      1.1  christos 	    else
    399      1.1  christos 	      { B2 (0xfb, 0x02); F ($5, 8, 4); IMM ($3, 12); } }
    400      1.1  christos 
    401      1.1  christos /* ---------------------------------------------------------------------- */
    402      1.1  christos 
    403      1.1  christos 	| RTSD '#' EXPR
    404      1.1  christos 	  { B1 (0x67); rtsd_immediate ($3); }
    405      1.1  christos 
    406      1.1  christos /* ---------------------------------------------------------------------- */
    407      1.1  christos 
    408      1.1  christos 	| SHLR { sub_op = 0; } op_shift
    409      1.1  christos 	| SHAR { sub_op = 1; } op_shift
    410      1.1  christos 	| SHLL { sub_op = 2; } op_shift
    411      1.1  christos 
    412      1.1  christos /* ---------------------------------------------------------------------- */
    413      1.1  christos 
    414      1.1  christos 	| PUSHM REG '-' REG
    415      1.1  christos 	  {
    416      1.1  christos 	    if ($2 == $4)
    417      1.1  christos 	      { B2 (0x7e, 0x80); F (LSIZE, 10, 2); F ($2, 12, 4); }
    418      1.1  christos 	    else
    419      1.1  christos 	     { B2 (0x6e, 0); F ($2, 8, 4); F ($4, 12, 4); }
    420      1.1  christos 	    if ($2 == 0)
    421      1.1  christos 	      rx_error (_("PUSHM cannot push R0"));
    422      1.1  christos 	    if ($2 > $4)
    423      1.1  christos 	      rx_error (_("PUSHM first reg must be <= second reg")); }
    424      1.1  christos 
    425      1.1  christos /* ---------------------------------------------------------------------- */
    426      1.1  christos 
    427      1.1  christos 	| POPM REG '-' REG
    428      1.1  christos 	  {
    429      1.1  christos 	    if ($2 == $4)
    430      1.1  christos 	      { B2 (0x7e, 0xb0); F ($2, 12, 4); }
    431      1.1  christos 	    else
    432      1.1  christos 	      { B2 (0x6f, 0); F ($2, 8, 4); F ($4, 12, 4); }
    433      1.1  christos 	    if ($2 == 0)
    434      1.1  christos 	      rx_error (_("POPM cannot pop R0"));
    435      1.1  christos 	    if ($2 > $4)
    436      1.1  christos 	      rx_error (_("POPM first reg must be <= second reg")); }
    437      1.1  christos 
    438      1.1  christos /* ---------------------------------------------------------------------- */
    439      1.1  christos 
    440      1.1  christos 	| ADD '#' EXPR ',' REG ',' REG
    441      1.1  christos 	  { B2 (0x70, 0x00); F ($5, 8, 4); F ($7, 12, 4); IMM ($3, 6); }
    442      1.1  christos 
    443      1.1  christos /* ---------------------------------------------------------------------- */
    444      1.1  christos 
    445      1.1  christos 	| INT '#' EXPR
    446      1.1  christos 	  { B2(0x75, 0x60), UO1 ($3); }
    447      1.1  christos 
    448      1.1  christos /* ---------------------------------------------------------------------- */
    449      1.1  christos 
    450      1.1  christos 	| BSET '#' EXPR ',' REG
    451      1.1  christos 	  { B2 (0x78, 0); FE ($3, 7, 5); F ($5, 12, 4); }
    452      1.1  christos 	| BCLR '#' EXPR ',' REG
    453      1.1  christos 	  { B2 (0x7a, 0); FE ($3, 7, 5); F ($5, 12, 4); }
    454      1.1  christos 
    455      1.1  christos /* ---------------------------------------------------------------------- */
    456      1.1  christos 
    457      1.1  christos 	| BTST '#' EXPR ',' REG
    458      1.1  christos 	  { B2 (0x7c, 0x00); FE ($3, 7, 5); F ($5, 12, 4); }
    459      1.1  christos 
    460      1.1  christos /* ---------------------------------------------------------------------- */
    461      1.1  christos 
    462      1.1  christos 	| SAT REG
    463      1.1  christos 	  { B2 (0x7e, 0x30); F ($2, 12, 4); }
    464      1.1  christos 	| RORC REG
    465      1.1  christos 	  { B2 (0x7e, 0x40); F ($2, 12, 4); }
    466      1.1  christos 	| ROLC REG
    467      1.1  christos 	  { B2 (0x7e, 0x50); F ($2, 12, 4); }
    468      1.1  christos 
    469      1.1  christos /* ---------------------------------------------------------------------- */
    470      1.1  christos 
    471      1.1  christos 	| PUSH bwl REG
    472      1.1  christos 	  { B2 (0x7e, 0x80); F ($2, 10, 2); F ($3, 12, 4); }
    473      1.1  christos 
    474      1.1  christos /* ---------------------------------------------------------------------- */
    475      1.1  christos 
    476      1.1  christos 	| POP REG
    477      1.1  christos 	  { B2 (0x7e, 0xb0); F ($2, 12, 4); }
    478      1.1  christos 
    479      1.1  christos /* ---------------------------------------------------------------------- */
    480      1.1  christos 
    481      1.1  christos 	| PUSHC CREG
    482  1.1.1.3  christos 	  { if ($2 == 13)
    483  1.1.1.3  christos 	      { rx_check_v2 (); }
    484  1.1.1.3  christos 	    if ($2 < 16)
    485      1.1  christos 	      { B2 (0x7e, 0xc0); F ($2, 12, 4); }
    486      1.1  christos 	    else
    487      1.1  christos 	      as_bad (_("PUSHC can only push the first 16 control registers")); }
    488      1.1  christos 
    489      1.1  christos /* ---------------------------------------------------------------------- */
    490      1.1  christos 
    491      1.1  christos 	| POPC CREG
    492  1.1.1.3  christos 	  { if ($2 == 13)
    493  1.1.1.3  christos 	    { rx_check_v2 (); }
    494  1.1.1.3  christos 	    if ($2 < 16)
    495      1.1  christos 	      { B2 (0x7e, 0xe0); F ($2, 12, 4); }
    496      1.1  christos 	    else
    497      1.1  christos 	      as_bad (_("POPC can only pop the first 16 control registers")); }
    498      1.1  christos 
    499      1.1  christos /* ---------------------------------------------------------------------- */
    500      1.1  christos 
    501      1.1  christos 	| SETPSW flag
    502      1.1  christos 	  { B2 (0x7f, 0xa0); F ($2, 12, 4); }
    503      1.1  christos 	| CLRPSW flag
    504      1.1  christos 	  { B2 (0x7f, 0xb0); F ($2, 12, 4); }
    505      1.1  christos 
    506      1.1  christos /* ---------------------------------------------------------------------- */
    507      1.1  christos 
    508      1.1  christos 	| JMP REG
    509      1.1  christos 	  { B2 (0x7f, 0x00); F ($2, 12, 4); }
    510      1.1  christos 	| JSR REG
    511      1.1  christos 	  { B2 (0x7f, 0x10); F ($2, 12, 4); }
    512      1.1  christos 	| BRA opt_l REG
    513      1.1  christos 	  { B2 (0x7f, 0x40); F ($3, 12, 4); }
    514      1.1  christos 	| BSR opt_l REG
    515      1.1  christos 	  { B2 (0x7f, 0x50); F ($3, 12, 4); }
    516      1.1  christos 
    517      1.1  christos /* ---------------------------------------------------------------------- */
    518      1.1  christos 
    519      1.1  christos 	| SCMPU
    520  1.1.1.2  christos 	  { B2 (0x7f, 0x83); rx_note_string_insn_use (); }
    521      1.1  christos 	| SMOVU
    522  1.1.1.2  christos 	  { B2 (0x7f, 0x87); rx_note_string_insn_use (); }
    523      1.1  christos 	| SMOVB
    524  1.1.1.2  christos 	  { B2 (0x7f, 0x8b); rx_note_string_insn_use (); }
    525      1.1  christos 	| SMOVF
    526  1.1.1.2  christos 	  { B2 (0x7f, 0x8f); rx_note_string_insn_use (); }
    527      1.1  christos 
    528      1.1  christos /* ---------------------------------------------------------------------- */
    529      1.1  christos 
    530      1.1  christos 	| SUNTIL bwl
    531  1.1.1.2  christos 	  { B2 (0x7f, 0x80); F ($2, 14, 2); rx_note_string_insn_use (); }
    532      1.1  christos 	| SWHILE bwl
    533  1.1.1.2  christos 	  { B2 (0x7f, 0x84); F ($2, 14, 2); rx_note_string_insn_use (); }
    534      1.1  christos 	| SSTR bwl
    535      1.1  christos 	  { B2 (0x7f, 0x88); F ($2, 14, 2); }
    536      1.1  christos 
    537      1.1  christos /* ---------------------------------------------------------------------- */
    538      1.1  christos 
    539      1.1  christos 	| RMPA bwl
    540  1.1.1.2  christos 	  { B2 (0x7f, 0x8c); F ($2, 14, 2); rx_note_string_insn_use (); }
    541      1.1  christos 
    542      1.1  christos /* ---------------------------------------------------------------------- */
    543      1.1  christos 
    544      1.1  christos 	| RTFI
    545      1.1  christos 	  { B2 (0x7f, 0x94); }
    546      1.1  christos 	| RTE
    547      1.1  christos 	  { B2 (0x7f, 0x95); }
    548      1.1  christos 	| WAIT
    549      1.1  christos 	  { B2 (0x7f, 0x96); }
    550      1.1  christos 	| SATR
    551      1.1  christos 	  { B2 (0x7f, 0x93); }
    552      1.1  christos 
    553      1.1  christos /* ---------------------------------------------------------------------- */
    554      1.1  christos 
    555      1.1  christos 	| MVTIPL '#' EXPR
    556      1.1  christos 	  { B3 (0x75, 0x70, 0x00); FE ($3, 20, 4); }
    557      1.1  christos 
    558      1.1  christos /* ---------------------------------------------------------------------- */
    559      1.1  christos 
    560      1.1  christos 	/* rx_disp5op changes the value if it succeeds, so keep it last.  */
    561      1.1  christos 	| MOV bwl REG ',' EXPR '[' REG ']'
    562      1.1  christos 	  { if ($3 <= 7 && $7 <= 7 && rx_disp5op (&$5, $2))
    563      1.1  christos 	      { B2 (0x80, 0); F ($2, 2, 2); F ($7, 9, 3); F ($3, 13, 3); rx_field5s ($5); }
    564      1.1  christos 	    else
    565      1.1  christos 	      { B2 (0xc3, 0x00); F ($2, 2, 2); F ($7, 8, 4); F ($3, 12, 4); DSP ($5, 4, $2); }}
    566      1.1  christos 
    567      1.1  christos /* ---------------------------------------------------------------------- */
    568      1.1  christos 
    569      1.1  christos 	| MOV bwl EXPR '[' REG ']' ',' REG
    570      1.1  christos 	  { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2))
    571      1.1  christos 	      { B2 (0x88, 0); F ($2, 2, 2); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); }
    572      1.1  christos 	    else
    573      1.1  christos 	      { B2 (0xcc, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } }
    574      1.1  christos 
    575      1.1  christos /* ---------------------------------------------------------------------- */
    576      1.1  christos 
    577      1.1  christos 	/* MOV a,b - if a is a reg and b is mem, src and dest are
    578      1.1  christos 	   swapped.  */
    579      1.1  christos 
    580      1.1  christos 	/* We don't use "disp" here because it causes a shift/reduce
    581      1.1  christos 	   conflict with the other displacement-less patterns.  */
    582      1.1  christos 
    583      1.1  christos 	| MOV bwl REG ',' '[' REG ']'
    584      1.1  christos 	  { B2 (0xc3, 0x00); F ($2, 2, 2); F ($6, 8, 4); F ($3, 12, 4); }
    585      1.1  christos 
    586      1.1  christos /* ---------------------------------------------------------------------- */
    587      1.1  christos 
    588      1.1  christos 	| MOV bwl '[' REG ']' ',' disp '[' REG ']'
    589      1.1  christos 	  { B2 (0xc0, 0); F ($2, 2, 2); F ($4, 8, 4); F ($9, 12, 4); DSP ($7, 4, $2); }
    590      1.1  christos 
    591      1.1  christos /* ---------------------------------------------------------------------- */
    592      1.1  christos 
    593      1.1  christos 	| MOV bwl EXPR '[' REG ']' ',' disp '[' REG ']'
    594      1.1  christos 	  { B2 (0xc0, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($10, 12, 4); DSP ($3, 6, $2); DSP ($8, 4, $2); }
    595      1.1  christos 
    596      1.1  christos /* ---------------------------------------------------------------------- */
    597      1.1  christos 
    598      1.1  christos 	| MOV bwl REG ',' REG
    599      1.1  christos 	  { B2 (0xcf, 0x00); F ($2, 2, 2); F ($3, 8, 4); F ($5, 12, 4); }
    600      1.1  christos 
    601      1.1  christos /* ---------------------------------------------------------------------- */
    602      1.1  christos 
    603      1.1  christos 	| MOV bwl '[' REG ']' ',' REG
    604      1.1  christos 	  { B2 (0xcc, 0x00); F ($2, 2, 2); F ($4, 8, 4); F ($7, 12, 4); }
    605      1.1  christos 
    606      1.1  christos /* ---------------------------------------------------------------------- */
    607      1.1  christos 
    608      1.1  christos 	| BSET '#' EXPR ',' disp '[' REG ']' DOT_B
    609      1.1  christos 	  { B2 (0xf0, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
    610      1.1  christos 	| BCLR '#' EXPR ',' disp '[' REG ']' DOT_B
    611      1.1  christos 	  { B2 (0xf0, 0x08); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
    612      1.1  christos 	| BTST '#' EXPR ',' disp '[' REG ']' DOT_B
    613      1.1  christos 	  { B2 (0xf4, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
    614      1.1  christos 
    615      1.1  christos /* ---------------------------------------------------------------------- */
    616      1.1  christos 
    617      1.1  christos 	| PUSH bwl disp '[' REG ']'
    618      1.1  christos 	  { B2 (0xf4, 0x08); F ($2, 14, 2); F ($5, 8, 4); DSP ($3, 6, $2); }
    619      1.1  christos 
    620      1.1  christos /* ---------------------------------------------------------------------- */
    621      1.1  christos 
    622      1.1  christos 	| SBB   { sub_op = 0; } op_dp20_rm_l
    623      1.1  christos 	| NEG   { sub_op = 1; sub_op2 = 1; } op_dp20_rr
    624      1.1  christos 	| ADC   { sub_op = 2; } op_dp20_rim_l
    625      1.1  christos 	| ABS   { sub_op = 3; sub_op2 = 2; } op_dp20_rr
    626      1.1  christos 	| MAX   { sub_op = 4; } op_dp20_rim
    627      1.1  christos 	| MIN   { sub_op = 5; } op_dp20_rim
    628      1.1  christos 	| EMUL  { sub_op = 6; } op_dp20_i
    629      1.1  christos 	| EMULU { sub_op = 7; } op_dp20_i
    630      1.1  christos 	| DIV   { sub_op = 8; } op_dp20_rim
    631      1.1  christos 	| DIVU  { sub_op = 9; } op_dp20_rim
    632      1.1  christos 	| TST   { sub_op = 12; } op_dp20_rim
    633      1.1  christos 	| XOR   { sub_op = 13; } op_dp20_rim
    634      1.1  christos 	| NOT   { sub_op = 14; sub_op2 = 0; } op_dp20_rr
    635  1.1.1.3  christos 	| STZ   { sub_op = 14; sub_op2 = 0; } op_dp20_ri
    636  1.1.1.3  christos 	| STNZ  { sub_op = 15; sub_op2 = 1; } op_dp20_ri
    637      1.1  christos 
    638      1.1  christos /* ---------------------------------------------------------------------- */
    639      1.1  christos 
    640      1.1  christos 	| EMUL  { sub_op = 6; } op_xchg
    641      1.1  christos 	| EMULU { sub_op = 7; } op_xchg
    642      1.1  christos 	| XCHG  { sub_op = 16; } op_xchg
    643      1.1  christos 	| ITOF  { sub_op = 17; } op_xchg
    644  1.1.1.3  christos 	| UTOF  { sub_op = 21; } op_xchg
    645      1.1  christos 
    646      1.1  christos /* ---------------------------------------------------------------------- */
    647      1.1  christos 
    648      1.1  christos 	| BSET REG ',' REG
    649      1.1  christos 	  { id24 (1, 0x63, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
    650      1.1  christos 	| BCLR REG ',' REG
    651      1.1  christos 	  { id24 (1, 0x67, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
    652      1.1  christos 	| BTST REG ',' REG
    653      1.1  christos 	  { id24 (1, 0x6b, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
    654      1.1  christos 	| BNOT REG ',' REG
    655      1.1  christos 	  { id24 (1, 0x6f, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
    656      1.1  christos 
    657  1.1.1.2  christos 	| BSET REG ',' disp '[' REG ']' opt_b
    658      1.1  christos 	  { id24 (1, 0x60, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
    659  1.1.1.2  christos 	| BCLR REG ',' disp '[' REG ']' opt_b
    660      1.1  christos 	  { id24 (1, 0x64, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
    661  1.1.1.2  christos 	| BTST REG ',' disp '[' REG ']' opt_b
    662      1.1  christos 	  { id24 (1, 0x68, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
    663  1.1.1.2  christos 	| BNOT REG ',' disp '[' REG ']' opt_b
    664      1.1  christos 	  { id24 (1, 0x6c, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
    665      1.1  christos 
    666      1.1  christos /* ---------------------------------------------------------------------- */
    667      1.1  christos 
    668  1.1.1.3  christos 	| FSUB  { sub_op = 0; } float3_op
    669      1.1  christos 	| FCMP  { sub_op = 1; } float2_op
    670  1.1.1.3  christos 	| FADD  { sub_op = 2; } float3_op
    671  1.1.1.3  christos 	| FMUL  { sub_op = 3; } float3_op
    672      1.1  christos 	| FDIV  { sub_op = 4; } float2_op
    673  1.1.1.3  christos 	| FSQRT { sub_op = 8; } float2_op_ni
    674      1.1  christos 	| FTOI  { sub_op = 5; } float2_op_ni
    675  1.1.1.3  christos 	| FTOU  { sub_op = 9; } float2_op_ni
    676      1.1  christos 	| ROUND { sub_op = 6; } float2_op_ni
    677      1.1  christos 
    678      1.1  christos /* ---------------------------------------------------------------------- */
    679      1.1  christos 
    680  1.1.1.3  christos 
    681  1.1.1.3  christos /* ---------------------------------------------------------------------- */
    682  1.1.1.3  christos 
    683      1.1  christos 	| SCCND DOT_L REG
    684      1.1  christos 	  { id24 (1, 0xdb, 0x00); F ($1, 20, 4); F ($3, 16, 4); }
    685      1.1  christos 	| SCCND bwl disp '[' REG ']'
    686      1.1  christos 	  { id24 (1, 0xd0, 0x00); F ($1, 20, 4); F ($2, 12, 2); F ($5, 16, 4); DSP ($3, 14, $2); }
    687      1.1  christos 
    688      1.1  christos /* ---------------------------------------------------------------------- */
    689      1.1  christos 
    690  1.1.1.2  christos 	| BMCND '#' EXPR ',' disp '[' REG ']' opt_b
    691      1.1  christos 	  { id24 (1, 0xe0, 0x00); F ($1, 20, 4); FE ($3, 11, 3);
    692      1.1  christos 	      F ($7, 16, 4); DSP ($5, 14, BSIZE); }
    693      1.1  christos 
    694      1.1  christos /* ---------------------------------------------------------------------- */
    695      1.1  christos 
    696  1.1.1.2  christos 	| BNOT '#' EXPR ',' disp '[' REG ']' opt_b
    697      1.1  christos 	  { id24 (1, 0xe0, 0x0f); FE ($3, 11, 3); F ($7, 16, 4);
    698      1.1  christos 	      DSP ($5, 14, BSIZE); }
    699      1.1  christos 
    700      1.1  christos /* ---------------------------------------------------------------------- */
    701      1.1  christos 
    702      1.1  christos 	| MULHI REG ',' REG
    703      1.1  christos 	  { id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
    704  1.1.1.3  christos 	| MULHI REG ',' REG ',' ACC
    705  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    706      1.1  christos 	| MULLO REG ',' REG
    707      1.1  christos 	  { id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
    708  1.1.1.3  christos 	| MULLO REG ',' REG ',' ACC
    709  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    710      1.1  christos 	| MACHI REG ',' REG
    711      1.1  christos 	  { id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
    712  1.1.1.3  christos 	| MACHI REG ',' REG ',' ACC
    713  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    714      1.1  christos 	| MACLO REG ',' REG
    715      1.1  christos 	  { id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
    716  1.1.1.3  christos 	|  MACLO REG ',' REG ',' ACC
    717  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    718      1.1  christos 
    719      1.1  christos /* ---------------------------------------------------------------------- */
    720      1.1  christos 
    721      1.1  christos 	/* We don't have syntax for these yet.  */
    722      1.1  christos 	| MVTACHI REG
    723      1.1  christos 	  { id24 (2, 0x17, 0x00); F ($2, 20, 4); }
    724  1.1.1.3  christos 	|  MVTACHI REG ',' ACC
    725  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x17, 0x00); F ($2, 20, 4); F ($4, 16, 1); }
    726      1.1  christos 	| MVTACLO REG
    727      1.1  christos 	  { id24 (2, 0x17, 0x10); F ($2, 20, 4); }
    728  1.1.1.3  christos 	| MVTACLO REG ',' ACC
    729  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x17, 0x10); F ($2, 20, 4); F ($4, 16, 1); }
    730      1.1  christos 	| MVFACHI REG
    731      1.1  christos 	  { id24 (2, 0x1f, 0x00); F ($2, 20, 4); }
    732  1.1.1.3  christos 	| MVFACHI { sub_op = 0; } mvfa_op
    733      1.1  christos 	| MVFACMI REG
    734      1.1  christos 	  { id24 (2, 0x1f, 0x20); F ($2, 20, 4); }
    735  1.1.1.3  christos 	| MVFACMI { sub_op = 2; } mvfa_op
    736      1.1  christos 	| MVFACLO REG
    737      1.1  christos 	  { id24 (2, 0x1f, 0x10); F ($2, 20, 4); }
    738  1.1.1.3  christos 	| MVFACLO { sub_op = 1; } mvfa_op
    739      1.1  christos 	| RACW '#' EXPR
    740      1.1  christos 	  { id24 (2, 0x18, 0x00);
    741      1.1  christos 	    if (rx_uintop ($3, 4) && $3.X_add_number == 1)
    742      1.1  christos 	      ;
    743      1.1  christos 	    else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
    744      1.1  christos 	      F (1, 19, 1);
    745      1.1  christos 	    else
    746      1.1  christos 	      as_bad (_("RACW expects #1 or #2"));}
    747  1.1.1.3  christos 	| RACW '#' EXPR ',' ACC
    748  1.1.1.3  christos 	    { rx_check_v2 (); id24 (2, 0x18, 0x00); F ($5, 16, 1);
    749  1.1.1.3  christos 	    if (rx_uintop ($3, 4) && $3.X_add_number == 1)
    750  1.1.1.3  christos 	      ;
    751  1.1.1.3  christos 	    else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
    752  1.1.1.3  christos 	      F (1, 19, 1);
    753  1.1.1.3  christos 	    else
    754  1.1.1.3  christos 	      as_bad (_("RACW expects #1 or #2"));}
    755      1.1  christos 
    756      1.1  christos /* ---------------------------------------------------------------------- */
    757      1.1  christos 
    758      1.1  christos 	| MOV bwl REG ',' '[' REG '+' ']'
    759      1.1  christos 	  { id24 (2, 0x20, 0); F ($2, 14, 2); F ($6, 16, 4); F ($3, 20, 4); }
    760      1.1  christos 	| MOV bwl REG ',' '[' '-' REG ']'
    761      1.1  christos 	  { id24 (2, 0x24, 0); F ($2, 14, 2); F ($7, 16, 4); F ($3, 20, 4); }
    762      1.1  christos 
    763      1.1  christos /* ---------------------------------------------------------------------- */
    764      1.1  christos 
    765      1.1  christos 	| MOV bwl '[' REG '+' ']' ',' REG
    766      1.1  christos 	  { id24 (2, 0x28, 0); F ($2, 14, 2); F ($4, 16, 4); F ($8, 20, 4); }
    767      1.1  christos 	| MOV bwl '[' '-' REG ']' ',' REG
    768      1.1  christos 	  { id24 (2, 0x2c, 0); F ($2, 14, 2); F ($5, 16, 4); F ($8, 20, 4); }
    769      1.1  christos 
    770      1.1  christos /* ---------------------------------------------------------------------- */
    771      1.1  christos 
    772      1.1  christos 	| MOVU bw '[' REG '+' ']' ','  REG
    773      1.1  christos 	  { id24 (2, 0x38, 0); F ($2, 15, 1); F ($4, 16, 4); F ($8, 20, 4); }
    774      1.1  christos 	| MOVU bw '[' '-' REG ']' ',' REG
    775      1.1  christos 	  { id24 (2, 0x3c, 0); F ($2, 15, 1); F ($5, 16, 4); F ($8, 20, 4); }
    776      1.1  christos 
    777      1.1  christos /* ---------------------------------------------------------------------- */
    778      1.1  christos 
    779      1.1  christos 	| ROTL { sub_op = 6; } op_shift_rot
    780      1.1  christos 	| ROTR { sub_op = 4; } op_shift_rot
    781      1.1  christos 	| REVW { sub_op = 5; } op_shift_rot
    782      1.1  christos 	| REVL { sub_op = 7; } op_shift_rot
    783      1.1  christos 
    784      1.1  christos /* ---------------------------------------------------------------------- */
    785      1.1  christos 
    786      1.1  christos 	| MVTC REG ',' CREG
    787  1.1.1.3  christos 	  { if ($4 == 13)
    788  1.1.1.3  christos 	      rx_check_v2 ();
    789  1.1.1.3  christos 	  id24 (2, 0x68, 0x00); F ($4 % 16, 20, 4); F ($4 / 16, 15, 1);
    790      1.1  christos 	    F ($2, 16, 4); }
    791      1.1  christos 
    792      1.1  christos /* ---------------------------------------------------------------------- */
    793      1.1  christos 
    794      1.1  christos 	| MVFC CREG ',' REG
    795  1.1.1.3  christos 	  { if ($2 == 13)
    796  1.1.1.3  christos 	    rx_check_v2 ();
    797  1.1.1.3  christos 	  id24 (2, 0x6a, 0); F ($2, 15, 5); F ($4, 20, 4); }
    798      1.1  christos 
    799      1.1  christos /* ---------------------------------------------------------------------- */
    800      1.1  christos 
    801      1.1  christos 	| ROTL '#' EXPR ',' REG
    802      1.1  christos 	  { id24 (2, 0x6e, 0); FE ($3, 15, 5); F ($5, 20, 4); }
    803      1.1  christos 	| ROTR '#' EXPR ',' REG
    804      1.1  christos 	  { id24 (2, 0x6c, 0); FE ($3, 15, 5); F ($5, 20, 4); }
    805      1.1  christos 
    806      1.1  christos /* ---------------------------------------------------------------------- */
    807      1.1  christos 
    808      1.1  christos 	| MVTC '#' EXPR ',' CREG
    809  1.1.1.3  christos 	  { if ($5 == 13)
    810  1.1.1.3  christos 	      rx_check_v2 ();
    811  1.1.1.3  christos 	    id24 (2, 0x73, 0x00); F ($5, 19, 5); IMM ($3, 12); }
    812      1.1  christos 
    813      1.1  christos /* ---------------------------------------------------------------------- */
    814      1.1  christos 
    815      1.1  christos 	| BMCND '#' EXPR ',' REG
    816      1.1  christos 	  { id24 (2, 0xe0, 0x00); F ($1, 16, 4); FE ($3, 11, 5);
    817      1.1  christos 	      F ($5, 20, 4); }
    818      1.1  christos 
    819      1.1  christos /* ---------------------------------------------------------------------- */
    820      1.1  christos 
    821      1.1  christos 	| BNOT '#' EXPR ',' REG
    822      1.1  christos 	  { id24 (2, 0xe0, 0xf0); FE ($3, 11, 5); F ($5, 20, 4); }
    823      1.1  christos 
    824      1.1  christos /* ---------------------------------------------------------------------- */
    825      1.1  christos 
    826      1.1  christos 	| MOV bwl REG ',' '[' REG ',' REG ']'
    827      1.1  christos 	  { id24 (3, 0x00, 0); F ($2, 10, 2); F ($6, 12, 4); F ($8, 16, 4); F ($3, 20, 4); }
    828      1.1  christos 
    829      1.1  christos 	| MOV bwl '[' REG ',' REG ']' ',' REG
    830      1.1  christos 	  { id24 (3, 0x40, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); }
    831      1.1  christos 
    832      1.1  christos 	| MOVU bw '[' REG ',' REG ']' ',' REG
    833      1.1  christos 	  { id24 (3, 0xc0, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); }
    834      1.1  christos 
    835      1.1  christos /* ---------------------------------------------------------------------- */
    836      1.1  christos 
    837      1.1  christos 	| SUB { sub_op = 0; } op_subadd
    838      1.1  christos 	| ADD { sub_op = 2; } op_subadd
    839      1.1  christos 	| MUL { sub_op = 3; } op_subadd
    840      1.1  christos 	| AND_ { sub_op = 4; } op_subadd
    841      1.1  christos 	| OR  { sub_op = 5; } op_subadd
    842      1.1  christos 
    843      1.1  christos /* ---------------------------------------------------------------------- */
    844      1.1  christos /* There is no SBB #imm so we fake it with ADC.  */
    845      1.1  christos 
    846      1.1  christos 	| SBB '#' EXPR ',' REG
    847      1.1  christos 	  { id24 (2, 0x70, 0x20); F ($5, 20, 4); NBIMM ($3, 12); }
    848      1.1  christos 
    849      1.1  christos /* ---------------------------------------------------------------------- */
    850      1.1  christos 
    851  1.1.1.3  christos 	| MOVCO REG ',' '[' REG ']'
    852  1.1.1.3  christos 	  { rx_check_v2 (); B3 (0xfd, 0x27, 0x00); F ($5, 16, 4); F ($2, 20, 4); }
    853  1.1.1.3  christos 
    854  1.1.1.3  christos /* ---------------------------------------------------------------------- */
    855  1.1.1.3  christos 
    856  1.1.1.3  christos 	| MOVLI '[' REG ']' ',' REG
    857  1.1.1.3  christos 	  { rx_check_v2 (); B3 (0xfd, 0x2f, 0x00); F ($3, 16, 4); F ($6, 20, 4); }
    858  1.1.1.3  christos 
    859  1.1.1.3  christos /* ---------------------------------------------------------------------- */
    860  1.1.1.3  christos 
    861  1.1.1.3  christos 	| EMACA REG ',' REG ',' ACC
    862  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x07, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    863  1.1.1.3  christos 	| EMSBA REG ',' REG ',' ACC
    864  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x47, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    865  1.1.1.3  christos 	| EMULA REG ',' REG ',' ACC
    866  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x03, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    867  1.1.1.3  christos 	| MACLH REG ',' REG ',' ACC
    868  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x06, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    869  1.1.1.3  christos 	| MSBHI REG ',' REG ',' ACC
    870  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x44, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    871  1.1.1.3  christos 	| MSBLH REG ',' REG ',' ACC
    872  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x46, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    873  1.1.1.3  christos 	| MSBLO REG ',' REG ',' ACC
    874  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x45, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    875  1.1.1.3  christos 	| MULLH REG ',' REG ',' ACC
    876  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x02, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); }
    877  1.1.1.3  christos 	| MVFACGU { sub_op = 3; } mvfa_op
    878  1.1.1.3  christos 	| MVTACGU REG ',' ACC
    879  1.1.1.3  christos 	  { rx_check_v2 (); id24 (2, 0x17, 0x30); F ($4, 16, 1); F ($2, 20, 4); }
    880  1.1.1.3  christos 	| RACL '#' EXPR ',' ACC
    881  1.1.1.3  christos 	{ rx_check_v2 (); id24 (2, 0x19, 0x00); F ($5, 16, 1);
    882  1.1.1.3  christos 	    if (rx_uintop ($3, 4) && $3.X_add_number == 1)
    883  1.1.1.3  christos 	      ;
    884  1.1.1.3  christos 	    else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
    885  1.1.1.3  christos 	      F (1, 19, 1);
    886  1.1.1.3  christos 	    else
    887  1.1.1.3  christos 	      as_bad (_("RACL expects #1 or #2"));}
    888  1.1.1.3  christos 	| RDACL '#' EXPR ',' ACC
    889  1.1.1.3  christos 	{ rx_check_v2 (); id24 (2, 0x19, 0x40); F ($5, 16, 1);
    890  1.1.1.3  christos 	    if (rx_uintop ($3, 4) && $3.X_add_number == 1)
    891  1.1.1.3  christos 	      ;
    892  1.1.1.3  christos 	    else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
    893  1.1.1.3  christos 	      F (1, 19, 1);
    894  1.1.1.3  christos 	    else
    895  1.1.1.3  christos 	      as_bad (_("RDACL expects #1 or #2"));}
    896  1.1.1.3  christos 	| RDACW '#' EXPR ',' ACC
    897  1.1.1.3  christos 	{ rx_check_v2 (); id24 (2, 0x18, 0x40); F ($5, 16, 1);
    898  1.1.1.3  christos 	    if (rx_uintop ($3, 4) && $3.X_add_number == 1)
    899  1.1.1.3  christos 	      ;
    900  1.1.1.3  christos 	    else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
    901  1.1.1.3  christos 	      F (1, 19, 1);
    902  1.1.1.3  christos 	    else
    903  1.1.1.3  christos 	      as_bad (_("RDACW expects #1 or #2"));}
    904  1.1.1.3  christos 
    905  1.1.1.3  christos /* ---------------------------------------------------------------------- */
    906  1.1.1.3  christos 
    907      1.1  christos 	;
    908      1.1  christos 
    909      1.1  christos /* ====================================================================== */
    910      1.1  christos 
    911      1.1  christos op_subadd
    912      1.1  christos 	: REG ',' REG
    913      1.1  christos 	  { B2 (0x43 + (sub_op<<2), 0); F ($1, 8, 4); F ($3, 12, 4); }
    914      1.1  christos 	| disp '[' REG ']' DOT_UB ',' REG
    915      1.1  christos 	  { B2 (0x40 + (sub_op<<2), 0); F ($3, 8, 4); F ($7, 12, 4); DSP ($1, 6, BSIZE); }
    916      1.1  christos 	| disp '[' REG ']' memex ',' REG
    917      1.1  christos 	  { B3 (MEMEX, sub_op<<2, 0); F ($5, 8, 2); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, sizemap[$5]); }
    918      1.1  christos 	| REG ',' REG ',' REG
    919      1.1  christos 	  { id24 (4, sub_op<<4, 0), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); }
    920      1.1  christos 	;
    921      1.1  christos 
    922      1.1  christos /* sbb, neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */
    923      1.1  christos 
    924      1.1  christos op_dp20_rm_l
    925      1.1  christos 	: REG ',' REG
    926      1.1  christos 	  { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); }
    927      1.1  christos 	| disp '[' REG ']' opt_l ',' REG
    928      1.1  christos 	  { B4 (MEMEX, 0xa0, 0x00 + sub_op, 0x00);
    929      1.1  christos 	  F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, LSIZE); }
    930      1.1  christos 	;
    931      1.1  christos 
    932      1.1  christos /* neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */
    933      1.1  christos 
    934      1.1  christos op_dp20_rm
    935      1.1  christos 	: REG ',' REG
    936      1.1  christos 	  { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); }
    937      1.1  christos 	| disp '[' REG ']' DOT_UB ',' REG
    938      1.1  christos 	  { id24 (1, 0x00 + (sub_op<<2), 0x00); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); }
    939      1.1  christos 	| disp '[' REG ']' memex ',' REG
    940      1.1  christos 	  { B4 (MEMEX, 0x20 + ($5 << 6), 0x00 + sub_op, 0x00);
    941      1.1  christos 	  F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, sizemap[$5]); }
    942      1.1  christos 	;
    943      1.1  christos 
    944      1.1  christos op_dp20_i
    945      1.1  christos 	: '#' EXPR ',' REG
    946      1.1  christos 	  { id24 (2, 0x70, sub_op<<4); F ($4, 20, 4); IMM ($2, 12); }
    947      1.1  christos 	;
    948      1.1  christos 
    949      1.1  christos op_dp20_rim
    950      1.1  christos 	: op_dp20_rm
    951      1.1  christos 	| op_dp20_i
    952      1.1  christos 	;
    953      1.1  christos 
    954      1.1  christos op_dp20_rim_l
    955      1.1  christos 	: op_dp20_rm_l
    956      1.1  christos 	| op_dp20_i
    957      1.1  christos 	;
    958      1.1  christos 
    959      1.1  christos op_dp20_rr
    960      1.1  christos 	: REG ',' REG
    961      1.1  christos 	  { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); }
    962      1.1  christos 	| REG
    963      1.1  christos 	  { B2 (0x7e, sub_op2 << 4); F ($1, 12, 4); }
    964      1.1  christos 	;
    965      1.1  christos 
    966  1.1.1.3  christos op_dp20_r
    967  1.1.1.3  christos 	: REG ',' REG
    968  1.1.1.3  christos 	  { id24 (1, 0x4b + (sub_op2<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); }
    969  1.1.1.3  christos 	;
    970  1.1.1.3  christos 
    971  1.1.1.3  christos op_dp20_ri
    972  1.1.1.3  christos 	: { rx_check_v2 (); }
    973  1.1.1.3  christos 	  op_dp20_r
    974  1.1.1.3  christos 	| op_dp20_i
    975  1.1.1.3  christos 	;
    976  1.1.1.3  christos 
    977  1.1.1.3  christos /* xchg, utof, itof, emul, emulu */
    978      1.1  christos op_xchg
    979      1.1  christos 	: REG ',' REG
    980      1.1  christos 	  { id24 (1, 0x03 + (sub_op<<2), 0); F ($1, 16, 4); F ($3, 20, 4); }
    981      1.1  christos 	| disp '[' REG ']' DOT_UB ',' REG
    982      1.1  christos 	  { id24 (1, 0x00 + (sub_op<<2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); }
    983      1.1  christos 	| disp '[' REG ']' memex ',' REG
    984      1.1  christos 	  { B4 (MEMEX, 0x20, 0x00 + sub_op, 0); F ($5, 8, 2); F ($3, 24, 4); F ($7, 28, 4);
    985      1.1  christos 	    DSP ($1, 14, sizemap[$5]); }
    986      1.1  christos 	;
    987      1.1  christos 
    988      1.1  christos /* 000:SHLR, 001:SHAR, 010:SHLL, 011:-, 100:ROTR, 101:REVW, 110:ROTL, 111:REVL */
    989      1.1  christos op_shift_rot
    990      1.1  christos 	: REG ',' REG
    991      1.1  christos 	  { id24 (2, 0x60 + sub_op, 0); F ($1, 16, 4); F ($3, 20, 4); }
    992      1.1  christos 	;
    993      1.1  christos op_shift
    994      1.1  christos 	: '#' EXPR ',' REG
    995      1.1  christos 	  { B2 (0x68 + (sub_op<<1), 0); FE ($2, 7, 5); F ($4, 12, 4); }
    996      1.1  christos 	| '#' EXPR ',' REG ',' REG
    997      1.1  christos 	  { id24 (2, 0x80 + (sub_op << 5), 0); FE ($2, 11, 5); F ($4, 16, 4); F ($6, 20, 4); }
    998      1.1  christos 	| op_shift_rot
    999      1.1  christos 	;
   1000      1.1  christos 
   1001  1.1.1.3  christos float3_op
   1002  1.1.1.3  christos 	: '#' EXPR ',' REG
   1003  1.1.1.3  christos 	  { rx_check_float_support (); id24 (2, 0x72, sub_op << 4); F ($4, 20, 4); O4 ($2); }
   1004  1.1.1.3  christos 	| REG ',' REG
   1005  1.1.1.3  christos 	  { rx_check_float_support (); id24 (1, 0x83 + (sub_op << 2), 0); F ($1, 16, 4); F ($3, 20, 4); }
   1006  1.1.1.3  christos 	| disp '[' REG ']' opt_l ',' REG
   1007  1.1.1.3  christos 	  { rx_check_float_support (); id24 (1, 0x80 + (sub_op << 2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, LSIZE); }
   1008  1.1.1.3  christos 	| REG ',' REG ',' REG
   1009  1.1.1.3  christos 	  { rx_check_v2 (); id24 (4, 0x80 + (sub_op << 4), 0 ); F ($1, 16, 4); F ($3, 20, 4); F ($5, 12, 4); }
   1010  1.1.1.3  christos 	;
   1011      1.1  christos 
   1012      1.1  christos float2_op
   1013  1.1.1.2  christos 	: { rx_check_float_support (); }
   1014  1.1.1.2  christos 	  '#' EXPR ',' REG
   1015  1.1.1.2  christos 	  { id24 (2, 0x72, sub_op << 4); F ($5, 20, 4); O4 ($3); }
   1016      1.1  christos 	| float2_op_ni
   1017      1.1  christos 	;
   1018  1.1.1.2  christos 
   1019      1.1  christos float2_op_ni
   1020  1.1.1.2  christos 	: { rx_check_float_support (); }
   1021  1.1.1.2  christos 	  REG ',' REG
   1022  1.1.1.2  christos 	  { id24 (1, 0x83 + (sub_op << 2), 0); F ($2, 16, 4); F ($4, 20, 4); }
   1023  1.1.1.2  christos 	| { rx_check_float_support (); }
   1024  1.1.1.2  christos 	  disp '[' REG ']' opt_l ',' REG
   1025  1.1.1.2  christos 	  { id24 (1, 0x80 + (sub_op << 2), 0); F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, LSIZE); }
   1026      1.1  christos 	;
   1027      1.1  christos 
   1028  1.1.1.3  christos mvfa_op
   1029  1.1.1.3  christos 	: { rx_check_v2 (); }
   1030  1.1.1.3  christos 	  '#' EXPR ',' ACC ',' REG
   1031  1.1.1.3  christos 	  { id24 (2, 0x1e, sub_op << 4); F ($7, 20, 4); F ($5, 16, 1);
   1032  1.1.1.3  christos 	    if (rx_uintop ($3, 4))
   1033  1.1.1.3  christos 	      {
   1034  1.1.1.3  christos 		switch (exp_val ($3))
   1035  1.1.1.3  christos 		  {
   1036  1.1.1.3  christos 		  case 0:
   1037  1.1.1.3  christos 		    F (1, 15, 1);
   1038  1.1.1.3  christos 		    break;
   1039  1.1.1.3  christos 		  case 1:
   1040  1.1.1.3  christos 		    F (1, 15, 1);
   1041  1.1.1.3  christos 		    F (1, 17, 1);
   1042  1.1.1.3  christos 		    break;
   1043  1.1.1.3  christos 		  case 2:
   1044  1.1.1.3  christos 		    break;
   1045  1.1.1.3  christos 		  default:
   1046  1.1.1.3  christos 		    as_bad (_("IMM expects #0 to #2"));}
   1047  1.1.1.3  christos 	      } else
   1048  1.1.1.3  christos 	        as_bad (_("IMM expects #0 to #2"));}
   1049  1.1.1.3  christos 	;
   1050  1.1.1.3  christos 
   1051      1.1  christos /* ====================================================================== */
   1052      1.1  christos 
   1053      1.1  christos disp	:      { $$ = zero_expr (); }
   1054      1.1  christos 	| EXPR { $$ = $1; }
   1055      1.1  christos 	;
   1056      1.1  christos 
   1057      1.1  christos flag	: { need_flag = 1; } FLAG { need_flag = 0; $$ = $2; }
   1058      1.1  christos 	;
   1059      1.1  christos 
   1060      1.1  christos /* DOT_UB is not listed here, it's handled with a separate pattern.  */
   1061      1.1  christos /* Use sizemap[$n] to get LSIZE etc.  */
   1062      1.1  christos memex	: DOT_B  { $$ = 0; }
   1063      1.1  christos 	| DOT_W  { $$ = 1; }
   1064      1.1  christos 	|        { $$ = 2; }
   1065      1.1  christos 	| DOT_L  { $$ = 2; }
   1066      1.1  christos 	| DOT_UW { $$ = 3; }
   1067      1.1  christos 	;
   1068      1.1  christos 
   1069      1.1  christos bwl	:       { $$ = LSIZE; }
   1070      1.1  christos 	| DOT_B { $$ = BSIZE; }
   1071      1.1  christos 	| DOT_W { $$ = WSIZE; }
   1072      1.1  christos 	| DOT_L { $$ = LSIZE; }
   1073      1.1  christos 	;
   1074      1.1  christos 
   1075      1.1  christos bw	:       { $$ = 1; }
   1076      1.1  christos 	| DOT_B { $$ = 0; }
   1077      1.1  christos 	| DOT_W { $$ = 1; }
   1078      1.1  christos 	;
   1079      1.1  christos 
   1080      1.1  christos opt_l	: 	{}
   1081      1.1  christos 	| DOT_L {}
   1082      1.1  christos 	;
   1083      1.1  christos 
   1084  1.1.1.2  christos opt_b	: 	{}
   1085  1.1.1.2  christos 	| DOT_B {}
   1086  1.1.1.2  christos 	;
   1087  1.1.1.2  christos 
   1088      1.1  christos %%
   1089      1.1  christos /* ====================================================================== */
   1090      1.1  christos 
   1091      1.1  christos static struct
   1092      1.1  christos {
   1093      1.1  christos   const char * string;
   1094      1.1  christos   int          token;
   1095      1.1  christos   int          val;
   1096      1.1  christos }
   1097      1.1  christos token_table[] =
   1098      1.1  christos {
   1099      1.1  christos   { "r0", REG, 0 },
   1100      1.1  christos   { "r1", REG, 1 },
   1101      1.1  christos   { "r2", REG, 2 },
   1102      1.1  christos   { "r3", REG, 3 },
   1103      1.1  christos   { "r4", REG, 4 },
   1104      1.1  christos   { "r5", REG, 5 },
   1105      1.1  christos   { "r6", REG, 6 },
   1106      1.1  christos   { "r7", REG, 7 },
   1107      1.1  christos   { "r8", REG, 8 },
   1108      1.1  christos   { "r9", REG, 9 },
   1109      1.1  christos   { "r10", REG, 10 },
   1110      1.1  christos   { "r11", REG, 11 },
   1111      1.1  christos   { "r12", REG, 12 },
   1112      1.1  christos   { "r13", REG, 13 },
   1113      1.1  christos   { "r14", REG, 14 },
   1114      1.1  christos   { "r15", REG, 15 },
   1115      1.1  christos 
   1116      1.1  christos   { "psw", CREG, 0 },
   1117      1.1  christos   { "pc", CREG, 1 },
   1118      1.1  christos   { "usp", CREG, 2 },
   1119      1.1  christos   { "fpsw", CREG, 3 },
   1120      1.1  christos   /* reserved */
   1121      1.1  christos   /* reserved */
   1122      1.1  christos   /* reserved */
   1123      1.1  christos   { "wr", CREG, 7 },
   1124      1.1  christos 
   1125      1.1  christos   { "bpsw", CREG, 8 },
   1126      1.1  christos   { "bpc", CREG, 9 },
   1127      1.1  christos   { "isp", CREG, 10 },
   1128      1.1  christos   { "fintv", CREG, 11 },
   1129      1.1  christos   { "intb", CREG, 12 },
   1130  1.1.1.3  christos   { "extb", CREG, 13 },
   1131      1.1  christos 
   1132      1.1  christos   { "pbp", CREG, 16 },
   1133      1.1  christos   { "pben", CREG, 17 },
   1134      1.1  christos 
   1135      1.1  christos   { "bbpsw", CREG, 24 },
   1136      1.1  christos   { "bbpc", CREG, 25 },
   1137      1.1  christos 
   1138      1.1  christos   { ".s", DOT_S, 0 },
   1139      1.1  christos   { ".b", DOT_B, 0 },
   1140      1.1  christos   { ".w", DOT_W, 0 },
   1141      1.1  christos   { ".l", DOT_L, 0 },
   1142      1.1  christos   { ".a", DOT_A , 0},
   1143      1.1  christos   { ".ub", DOT_UB, 0 },
   1144      1.1  christos   { ".uw", DOT_UW , 0},
   1145      1.1  christos 
   1146      1.1  christos   { "c", FLAG, 0 },
   1147      1.1  christos   { "z", FLAG, 1 },
   1148      1.1  christos   { "s", FLAG, 2 },
   1149      1.1  christos   { "o", FLAG, 3 },
   1150      1.1  christos   { "i", FLAG, 8 },
   1151      1.1  christos   { "u", FLAG, 9 },
   1152      1.1  christos 
   1153  1.1.1.3  christos   { "a0", ACC, 0 },
   1154  1.1.1.3  christos   { "a1", ACC, 1 },
   1155  1.1.1.3  christos 
   1156      1.1  christos #define OPC(x) { #x, x, IS_OPCODE }
   1157      1.1  christos   OPC(ABS),
   1158      1.1  christos   OPC(ADC),
   1159      1.1  christos   OPC(ADD),
   1160      1.1  christos   { "and", AND_, IS_OPCODE },
   1161      1.1  christos   OPC(BCLR),
   1162      1.1  christos   OPC(BCND),
   1163      1.1  christos   OPC(BMCND),
   1164      1.1  christos   OPC(BNOT),
   1165      1.1  christos   OPC(BRA),
   1166      1.1  christos   OPC(BRK),
   1167      1.1  christos   OPC(BSET),
   1168      1.1  christos   OPC(BSR),
   1169      1.1  christos   OPC(BTST),
   1170      1.1  christos   OPC(CLRPSW),
   1171      1.1  christos   OPC(CMP),
   1172      1.1  christos   OPC(DBT),
   1173      1.1  christos   OPC(DIV),
   1174      1.1  christos   OPC(DIVU),
   1175      1.1  christos   OPC(EDIV),
   1176      1.1  christos   OPC(EDIVU),
   1177  1.1.1.3  christos   OPC(EMACA),
   1178  1.1.1.3  christos   OPC(EMSBA),
   1179      1.1  christos   OPC(EMUL),
   1180  1.1.1.3  christos   OPC(EMULA),
   1181      1.1  christos   OPC(EMULU),
   1182      1.1  christos   OPC(FADD),
   1183      1.1  christos   OPC(FCMP),
   1184      1.1  christos   OPC(FDIV),
   1185      1.1  christos   OPC(FMUL),
   1186      1.1  christos   OPC(FREIT),
   1187  1.1.1.3  christos   OPC(FSQRT),
   1188  1.1.1.3  christos   OPC(FTOU),
   1189      1.1  christos   OPC(FSUB),
   1190      1.1  christos   OPC(FTOI),
   1191      1.1  christos   OPC(INT),
   1192      1.1  christos   OPC(ITOF),
   1193      1.1  christos   OPC(JMP),
   1194      1.1  christos   OPC(JSR),
   1195  1.1.1.3  christos   OPC(MVFACGU),
   1196      1.1  christos   OPC(MVFACHI),
   1197      1.1  christos   OPC(MVFACMI),
   1198      1.1  christos   OPC(MVFACLO),
   1199      1.1  christos   OPC(MVFC),
   1200  1.1.1.3  christos   OPC(MVTACGU),
   1201      1.1  christos   OPC(MVTACHI),
   1202      1.1  christos   OPC(MVTACLO),
   1203      1.1  christos   OPC(MVTC),
   1204      1.1  christos   OPC(MVTIPL),
   1205      1.1  christos   OPC(MACHI),
   1206      1.1  christos   OPC(MACLO),
   1207  1.1.1.3  christos   OPC(MACLH),
   1208      1.1  christos   OPC(MAX),
   1209      1.1  christos   OPC(MIN),
   1210      1.1  christos   OPC(MOV),
   1211  1.1.1.3  christos   OPC(MOVCO),
   1212  1.1.1.3  christos   OPC(MOVLI),
   1213      1.1  christos   OPC(MOVU),
   1214  1.1.1.3  christos   OPC(MSBHI),
   1215  1.1.1.3  christos   OPC(MSBLH),
   1216  1.1.1.3  christos   OPC(MSBLO),
   1217      1.1  christos   OPC(MUL),
   1218      1.1  christos   OPC(MULHI),
   1219  1.1.1.3  christos   OPC(MULLH),
   1220      1.1  christos   OPC(MULLO),
   1221      1.1  christos   OPC(MULU),
   1222      1.1  christos   OPC(NEG),
   1223      1.1  christos   OPC(NOP),
   1224      1.1  christos   OPC(NOT),
   1225      1.1  christos   OPC(OR),
   1226      1.1  christos   OPC(POP),
   1227      1.1  christos   OPC(POPC),
   1228      1.1  christos   OPC(POPM),
   1229      1.1  christos   OPC(PUSH),
   1230      1.1  christos   OPC(PUSHA),
   1231      1.1  christos   OPC(PUSHC),
   1232      1.1  christos   OPC(PUSHM),
   1233  1.1.1.3  christos   OPC(RACL),
   1234      1.1  christos   OPC(RACW),
   1235  1.1.1.3  christos   OPC(RDACL),
   1236  1.1.1.3  christos   OPC(RDACW),
   1237      1.1  christos   OPC(REIT),
   1238      1.1  christos   OPC(REVL),
   1239      1.1  christos   OPC(REVW),
   1240      1.1  christos   OPC(RMPA),
   1241      1.1  christos   OPC(ROLC),
   1242      1.1  christos   OPC(RORC),
   1243      1.1  christos   OPC(ROTL),
   1244      1.1  christos   OPC(ROTR),
   1245      1.1  christos   OPC(ROUND),
   1246      1.1  christos   OPC(RTE),
   1247      1.1  christos   OPC(RTFI),
   1248      1.1  christos   OPC(RTS),
   1249      1.1  christos   OPC(RTSD),
   1250      1.1  christos   OPC(SAT),
   1251      1.1  christos   OPC(SATR),
   1252      1.1  christos   OPC(SBB),
   1253      1.1  christos   OPC(SCCND),
   1254      1.1  christos   OPC(SCMPU),
   1255      1.1  christos   OPC(SETPSW),
   1256      1.1  christos   OPC(SHAR),
   1257      1.1  christos   OPC(SHLL),
   1258      1.1  christos   OPC(SHLR),
   1259      1.1  christos   OPC(SMOVB),
   1260      1.1  christos   OPC(SMOVF),
   1261      1.1  christos   OPC(SMOVU),
   1262      1.1  christos   OPC(SSTR),
   1263      1.1  christos   OPC(STNZ),
   1264      1.1  christos   OPC(STOP),
   1265      1.1  christos   OPC(STZ),
   1266      1.1  christos   OPC(SUB),
   1267      1.1  christos   OPC(SUNTIL),
   1268      1.1  christos   OPC(SWHILE),
   1269      1.1  christos   OPC(TST),
   1270  1.1.1.3  christos   OPC(UTOF),
   1271      1.1  christos   OPC(WAIT),
   1272      1.1  christos   OPC(XCHG),
   1273      1.1  christos   OPC(XOR),
   1274      1.1  christos };
   1275      1.1  christos 
   1276      1.1  christos #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
   1277      1.1  christos 
   1278      1.1  christos static struct
   1279      1.1  christos {
   1280  1.1.1.3  christos   const char * string;
   1281      1.1  christos   int    token;
   1282      1.1  christos }
   1283      1.1  christos condition_opcode_table[] =
   1284      1.1  christos {
   1285      1.1  christos   { "b", BCND },
   1286      1.1  christos   { "bm", BMCND },
   1287      1.1  christos   { "sc", SCCND },
   1288      1.1  christos };
   1289      1.1  christos 
   1290      1.1  christos #define NUM_CONDITION_OPCODES (sizeof (condition_opcode_table) / sizeof (condition_opcode_table[0]))
   1291      1.1  christos 
   1292      1.1  christos static struct
   1293      1.1  christos {
   1294  1.1.1.3  christos   const char * string;
   1295      1.1  christos   int    val;
   1296      1.1  christos }
   1297      1.1  christos condition_table[] =
   1298      1.1  christos {
   1299      1.1  christos   { "z", 0 },
   1300      1.1  christos   { "eq", 0 },
   1301      1.1  christos   { "geu",  2 },
   1302      1.1  christos   { "c",  2 },
   1303      1.1  christos   { "gtu", 4 },
   1304      1.1  christos   { "pz", 6 },
   1305      1.1  christos   { "ge", 8 },
   1306      1.1  christos   { "gt", 10 },
   1307      1.1  christos   { "o",  12},
   1308      1.1  christos   /* always = 14 */
   1309      1.1  christos   { "nz", 1 },
   1310      1.1  christos   { "ne", 1 },
   1311      1.1  christos   { "ltu", 3 },
   1312      1.1  christos   { "nc", 3 },
   1313      1.1  christos   { "leu", 5 },
   1314      1.1  christos   { "n", 7 },
   1315      1.1  christos   { "lt", 9 },
   1316      1.1  christos   { "le", 11 },
   1317      1.1  christos   { "no", 13 }
   1318      1.1  christos   /* never = 15 */
   1319      1.1  christos };
   1320      1.1  christos 
   1321      1.1  christos #define NUM_CONDITIONS (sizeof (condition_table) / sizeof (condition_table[0]))
   1322      1.1  christos 
   1323      1.1  christos void
   1324      1.1  christos rx_lex_init (char * beginning, char * ending)
   1325      1.1  christos {
   1326      1.1  christos   rx_init_start = beginning;
   1327      1.1  christos   rx_lex_start = beginning;
   1328      1.1  christos   rx_lex_end = ending;
   1329      1.1  christos   rx_in_brackets = 0;
   1330      1.1  christos   rx_last_token = 0;
   1331      1.1  christos 
   1332      1.1  christos   setbuf (stdout, 0);
   1333      1.1  christos }
   1334      1.1  christos 
   1335      1.1  christos static int
   1336  1.1.1.3  christos check_condition (const char * base)
   1337      1.1  christos {
   1338      1.1  christos   char * cp;
   1339      1.1  christos   unsigned int i;
   1340      1.1  christos 
   1341      1.1  christos   if ((unsigned) (rx_lex_end - rx_lex_start) < strlen (base) + 1)
   1342      1.1  christos     return 0;
   1343      1.1  christos   if (memcmp (rx_lex_start, base, strlen (base)))
   1344      1.1  christos     return 0;
   1345      1.1  christos   cp = rx_lex_start + strlen (base);
   1346      1.1  christos   for (i = 0; i < NUM_CONDITIONS; i ++)
   1347      1.1  christos     {
   1348      1.1  christos       if (strcasecmp (cp, condition_table[i].string) == 0)
   1349      1.1  christos 	{
   1350      1.1  christos 	  rx_lval.regno = condition_table[i].val;
   1351      1.1  christos 	  return 1;
   1352      1.1  christos 	}
   1353      1.1  christos     }
   1354      1.1  christos   return 0;
   1355      1.1  christos }
   1356      1.1  christos 
   1357      1.1  christos static int
   1358      1.1  christos rx_lex (void)
   1359      1.1  christos {
   1360      1.1  christos   unsigned int ci;
   1361      1.1  christos   char * save_input_pointer;
   1362      1.1  christos 
   1363      1.1  christos   while (ISSPACE (*rx_lex_start)
   1364      1.1  christos 	 && rx_lex_start != rx_lex_end)
   1365      1.1  christos     rx_lex_start ++;
   1366      1.1  christos 
   1367      1.1  christos   rx_last_exp_start = rx_lex_start;
   1368      1.1  christos 
   1369      1.1  christos   if (rx_lex_start == rx_lex_end)
   1370      1.1  christos     return 0;
   1371      1.1  christos 
   1372      1.1  christos   if (ISALPHA (*rx_lex_start)
   1373      1.1  christos       || (rx_pid_register != -1 && memcmp (rx_lex_start, "%pidreg", 7) == 0)
   1374      1.1  christos       || (rx_gp_register != -1 && memcmp (rx_lex_start, "%gpreg", 6) == 0)
   1375      1.1  christos       || (*rx_lex_start == '.' && ISALPHA (rx_lex_start[1])))
   1376      1.1  christos     {
   1377      1.1  christos       unsigned int i;
   1378      1.1  christos       char * e;
   1379      1.1  christos       char save;
   1380      1.1  christos 
   1381      1.1  christos       for (e = rx_lex_start + 1;
   1382      1.1  christos 	   e < rx_lex_end && ISALNUM (*e);
   1383      1.1  christos 	   e ++)
   1384      1.1  christos 	;
   1385      1.1  christos       save = *e;
   1386      1.1  christos       *e = 0;
   1387      1.1  christos 
   1388      1.1  christos       if (strcmp (rx_lex_start, "%pidreg") == 0)
   1389      1.1  christos 	{
   1390      1.1  christos 	  {
   1391      1.1  christos 	    rx_lval.regno = rx_pid_register;
   1392      1.1  christos 	    *e = save;
   1393      1.1  christos 	    rx_lex_start = e;
   1394      1.1  christos 	    rx_last_token = REG;
   1395      1.1  christos 	    return REG;
   1396      1.1  christos 	  }
   1397      1.1  christos 	}
   1398      1.1  christos 
   1399      1.1  christos       if (strcmp (rx_lex_start, "%gpreg") == 0)
   1400      1.1  christos 	{
   1401      1.1  christos 	  {
   1402      1.1  christos 	    rx_lval.regno = rx_gp_register;
   1403      1.1  christos 	    *e = save;
   1404      1.1  christos 	    rx_lex_start = e;
   1405      1.1  christos 	    rx_last_token = REG;
   1406      1.1  christos 	    return REG;
   1407      1.1  christos 	  }
   1408      1.1  christos 	}
   1409      1.1  christos 
   1410      1.1  christos       if (rx_last_token == 0)
   1411      1.1  christos 	for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++)
   1412      1.1  christos 	  if (check_condition (condition_opcode_table[ci].string))
   1413      1.1  christos 	    {
   1414      1.1  christos 	      *e = save;
   1415      1.1  christos 	      rx_lex_start = e;
   1416      1.1  christos 	      rx_last_token = condition_opcode_table[ci].token;
   1417      1.1  christos 	      return condition_opcode_table[ci].token;
   1418      1.1  christos 	    }
   1419      1.1  christos 
   1420      1.1  christos       for (i = 0; i < NUM_TOKENS; i++)
   1421      1.1  christos 	if (strcasecmp (rx_lex_start, token_table[i].string) == 0
   1422      1.1  christos 	    && !(token_table[i].val == IS_OPCODE && rx_last_token != 0)
   1423      1.1  christos 	    && !(token_table[i].token == FLAG && !need_flag))
   1424      1.1  christos 	  {
   1425      1.1  christos 	    rx_lval.regno = token_table[i].val;
   1426      1.1  christos 	    *e = save;
   1427      1.1  christos 	    rx_lex_start = e;
   1428      1.1  christos 	    rx_last_token = token_table[i].token;
   1429      1.1  christos 	    return token_table[i].token;
   1430      1.1  christos 	  }
   1431      1.1  christos       *e = save;
   1432      1.1  christos     }
   1433      1.1  christos 
   1434      1.1  christos   if (rx_last_token == 0)
   1435      1.1  christos     {
   1436      1.1  christos       rx_last_token = UNKNOWN_OPCODE;
   1437      1.1  christos       return UNKNOWN_OPCODE;
   1438      1.1  christos     }
   1439      1.1  christos 
   1440      1.1  christos   if (rx_last_token == UNKNOWN_OPCODE)
   1441      1.1  christos     return 0;
   1442      1.1  christos 
   1443      1.1  christos   if (*rx_lex_start == '[')
   1444      1.1  christos     rx_in_brackets = 1;
   1445      1.1  christos   if (*rx_lex_start == ']')
   1446      1.1  christos     rx_in_brackets = 0;
   1447      1.1  christos 
   1448      1.1  christos   if (rx_in_brackets
   1449      1.1  christos       || rx_last_token == REG
   1450      1.1  christos       || strchr ("[],#", *rx_lex_start))
   1451      1.1  christos     {
   1452      1.1  christos       rx_last_token = *rx_lex_start;
   1453      1.1  christos       return *rx_lex_start ++;
   1454      1.1  christos     }
   1455      1.1  christos 
   1456      1.1  christos   save_input_pointer = input_line_pointer;
   1457      1.1  christos   input_line_pointer = rx_lex_start;
   1458      1.1  christos   rx_lval.exp.X_md = 0;
   1459      1.1  christos   expression (&rx_lval.exp);
   1460      1.1  christos 
   1461      1.1  christos   /* We parse but ignore any :<size> modifier on expressions.  */
   1462      1.1  christos   if (*input_line_pointer == ':')
   1463      1.1  christos     {
   1464      1.1  christos       char *cp;
   1465      1.1  christos 
   1466      1.1  christos       for (cp  = input_line_pointer + 1; *cp && cp < rx_lex_end; cp++)
   1467      1.1  christos 	if (!ISDIGIT (*cp))
   1468      1.1  christos 	  break;
   1469      1.1  christos       if (cp > input_line_pointer+1)
   1470      1.1  christos 	input_line_pointer = cp;
   1471      1.1  christos     }
   1472      1.1  christos 
   1473      1.1  christos   rx_lex_start = input_line_pointer;
   1474      1.1  christos   input_line_pointer = save_input_pointer;
   1475      1.1  christos   rx_last_token = EXPR;
   1476      1.1  christos   return EXPR;
   1477      1.1  christos }
   1478      1.1  christos 
   1479      1.1  christos int
   1480      1.1  christos rx_error (const char * str)
   1481      1.1  christos {
   1482      1.1  christos   int len;
   1483      1.1  christos 
   1484      1.1  christos   len = rx_last_exp_start - rx_init_start;
   1485      1.1  christos 
   1486      1.1  christos   as_bad ("%s", rx_init_start);
   1487      1.1  christos   as_bad ("%*s^ %s", len, "", str);
   1488      1.1  christos   return 0;
   1489      1.1  christos }
   1490      1.1  christos 
   1491      1.1  christos static int
   1492      1.1  christos rx_intop (expressionS exp, int nbits, int opbits)
   1493      1.1  christos {
   1494      1.1  christos   long v;
   1495      1.1  christos   long mask, msb;
   1496      1.1  christos 
   1497  1.1.1.3  christos   if (exp.X_op == O_big)
   1498  1.1.1.3  christos     {
   1499  1.1.1.3  christos       if (nbits == 32)
   1500  1.1.1.3  christos 	return 1;
   1501  1.1.1.3  christos       if (exp.X_add_number == -1)
   1502  1.1.1.3  christos 	return 0;
   1503  1.1.1.3  christos     }
   1504  1.1.1.3  christos   else if (exp.X_op != O_constant)
   1505      1.1  christos     return 0;
   1506      1.1  christos   v = exp.X_add_number;
   1507      1.1  christos 
   1508      1.1  christos   msb = 1UL << (opbits - 1);
   1509      1.1  christos   mask = (1UL << opbits) - 1;
   1510      1.1  christos 
   1511      1.1  christos   if ((v & msb) && ! (v & ~mask))
   1512      1.1  christos     v -= 1UL << opbits;
   1513      1.1  christos 
   1514      1.1  christos   switch (nbits)
   1515      1.1  christos     {
   1516      1.1  christos     case 4:
   1517      1.1  christos       return -0x8 <= v && v <= 0x7;
   1518      1.1  christos     case 5:
   1519      1.1  christos       return -0x10 <= v && v <= 0x17;
   1520      1.1  christos     case 8:
   1521      1.1  christos       return -0x80 <= v && v <= 0x7f;
   1522      1.1  christos     case 16:
   1523      1.1  christos       return -0x8000 <= v && v <= 0x7fff;
   1524      1.1  christos     case 24:
   1525      1.1  christos       return -0x800000 <= v && v <= 0x7fffff;
   1526      1.1  christos     case 32:
   1527      1.1  christos       return 1;
   1528      1.1  christos     default:
   1529      1.1  christos       printf ("rx_intop passed %d\n", nbits);
   1530      1.1  christos       abort ();
   1531      1.1  christos     }
   1532      1.1  christos   return 1;
   1533      1.1  christos }
   1534      1.1  christos 
   1535      1.1  christos static int
   1536      1.1  christos rx_uintop (expressionS exp, int nbits)
   1537      1.1  christos {
   1538      1.1  christos   unsigned long v;
   1539      1.1  christos 
   1540      1.1  christos   if (exp.X_op != O_constant)
   1541      1.1  christos     return 0;
   1542      1.1  christos   v = exp.X_add_number;
   1543      1.1  christos 
   1544      1.1  christos   switch (nbits)
   1545      1.1  christos     {
   1546      1.1  christos     case 4:
   1547      1.1  christos       return v <= 0xf;
   1548      1.1  christos     case 8:
   1549      1.1  christos       return v <= 0xff;
   1550      1.1  christos     case 16:
   1551      1.1  christos       return v <= 0xffff;
   1552      1.1  christos     case 24:
   1553      1.1  christos       return v <= 0xffffff;
   1554      1.1  christos     default:
   1555      1.1  christos       printf ("rx_uintop passed %d\n", nbits);
   1556      1.1  christos       abort ();
   1557      1.1  christos     }
   1558      1.1  christos   return 1;
   1559      1.1  christos }
   1560      1.1  christos 
   1561      1.1  christos static int
   1562      1.1  christos rx_disp3op (expressionS exp)
   1563      1.1  christos {
   1564      1.1  christos   unsigned long v;
   1565      1.1  christos 
   1566      1.1  christos   if (exp.X_op != O_constant)
   1567      1.1  christos     return 0;
   1568      1.1  christos   v = exp.X_add_number;
   1569      1.1  christos   if (v < 3 || v > 10)
   1570      1.1  christos     return 0;
   1571      1.1  christos   return 1;
   1572      1.1  christos }
   1573      1.1  christos 
   1574      1.1  christos static int
   1575      1.1  christos rx_disp5op (expressionS * exp, int msize)
   1576      1.1  christos {
   1577      1.1  christos   long v;
   1578      1.1  christos 
   1579      1.1  christos   if (exp->X_op != O_constant)
   1580      1.1  christos     return 0;
   1581      1.1  christos   v = exp->X_add_number;
   1582      1.1  christos 
   1583      1.1  christos   switch (msize)
   1584      1.1  christos     {
   1585      1.1  christos     case BSIZE:
   1586  1.1.1.2  christos       if (0 <= v && v <= 31)
   1587      1.1  christos 	return 1;
   1588      1.1  christos       break;
   1589      1.1  christos     case WSIZE:
   1590      1.1  christos       if (v & 1)
   1591      1.1  christos 	return 0;
   1592  1.1.1.2  christos       if (0 <= v && v <= 63)
   1593      1.1  christos 	{
   1594      1.1  christos 	  exp->X_add_number >>= 1;
   1595      1.1  christos 	  return 1;
   1596      1.1  christos 	}
   1597      1.1  christos       break;
   1598      1.1  christos     case LSIZE:
   1599      1.1  christos       if (v & 3)
   1600      1.1  christos 	return 0;
   1601  1.1.1.2  christos       if (0 <= v && v <= 127)
   1602      1.1  christos 	{
   1603      1.1  christos 	  exp->X_add_number >>= 2;
   1604      1.1  christos 	  return 1;
   1605      1.1  christos 	}
   1606      1.1  christos       break;
   1607      1.1  christos     }
   1608      1.1  christos   return 0;
   1609      1.1  christos }
   1610      1.1  christos 
   1611      1.1  christos /* Just like the above, but allows a zero displacement.  */
   1612      1.1  christos 
   1613      1.1  christos static int
   1614      1.1  christos rx_disp5op0 (expressionS * exp, int msize)
   1615      1.1  christos {
   1616      1.1  christos   if (exp->X_op != O_constant)
   1617      1.1  christos     return 0;
   1618      1.1  christos   if (exp->X_add_number == 0)
   1619      1.1  christos     return 1;
   1620      1.1  christos   return rx_disp5op (exp, msize);
   1621      1.1  christos }
   1622      1.1  christos 
   1623      1.1  christos static int
   1624      1.1  christos exp_val (expressionS exp)
   1625      1.1  christos {
   1626      1.1  christos   if (exp.X_op != O_constant)
   1627      1.1  christos   {
   1628      1.1  christos     rx_error (_("constant expected"));
   1629      1.1  christos     return 0;
   1630      1.1  christos   }
   1631      1.1  christos   return exp.X_add_number;
   1632      1.1  christos }
   1633      1.1  christos 
   1634      1.1  christos static expressionS
   1635      1.1  christos zero_expr (void)
   1636      1.1  christos {
   1637      1.1  christos   /* Static, so program load sets it to all zeros, which is what we want.  */
   1638      1.1  christos   static expressionS zero;
   1639      1.1  christos   zero.X_op = O_constant;
   1640      1.1  christos   return zero;
   1641      1.1  christos }
   1642      1.1  christos 
   1643      1.1  christos static int
   1644      1.1  christos immediate (expressionS exp, int type, int pos, int bits)
   1645      1.1  christos {
   1646      1.1  christos   /* We will emit constants ourself here, so negate them.  */
   1647      1.1  christos   if (type == RXREL_NEGATIVE && exp.X_op == O_constant)
   1648      1.1  christos     exp.X_add_number = - exp.X_add_number;
   1649      1.1  christos   if (type == RXREL_NEGATIVE_BORROW)
   1650      1.1  christos     {
   1651      1.1  christos       if (exp.X_op == O_constant)
   1652      1.1  christos 	exp.X_add_number = - exp.X_add_number - 1;
   1653      1.1  christos       else
   1654      1.1  christos 	rx_error (_("sbb cannot use symbolic immediates"));
   1655      1.1  christos     }
   1656      1.1  christos 
   1657      1.1  christos   if (rx_intop (exp, 8, bits))
   1658      1.1  christos     {
   1659      1.1  christos       rx_op (exp, 1, type);
   1660      1.1  christos       return 1;
   1661      1.1  christos     }
   1662      1.1  christos   else if (rx_intop (exp, 16, bits))
   1663      1.1  christos     {
   1664      1.1  christos       rx_op (exp, 2, type);
   1665      1.1  christos       return 2;
   1666      1.1  christos     }
   1667      1.1  christos   else if (rx_uintop (exp, 16) && bits == 16)
   1668      1.1  christos     {
   1669      1.1  christos       rx_op (exp, 2, type);
   1670      1.1  christos       return 2;
   1671      1.1  christos     }
   1672      1.1  christos   else if (rx_intop (exp, 24, bits))
   1673      1.1  christos     {
   1674      1.1  christos       rx_op (exp, 3, type);
   1675      1.1  christos       return 3;
   1676      1.1  christos     }
   1677      1.1  christos   else if (rx_intop (exp, 32, bits))
   1678      1.1  christos     {
   1679      1.1  christos       rx_op (exp, 4, type);
   1680      1.1  christos       return 0;
   1681      1.1  christos     }
   1682      1.1  christos   else if (type == RXREL_SIGNED)
   1683      1.1  christos     {
   1684      1.1  christos       /* This is a symbolic immediate, we will relax it later.  */
   1685      1.1  christos       rx_relax (RX_RELAX_IMM, pos);
   1686      1.1  christos       rx_op (exp, linkrelax ? 4 : 1, type);
   1687      1.1  christos       return 1;
   1688      1.1  christos     }
   1689      1.1  christos   else
   1690      1.1  christos     {
   1691      1.1  christos       /* Let the linker deal with it.  */
   1692      1.1  christos       rx_op (exp, 4, type);
   1693      1.1  christos       return 0;
   1694      1.1  christos     }
   1695      1.1  christos }
   1696      1.1  christos 
   1697      1.1  christos static int
   1698      1.1  christos displacement (expressionS exp, int msize)
   1699      1.1  christos {
   1700      1.1  christos   int val;
   1701      1.1  christos   int vshift = 0;
   1702      1.1  christos 
   1703      1.1  christos   if (exp.X_op == O_symbol
   1704      1.1  christos       && exp.X_md)
   1705      1.1  christos     {
   1706      1.1  christos       switch (exp.X_md)
   1707      1.1  christos 	{
   1708      1.1  christos 	case BFD_RELOC_GPREL16:
   1709      1.1  christos 	  switch (msize)
   1710      1.1  christos 	    {
   1711      1.1  christos 	    case BSIZE:
   1712      1.1  christos 	      exp.X_md = BFD_RELOC_RX_GPRELB;
   1713      1.1  christos 	      break;
   1714      1.1  christos 	    case WSIZE:
   1715      1.1  christos 	      exp.X_md = BFD_RELOC_RX_GPRELW;
   1716      1.1  christos 	      break;
   1717      1.1  christos 	    case LSIZE:
   1718      1.1  christos 	      exp.X_md = BFD_RELOC_RX_GPRELL;
   1719      1.1  christos 	      break;
   1720      1.1  christos 	    }
   1721      1.1  christos 	  O2 (exp);
   1722      1.1  christos 	  return 2;
   1723      1.1  christos 	}
   1724      1.1  christos     }
   1725      1.1  christos 
   1726      1.1  christos   if (exp.X_op == O_subtract)
   1727      1.1  christos     {
   1728      1.1  christos       exp.X_md = BFD_RELOC_RX_DIFF;
   1729      1.1  christos       O2 (exp);
   1730      1.1  christos       return 2;
   1731      1.1  christos     }
   1732      1.1  christos 
   1733      1.1  christos   if (exp.X_op != O_constant)
   1734      1.1  christos     {
   1735      1.1  christos       rx_error (_("displacements must be constants"));
   1736      1.1  christos       return -1;
   1737      1.1  christos     }
   1738      1.1  christos   val = exp.X_add_number;
   1739      1.1  christos 
   1740      1.1  christos   if (val == 0)
   1741      1.1  christos     return 0;
   1742      1.1  christos 
   1743      1.1  christos   switch (msize)
   1744      1.1  christos     {
   1745      1.1  christos     case BSIZE:
   1746      1.1  christos       break;
   1747      1.1  christos     case WSIZE:
   1748      1.1  christos       if (val & 1)
   1749      1.1  christos 	rx_error (_("word displacement not word-aligned"));
   1750      1.1  christos       vshift = 1;
   1751      1.1  christos       break;
   1752      1.1  christos     case LSIZE:
   1753      1.1  christos       if (val & 3)
   1754      1.1  christos 	rx_error (_("long displacement not long-aligned"));
   1755      1.1  christos       vshift = 2;
   1756      1.1  christos       break;
   1757      1.1  christos     default:
   1758      1.1  christos       as_bad (_("displacement with unknown size (internal bug?)\n"));
   1759      1.1  christos       break;
   1760      1.1  christos     }
   1761      1.1  christos 
   1762      1.1  christos   val >>= vshift;
   1763      1.1  christos   exp.X_add_number = val;
   1764      1.1  christos 
   1765      1.1  christos   if (0 <= val && val <= 255 )
   1766      1.1  christos     {
   1767      1.1  christos       O1 (exp);
   1768      1.1  christos       return 1;
   1769      1.1  christos     }
   1770      1.1  christos 
   1771      1.1  christos   if (0 <= val && val <= 65535)
   1772      1.1  christos     {
   1773      1.1  christos       O2 (exp);
   1774      1.1  christos       return 2;
   1775      1.1  christos     }
   1776      1.1  christos   if (val < 0)
   1777      1.1  christos     rx_error (_("negative displacements not allowed"));
   1778      1.1  christos   else
   1779      1.1  christos     rx_error (_("displacement too large"));
   1780      1.1  christos   return -1;
   1781      1.1  christos }
   1782      1.1  christos 
   1783      1.1  christos static void
   1784      1.1  christos rtsd_immediate (expressionS exp)
   1785      1.1  christos {
   1786      1.1  christos   int val;
   1787      1.1  christos 
   1788      1.1  christos   if (exp.X_op != O_constant)
   1789      1.1  christos     {
   1790      1.1  christos       rx_error (_("rtsd size must be constant"));
   1791      1.1  christos       return;
   1792      1.1  christos     }
   1793      1.1  christos   val = exp.X_add_number;
   1794      1.1  christos   if (val & 3)
   1795      1.1  christos     rx_error (_("rtsd size must be multiple of 4"));
   1796      1.1  christos 
   1797      1.1  christos   if (val < 0 || val > 1020)
   1798      1.1  christos     rx_error (_("rtsd size must be 0..1020"));
   1799      1.1  christos 
   1800      1.1  christos   val >>= 2;
   1801      1.1  christos   exp.X_add_number = val;
   1802      1.1  christos   O1 (exp);
   1803      1.1  christos }
   1804      1.1  christos 
   1805      1.1  christos static void
   1806      1.1  christos rx_range (expressionS exp, int minv, int maxv)
   1807      1.1  christos {
   1808      1.1  christos   int val;
   1809      1.1  christos 
   1810      1.1  christos   if (exp.X_op != O_constant)
   1811      1.1  christos     return;
   1812      1.1  christos 
   1813      1.1  christos   val = exp.X_add_number;
   1814      1.1  christos   if (val < minv || val > maxv)
   1815      1.1  christos     as_warn (_("Value %d out of range %d..%d"), val, minv, maxv);
   1816      1.1  christos }
   1817  1.1.1.2  christos 
   1818  1.1.1.2  christos static void
   1819  1.1.1.2  christos rx_check_float_support (void)
   1820  1.1.1.2  christos {
   1821  1.1.1.2  christos   if (rx_cpu == RX100 || rx_cpu == RX200)
   1822  1.1.1.2  christos     rx_error (_("target CPU type does not support floating point instructions"));
   1823  1.1.1.2  christos }
   1824  1.1.1.3  christos 
   1825  1.1.1.3  christos static void
   1826  1.1.1.3  christos rx_check_v2 (void)
   1827  1.1.1.3  christos {
   1828  1.1.1.3  christos   if (rx_cpu < RXV2)
   1829  1.1.1.3  christos     rx_error (_("target CPU type does not support v2 instructions"));
   1830  1.1.1.3  christos }
   1831