2011-11-21 Kwok Cheung Yeung <kcy@codesourcery.com>
[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;
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
168%token NOP
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
221 { B1 (0x0f|$1); O2 ($6); }
222
223 | addsub A ',' opt_es '[' HL ']'
224 { B1 (0x0d|$1); }
225
226 | addsub A ',' opt_es '[' HL '+' EXPR ']'
227 { B1 (0x0e|$1); O1 ($8); }
228
229 | addsub A ',' opt_es '[' HL '+' B ']'
230 { B2 (0x61, 0x80|$1); }
231
232 | addsub A ',' opt_es '[' HL '+' C ']'
233 { B2 (0x61, 0x82|$1); }
234
235
236
237 | addsub opt_es '!' EXPR ',' '#' EXPR
238 { if ($1 != 0x40)
239 { rl78_error ("Only CMP takes these operands"); }
240 else
241 { B1 (0x00|$1); O2 ($4); O1 ($7); }
242 }
243
244/* ---------------------------------------------------------------------- */
245
246 | addsubw AX ',' '#' EXPR
247 { B1 (0x04|$1); O2 ($5); }
248
249 | addsubw AX ',' regw
250 { B1 (0x01|$1); F ($4, 5, 2); }
251
252 | addsubw AX ',' EXPR {SA($4)}
253 { B1 (0x06|$1); O1 ($4); }
254
255 | addsubw AX ',' opt_es '!' EXPR
256 { B1 (0x02|$1); O2 ($6); }
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
339 { B1 (0xee); PC2 ($4); }
340
341 | BR '!' EXPR
342 { B1 (0xed); O2 ($3); }
343
344 | BR '!' '!' EXPR
345 { B1 (0xec); O3 ($4); }
346
347/* ---------------------------------------------------------------------- */
348
349 | BRK
350 { B2 (0x61, 0xcc); }
351
352 | BRK1
353 { B1 (0xff); }
354
355/* ---------------------------------------------------------------------- */
356
357 | CALL regw
358 { B2 (0x61, 0xca); F ($2, 10, 2); }
359
360 | CALL '$' '!' EXPR
361 { B1 (0xfe); PC2 ($4); }
362
363 | CALL '!' EXPR
364 { B1 (0xfd); O2 ($3); }
365
366 | CALL '!' '!' EXPR
367 { B1 (0xfc); O3 ($4); }
368
369 | CALLT '[' EXPR ']'
370 { if ($3.X_op != O_constant)
371 rl78_error ("CALLT requires a numeric address");
372 else
373 {
374 int i = $3.X_add_number;
375 if (i < 0x80 || i > 0xbe)
376 rl78_error ("CALLT address not 0x80..0xbe");
377 else if (i & 1)
378 rl78_error ("CALLT address not even");
379 else
380 {
381 B2 (0x61, 0x84);
382 F ((i >> 1) & 7, 9, 3);
383 F ((i >> 4) & 7, 14, 2);
384 }
385 }
386 }
387
388/* ---------------------------------------------------------------------- */
389
390 | setclr1 CY
391 { B2 (0x71, $1 ? 0x88 : 0x80); }
392
393 | setclr1 sfr '.' EXPR
394 { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); }
395
396 | setclr1 EXPR '.' EXPR
397 { if (expr_is_sfr ($2))
398 { B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); }
399 else if (expr_is_saddr ($2))
400 { B2 (0x71, 0x02|$1); FE ($4, 9, 3); O1 ($2); }
401 else
402 NOT_SFR_OR_SADDR;
403 }
404
405 | setclr1 A '.' EXPR
406 { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
407
408 | setclr1 opt_es '!' EXPR '.' EXPR
409 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); }
410
411 | setclr1 opt_es '[' HL ']' '.' EXPR
412 { B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
413
414/* ---------------------------------------------------------------------- */
415
416 | oneclrb A
417 { B1 (0xe1|$1); }
418 | oneclrb X
419 { B1 (0xe0|$1); }
420 | oneclrb B
421 { B1 (0xe3|$1); }
422 | oneclrb C
423 { B1 (0xe2|$1); }
424
425 | oneclrb EXPR {SA($2)}
426 { B1 (0xe4|$1); O1 ($2); }
427
428 | oneclrb opt_es '!' EXPR
429 { B1 (0xe5|$1); O2 ($4); }
430
431/* ---------------------------------------------------------------------- */
432
433 | oneclrw AX
434 { B1 (0xe6|$1); }
435 | oneclrw BC
436 { B1 (0xe7|$1); }
437
438/* ---------------------------------------------------------------------- */
439
440 | CMP0 A
441 { B1 (0xd1); }
442
443 | CMP0 X
444 { B1 (0xd0); }
445
446 | CMP0 B
447 { B1 (0xd3); }
448
449 | CMP0 C
450 { B1 (0xd2); }
451
452 | CMP0 EXPR {SA($2)}
453 { B1 (0xd4); O1 ($2); }
454
455 | CMP0 opt_es '!' EXPR
456 { B1 (0xd5); O2 ($4); }
457
458/* ---------------------------------------------------------------------- */
459
460 | CMPS X ',' opt_es '[' HL '+' EXPR ']'
461 { B2 (0x61, 0xde); O1 ($8); }
462
463/* ---------------------------------------------------------------------- */
464
465 | incdec regb
466 { B1 (0x80|$1); F ($2, 5, 3); }
467
468 | incdec EXPR {SA($2)}
469 { B1 (0xa4|$1); O1 ($2); }
470 | incdec '!' EXPR
471 { B1 (0xa0|$1); O2 ($3); }
472 | incdec ES ':' '!' EXPR
473 { B2 (0x11, 0xa0|$1); O2 ($5); }
474 | incdec '[' HL '+' EXPR ']'
475 { B2 (0x61, 0x59+$1); O1 ($5); }
476 | incdec ES ':' '[' HL '+' EXPR ']'
477 { B3 (0x11, 0x61, 0x59+$1); O1 ($7); }
478
479/* ---------------------------------------------------------------------- */
480
481 | incdecw regw
482 { B1 (0xa1|$1); F ($2, 5, 2); }
483
484 | incdecw EXPR {SA($2)}
485 { B1 (0xa6|$1); O1 ($2); }
486
487 | incdecw opt_es '!' EXPR
488 { B1 (0xa2|$1); O2 ($4); }
489
490 | incdecw opt_es '[' HL '+' EXPR ']'
491 { B2 (0x61, 0x79+$1); O1 ($6); }
492
493/* ---------------------------------------------------------------------- */
494
495 | DI
496 { B3 (0x71, 0x7b, 0xfa); }
497
498 | EI
499 { B3 (0x71, 0x7a, 0xfa); }
500
501/* ---------------------------------------------------------------------- */
502
503 | MULHU
504 { B3 (0xce, 0xfb, 0x01); }
505
506 | MULH
507 { B3 (0xce, 0xfb, 0x02); }
508
509 | MULU X
510 { B1 (0xd6); }
511
512 | DIVHU
513 { B3 (0xce, 0xfb, 0x03); }
514
515 | DIVWU
516 { B3 (0xce, 0xfb, 0x04); }
517
518 | MACHU
519 { B3 (0xce, 0xfb, 0x05); }
520
521 | MACH
522 { B3 (0xce, 0xfb, 0x06); }
523
524/* ---------------------------------------------------------------------- */
525
526 | HALT
527 { B2 (0x61, 0xed); }
528
529/* ---------------------------------------------------------------------- */
530/* Note that opt_es is included even when it's not an option, to avoid
531 shift/reduce conflicts. The NOT_ES macro produces an error if ES:
532 is given by the user. */
533
534 | MOV A ',' '#' EXPR
535 { B1 (0x51); O1 ($5); }
536 | MOV regb_na ',' '#' EXPR
537 { B1 (0x50); F($2, 5, 3); O1 ($5); }
538
539 | MOV sfr ',' '#' EXPR
540 { if ($2 != 0xfd)
541 { B2 (0xce, $2); O1 ($5); }
542 else
543 { B1 (0x41); O1 ($5); }
544 }
545
546 | MOV opt_es EXPR ',' '#' EXPR {NOT_ES}
547 { if (expr_is_sfr ($3))
548 { B1 (0xce); O1 ($3); O1 ($6); }
549 else if (expr_is_saddr ($3))
550 { B1 (0xcd); O1 ($3); O1 ($6); }
551 else
552 NOT_SFR_OR_SADDR;
553 }
554
555 | MOV '!' EXPR ',' '#' EXPR
556 { B1 (0xcf); O2 ($3); O1 ($6); }
557
558 | MOV ES ':' '!' EXPR ',' '#' EXPR
559 { B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
560
561 | MOV regb_na ',' A
562 { B1 (0x70); F ($2, 5, 3); }
563
564 | MOV A ',' regb_na
565 { B1 (0x60); F ($4, 5, 3); }
566
567 | MOV opt_es EXPR ',' A {NOT_ES}
568 { if (expr_is_sfr ($3))
569 { B1 (0x9e); O1 ($3); }
570 else if (expr_is_saddr ($3))
571 { B1 (0x9d); O1 ($3); }
572 else
573 NOT_SFR_OR_SADDR;
574 }
575
576 | MOV A ',' opt_es '!' EXPR
577 { B1 (0x8f); O2 ($6); }
578
579 | MOV '!' EXPR ',' A
580 { B1 (0x9f); O2 ($3); }
581
582 | MOV ES ':' '!' EXPR ',' A
583 { B2 (0x11, 0x9f); O2 ($5); }
584
585 | MOV regb_na ',' opt_es '!' EXPR
586 { B1 (0xc9|reg_xbc($2)); O2 ($6); }
587
588 | MOV A ',' opt_es EXPR {NOT_ES}
589 { if (expr_is_saddr ($5))
590 { B1 (0x8d); O1 ($5); }
591 else if (expr_is_sfr ($5))
592 { B1 (0x8e); O1 ($5); }
593 else
594 NOT_SFR_OR_SADDR;
595 }
596
597 | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
598 { B1 (0xc8|reg_xbc($2)); O1 ($5); }
599
600 | MOV A ',' sfr
601 { B2 (0x8e, $4); }
602
603 | MOV sfr ',' regb
604 { if ($4 != 1)
605 rl78_error ("Only A allowed here");
606 else
607 { B2 (0x9e, $2); }
608 }
609
610 | MOV sfr ',' opt_es EXPR {SA($5)} {NOT_ES}
611 { if ($2 != 0xfd)
612 rl78_error ("Only ES allowed here");
613 else
614 { B2 (0x61, 0xb8); O1 ($5); }
615 }
616
617 | MOV A ',' opt_es '[' DE ']'
618 { B1 (0x89); }
619
620 | MOV opt_es '[' DE ']' ',' A
621 { B1 (0x99); }
622
623 | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR
624 { B1 (0xca); O1 ($6); O1 ($10); }
625
626 | MOV A ',' opt_es '[' DE '+' EXPR ']'
627 { B1 (0x8a); O1 ($8); }
628
629 | MOV opt_es '[' DE '+' EXPR ']' ',' A
630 { B1 (0x9a); O1 ($6); }
631
632 | MOV A ',' opt_es '[' HL ']'
633 { B1 (0x8b); }
634
635 | MOV opt_es '[' HL ']' ',' A
636 { B1 (0x9b); }
637
638 | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR
639 { B1 (0xcc); O1 ($6); O1 ($10); }
640
641 | MOV A ',' opt_es '[' HL '+' EXPR ']'
642 { B1 (0x8c); O1 ($8); }
643
644 | MOV opt_es '[' HL '+' EXPR ']' ',' A
645 { B1 (0x9c); O1 ($6); }
646
647 | MOV A ',' opt_es '[' HL '+' B ']'
648 { B2 (0x61, 0xc9); }
649
650 | MOV opt_es '[' HL '+' B ']' ',' A
651 { B2 (0x61, 0xd9); }
652
653 | MOV A ',' opt_es '[' HL '+' C ']'
654 { B2 (0x61, 0xe9); }
655
656 | MOV opt_es '[' HL '+' C ']' ',' A
657 { B2 (0x61, 0xf9); }
658
659 | MOV opt_es EXPR '[' B ']' ',' '#' EXPR
660 { B1 (0x19); O2 ($3); O1 ($9); }
661
662 | MOV A ',' opt_es EXPR '[' B ']'
663 { B1 (0x09); O2 ($5); }
664
665 | MOV opt_es EXPR '[' B ']' ',' A
666 { B1 (0x18); O2 ($3); }
667
668 | MOV opt_es EXPR '[' C ']' ',' '#' EXPR
669 { B1 (0x38); O2 ($3); O1 ($9); }
670
671 | MOV A ',' opt_es EXPR '[' C ']'
672 { B1 (0x29); O2 ($5); }
673
674 | MOV opt_es EXPR '[' C ']' ',' A
675 { B1 (0x28); O2 ($3); }
676
677 | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR
678 { B1 (0x39); O2 ($3); O1 ($9); }
679
680 | MOV opt_es '[' BC ']' ',' '#' EXPR
681 { B3 (0x39, 0, 0); O1 ($8); }
682
683 | MOV A ',' opt_es EXPR '[' BC ']'
684 { B1 (0x49); O2 ($5); }
685
686 | MOV A ',' opt_es '[' BC ']'
687 { B3 (0x49, 0, 0); }
688
689 | MOV opt_es EXPR '[' BC ']' ',' A
690 { B1 (0x48); O2 ($3); }
691
692 | MOV opt_es '[' BC ']' ',' A
693 { B3 (0x48, 0, 0); }
694
695 | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES}
696 { B1 (0xc8); O1 ($6); O1 ($10); }
697
698 | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES}
699 { B2 (0xc8, 0); O1 ($8); }
700
701 | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
702 { B1 (0x88); O1 ($8); }
703
704 | MOV A ',' opt_es '[' SP ']' {NOT_ES}
705 { B2 (0x88, 0); }
706
707 | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES}
708 { B1 (0x98); O1 ($6); }
709
710 | MOV opt_es '[' SP ']' ',' A {NOT_ES}
711 { B2 (0x98, 0); }
712
713/* ---------------------------------------------------------------------- */
714
715 | MOV1 CY ',' EXPR '.' EXPR
716 { if (expr_is_saddr ($4))
717 { B2 (0x71, 0x04); FE ($6, 9, 3); O1 ($4); }
718 else if (expr_is_sfr ($4))
719 { B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); }
720 else
721 NOT_SFR_OR_SADDR;
722 }
723
724 | MOV1 CY ',' A '.' EXPR
725 { B2 (0x71, 0x8c); FE ($6, 9, 3); }
726
727 | MOV1 CY ',' sfr '.' EXPR
728 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
729
730 | MOV1 CY ',' opt_es '[' HL ']' '.' EXPR
731 { B2 (0x71, 0x84); FE ($9, 9, 3); }
732
733 | MOV1 EXPR '.' EXPR ',' CY
734 { if (expr_is_saddr ($2))
735 { B2 (0x71, 0x01); FE ($4, 9, 3); O1 ($2); }
736 else if (expr_is_sfr ($2))
737 { B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); }
738 else
739 NOT_SFR_OR_SADDR;
740 }
741
742 | MOV1 A '.' EXPR ',' CY
743 { B2 (0x71, 0x89); FE ($4, 9, 3); }
744
745 | MOV1 sfr '.' EXPR ',' CY
746 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
747
748 | MOV1 opt_es '[' HL ']' '.' EXPR ',' CY
749 { B2 (0x71, 0x81); FE ($7, 9, 3); }
750
751/* ---------------------------------------------------------------------- */
752
753 | MOVS opt_es '[' HL '+' EXPR ']' ',' X
754 { B2 (0x61, 0xce); O1 ($6); }
755
756/* ---------------------------------------------------------------------- */
757
758 | MOVW AX ',' '#' EXPR
759 { B1 (0x30); O2 ($5); }
760
761 | MOVW regw_na ',' '#' EXPR
762 { B1 (0x30); F ($2, 5, 2); O2 ($5); }
763
764 | MOVW opt_es EXPR ',' '#' EXPR {NOT_ES}
765 { if (expr_is_saddr ($3))
766 { B1 (0xc9); O1 ($3); O2 ($6); }
767 else if (expr_is_sfr ($3))
768 { B1 (0xcb); O1 ($3); O2 ($6); }
769 else
770 NOT_SFR_OR_SADDR;
771 }
772
773 | MOVW AX ',' opt_es EXPR {NOT_ES}
774 { if (expr_is_saddr ($5))
775 { B1 (0xad); O1 ($5); WA($5); }
776 else if (expr_is_sfr ($5))
777 { B1 (0xae); O1 ($5); WA($5); }
778 else
779 NOT_SFR_OR_SADDR;
780 }
781
782 | MOVW opt_es EXPR ',' AX {NOT_ES}
783 { if (expr_is_saddr ($3))
784 { B1 (0xbd); O1 ($3); WA($3); }
785 else if (expr_is_sfr ($3))
786 { B1 (0xbe); O1 ($3); WA($3); }
787 else
788 NOT_SFR_OR_SADDR;
789 }
790
791 | MOVW AX ',' regw_na
792 { B1 (0x11); F ($4, 5, 2); }
793
794 | MOVW regw_na ',' AX
795 { B1 (0x10); F ($2, 5, 2); }
796
797 | MOVW AX ',' opt_es '!' EXPR
798 { B1 (0xaf); O2 ($6); WA($6); }
799
800 | MOVW opt_es '!' EXPR ',' AX
801 { B1 (0xbf); O2 ($4); WA($4); }
802
803 | MOVW AX ',' opt_es '[' DE ']'
804 { B1 (0xa9); }
805
806 | MOVW opt_es '[' DE ']' ',' AX
807 { B1 (0xb9); }
808
809 | MOVW AX ',' opt_es '[' DE '+' EXPR ']'
810 { B1 (0xaa); O1 ($8); }
811
812 | MOVW opt_es '[' DE '+' EXPR ']' ',' AX
813 { B1 (0xba); O1 ($6); }
814
815 | MOVW AX ',' opt_es '[' HL ']'
816 { B1 (0xab); }
817
818 | MOVW opt_es '[' HL ']' ',' AX
819 { B1 (0xbb); }
820
821 | MOVW AX ',' opt_es '[' HL '+' EXPR ']'
822 { B1 (0xac); O1 ($8); }
823
824 | MOVW opt_es '[' HL '+' EXPR ']' ',' AX
825 { B1 (0xbc); O1 ($6); }
826
827 | MOVW AX ',' opt_es EXPR '[' B ']'
828 { B1 (0x59); O2 ($5); }
829
830 | MOVW opt_es EXPR '[' B ']' ',' AX
831 { B1 (0x58); O2 ($3); }
832
833 | MOVW AX ',' opt_es EXPR '[' C ']'
834 { B1 (0x69); O2 ($5); }
835
836 | MOVW opt_es EXPR '[' C ']' ',' AX
837 { B1 (0x68); O2 ($3); }
838
839 | MOVW AX ',' opt_es EXPR '[' BC ']'
840 { B1 (0x79); O2 ($5); }
841
842 | MOVW AX ',' opt_es '[' BC ']'
843 { B3 (0x79, 0, 0); }
844
845 | MOVW opt_es EXPR '[' BC ']' ',' AX
846 { B1 (0x78); O2 ($3); }
847
848 | MOVW opt_es '[' BC ']' ',' AX
849 { B3 (0x78, 0, 0); }
850
851 | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
852 { B1 (0xa8); O1 ($8); WA($8);}
853
854 | MOVW AX ',' opt_es '[' SP ']' {NOT_ES}
855 { B2 (0xa8, 0); }
856
857 | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES}
858 { B1 (0xb8); O1 ($6); WA($6); }
859
860 | MOVW opt_es '[' SP ']' ',' AX {NOT_ES}
861 { B2 (0xb8, 0); }
862
863 | MOVW regw_na ',' EXPR {SA($4)}
864 { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); }
865
866 | MOVW regw_na ',' opt_es '!' EXPR
867 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); }
868
869 | MOVW SP ',' '#' EXPR
870 { B2 (0xcb, 0xf8); O2 ($5); }
871
872 | MOVW SP ',' AX
873 { B2 (0xbe, 0xf8); }
874
875 | MOVW AX ',' SP
876 { B2 (0xae, 0xf8); }
877
878 | MOVW regw_na ',' SP
879 { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); }
880
881/* ---------------------------------------------------------------------- */
882
883 | NOP
884 { B1 (0x00); }
885
886/* ---------------------------------------------------------------------- */
887
888 | POP regw
889 { B1 (0xc0); F ($2, 5, 2); }
890
891 | POP PSW
892 { B2 (0x61, 0xcd); };
893
894 | PUSH regw
895 { B1 (0xc1); F ($2, 5, 2); }
896
897 | PUSH PSW
898 { B2 (0x61, 0xdd); };
899
900/* ---------------------------------------------------------------------- */
901
902 | RET
903 { B1 (0xd7); }
904
905 | RETI
906 { B2 (0x61, 0xfc); }
907
908 | RETB
909 { B2 (0x61, 0xec); }
910
911/* ---------------------------------------------------------------------- */
912
913 | ROL A ',' EXPR
914 { if (check_expr_is_const ($4, 1, 1))
915 { B2 (0x61, 0xeb); }
916 }
917
918 | ROLC A ',' EXPR
919 { if (check_expr_is_const ($4, 1, 1))
920 { B2 (0x61, 0xdc); }
921 }
922
923 | ROLWC AX ',' EXPR
924 { if (check_expr_is_const ($4, 1, 1))
925 { B2 (0x61, 0xee); }
926 }
927
928 | ROLWC BC ',' EXPR
929 { if (check_expr_is_const ($4, 1, 1))
930 { B2 (0x61, 0xfe); }
931 }
932
933 | ROR A ',' EXPR
934 { if (check_expr_is_const ($4, 1, 1))
935 { B2 (0x61, 0xdb); }
936 }
937
938 | RORC A ',' EXPR
939 { if (check_expr_is_const ($4, 1, 1))
940 { B2 (0x61, 0xfb);}
941 }
942
943/* ---------------------------------------------------------------------- */
944
945 | SAR A ',' EXPR
946 { if (check_expr_is_const ($4, 1, 7))
947 { B2 (0x31, 0x0b); FE ($4, 9, 3); }
948 }
949
950 | SARW AX ',' EXPR
951 { if (check_expr_is_const ($4, 1, 15))
952 { B2 (0x31, 0x0f); FE ($4, 8, 4); }
953 }
954
955/* ---------------------------------------------------------------------- */
956
957 | SEL RB0
958 { B2 (0x61, 0xcf); }
959
960 | SEL RB1
961 { B2 (0x61, 0xdf); }
962
963 | SEL RB2
964 { B2 (0x61, 0xef); }
965
966 | SEL RB3
967 { B2 (0x61, 0xff); }
968
969/* ---------------------------------------------------------------------- */
970
971 | SHL A ',' EXPR
972 { if (check_expr_is_const ($4, 1, 7))
973 { B2 (0x31, 0x09); FE ($4, 9, 3); }
974 }
975
976 | SHL B ',' EXPR
977 { if (check_expr_is_const ($4, 1, 7))
978 { B2 (0x31, 0x08); FE ($4, 9, 3); }
979 }
980
981 | SHL C ',' EXPR
982 { if (check_expr_is_const ($4, 1, 7))
983 { B2 (0x31, 0x07); FE ($4, 9, 3); }
984 }
985
986 | SHLW AX ',' EXPR
987 { if (check_expr_is_const ($4, 1, 15))
988 { B2 (0x31, 0x0d); FE ($4, 8, 4); }
989 }
990
991 | SHLW BC ',' EXPR
992 { if (check_expr_is_const ($4, 1, 15))
993 { B2 (0x31, 0x0c); FE ($4, 8, 4); }
994 }
995
996/* ---------------------------------------------------------------------- */
997
998 | SHR A ',' EXPR
999 { if (check_expr_is_const ($4, 1, 7))
1000 { B2 (0x31, 0x0a); FE ($4, 9, 3); }
1001 }
1002
1003 | SHRW AX ',' EXPR
1004 { if (check_expr_is_const ($4, 1, 15))
1005 { B2 (0x31, 0x0e); FE ($4, 8, 4); }
1006 }
1007
1008/* ---------------------------------------------------------------------- */
1009
1010 | SKC
1011 { B2 (0x61, 0xc8); }
1012
1013 | SKH
1014 { B2 (0x61, 0xe3); }
1015
1016 | SKNC
1017 { B2 (0x61, 0xd8); }
1018
1019 | SKNH
1020 { B2 (0x61, 0xf3); }
1021
1022 | SKNZ
1023 { B2 (0x61, 0xf8); }
1024
1025 | SKZ
1026 { B2 (0x61, 0xe8); }
1027
1028/* ---------------------------------------------------------------------- */
1029
1030 | STOP
1031 { B2 (0x61, 0xfd); }
1032
1033/* ---------------------------------------------------------------------- */
1034
1035 | XCH A ',' regb_na
1036 { if ($4 == 0) /* X */
1037 { B1 (0x08); }
1038 else
1039 { B2 (0x61, 0x88); F ($4, 13, 3); }
1040 }
1041
1042 | XCH A ',' opt_es '!' EXPR
1043 { B2 (0x61, 0xaa); O2 ($6); }
1044
1045 | XCH A ',' opt_es '[' DE ']'
1046 { B2 (0x61, 0xae); }
1047
1048 | XCH A ',' opt_es '[' DE '+' EXPR ']'
1049 { B2 (0x61, 0xaf); O1 ($8); }
1050
1051 | XCH A ',' opt_es '[' HL ']'
1052 { B2 (0x61, 0xac); }
1053
1054 | XCH A ',' opt_es '[' HL '+' EXPR ']'
1055 { B2 (0x61, 0xad); O1 ($8); }
1056
1057 | XCH A ',' opt_es '[' HL '+' B ']'
1058 { B2 (0x61, 0xb9); }
1059
1060 | XCH A ',' opt_es '[' HL '+' C ']'
1061 { B2 (0x61, 0xa9); }
1062
1063 | XCH A ',' EXPR
1064 { if (expr_is_sfr ($4))
1065 { B2 (0x61, 0xab); O1 ($4); }
1066 else if (expr_is_saddr ($4))
1067 { B2 (0x61, 0xa8); O1 ($4); }
1068 else
1069 NOT_SFR_OR_SADDR;
1070 }
1071
1072/* ---------------------------------------------------------------------- */
1073
1074 | XCHW AX ',' regw_na
1075 { B1 (0x31); F ($4, 5, 2); }
1076
1077/* ---------------------------------------------------------------------- */
1078
1079 ; /* end of statement */
1080
1081/* ---------------------------------------------------------------------- */
1082
1083opt_es : /* nothing */
1084 | ES ':'
1085 { rl78_prefix (0x11); }
1086 ;
1087
1088regb : X { $$ = 0; }
1089 | A { $$ = 1; }
1090 | C { $$ = 2; }
1091 | B { $$ = 3; }
1092 | E { $$ = 4; }
1093 | D { $$ = 5; }
1094 | L { $$ = 6; }
1095 | H { $$ = 7; }
1096 ;
1097
1098regb_na : X { $$ = 0; }
1099 | C { $$ = 2; }
1100 | B { $$ = 3; }
1101 | E { $$ = 4; }
1102 | D { $$ = 5; }
1103 | L { $$ = 6; }
1104 | H { $$ = 7; }
1105 ;
1106
1107regw : AX { $$ = 0; }
1108 | BC { $$ = 1; }
1109 | DE { $$ = 2; }
1110 | HL { $$ = 3; }
1111 ;
1112
1113regw_na : BC { $$ = 1; }
1114 | DE { $$ = 2; }
1115 | HL { $$ = 3; }
1116 ;
1117
1118sfr : SPL { $$ = 0xf8; }
1119 | SPH { $$ = 0xf9; }
1120 | PSW { $$ = 0xfa; }
1121 | CS { $$ = 0xfc; }
1122 | ES { $$ = 0xfd; }
1123 | PMC { $$ = 0xfe; }
1124 | MEM { $$ = 0xff; }
1125 ;
1126
1127/* ---------------------------------------------------------------------- */
1128/* Shortcuts for groups of opcodes with common encodings. */
1129
1130addsub : ADD { $$ = 0x00; }
1131 | ADDC { $$ = 0x10; }
1132 | SUB { $$ = 0x20; }
1133 | SUBC { $$ = 0x30; }
1134 | CMP { $$ = 0x40; }
1135 | AND_ { $$ = 0x50; }
1136 | OR { $$ = 0x60; }
1137 | XOR { $$ = 0x70; }
1138 ;
1139
1140addsubw : ADDW { $$ = 0x00; }
1141 | SUBW { $$ = 0x20; }
1142 | CMPW { $$ = 0x40; }
1143 ;
1144
1145andor1 : AND1 { $$ = 0x05; }
1146 | OR1 { $$ = 0x06; }
1147 | XOR1 { $$ = 0x07; }
1148 ;
1149
1150bt_bf : BT { $$ = 0x02; }
1151 | BF { $$ = 0x04; }
1152 | BTCLR { $$ = 0x00; }
1153 ;
1154
1155setclr1 : SET1 { $$ = 0; }
1156 | CLR1 { $$ = 1; }
1157 ;
1158
1159oneclrb : ONEB { $$ = 0x00; }
1160 | CLRB { $$ = 0x10; }
1161 ;
1162
1163oneclrw : ONEW { $$ = 0x00; }
1164 | CLRW { $$ = 0x10; }
1165 ;
1166
1167incdec : INC { $$ = 0x00; }
1168 | DEC { $$ = 0x10; }
1169 ;
1170
1171incdecw : INCW { $$ = 0x00; }
1172 | DECW { $$ = 0x10; }
1173 ;
1174
1175%%
1176/* ====================================================================== */
1177
1178static struct
1179{
1180 const char * string;
1181 int token;
1182 int val;
1183}
1184token_table[] =
1185{
1186 { "r0", X, 0 },
1187 { "r1", A, 1 },
1188 { "r2", C, 2 },
1189 { "r3", B, 3 },
1190 { "r4", E, 4 },
1191 { "r5", D, 5 },
1192 { "r6", L, 6 },
1193 { "r7", H, 7 },
1194 { "x", X, 0 },
1195 { "a", A, 1 },
1196 { "c", C, 2 },
1197 { "b", B, 3 },
1198 { "e", E, 4 },
1199 { "d", D, 5 },
1200 { "l", L, 6 },
1201 { "h", H, 7 },
1202
1203 { "rp0", AX, 0 },
1204 { "rp1", BC, 1 },
1205 { "rp2", DE, 2 },
1206 { "rp3", HL, 3 },
1207 { "ax", AX, 0 },
1208 { "bc", BC, 1 },
1209 { "de", DE, 2 },
1210 { "hl", HL, 3 },
1211
1212 { "RB0", RB0, 0 },
1213 { "RB1", RB1, 1 },
1214 { "RB2", RB2, 2 },
1215 { "RB3", RB3, 3 },
1216
1217 { "sp", SP, 0 },
1218 { "cy", CY, 0 },
1219
1220 { "spl", SPL, 0xf8 },
1221 { "sph", SPH, 0xf9 },
1222 { "psw", PSW, 0xfa },
1223 { "cs", CS, 0xfc },
1224 { "es", ES, 0xfd },
1225 { "pmc", PMC, 0xfe },
1226 { "mem", MEM, 0xff },
1227
1228 { ".s", DOT_S, 0 },
1229 { ".b", DOT_B, 0 },
1230 { ".w", DOT_W, 0 },
1231 { ".l", DOT_L, 0 },
1232 { ".a", DOT_A , 0},
1233 { ".ub", DOT_UB, 0 },
1234 { ".uw", DOT_UW , 0},
1235
1236 { "c", FLAG, 0 },
1237 { "z", FLAG, 1 },
1238 { "s", FLAG, 2 },
1239 { "o", FLAG, 3 },
1240 { "i", FLAG, 8 },
1241 { "u", FLAG, 9 },
1242
1243#define OPC(x) { #x, x, IS_OPCODE }
1244
1245 OPC(ADD),
1246 OPC(ADDC),
1247 OPC(ADDW),
1248 { "and", AND_, IS_OPCODE },
1249 OPC(AND1),
1250 OPC(BC),
1251 OPC(BF),
1252 OPC(BH),
1253 OPC(BNC),
1254 OPC(BNH),
1255 OPC(BNZ),
1256 OPC(BR),
1257 OPC(BRK),
1258 OPC(BRK1),
1259 OPC(BT),
1260 OPC(BTCLR),
1261 OPC(BZ),
1262 OPC(CALL),
1263 OPC(CALLT),
1264 OPC(CLR1),
1265 OPC(CLRB),
1266 OPC(CLRW),
1267 OPC(CMP),
1268 OPC(CMP0),
1269 OPC(CMPS),
1270 OPC(CMPW),
1271 OPC(DEC),
1272 OPC(DECW),
1273 OPC(DI),
1274 OPC(DIVHU),
1275 OPC(DIVWU),
1276 OPC(EI),
1277 OPC(HALT),
1278 OPC(INC),
1279 OPC(INCW),
1280 OPC(MACH),
1281 OPC(MACHU),
1282 OPC(MOV),
1283 OPC(MOV1),
1284 OPC(MOVS),
1285 OPC(MOVW),
1286 OPC(MULH),
1287 OPC(MULHU),
1288 OPC(MULU),
1289 OPC(NOP),
1290 OPC(ONEB),
1291 OPC(ONEW),
1292 OPC(OR),
1293 OPC(OR1),
1294 OPC(POP),
1295 OPC(PUSH),
1296 OPC(RET),
1297 OPC(RETI),
1298 OPC(RETB),
1299 OPC(ROL),
1300 OPC(ROLC),
1301 OPC(ROLWC),
1302 OPC(ROR),
1303 OPC(RORC),
1304 OPC(SAR),
1305 OPC(SARW),
1306 OPC(SEL),
1307 OPC(SET1),
1308 OPC(SHL),
1309 OPC(SHLW),
1310 OPC(SHR),
1311 OPC(SHRW),
1312 OPC(SKC),
1313 OPC(SKH),
1314 OPC(SKNC),
1315 OPC(SKNH),
1316 OPC(SKNZ),
1317 OPC(SKZ),
1318 OPC(STOP),
1319 OPC(SUB),
1320 OPC(SUBC),
1321 OPC(SUBW),
1322 OPC(XCH),
1323 OPC(XCHW),
1324 OPC(XOR),
1325 OPC(XOR1),
1326};
1327
1328#define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1329
1330void
1331rl78_lex_init (char * beginning, char * ending)
1332{
1333 rl78_init_start = beginning;
1334 rl78_lex_start = beginning;
1335 rl78_lex_end = ending;
1336 rl78_in_brackets = 0;
1337 rl78_last_token = 0;
1338
1339 setbuf (stdout, 0);
1340}
1341
1342static int
1343rl78_lex (void)
1344{
1345 /*unsigned int ci;*/
1346 char * save_input_pointer;
1347
1348 while (ISSPACE (*rl78_lex_start)
1349 && rl78_lex_start != rl78_lex_end)
1350 rl78_lex_start ++;
1351
1352 rl78_last_exp_start = rl78_lex_start;
1353
1354 if (rl78_lex_start == rl78_lex_end)
1355 return 0;
1356
1357 if (ISALPHA (*rl78_lex_start)
1358 || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
1359 {
1360 unsigned int i;
1361 char * e;
1362 char save;
1363
1364 for (e = rl78_lex_start + 1;
1365 e < rl78_lex_end && ISALNUM (*e);
1366 e ++)
1367 ;
1368 save = *e;
1369 *e = 0;
1370
1371 for (i = 0; i < NUM_TOKENS; i++)
1372 if (strcasecmp (rl78_lex_start, token_table[i].string) == 0
1373 && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0)
1374 && !(token_table[i].token == FLAG && !need_flag))
1375 {
1376 rl78_lval.regno = token_table[i].val;
1377 *e = save;
1378 rl78_lex_start = e;
1379 rl78_last_token = token_table[i].token;
1380 return token_table[i].token;
1381 }
1382 *e = save;
1383 }
1384
1385 if (rl78_last_token == 0)
1386 {
1387 rl78_last_token = UNKNOWN_OPCODE;
1388 return UNKNOWN_OPCODE;
1389 }
1390
1391 if (rl78_last_token == UNKNOWN_OPCODE)
1392 return 0;
1393
1394 if (*rl78_lex_start == '[')
1395 rl78_in_brackets = 1;
1396 if (*rl78_lex_start == ']')
1397 rl78_in_brackets = 0;
1398
1399 /* '.' is funny - the syntax includes it for bitfields, but only for
1400 bitfields. We check for it specially so we can allow labels
1401 with '.' in them. */
1402
1403 if (*rl78_lex_start == '.'
1404 && ISDIGIT (rl78_lex_start[1])
1405 && (rl78_last_token == ']'
1406 || rl78_last_token == A
1407 || rl78_last_token == PSW
1408 || rl78_last_token == EXPR))
1409 {
1410 rl78_last_token = *rl78_lex_start;
1411 return *rl78_lex_start ++;
1412 }
1413
1414 if ((rl78_in_brackets && *rl78_lex_start == '+')
1415 || strchr ("[],#!$:", *rl78_lex_start))
1416 {
1417 rl78_last_token = *rl78_lex_start;
1418 return *rl78_lex_start ++;
1419 }
1420
1421 save_input_pointer = input_line_pointer;
1422 input_line_pointer = rl78_lex_start;
1423 rl78_lval.exp.X_md = 0;
1424 expression (&rl78_lval.exp);
1425
1426 rl78_lex_start = input_line_pointer;
1427 input_line_pointer = save_input_pointer;
1428 rl78_last_token = EXPR;
1429 return EXPR;
1430}
1431
1432int
1433rl78_error (char * str)
1434{
1435 int len;
1436
1437 len = rl78_last_exp_start - rl78_init_start;
1438
1439 as_bad ("%s", rl78_init_start);
1440 as_bad ("%*s^ %s", len, "", str);
1441 return 0;
1442}
1443
1444static int
1445expr_is_sfr (expressionS exp)
1446{
1447 unsigned long v;
1448
1449 if (exp.X_op != O_constant)
1450 return 0;
1451
1452 v = exp.X_add_number;
1453 if (0xFFF00 <= v && v <= 0xFFFFF)
1454 return 1;
1455 return 0;
1456}
1457
1458static int
1459expr_is_saddr (expressionS exp)
1460{
1461 unsigned long v;
1462
1463 if (exp.X_op != O_constant)
1464 return 0;
1465
1466 v = exp.X_add_number;
1467 if (0xFFE20 <= v && v <= 0xFFF1F)
1468 return 1;
1469 return 0;
1470}
1471
1472static int
1473expr_is_word_aligned (expressionS exp)
1474{
1475 unsigned long v;
1476
1477 if (exp.X_op != O_constant)
1478 return 1;
1479
1480 v = exp.X_add_number;
1481 if (v & 1)
1482 return 0;
1483 return 1;
1484
1485}
1486
1487static void
1488check_expr_is_bit_index (expressionS exp)
1489{
1490 int val;
1491
1492 if (exp.X_op != O_constant)
1493 {
1494 rl78_error (_("bit index must be a constant"));
1495 return;
1496 }
1497 val = exp.X_add_number;
1498
1499 if (val < 0 || val > 7)
1500 rl78_error (_("rtsd size must be 0..7"));
1501}
1502
1503static int
1504exp_val (expressionS exp)
1505{
1506 if (exp.X_op != O_constant)
1507 {
1508 rl78_error (_("constant expected"));
1509 return 0;
1510 }
1511 return exp.X_add_number;
1512}
1513
1514static int
1515check_expr_is_const (expressionS e, int vmin, int vmax)
1516{
1517 static char buf[100];
1518 if (e.X_op != O_constant
1519 || e.X_add_number < vmin
1520 || e.X_add_number > vmax)
1521 {
1522 if (vmin == vmax)
1523 sprintf (buf, "%d expected here", vmin);
1524 else
1525 sprintf (buf, "%d..%d expected here", vmin, vmax);
1526 rl78_error(buf);
1527 return 0;
1528 }
1529 return 1;
1530}
1531
1532
This page took 0.084077 seconds and 4 git commands to generate.