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