Home | History | Annotate | Download | only in config
      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
    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
   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 *
   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
   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
   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
   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
   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
   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
   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
   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
   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