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