]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/rl78-parse.y
[bfd]
[thirdparty/binutils-gdb.git] / gas / config / rl78-parse.y
1 /* rl78-parse.y Renesas RL78 parser
2 Copyright 2011
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 "rl78-defs.h"
26
27 static int rl78_lex (void);
28
29 /* Ok, here are the rules for using these macros...
30
31 B*() is used to specify the base opcode bytes. Fields to be filled
32 in later, leave zero. Call this first.
33
34 F() and FE() are used to fill in fields within the base opcode bytes. You MUST
35 call B*() before any F() or FE().
36
37 [UN]*O*(), PC*() appends operands to the end of the opcode. You
38 must call P() and B*() before any of these, so that the fixups
39 have the right byte location.
40 O = signed, UO = unsigned, NO = negated, PC = pcrel
41
42 IMM() adds an immediate and fills in the field for it.
43 NIMM() same, but negates the immediate.
44 NBIMM() same, but negates the immediate, for sbb.
45 DSP() adds a displacement, and fills in the field for it.
46
47 Note that order is significant for the O, IMM, and DSP macros, as
48 they append their data to the operand buffer in the order that you
49 call them.
50
51 Use "disp" for displacements whenever possible; this handles the
52 "0" case properly. */
53
54 #define B1(b1) rl78_base1 (b1)
55 #define B2(b1, b2) rl78_base2 (b1, b2)
56 #define B3(b1, b2, b3) rl78_base3 (b1, b2, b3)
57 #define B4(b1, b2, b3, b4) rl78_base4 (b1, b2, b3, b4)
58
59 /* POS is bits from the MSB of the first byte to the LSB of the last byte. */
60 #define F(val,pos,sz) rl78_field (val, pos, sz)
61 #define FE(exp,pos,sz) rl78_field (exp_val (exp), pos, sz);
62
63 #define O1(v) rl78_op (v, 1, RL78REL_DATA)
64 #define O2(v) rl78_op (v, 2, RL78REL_DATA)
65 #define O3(v) rl78_op (v, 3, RL78REL_DATA)
66 #define O4(v) rl78_op (v, 4, RL78REL_DATA)
67
68 #define PC1(v) rl78_op (v, 1, RL78REL_PCREL)
69 #define PC2(v) rl78_op (v, 2, RL78REL_PCREL)
70 #define PC3(v) rl78_op (v, 3, RL78REL_PCREL)
71
72 #define IMM(v,pos) F (immediate (v, RL78REL_SIGNED, pos), pos, 2); \
73 if (v.X_op != O_constant && v.X_op != O_big) rl78_linkrelax_imm (pos)
74 #define NIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE, pos), pos, 2)
75 #define NBIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE_BORROW, pos), pos, 2)
76 #define DSP(v,pos,msz) if (!v.X_md) rl78_relax (RL78_RELAX_DISP, pos); \
77 else rl78_linkrelax_dsp (pos); \
78 F (displacement (v, msz), pos, 2)
79
80 #define id24(a,b2,b3) B3 (0xfb+a, b2, b3)
81
82 static int expr_is_sfr (expressionS);
83 static int expr_is_saddr (expressionS);
84 static int expr_is_word_aligned (expressionS);
85 static int exp_val (expressionS exp);
86
87 static int need_flag = 0;
88 static int rl78_in_brackets = 0;
89 static int rl78_last_token = 0;
90 static char * rl78_init_start;
91 static char * rl78_last_exp_start = 0;
92 static int rl78_bit_insn = 0;
93
94 #define YYDEBUG 1
95 #define YYERROR_VERBOSE 1
96
97 #define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F")
98 #define SA(e) if (!expr_is_saddr (e)) NOT_SADDR;
99
100 #define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF")
101 #define SFR(e) if (!expr_is_sfr (e)) NOT_SFR;
102
103 #define NOT_SFR_OR_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFFFF")
104
105 #define NOT_ES if (rl78_has_prefix()) rl78_error ("ES: prefix not allowed here");
106
107 #define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
108
109 static void check_expr_is_bit_index (expressionS);
110 #define Bit(e) check_expr_is_bit_index (e);
111
112 /* Returns TRUE (non-zero) if the expression is a constant in the
113 given range. */
114 static int check_expr_is_const (expressionS, int vmin, int vmax);
115
116 /* Convert a "regb" value to a "reg_xbc" value. Error if other
117 registers are passed. Needed to avoid reduce-reduce conflicts. */
118 static int
119 reg_xbc (int reg)
120 {
121 switch (reg)
122 {
123 case 0: /* X */
124 return 0x10;
125 case 3: /* B */
126 return 0x20;
127 case 2: /* C */
128 return 0x30;
129 default:
130 rl78_error ("Only X, B, or C allowed here");
131 return 0;
132 }
133 }
134
135 %}
136
137 %name-prefix="rl78_"
138
139 %union {
140 int regno;
141 expressionS exp;
142 }
143
144 %type <regno> regb regb_na regw regw_na FLAG sfr
145 %type <regno> A X B C D E H L AX BC DE HL
146 %type <exp> EXPR
147
148 %type <regno> addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw
149 %type <regno> incdec incdecw
150
151 %token A X B C D E H L AX BC DE HL
152 %token SPL SPH PSW CS ES PMC MEM
153 %token FLAG SP CY
154 %token RB0 RB1 RB2 RB3
155
156 %token EXPR UNKNOWN_OPCODE IS_OPCODE
157
158 %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
159
160 %token ADD ADDC ADDW AND_ AND1
161 /* BC is also a register pair */
162 %token BF BH BNC BNH BNZ BR BRK BRK1 BT BTCLR BZ
163 %token CALL CALLT CLR1 CLRB CLRW CMP CMP0 CMPS CMPW
164 %token DEC DECW DI DIVHU DIVWU
165 %token EI
166 %token HALT
167 %token INC INCW
168 %token MACH MACHU MOV MOV1 MOVS MOVW MULH MULHU MULU
169 %token NOP
170 %token ONEB ONEW OR OR1
171 %token POP PUSH
172 %token RET RETI RETB ROL ROLC ROLWC ROR RORC
173 %token SAR SARW SEL SET1 SHL SHLW SHR SHRW
174 %token SKC SKH SKNC SKNH SKNZ SKZ STOP SUB SUBC SUBW
175 %token XCH XCHW XOR XOR1
176
177 %%
178 /* ====================================================================== */
179
180 statement :
181
182 UNKNOWN_OPCODE
183 { as_bad (_("Unknown opcode: %s"), rl78_init_start); }
184
185 /* The opcodes are listed in approximately alphabetical order. */
186
187 /* For reference:
188
189 sfr = special function register - symbol, 0xFFF00 to 0xFFFFF
190 sfrp = special function register - symbol, 0xFFF00 to 0xFFFFE, even only
191 saddr = 0xFFE20 to 0xFFF1F
192 saddrp = 0xFFE20 to 0xFFF1E, even only
193
194 addr20 = 0x00000 to 0xFFFFF
195 addr16 = 0x00000 to 0x0FFFF, even only for 16-bit ops
196 addr5 = 0x00000 to 0x000BE, even only
197 */
198
199 /* ---------------------------------------------------------------------- */
200
201 /* addsub is ADD, ADDC, SUB, SUBC, AND, OR, XOR, and parts of CMP. */
202
203 | addsub A ',' '#' EXPR
204 { B1 (0x0c|$1); O1 ($5); }
205
206 | addsub EXPR {SA($2)} ',' '#' EXPR
207 { B1 (0x0a|$1); O1 ($2); O1 ($6); }
208
209 | addsub A ',' A
210 { B2 (0x61, 0x01|$1); }
211
212 | addsub A ',' regb_na
213 { B2 (0x61, 0x08|$1); F ($4, 13, 3); }
214
215 | addsub regb_na ',' A
216 { B2 (0x61, 0x00|$1); F ($2, 13, 3); }
217
218 | addsub A ',' EXPR {SA($4)}
219 { B1 (0x0b|$1); O1 ($4); }
220
221 | addsub A ',' opt_es '!' EXPR
222 { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
223
224 | addsub A ',' opt_es '[' HL ']'
225 { B1 (0x0d|$1); }
226
227 | addsub A ',' opt_es '[' HL '+' EXPR ']'
228 { B1 (0x0e|$1); O1 ($8); }
229
230 | addsub A ',' opt_es '[' HL '+' B ']'
231 { B2 (0x61, 0x80|$1); }
232
233 | addsub A ',' opt_es '[' HL '+' C ']'
234 { B2 (0x61, 0x82|$1); }
235
236
237
238 | addsub opt_es '!' EXPR ',' '#' EXPR
239 { if ($1 != 0x40)
240 { rl78_error ("Only CMP takes these operands"); }
241 else
242 { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
243 }
244
245 /* ---------------------------------------------------------------------- */
246
247 | addsubw AX ',' '#' EXPR
248 { B1 (0x04|$1); O2 ($5); }
249
250 | addsubw AX ',' regw
251 { B1 (0x01|$1); F ($4, 5, 2); }
252
253 | addsubw AX ',' EXPR {SA($4)}
254 { B1 (0x06|$1); O1 ($4); }
255
256 | addsubw AX ',' opt_es '!' EXPR
257 { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
258
259 | addsubw AX ',' opt_es '[' HL '+' EXPR ']'
260 { B2 (0x61, 0x09|$1); O1 ($8); }
261
262 | addsubw AX ',' opt_es '[' HL ']'
263 { B4 (0x61, 0x09|$1, 0, 0); }
264
265 | addsubw SP ',' '#' EXPR
266 { B1 ($1 ? 0x20 : 0x10); O1 ($5);
267 if ($1 == 0x40)
268 rl78_error ("CMPW SP,#imm not allowed");
269 }
270
271 /* ---------------------------------------------------------------------- */
272
273 | andor1 CY ',' sfr '.' EXPR {Bit($6)}
274 { B3 (0x71, 0x08|$1, $4); FE ($6, 9, 3); }
275
276 | andor1 CY ',' EXPR '.' EXPR {Bit($6)}
277 { if (expr_is_sfr ($4))
278 { B2 (0x71, 0x08|$1); FE ($6, 9, 3); O1 ($4); }
279 else if (expr_is_saddr ($4))
280 { B2 (0x71, 0x00|$1); FE ($6, 9, 3); O1 ($4); }
281 else
282 NOT_SFR_OR_SADDR;
283 }
284
285 | andor1 CY ',' A '.' EXPR {Bit($6)}
286 { B2 (0x71, 0x88|$1); FE ($6, 9, 3); }
287
288 | andor1 CY ',' opt_es '[' HL ']' '.' EXPR {Bit($9)}
289 { B2 (0x71, 0x80|$1); FE ($9, 9, 3); }
290
291 /* ---------------------------------------------------------------------- */
292
293 | BC '$' EXPR
294 { B1 (0xdc); PC1 ($3); }
295
296 | BNC '$' EXPR
297 { B1 (0xde); PC1 ($3); }
298
299 | BZ '$' EXPR
300 { B1 (0xdd); PC1 ($3); }
301
302 | BNZ '$' EXPR
303 { B1 (0xdf); PC1 ($3); }
304
305 | BH '$' EXPR
306 { B2 (0x61, 0xc3); PC1 ($3); }
307
308 | BNH '$' EXPR
309 { B2 (0x61, 0xd3); PC1 ($3); }
310
311 /* ---------------------------------------------------------------------- */
312
313 | bt_bf sfr '.' EXPR ',' '$' EXPR
314 { B3 (0x31, 0x80|$1, $2); FE ($4, 9, 3); PC1 ($7); }
315
316 | bt_bf EXPR '.' EXPR ',' '$' EXPR
317 { if (expr_is_sfr ($2))
318 { B2 (0x31, 0x80|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
319 else if (expr_is_saddr ($2))
320 { B2 (0x31, 0x00|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
321 else
322 NOT_SFR_OR_SADDR;
323 }
324
325 | bt_bf A '.' EXPR ',' '$' EXPR
326 { B2 (0x31, 0x01|$1); FE ($4, 9, 3); PC1 ($7); }
327
328 | bt_bf opt_es '[' HL ']' '.' EXPR ',' '$' EXPR
329 { B2 (0x31, 0x81|$1); FE ($7, 9, 3); PC1 ($10); }
330
331 /* ---------------------------------------------------------------------- */
332
333 | BR AX
334 { B2 (0x61, 0xcb); }
335
336 | BR '$' EXPR
337 { B1 (0xef); PC1 ($3); }
338
339 | BR '$' '!' EXPR
340 { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
341
342 | BR '!' EXPR
343 { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
344
345 | BR '!' '!' EXPR
346 { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
347
348 /* ---------------------------------------------------------------------- */
349
350 | BRK
351 { B2 (0x61, 0xcc); }
352
353 | BRK1
354 { B1 (0xff); }
355
356 /* ---------------------------------------------------------------------- */
357
358 | CALL regw
359 { B2 (0x61, 0xca); F ($2, 10, 2); }
360
361 | CALL '$' '!' EXPR
362 { B1 (0xfe); PC2 ($4); }
363
364 | CALL '!' EXPR
365 { B1 (0xfd); O2 ($3); }
366
367 | CALL '!' '!' EXPR
368 { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
369
370 | CALLT '[' EXPR ']'
371 { if ($3.X_op != O_constant)
372 rl78_error ("CALLT requires a numeric address");
373 else
374 {
375 int i = $3.X_add_number;
376 if (i < 0x80 || i > 0xbe)
377 rl78_error ("CALLT address not 0x80..0xbe");
378 else if (i & 1)
379 rl78_error ("CALLT address not even");
380 else
381 {
382 B2 (0x61, 0x84);
383 F ((i >> 1) & 7, 9, 3);
384 F ((i >> 4) & 7, 14, 2);
385 }
386 }
387 }
388
389 /* ---------------------------------------------------------------------- */
390
391 | setclr1 CY
392 { B2 (0x71, $1 ? 0x88 : 0x80); }
393
394 | setclr1 sfr '.' EXPR
395 { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); }
396
397 | setclr1 EXPR '.' EXPR
398 { if (expr_is_sfr ($2))
399 { B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); }
400 else if (expr_is_saddr ($2))
401 { B2 (0x71, 0x02|$1); FE ($4, 9, 3); O1 ($2); }
402 else
403 NOT_SFR_OR_SADDR;
404 }
405
406 | setclr1 A '.' EXPR
407 { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
408
409 | setclr1 opt_es '!' EXPR '.' EXPR
410 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
411
412 | setclr1 opt_es '[' HL ']' '.' EXPR
413 { B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
414
415 /* ---------------------------------------------------------------------- */
416
417 | oneclrb A
418 { B1 (0xe1|$1); }
419 | oneclrb X
420 { B1 (0xe0|$1); }
421 | oneclrb B
422 { B1 (0xe3|$1); }
423 | oneclrb C
424 { B1 (0xe2|$1); }
425
426 | oneclrb EXPR {SA($2)}
427 { B1 (0xe4|$1); O1 ($2); }
428
429 | oneclrb opt_es '!' EXPR
430 { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
431
432 /* ---------------------------------------------------------------------- */
433
434 | oneclrw AX
435 { B1 (0xe6|$1); }
436 | oneclrw BC
437 { B1 (0xe7|$1); }
438
439 /* ---------------------------------------------------------------------- */
440
441 | CMP0 A
442 { B1 (0xd1); }
443
444 | CMP0 X
445 { B1 (0xd0); }
446
447 | CMP0 B
448 { B1 (0xd3); }
449
450 | CMP0 C
451 { B1 (0xd2); }
452
453 | CMP0 EXPR {SA($2)}
454 { B1 (0xd4); O1 ($2); }
455
456 | CMP0 opt_es '!' EXPR
457 { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
458
459 /* ---------------------------------------------------------------------- */
460
461 | CMPS X ',' opt_es '[' HL '+' EXPR ']'
462 { B2 (0x61, 0xde); O1 ($8); }
463
464 /* ---------------------------------------------------------------------- */
465
466 | incdec regb
467 { B1 (0x80|$1); F ($2, 5, 3); }
468
469 | incdec EXPR {SA($2)}
470 { B1 (0xa4|$1); O1 ($2); }
471 | incdec '!' EXPR
472 { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
473 | incdec ES ':' '!' EXPR
474 { B2 (0x11, 0xa0|$1); O2 ($5); }
475 | incdec '[' HL '+' EXPR ']'
476 { B2 (0x61, 0x59+$1); O1 ($5); }
477 | incdec ES ':' '[' HL '+' EXPR ']'
478 { B3 (0x11, 0x61, 0x59+$1); O1 ($7); }
479
480 /* ---------------------------------------------------------------------- */
481
482 | incdecw regw
483 { B1 (0xa1|$1); F ($2, 5, 2); }
484
485 | incdecw EXPR {SA($2)}
486 { B1 (0xa6|$1); O1 ($2); }
487
488 | incdecw opt_es '!' EXPR
489 { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
490
491 | incdecw opt_es '[' HL '+' EXPR ']'
492 { B2 (0x61, 0x79+$1); O1 ($6); }
493
494 /* ---------------------------------------------------------------------- */
495
496 | DI
497 { B3 (0x71, 0x7b, 0xfa); }
498
499 | EI
500 { B3 (0x71, 0x7a, 0xfa); }
501
502 /* ---------------------------------------------------------------------- */
503
504 | MULHU
505 { B3 (0xce, 0xfb, 0x01); }
506
507 | MULH
508 { B3 (0xce, 0xfb, 0x02); }
509
510 | MULU X
511 { B1 (0xd6); }
512
513 | DIVHU
514 { B3 (0xce, 0xfb, 0x03); }
515
516 | DIVWU
517 { B3 (0xce, 0xfb, 0x04); }
518
519 | MACHU
520 { B3 (0xce, 0xfb, 0x05); }
521
522 | MACH
523 { B3 (0xce, 0xfb, 0x06); }
524
525 /* ---------------------------------------------------------------------- */
526
527 | HALT
528 { B2 (0x61, 0xed); }
529
530 /* ---------------------------------------------------------------------- */
531 /* Note that opt_es is included even when it's not an option, to avoid
532 shift/reduce conflicts. The NOT_ES macro produces an error if ES:
533 is given by the user. */
534
535 | MOV A ',' '#' EXPR
536 { B1 (0x51); O1 ($5); }
537 | MOV regb_na ',' '#' EXPR
538 { B1 (0x50); F($2, 5, 3); O1 ($5); }
539
540 | MOV sfr ',' '#' EXPR
541 { if ($2 != 0xfd)
542 { B2 (0xce, $2); O1 ($5); }
543 else
544 { B1 (0x41); O1 ($5); }
545 }
546
547 | MOV opt_es EXPR ',' '#' EXPR {NOT_ES}
548 { if (expr_is_sfr ($3))
549 { B1 (0xce); O1 ($3); O1 ($6); }
550 else if (expr_is_saddr ($3))
551 { B1 (0xcd); O1 ($3); O1 ($6); }
552 else
553 NOT_SFR_OR_SADDR;
554 }
555
556 | MOV '!' EXPR ',' '#' EXPR
557 { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
558
559 | MOV ES ':' '!' EXPR ',' '#' EXPR
560 { B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
561
562 | MOV regb_na ',' A
563 { B1 (0x70); F ($2, 5, 3); }
564
565 | MOV A ',' regb_na
566 { B1 (0x60); F ($4, 5, 3); }
567
568 | MOV opt_es EXPR ',' A {NOT_ES}
569 { if (expr_is_sfr ($3))
570 { B1 (0x9e); O1 ($3); }
571 else if (expr_is_saddr ($3))
572 { B1 (0x9d); O1 ($3); }
573 else
574 NOT_SFR_OR_SADDR;
575 }
576
577 | MOV A ',' opt_es '!' EXPR
578 { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
579
580 | MOV '!' EXPR ',' A
581 { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
582
583 | MOV ES ':' '!' EXPR ',' A
584 { B2 (0x11, 0x9f); O2 ($5); }
585
586 | MOV regb_na ',' opt_es '!' EXPR
587 { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
588
589 | MOV A ',' opt_es EXPR {NOT_ES}
590 { if (expr_is_saddr ($5))
591 { B1 (0x8d); O1 ($5); }
592 else if (expr_is_sfr ($5))
593 { B1 (0x8e); O1 ($5); }
594 else
595 NOT_SFR_OR_SADDR;
596 }
597
598 | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
599 { B1 (0xc8|reg_xbc($2)); O1 ($5); }
600
601 | MOV A ',' sfr
602 { B2 (0x8e, $4); }
603
604 | MOV sfr ',' regb
605 { if ($4 != 1)
606 rl78_error ("Only A allowed here");
607 else
608 { B2 (0x9e, $2); }
609 }
610
611 | MOV sfr ',' opt_es EXPR {SA($5)} {NOT_ES}
612 { if ($2 != 0xfd)
613 rl78_error ("Only ES allowed here");
614 else
615 { B2 (0x61, 0xb8); O1 ($5); }
616 }
617
618 | MOV A ',' opt_es '[' DE ']'
619 { B1 (0x89); }
620
621 | MOV opt_es '[' DE ']' ',' A
622 { B1 (0x99); }
623
624 | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR
625 { B1 (0xca); O1 ($6); O1 ($10); }
626
627 | MOV A ',' opt_es '[' DE '+' EXPR ']'
628 { B1 (0x8a); O1 ($8); }
629
630 | MOV opt_es '[' DE '+' EXPR ']' ',' A
631 { B1 (0x9a); O1 ($6); }
632
633 | MOV A ',' opt_es '[' HL ']'
634 { B1 (0x8b); }
635
636 | MOV opt_es '[' HL ']' ',' A
637 { B1 (0x9b); }
638
639 | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR
640 { B1 (0xcc); O1 ($6); O1 ($10); }
641
642 | MOV A ',' opt_es '[' HL '+' EXPR ']'
643 { B1 (0x8c); O1 ($8); }
644
645 | MOV opt_es '[' HL '+' EXPR ']' ',' A
646 { B1 (0x9c); O1 ($6); }
647
648 | MOV A ',' opt_es '[' HL '+' B ']'
649 { B2 (0x61, 0xc9); }
650
651 | MOV opt_es '[' HL '+' B ']' ',' A
652 { B2 (0x61, 0xd9); }
653
654 | MOV A ',' opt_es '[' HL '+' C ']'
655 { B2 (0x61, 0xe9); }
656
657 | MOV opt_es '[' HL '+' C ']' ',' A
658 { B2 (0x61, 0xf9); }
659
660 | MOV opt_es EXPR '[' B ']' ',' '#' EXPR
661 { B1 (0x19); O2 ($3); O1 ($9); }
662
663 | MOV A ',' opt_es EXPR '[' B ']'
664 { B1 (0x09); O2 ($5); }
665
666 | MOV opt_es EXPR '[' B ']' ',' A
667 { B1 (0x18); O2 ($3); }
668
669 | MOV opt_es EXPR '[' C ']' ',' '#' EXPR
670 { B1 (0x38); O2 ($3); O1 ($9); }
671
672 | MOV A ',' opt_es EXPR '[' C ']'
673 { B1 (0x29); O2 ($5); }
674
675 | MOV opt_es EXPR '[' C ']' ',' A
676 { B1 (0x28); O2 ($3); }
677
678 | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR
679 { B1 (0x39); O2 ($3); O1 ($9); }
680
681 | MOV opt_es '[' BC ']' ',' '#' EXPR
682 { B3 (0x39, 0, 0); O1 ($8); }
683
684 | MOV A ',' opt_es EXPR '[' BC ']'
685 { B1 (0x49); O2 ($5); }
686
687 | MOV A ',' opt_es '[' BC ']'
688 { B3 (0x49, 0, 0); }
689
690 | MOV opt_es EXPR '[' BC ']' ',' A
691 { B1 (0x48); O2 ($3); }
692
693 | MOV opt_es '[' BC ']' ',' A
694 { B3 (0x48, 0, 0); }
695
696 | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES}
697 { B1 (0xc8); O1 ($6); O1 ($10); }
698
699 | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES}
700 { B2 (0xc8, 0); O1 ($8); }
701
702 | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
703 { B1 (0x88); O1 ($8); }
704
705 | MOV A ',' opt_es '[' SP ']' {NOT_ES}
706 { B2 (0x88, 0); }
707
708 | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES}
709 { B1 (0x98); O1 ($6); }
710
711 | MOV opt_es '[' SP ']' ',' A {NOT_ES}
712 { B2 (0x98, 0); }
713
714 /* ---------------------------------------------------------------------- */
715
716 | mov1 CY ',' EXPR '.' EXPR
717 { if (expr_is_saddr ($4))
718 { B2 (0x71, 0x04); FE ($6, 9, 3); O1 ($4); }
719 else if (expr_is_sfr ($4))
720 { B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); }
721 else
722 NOT_SFR_OR_SADDR;
723 }
724
725 | mov1 CY ',' A '.' EXPR
726 { B2 (0x71, 0x8c); FE ($6, 9, 3); }
727
728 | mov1 CY ',' sfr '.' EXPR
729 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
730
731 | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
732 { B2 (0x71, 0x84); FE ($9, 9, 3); }
733
734 | mov1 EXPR '.' EXPR ',' CY
735 { if (expr_is_saddr ($2))
736 { B2 (0x71, 0x01); FE ($4, 9, 3); O1 ($2); }
737 else if (expr_is_sfr ($2))
738 { B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); }
739 else
740 NOT_SFR_OR_SADDR;
741 }
742
743 | mov1 A '.' EXPR ',' CY
744 { B2 (0x71, 0x89); FE ($4, 9, 3); }
745
746 | mov1 sfr '.' EXPR ',' CY
747 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
748
749 | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
750 { B2 (0x71, 0x81); FE ($7, 9, 3); }
751
752 /* ---------------------------------------------------------------------- */
753
754 | MOVS opt_es '[' HL '+' EXPR ']' ',' X
755 { B2 (0x61, 0xce); O1 ($6); }
756
757 /* ---------------------------------------------------------------------- */
758
759 | MOVW AX ',' '#' EXPR
760 { B1 (0x30); O2 ($5); }
761
762 | MOVW regw_na ',' '#' EXPR
763 { B1 (0x30); F ($2, 5, 2); O2 ($5); }
764
765 | MOVW opt_es EXPR ',' '#' EXPR {NOT_ES}
766 { if (expr_is_saddr ($3))
767 { B1 (0xc9); O1 ($3); O2 ($6); }
768 else if (expr_is_sfr ($3))
769 { B1 (0xcb); O1 ($3); O2 ($6); }
770 else
771 NOT_SFR_OR_SADDR;
772 }
773
774 | MOVW AX ',' opt_es EXPR {NOT_ES}
775 { if (expr_is_saddr ($5))
776 { B1 (0xad); O1 ($5); WA($5); }
777 else if (expr_is_sfr ($5))
778 { B1 (0xae); O1 ($5); WA($5); }
779 else
780 NOT_SFR_OR_SADDR;
781 }
782
783 | MOVW opt_es EXPR ',' AX {NOT_ES}
784 { if (expr_is_saddr ($3))
785 { B1 (0xbd); O1 ($3); WA($3); }
786 else if (expr_is_sfr ($3))
787 { B1 (0xbe); O1 ($3); WA($3); }
788 else
789 NOT_SFR_OR_SADDR;
790 }
791
792 | MOVW AX ',' regw_na
793 { B1 (0x11); F ($4, 5, 2); }
794
795 | MOVW regw_na ',' AX
796 { B1 (0x10); F ($2, 5, 2); }
797
798 | MOVW AX ',' opt_es '!' EXPR
799 { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
800
801 | MOVW opt_es '!' EXPR ',' AX
802 { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
803
804 | MOVW AX ',' opt_es '[' DE ']'
805 { B1 (0xa9); }
806
807 | MOVW opt_es '[' DE ']' ',' AX
808 { B1 (0xb9); }
809
810 | MOVW AX ',' opt_es '[' DE '+' EXPR ']'
811 { B1 (0xaa); O1 ($8); }
812
813 | MOVW opt_es '[' DE '+' EXPR ']' ',' AX
814 { B1 (0xba); O1 ($6); }
815
816 | MOVW AX ',' opt_es '[' HL ']'
817 { B1 (0xab); }
818
819 | MOVW opt_es '[' HL ']' ',' AX
820 { B1 (0xbb); }
821
822 | MOVW AX ',' opt_es '[' HL '+' EXPR ']'
823 { B1 (0xac); O1 ($8); }
824
825 | MOVW opt_es '[' HL '+' EXPR ']' ',' AX
826 { B1 (0xbc); O1 ($6); }
827
828 | MOVW AX ',' opt_es EXPR '[' B ']'
829 { B1 (0x59); O2 ($5); }
830
831 | MOVW opt_es EXPR '[' B ']' ',' AX
832 { B1 (0x58); O2 ($3); }
833
834 | MOVW AX ',' opt_es EXPR '[' C ']'
835 { B1 (0x69); O2 ($5); }
836
837 | MOVW opt_es EXPR '[' C ']' ',' AX
838 { B1 (0x68); O2 ($3); }
839
840 | MOVW AX ',' opt_es EXPR '[' BC ']'
841 { B1 (0x79); O2 ($5); }
842
843 | MOVW AX ',' opt_es '[' BC ']'
844 { B3 (0x79, 0, 0); }
845
846 | MOVW opt_es EXPR '[' BC ']' ',' AX
847 { B1 (0x78); O2 ($3); }
848
849 | MOVW opt_es '[' BC ']' ',' AX
850 { B3 (0x78, 0, 0); }
851
852 | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
853 { B1 (0xa8); O1 ($8); WA($8);}
854
855 | MOVW AX ',' opt_es '[' SP ']' {NOT_ES}
856 { B2 (0xa8, 0); }
857
858 | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES}
859 { B1 (0xb8); O1 ($6); WA($6); }
860
861 | MOVW opt_es '[' SP ']' ',' AX {NOT_ES}
862 { B2 (0xb8, 0); }
863
864 | MOVW regw_na ',' EXPR {SA($4)}
865 { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); }
866
867 | MOVW regw_na ',' opt_es '!' EXPR
868 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
869
870 | MOVW SP ',' '#' EXPR
871 { B2 (0xcb, 0xf8); O2 ($5); }
872
873 | MOVW SP ',' AX
874 { B2 (0xbe, 0xf8); }
875
876 | MOVW AX ',' SP
877 { B2 (0xae, 0xf8); }
878
879 | MOVW regw_na ',' SP
880 { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); }
881
882 /* ---------------------------------------------------------------------- */
883
884 | NOP
885 { B1 (0x00); }
886
887 /* ---------------------------------------------------------------------- */
888
889 | POP regw
890 { B1 (0xc0); F ($2, 5, 2); }
891
892 | POP PSW
893 { B2 (0x61, 0xcd); };
894
895 | PUSH regw
896 { B1 (0xc1); F ($2, 5, 2); }
897
898 | PUSH PSW
899 { B2 (0x61, 0xdd); };
900
901 /* ---------------------------------------------------------------------- */
902
903 | RET
904 { B1 (0xd7); }
905
906 | RETI
907 { B2 (0x61, 0xfc); }
908
909 | RETB
910 { B2 (0x61, 0xec); }
911
912 /* ---------------------------------------------------------------------- */
913
914 | ROL A ',' EXPR
915 { if (check_expr_is_const ($4, 1, 1))
916 { B2 (0x61, 0xeb); }
917 }
918
919 | ROLC A ',' EXPR
920 { if (check_expr_is_const ($4, 1, 1))
921 { B2 (0x61, 0xdc); }
922 }
923
924 | ROLWC AX ',' EXPR
925 { if (check_expr_is_const ($4, 1, 1))
926 { B2 (0x61, 0xee); }
927 }
928
929 | ROLWC BC ',' EXPR
930 { if (check_expr_is_const ($4, 1, 1))
931 { B2 (0x61, 0xfe); }
932 }
933
934 | ROR A ',' EXPR
935 { if (check_expr_is_const ($4, 1, 1))
936 { B2 (0x61, 0xdb); }
937 }
938
939 | RORC A ',' EXPR
940 { if (check_expr_is_const ($4, 1, 1))
941 { B2 (0x61, 0xfb);}
942 }
943
944 /* ---------------------------------------------------------------------- */
945
946 | SAR A ',' EXPR
947 { if (check_expr_is_const ($4, 1, 7))
948 { B2 (0x31, 0x0b); FE ($4, 9, 3); }
949 }
950
951 | SARW AX ',' EXPR
952 { if (check_expr_is_const ($4, 1, 15))
953 { B2 (0x31, 0x0f); FE ($4, 8, 4); }
954 }
955
956 /* ---------------------------------------------------------------------- */
957
958 | SEL RB0
959 { B2 (0x61, 0xcf); }
960
961 | SEL RB1
962 { B2 (0x61, 0xdf); }
963
964 | SEL RB2
965 { B2 (0x61, 0xef); }
966
967 | SEL RB3
968 { B2 (0x61, 0xff); }
969
970 /* ---------------------------------------------------------------------- */
971
972 | SHL A ',' EXPR
973 { if (check_expr_is_const ($4, 1, 7))
974 { B2 (0x31, 0x09); FE ($4, 9, 3); }
975 }
976
977 | SHL B ',' EXPR
978 { if (check_expr_is_const ($4, 1, 7))
979 { B2 (0x31, 0x08); FE ($4, 9, 3); }
980 }
981
982 | SHL C ',' EXPR
983 { if (check_expr_is_const ($4, 1, 7))
984 { B2 (0x31, 0x07); FE ($4, 9, 3); }
985 }
986
987 | SHLW AX ',' EXPR
988 { if (check_expr_is_const ($4, 1, 15))
989 { B2 (0x31, 0x0d); FE ($4, 8, 4); }
990 }
991
992 | SHLW BC ',' EXPR
993 { if (check_expr_is_const ($4, 1, 15))
994 { B2 (0x31, 0x0c); FE ($4, 8, 4); }
995 }
996
997 /* ---------------------------------------------------------------------- */
998
999 | SHR A ',' EXPR
1000 { if (check_expr_is_const ($4, 1, 7))
1001 { B2 (0x31, 0x0a); FE ($4, 9, 3); }
1002 }
1003
1004 | SHRW AX ',' EXPR
1005 { if (check_expr_is_const ($4, 1, 15))
1006 { B2 (0x31, 0x0e); FE ($4, 8, 4); }
1007 }
1008
1009 /* ---------------------------------------------------------------------- */
1010
1011 | SKC
1012 { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
1013
1014 | SKH
1015 { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
1016
1017 | SKNC
1018 { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
1019
1020 | SKNH
1021 { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
1022
1023 | SKNZ
1024 { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
1025
1026 | SKZ
1027 { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
1028
1029 /* ---------------------------------------------------------------------- */
1030
1031 | STOP
1032 { B2 (0x61, 0xfd); }
1033
1034 /* ---------------------------------------------------------------------- */
1035
1036 | XCH A ',' regb_na
1037 { if ($4 == 0) /* X */
1038 { B1 (0x08); }
1039 else
1040 { B2 (0x61, 0x88); F ($4, 13, 3); }
1041 }
1042
1043 | XCH A ',' opt_es '!' EXPR
1044 { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
1045
1046 | XCH A ',' opt_es '[' DE ']'
1047 { B2 (0x61, 0xae); }
1048
1049 | XCH A ',' opt_es '[' DE '+' EXPR ']'
1050 { B2 (0x61, 0xaf); O1 ($8); }
1051
1052 | XCH A ',' opt_es '[' HL ']'
1053 { B2 (0x61, 0xac); }
1054
1055 | XCH A ',' opt_es '[' HL '+' EXPR ']'
1056 { B2 (0x61, 0xad); O1 ($8); }
1057
1058 | XCH A ',' opt_es '[' HL '+' B ']'
1059 { B2 (0x61, 0xb9); }
1060
1061 | XCH A ',' opt_es '[' HL '+' C ']'
1062 { B2 (0x61, 0xa9); }
1063
1064 | XCH A ',' EXPR
1065 { if (expr_is_sfr ($4))
1066 { B2 (0x61, 0xab); O1 ($4); }
1067 else if (expr_is_saddr ($4))
1068 { B2 (0x61, 0xa8); O1 ($4); }
1069 else
1070 NOT_SFR_OR_SADDR;
1071 }
1072
1073 /* ---------------------------------------------------------------------- */
1074
1075 | XCHW AX ',' regw_na
1076 { B1 (0x31); F ($4, 5, 2); }
1077
1078 /* ---------------------------------------------------------------------- */
1079
1080 ; /* end of statement */
1081
1082 /* ---------------------------------------------------------------------- */
1083
1084 opt_es : /* nothing */
1085 | ES ':'
1086 { rl78_prefix (0x11); }
1087 ;
1088
1089 regb : X { $$ = 0; }
1090 | A { $$ = 1; }
1091 | C { $$ = 2; }
1092 | B { $$ = 3; }
1093 | E { $$ = 4; }
1094 | D { $$ = 5; }
1095 | L { $$ = 6; }
1096 | H { $$ = 7; }
1097 ;
1098
1099 regb_na : X { $$ = 0; }
1100 | C { $$ = 2; }
1101 | B { $$ = 3; }
1102 | E { $$ = 4; }
1103 | D { $$ = 5; }
1104 | L { $$ = 6; }
1105 | H { $$ = 7; }
1106 ;
1107
1108 regw : AX { $$ = 0; }
1109 | BC { $$ = 1; }
1110 | DE { $$ = 2; }
1111 | HL { $$ = 3; }
1112 ;
1113
1114 regw_na : BC { $$ = 1; }
1115 | DE { $$ = 2; }
1116 | HL { $$ = 3; }
1117 ;
1118
1119 sfr : SPL { $$ = 0xf8; }
1120 | SPH { $$ = 0xf9; }
1121 | PSW { $$ = 0xfa; }
1122 | CS { $$ = 0xfc; }
1123 | ES { $$ = 0xfd; }
1124 | PMC { $$ = 0xfe; }
1125 | MEM { $$ = 0xff; }
1126 ;
1127
1128 /* ---------------------------------------------------------------------- */
1129 /* Shortcuts for groups of opcodes with common encodings. */
1130
1131 addsub : ADD { $$ = 0x00; }
1132 | ADDC { $$ = 0x10; }
1133 | SUB { $$ = 0x20; }
1134 | SUBC { $$ = 0x30; }
1135 | CMP { $$ = 0x40; }
1136 | AND_ { $$ = 0x50; }
1137 | OR { $$ = 0x60; }
1138 | XOR { $$ = 0x70; }
1139 ;
1140
1141 addsubw : ADDW { $$ = 0x00; }
1142 | SUBW { $$ = 0x20; }
1143 | CMPW { $$ = 0x40; }
1144 ;
1145
1146 andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
1147 | OR1 { $$ = 0x06; rl78_bit_insn = 1;}
1148 | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
1149 ;
1150
1151 bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1;}
1152 | BF { $$ = 0x04; rl78_bit_insn = 1; }
1153 | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
1154 ;
1155
1156 setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
1157 | CLR1 { $$ = 1; rl78_bit_insn = 1; }
1158 ;
1159
1160 oneclrb : ONEB { $$ = 0x00; }
1161 | CLRB { $$ = 0x10; }
1162 ;
1163
1164 oneclrw : ONEW { $$ = 0x00; }
1165 | CLRW { $$ = 0x10; }
1166 ;
1167
1168 incdec : INC { $$ = 0x00; }
1169 | DEC { $$ = 0x10; }
1170 ;
1171
1172 incdecw : INCW { $$ = 0x00; }
1173 | DECW { $$ = 0x10; }
1174 ;
1175
1176 mov1 : MOV1 { rl78_bit_insn = 1; }
1177 ;
1178
1179 %%
1180 /* ====================================================================== */
1181
1182 static struct
1183 {
1184 const char * string;
1185 int token;
1186 int val;
1187 }
1188 token_table[] =
1189 {
1190 { "r0", X, 0 },
1191 { "r1", A, 1 },
1192 { "r2", C, 2 },
1193 { "r3", B, 3 },
1194 { "r4", E, 4 },
1195 { "r5", D, 5 },
1196 { "r6", L, 6 },
1197 { "r7", H, 7 },
1198 { "x", X, 0 },
1199 { "a", A, 1 },
1200 { "c", C, 2 },
1201 { "b", B, 3 },
1202 { "e", E, 4 },
1203 { "d", D, 5 },
1204 { "l", L, 6 },
1205 { "h", H, 7 },
1206
1207 { "rp0", AX, 0 },
1208 { "rp1", BC, 1 },
1209 { "rp2", DE, 2 },
1210 { "rp3", HL, 3 },
1211 { "ax", AX, 0 },
1212 { "bc", BC, 1 },
1213 { "de", DE, 2 },
1214 { "hl", HL, 3 },
1215
1216 { "RB0", RB0, 0 },
1217 { "RB1", RB1, 1 },
1218 { "RB2", RB2, 2 },
1219 { "RB3", RB3, 3 },
1220
1221 { "sp", SP, 0 },
1222 { "cy", CY, 0 },
1223
1224 { "spl", SPL, 0xf8 },
1225 { "sph", SPH, 0xf9 },
1226 { "psw", PSW, 0xfa },
1227 { "cs", CS, 0xfc },
1228 { "es", ES, 0xfd },
1229 { "pmc", PMC, 0xfe },
1230 { "mem", MEM, 0xff },
1231
1232 { ".s", DOT_S, 0 },
1233 { ".b", DOT_B, 0 },
1234 { ".w", DOT_W, 0 },
1235 { ".l", DOT_L, 0 },
1236 { ".a", DOT_A , 0},
1237 { ".ub", DOT_UB, 0 },
1238 { ".uw", DOT_UW , 0},
1239
1240 { "c", FLAG, 0 },
1241 { "z", FLAG, 1 },
1242 { "s", FLAG, 2 },
1243 { "o", FLAG, 3 },
1244 { "i", FLAG, 8 },
1245 { "u", FLAG, 9 },
1246
1247 #define OPC(x) { #x, x, IS_OPCODE }
1248
1249 OPC(ADD),
1250 OPC(ADDC),
1251 OPC(ADDW),
1252 { "and", AND_, IS_OPCODE },
1253 OPC(AND1),
1254 OPC(BC),
1255 OPC(BF),
1256 OPC(BH),
1257 OPC(BNC),
1258 OPC(BNH),
1259 OPC(BNZ),
1260 OPC(BR),
1261 OPC(BRK),
1262 OPC(BRK1),
1263 OPC(BT),
1264 OPC(BTCLR),
1265 OPC(BZ),
1266 OPC(CALL),
1267 OPC(CALLT),
1268 OPC(CLR1),
1269 OPC(CLRB),
1270 OPC(CLRW),
1271 OPC(CMP),
1272 OPC(CMP0),
1273 OPC(CMPS),
1274 OPC(CMPW),
1275 OPC(DEC),
1276 OPC(DECW),
1277 OPC(DI),
1278 OPC(DIVHU),
1279 OPC(DIVWU),
1280 OPC(EI),
1281 OPC(HALT),
1282 OPC(INC),
1283 OPC(INCW),
1284 OPC(MACH),
1285 OPC(MACHU),
1286 OPC(MOV),
1287 OPC(MOV1),
1288 OPC(MOVS),
1289 OPC(MOVW),
1290 OPC(MULH),
1291 OPC(MULHU),
1292 OPC(MULU),
1293 OPC(NOP),
1294 OPC(ONEB),
1295 OPC(ONEW),
1296 OPC(OR),
1297 OPC(OR1),
1298 OPC(POP),
1299 OPC(PUSH),
1300 OPC(RET),
1301 OPC(RETI),
1302 OPC(RETB),
1303 OPC(ROL),
1304 OPC(ROLC),
1305 OPC(ROLWC),
1306 OPC(ROR),
1307 OPC(RORC),
1308 OPC(SAR),
1309 OPC(SARW),
1310 OPC(SEL),
1311 OPC(SET1),
1312 OPC(SHL),
1313 OPC(SHLW),
1314 OPC(SHR),
1315 OPC(SHRW),
1316 OPC(SKC),
1317 OPC(SKH),
1318 OPC(SKNC),
1319 OPC(SKNH),
1320 OPC(SKNZ),
1321 OPC(SKZ),
1322 OPC(STOP),
1323 OPC(SUB),
1324 OPC(SUBC),
1325 OPC(SUBW),
1326 OPC(XCH),
1327 OPC(XCHW),
1328 OPC(XOR),
1329 OPC(XOR1),
1330 };
1331
1332 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1333
1334 void
1335 rl78_lex_init (char * beginning, char * ending)
1336 {
1337 rl78_init_start = beginning;
1338 rl78_lex_start = beginning;
1339 rl78_lex_end = ending;
1340 rl78_in_brackets = 0;
1341 rl78_last_token = 0;
1342
1343 rl78_bit_insn = 0;
1344
1345 setbuf (stdout, 0);
1346 }
1347
1348 /* Return a pointer to the '.' in a bit index expression (like
1349 foo.5), or NULL if none is found. */
1350 static char *
1351 find_bit_index (char *tok)
1352 {
1353 char *last_dot = NULL;
1354 char *last_digit = NULL;
1355 while (*tok && *tok != ',')
1356 {
1357 if (*tok == '.')
1358 {
1359 last_dot = tok;
1360 last_digit = NULL;
1361 }
1362 else if (*tok >= '0' && *tok <= '7'
1363 && last_dot != NULL
1364 && last_digit == NULL)
1365 {
1366 last_digit = tok;
1367 }
1368 else if (ISSPACE (*tok))
1369 {
1370 /* skip */
1371 }
1372 else
1373 {
1374 last_dot = NULL;
1375 last_digit = NULL;
1376 }
1377 tok ++;
1378 }
1379 if (last_dot != NULL
1380 && last_digit != NULL)
1381 return last_dot;
1382 return NULL;
1383 }
1384
1385 static int
1386 rl78_lex (void)
1387 {
1388 /*unsigned int ci;*/
1389 char * save_input_pointer;
1390 char * bit = NULL;
1391
1392 while (ISSPACE (*rl78_lex_start)
1393 && rl78_lex_start != rl78_lex_end)
1394 rl78_lex_start ++;
1395
1396 rl78_last_exp_start = rl78_lex_start;
1397
1398 if (rl78_lex_start == rl78_lex_end)
1399 return 0;
1400
1401 if (ISALPHA (*rl78_lex_start)
1402 || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
1403 {
1404 unsigned int i;
1405 char * e;
1406 char save;
1407
1408 for (e = rl78_lex_start + 1;
1409 e < rl78_lex_end && ISALNUM (*e);
1410 e ++)
1411 ;
1412 save = *e;
1413 *e = 0;
1414
1415 for (i = 0; i < NUM_TOKENS; i++)
1416 if (strcasecmp (rl78_lex_start, token_table[i].string) == 0
1417 && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0)
1418 && !(token_table[i].token == FLAG && !need_flag))
1419 {
1420 rl78_lval.regno = token_table[i].val;
1421 *e = save;
1422 rl78_lex_start = e;
1423 rl78_last_token = token_table[i].token;
1424 return token_table[i].token;
1425 }
1426 *e = save;
1427 }
1428
1429 if (rl78_last_token == 0)
1430 {
1431 rl78_last_token = UNKNOWN_OPCODE;
1432 return UNKNOWN_OPCODE;
1433 }
1434
1435 if (rl78_last_token == UNKNOWN_OPCODE)
1436 return 0;
1437
1438 if (*rl78_lex_start == '[')
1439 rl78_in_brackets = 1;
1440 if (*rl78_lex_start == ']')
1441 rl78_in_brackets = 0;
1442
1443 /* '.' is funny - the syntax includes it for bitfields, but only for
1444 bitfields. We check for it specially so we can allow labels
1445 with '.' in them. */
1446
1447 if (rl78_bit_insn
1448 && *rl78_lex_start == '.'
1449 && find_bit_index (rl78_lex_start) == rl78_lex_start)
1450 {
1451 rl78_last_token = *rl78_lex_start;
1452 return *rl78_lex_start ++;
1453 }
1454
1455 if ((rl78_in_brackets && *rl78_lex_start == '+')
1456 || strchr ("[],#!$:", *rl78_lex_start))
1457 {
1458 rl78_last_token = *rl78_lex_start;
1459 return *rl78_lex_start ++;
1460 }
1461
1462 /* Again, '.' is funny. Look for '.<digit>' at the end of the line
1463 or before a comma, which is a bitfield, not an expression. */
1464
1465 if (rl78_bit_insn)
1466 {
1467 bit = find_bit_index (rl78_lex_start);
1468 if (bit)
1469 *bit = 0;
1470 else
1471 bit = NULL;
1472 }
1473
1474 save_input_pointer = input_line_pointer;
1475 input_line_pointer = rl78_lex_start;
1476 rl78_lval.exp.X_md = 0;
1477 expression (&rl78_lval.exp);
1478
1479 if (bit)
1480 *bit = '.';
1481
1482 rl78_lex_start = input_line_pointer;
1483 input_line_pointer = save_input_pointer;
1484 rl78_last_token = EXPR;
1485 return EXPR;
1486 }
1487
1488 int
1489 rl78_error (const char * str)
1490 {
1491 int len;
1492
1493 len = rl78_last_exp_start - rl78_init_start;
1494
1495 as_bad ("%s", rl78_init_start);
1496 as_bad ("%*s^ %s", len, "", str);
1497 return 0;
1498 }
1499
1500 static int
1501 expr_is_sfr (expressionS exp)
1502 {
1503 unsigned long v;
1504
1505 if (exp.X_op != O_constant)
1506 return 0;
1507
1508 v = exp.X_add_number;
1509 if (0xFFF00 <= v && v <= 0xFFFFF)
1510 return 1;
1511 return 0;
1512 }
1513
1514 static int
1515 expr_is_saddr (expressionS exp)
1516 {
1517 unsigned long v;
1518
1519 if (exp.X_op != O_constant)
1520 return 0;
1521
1522 v = exp.X_add_number;
1523 if (0xFFE20 <= v && v <= 0xFFF1F)
1524 return 1;
1525 return 0;
1526 }
1527
1528 static int
1529 expr_is_word_aligned (expressionS exp)
1530 {
1531 unsigned long v;
1532
1533 if (exp.X_op != O_constant)
1534 return 1;
1535
1536 v = exp.X_add_number;
1537 if (v & 1)
1538 return 0;
1539 return 1;
1540
1541 }
1542
1543 static void
1544 check_expr_is_bit_index (expressionS exp)
1545 {
1546 int val;
1547
1548 if (exp.X_op != O_constant)
1549 {
1550 rl78_error (_("bit index must be a constant"));
1551 return;
1552 }
1553 val = exp.X_add_number;
1554
1555 if (val < 0 || val > 7)
1556 rl78_error (_("rtsd size must be 0..7"));
1557 }
1558
1559 static int
1560 exp_val (expressionS exp)
1561 {
1562 if (exp.X_op != O_constant)
1563 {
1564 rl78_error (_("constant expected"));
1565 return 0;
1566 }
1567 return exp.X_add_number;
1568 }
1569
1570 static int
1571 check_expr_is_const (expressionS e, int vmin, int vmax)
1572 {
1573 static char buf[100];
1574 if (e.X_op != O_constant
1575 || e.X_add_number < vmin
1576 || e.X_add_number > vmax)
1577 {
1578 if (vmin == vmax)
1579 sprintf (buf, "%d expected here", vmin);
1580 else
1581 sprintf (buf, "%d..%d expected here", vmin, vmax);
1582 rl78_error(buf);
1583 return 0;
1584 }
1585 return 1;
1586 }
1587
1588