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