b487312f5a740cd0ec782ea10cea3c9a9415fcc7
[external/binutils.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 NOT1
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         | NOT1 CY
890           { B2 (0x71, 0xc0); }
891
892 /* ---------------------------------------------------------------------- */
893
894         | POP regw
895           { B1 (0xc0); F ($2, 5, 2); }
896
897         | POP PSW
898           { B2 (0x61, 0xcd); };
899
900         | PUSH regw
901           { B1 (0xc1); F ($2, 5, 2); }
902
903         | PUSH PSW
904           { B2 (0x61, 0xdd); };
905
906 /* ---------------------------------------------------------------------- */
907
908         | RET
909           { B1 (0xd7); }
910
911         | RETI
912           { B2 (0x61, 0xfc); }
913
914         | RETB
915           { B2 (0x61, 0xec); }
916
917 /* ---------------------------------------------------------------------- */
918
919         | ROL A ',' EXPR
920           { if (check_expr_is_const ($4, 1, 1))
921               { B2 (0x61, 0xeb); }
922           }
923
924         | ROLC A ',' EXPR
925           { if (check_expr_is_const ($4, 1, 1))
926               { B2 (0x61, 0xdc); }
927           }
928
929         | ROLWC AX ',' EXPR
930           { if (check_expr_is_const ($4, 1, 1))
931               { B2 (0x61, 0xee); }
932           }
933
934         | ROLWC BC ',' EXPR
935           { if (check_expr_is_const ($4, 1, 1))
936               { B2 (0x61, 0xfe); }
937           }
938
939         | ROR A ',' EXPR
940           { if (check_expr_is_const ($4, 1, 1))
941               { B2 (0x61, 0xdb); }
942           }
943
944         | RORC A ',' EXPR
945           { if (check_expr_is_const ($4, 1, 1))
946               { B2 (0x61, 0xfb);}
947           }
948
949 /* ---------------------------------------------------------------------- */
950
951         | SAR A ',' EXPR
952           { if (check_expr_is_const ($4, 1, 7))
953               { B2 (0x31, 0x0b); FE ($4, 9, 3); }
954           }
955
956         | SARW AX ',' EXPR
957           { if (check_expr_is_const ($4, 1, 15))
958               { B2 (0x31, 0x0f); FE ($4, 8, 4); }
959           }
960
961 /* ---------------------------------------------------------------------- */
962
963         | SEL RB0
964           { B2 (0x61, 0xcf); }
965
966         | SEL RB1
967           { B2 (0x61, 0xdf); }
968
969         | SEL RB2
970           { B2 (0x61, 0xef); }
971
972         | SEL RB3
973           { B2 (0x61, 0xff); }
974
975 /* ---------------------------------------------------------------------- */
976
977         | SHL A ',' EXPR
978           { if (check_expr_is_const ($4, 1, 7))
979               { B2 (0x31, 0x09); FE ($4, 9, 3); }
980           }
981
982         | SHL B ',' EXPR
983           { if (check_expr_is_const ($4, 1, 7))
984               { B2 (0x31, 0x08); FE ($4, 9, 3); }
985           }
986
987         | SHL C ',' EXPR
988           { if (check_expr_is_const ($4, 1, 7))
989               { B2 (0x31, 0x07); FE ($4, 9, 3); }
990           }
991
992         | SHLW AX ',' EXPR
993           { if (check_expr_is_const ($4, 1, 15))
994               { B2 (0x31, 0x0d); FE ($4, 8, 4); }
995           }
996
997         | SHLW BC ',' EXPR
998           { if (check_expr_is_const ($4, 1, 15))
999               { B2 (0x31, 0x0c); FE ($4, 8, 4); }
1000           }
1001
1002 /* ---------------------------------------------------------------------- */
1003
1004         | SHR A ',' EXPR
1005           { if (check_expr_is_const ($4, 1, 7))
1006               { B2 (0x31, 0x0a); FE ($4, 9, 3); }
1007           }
1008
1009         | SHRW AX ',' EXPR
1010           { if (check_expr_is_const ($4, 1, 15))
1011               { B2 (0x31, 0x0e); FE ($4, 8, 4); }
1012           }
1013
1014 /* ---------------------------------------------------------------------- */
1015
1016         | SKC
1017           { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
1018
1019         | SKH
1020           { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
1021
1022         | SKNC
1023           { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
1024
1025         | SKNH
1026           { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
1027
1028         | SKNZ
1029           { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
1030
1031         | SKZ
1032           { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
1033
1034 /* ---------------------------------------------------------------------- */
1035
1036         | STOP
1037           { B2 (0x61, 0xfd); }
1038
1039 /* ---------------------------------------------------------------------- */
1040
1041         | XCH A ',' regb_na
1042           { if ($4 == 0) /* X */
1043               { B1 (0x08); }
1044             else
1045               { B2 (0x61, 0x88); F ($4, 13, 3); }
1046           }
1047
1048         | XCH A ',' opt_es '!' EXPR
1049           { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
1050
1051         | XCH A ',' opt_es '[' DE ']'
1052           { B2 (0x61, 0xae); }
1053
1054         | XCH A ',' opt_es '[' DE '+' EXPR ']'
1055           { B2 (0x61, 0xaf); O1 ($8); }
1056
1057         | XCH A ',' opt_es '[' HL ']'
1058           { B2 (0x61, 0xac); }
1059
1060         | XCH A ',' opt_es '[' HL '+' EXPR ']'
1061           { B2 (0x61, 0xad); O1 ($8); }
1062
1063         | XCH A ',' opt_es '[' HL '+' B ']'
1064           { B2 (0x61, 0xb9); }
1065
1066         | XCH A ',' opt_es '[' HL '+' C ']'
1067           { B2 (0x61, 0xa9); }
1068
1069         | XCH A ',' EXPR
1070           { if (expr_is_sfr ($4))
1071               { B2 (0x61, 0xab); O1 ($4); }
1072             else if (expr_is_saddr ($4))
1073               { B2 (0x61, 0xa8); O1 ($4); }
1074             else
1075               NOT_SFR_OR_SADDR;
1076           }
1077
1078 /* ---------------------------------------------------------------------- */
1079
1080         | XCHW AX ',' regw_na
1081           { B1 (0x31); F ($4, 5, 2); }
1082
1083 /* ---------------------------------------------------------------------- */
1084
1085         ; /* end of statement */
1086
1087 /* ---------------------------------------------------------------------- */
1088
1089 opt_es  : /* nothing */
1090         | ES ':'
1091           { rl78_prefix (0x11); }
1092         ;
1093
1094 regb    : X { $$ = 0; }
1095         | A { $$ = 1; }
1096         | C { $$ = 2; }
1097         | B { $$ = 3; }
1098         | E { $$ = 4; }
1099         | D { $$ = 5; }
1100         | L { $$ = 6; }
1101         | H { $$ = 7; }
1102         ;
1103
1104 regb_na : X { $$ = 0; }
1105         | C { $$ = 2; }
1106         | B { $$ = 3; }
1107         | E { $$ = 4; }
1108         | D { $$ = 5; }
1109         | L { $$ = 6; }
1110         | H { $$ = 7; }
1111         ;
1112
1113 regw    : AX { $$ = 0; }
1114         | BC { $$ = 1; }
1115         | DE { $$ = 2; }
1116         | HL { $$ = 3; }
1117         ;
1118
1119 regw_na : BC { $$ = 1; }
1120         | DE { $$ = 2; }
1121         | HL { $$ = 3; }
1122         ;
1123
1124 sfr     : SPL { $$ = 0xf8; }
1125         | SPH { $$ = 0xf9; }
1126         | PSW { $$ = 0xfa; }
1127         | CS  { $$ = 0xfc; }
1128         | ES  { $$ = 0xfd; }
1129         | PMC { $$ = 0xfe; }
1130         | MEM { $$ = 0xff; }
1131         ;
1132
1133 /* ---------------------------------------------------------------------- */
1134 /* Shortcuts for groups of opcodes with common encodings.                 */
1135
1136 addsub  : ADD  { $$ = 0x00; }
1137         | ADDC { $$ = 0x10; }
1138         | SUB  { $$ = 0x20; }
1139         | SUBC { $$ = 0x30; }
1140         | CMP  { $$ = 0x40; }
1141         | AND_ { $$ = 0x50; }
1142         | OR   { $$ = 0x60; }
1143         | XOR  { $$ = 0x70; }
1144         ;
1145
1146 addsubw : ADDW  { $$ = 0x00; }
1147         | SUBW  { $$ = 0x20; }
1148         | CMPW  { $$ = 0x40; }
1149         ;
1150
1151 andor1  : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
1152         | OR1  { $$ = 0x06; rl78_bit_insn = 1;}
1153         | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
1154         ;
1155
1156 bt_bf   : BT { $$ = 0x02;    rl78_bit_insn = 1;}
1157         | BF { $$ = 0x04;    rl78_bit_insn = 1; }
1158         | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
1159         ;
1160
1161 setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
1162         | CLR1 { $$ = 1; rl78_bit_insn = 1; }
1163         ;
1164
1165 oneclrb : ONEB { $$ = 0x00; }
1166         | CLRB { $$ = 0x10; }
1167         ;
1168
1169 oneclrw : ONEW { $$ = 0x00; }
1170         | CLRW { $$ = 0x10; }
1171         ;
1172
1173 incdec  : INC { $$ = 0x00; }
1174         | DEC { $$ = 0x10; }
1175         ;
1176
1177 incdecw : INCW { $$ = 0x00; }
1178         | DECW { $$ = 0x10; }
1179         ;
1180
1181 mov1    : MOV1 { rl78_bit_insn = 1; }
1182         ;
1183
1184 %%
1185 /* ====================================================================== */
1186
1187 static struct
1188 {
1189   const char * string;
1190   int          token;
1191   int          val;
1192 }
1193 token_table[] =
1194 {
1195   { "r0", X, 0 },
1196   { "r1", A, 1 },
1197   { "r2", C, 2 },
1198   { "r3", B, 3 },
1199   { "r4", E, 4 },
1200   { "r5", D, 5 },
1201   { "r6", L, 6 },
1202   { "r7", H, 7 },
1203   { "x", X, 0 },
1204   { "a", A, 1 },
1205   { "c", C, 2 },
1206   { "b", B, 3 },
1207   { "e", E, 4 },
1208   { "d", D, 5 },
1209   { "l", L, 6 },
1210   { "h", H, 7 },
1211
1212   { "rp0", AX, 0 },
1213   { "rp1", BC, 1 },
1214   { "rp2", DE, 2 },
1215   { "rp3", HL, 3 },
1216   { "ax", AX, 0 },
1217   { "bc", BC, 1 },
1218   { "de", DE, 2 },
1219   { "hl", HL, 3 },
1220
1221   { "RB0", RB0, 0 },
1222   { "RB1", RB1, 1 },
1223   { "RB2", RB2, 2 },
1224   { "RB3", RB3, 3 },
1225
1226   { "sp", SP, 0 },
1227   { "cy", CY, 0 },
1228
1229   { "spl", SPL, 0xf8 },
1230   { "sph", SPH, 0xf9 },
1231   { "psw", PSW, 0xfa },
1232   { "cs", CS, 0xfc },
1233   { "es", ES, 0xfd },
1234   { "pmc", PMC, 0xfe },
1235   { "mem", MEM, 0xff },
1236
1237   { ".s", DOT_S, 0 },
1238   { ".b", DOT_B, 0 },
1239   { ".w", DOT_W, 0 },
1240   { ".l", DOT_L, 0 },
1241   { ".a", DOT_A , 0},
1242   { ".ub", DOT_UB, 0 },
1243   { ".uw", DOT_UW , 0},
1244
1245   { "c", FLAG, 0 },
1246   { "z", FLAG, 1 },
1247   { "s", FLAG, 2 },
1248   { "o", FLAG, 3 },
1249   { "i", FLAG, 8 },
1250   { "u", FLAG, 9 },
1251
1252 #define OPC(x) { #x, x, IS_OPCODE }
1253
1254   OPC(ADD),
1255   OPC(ADDC),
1256   OPC(ADDW),
1257   { "and", AND_, IS_OPCODE },
1258   OPC(AND1),
1259   OPC(BC),
1260   OPC(BF),
1261   OPC(BH),
1262   OPC(BNC),
1263   OPC(BNH),
1264   OPC(BNZ),
1265   OPC(BR),
1266   OPC(BRK),
1267   OPC(BRK1),
1268   OPC(BT),
1269   OPC(BTCLR),
1270   OPC(BZ),
1271   OPC(CALL),
1272   OPC(CALLT),
1273   OPC(CLR1),
1274   OPC(CLRB),
1275   OPC(CLRW),
1276   OPC(CMP),
1277   OPC(CMP0),
1278   OPC(CMPS),
1279   OPC(CMPW),
1280   OPC(DEC),
1281   OPC(DECW),
1282   OPC(DI),
1283   OPC(DIVHU),
1284   OPC(DIVWU),
1285   OPC(EI),
1286   OPC(HALT),
1287   OPC(INC),
1288   OPC(INCW),
1289   OPC(MACH),
1290   OPC(MACHU),
1291   OPC(MOV),
1292   OPC(MOV1),
1293   OPC(MOVS),
1294   OPC(MOVW),
1295   OPC(MULH),
1296   OPC(MULHU),
1297   OPC(MULU),
1298   OPC(NOP),
1299   OPC(NOT1),
1300   OPC(ONEB),
1301   OPC(ONEW),
1302   OPC(OR),
1303   OPC(OR1),
1304   OPC(POP),
1305   OPC(PUSH),
1306   OPC(RET),
1307   OPC(RETI),
1308   OPC(RETB),
1309   OPC(ROL),
1310   OPC(ROLC),
1311   OPC(ROLWC),
1312   OPC(ROR),
1313   OPC(RORC),
1314   OPC(SAR),
1315   OPC(SARW),
1316   OPC(SEL),
1317   OPC(SET1),
1318   OPC(SHL),
1319   OPC(SHLW),
1320   OPC(SHR),
1321   OPC(SHRW),
1322   OPC(SKC),
1323   OPC(SKH),
1324   OPC(SKNC),
1325   OPC(SKNH),
1326   OPC(SKNZ),
1327   OPC(SKZ),
1328   OPC(STOP),
1329   OPC(SUB),
1330   OPC(SUBC),
1331   OPC(SUBW),
1332   OPC(XCH),
1333   OPC(XCHW),
1334   OPC(XOR),
1335   OPC(XOR1),
1336 };
1337
1338 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1339
1340 void
1341 rl78_lex_init (char * beginning, char * ending)
1342 {
1343   rl78_init_start = beginning;
1344   rl78_lex_start = beginning;
1345   rl78_lex_end = ending;
1346   rl78_in_brackets = 0;
1347   rl78_last_token = 0;
1348
1349   rl78_bit_insn = 0;
1350
1351   setbuf (stdout, 0);
1352 }
1353
1354 /* Return a pointer to the '.' in a bit index expression (like
1355    foo.5), or NULL if none is found.  */
1356 static char *
1357 find_bit_index (char *tok)
1358 {
1359   char *last_dot = NULL;
1360   char *last_digit = NULL;
1361   while (*tok && *tok != ',')
1362     {
1363       if (*tok == '.')
1364         {
1365           last_dot = tok;
1366           last_digit = NULL;
1367         }
1368       else if (*tok >= '0' && *tok <= '7'
1369                && last_dot != NULL
1370                && last_digit == NULL)
1371         {
1372           last_digit = tok;
1373         }
1374       else if (ISSPACE (*tok))
1375         {
1376           /* skip */
1377         }
1378       else
1379         {
1380           last_dot = NULL;
1381           last_digit = NULL;
1382         }
1383       tok ++;
1384     }
1385   if (last_dot != NULL
1386       && last_digit != NULL)
1387     return last_dot;
1388   return NULL;
1389 }
1390
1391 static int
1392 rl78_lex (void)
1393 {
1394   /*unsigned int ci;*/
1395   char * save_input_pointer;
1396   char * bit = NULL;
1397
1398   while (ISSPACE (*rl78_lex_start)
1399          && rl78_lex_start != rl78_lex_end)
1400     rl78_lex_start ++;
1401
1402   rl78_last_exp_start = rl78_lex_start;
1403
1404   if (rl78_lex_start == rl78_lex_end)
1405     return 0;
1406
1407   if (ISALPHA (*rl78_lex_start)
1408       || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
1409     {
1410       unsigned int i;
1411       char * e;
1412       char save;
1413
1414       for (e = rl78_lex_start + 1;
1415            e < rl78_lex_end && ISALNUM (*e);
1416            e ++)
1417         ;
1418       save = *e;
1419       *e = 0;
1420
1421       for (i = 0; i < NUM_TOKENS; i++)
1422         if (strcasecmp (rl78_lex_start, token_table[i].string) == 0
1423             && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0)
1424             && !(token_table[i].token == FLAG && !need_flag))
1425           {
1426             rl78_lval.regno = token_table[i].val;
1427             *e = save;
1428             rl78_lex_start = e;
1429             rl78_last_token = token_table[i].token;
1430             return token_table[i].token;
1431           }
1432       *e = save;
1433     }
1434
1435   if (rl78_last_token == 0)
1436     {
1437       rl78_last_token = UNKNOWN_OPCODE;
1438       return UNKNOWN_OPCODE;
1439     }
1440
1441   if (rl78_last_token == UNKNOWN_OPCODE)
1442     return 0;
1443
1444   if (*rl78_lex_start == '[')
1445     rl78_in_brackets = 1;
1446   if (*rl78_lex_start == ']')
1447     rl78_in_brackets = 0;
1448
1449   /* '.' is funny - the syntax includes it for bitfields, but only for
1450       bitfields.  We check for it specially so we can allow labels
1451       with '.' in them.  */
1452
1453   if (rl78_bit_insn
1454       && *rl78_lex_start == '.'
1455       && find_bit_index (rl78_lex_start) == rl78_lex_start)
1456     {
1457       rl78_last_token = *rl78_lex_start;
1458       return *rl78_lex_start ++;
1459     }
1460
1461   if ((rl78_in_brackets && *rl78_lex_start == '+')
1462       || strchr ("[],#!$:", *rl78_lex_start))
1463     {
1464       rl78_last_token = *rl78_lex_start;
1465       return *rl78_lex_start ++;
1466     }
1467
1468   /* Again, '.' is funny.  Look for '.<digit>' at the end of the line
1469      or before a comma, which is a bitfield, not an expression.  */
1470
1471   if (rl78_bit_insn)
1472     {
1473       bit = find_bit_index (rl78_lex_start);
1474       if (bit)
1475         *bit = 0;
1476       else
1477         bit = NULL;
1478     }
1479
1480   save_input_pointer = input_line_pointer;
1481   input_line_pointer = rl78_lex_start;
1482   rl78_lval.exp.X_md = 0;
1483   expression (&rl78_lval.exp);
1484
1485   if (bit)
1486     *bit = '.';
1487
1488   rl78_lex_start = input_line_pointer;
1489   input_line_pointer = save_input_pointer;
1490   rl78_last_token = EXPR;
1491   return EXPR;
1492 }
1493
1494 int
1495 rl78_error (const char * str)
1496 {
1497   int len;
1498
1499   len = rl78_last_exp_start - rl78_init_start;
1500
1501   as_bad ("%s", rl78_init_start);
1502   as_bad ("%*s^ %s", len, "", str);
1503   return 0;
1504 }
1505
1506 static int
1507 expr_is_sfr (expressionS exp)
1508 {
1509   unsigned long v;
1510
1511   if (exp.X_op != O_constant)
1512     return 0;
1513
1514   v = exp.X_add_number;
1515   if (0xFFF00 <= v && v <= 0xFFFFF)
1516     return 1;
1517   return 0;
1518 }
1519
1520 static int
1521 expr_is_saddr (expressionS exp)
1522 {
1523   unsigned long v;
1524
1525   if (exp.X_op != O_constant)
1526     return 0;
1527
1528   v = exp.X_add_number;
1529   if (0xFFE20 <= v && v <= 0xFFF1F)
1530     return 1;
1531   return 0;
1532 }
1533
1534 static int
1535 expr_is_word_aligned (expressionS exp)
1536 {
1537   unsigned long v;
1538
1539   if (exp.X_op != O_constant)
1540     return 1;
1541
1542   v = exp.X_add_number;
1543   if (v & 1)
1544     return 0;
1545   return 1;
1546   
1547 }
1548
1549 static void
1550 check_expr_is_bit_index (expressionS exp)
1551 {
1552   int val;
1553
1554   if (exp.X_op != O_constant)
1555     {
1556       rl78_error (_("bit index must be a constant"));
1557       return;
1558     }
1559   val = exp.X_add_number;
1560
1561   if (val < 0 || val > 7)
1562     rl78_error (_("rtsd size must be 0..7"));
1563 }
1564
1565 static int
1566 exp_val (expressionS exp)
1567 {
1568   if (exp.X_op != O_constant)
1569   {
1570     rl78_error (_("constant expected"));
1571     return 0;
1572   }
1573   return exp.X_add_number;
1574 }
1575
1576 static int
1577 check_expr_is_const (expressionS e, int vmin, int vmax)
1578 {
1579   static char buf[100];
1580   if (e.X_op != O_constant
1581       || e.X_add_number < vmin
1582       || e.X_add_number > vmax)
1583     {
1584       if (vmin == vmax)
1585         sprintf (buf, "%d expected here", vmin);
1586       else
1587         sprintf (buf, "%d..%d expected here", vmin, vmax);
1588       rl78_error(buf);
1589       return 0;
1590     }
1591   return 1;
1592 }
1593
1594