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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 16 khays
/* rx-parse.y  Renesas RX parser
2
   Copyright 2008, 2009
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 "rx-defs.h"
26
 
27
static int rx_lex (void);
28
 
29
#define COND_EQ 0
30
#define COND_NE 1
31
 
32
#define MEMEX 0x06
33
 
34
#define BSIZE 0
35
#define WSIZE 1
36
#define LSIZE 2
37
 
38
/*                       .sb    .sw    .l     .uw   */
39
static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE };
40
 
41
/* Ok, here are the rules for using these macros...
42
 
43
   B*() is used to specify the base opcode bytes.  Fields to be filled
44
        in later, leave zero.  Call this first.
45
 
46
   F() and FE() are used to fill in fields within the base opcode bytes.  You MUST
47
        call B*() before any F() or FE().
48
 
49
   [UN]*O*(), PC*() appends operands to the end of the opcode.  You
50
        must call P() and B*() before any of these, so that the fixups
51
        have the right byte location.
52
        O = signed, UO = unsigned, NO = negated, PC = pcrel
53
 
54
   IMM() adds an immediate and fills in the field for it.
55
   NIMM() same, but negates the immediate.
56
   NBIMM() same, but negates the immediate, for sbb.
57
   DSP() adds a displacement, and fills in the field for it.
58
 
59
   Note that order is significant for the O, IMM, and DSP macros, as
60
   they append their data to the operand buffer in the order that you
61
   call them.
62
 
63
   Use "disp" for displacements whenever possible; this handles the
64
   "0" case properly.  */
65
 
66
#define B1(b1)             rx_base1 (b1)
67
#define B2(b1, b2)         rx_base2 (b1, b2)
68
#define B3(b1, b2, b3)     rx_base3 (b1, b2, b3)
69
#define B4(b1, b2, b3, b4) rx_base4 (b1, b2, b3, b4)
70
 
71
/* POS is bits from the MSB of the first byte to the LSB of the last byte.  */
72
#define F(val,pos,sz)      rx_field (val, pos, sz)
73
#define FE(exp,pos,sz)     rx_field (exp_val (exp), pos, sz);
74
 
75
#define O1(v)              rx_op (v, 1, RXREL_SIGNED)
76
#define O2(v)              rx_op (v, 2, RXREL_SIGNED)
77
#define O3(v)              rx_op (v, 3, RXREL_SIGNED)
78
#define O4(v)              rx_op (v, 4, RXREL_SIGNED)
79
 
80
#define UO1(v)             rx_op (v, 1, RXREL_UNSIGNED)
81
#define UO2(v)             rx_op (v, 2, RXREL_UNSIGNED)
82
#define UO3(v)             rx_op (v, 3, RXREL_UNSIGNED)
83
#define UO4(v)             rx_op (v, 4, RXREL_UNSIGNED)
84
 
85
#define NO1(v)             rx_op (v, 1, RXREL_NEGATIVE)
86
#define NO2(v)             rx_op (v, 2, RXREL_NEGATIVE)
87
#define NO3(v)             rx_op (v, 3, RXREL_NEGATIVE)
88
#define NO4(v)             rx_op (v, 4, RXREL_NEGATIVE)
89
 
90
#define PC1(v)             rx_op (v, 1, RXREL_PCREL)
91
#define PC2(v)             rx_op (v, 2, RXREL_PCREL)
92
#define PC3(v)             rx_op (v, 3, RXREL_PCREL)
93
 
94
#define IMM(v,pos)         F (immediate (v, RXREL_SIGNED, pos), pos, 2); \
95
                           if (v.X_op != O_constant && v.X_op != O_big) rx_linkrelax_imm (pos)
96
#define NIMM(v,pos)        F (immediate (v, RXREL_NEGATIVE, pos), pos, 2)
97
#define NBIMM(v,pos)       F (immediate (v, RXREL_NEGATIVE_BORROW, pos), pos, 2)
98
#define DSP(v,pos,msz)     if (!v.X_md) rx_relax (RX_RELAX_DISP, pos); \
99
                           else rx_linkrelax_dsp (pos); \
100
                           F (displacement (v, msz), pos, 2)
101
 
102
#define id24(a,b2,b3)      B3 (0xfb+a, b2, b3)
103
 
104
static int         rx_intop (expressionS, int);
105
static int         rx_uintop (expressionS, int);
106
static int         rx_disp3op (expressionS);
107
static int         rx_disp5op (expressionS *, int);
108
static int         rx_disp5op0 (expressionS *, int);
109
static int         exp_val (expressionS exp);
110
static expressionS zero_expr (void);
111
static int         immediate (expressionS, int, int);
112
static int         displacement (expressionS, int);
113
static void        rtsd_immediate (expressionS);
114
 
115
static int    need_flag = 0;
116
static int    rx_in_brackets = 0;
117
static int    rx_last_token = 0;
118
static char * rx_init_start;
119
static char * rx_last_exp_start = 0;
120
static int    sub_op;
121
static int    sub_op2;
122
 
123
#define YYDEBUG 1
124
#define YYERROR_VERBOSE 1
125
 
126
%}
127
 
128
%name-prefix="rx_"
129
 
130
%union {
131
  int regno;
132
  expressionS exp;
133
}
134
 
135
%type  REG FLAG CREG BCND BMCND SCCND
136
%type  flag bwl bw memex
137
%type  EXPR disp
138
 
139
%token REG FLAG CREG
140
 
141
%token EXPR UNKNOWN_OPCODE IS_OPCODE
142
 
143
%token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
144
 
145
%token ABS ADC ADD AND_
146
%token BCLR BCND BMCND BNOT BRA BRK BSET BSR BTST
147
%token CLRPSW CMP
148
%token DBT DIV DIVU
149
%token EDIV EDIVU EMUL EMULU
150
%token FADD FCMP FDIV FMUL FREIT FSUB FTOI
151
%token INT ITOF
152
%token JMP JSR
153
%token MACHI MACLO MAX MIN MOV MOVU MUL MULHI MULLO MULU MVFACHI MVFACMI MVFACLO
154
%token   MVFC MVTACHI MVTACLO MVTC MVTIPL
155
%token NEG NOP NOT
156
%token OR
157
%token POP POPC POPM PUSH PUSHA PUSHC PUSHM
158
%token RACW REIT REVL REVW RMPA ROLC RORC ROTL ROTR ROUND RTE RTFI RTS RTSD
159
%token SAT SATR SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF
160
%token   SMOVU SSTR STNZ STOP STZ SUB SUNTIL SWHILE
161
%token TST
162
%token WAIT
163
%token XCHG XOR
164
 
165
%%
166
/* ====================================================================== */
167
 
168
statement :
169
 
170
          UNKNOWN_OPCODE
171
          { as_bad (_("Unknown opcode: %s"), rx_init_start); }
172
 
173
/* ---------------------------------------------------------------------- */
174
 
175
        | BRK
176
          { B1 (0x00); }
177
 
178
        | DBT
179
          { B1 (0x01); }
180
 
181
        | RTS
182
          { B1 (0x02); }
183
 
184
        | NOP
185
          { B1 (0x03); }
186
 
187
/* ---------------------------------------------------------------------- */
188
 
189
        | BRA EXPR
190
          { if (rx_disp3op ($2))
191
              { B1 (0x08); rx_disp3 ($2, 5); }
192
            else if (rx_intop ($2, 8))
193
              { B1 (0x2e); PC1 ($2); }
194
            else if (rx_intop ($2, 16))
195
              { B1 (0x38); PC2 ($2); }
196
            else if (rx_intop ($2, 24))
197
              { B1 (0x04); PC3 ($2); }
198
            else
199
              { rx_relax (RX_RELAX_BRANCH, 0);
200
                rx_linkrelax_branch ();
201
                /* We'll convert this to a longer one later if needed.  */
202
                B1 (0x08); rx_disp3 ($2, 5); } }
203
 
204
        | BRA DOT_A EXPR
205
          { B1 (0x04); PC3 ($3); }
206
 
207
        | BRA DOT_S EXPR
208
          { B1 (0x08); rx_disp3 ($3, 5); }
209
 
210
/* ---------------------------------------------------------------------- */
211
 
212
        | BSR EXPR
213
          { if (rx_intop ($2, 16))
214
              { B1 (0x39); PC2 ($2); }
215
            else if (rx_intop ($2, 24))
216
              { B1 (0x05); PC3 ($2); }
217
            else
218
              { rx_relax (RX_RELAX_BRANCH, 0);
219
                rx_linkrelax_branch ();
220
                B1 (0x39); PC2 ($2); } }
221
        | BSR DOT_A EXPR
222
          { B1 (0x05), PC3 ($3); }
223
 
224
/* ---------------------------------------------------------------------- */
225
 
226
        | BCND DOT_S EXPR
227
          { if ($1 == COND_EQ || $1 == COND_NE)
228
              { B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($3, 5); }
229
            else
230
              as_bad (_("Only BEQ and BNE may have .S")); }
231
 
232
/* ---------------------------------------------------------------------- */
233
 
234
        | BCND DOT_B EXPR
235
          { B1 (0x20); F ($1, 4, 4); PC1 ($3); }
236
 
237
        | BRA DOT_B EXPR
238
          { B1 (0x2e), PC1 ($3); }
239
 
240
/* ---------------------------------------------------------------------- */
241
 
242
        | BRA DOT_W EXPR
243
          { B1 (0x38), PC2 ($3); }
244
        | BSR DOT_W EXPR
245
          { B1 (0x39), PC2 ($3); }
246
        | BCND DOT_W EXPR
247
          { if ($1 == COND_EQ || $1 == COND_NE)
248
              { B1 ($1 == COND_EQ ? 0x3a : 0x3b); PC2 ($3); }
249
            else
250
              as_bad (_("Only BEQ and BNE may have .W")); }
251
        | BCND EXPR
252
          { if ($1 == COND_EQ || $1 == COND_NE)
253
              {
254
                rx_relax (RX_RELAX_BRANCH, 0);
255
                rx_linkrelax_branch ();
256
                B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($2, 5);
257
              }
258
            else
259
              {
260
                rx_relax (RX_RELAX_BRANCH, 0);
261
                /* This is because we might turn it into a
262
                   jump-over-jump long branch.  */
263
                rx_linkrelax_branch ();
264
                B1 (0x20); F ($1, 4, 4); PC1 ($2);
265
              } }
266
 
267
/* ---------------------------------------------------------------------- */
268
 
269
        | MOV DOT_B '#' EXPR ',' disp '[' REG ']'
270
          /* rx_disp5op changes the value if it succeeds, so keep it last.  */
271
          { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, BSIZE))
272
              { B2 (0x3c, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
273
            else
274
              { B2 (0xf8, 0x04); F ($8, 8, 4); DSP ($6, 6, BSIZE); O1 ($4);
275
              if ($4.X_op != O_constant && $4.X_op != O_big) rx_linkrelax_imm (12); } }
276
 
277
        | MOV DOT_W '#' EXPR ',' disp '[' REG ']'
278
          { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, WSIZE))
279
              { B2 (0x3d, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
280
            else
281
              { B2 (0xf8, 0x01); F ($8, 8, 4); DSP ($6, 6, WSIZE); IMM ($4, 12); } }
282
 
283
        | MOV DOT_L '#' EXPR ',' disp '[' REG ']'
284
          { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, LSIZE))
285
              { B2 (0x3e, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); }
286
            else
287
              { B2 (0xf8, 0x02); F ($8, 8, 4); DSP ($6, 6, LSIZE); IMM ($4, 12); } }
288
 
289
/* ---------------------------------------------------------------------- */
290
 
291
        | RTSD '#' EXPR ',' REG '-' REG
292
          { B2 (0x3f, 0); F ($5, 8, 4); F ($7, 12, 4); rtsd_immediate ($3);
293
            if ($5 == 0)
294
              rx_error (_("RTSD cannot pop R0"));
295
            if ($5 > $7)
296
              rx_error (_("RTSD first reg must be <= second reg")); }
297
 
298
/* ---------------------------------------------------------------------- */
299
 
300
        | CMP REG ',' REG
301
          { B2 (0x47, 0); F ($2, 8, 4); F ($4, 12, 4); }
302
 
303
/* ---------------------------------------------------------------------- */
304
 
305
        | CMP disp '[' REG ']' DOT_UB ',' REG
306
          { B2 (0x44, 0); F ($4, 8, 4); F ($8, 12, 4); DSP ($2, 6, BSIZE); }
307
 
308
        | CMP disp '[' REG ']' memex ',' REG
309
          { B3 (MEMEX, 0x04, 0); F ($6, 8, 2);  F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, sizemap[$6]); }
310
 
311
/* ---------------------------------------------------------------------- */
312
 
313
        | MOVU bw REG ',' REG
314
          { B2 (0x5b, 0x00); F ($2, 5, 1); F ($3, 8, 4); F ($5, 12, 4); }
315
 
316
/* ---------------------------------------------------------------------- */
317
 
318
        | MOVU bw '[' REG ']' ',' REG
319
          { B2 (0x58, 0x00); F ($2, 5, 1); F ($4, 8, 4); F ($7, 12, 4); }
320
 
321
        | MOVU bw EXPR '[' REG ']' ',' REG
322
          { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2))
323
              { B2 (0xb0, 0); F ($2, 4, 1); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); }
324
            else
325
              { B2 (0x58, 0x00); F ($2, 5, 1); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } }
326
 
327
/* ---------------------------------------------------------------------- */
328
 
329
        | SUB '#' EXPR ',' REG
330
          { if (rx_uintop ($3, 4))
331
              { B2 (0x60, 0); FE ($3, 8, 4); F ($5, 12, 4); }
332
            else
333
              /* This is really an add, but we negate the immediate.  */
334
              { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); NIMM ($3, 6); } }
335
 
336
        | CMP '#' EXPR ',' REG
337
          { if (rx_uintop ($3, 4))
338
              { B2 (0x61, 0); FE ($3, 8, 4); F ($5, 12, 4); }
339
            else if (rx_uintop ($3, 8))
340
              { B2 (0x75, 0x50); F ($5, 12, 4); UO1 ($3); }
341
            else
342
              { B2 (0x74, 0x00); F ($5, 12, 4); IMM ($3, 6); } }
343
 
344
        | ADD '#' EXPR ',' REG
345
          { if (rx_uintop ($3, 4))
346
              { B2 (0x62, 0); FE ($3, 8, 4); F ($5, 12, 4); }
347
            else
348
              { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); IMM ($3, 6); } }
349
 
350
        | MUL '#' EXPR ',' REG
351
          { if (rx_uintop ($3, 4))
352
              { B2 (0x63, 0); FE ($3, 8, 4); F ($5, 12, 4); }
353
            else
354
              { B2 (0x74, 0x10); F ($5, 12, 4); IMM ($3, 6); } }
355
 
356
        | AND_ '#' EXPR ',' REG
357
          { if (rx_uintop ($3, 4))
358
              { B2 (0x64, 0); FE ($3, 8, 4); F ($5, 12, 4); }
359
            else
360
              { B2 (0x74, 0x20); F ($5, 12, 4); IMM ($3, 6); } }
361
 
362
        | OR '#' EXPR ',' REG
363
          { if (rx_uintop ($3, 4))
364
              { B2 (0x65, 0); FE ($3, 8, 4); F ($5, 12, 4); }
365
            else
366
              { B2 (0x74, 0x30); F ($5, 12, 4); IMM ($3, 6); } }
367
 
368
        | MOV DOT_L '#' EXPR ',' REG
369
          { if (rx_uintop ($4, 4))
370
              { B2 (0x66, 0); FE ($4, 8, 4); F ($6, 12, 4); }
371
            else if (rx_uintop ($4, 8))
372
              { B2 (0x75, 0x40); F ($6, 12, 4); UO1 ($4); }
373
            else
374
              { B2 (0xfb, 0x02); F ($6, 8, 4); IMM ($4, 12); } }
375
 
376
        | MOV '#' EXPR ',' REG
377
          { if (rx_uintop ($3, 4))
378
              { B2 (0x66, 0); FE ($3, 8, 4); F ($5, 12, 4); }
379
            else if (rx_uintop ($3, 8))
380
              { B2 (0x75, 0x40); F ($5, 12, 4); UO1 ($3); }
381
            else
382
              { B2 (0xfb, 0x02); F ($5, 8, 4); IMM ($3, 12); } }
383
 
384
/* ---------------------------------------------------------------------- */
385
 
386
        | RTSD '#' EXPR
387
          { B1 (0x67); rtsd_immediate ($3); }
388
 
389
/* ---------------------------------------------------------------------- */
390
 
391
        | SHLR { sub_op = 0; } op_shift
392
        | SHAR { sub_op = 1; } op_shift
393
        | SHLL { sub_op = 2; } op_shift
394
 
395
/* ---------------------------------------------------------------------- */
396
 
397
        | PUSHM REG '-' REG
398
          {
399
            if ($2 == $4)
400
              { B2 (0x7e, 0x80); F (LSIZE, 10, 2); F ($2, 12, 4); }
401
            else
402
             { B2 (0x6e, 0); F ($2, 8, 4); F ($4, 12, 4); }
403
            if ($2 == 0)
404
              rx_error (_("PUSHM cannot push R0"));
405
            if ($2 > $4)
406
              rx_error (_("PUSHM first reg must be <= second reg")); }
407
 
408
/* ---------------------------------------------------------------------- */
409
 
410
        | POPM REG '-' REG
411
          {
412
            if ($2 == $4)
413
              { B2 (0x7e, 0xb0); F ($2, 12, 4); }
414
            else
415
              { B2 (0x6f, 0); F ($2, 8, 4); F ($4, 12, 4); }
416
            if ($2 == 0)
417
              rx_error (_("POPM cannot pop R0"));
418
            if ($2 > $4)
419
              rx_error (_("POPM first reg must be <= second reg")); }
420
 
421
/* ---------------------------------------------------------------------- */
422
 
423
        | ADD '#' EXPR ',' REG ',' REG
424
          { B2 (0x70, 0x00); F ($5, 8, 4); F ($7, 12, 4); IMM ($3, 6); }
425
 
426
/* ---------------------------------------------------------------------- */
427
 
428
        | INT '#' EXPR
429
          { B2(0x75, 0x60), UO1 ($3); }
430
 
431
/* ---------------------------------------------------------------------- */
432
 
433
        | BSET '#' EXPR ',' REG
434
          { B2 (0x78, 0); FE ($3, 7, 5); F ($5, 12, 4); }
435
        | BCLR '#' EXPR ',' REG
436
          { B2 (0x7a, 0); FE ($3, 7, 5); F ($5, 12, 4); }
437
 
438
/* ---------------------------------------------------------------------- */
439
 
440
        | BTST '#' EXPR ',' REG
441
          { B2 (0x7c, 0x00); FE ($3, 7, 5); F ($5, 12, 4); }
442
 
443
/* ---------------------------------------------------------------------- */
444
 
445
        | SAT REG
446
          { B2 (0x7e, 0x30); F ($2, 12, 4); }
447
        | RORC REG
448
          { B2 (0x7e, 0x40); F ($2, 12, 4); }
449
        | ROLC REG
450
          { B2 (0x7e, 0x50); F ($2, 12, 4); }
451
 
452
/* ---------------------------------------------------------------------- */
453
 
454
        | PUSH bwl REG
455
          { B2 (0x7e, 0x80); F ($2, 10, 2); F ($3, 12, 4); }
456
 
457
/* ---------------------------------------------------------------------- */
458
 
459
        | POP REG
460
          { B2 (0x7e, 0xb0); F ($2, 12, 4); }
461
 
462
/* ---------------------------------------------------------------------- */
463
 
464
        | PUSHC CREG
465
          { if ($2 < 16)
466
              { B2 (0x7e, 0xc0); F ($2, 12, 4); }
467
            else
468
              as_bad (_("PUSHC can only push the first 16 control registers")); }
469
 
470
/* ---------------------------------------------------------------------- */
471
 
472
        | POPC CREG
473
          { if ($2 < 16)
474
              { B2 (0x7e, 0xe0); F ($2, 12, 4); }
475
            else
476
              as_bad (_("POPC can only pop the first 16 control registers")); }
477
 
478
/* ---------------------------------------------------------------------- */
479
 
480
        | SETPSW flag
481
          { B2 (0x7f, 0xa0); F ($2, 12, 4); }
482
        | CLRPSW flag
483
          { B2 (0x7f, 0xb0); F ($2, 12, 4); }
484
 
485
/* ---------------------------------------------------------------------- */
486
 
487
        | JMP REG
488
          { B2 (0x7f, 0x00); F ($2, 12, 4); }
489
        | JSR REG
490
          { B2 (0x7f, 0x10); F ($2, 12, 4); }
491
        | BRA opt_l REG
492
          { B2 (0x7f, 0x40); F ($3, 12, 4); }
493
        | BSR opt_l REG
494
          { B2 (0x7f, 0x50); F ($3, 12, 4); }
495
 
496
/* ---------------------------------------------------------------------- */
497
 
498
        | SCMPU
499
          { B2 (0x7f, 0x83); }
500
        | SMOVU
501
          { B2 (0x7f, 0x87); }
502
        | SMOVB
503
          { B2 (0x7f, 0x8b); }
504
        | SMOVF
505
          { B2 (0x7f, 0x8f); }
506
 
507
/* ---------------------------------------------------------------------- */
508
 
509
        | SUNTIL bwl
510
          { B2 (0x7f, 0x80); F ($2, 14, 2); }
511
        | SWHILE bwl
512
          { B2 (0x7f, 0x84); F ($2, 14, 2); }
513
        | SSTR bwl
514
          { B2 (0x7f, 0x88); F ($2, 14, 2); }
515
 
516
/* ---------------------------------------------------------------------- */
517
 
518
        | RMPA bwl
519
          { B2 (0x7f, 0x8c); F ($2, 14, 2); }
520
 
521
/* ---------------------------------------------------------------------- */
522
 
523
        | RTFI
524
          { B2 (0x7f, 0x94); }
525
        | RTE
526
          { B2 (0x7f, 0x95); }
527
        | WAIT
528
          { B2 (0x7f, 0x96); }
529
        | SATR
530
          { B2 (0x7f, 0x93); }
531
 
532
/* ---------------------------------------------------------------------- */
533
 
534
        | MVTIPL '#' EXPR
535
          { B3 (0x75, 0x70, 0x00); FE ($3, 20, 4); }
536
 
537
/* ---------------------------------------------------------------------- */
538
 
539
        /* rx_disp5op changes the value if it succeeds, so keep it last.  */
540
        | MOV bwl REG ',' EXPR '[' REG ']'
541
          { if ($3 <= 7 && $7 <= 7 && rx_disp5op (&$5, $2))
542
              { B2 (0x80, 0); F ($2, 2, 2); F ($7, 9, 3); F ($3, 13, 3); rx_field5s ($5); }
543
            else
544
              { B2 (0xc3, 0x00); F ($2, 2, 2); F ($7, 8, 4); F ($3, 12, 4); DSP ($5, 4, $2); }}
545
 
546
/* ---------------------------------------------------------------------- */
547
 
548
        | MOV bwl EXPR '[' REG ']' ',' REG
549
          { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2))
550
              { B2 (0x88, 0); F ($2, 2, 2); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); }
551
            else
552
              { B2 (0xcc, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } }
553
 
554
/* ---------------------------------------------------------------------- */
555
 
556
        /* MOV a,b - if a is a reg and b is mem, src and dest are
557
           swapped.  */
558
 
559
        /* We don't use "disp" here because it causes a shift/reduce
560
           conflict with the other displacement-less patterns.  */
561
 
562
        | MOV bwl REG ',' '[' REG ']'
563
          { B2 (0xc3, 0x00); F ($2, 2, 2); F ($6, 8, 4); F ($3, 12, 4); }
564
 
565
/* ---------------------------------------------------------------------- */
566
 
567
        | MOV bwl '[' REG ']' ',' disp '[' REG ']'
568
          { B2 (0xc0, 0); F ($2, 2, 2); F ($4, 8, 4); F ($9, 12, 4); DSP ($7, 4, $2); }
569
 
570
/* ---------------------------------------------------------------------- */
571
 
572
        | MOV bwl EXPR '[' REG ']' ',' disp '[' REG ']'
573
          { B2 (0xc0, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($10, 12, 4); DSP ($3, 6, $2); DSP ($8, 4, $2); }
574
 
575
/* ---------------------------------------------------------------------- */
576
 
577
        | MOV bwl REG ',' REG
578
          { B2 (0xcf, 0x00); F ($2, 2, 2); F ($3, 8, 4); F ($5, 12, 4); }
579
 
580
/* ---------------------------------------------------------------------- */
581
 
582
        | MOV bwl '[' REG ']' ',' REG
583
          { B2 (0xcc, 0x00); F ($2, 2, 2); F ($4, 8, 4); F ($7, 12, 4); }
584
 
585
/* ---------------------------------------------------------------------- */
586
 
587
        | BSET '#' EXPR ',' disp '[' REG ']' DOT_B
588
          { B2 (0xf0, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
589
        | BCLR '#' EXPR ',' disp '[' REG ']' DOT_B
590
          { B2 (0xf0, 0x08); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
591
        | BTST '#' EXPR ',' disp '[' REG ']' DOT_B
592
          { B2 (0xf4, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); }
593
 
594
/* ---------------------------------------------------------------------- */
595
 
596
        | PUSH bwl disp '[' REG ']'
597
          { B2 (0xf4, 0x08); F ($2, 14, 2); F ($5, 8, 4); DSP ($3, 6, $2); }
598
 
599
/* ---------------------------------------------------------------------- */
600
 
601
        | SBB   { sub_op = 0; } op_dp20_rm
602
        | NEG   { sub_op = 1; sub_op2 = 1; } op_dp20_rms
603
        | ADC   { sub_op = 2; } op_dp20_rim
604
        | ABS   { sub_op = 3; sub_op2 = 2; } op_dp20_rms
605
        | MAX   { sub_op = 4; } op_dp20_rim
606
        | MIN   { sub_op = 5; } op_dp20_rim
607
        | EMUL  { sub_op = 6; } op_dp20_i
608
        | EMULU { sub_op = 7; } op_dp20_i
609
        | DIV   { sub_op = 8; } op_dp20_rim
610
        | DIVU  { sub_op = 9; } op_dp20_rim
611
        | TST   { sub_op = 12; } op_dp20_rim
612
        | XOR   { sub_op = 13; } op_dp20_rim
613
        | NOT   { sub_op = 14; sub_op2 = 0; } op_dp20_rms
614
        | STZ   { sub_op = 14; } op_dp20_i
615
        | STNZ  { sub_op = 15; } op_dp20_i
616
 
617
/* ---------------------------------------------------------------------- */
618
 
619
        | EMUL  { sub_op = 6; } op_xchg
620
        | EMULU { sub_op = 7; } op_xchg
621
        | XCHG  { sub_op = 16; } op_xchg
622
        | ITOF  { sub_op = 17; } op_xchg
623
 
624
/* ---------------------------------------------------------------------- */
625
 
626
        | BSET REG ',' REG
627
          { id24 (1, 0x63, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
628
        | BCLR REG ',' REG
629
          { id24 (1, 0x67, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
630
        | BTST REG ',' REG
631
          { id24 (1, 0x6b, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
632
        | BNOT REG ',' REG
633
          { id24 (1, 0x6f, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
634
 
635
        | BSET REG ',' disp '[' REG ']' DOT_B
636
          { id24 (1, 0x60, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
637
        | BCLR REG ',' disp '[' REG ']' DOT_B
638
          { id24 (1, 0x64, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
639
        | BTST REG ',' disp '[' REG ']' DOT_B
640
          { id24 (1, 0x68, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
641
        | BNOT REG ',' disp '[' REG ']' DOT_B
642
          { id24 (1, 0x6c, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
643
 
644
/* ---------------------------------------------------------------------- */
645
 
646
        | FSUB  { sub_op = 0; } float2_op
647
        | FCMP  { sub_op = 1; } float2_op
648
        | FADD  { sub_op = 2; } float2_op
649
        | FMUL  { sub_op = 3; } float2_op
650
        | FDIV  { sub_op = 4; } float2_op
651
        | FTOI  { sub_op = 5; } float2_op_ni
652
        | ROUND { sub_op = 6; } float2_op_ni
653
 
654
/* ---------------------------------------------------------------------- */
655
 
656
        | SCCND DOT_L REG
657
          { id24 (1, 0xdb, 0x00); F ($1, 20, 4); F ($3, 16, 4); }
658
        | SCCND bwl disp '[' REG ']'
659
          { id24 (1, 0xd0, 0x00); F ($1, 20, 4); F ($2, 12, 2); F ($5, 16, 4); DSP ($3, 14, $2); }
660
 
661
/* ---------------------------------------------------------------------- */
662
 
663
        | BMCND '#' EXPR ',' disp '[' REG ']' DOT_B
664
          { id24 (1, 0xe0, 0x00); F ($1, 20, 4); FE ($3, 11, 3);
665
              F ($7, 16, 4); DSP ($5, 14, BSIZE); }
666
 
667
/* ---------------------------------------------------------------------- */
668
 
669
        | BNOT '#' EXPR ',' disp '[' REG ']' DOT_B
670
          { id24 (1, 0xe0, 0x0f); FE ($3, 11, 3); F ($7, 16, 4);
671
              DSP ($5, 14, BSIZE); }
672
 
673
/* ---------------------------------------------------------------------- */
674
 
675
        | MULHI REG ',' REG
676
          { id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
677
        | MULLO REG ',' REG
678
          { id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
679
        | MACHI REG ',' REG
680
          { id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
681
        | MACLO REG ',' REG
682
          { id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); }
683
 
684
/* ---------------------------------------------------------------------- */
685
 
686
        /* We don't have syntax for these yet.  */
687
        | MVTACHI REG
688
          { id24 (2, 0x17, 0x00); F ($2, 20, 4); }
689
        | MVTACLO REG
690
          { id24 (2, 0x17, 0x10); F ($2, 20, 4); }
691
        | MVFACHI REG
692
          { id24 (2, 0x1f, 0x00); F ($2, 20, 4); }
693
        | MVFACMI REG
694
          { id24 (2, 0x1f, 0x20); F ($2, 20, 4); }
695
        | MVFACLO REG
696
          { id24 (2, 0x1f, 0x10); F ($2, 20, 4); }
697
 
698
        | RACW '#' EXPR
699
          { id24 (2, 0x18, 0x00);
700
            if (rx_uintop ($3, 4) && $3.X_add_number == 1)
701
              ;
702
            else if (rx_uintop ($3, 4) && $3.X_add_number == 2)
703
              F (1, 19, 1);
704
            else
705
              as_bad (_("RACW expects #1 or #2"));}
706
 
707
/* ---------------------------------------------------------------------- */
708
 
709
        | MOV bwl REG ',' '[' REG '+' ']'
710
          { id24 (2, 0x20, 0); F ($2, 14, 2); F ($6, 16, 4); F ($3, 20, 4); }
711
        | MOV bwl REG ',' '[' '-' REG ']'
712
          { id24 (2, 0x24, 0); F ($2, 14, 2); F ($7, 16, 4); F ($3, 20, 4); }
713
 
714
/* ---------------------------------------------------------------------- */
715
 
716
        | MOV bwl '[' REG '+' ']' ',' REG
717
          { id24 (2, 0x28, 0); F ($2, 14, 2); F ($4, 16, 4); F ($8, 20, 4); }
718
        | MOV bwl '[' '-' REG ']' ',' REG
719
          { id24 (2, 0x2c, 0); F ($2, 14, 2); F ($5, 16, 4); F ($8, 20, 4); }
720
 
721
/* ---------------------------------------------------------------------- */
722
 
723
        | MOVU bw '[' REG '+' ']' ','  REG
724
          { id24 (2, 0x38, 0); F ($2, 15, 1); F ($4, 16, 4); F ($8, 20, 4); }
725
        | MOVU bw '[' '-' REG ']' ',' REG
726
          { id24 (2, 0x3c, 0); F ($2, 15, 1); F ($5, 16, 4); F ($8, 20, 4); }
727
 
728
/* ---------------------------------------------------------------------- */
729
 
730
        | ROTL { sub_op = 6; } op_shift_rot
731
        | ROTR { sub_op = 4; } op_shift_rot
732
        | REVW { sub_op = 5; } op_shift_rot
733
        | REVL { sub_op = 7; } op_shift_rot
734
 
735
/* ---------------------------------------------------------------------- */
736
 
737
        | MVTC REG ',' CREG
738
          { id24 (2, 0x68, 0x00); F ($4 % 16, 20, 4); F ($4 / 16, 15, 1);
739
            F ($2, 16, 4); }
740
 
741
/* ---------------------------------------------------------------------- */
742
 
743
        | MVFC CREG ',' REG
744
          { id24 (2, 0x6a, 0); F ($2, 15, 5); F ($4, 20, 4); }
745
 
746
/* ---------------------------------------------------------------------- */
747
 
748
        | ROTL '#' EXPR ',' REG
749
          { id24 (2, 0x6e, 0); FE ($3, 15, 5); F ($5, 20, 4); }
750
        | ROTR '#' EXPR ',' REG
751
          { id24 (2, 0x6c, 0); FE ($3, 15, 5); F ($5, 20, 4); }
752
 
753
/* ---------------------------------------------------------------------- */
754
 
755
        | MVTC '#' EXPR ',' CREG
756
          { id24 (2, 0x73, 0x00); F ($5, 19, 5); IMM ($3, 12); }
757
 
758
/* ---------------------------------------------------------------------- */
759
 
760
        | BMCND '#' EXPR ',' REG
761
          { id24 (2, 0xe0, 0x00); F ($1, 16, 4); FE ($3, 11, 5);
762
              F ($5, 20, 4); }
763
 
764
/* ---------------------------------------------------------------------- */
765
 
766
        | BNOT '#' EXPR ',' REG
767
          { id24 (2, 0xe0, 0xf0); FE ($3, 11, 5); F ($5, 20, 4); }
768
 
769
/* ---------------------------------------------------------------------- */
770
 
771
        | MOV bwl REG ',' '[' REG ',' REG ']'
772
          { id24 (3, 0x00, 0); F ($2, 10, 2); F ($6, 12, 4); F ($8, 16, 4); F ($3, 20, 4); }
773
 
774
        | MOV bwl '[' REG ',' REG ']' ',' REG
775
          { id24 (3, 0x40, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); }
776
 
777
        | MOVU bw '[' REG ',' REG ']' ',' REG
778
          { id24 (3, 0xc0, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); }
779
 
780
/* ---------------------------------------------------------------------- */
781
 
782
        | SUB { sub_op = 0; } op_subadd
783
        | ADD { sub_op = 2; } op_subadd
784
        | MUL { sub_op = 3; } op_subadd
785
        | AND_ { sub_op = 4; } op_subadd
786
        | OR  { sub_op = 5; } op_subadd
787
 
788
/* ---------------------------------------------------------------------- */
789
/* There is no SBB #imm so we fake it with ADC.  */
790
 
791
        | SBB '#' EXPR ',' REG
792
          { id24 (2, 0x70, 0x20); F ($5, 20, 4); NBIMM ($3, 12); }
793
 
794
/* ---------------------------------------------------------------------- */
795
 
796
        ;
797
 
798
/* ====================================================================== */
799
 
800
op_subadd
801
        : REG ',' REG
802
          { B2 (0x43 + (sub_op<<2), 0); F ($1, 8, 4); F ($3, 12, 4); }
803
        | disp '[' REG ']' DOT_UB ',' REG
804
          { B2 (0x40 + (sub_op<<2), 0); F ($3, 8, 4); F ($7, 12, 4); DSP ($1, 6, BSIZE); }
805
        | disp '[' REG ']' memex ',' REG
806
          { B3 (MEMEX, sub_op<<2, 0); F ($5, 8, 2); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, sizemap[$5]); }
807
        | REG ',' REG ',' REG
808
          { id24 (4, sub_op<<4, 0), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); }
809
        ;
810
 
811
/* sbb, neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */
812
 
813
op_dp20_rm
814
        : REG ',' REG
815
          { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); }
816
        | disp '[' REG ']' DOT_UB ',' REG
817
          { id24 (1, 0x00 + (sub_op<<2), 0x00); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); }
818
        | disp '[' REG ']' memex ',' REG
819
          { B4 (MEMEX, 0x20 + ($5 << 6), 0x00 + sub_op, 0x00);
820
          F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, sizemap[$5]); }
821
        ;
822
 
823
op_dp20_i
824
        : '#' EXPR ',' REG
825
          { id24 (2, 0x70, sub_op<<4); F ($4, 20, 4); IMM ($2, 12); }
826
        ;
827
 
828
op_dp20_rim
829
        : op_dp20_rm
830
        | op_dp20_i
831
        ;
832
 
833
op_dp20_rms
834
        : op_dp20_rm
835
        | REG
836
          { B2 (0x7e, sub_op2 << 4); F ($1, 12, 4); }
837
        ;
838
 
839
/* xchg, itof, emul, emulu */
840
op_xchg
841
        : REG ',' REG
842
          { id24 (1, 0x03 + (sub_op<<2), 0); F ($1, 16, 4); F ($3, 20, 4); }
843
        | disp '[' REG ']' DOT_UB ',' REG
844
          { id24 (1, 0x00 + (sub_op<<2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); }
845
        | disp '[' REG ']' memex ',' REG
846
          { B4 (MEMEX, 0x20, 0x00 + sub_op, 0); F ($5, 8, 2); F ($3, 24, 4); F ($7, 28, 4);
847
            DSP ($1, 14, sizemap[$5]); }
848
        ;
849
 
850
/* 000:SHLR, 001:SHAR, 010:SHLL, 011:-, 100:ROTR, 101:REVW, 110:ROTL, 111:REVL */
851
op_shift_rot
852
        : REG ',' REG
853
          { id24 (2, 0x60 + sub_op, 0); F ($1, 16, 4); F ($3, 20, 4); }
854
        ;
855
op_shift
856
        : '#' EXPR ',' REG
857
          { B2 (0x68 + (sub_op<<1), 0); FE ($2, 7, 5); F ($4, 12, 4); }
858
        | '#' EXPR ',' REG ',' REG
859
          { id24 (2, 0x80 + (sub_op << 5), 0); FE ($2, 11, 5); F ($4, 16, 4); F ($6, 20, 4); }
860
        | op_shift_rot
861
        ;
862
 
863
 
864
 
865
float2_op
866
        : '#' EXPR ',' REG
867
          { id24 (2, 0x72, sub_op << 4); F ($4, 20, 4); O4 ($2); }
868
        | float2_op_ni
869
        ;
870
float2_op_ni
871
        : REG ',' REG
872
          { id24 (1, 0x83 + (sub_op << 2), 0); F ($1, 16, 4); F ($3, 20, 4); }
873
        | disp '[' REG ']' opt_l ',' REG
874
          { id24 (1, 0x80 + (sub_op << 2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, LSIZE); }
875
        ;
876
 
877
/* ====================================================================== */
878
 
879
disp    :      { $$ = zero_expr (); }
880
        | EXPR { $$ = $1; }
881
        ;
882
 
883
flag    : { need_flag = 1; } FLAG { need_flag = 0; $$ = $2; }
884
        ;
885
 
886
/* DOT_UB is not listed here, it's handled with a separate pattern.  */
887
/* Use sizemap[$n] to get LSIZE etc.  */
888
memex   : DOT_B  { $$ = 0; }
889
        | DOT_W  { $$ = 1; }
890
        |        { $$ = 2; }
891
        | DOT_L  { $$ = 2; }
892
        | DOT_UW { $$ = 3; }
893
        ;
894
 
895
bwl     :       { $$ = LSIZE; }
896
        | DOT_B { $$ = BSIZE; }
897
        | DOT_W { $$ = WSIZE; }
898
        | DOT_L { $$ = LSIZE; }
899
        ;
900
 
901
bw      :       { $$ = 1; }
902
        | DOT_B { $$ = 0; }
903
        | DOT_W { $$ = 1; }
904
        ;
905
 
906
opt_l   :       {}
907
        | DOT_L {}
908
        ;
909
 
910
%%
911
/* ====================================================================== */
912
 
913
static struct
914
{
915
  const char * string;
916
  int          token;
917
  int          val;
918
}
919
token_table[] =
920
{
921
  { "r0", REG, 0 },
922
  { "r1", REG, 1 },
923
  { "r2", REG, 2 },
924
  { "r3", REG, 3 },
925
  { "r4", REG, 4 },
926
  { "r5", REG, 5 },
927
  { "r6", REG, 6 },
928
  { "r7", REG, 7 },
929
  { "r8", REG, 8 },
930
  { "r9", REG, 9 },
931
  { "r10", REG, 10 },
932
  { "r11", REG, 11 },
933
  { "r12", REG, 12 },
934
  { "r13", REG, 13 },
935
  { "r14", REG, 14 },
936
  { "r15", REG, 15 },
937
 
938
  { "psw", CREG, 0 },
939
  { "pc", CREG, 1 },
940
  { "usp", CREG, 2 },
941
  { "fpsw", CREG, 3 },
942
  /* reserved */
943
  /* reserved */
944
  /* reserved */
945
  { "wr", CREG, 7 },
946
 
947
  { "bpsw", CREG, 8 },
948
  { "bpc", CREG, 9 },
949
  { "isp", CREG, 10 },
950
  { "fintv", CREG, 11 },
951
  { "intb", CREG, 12 },
952
 
953
  { "pbp", CREG, 16 },
954
  { "pben", CREG, 17 },
955
 
956
  { "bbpsw", CREG, 24 },
957
  { "bbpc", CREG, 25 },
958
 
959
  { ".s", DOT_S, 0 },
960
  { ".b", DOT_B, 0 },
961
  { ".w", DOT_W, 0 },
962
  { ".l", DOT_L, 0 },
963
  { ".a", DOT_A , 0},
964
  { ".ub", DOT_UB, 0 },
965
  { ".uw", DOT_UW , 0},
966
 
967
  { "c", FLAG, 0 },
968
  { "z", FLAG, 1 },
969
  { "s", FLAG, 2 },
970
  { "o", FLAG, 3 },
971
  { "i", FLAG, 8 },
972
  { "u", FLAG, 9 },
973
 
974
#define OPC(x) { #x, x, IS_OPCODE }
975
  OPC(ABS),
976
  OPC(ADC),
977
  OPC(ADD),
978
  { "and", AND_, IS_OPCODE },
979
  OPC(BCLR),
980
  OPC(BCND),
981
  OPC(BMCND),
982
  OPC(BNOT),
983
  OPC(BRA),
984
  OPC(BRK),
985
  OPC(BSET),
986
  OPC(BSR),
987
  OPC(BTST),
988
  OPC(CLRPSW),
989
  OPC(CMP),
990
  OPC(DBT),
991
  OPC(DIV),
992
  OPC(DIVU),
993
  OPC(EDIV),
994
  OPC(EDIVU),
995
  OPC(EMUL),
996
  OPC(EMULU),
997
  OPC(FADD),
998
  OPC(FCMP),
999
  OPC(FDIV),
1000
  OPC(FMUL),
1001
  OPC(FREIT),
1002
  OPC(FSUB),
1003
  OPC(FTOI),
1004
  OPC(INT),
1005
  OPC(ITOF),
1006
  OPC(JMP),
1007
  OPC(JSR),
1008
  OPC(MVFACHI),
1009
  OPC(MVFACMI),
1010
  OPC(MVFACLO),
1011
  OPC(MVFC),
1012
  OPC(MVTACHI),
1013
  OPC(MVTACLO),
1014
  OPC(MVTC),
1015
  OPC(MVTIPL),
1016
  OPC(MACHI),
1017
  OPC(MACLO),
1018
  OPC(MAX),
1019
  OPC(MIN),
1020
  OPC(MOV),
1021
  OPC(MOVU),
1022
  OPC(MUL),
1023
  OPC(MULHI),
1024
  OPC(MULLO),
1025
  OPC(MULU),
1026
  OPC(NEG),
1027
  OPC(NOP),
1028
  OPC(NOT),
1029
  OPC(OR),
1030
  OPC(POP),
1031
  OPC(POPC),
1032
  OPC(POPM),
1033
  OPC(PUSH),
1034
  OPC(PUSHA),
1035
  OPC(PUSHC),
1036
  OPC(PUSHM),
1037
  OPC(RACW),
1038
  OPC(REIT),
1039
  OPC(REVL),
1040
  OPC(REVW),
1041
  OPC(RMPA),
1042
  OPC(ROLC),
1043
  OPC(RORC),
1044
  OPC(ROTL),
1045
  OPC(ROTR),
1046
  OPC(ROUND),
1047
  OPC(RTE),
1048
  OPC(RTFI),
1049
  OPC(RTS),
1050
  OPC(RTSD),
1051
  OPC(SAT),
1052
  OPC(SATR),
1053
  OPC(SBB),
1054
  OPC(SCCND),
1055
  OPC(SCMPU),
1056
  OPC(SETPSW),
1057
  OPC(SHAR),
1058
  OPC(SHLL),
1059
  OPC(SHLR),
1060
  OPC(SMOVB),
1061
  OPC(SMOVF),
1062
  OPC(SMOVU),
1063
  OPC(SSTR),
1064
  OPC(STNZ),
1065
  OPC(STOP),
1066
  OPC(STZ),
1067
  OPC(SUB),
1068
  OPC(SUNTIL),
1069
  OPC(SWHILE),
1070
  OPC(TST),
1071
  OPC(WAIT),
1072
  OPC(XCHG),
1073
  OPC(XOR),
1074
};
1075
 
1076
#define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
1077
 
1078
static struct
1079
{
1080
  char * string;
1081
  int    token;
1082
}
1083
condition_opcode_table[] =
1084
{
1085
  { "b", BCND },
1086
  { "bm", BMCND },
1087
  { "sc", SCCND },
1088
};
1089
 
1090
#define NUM_CONDITION_OPCODES (sizeof (condition_opcode_table) / sizeof (condition_opcode_table[0]))
1091
 
1092
static struct
1093
{
1094
  char * string;
1095
  int    val;
1096
}
1097
condition_table[] =
1098
{
1099
  { "z", 0 },
1100
  { "eq", 0 },
1101
  { "geu",  2 },
1102
  { "c",  2 },
1103
  { "gtu", 4 },
1104
  { "pz", 6 },
1105
  { "ge", 8 },
1106
  { "gt", 10 },
1107
  { "o",  12},
1108
  /* always = 14 */
1109
  { "nz", 1 },
1110
  { "ne", 1 },
1111
  { "ltu", 3 },
1112
  { "nc", 3 },
1113
  { "leu", 5 },
1114
  { "n", 7 },
1115
  { "lt", 9 },
1116
  { "le", 11 },
1117
  { "no", 13 }
1118
  /* never = 15 */
1119
};
1120
 
1121
#define NUM_CONDITIONS (sizeof (condition_table) / sizeof (condition_table[0]))
1122
 
1123
void
1124
rx_lex_init (char * beginning, char * ending)
1125
{
1126
  rx_init_start = beginning;
1127
  rx_lex_start = beginning;
1128
  rx_lex_end = ending;
1129
  rx_in_brackets = 0;
1130
  rx_last_token = 0;
1131
 
1132
  setbuf (stdout, 0);
1133
}
1134
 
1135
static int
1136
check_condition (char * base)
1137
{
1138
  char * cp;
1139
  unsigned int i;
1140
 
1141
  if ((unsigned) (rx_lex_end - rx_lex_start) < strlen (base) + 1)
1142
    return 0;
1143
  if (memcmp (rx_lex_start, base, strlen (base)))
1144
    return 0;
1145
  cp = rx_lex_start + strlen (base);
1146
  for (i = 0; i < NUM_CONDITIONS; i ++)
1147
    {
1148
      if (strcasecmp (cp, condition_table[i].string) == 0)
1149
        {
1150
          rx_lval.regno = condition_table[i].val;
1151
          return 1;
1152
        }
1153
    }
1154
  return 0;
1155
}
1156
 
1157
static int
1158
rx_lex (void)
1159
{
1160
  unsigned int ci;
1161
  char * save_input_pointer;
1162
 
1163
  while (ISSPACE (*rx_lex_start)
1164
         && rx_lex_start != rx_lex_end)
1165
    rx_lex_start ++;
1166
 
1167
  rx_last_exp_start = rx_lex_start;
1168
 
1169
  if (rx_lex_start == rx_lex_end)
1170
    return 0;
1171
 
1172
  if (ISALPHA (*rx_lex_start)
1173
      || (*rx_lex_start == '.' && ISALPHA (rx_lex_start[1])))
1174
    {
1175
      unsigned int i;
1176
      char * e;
1177
      char save;
1178
 
1179
      for (e = rx_lex_start + 1;
1180
           e < rx_lex_end && ISALNUM (*e);
1181
           e ++)
1182
        ;
1183
      save = *e;
1184
      *e = 0;
1185
 
1186
      if (rx_last_token == 0)
1187
        for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++)
1188
          if (check_condition (condition_opcode_table[ci].string))
1189
            {
1190
              *e = save;
1191
              rx_lex_start = e;
1192
              rx_last_token = condition_opcode_table[ci].token;
1193
              return condition_opcode_table[ci].token;
1194
            }
1195
 
1196
      for (i = 0; i < NUM_TOKENS; i++)
1197
        if (strcasecmp (rx_lex_start, token_table[i].string) == 0
1198
            && !(token_table[i].val == IS_OPCODE && rx_last_token != 0)
1199
            && !(token_table[i].token == FLAG && !need_flag))
1200
          {
1201
            rx_lval.regno = token_table[i].val;
1202
            *e = save;
1203
            rx_lex_start = e;
1204
            rx_last_token = token_table[i].token;
1205
            return token_table[i].token;
1206
          }
1207
      *e = save;
1208
    }
1209
 
1210
  if (rx_last_token == 0)
1211
    {
1212
      rx_last_token = UNKNOWN_OPCODE;
1213
      return UNKNOWN_OPCODE;
1214
    }
1215
 
1216
  if (rx_last_token == UNKNOWN_OPCODE)
1217
    return 0;
1218
 
1219
  if (*rx_lex_start == '[')
1220
    rx_in_brackets = 1;
1221
  if (*rx_lex_start == ']')
1222
    rx_in_brackets = 0;
1223
 
1224
  if (rx_in_brackets
1225
      || rx_last_token == REG
1226
      || strchr ("[],#", *rx_lex_start))
1227
    {
1228
      rx_last_token = *rx_lex_start;
1229
      return *rx_lex_start ++;
1230
    }
1231
 
1232
  save_input_pointer = input_line_pointer;
1233
  input_line_pointer = rx_lex_start;
1234
  rx_lval.exp.X_md = 0;
1235
  expression (&rx_lval.exp);
1236
 
1237
  /* We parse but ignore any : modifier on expressions.  */
1238
  if (*input_line_pointer == ':')
1239
    {
1240
      char *cp;
1241
 
1242
      for (cp  = input_line_pointer + 1; *cp && cp < rx_lex_end; cp++)
1243
        if (!ISDIGIT (*cp))
1244
          break;
1245
      if (cp > input_line_pointer+1)
1246
        input_line_pointer = cp;
1247
    }
1248
 
1249
  rx_lex_start = input_line_pointer;
1250
  input_line_pointer = save_input_pointer;
1251
  rx_last_token = EXPR;
1252
  return EXPR;
1253
}
1254
 
1255
int
1256
rx_error (char * str)
1257
{
1258
  int len;
1259
 
1260
  len = rx_last_exp_start - rx_init_start;
1261
 
1262
  as_bad ("%s", rx_init_start);
1263
  as_bad ("%*s^ %s", len, "", str);
1264
  return 0;
1265
}
1266
 
1267
static int
1268
rx_intop (expressionS exp, int nbits)
1269
{
1270
  long v;
1271
 
1272
  if (exp.X_op == O_big && nbits == 32)
1273
      return 1;
1274
  if (exp.X_op != O_constant)
1275
    return 0;
1276
  v = exp.X_add_number;
1277
 
1278
  switch (nbits)
1279
    {
1280
    case 4:
1281
      return -0x8 <= v && v <= 0x7;
1282
    case 5:
1283
      return -0x10 <= v && v <= 0x17;
1284
    case 8:
1285
      return -0x80 <= v && v <= 0x7f;
1286
    case 16:
1287
      return -0x8000 <= v && v <= 0x7fff;
1288
    case 24:
1289
      return -0x800000 <= v && v <= 0x7fffff;
1290
    case 32:
1291
      return 1;
1292
    default:
1293
      printf ("rx_intop passed %d\n", nbits);
1294
      abort ();
1295
    }
1296
  return 1;
1297
}
1298
 
1299
static int
1300
rx_uintop (expressionS exp, int nbits)
1301
{
1302
  unsigned long v;
1303
 
1304
  if (exp.X_op != O_constant)
1305
    return 0;
1306
  v = exp.X_add_number;
1307
 
1308
  switch (nbits)
1309
    {
1310
    case 4:
1311
      return v <= 0xf;
1312
    case 8:
1313
      return v <= 0xff;
1314
    case 16:
1315
      return v <= 0xffff;
1316
    case 24:
1317
      return v <= 0xffffff;
1318
    default:
1319
      printf ("rx_uintop passed %d\n", nbits);
1320
      abort ();
1321
    }
1322
  return 1;
1323
}
1324
 
1325
static int
1326
rx_disp3op (expressionS exp)
1327
{
1328
  unsigned long v;
1329
 
1330
  if (exp.X_op != O_constant)
1331
    return 0;
1332
  v = exp.X_add_number;
1333
  if (v < 3 || v > 10)
1334
    return 0;
1335
  return 1;
1336
}
1337
 
1338
static int
1339
rx_disp5op (expressionS * exp, int msize)
1340
{
1341
  long v;
1342
 
1343
  if (exp->X_op != O_constant)
1344
    return 0;
1345
  v = exp->X_add_number;
1346
 
1347
  switch (msize)
1348
    {
1349
    case BSIZE:
1350
      if (0 < v && v <= 31)
1351
        return 1;
1352
      break;
1353
    case WSIZE:
1354
      if (v & 1)
1355
        return 0;
1356
      if (0 < v && v <= 63)
1357
        {
1358
          exp->X_add_number >>= 1;
1359
          return 1;
1360
        }
1361
      break;
1362
    case LSIZE:
1363
      if (v & 3)
1364
        return 0;
1365
      if (0 < v && v <= 127)
1366
        {
1367
          exp->X_add_number >>= 2;
1368
          return 1;
1369
        }
1370
      break;
1371
    }
1372
  return 0;
1373
}
1374
 
1375
/* Just like the above, but allows a zero displacement.  */
1376
 
1377
static int
1378
rx_disp5op0 (expressionS * exp, int msize)
1379
{
1380
  if (exp->X_op != O_constant)
1381
    return 0;
1382
  if (exp->X_add_number == 0)
1383
    return 1;
1384
  return rx_disp5op (exp, msize);
1385
}
1386
 
1387
static int
1388
exp_val (expressionS exp)
1389
{
1390
  if (exp.X_op != O_constant)
1391
  {
1392
    rx_error (_("constant expected"));
1393
    return 0;
1394
  }
1395
  return exp.X_add_number;
1396
}
1397
 
1398
static expressionS
1399
zero_expr (void)
1400
{
1401
  /* Static, so program load sets it to all zeros, which is what we want.  */
1402
  static expressionS zero;
1403
  zero.X_op = O_constant;
1404
  return zero;
1405
}
1406
 
1407
static int
1408
immediate (expressionS exp, int type, int pos)
1409
{
1410
  /* We will emit constants ourself here, so negate them.  */
1411
  if (type == RXREL_NEGATIVE && exp.X_op == O_constant)
1412
    exp.X_add_number = - exp.X_add_number;
1413
  if (type == RXREL_NEGATIVE_BORROW)
1414
    {
1415
      if (exp.X_op == O_constant)
1416
        exp.X_add_number = - exp.X_add_number - 1;
1417
      else
1418
        rx_error (_("sbb cannot use symbolic immediates"));
1419
    }
1420
 
1421
  if (rx_intop (exp, 8))
1422
    {
1423
      rx_op (exp, 1, type);
1424
      return 1;
1425
    }
1426
  else if (rx_intop (exp, 16))
1427
    {
1428
      rx_op (exp, 2, type);
1429
      return 2;
1430
    }
1431
  else if (rx_intop (exp, 24))
1432
    {
1433
      rx_op (exp, 3, type);
1434
      return 3;
1435
    }
1436
  else if (rx_intop (exp, 32))
1437
    {
1438
      rx_op (exp, 4, type);
1439
      return 0;
1440
    }
1441
  else if (type == RXREL_SIGNED)
1442
    {
1443
      /* This is a symbolic immediate, we will relax it later.  */
1444
      rx_relax (RX_RELAX_IMM, pos);
1445
      rx_op (exp, linkrelax ? 4 : 1, type);
1446
      return 1;
1447
    }
1448
  else
1449
    {
1450
      /* Let the linker deal with it.  */
1451
      rx_op (exp, 4, type);
1452
      return 0;
1453
    }
1454
}
1455
 
1456
static int
1457
displacement (expressionS exp, int msize)
1458
{
1459
  int val;
1460
  int vshift = 0;
1461
 
1462
  if (exp.X_op == O_symbol
1463
      && exp.X_md)
1464
    {
1465
      switch (exp.X_md)
1466
        {
1467
        case BFD_RELOC_GPREL16:
1468
          switch (msize)
1469
            {
1470
            case BSIZE:
1471
              exp.X_md = BFD_RELOC_RX_GPRELB;
1472
              break;
1473
            case WSIZE:
1474
              exp.X_md = BFD_RELOC_RX_GPRELW;
1475
              break;
1476
            case LSIZE:
1477
              exp.X_md = BFD_RELOC_RX_GPRELL;
1478
              break;
1479
            }
1480
          O2 (exp);
1481
          return 2;
1482
        }
1483
    }
1484
 
1485
  if (exp.X_op != O_constant)
1486
    {
1487
      rx_error (_("displacements must be constants"));
1488
      return -1;
1489
    }
1490
  val = exp.X_add_number;
1491
 
1492
  if (val == 0)
1493
    return 0;
1494
 
1495
  switch (msize)
1496
    {
1497
    case BSIZE:
1498
      break;
1499
    case WSIZE:
1500
      if (val & 1)
1501
        rx_error (_("word displacement not word-aligned"));
1502
      vshift = 1;
1503
      break;
1504
    case LSIZE:
1505
      if (val & 3)
1506
        rx_error (_("long displacement not long-aligned"));
1507
      vshift = 2;
1508
      break;
1509
    default:
1510
      as_bad (_("displacement with unknown size (internal bug?)\n"));
1511
      break;
1512
    }
1513
 
1514
  val >>= vshift;
1515
  exp.X_add_number = val;
1516
 
1517
  if (0 <= val && val <= 255 )
1518
    {
1519
      O1 (exp);
1520
      return 1;
1521
    }
1522
 
1523
  if (0 <= val && val <= 65535)
1524
    {
1525
      O2 (exp);
1526
      return 2;
1527
    }
1528
  if (val < 0)
1529
    rx_error (_("negative displacements not allowed"));
1530
  else
1531
    rx_error (_("displacement too large"));
1532
  return -1;
1533
}
1534
 
1535
static void
1536
rtsd_immediate (expressionS exp)
1537
{
1538
  int val;
1539
 
1540
  if (exp.X_op != O_constant)
1541
    {
1542
      rx_error (_("rtsd size must be constant"));
1543
      return;
1544
    }
1545
  val = exp.X_add_number;
1546
  if (val & 3)
1547
    rx_error (_("rtsd size must be multiple of 4"));
1548
 
1549
  if (val < 0 || val > 1020)
1550
    rx_error (_("rtsd size must be 0..1020"));
1551
 
1552
  val >>= 2;
1553
  exp.X_add_number = val;
1554
  O1 (exp);
1555
}

powered by: WebSVN 2.1.0

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