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