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