* elf32-spu.c (build_stub): Fix malloc under-allocation.
[binutils.git] / gas / config / rl78-parse.y
blobb487312f5a740cd0ec782ea10cea3c9a9415fcc7
1 /* rl78-parse.y Renesas RL78 parser
2 Copyright 2011
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "rl78-defs.h"
27 static int rl78_lex (void);
29 /* Ok, here are the rules for using these macros...
31 B*() is used to specify the base opcode bytes. Fields to be filled
32 in later, leave zero. Call this first.
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().
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
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.
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.
51 Use "disp" for displacements whenever possible; this handles the
52 "0" case properly. */
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)
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);
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)
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)
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)
80 #define id24(a,b2,b3) B3 (0xfb+a, b2, b3)
82 static int expr_is_sfr (expressionS);
83 static int expr_is_saddr (expressionS);
84 static int expr_is_word_aligned (expressionS);
85 static int exp_val (expressionS exp);
87 static int need_flag = 0;
88 static int rl78_in_brackets = 0;
89 static int rl78_last_token = 0;
90 static char * rl78_init_start;
91 static char * rl78_last_exp_start = 0;
92 static int rl78_bit_insn = 0;
94 #define YYDEBUG 1
95 #define YYERROR_VERBOSE 1
97 #define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F")
98 #define SA(e) if (!expr_is_saddr (e)) NOT_SADDR;
100 #define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF")
101 #define SFR(e) if (!expr_is_sfr (e)) NOT_SFR;
103 #define NOT_SFR_OR_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFFFF")
105 #define NOT_ES if (rl78_has_prefix()) rl78_error ("ES: prefix not allowed here");
107 #define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
109 static void check_expr_is_bit_index (expressionS);
110 #define Bit(e) check_expr_is_bit_index (e);
112 /* Returns TRUE (non-zero) if the expression is a constant in the
113 given range. */
114 static int check_expr_is_const (expressionS, int vmin, int vmax);
116 /* Convert a "regb" value to a "reg_xbc" value. Error if other
117 registers are passed. Needed to avoid reduce-reduce conflicts. */
118 static int
119 reg_xbc (int reg)
121 switch (reg)
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;
137 %name-prefix="rl78_"
139 %union {
140 int regno;
141 expressionS exp;
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
148 %type <regno> addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw
149 %type <regno> incdec incdecw
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
156 %token EXPR UNKNOWN_OPCODE IS_OPCODE
158 %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
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
169 %token NOP NOT1
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
178 /* ====================================================================== */
180 statement :
182 UNKNOWN_OPCODE
183 { as_bad (_("Unknown opcode: %s"), rl78_init_start); }
185 /* The opcodes are listed in approximately alphabetical order. */
187 /* For reference:
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
194 addr20 = 0x00000 to 0xFFFFF
195 addr16 = 0x00000 to 0x0FFFF, even only for 16-bit ops
196 addr5 = 0x00000 to 0x000BE, even only
199 /* ---------------------------------------------------------------------- */
201 /* addsub is ADD, ADDC, SUB, SUBC, AND, OR, XOR, and parts of CMP. */
203 | addsub A ',' '#' EXPR
204 { B1 (0x0c|$1); O1 ($5); }
206 | addsub EXPR {SA($2)} ',' '#' EXPR
207 { B1 (0x0a|$1); O1 ($2); O1 ($6); }
209 | addsub A ',' A
210 { B2 (0x61, 0x01|$1); }
212 | addsub A ',' regb_na
213 { B2 (0x61, 0x08|$1); F ($4, 13, 3); }
215 | addsub regb_na ',' A
216 { B2 (0x61, 0x00|$1); F ($2, 13, 3); }
218 | addsub A ',' EXPR {SA($4)}
219 { B1 (0x0b|$1); O1 ($4); }
221 | addsub A ',' opt_es '!' EXPR
222 { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
224 | addsub A ',' opt_es '[' HL ']'
225 { B1 (0x0d|$1); }
227 | addsub A ',' opt_es '[' HL '+' EXPR ']'
228 { B1 (0x0e|$1); O1 ($8); }
230 | addsub A ',' opt_es '[' HL '+' B ']'
231 { B2 (0x61, 0x80|$1); }
233 | addsub A ',' opt_es '[' HL '+' C ']'
234 { B2 (0x61, 0x82|$1); }
238 | addsub opt_es '!' EXPR ',' '#' EXPR
239 { if ($1 != 0x40)
240 { rl78_error ("Only CMP takes these operands"); }
241 else
242 { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
245 /* ---------------------------------------------------------------------- */
247 | addsubw AX ',' '#' EXPR
248 { B1 (0x04|$1); O2 ($5); }
250 | addsubw AX ',' regw
251 { B1 (0x01|$1); F ($4, 5, 2); }
253 | addsubw AX ',' EXPR {SA($4)}
254 { B1 (0x06|$1); O1 ($4); }
256 | addsubw AX ',' opt_es '!' EXPR
257 { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
259 | addsubw AX ',' opt_es '[' HL '+' EXPR ']'
260 { B2 (0x61, 0x09|$1); O1 ($8); }
262 | addsubw AX ',' opt_es '[' HL ']'
263 { B4 (0x61, 0x09|$1, 0, 0); }
265 | addsubw SP ',' '#' EXPR
266 { B1 ($1 ? 0x20 : 0x10); O1 ($5);
267 if ($1 == 0x40)
268 rl78_error ("CMPW SP,#imm not allowed");
271 /* ---------------------------------------------------------------------- */
273 | andor1 CY ',' sfr '.' EXPR {Bit($6)}
274 { B3 (0x71, 0x08|$1, $4); FE ($6, 9, 3); }
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;
285 | andor1 CY ',' A '.' EXPR {Bit($6)}
286 { B2 (0x71, 0x88|$1); FE ($6, 9, 3); }
288 | andor1 CY ',' opt_es '[' HL ']' '.' EXPR {Bit($9)}
289 { B2 (0x71, 0x80|$1); FE ($9, 9, 3); }
291 /* ---------------------------------------------------------------------- */
293 | BC '$' EXPR
294 { B1 (0xdc); PC1 ($3); }
296 | BNC '$' EXPR
297 { B1 (0xde); PC1 ($3); }
299 | BZ '$' EXPR
300 { B1 (0xdd); PC1 ($3); }
302 | BNZ '$' EXPR
303 { B1 (0xdf); PC1 ($3); }
305 | BH '$' EXPR
306 { B2 (0x61, 0xc3); PC1 ($3); }
308 | BNH '$' EXPR
309 { B2 (0x61, 0xd3); PC1 ($3); }
311 /* ---------------------------------------------------------------------- */
313 | bt_bf sfr '.' EXPR ',' '$' EXPR
314 { B3 (0x31, 0x80|$1, $2); FE ($4, 9, 3); PC1 ($7); }
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;
325 | bt_bf A '.' EXPR ',' '$' EXPR
326 { B2 (0x31, 0x01|$1); FE ($4, 9, 3); PC1 ($7); }
328 | bt_bf opt_es '[' HL ']' '.' EXPR ',' '$' EXPR
329 { B2 (0x31, 0x81|$1); FE ($7, 9, 3); PC1 ($10); }
331 /* ---------------------------------------------------------------------- */
333 | BR AX
334 { B2 (0x61, 0xcb); }
336 | BR '$' EXPR
337 { B1 (0xef); PC1 ($3); }
339 | BR '$' '!' EXPR
340 { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
342 | BR '!' EXPR
343 { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
345 | BR '!' '!' EXPR
346 { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
348 /* ---------------------------------------------------------------------- */
350 | BRK
351 { B2 (0x61, 0xcc); }
353 | BRK1
354 { B1 (0xff); }
356 /* ---------------------------------------------------------------------- */
358 | CALL regw
359 { B2 (0x61, 0xca); F ($2, 10, 2); }
361 | CALL '$' '!' EXPR
362 { B1 (0xfe); PC2 ($4); }
364 | CALL '!' EXPR
365 { B1 (0xfd); O2 ($3); }
367 | CALL '!' '!' EXPR
368 { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
370 | CALLT '[' EXPR ']'
371 { if ($3.X_op != O_constant)
372 rl78_error ("CALLT requires a numeric address");
373 else
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
382 B2 (0x61, 0x84);
383 F ((i >> 1) & 7, 9, 3);
384 F ((i >> 4) & 7, 14, 2);
389 /* ---------------------------------------------------------------------- */
391 | setclr1 CY
392 { B2 (0x71, $1 ? 0x88 : 0x80); }
394 | setclr1 sfr '.' EXPR
395 { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); }
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;
406 | setclr1 A '.' EXPR
407 { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
409 | setclr1 opt_es '!' EXPR '.' EXPR
410 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
412 | setclr1 opt_es '[' HL ']' '.' EXPR
413 { B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
415 /* ---------------------------------------------------------------------- */
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); }
426 | oneclrb EXPR {SA($2)}
427 { B1 (0xe4|$1); O1 ($2); }
429 | oneclrb opt_es '!' EXPR
430 { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
432 /* ---------------------------------------------------------------------- */
434 | oneclrw AX
435 { B1 (0xe6|$1); }
436 | oneclrw BC
437 { B1 (0xe7|$1); }
439 /* ---------------------------------------------------------------------- */
441 | CMP0 A
442 { B1 (0xd1); }
444 | CMP0 X
445 { B1 (0xd0); }
447 | CMP0 B
448 { B1 (0xd3); }
450 | CMP0 C
451 { B1 (0xd2); }
453 | CMP0 EXPR {SA($2)}
454 { B1 (0xd4); O1 ($2); }
456 | CMP0 opt_es '!' EXPR
457 { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
459 /* ---------------------------------------------------------------------- */
461 | CMPS X ',' opt_es '[' HL '+' EXPR ']'
462 { B2 (0x61, 0xde); O1 ($8); }
464 /* ---------------------------------------------------------------------- */
466 | incdec regb
467 { B1 (0x80|$1); F ($2, 5, 3); }
469 | incdec EXPR {SA($2)}
470 { B1 (0xa4|$1); O1 ($2); }
471 | incdec '!' EXPR
472 { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
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); }
480 /* ---------------------------------------------------------------------- */
482 | incdecw regw
483 { B1 (0xa1|$1); F ($2, 5, 2); }
485 | incdecw EXPR {SA($2)}
486 { B1 (0xa6|$1); O1 ($2); }
488 | incdecw opt_es '!' EXPR
489 { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
491 | incdecw opt_es '[' HL '+' EXPR ']'
492 { B2 (0x61, 0x79+$1); O1 ($6); }
494 /* ---------------------------------------------------------------------- */
496 | DI
497 { B3 (0x71, 0x7b, 0xfa); }
499 | EI
500 { B3 (0x71, 0x7a, 0xfa); }
502 /* ---------------------------------------------------------------------- */
504 | MULHU
505 { B3 (0xce, 0xfb, 0x01); }
507 | MULH
508 { B3 (0xce, 0xfb, 0x02); }
510 | MULU X
511 { B1 (0xd6); }
513 | DIVHU
514 { B3 (0xce, 0xfb, 0x03); }
516 | DIVWU
517 { B3 (0xce, 0xfb, 0x04); }
519 | MACHU
520 { B3 (0xce, 0xfb, 0x05); }
522 | MACH
523 { B3 (0xce, 0xfb, 0x06); }
525 /* ---------------------------------------------------------------------- */
527 | HALT
528 { B2 (0x61, 0xed); }
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. */
535 | MOV A ',' '#' EXPR
536 { B1 (0x51); O1 ($5); }
537 | MOV regb_na ',' '#' EXPR
538 { B1 (0x50); F($2, 5, 3); O1 ($5); }
540 | MOV sfr ',' '#' EXPR
541 { if ($2 != 0xfd)
542 { B2 (0xce, $2); O1 ($5); }
543 else
544 { B1 (0x41); O1 ($5); }
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;
556 | MOV '!' EXPR ',' '#' EXPR
557 { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
559 | MOV ES ':' '!' EXPR ',' '#' EXPR
560 { B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
562 | MOV regb_na ',' A
563 { B1 (0x70); F ($2, 5, 3); }
565 | MOV A ',' regb_na
566 { B1 (0x60); F ($4, 5, 3); }
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;
577 | MOV A ',' opt_es '!' EXPR
578 { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
580 | MOV '!' EXPR ',' A
581 { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
583 | MOV ES ':' '!' EXPR ',' A
584 { B2 (0x11, 0x9f); O2 ($5); }
586 | MOV regb_na ',' opt_es '!' EXPR
587 { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
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;
598 | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
599 { B1 (0xc8|reg_xbc($2)); O1 ($5); }
601 | MOV A ',' sfr
602 { B2 (0x8e, $4); }
604 | MOV sfr ',' regb
605 { if ($4 != 1)
606 rl78_error ("Only A allowed here");
607 else
608 { B2 (0x9e, $2); }
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); }
618 | MOV A ',' opt_es '[' DE ']'
619 { B1 (0x89); }
621 | MOV opt_es '[' DE ']' ',' A
622 { B1 (0x99); }
624 | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR
625 { B1 (0xca); O1 ($6); O1 ($10); }
627 | MOV A ',' opt_es '[' DE '+' EXPR ']'
628 { B1 (0x8a); O1 ($8); }
630 | MOV opt_es '[' DE '+' EXPR ']' ',' A
631 { B1 (0x9a); O1 ($6); }
633 | MOV A ',' opt_es '[' HL ']'
634 { B1 (0x8b); }
636 | MOV opt_es '[' HL ']' ',' A
637 { B1 (0x9b); }
639 | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR
640 { B1 (0xcc); O1 ($6); O1 ($10); }
642 | MOV A ',' opt_es '[' HL '+' EXPR ']'
643 { B1 (0x8c); O1 ($8); }
645 | MOV opt_es '[' HL '+' EXPR ']' ',' A
646 { B1 (0x9c); O1 ($6); }
648 | MOV A ',' opt_es '[' HL '+' B ']'
649 { B2 (0x61, 0xc9); }
651 | MOV opt_es '[' HL '+' B ']' ',' A
652 { B2 (0x61, 0xd9); }
654 | MOV A ',' opt_es '[' HL '+' C ']'
655 { B2 (0x61, 0xe9); }
657 | MOV opt_es '[' HL '+' C ']' ',' A
658 { B2 (0x61, 0xf9); }
660 | MOV opt_es EXPR '[' B ']' ',' '#' EXPR
661 { B1 (0x19); O2 ($3); O1 ($9); }
663 | MOV A ',' opt_es EXPR '[' B ']'
664 { B1 (0x09); O2 ($5); }
666 | MOV opt_es EXPR '[' B ']' ',' A
667 { B1 (0x18); O2 ($3); }
669 | MOV opt_es EXPR '[' C ']' ',' '#' EXPR
670 { B1 (0x38); O2 ($3); O1 ($9); }
672 | MOV A ',' opt_es EXPR '[' C ']'
673 { B1 (0x29); O2 ($5); }
675 | MOV opt_es EXPR '[' C ']' ',' A
676 { B1 (0x28); O2 ($3); }
678 | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR
679 { B1 (0x39); O2 ($3); O1 ($9); }
681 | MOV opt_es '[' BC ']' ',' '#' EXPR
682 { B3 (0x39, 0, 0); O1 ($8); }
684 | MOV A ',' opt_es EXPR '[' BC ']'
685 { B1 (0x49); O2 ($5); }
687 | MOV A ',' opt_es '[' BC ']'
688 { B3 (0x49, 0, 0); }
690 | MOV opt_es EXPR '[' BC ']' ',' A
691 { B1 (0x48); O2 ($3); }
693 | MOV opt_es '[' BC ']' ',' A
694 { B3 (0x48, 0, 0); }
696 | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES}
697 { B1 (0xc8); O1 ($6); O1 ($10); }
699 | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES}
700 { B2 (0xc8, 0); O1 ($8); }
702 | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
703 { B1 (0x88); O1 ($8); }
705 | MOV A ',' opt_es '[' SP ']' {NOT_ES}
706 { B2 (0x88, 0); }
708 | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES}
709 { B1 (0x98); O1 ($6); }
711 | MOV opt_es '[' SP ']' ',' A {NOT_ES}
712 { B2 (0x98, 0); }
714 /* ---------------------------------------------------------------------- */
716 | mov1 CY ',' EXPR '.' EXPR
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;
725 | mov1 CY ',' A '.' EXPR
726 { B2 (0x71, 0x8c); FE ($6, 9, 3); }
728 | mov1 CY ',' sfr '.' EXPR
729 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
731 | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
732 { B2 (0x71, 0x84); FE ($9, 9, 3); }
734 | mov1 EXPR '.' EXPR ',' CY
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;
743 | mov1 A '.' EXPR ',' CY
744 { B2 (0x71, 0x89); FE ($4, 9, 3); }
746 | mov1 sfr '.' EXPR ',' CY
747 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
749 | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
750 { B2 (0x71, 0x81); FE ($7, 9, 3); }
752 /* ---------------------------------------------------------------------- */
754 | MOVS opt_es '[' HL '+' EXPR ']' ',' X
755 { B2 (0x61, 0xce); O1 ($6); }
757 /* ---------------------------------------------------------------------- */
759 | MOVW AX ',' '#' EXPR
760 { B1 (0x30); O2 ($5); }
762 | MOVW regw_na ',' '#' EXPR
763 { B1 (0x30); F ($2, 5, 2); O2 ($5); }
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;
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;
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;
792 | MOVW AX ',' regw_na
793 { B1 (0x11); F ($4, 5, 2); }
795 | MOVW regw_na ',' AX
796 { B1 (0x10); F ($2, 5, 2); }
798 | MOVW AX ',' opt_es '!' EXPR
799 { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
801 | MOVW opt_es '!' EXPR ',' AX
802 { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
804 | MOVW AX ',' opt_es '[' DE ']'
805 { B1 (0xa9); }
807 | MOVW opt_es '[' DE ']' ',' AX
808 { B1 (0xb9); }
810 | MOVW AX ',' opt_es '[' DE '+' EXPR ']'
811 { B1 (0xaa); O1 ($8); }
813 | MOVW opt_es '[' DE '+' EXPR ']' ',' AX
814 { B1 (0xba); O1 ($6); }
816 | MOVW AX ',' opt_es '[' HL ']'
817 { B1 (0xab); }
819 | MOVW opt_es '[' HL ']' ',' AX
820 { B1 (0xbb); }
822 | MOVW AX ',' opt_es '[' HL '+' EXPR ']'
823 { B1 (0xac); O1 ($8); }
825 | MOVW opt_es '[' HL '+' EXPR ']' ',' AX
826 { B1 (0xbc); O1 ($6); }
828 | MOVW AX ',' opt_es EXPR '[' B ']'
829 { B1 (0x59); O2 ($5); }
831 | MOVW opt_es EXPR '[' B ']' ',' AX
832 { B1 (0x58); O2 ($3); }
834 | MOVW AX ',' opt_es EXPR '[' C ']'
835 { B1 (0x69); O2 ($5); }
837 | MOVW opt_es EXPR '[' C ']' ',' AX
838 { B1 (0x68); O2 ($3); }
840 | MOVW AX ',' opt_es EXPR '[' BC ']'
841 { B1 (0x79); O2 ($5); }
843 | MOVW AX ',' opt_es '[' BC ']'
844 { B3 (0x79, 0, 0); }
846 | MOVW opt_es EXPR '[' BC ']' ',' AX
847 { B1 (0x78); O2 ($3); }
849 | MOVW opt_es '[' BC ']' ',' AX
850 { B3 (0x78, 0, 0); }
852 | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
853 { B1 (0xa8); O1 ($8); WA($8);}
855 | MOVW AX ',' opt_es '[' SP ']' {NOT_ES}
856 { B2 (0xa8, 0); }
858 | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES}
859 { B1 (0xb8); O1 ($6); WA($6); }
861 | MOVW opt_es '[' SP ']' ',' AX {NOT_ES}
862 { B2 (0xb8, 0); }
864 | MOVW regw_na ',' EXPR {SA($4)}
865 { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); }
867 | MOVW regw_na ',' opt_es '!' EXPR
868 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
870 | MOVW SP ',' '#' EXPR
871 { B2 (0xcb, 0xf8); O2 ($5); }
873 | MOVW SP ',' AX
874 { B2 (0xbe, 0xf8); }
876 | MOVW AX ',' SP
877 { B2 (0xae, 0xf8); }
879 | MOVW regw_na ',' SP
880 { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); }
882 /* ---------------------------------------------------------------------- */
884 | NOP
885 { B1 (0x00); }
887 /* ---------------------------------------------------------------------- */
889 | NOT1 CY
890 { B2 (0x71, 0xc0); }
892 /* ---------------------------------------------------------------------- */
894 | POP regw
895 { B1 (0xc0); F ($2, 5, 2); }
897 | POP PSW
898 { B2 (0x61, 0xcd); };
900 | PUSH regw
901 { B1 (0xc1); F ($2, 5, 2); }
903 | PUSH PSW
904 { B2 (0x61, 0xdd); };
906 /* ---------------------------------------------------------------------- */
908 | RET
909 { B1 (0xd7); }
911 | RETI
912 { B2 (0x61, 0xfc); }
914 | RETB
915 { B2 (0x61, 0xec); }
917 /* ---------------------------------------------------------------------- */
919 | ROL A ',' EXPR
920 { if (check_expr_is_const ($4, 1, 1))
921 { B2 (0x61, 0xeb); }
924 | ROLC A ',' EXPR
925 { if (check_expr_is_const ($4, 1, 1))
926 { B2 (0x61, 0xdc); }
929 | ROLWC AX ',' EXPR
930 { if (check_expr_is_const ($4, 1, 1))
931 { B2 (0x61, 0xee); }
934 | ROLWC BC ',' EXPR
935 { if (check_expr_is_const ($4, 1, 1))
936 { B2 (0x61, 0xfe); }
939 | ROR A ',' EXPR
940 { if (check_expr_is_const ($4, 1, 1))
941 { B2 (0x61, 0xdb); }
944 | RORC A ',' EXPR
945 { if (check_expr_is_const ($4, 1, 1))
946 { B2 (0x61, 0xfb);}
949 /* ---------------------------------------------------------------------- */
951 | SAR A ',' EXPR
952 { if (check_expr_is_const ($4, 1, 7))
953 { B2 (0x31, 0x0b); FE ($4, 9, 3); }
956 | SARW AX ',' EXPR
957 { if (check_expr_is_const ($4, 1, 15))
958 { B2 (0x31, 0x0f); FE ($4, 8, 4); }
961 /* ---------------------------------------------------------------------- */
963 | SEL RB0
964 { B2 (0x61, 0xcf); }
966 | SEL RB1
967 { B2 (0x61, 0xdf); }
969 | SEL RB2
970 { B2 (0x61, 0xef); }
972 | SEL RB3
973 { B2 (0x61, 0xff); }
975 /* ---------------------------------------------------------------------- */
977 | SHL A ',' EXPR
978 { if (check_expr_is_const ($4, 1, 7))
979 { B2 (0x31, 0x09); FE ($4, 9, 3); }
982 | SHL B ',' EXPR
983 { if (check_expr_is_const ($4, 1, 7))
984 { B2 (0x31, 0x08); FE ($4, 9, 3); }
987 | SHL C ',' EXPR
988 { if (check_expr_is_const ($4, 1, 7))
989 { B2 (0x31, 0x07); FE ($4, 9, 3); }
992 | SHLW AX ',' EXPR
993 { if (check_expr_is_const ($4, 1, 15))
994 { B2 (0x31, 0x0d); FE ($4, 8, 4); }
997 | SHLW BC ',' EXPR
998 { if (check_expr_is_const ($4, 1, 15))
999 { B2 (0x31, 0x0c); FE ($4, 8, 4); }
1002 /* ---------------------------------------------------------------------- */
1004 | SHR A ',' EXPR
1005 { if (check_expr_is_const ($4, 1, 7))
1006 { B2 (0x31, 0x0a); FE ($4, 9, 3); }
1009 | SHRW AX ',' EXPR
1010 { if (check_expr_is_const ($4, 1, 15))
1011 { B2 (0x31, 0x0e); FE ($4, 8, 4); }
1014 /* ---------------------------------------------------------------------- */
1016 | SKC
1017 { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
1019 | SKH
1020 { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
1022 | SKNC
1023 { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
1025 | SKNH
1026 { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
1028 | SKNZ
1029 { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
1031 | SKZ
1032 { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
1034 /* ---------------------------------------------------------------------- */
1036 | STOP
1037 { B2 (0x61, 0xfd); }
1039 /* ---------------------------------------------------------------------- */
1041 | XCH A ',' regb_na
1042 { if ($4 == 0) /* X */
1043 { B1 (0x08); }
1044 else
1045 { B2 (0x61, 0x88); F ($4, 13, 3); }
1048 | XCH A ',' opt_es '!' EXPR
1049 { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
1051 | XCH A ',' opt_es '[' DE ']'
1052 { B2 (0x61, 0xae); }
1054 | XCH A ',' opt_es '[' DE '+' EXPR ']'
1055 { B2 (0x61, 0xaf); O1 ($8); }
1057 | XCH A ',' opt_es '[' HL ']'
1058 { B2 (0x61, 0xac); }
1060 | XCH A ',' opt_es '[' HL '+' EXPR ']'
1061 { B2 (0x61, 0xad); O1 ($8); }
1063 | XCH A ',' opt_es '[' HL '+' B ']'
1064 { B2 (0x61, 0xb9); }
1066 | XCH A ',' opt_es '[' HL '+' C ']'
1067 { B2 (0x61, 0xa9); }
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;
1078 /* ---------------------------------------------------------------------- */
1080 | XCHW AX ',' regw_na
1081 { B1 (0x31); F ($4, 5, 2); }
1083 /* ---------------------------------------------------------------------- */
1085 ; /* end of statement */
1087 /* ---------------------------------------------------------------------- */
1089 opt_es : /* nothing */
1090 | ES ':'
1091 { rl78_prefix (0x11); }
1094 regb : X { $$ = 0; }
1095 | A { $$ = 1; }
1096 | C { $$ = 2; }
1097 | B { $$ = 3; }
1098 | E { $$ = 4; }
1099 | D { $$ = 5; }
1100 | L { $$ = 6; }
1101 | H { $$ = 7; }
1104 regb_na : X { $$ = 0; }
1105 | C { $$ = 2; }
1106 | B { $$ = 3; }
1107 | E { $$ = 4; }
1108 | D { $$ = 5; }
1109 | L { $$ = 6; }
1110 | H { $$ = 7; }
1113 regw : AX { $$ = 0; }
1114 | BC { $$ = 1; }
1115 | DE { $$ = 2; }
1116 | HL { $$ = 3; }
1119 regw_na : BC { $$ = 1; }
1120 | DE { $$ = 2; }
1121 | HL { $$ = 3; }
1124 sfr : SPL { $$ = 0xf8; }
1125 | SPH { $$ = 0xf9; }
1126 | PSW { $$ = 0xfa; }
1127 | CS { $$ = 0xfc; }
1128 | ES { $$ = 0xfd; }
1129 | PMC { $$ = 0xfe; }
1130 | MEM { $$ = 0xff; }
1133 /* ---------------------------------------------------------------------- */
1134 /* Shortcuts for groups of opcodes with common encodings. */
1136 addsub : ADD { $$ = 0x00; }
1137 | ADDC { $$ = 0x10; }
1138 | SUB { $$ = 0x20; }
1139 | SUBC { $$ = 0x30; }
1140 | CMP { $$ = 0x40; }
1141 | AND_ { $$ = 0x50; }
1142 | OR { $$ = 0x60; }
1143 | XOR { $$ = 0x70; }
1146 addsubw : ADDW { $$ = 0x00; }
1147 | SUBW { $$ = 0x20; }
1148 | CMPW { $$ = 0x40; }
1151 andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
1152 | OR1 { $$ = 0x06; rl78_bit_insn = 1;}
1153 | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
1156 bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1;}
1157 | BF { $$ = 0x04; rl78_bit_insn = 1; }
1158 | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
1161 setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
1162 | CLR1 { $$ = 1; rl78_bit_insn = 1; }
1165 oneclrb : ONEB { $$ = 0x00; }
1166 | CLRB { $$ = 0x10; }
1169 oneclrw : ONEW { $$ = 0x00; }
1170 | CLRW { $$ = 0x10; }
1173 incdec : INC { $$ = 0x00; }
1174 | DEC { $$ = 0x10; }
1177 incdecw : INCW { $$ = 0x00; }
1178 | DECW { $$ = 0x10; }
1181 mov1 : MOV1 { rl78_bit_insn = 1; }
1185 /* ====================================================================== */
1187 static struct
1189 const char * string;
1190 int token;
1191 int val;
1193 token_table[] =
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 },
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 },
1221 { "RB0", RB0, 0 },
1222 { "RB1", RB1, 1 },
1223 { "RB2", RB2, 2 },
1224 { "RB3", RB3, 3 },
1226 { "sp", SP, 0 },
1227 { "cy", CY, 0 },
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 },
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},
1245 { "c", FLAG, 0 },
1246 { "z", FLAG, 1 },
1247 { "s", FLAG, 2 },
1248 { "o", FLAG, 3 },
1249 { "i", FLAG, 8 },
1250 { "u", FLAG, 9 },
1252 #define OPC(x) { #x, x, IS_OPCODE }
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),
1299 OPC(NOT1),
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),
1338 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1340 void
1341 rl78_lex_init (char * beginning, char * ending)
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;
1349 rl78_bit_insn = 0;
1351 setbuf (stdout, 0);
1354 /* Return a pointer to the '.' in a bit index expression (like
1355 foo.5), or NULL if none is found. */
1356 static char *
1357 find_bit_index (char *tok)
1359 char *last_dot = NULL;
1360 char *last_digit = NULL;
1361 while (*tok && *tok != ',')
1363 if (*tok == '.')
1365 last_dot = tok;
1366 last_digit = NULL;
1368 else if (*tok >= '0' && *tok <= '7'
1369 && last_dot != NULL
1370 && last_digit == NULL)
1372 last_digit = tok;
1374 else if (ISSPACE (*tok))
1376 /* skip */
1378 else
1380 last_dot = NULL;
1381 last_digit = NULL;
1383 tok ++;
1385 if (last_dot != NULL
1386 && last_digit != NULL)
1387 return last_dot;
1388 return NULL;
1391 static int
1392 rl78_lex (void)
1394 /*unsigned int ci;*/
1395 char * save_input_pointer;
1396 char * bit = NULL;
1398 while (ISSPACE (*rl78_lex_start)
1399 && rl78_lex_start != rl78_lex_end)
1400 rl78_lex_start ++;
1402 rl78_last_exp_start = rl78_lex_start;
1404 if (rl78_lex_start == rl78_lex_end)
1405 return 0;
1407 if (ISALPHA (*rl78_lex_start)
1408 || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
1410 unsigned int i;
1411 char * e;
1412 char save;
1414 for (e = rl78_lex_start + 1;
1415 e < rl78_lex_end && ISALNUM (*e);
1416 e ++)
1418 save = *e;
1419 *e = 0;
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))
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;
1432 *e = save;
1435 if (rl78_last_token == 0)
1437 rl78_last_token = UNKNOWN_OPCODE;
1438 return UNKNOWN_OPCODE;
1441 if (rl78_last_token == UNKNOWN_OPCODE)
1442 return 0;
1444 if (*rl78_lex_start == '[')
1445 rl78_in_brackets = 1;
1446 if (*rl78_lex_start == ']')
1447 rl78_in_brackets = 0;
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. */
1453 if (rl78_bit_insn
1454 && *rl78_lex_start == '.'
1455 && find_bit_index (rl78_lex_start) == rl78_lex_start)
1457 rl78_last_token = *rl78_lex_start;
1458 return *rl78_lex_start ++;
1461 if ((rl78_in_brackets && *rl78_lex_start == '+')
1462 || strchr ("[],#!$:", *rl78_lex_start))
1464 rl78_last_token = *rl78_lex_start;
1465 return *rl78_lex_start ++;
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. */
1471 if (rl78_bit_insn)
1473 bit = find_bit_index (rl78_lex_start);
1474 if (bit)
1475 *bit = 0;
1476 else
1477 bit = NULL;
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);
1485 if (bit)
1486 *bit = '.';
1488 rl78_lex_start = input_line_pointer;
1489 input_line_pointer = save_input_pointer;
1490 rl78_last_token = EXPR;
1491 return EXPR;
1495 rl78_error (const char * str)
1497 int len;
1499 len = rl78_last_exp_start - rl78_init_start;
1501 as_bad ("%s", rl78_init_start);
1502 as_bad ("%*s^ %s", len, "", str);
1503 return 0;
1506 static int
1507 expr_is_sfr (expressionS exp)
1509 unsigned long v;
1511 if (exp.X_op != O_constant)
1512 return 0;
1514 v = exp.X_add_number;
1515 if (0xFFF00 <= v && v <= 0xFFFFF)
1516 return 1;
1517 return 0;
1520 static int
1521 expr_is_saddr (expressionS exp)
1523 unsigned long v;
1525 if (exp.X_op != O_constant)
1526 return 0;
1528 v = exp.X_add_number;
1529 if (0xFFE20 <= v && v <= 0xFFF1F)
1530 return 1;
1531 return 0;
1534 static int
1535 expr_is_word_aligned (expressionS exp)
1537 unsigned long v;
1539 if (exp.X_op != O_constant)
1540 return 1;
1542 v = exp.X_add_number;
1543 if (v & 1)
1544 return 0;
1545 return 1;
1549 static void
1550 check_expr_is_bit_index (expressionS exp)
1552 int val;
1554 if (exp.X_op != O_constant)
1556 rl78_error (_("bit index must be a constant"));
1557 return;
1559 val = exp.X_add_number;
1561 if (val < 0 || val > 7)
1562 rl78_error (_("rtsd size must be 0..7"));
1565 static int
1566 exp_val (expressionS exp)
1568 if (exp.X_op != O_constant)
1570 rl78_error (_("constant expected"));
1571 return 0;
1573 return exp.X_add_number;
1576 static int
1577 check_expr_is_const (expressionS e, int vmin, int vmax)
1579 static char buf[100];
1580 if (e.X_op != O_constant
1581 || e.X_add_number < vmin
1582 || e.X_add_number > vmax)
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;
1591 return 1;