1 /* rl78-parse.y Renesas RL78 parser
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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
24 #include "safe-ctype.h"
25 #include "rl78-defs.h"
27 static int rl78_lex (void);
29 /* Ok, here are the rules for using these macros...
31 B*() is used to specify the base opcode bytes. Fields to be filled
32 in later, leave zero. Call this first.
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().
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
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.
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
51 Use "disp" for displacements whenever possible; this handles the
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)
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);
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)
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)
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)
80 #define id24(a,b2,b3) B3 (0xfb+a, b2, b3)
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);
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;
94 #define YYERROR_VERBOSE 1
96 #define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F")
97 #define SA(e) if (!expr_is_saddr (e)) NOT_SADDR;
99 #define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF")
100 #define SFR(e) if (!expr_is_sfr (e)) NOT_SFR;
102 #define NOT_SFR_OR_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFFFF")
104 #define NOT_ES if (rl78_has_prefix()) rl78_error ("ES: prefix not allowed here");
106 #define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
108 static void check_expr_is_bit_index (expressionS);
109 #define Bit(e) check_expr_is_bit_index (e);
111 /* Returns TRUE (non-zero) if the expression is a constant in the
113 static int check_expr_is_const (expressionS, int vmin, int vmax);
115 /* Convert a "regb" value to a "reg_xbc" value. Error if other
116 registers are passed. Needed to avoid reduce-reduce conflicts. */
129 rl78_error ("Only X, B, or C allowed here");
143 %type <regno> regb regb_na regw regw_na FLAG sfr
144 %type <regno> A X B C D E H L AX BC DE HL
147 %type <regno> addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw
148 %type <regno> incdec incdecw
150 %token A X B C D E H L AX BC DE HL
151 %token SPL SPH PSW CS ES PMC MEM
153 %token RB0 RB1 RB2 RB3
155 %token EXPR UNKNOWN_OPCODE IS_OPCODE
157 %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
159 %token ADD ADDC ADDW AND_ AND1
160 /* BC is also a register pair */
161 %token BF BH BNC BNH BNZ BR BRK BRK1 BT BTCLR BZ
162 %token CALL CALLT CLR1 CLRB CLRW CMP CMP0 CMPS CMPW
163 %token DEC DECW DI DIVHU DIVWU
167 %token MACH MACHU MOV MOV1 MOVS MOVW MULH MULHU MULU
169 %token ONEB ONEW OR OR1
171 %token RET RETI RETB ROL ROLC ROLWC ROR RORC
172 %token SAR SARW SEL SET1 SHL SHLW SHR SHRW
173 %token SKC SKH SKNC SKNH SKNZ SKZ STOP SUB SUBC SUBW
174 %token XCH XCHW XOR XOR1
177 /* ====================================================================== */
182 { as_bad (_("Unknown opcode: %s"), rl78_init_start); }
184 /* The opcodes are listed in approximately alphabetical order. */
188 sfr = special function register - symbol, 0xFFF00 to 0xFFFFF
189 sfrp = special function register - symbol, 0xFFF00 to 0xFFFFE, even only
190 saddr = 0xFFE20 to 0xFFF1F
191 saddrp = 0xFFE20 to 0xFFF1E, even only
193 addr20 = 0x00000 to 0xFFFFF
194 addr16 = 0x00000 to 0x0FFFF, even only for 16-bit ops
195 addr5 = 0x00000 to 0x000BE, even only
198 /* ---------------------------------------------------------------------- */
200 /* addsub is ADD, ADDC, SUB, SUBC, AND, OR, XOR, and parts of CMP. */
202 | addsub A ',' '#' EXPR
203 { B1 (0x0c|$1); O1 ($5); }
205 | addsub EXPR {SA($2)} ',' '#' EXPR
206 { B1 (0x0a|$1); O1 ($2); O1 ($6); }
209 { B2 (0x61, 0x01|$1); }
211 | addsub A ',' regb_na
212 { B2 (0x61, 0x08|$1); F ($4, 13, 3); }
214 | addsub regb_na ',' A
215 { B2 (0x61, 0x00|$1); F ($2, 13, 3); }
217 | addsub A ',' EXPR {SA($4)}
218 { B1 (0x0b|$1); O1 ($4); }
220 | addsub A ',' opt_es '!' EXPR
221 { B1 (0x0f|$1); O2 ($6); }
223 | addsub A ',' opt_es '[' HL ']'
226 | addsub A ',' opt_es '[' HL '+' EXPR ']'
227 { B1 (0x0e|$1); O1 ($8); }
229 | addsub A ',' opt_es '[' HL '+' B ']'
230 { B2 (0x61, 0x80|$1); }
232 | addsub A ',' opt_es '[' HL '+' C ']'
233 { B2 (0x61, 0x82|$1); }
237 | addsub opt_es '!' EXPR ',' '#' EXPR
239 { rl78_error ("Only CMP takes these operands"); }
241 { B1 (0x00|$1); O2 ($4); O1 ($7); }
244 /* ---------------------------------------------------------------------- */
246 | addsubw AX ',' '#' EXPR
247 { B1 (0x04|$1); O2 ($5); }
249 | addsubw AX ',' regw
250 { B1 (0x01|$1); F ($4, 5, 2); }
252 | addsubw AX ',' EXPR {SA($4)}
253 { B1 (0x06|$1); O1 ($4); }
255 | addsubw AX ',' opt_es '!' EXPR
256 { B1 (0x02|$1); O2 ($6); }
258 | addsubw AX ',' opt_es '[' HL '+' EXPR ']'
259 { B2 (0x61, 0x09|$1); O1 ($8); }
261 | addsubw AX ',' opt_es '[' HL ']'
262 { B4 (0x61, 0x09|$1, 0, 0); }
264 | addsubw SP ',' '#' EXPR
265 { B1 ($1 ? 0x20 : 0x10); O1 ($5);
267 rl78_error ("CMPW SP,#imm not allowed");
270 /* ---------------------------------------------------------------------- */
272 | andor1 CY ',' sfr '.' EXPR {Bit($6)}
273 { B3 (0x71, 0x08|$1, $4); FE ($6, 9, 3); }
275 | andor1 CY ',' EXPR '.' EXPR {Bit($6)}
276 { if (expr_is_sfr ($4))
277 { B2 (0x71, 0x08|$1); FE ($6, 9, 3); O1 ($4); }
278 else if (expr_is_saddr ($4))
279 { B2 (0x71, 0x00|$1); FE ($6, 9, 3); O1 ($4); }
284 | andor1 CY ',' A '.' EXPR {Bit($6)}
285 { B2 (0x71, 0x88|$1); FE ($6, 9, 3); }
287 | andor1 CY ',' opt_es '[' HL ']' '.' EXPR {Bit($9)}
288 { B2 (0x71, 0x80|$1); FE ($9, 9, 3); }
290 /* ---------------------------------------------------------------------- */
293 { B1 (0xdc); PC1 ($3); }
296 { B1 (0xde); PC1 ($3); }
299 { B1 (0xdd); PC1 ($3); }
302 { B1 (0xdf); PC1 ($3); }
305 { B2 (0x61, 0xc3); PC1 ($3); }
308 { B2 (0x61, 0xd3); PC1 ($3); }
310 /* ---------------------------------------------------------------------- */
312 | bt_bf sfr '.' EXPR ',' '$' EXPR
313 { B3 (0x31, 0x80|$1, $2); FE ($4, 9, 3); PC1 ($7); }
315 | bt_bf EXPR '.' EXPR ',' '$' EXPR
316 { if (expr_is_sfr ($2))
317 { B2 (0x31, 0x80|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
318 else if (expr_is_saddr ($2))
319 { B2 (0x31, 0x00|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
324 | bt_bf A '.' EXPR ',' '$' EXPR
325 { B2 (0x31, 0x01|$1); FE ($4, 9, 3); PC1 ($7); }
327 | bt_bf opt_es '[' HL ']' '.' EXPR ',' '$' EXPR
328 { B2 (0x31, 0x81|$1); FE ($7, 9, 3); PC1 ($10); }
330 /* ---------------------------------------------------------------------- */
336 { B1 (0xef); PC1 ($3); }
339 { B1 (0xee); PC2 ($4); }
342 { B1 (0xed); O2 ($3); }
345 { B1 (0xec); O3 ($4); }
347 /* ---------------------------------------------------------------------- */
355 /* ---------------------------------------------------------------------- */
358 { B2 (0x61, 0xca); F ($2, 10, 2); }
361 { B1 (0xfe); PC2 ($4); }
364 { B1 (0xfd); O2 ($3); }
367 { B1 (0xfc); O3 ($4); }
370 { if ($3.X_op != O_constant)
371 rl78_error ("CALLT requires a numeric address");
374 int i = $3.X_add_number;
375 if (i < 0x80 || i > 0xbe)
376 rl78_error ("CALLT address not 0x80..0xbe");
378 rl78_error ("CALLT address not even");
382 F ((i >> 1) & 7, 9, 3);
383 F ((i >> 4) & 7, 14, 2);
388 /* ---------------------------------------------------------------------- */
391 { B2 (0x71, $1 ? 0x88 : 0x80); }
393 | setclr1 sfr '.' EXPR
394 { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); }
396 | setclr1 EXPR '.' EXPR
397 { if (expr_is_sfr ($2))
398 { B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); }
399 else if (expr_is_saddr ($2))
400 { B2 (0x71, 0x02|$1); FE ($4, 9, 3); O1 ($2); }
406 { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
408 | setclr1 opt_es '!' EXPR '.' EXPR
409 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); }
411 | setclr1 opt_es '[' HL ']' '.' EXPR
412 { B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
414 /* ---------------------------------------------------------------------- */
425 | oneclrb EXPR {SA($2)}
426 { B1 (0xe4|$1); O1 ($2); }
428 | oneclrb opt_es '!' EXPR
429 { B1 (0xe5|$1); O2 ($4); }
431 /* ---------------------------------------------------------------------- */
438 /* ---------------------------------------------------------------------- */
453 { B1 (0xd4); O1 ($2); }
455 | CMP0 opt_es '!' EXPR
456 { B1 (0xd5); O2 ($4); }
458 /* ---------------------------------------------------------------------- */
460 | CMPS X ',' opt_es '[' HL '+' EXPR ']'
461 { B2 (0x61, 0xde); O1 ($8); }
463 /* ---------------------------------------------------------------------- */
466 { B1 (0x80|$1); F ($2, 5, 3); }
468 | incdec EXPR {SA($2)}
469 { B1 (0xa4|$1); O1 ($2); }
471 { B1 (0xa0|$1); O2 ($3); }
472 | incdec ES ':' '!' EXPR
473 { B2 (0x11, 0xa0|$1); O2 ($5); }
474 | incdec '[' HL '+' EXPR ']'
475 { B2 (0x61, 0x59+$1); O1 ($5); }
476 | incdec ES ':' '[' HL '+' EXPR ']'
477 { B3 (0x11, 0x61, 0x59+$1); O1 ($7); }
479 /* ---------------------------------------------------------------------- */
482 { B1 (0xa1|$1); F ($2, 5, 2); }
484 | incdecw EXPR {SA($2)}
485 { B1 (0xa6|$1); O1 ($2); }
487 | incdecw opt_es '!' EXPR
488 { B1 (0xa2|$1); O2 ($4); }
490 | incdecw opt_es '[' HL '+' EXPR ']'
491 { B2 (0x61, 0x79+$1); O1 ($6); }
493 /* ---------------------------------------------------------------------- */
496 { B3 (0x71, 0x7b, 0xfa); }
499 { B3 (0x71, 0x7a, 0xfa); }
501 /* ---------------------------------------------------------------------- */
504 { B3 (0xce, 0xfb, 0x01); }
507 { B3 (0xce, 0xfb, 0x02); }
513 { B3 (0xce, 0xfb, 0x03); }
516 { B3 (0xce, 0xfb, 0x04); }
519 { B3 (0xce, 0xfb, 0x05); }
522 { B3 (0xce, 0xfb, 0x06); }
524 /* ---------------------------------------------------------------------- */
529 /* ---------------------------------------------------------------------- */
530 /* Note that opt_es is included even when it's not an option, to avoid
531 shift/reduce conflicts. The NOT_ES macro produces an error if ES:
532 is given by the user. */
535 { B1 (0x51); O1 ($5); }
536 | MOV regb_na ',' '#' EXPR
537 { B1 (0x50); F($2, 5, 3); O1 ($5); }
539 | MOV sfr ',' '#' EXPR
541 { B2 (0xce, $2); O1 ($5); }
543 { B1 (0x41); O1 ($5); }
546 | MOV opt_es EXPR ',' '#' EXPR {NOT_ES}
547 { if (expr_is_sfr ($3))
548 { B1 (0xce); O1 ($3); O1 ($6); }
549 else if (expr_is_saddr ($3))
550 { B1 (0xcd); O1 ($3); O1 ($6); }
555 | MOV '!' EXPR ',' '#' EXPR
556 { B1 (0xcf); O2 ($3); O1 ($6); }
558 | MOV ES ':' '!' EXPR ',' '#' EXPR
559 { B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
562 { B1 (0x70); F ($2, 5, 3); }
565 { B1 (0x60); F ($4, 5, 3); }
567 | MOV opt_es EXPR ',' A {NOT_ES}
568 { if (expr_is_sfr ($3))
569 { B1 (0x9e); O1 ($3); }
570 else if (expr_is_saddr ($3))
571 { B1 (0x9d); O1 ($3); }
576 | MOV A ',' opt_es '!' EXPR
577 { B1 (0x8f); O2 ($6); }
580 { B1 (0x9f); O2 ($3); }
582 | MOV ES ':' '!' EXPR ',' A
583 { B2 (0x11, 0x9f); O2 ($5); }
585 | MOV regb_na ',' opt_es '!' EXPR
586 { B1 (0xc9|reg_xbc($2)); O2 ($6); }
588 | MOV A ',' opt_es EXPR {NOT_ES}
589 { if (expr_is_saddr ($5))
590 { B1 (0x8d); O1 ($5); }
591 else if (expr_is_sfr ($5))
592 { B1 (0x8e); O1 ($5); }
597 | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
598 { B1 (0xc8|reg_xbc($2)); O1 ($5); }
605 rl78_error ("Only A allowed here");
610 | MOV sfr ',' opt_es EXPR {SA($5)} {NOT_ES}
612 rl78_error ("Only ES allowed here");
614 { B2 (0x61, 0xb8); O1 ($5); }
617 | MOV A ',' opt_es '[' DE ']'
620 | MOV opt_es '[' DE ']' ',' A
623 | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR
624 { B1 (0xca); O1 ($6); O1 ($10); }
626 | MOV A ',' opt_es '[' DE '+' EXPR ']'
627 { B1 (0x8a); O1 ($8); }
629 | MOV opt_es '[' DE '+' EXPR ']' ',' A
630 { B1 (0x9a); O1 ($6); }
632 | MOV A ',' opt_es '[' HL ']'
635 | MOV opt_es '[' HL ']' ',' A
638 | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR
639 { B1 (0xcc); O1 ($6); O1 ($10); }
641 | MOV A ',' opt_es '[' HL '+' EXPR ']'
642 { B1 (0x8c); O1 ($8); }
644 | MOV opt_es '[' HL '+' EXPR ']' ',' A
645 { B1 (0x9c); O1 ($6); }
647 | MOV A ',' opt_es '[' HL '+' B ']'
650 | MOV opt_es '[' HL '+' B ']' ',' A
653 | MOV A ',' opt_es '[' HL '+' C ']'
656 | MOV opt_es '[' HL '+' C ']' ',' A
659 | MOV opt_es EXPR '[' B ']' ',' '#' EXPR
660 { B1 (0x19); O2 ($3); O1 ($9); }
662 | MOV A ',' opt_es EXPR '[' B ']'
663 { B1 (0x09); O2 ($5); }
665 | MOV opt_es EXPR '[' B ']' ',' A
666 { B1 (0x18); O2 ($3); }
668 | MOV opt_es EXPR '[' C ']' ',' '#' EXPR
669 { B1 (0x38); O2 ($3); O1 ($9); }
671 | MOV A ',' opt_es EXPR '[' C ']'
672 { B1 (0x29); O2 ($5); }
674 | MOV opt_es EXPR '[' C ']' ',' A
675 { B1 (0x28); O2 ($3); }
677 | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR
678 { B1 (0x39); O2 ($3); O1 ($9); }
680 | MOV opt_es '[' BC ']' ',' '#' EXPR
681 { B3 (0x39, 0, 0); O1 ($8); }
683 | MOV A ',' opt_es EXPR '[' BC ']'
684 { B1 (0x49); O2 ($5); }
686 | MOV A ',' opt_es '[' BC ']'
689 | MOV opt_es EXPR '[' BC ']' ',' A
690 { B1 (0x48); O2 ($3); }
692 | MOV opt_es '[' BC ']' ',' A
695 | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES}
696 { B1 (0xc8); O1 ($6); O1 ($10); }
698 | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES}
699 { B2 (0xc8, 0); O1 ($8); }
701 | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
702 { B1 (0x88); O1 ($8); }
704 | MOV A ',' opt_es '[' SP ']' {NOT_ES}
707 | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES}
708 { B1 (0x98); O1 ($6); }
710 | MOV opt_es '[' SP ']' ',' A {NOT_ES}
713 /* ---------------------------------------------------------------------- */
715 | MOV1 CY ',' EXPR '.' EXPR
716 { if (expr_is_saddr ($4))
717 { B2 (0x71, 0x04); FE ($6, 9, 3); O1 ($4); }
718 else if (expr_is_sfr ($4))
719 { B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); }
724 | MOV1 CY ',' A '.' EXPR
725 { B2 (0x71, 0x8c); FE ($6, 9, 3); }
727 | MOV1 CY ',' sfr '.' EXPR
728 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
730 | MOV1 CY ',' opt_es '[' HL ']' '.' EXPR
731 { B2 (0x71, 0x84); FE ($9, 9, 3); }
733 | MOV1 EXPR '.' EXPR ',' CY
734 { if (expr_is_saddr ($2))
735 { B2 (0x71, 0x01); FE ($4, 9, 3); O1 ($2); }
736 else if (expr_is_sfr ($2))
737 { B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); }
742 | MOV1 A '.' EXPR ',' CY
743 { B2 (0x71, 0x89); FE ($4, 9, 3); }
745 | MOV1 sfr '.' EXPR ',' CY
746 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
748 | MOV1 opt_es '[' HL ']' '.' EXPR ',' CY
749 { B2 (0x71, 0x81); FE ($7, 9, 3); }
751 /* ---------------------------------------------------------------------- */
753 | MOVS opt_es '[' HL '+' EXPR ']' ',' X
754 { B2 (0x61, 0xce); O1 ($6); }
756 /* ---------------------------------------------------------------------- */
758 | MOVW AX ',' '#' EXPR
759 { B1 (0x30); O2 ($5); }
761 | MOVW regw_na ',' '#' EXPR
762 { B1 (0x30); F ($2, 5, 2); O2 ($5); }
764 | MOVW opt_es EXPR ',' '#' EXPR {NOT_ES}
765 { if (expr_is_saddr ($3))
766 { B1 (0xc9); O1 ($3); O2 ($6); }
767 else if (expr_is_sfr ($3))
768 { B1 (0xcb); O1 ($3); O2 ($6); }
773 | MOVW AX ',' opt_es EXPR {NOT_ES}
774 { if (expr_is_saddr ($5))
775 { B1 (0xad); O1 ($5); WA($5); }
776 else if (expr_is_sfr ($5))
777 { B1 (0xae); O1 ($5); WA($5); }
782 | MOVW opt_es EXPR ',' AX {NOT_ES}
783 { if (expr_is_saddr ($3))
784 { B1 (0xbd); O1 ($3); WA($3); }
785 else if (expr_is_sfr ($3))
786 { B1 (0xbe); O1 ($3); WA($3); }
791 | MOVW AX ',' regw_na
792 { B1 (0x11); F ($4, 5, 2); }
794 | MOVW regw_na ',' AX
795 { B1 (0x10); F ($2, 5, 2); }
797 | MOVW AX ',' opt_es '!' EXPR
798 { B1 (0xaf); O2 ($6); WA($6); }
800 | MOVW opt_es '!' EXPR ',' AX
801 { B1 (0xbf); O2 ($4); WA($4); }
803 | MOVW AX ',' opt_es '[' DE ']'
806 | MOVW opt_es '[' DE ']' ',' AX
809 | MOVW AX ',' opt_es '[' DE '+' EXPR ']'
810 { B1 (0xaa); O1 ($8); }
812 | MOVW opt_es '[' DE '+' EXPR ']' ',' AX
813 { B1 (0xba); O1 ($6); }
815 | MOVW AX ',' opt_es '[' HL ']'
818 | MOVW opt_es '[' HL ']' ',' AX
821 | MOVW AX ',' opt_es '[' HL '+' EXPR ']'
822 { B1 (0xac); O1 ($8); }
824 | MOVW opt_es '[' HL '+' EXPR ']' ',' AX
825 { B1 (0xbc); O1 ($6); }
827 | MOVW AX ',' opt_es EXPR '[' B ']'
828 { B1 (0x59); O2 ($5); }
830 | MOVW opt_es EXPR '[' B ']' ',' AX
831 { B1 (0x58); O2 ($3); }
833 | MOVW AX ',' opt_es EXPR '[' C ']'
834 { B1 (0x69); O2 ($5); }
836 | MOVW opt_es EXPR '[' C ']' ',' AX
837 { B1 (0x68); O2 ($3); }
839 | MOVW AX ',' opt_es EXPR '[' BC ']'
840 { B1 (0x79); O2 ($5); }
842 | MOVW AX ',' opt_es '[' BC ']'
845 | MOVW opt_es EXPR '[' BC ']' ',' AX
846 { B1 (0x78); O2 ($3); }
848 | MOVW opt_es '[' BC ']' ',' AX
851 | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
852 { B1 (0xa8); O1 ($8); WA($8);}
854 | MOVW AX ',' opt_es '[' SP ']' {NOT_ES}
857 | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES}
858 { B1 (0xb8); O1 ($6); WA($6); }
860 | MOVW opt_es '[' SP ']' ',' AX {NOT_ES}
863 | MOVW regw_na ',' EXPR {SA($4)}
864 { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); }
866 | MOVW regw_na ',' opt_es '!' EXPR
867 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); }
869 | MOVW SP ',' '#' EXPR
870 { B2 (0xcb, 0xf8); O2 ($5); }
878 | MOVW regw_na ',' SP
879 { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); }
881 /* ---------------------------------------------------------------------- */
886 /* ---------------------------------------------------------------------- */
889 { B1 (0xc0); F ($2, 5, 2); }
892 { B2 (0x61, 0xcd); };
895 { B1 (0xc1); F ($2, 5, 2); }
898 { B2 (0x61, 0xdd); };
900 /* ---------------------------------------------------------------------- */
911 /* ---------------------------------------------------------------------- */
914 { if (check_expr_is_const ($4, 1, 1))
919 { if (check_expr_is_const ($4, 1, 1))
924 { if (check_expr_is_const ($4, 1, 1))
929 { if (check_expr_is_const ($4, 1, 1))
934 { if (check_expr_is_const ($4, 1, 1))
939 { if (check_expr_is_const ($4, 1, 1))
943 /* ---------------------------------------------------------------------- */
946 { if (check_expr_is_const ($4, 1, 7))
947 { B2 (0x31, 0x0b); FE ($4, 9, 3); }
951 { if (check_expr_is_const ($4, 1, 15))
952 { B2 (0x31, 0x0f); FE ($4, 8, 4); }
955 /* ---------------------------------------------------------------------- */
969 /* ---------------------------------------------------------------------- */
972 { if (check_expr_is_const ($4, 1, 7))
973 { B2 (0x31, 0x09); FE ($4, 9, 3); }
977 { if (check_expr_is_const ($4, 1, 7))
978 { B2 (0x31, 0x08); FE ($4, 9, 3); }
982 { if (check_expr_is_const ($4, 1, 7))
983 { B2 (0x31, 0x07); FE ($4, 9, 3); }
987 { if (check_expr_is_const ($4, 1, 15))
988 { B2 (0x31, 0x0d); FE ($4, 8, 4); }
992 { if (check_expr_is_const ($4, 1, 15))
993 { B2 (0x31, 0x0c); FE ($4, 8, 4); }
996 /* ---------------------------------------------------------------------- */
999 { if (check_expr_is_const ($4, 1, 7))
1000 { B2 (0x31, 0x0a); FE ($4, 9, 3); }
1004 { if (check_expr_is_const ($4, 1, 15))
1005 { B2 (0x31, 0x0e); FE ($4, 8, 4); }
1008 /* ---------------------------------------------------------------------- */
1011 { B2 (0x61, 0xc8); }
1014 { B2 (0x61, 0xe3); }
1017 { B2 (0x61, 0xd8); }
1020 { B2 (0x61, 0xf3); }
1023 { B2 (0x61, 0xf8); }
1026 { B2 (0x61, 0xe8); }
1028 /* ---------------------------------------------------------------------- */
1031 { B2 (0x61, 0xfd); }
1033 /* ---------------------------------------------------------------------- */
1036 { if ($4 == 0) /* X */
1039 { B2 (0x61, 0x88); F ($4, 13, 3); }
1042 | XCH A ',' opt_es '!' EXPR
1043 { B2 (0x61, 0xaa); O2 ($6); }
1045 | XCH A ',' opt_es '[' DE ']'
1046 { B2 (0x61, 0xae); }
1048 | XCH A ',' opt_es '[' DE '+' EXPR ']'
1049 { B2 (0x61, 0xaf); O1 ($8); }
1051 | XCH A ',' opt_es '[' HL ']'
1052 { B2 (0x61, 0xac); }
1054 | XCH A ',' opt_es '[' HL '+' EXPR ']'
1055 { B2 (0x61, 0xad); O1 ($8); }
1057 | XCH A ',' opt_es '[' HL '+' B ']'
1058 { B2 (0x61, 0xb9); }
1060 | XCH A ',' opt_es '[' HL '+' C ']'
1061 { B2 (0x61, 0xa9); }
1064 { if (expr_is_sfr ($4))
1065 { B2 (0x61, 0xab); O1 ($4); }
1066 else if (expr_is_saddr ($4))
1067 { B2 (0x61, 0xa8); O1 ($4); }
1072 /* ---------------------------------------------------------------------- */
1074 | XCHW AX ',' regw_na
1075 { B1 (0x31); F ($4, 5, 2); }
1077 /* ---------------------------------------------------------------------- */
1079 ; /* end of statement */
1081 /* ---------------------------------------------------------------------- */
1083 opt_es : /* nothing */
1085 { rl78_prefix (0x11); }
1088 regb : X { $$ = 0; }
1098 regb_na : X { $$ = 0; }
1107 regw : AX { $$ = 0; }
1113 regw_na : BC { $$ = 1; }
1118 sfr : SPL { $$ = 0xf8; }
1119 | SPH { $$ = 0xf9; }
1120 | PSW { $$ = 0xfa; }
1123 | PMC { $$ = 0xfe; }
1124 | MEM { $$ = 0xff; }
1127 /* ---------------------------------------------------------------------- */
1128 /* Shortcuts for groups of opcodes with common encodings. */
1130 addsub : ADD { $$ = 0x00; }
1131 | ADDC { $$ = 0x10; }
1132 | SUB { $$ = 0x20; }
1133 | SUBC { $$ = 0x30; }
1134 | CMP { $$ = 0x40; }
1135 | AND_ { $$ = 0x50; }
1137 | XOR { $$ = 0x70; }
1140 addsubw : ADDW { $$ = 0x00; }
1141 | SUBW { $$ = 0x20; }
1142 | CMPW { $$ = 0x40; }
1145 andor1 : AND1 { $$ = 0x05; }
1146 | OR1 { $$ = 0x06; }
1147 | XOR1 { $$ = 0x07; }
1150 bt_bf : BT { $$ = 0x02; }
1152 | BTCLR { $$ = 0x00; }
1155 setclr1 : SET1 { $$ = 0; }
1159 oneclrb : ONEB { $$ = 0x00; }
1160 | CLRB { $$ = 0x10; }
1163 oneclrw : ONEW { $$ = 0x00; }
1164 | CLRW { $$ = 0x10; }
1167 incdec : INC { $$ = 0x00; }
1168 | DEC { $$ = 0x10; }
1171 incdecw : INCW { $$ = 0x00; }
1172 | DECW { $$ = 0x10; }
1176 /* ====================================================================== */
1180 const char * string;
1220 { "spl", SPL, 0xf8 },
1221 { "sph", SPH, 0xf9 },
1222 { "psw", PSW, 0xfa },
1225 { "pmc", PMC, 0xfe },
1226 { "mem", MEM, 0xff },
1233 { ".ub", DOT_UB, 0 },
1234 { ".uw", DOT_UW , 0},
1243 #define OPC(x) { #x, x, IS_OPCODE }
1248 { "and", AND_, IS_OPCODE },
1328 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1331 rl78_lex_init (char * beginning, char * ending)
1333 rl78_init_start = beginning;
1334 rl78_lex_start = beginning;
1335 rl78_lex_end = ending;
1336 rl78_in_brackets = 0;
1337 rl78_last_token = 0;
1345 /*unsigned int ci;*/
1346 char * save_input_pointer;
1348 while (ISSPACE (*rl78_lex_start)
1349 && rl78_lex_start != rl78_lex_end)
1352 rl78_last_exp_start = rl78_lex_start;
1354 if (rl78_lex_start == rl78_lex_end)
1357 if (ISALPHA (*rl78_lex_start)
1358 || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
1364 for (e = rl78_lex_start + 1;
1365 e < rl78_lex_end && ISALNUM (*e);
1371 for (i = 0; i < NUM_TOKENS; i++)
1372 if (strcasecmp (rl78_lex_start, token_table[i].string) == 0
1373 && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0)
1374 && !(token_table[i].token == FLAG && !need_flag))
1376 rl78_lval.regno = token_table[i].val;
1379 rl78_last_token = token_table[i].token;
1380 return token_table[i].token;
1385 if (rl78_last_token == 0)
1387 rl78_last_token = UNKNOWN_OPCODE;
1388 return UNKNOWN_OPCODE;
1391 if (rl78_last_token == UNKNOWN_OPCODE)
1394 if (*rl78_lex_start == '[')
1395 rl78_in_brackets = 1;
1396 if (*rl78_lex_start == ']')
1397 rl78_in_brackets = 0;
1399 /* '.' is funny - the syntax includes it for bitfields, but only for
1400 bitfields. We check for it specially so we can allow labels
1401 with '.' in them. */
1403 if (*rl78_lex_start == '.'
1404 && ISDIGIT (rl78_lex_start[1])
1405 && (rl78_last_token == ']'
1406 || rl78_last_token == A
1407 || rl78_last_token == PSW
1408 || rl78_last_token == EXPR))
1410 rl78_last_token = *rl78_lex_start;
1411 return *rl78_lex_start ++;
1414 if ((rl78_in_brackets && *rl78_lex_start == '+')
1415 || strchr ("[],#!$:", *rl78_lex_start))
1417 rl78_last_token = *rl78_lex_start;
1418 return *rl78_lex_start ++;
1421 save_input_pointer = input_line_pointer;
1422 input_line_pointer = rl78_lex_start;
1423 rl78_lval.exp.X_md = 0;
1424 expression (&rl78_lval.exp);
1426 rl78_lex_start = input_line_pointer;
1427 input_line_pointer = save_input_pointer;
1428 rl78_last_token = EXPR;
1433 rl78_error (char * str)
1437 len = rl78_last_exp_start - rl78_init_start;
1439 as_bad ("%s", rl78_init_start);
1440 as_bad ("%*s^ %s", len, "", str);
1445 expr_is_sfr (expressionS exp)
1449 if (exp.X_op != O_constant)
1452 v = exp.X_add_number;
1453 if (0xFFF00 <= v && v <= 0xFFFFF)
1459 expr_is_saddr (expressionS exp)
1463 if (exp.X_op != O_constant)
1466 v = exp.X_add_number;
1467 if (0xFFE20 <= v && v <= 0xFFF1F)
1473 expr_is_word_aligned (expressionS exp)
1477 if (exp.X_op != O_constant)
1480 v = exp.X_add_number;
1488 check_expr_is_bit_index (expressionS exp)
1492 if (exp.X_op != O_constant)
1494 rl78_error (_("bit index must be a constant"));
1497 val = exp.X_add_number;
1499 if (val < 0 || val > 7)
1500 rl78_error (_("rtsd size must be 0..7"));
1504 exp_val (expressionS exp)
1506 if (exp.X_op != O_constant)
1508 rl78_error (_("constant expected"));
1511 return exp.X_add_number;
1515 check_expr_is_const (expressionS e, int vmin, int vmax)
1517 static char buf[100];
1518 if (e.X_op != O_constant
1519 || e.X_add_number < vmin
1520 || e.X_add_number > vmax)
1523 sprintf (buf, "%d expected here", vmin);
1525 sprintf (buf, "%d..%d expected here", vmin, vmax);