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