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