OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [rl78-parse.y] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 163 khays
/* 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
 
27
static 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
 
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);
86
 
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 166 khays
static int    rl78_bit_insn = 0;
93 163 khays
 
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
 
109
static 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.  */
114
static 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.  */
118
static int
119
reg_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  regb regb_na regw regw_na FLAG sfr
145
%type  A X B C D E H L AX BC DE HL
146
%type  EXPR
147
 
148
%type  addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw
149
%type  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
169 166 khays
%token NOP NOT1
170 163 khays
%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
 
180
statement :
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
222 166 khays
          { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
223 163 khays
 
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
242 166 khays
              { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
243 163 khays
          }
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
257 166 khays
          { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
258 163 khays
 
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
340 166 khays
          { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
341 163 khays
 
342
        | BR '!' EXPR
343 166 khays
          { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
344 163 khays
 
345
        | BR '!' '!' EXPR
346 166 khays
          { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
347 163 khays
 
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
368 166 khays
          { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
369 163 khays
 
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
410 166 khays
          { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
411 163 khays
 
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
430 166 khays
          { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
431 163 khays
 
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
457 166 khays
          { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
458 163 khays
 
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
472 166 khays
          { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
473 163 khays
        | 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
489 166 khays
          { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
490 163 khays
 
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
557 166 khays
          { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
558 163 khays
 
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
578 166 khays
          { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
579 163 khays
 
580
        | MOV '!' EXPR ',' A
581 166 khays
          { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
582 163 khays
 
583
        | MOV ES ':' '!' EXPR ',' A
584
          { B2 (0x11, 0x9f); O2 ($5); }
585
 
586
        | MOV regb_na ',' opt_es '!' EXPR
587 166 khays
          { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
588 163 khays
 
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
 
716 166 khays
        | mov1 CY ',' EXPR '.' EXPR
717 163 khays
          { 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
 
725 166 khays
        | mov1 CY ',' A '.' EXPR
726 163 khays
          { B2 (0x71, 0x8c); FE ($6, 9, 3); }
727
 
728 166 khays
        | mov1 CY ',' sfr '.' EXPR
729 163 khays
          { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
730
 
731 166 khays
        | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
732 163 khays
          { B2 (0x71, 0x84); FE ($9, 9, 3); }
733
 
734 166 khays
        | mov1 EXPR '.' EXPR ',' CY
735 163 khays
          { 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
 
743 166 khays
        | mov1 A '.' EXPR ',' CY
744 163 khays
          { B2 (0x71, 0x89); FE ($4, 9, 3); }
745
 
746 166 khays
        | mov1 sfr '.' EXPR ',' CY
747 163 khays
          { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
748
 
749 166 khays
        | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
750 163 khays
          { 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
799 166 khays
          { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
800 163 khays
 
801
        | MOVW opt_es '!' EXPR ',' AX
802 166 khays
          { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
803 163 khays
 
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
868 166 khays
          { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
869 163 khays
 
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
 
887
/* ---------------------------------------------------------------------- */
888
 
889 166 khays
        | NOT1 CY
890
          { B2 (0x71, 0xc0); }
891
 
892
/* ---------------------------------------------------------------------- */
893
 
894 163 khays
        | 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
1017 166 khays
          { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
1018 163 khays
 
1019
        | SKH
1020 166 khays
          { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
1021 163 khays
 
1022
        | SKNC
1023 166 khays
          { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
1024 163 khays
 
1025
        | SKNH
1026 166 khays
          { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
1027 163 khays
 
1028
        | SKNZ
1029 166 khays
          { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
1030 163 khays
 
1031
        | SKZ
1032 166 khays
          { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
1033 163 khays
 
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
1049 166 khays
          { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
1050 163 khays
 
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
 
1089
opt_es  : /* nothing */
1090
        | ES ':'
1091
          { rl78_prefix (0x11); }
1092
        ;
1093
 
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; }
1102
        ;
1103
 
1104
regb_na : X { $$ = 0; }
1105
        | C { $$ = 2; }
1106
        | B { $$ = 3; }
1107
        | E { $$ = 4; }
1108
        | D { $$ = 5; }
1109
        | L { $$ = 6; }
1110
        | H { $$ = 7; }
1111
        ;
1112
 
1113
regw    : AX { $$ = 0; }
1114
        | BC { $$ = 1; }
1115
        | DE { $$ = 2; }
1116
        | HL { $$ = 3; }
1117
        ;
1118
 
1119
regw_na : BC { $$ = 1; }
1120
        | DE { $$ = 2; }
1121
        | HL { $$ = 3; }
1122
        ;
1123
 
1124
sfr     : 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
 
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; }
1144
        ;
1145
 
1146
addsubw : ADDW  { $$ = 0x00; }
1147
        | SUBW  { $$ = 0x20; }
1148
        | CMPW  { $$ = 0x40; }
1149
        ;
1150
 
1151 166 khays
andor1  : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
1152
        | OR1  { $$ = 0x06; rl78_bit_insn = 1;}
1153
        | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
1154 163 khays
        ;
1155
 
1156 166 khays
bt_bf   : BT { $$ = 0x02;    rl78_bit_insn = 1;}
1157
        | BF { $$ = 0x04;    rl78_bit_insn = 1; }
1158
        | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
1159 163 khays
        ;
1160
 
1161 166 khays
setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
1162
        | CLR1 { $$ = 1; rl78_bit_insn = 1; }
1163 163 khays
        ;
1164
 
1165
oneclrb : ONEB { $$ = 0x00; }
1166
        | CLRB { $$ = 0x10; }
1167
        ;
1168
 
1169
oneclrw : ONEW { $$ = 0x00; }
1170
        | CLRW { $$ = 0x10; }
1171
        ;
1172
 
1173
incdec  : INC { $$ = 0x00; }
1174
        | DEC { $$ = 0x10; }
1175
        ;
1176
 
1177
incdecw : INCW { $$ = 0x00; }
1178
        | DECW { $$ = 0x10; }
1179
        ;
1180
 
1181 166 khays
mov1    : MOV1 { rl78_bit_insn = 1; }
1182
        ;
1183
 
1184 163 khays
%%
1185
/* ====================================================================== */
1186
 
1187
static struct
1188
{
1189
  const char * string;
1190
  int          token;
1191
  int          val;
1192
}
1193
token_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),
1299 166 khays
  OPC(NOT1),
1300 163 khays
  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
 
1340
void
1341
rl78_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
 
1349 166 khays
  rl78_bit_insn = 0;
1350
 
1351 163 khays
  setbuf (stdout, 0);
1352
}
1353
 
1354 166 khays
/* 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)
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
 
1391 163 khays
static int
1392
rl78_lex (void)
1393
{
1394
  /*unsigned int ci;*/
1395
  char * save_input_pointer;
1396 166 khays
  char * bit = NULL;
1397 163 khays
 
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
 
1453 166 khays
  if (rl78_bit_insn
1454
      && *rl78_lex_start == '.'
1455
      && find_bit_index (rl78_lex_start) == rl78_lex_start)
1456 163 khays
    {
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
 
1468 166 khays
  /* Again, '.' is funny.  Look for '.' 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
 
1480 163 khays
  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
 
1485 166 khays
  if (bit)
1486
    *bit = '.';
1487
 
1488 163 khays
  rl78_lex_start = input_line_pointer;
1489
  input_line_pointer = save_input_pointer;
1490
  rl78_last_token = EXPR;
1491
  return EXPR;
1492
}
1493
 
1494
int
1495 166 khays
rl78_error (const char * str)
1496 163 khays
{
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
 
1506
static int
1507
expr_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
 
1520
static int
1521
expr_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
 
1534
static int
1535
expr_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
 
1549
static void
1550
check_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
 
1565
static int
1566
exp_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
 
1576
static int
1577
check_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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.