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