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