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