Update copyright years
[deliverable/binutils-gdb.git] / gas / config / rl78-parse.y
CommitLineData
99c513f6 1/* rl78-parse.y Renesas RL78 parser
4b95cf5c 2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
99c513f6
DD
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
26static 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
81static int expr_is_sfr (expressionS);
82static int expr_is_saddr (expressionS);
83static int expr_is_word_aligned (expressionS);
84static int exp_val (expressionS exp);
85
86static int need_flag = 0;
87static int rl78_in_brackets = 0;
88static int rl78_last_token = 0;
89static char * rl78_init_start;
90static char * rl78_last_exp_start = 0;
9cea966c 91static int rl78_bit_insn = 0;
99c513f6
DD
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
108static 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. */
113static 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. */
117static int
118reg_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
21abe33a 168%token NOP NOT1
99c513f6
DD
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
179statement :
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
9cea966c 221 { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 241 { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 256 { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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); }
294
295 | BNC '$' EXPR
296 { B1 (0xde); PC1 ($3); }
297
298 | BZ '$' EXPR
299 { B1 (0xdd); PC1 ($3); }
300
301 | BNZ '$' EXPR
302 { B1 (0xdf); PC1 ($3); }
303
304 | BH '$' EXPR
305 { B2 (0x61, 0xc3); PC1 ($3); }
306
307 | BNH '$' EXPR
308 { B2 (0x61, 0xd3); PC1 ($3); }
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
9cea966c 339 { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
99c513f6
DD
340
341 | BR '!' EXPR
9cea966c 342 { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
99c513f6
DD
343
344 | BR '!' '!' EXPR
9cea966c 345 { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
99c513f6
DD
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
9cea966c 367 { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
99c513f6
DD
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
9cea966c 409 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 429 { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 456 { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 471 { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 488 { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
151fa98f
NC
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
99c513f6 520 | DIVWU
151fa98f 521 { B3 (0xce, 0xfb, 0x0b); }
99c513f6
DD
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
9cea966c 561 { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 582 { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
583
584 | MOV '!' EXPR ',' A
9cea966c 585 { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
99c513f6
DD
586
587 | MOV ES ':' '!' EXPR ',' A
588 { B2 (0x11, 0x9f); O2 ($5); }
589
590 | MOV regb_na ',' opt_es '!' EXPR
9cea966c 591 { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 720 | mov1 CY ',' EXPR '.' EXPR
99c513f6
DD
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
9cea966c 729 | mov1 CY ',' A '.' EXPR
99c513f6
DD
730 { B2 (0x71, 0x8c); FE ($6, 9, 3); }
731
9cea966c 732 | mov1 CY ',' sfr '.' EXPR
99c513f6
DD
733 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
734
9cea966c 735 | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
99c513f6
DD
736 { B2 (0x71, 0x84); FE ($9, 9, 3); }
737
9cea966c 738 | mov1 EXPR '.' EXPR ',' CY
99c513f6
DD
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
9cea966c 747 | mov1 A '.' EXPR ',' CY
99c513f6
DD
748 { B2 (0x71, 0x89); FE ($4, 9, 3); }
749
9cea966c 750 | mov1 sfr '.' EXPR ',' CY
99c513f6
DD
751 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
752
9cea966c 753 | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
99c513f6
DD
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
9cea966c 803 { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
804
805 | MOVW opt_es '!' EXPR ',' AX
9cea966c 806 { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
9cea966c 872 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
21abe33a
DD
891/* ---------------------------------------------------------------------- */
892
893 | NOT1 CY
894 { B2 (0x71, 0xc0); }
895
99c513f6
DD
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
9cea966c 1021 { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
99c513f6
DD
1022
1023 | SKH
9cea966c 1024 { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
99c513f6
DD
1025
1026 | SKNC
9cea966c 1027 { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
99c513f6
DD
1028
1029 | SKNH
9cea966c 1030 { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
99c513f6
DD
1031
1032 | SKNZ
9cea966c 1033 { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
99c513f6
DD
1034
1035 | SKZ
9cea966c 1036 { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
99c513f6
DD
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
9cea966c 1053 { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
99c513f6
DD
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
1093opt_es : /* nothing */
1094 | ES ':'
1095 { rl78_prefix (0x11); }
1096 ;
1097
1098regb : 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
1108regb_na : X { $$ = 0; }
1109 | C { $$ = 2; }
1110 | B { $$ = 3; }
1111 | E { $$ = 4; }
1112 | D { $$ = 5; }
1113 | L { $$ = 6; }
1114 | H { $$ = 7; }
1115 ;
1116
1117regw : AX { $$ = 0; }
1118 | BC { $$ = 1; }
1119 | DE { $$ = 2; }
1120 | HL { $$ = 3; }
1121 ;
1122
1123regw_na : BC { $$ = 1; }
1124 | DE { $$ = 2; }
1125 | HL { $$ = 3; }
1126 ;
1127
1128sfr : 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
1140addsub : 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
1150addsubw : ADDW { $$ = 0x00; }
1151 | SUBW { $$ = 0x20; }
1152 | CMPW { $$ = 0x40; }
1153 ;
1154
9cea966c
DD
1155andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
1156 | OR1 { $$ = 0x06; rl78_bit_insn = 1;}
1157 | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
99c513f6
DD
1158 ;
1159
9cea966c
DD
1160bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1;}
1161 | BF { $$ = 0x04; rl78_bit_insn = 1; }
1162 | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
99c513f6
DD
1163 ;
1164
9cea966c
DD
1165setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
1166 | CLR1 { $$ = 1; rl78_bit_insn = 1; }
99c513f6
DD
1167 ;
1168
1169oneclrb : ONEB { $$ = 0x00; }
1170 | CLRB { $$ = 0x10; }
1171 ;
1172
1173oneclrw : ONEW { $$ = 0x00; }
1174 | CLRW { $$ = 0x10; }
1175 ;
1176
1177incdec : INC { $$ = 0x00; }
1178 | DEC { $$ = 0x10; }
1179 ;
1180
1181incdecw : INCW { $$ = 0x00; }
1182 | DECW { $$ = 0x10; }
1183 ;
1184
9cea966c
DD
1185mov1 : MOV1 { rl78_bit_insn = 1; }
1186 ;
1187
99c513f6
DD
1188%%
1189/* ====================================================================== */
1190
1191static struct
1192{
1193 const char * string;
1194 int token;
1195 int val;
1196}
1197token_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),
21abe33a 1303 OPC(NOT1),
99c513f6
DD
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
1344void
1345rl78_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
9cea966c
DD
1353 rl78_bit_insn = 0;
1354
99c513f6
DD
1355 setbuf (stdout, 0);
1356}
1357
9cea966c
DD
1358/* Return a pointer to the '.' in a bit index expression (like
1359 foo.5), or NULL if none is found. */
1360static char *
1361find_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
99c513f6
DD
1395static int
1396rl78_lex (void)
1397{
1398 /*unsigned int ci;*/
1399 char * save_input_pointer;
9cea966c 1400 char * bit = NULL;
99c513f6
DD
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
9cea966c
DD
1457 if (rl78_bit_insn
1458 && *rl78_lex_start == '.'
1459 && find_bit_index (rl78_lex_start) == rl78_lex_start)
99c513f6
DD
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
9cea966c
DD
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
99c513f6
DD
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
9cea966c
DD
1489 if (bit)
1490 *bit = '.';
1491
99c513f6
DD
1492 rl78_lex_start = input_line_pointer;
1493 input_line_pointer = save_input_pointer;
1494 rl78_last_token = EXPR;
1495 return EXPR;
1496}
1497
1498int
cc189285 1499rl78_error (const char * str)
99c513f6
DD
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
1510static int
1511expr_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
1524static int
1525expr_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
1538static int
1539expr_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
1553static void
1554check_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
1569static int
1570exp_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
1580static int
1581check_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
This page took 0.171907 seconds and 4 git commands to generate.