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