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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [gdb-5.0/] [opcodes/] [m32r-asm.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Assembler interface for targets using CGEN. -*- C -*-
2
   CGEN: Cpu tools GENerator
3
 
4
THIS FILE IS MACHINE GENERATED WITH CGEN.
5
- the resultant file is machine generated, cgen-asm.in isn't
6
 
7
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
8
 
9
This file is part of the GNU Binutils and GDB, the GNU debugger.
10
 
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2, or (at your option)
14
any later version.
15
 
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
GNU General Public License for more details.
20
 
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software Foundation, Inc.,
23
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24
 
25
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
26
   Keep that in mind.  */
27
 
28
#include "sysdep.h"
29
#include <ctype.h>
30
#include <stdio.h>
31
#include "ansidecl.h"
32
#include "bfd.h"
33
#include "symcat.h"
34
#include "m32r-desc.h"
35
#include "m32r-opc.h"
36
#include "opintl.h"
37
 
38
#undef min
39
#define min(a,b) ((a) < (b) ? (a) : (b))
40
#undef max
41
#define max(a,b) ((a) > (b) ? (a) : (b))
42
 
43
static const char * parse_insn_normal
44
     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
45
 
46
/* -- assembler routines inserted here */
47
 
48
/* -- asm.c */
49
 
50
/* Handle '#' prefixes (i.e. skip over them).  */
51
 
52
static const char *
53
parse_hash (cd, strp, opindex, valuep)
54
     CGEN_CPU_DESC cd;
55
     const char **strp;
56
     int opindex;
57
     unsigned long *valuep;
58
{
59
  if (**strp == '#')
60
    ++*strp;
61
  return NULL;
62
}
63
 
64
/* Handle shigh(), high().  */
65
 
66
static const char *
67
parse_hi16 (cd, strp, opindex, valuep)
68
     CGEN_CPU_DESC cd;
69
     const char **strp;
70
     int opindex;
71
     unsigned long *valuep;
72
{
73
  const char *errmsg;
74
  enum cgen_parse_operand_result result_type;
75
  bfd_vma value;
76
 
77
  if (**strp == '#')
78
    ++*strp;
79
 
80
  if (strncasecmp (*strp, "high(", 5) == 0)
81
    {
82
      *strp += 5;
83
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
84
                                   &result_type, &value);
85
      if (**strp != ')')
86
        return "missing `)'";
87
      ++*strp;
88
      if (errmsg == NULL
89
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
90
        value >>= 16;
91
      *valuep = value;
92
      return errmsg;
93
    }
94
  else if (strncasecmp (*strp, "shigh(", 6) == 0)
95
    {
96
      *strp += 6;
97
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
98
                                   &result_type, &value);
99
      if (**strp != ')')
100
        return "missing `)'";
101
      ++*strp;
102
      if (errmsg == NULL
103
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
104
        value = (value >> 16) + (value & 0x8000 ? 1 : 0);
105
      *valuep = value;
106
      return errmsg;
107
    }
108
 
109
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
110
}
111
 
112
/* Handle low() in a signed context.  Also handle sda().
113
   The signedness of the value doesn't matter to low(), but this also
114
   handles the case where low() isn't present.  */
115
 
116
static const char *
117
parse_slo16 (cd, strp, opindex, valuep)
118
     CGEN_CPU_DESC cd;
119
     const char **strp;
120
     int opindex;
121
     long *valuep;
122
{
123
  const char *errmsg;
124
  enum cgen_parse_operand_result result_type;
125
  bfd_vma value;
126
 
127
  if (**strp == '#')
128
    ++*strp;
129
 
130
  if (strncasecmp (*strp, "low(", 4) == 0)
131
    {
132
      *strp += 4;
133
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
134
                                   &result_type, &value);
135
      if (**strp != ')')
136
        return "missing `)'";
137
      ++*strp;
138
      if (errmsg == NULL
139
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
140
        value &= 0xffff;
141
      *valuep = value;
142
      return errmsg;
143
    }
144
 
145
  if (strncasecmp (*strp, "sda(", 4) == 0)
146
    {
147
      *strp += 4;
148
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16,
149
                                   NULL, &value);
150
      if (**strp != ')')
151
        return "missing `)'";
152
      ++*strp;
153
      *valuep = value;
154
      return errmsg;
155
    }
156
 
157
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
158
}
159
 
160
/* Handle low() in an unsigned context.
161
   The signedness of the value doesn't matter to low(), but this also
162
   handles the case where low() isn't present.  */
163
 
164
static const char *
165
parse_ulo16 (cd, strp, opindex, valuep)
166
     CGEN_CPU_DESC cd;
167
     const char **strp;
168
     int opindex;
169
     unsigned long *valuep;
170
{
171
  const char *errmsg;
172
  enum cgen_parse_operand_result result_type;
173
  bfd_vma value;
174
 
175
  if (**strp == '#')
176
    ++*strp;
177
 
178
  if (strncasecmp (*strp, "low(", 4) == 0)
179
    {
180
      *strp += 4;
181
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
182
                                   &result_type, &value);
183
      if (**strp != ')')
184
        return "missing `)'";
185
      ++*strp;
186
      if (errmsg == NULL
187
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
188
        value &= 0xffff;
189
      *valuep = value;
190
      return errmsg;
191
    }
192
 
193
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
194
}
195
 
196
/* -- */
197
 
198
/* Main entry point for operand parsing.
199
 
200
   This function is basically just a big switch statement.  Earlier versions
201
   used tables to look up the function to use, but
202
   - if the table contains both assembler and disassembler functions then
203
     the disassembler contains much of the assembler and vice-versa,
204
   - there's a lot of inlining possibilities as things grow,
205
   - using a switch statement avoids the function call overhead.
206
 
207
   This function could be moved into `parse_insn_normal', but keeping it
208
   separate makes clear the interface between `parse_insn_normal' and each of
209
   the handlers.
210
*/
211
 
212
const char *
213
m32r_cgen_parse_operand (cd, opindex, strp, fields)
214
     CGEN_CPU_DESC cd;
215
     int opindex;
216
     const char ** strp;
217
     CGEN_FIELDS * fields;
218
{
219
  const char * errmsg = NULL;
220
  /* Used by scalar operands that still need to be parsed.  */
221
  long junk;
222
 
223
  switch (opindex)
224
    {
225
    case M32R_OPERAND_ACC :
226
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
227
      break;
228
    case M32R_OPERAND_ACCD :
229
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
230
      break;
231
    case M32R_OPERAND_ACCS :
232
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
233
      break;
234
    case M32R_OPERAND_DCR :
235
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r1);
236
      break;
237
    case M32R_OPERAND_DISP16 :
238
      {
239
        bfd_vma value;
240
        errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP16, 0, NULL,  & value);
241
        fields->f_disp16 = value;
242
      }
243
      break;
244
    case M32R_OPERAND_DISP24 :
245
      {
246
        bfd_vma value;
247
        errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP24, 0, NULL,  & value);
248
        fields->f_disp24 = value;
249
      }
250
      break;
251
    case M32R_OPERAND_DISP8 :
252
      {
253
        bfd_vma value;
254
        errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP8, 0, NULL,  & value);
255
        fields->f_disp8 = value;
256
      }
257
      break;
258
    case M32R_OPERAND_DR :
259
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
260
      break;
261
    case M32R_OPERAND_HASH :
262
      errmsg = parse_hash (cd, strp, M32R_OPERAND_HASH, &junk);
263
      break;
264
    case M32R_OPERAND_HI16 :
265
      errmsg = parse_hi16 (cd, strp, M32R_OPERAND_HI16, &fields->f_hi16);
266
      break;
267
    case M32R_OPERAND_IMM1 :
268
      errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_IMM1, &fields->f_imm1);
269
      break;
270
    case M32R_OPERAND_SCR :
271
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r2);
272
      break;
273
    case M32R_OPERAND_SIMM16 :
274
      errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
275
      break;
276
    case M32R_OPERAND_SIMM8 :
277
      errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
278
      break;
279
    case M32R_OPERAND_SLO16 :
280
      errmsg = parse_slo16 (cd, strp, M32R_OPERAND_SLO16, &fields->f_simm16);
281
      break;
282
    case M32R_OPERAND_SR :
283
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
284
      break;
285
    case M32R_OPERAND_SRC1 :
286
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
287
      break;
288
    case M32R_OPERAND_SRC2 :
289
      errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
290
      break;
291
    case M32R_OPERAND_UIMM16 :
292
      errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
293
      break;
294
    case M32R_OPERAND_UIMM24 :
295
      {
296
        bfd_vma value;
297
        errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_UIMM24, 0, NULL,  & value);
298
        fields->f_uimm24 = value;
299
      }
300
      break;
301
    case M32R_OPERAND_UIMM4 :
302
      errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
303
      break;
304
    case M32R_OPERAND_UIMM5 :
305
      errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
306
      break;
307
    case M32R_OPERAND_ULO16 :
308
      errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
309
      break;
310
 
311
    default :
312
      /* xgettext:c-format */
313
      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
314
      abort ();
315
  }
316
 
317
  return errmsg;
318
}
319
 
320
cgen_parse_fn * const m32r_cgen_parse_handlers[] =
321
{
322
  parse_insn_normal,
323
};
324
 
325
void
326
m32r_cgen_init_asm (cd)
327
     CGEN_CPU_DESC cd;
328
{
329
  m32r_cgen_init_opcode_table (cd);
330
  m32r_cgen_init_ibld_table (cd);
331
  cd->parse_handlers = & m32r_cgen_parse_handlers[0];
332
  cd->parse_operand = m32r_cgen_parse_operand;
333
}
334
 
335
 
336
/* Default insn parser.
337
 
338
   The syntax string is scanned and operands are parsed and stored in FIELDS.
339
   Relocs are queued as we go via other callbacks.
340
 
341
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
342
   parse the instruction, we return 0 and the caller will start over from
343
   the beginning.  Backtracking will be necessary in parsing subexpressions,
344
   but that can be handled there.  Not handling backtracking here may get
345
   expensive in the case of the m68k.  Deal with later.
346
 
347
   Returns NULL for success, an error message for failure.
348
*/
349
 
350
static const char *
351
parse_insn_normal (cd, insn, strp, fields)
352
     CGEN_CPU_DESC cd;
353
     const CGEN_INSN *insn;
354
     const char **strp;
355
     CGEN_FIELDS *fields;
356
{
357
  /* ??? Runtime added insns not handled yet.  */
358
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
359
  const char *str = *strp;
360
  const char *errmsg;
361
  const char *p;
362
  const unsigned char * syn;
363
#ifdef CGEN_MNEMONIC_OPERANDS
364
  /* FIXME: wip */
365
  int past_opcode_p;
366
#endif
367
 
368
  /* For now we assume the mnemonic is first (there are no leading operands).
369
     We can parse it without needing to set up operand parsing.
370
     GAS's input scrubber will ensure mnemonics are lowercase, but we may
371
     not be called from GAS.  */
372
  p = CGEN_INSN_MNEMONIC (insn);
373
  while (*p && tolower (*p) == tolower (*str))
374
    ++p, ++str;
375
 
376
  if (* p)
377
    return _("unrecognized instruction");
378
 
379
#ifndef CGEN_MNEMONIC_OPERANDS
380
  if (* str && !isspace (* str))
381
    return _("unrecognized instruction");
382
#endif
383
 
384
  CGEN_INIT_PARSE (cd);
385
  cgen_init_parse_operand (cd);
386
#ifdef CGEN_MNEMONIC_OPERANDS
387
  past_opcode_p = 0;
388
#endif
389
 
390
  /* We don't check for (*str != '\0') here because we want to parse
391
     any trailing fake arguments in the syntax string.  */
392
  syn = CGEN_SYNTAX_STRING (syntax);
393
 
394
  /* Mnemonics come first for now, ensure valid string.  */
395
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
396
    abort ();
397
 
398
  ++syn;
399
 
400
  while (* syn != 0)
401
    {
402
      /* Non operand chars must match exactly.  */
403
      if (CGEN_SYNTAX_CHAR_P (* syn))
404
        {
405
          /* FIXME: While we allow for non-GAS callers above, we assume the
406
             first char after the mnemonic part is a space.  */
407
          /* FIXME: We also take inappropriate advantage of the fact that
408
             GAS's input scrubber will remove extraneous blanks.  */
409
          if (*str == CGEN_SYNTAX_CHAR (* syn))
410
            {
411
#ifdef CGEN_MNEMONIC_OPERANDS
412
              if (* syn == ' ')
413
                past_opcode_p = 1;
414
#endif
415
              ++ syn;
416
              ++ str;
417
            }
418
          else
419
            {
420
              /* Syntax char didn't match.  Can't be this insn.  */
421
              /* FIXME: would like to return something like
422
                 "expected char `c'" */
423
              return _("syntax error");
424
            }
425
          continue;
426
        }
427
 
428
      /* We have an operand of some sort.  */
429
      errmsg = m32r_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
430
                                          &str, fields);
431
      if (errmsg)
432
        return errmsg;
433
 
434
      /* Done with this operand, continue with next one.  */
435
      ++ syn;
436
    }
437
 
438
  /* If we're at the end of the syntax string, we're done.  */
439
  if (* syn == '\0')
440
    {
441
      /* FIXME: For the moment we assume a valid `str' can only contain
442
         blanks now.  IE: We needn't try again with a longer version of
443
         the insn and it is assumed that longer versions of insns appear
444
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
445
      while (isspace (* str))
446
        ++ str;
447
 
448
      if (* str != '\0')
449
        return _("junk at end of line"); /* FIXME: would like to include `str' */
450
 
451
      return NULL;
452
    }
453
 
454
  /* We couldn't parse it.  */
455
  return _("unrecognized instruction");
456
}
457
 
458
/* Main entry point.
459
   This routine is called for each instruction to be assembled.
460
   STR points to the insn to be assembled.
461
   We assume all necessary tables have been initialized.
462
   The assembled instruction, less any fixups, is stored in BUF.
463
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
464
   still needs to be converted to target byte order, otherwise BUF is an array
465
   of bytes in target byte order.
466
   The result is a pointer to the insn's entry in the opcode table,
467
   or NULL if an error occured (an error message will have already been
468
   printed).
469
 
470
   Note that when processing (non-alias) macro-insns,
471
   this function recurses.
472
 
473
   ??? It's possible to make this cpu-independent.
474
   One would have to deal with a few minor things.
475
   At this point in time doing so would be more of a curiosity than useful
476
   [for example this file isn't _that_ big], but keeping the possibility in
477
   mind helps keep the design clean.  */
478
 
479
const CGEN_INSN *
480
m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
481
     CGEN_CPU_DESC cd;
482
     const char *str;
483
     CGEN_FIELDS *fields;
484
     CGEN_INSN_BYTES_PTR buf;
485
     char **errmsg;
486
{
487
  const char *start;
488
  CGEN_INSN_LIST *ilist;
489
  const char *tmp_errmsg;
490
 
491
  /* Skip leading white space.  */
492
  while (isspace (* str))
493
    ++ str;
494
 
495
  /* The instructions are stored in hashed lists.
496
     Get the first in the list.  */
497
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
498
 
499
  /* Keep looking until we find a match.  */
500
 
501
  start = str;
502
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
503
    {
504
      const CGEN_INSN *insn = ilist->insn;
505
 
506
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
507
      /* not usually needed as unsupported opcodes shouldn't be in the hash lists */
508
      /* Is this insn supported by the selected cpu?  */
509
      if (! m32r_cgen_insn_supported (cd, insn))
510
        continue;
511
#endif
512
 
513
      /* If the RELAX attribute is set, this is an insn that shouldn't be
514
         chosen immediately.  Instead, it is used during assembler/linker
515
         relaxation if possible.  */
516
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
517
        continue;
518
 
519
      str = start;
520
 
521
      /* Allow parse/insert handlers to obtain length of insn.  */
522
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
523
 
524
      if (!(tmp_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields)))
525
        {
526
          /* ??? 0 is passed for `pc' */
527
          if (CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, (bfd_vma) 0)
528
              != NULL)
529
            continue;
530
          /* It is up to the caller to actually output the insn and any
531
             queued relocs.  */
532
          return insn;
533
        }
534
 
535
      /* Try the next entry.  */
536
    }
537
 
538
  {
539
    static char errbuf[150];
540
 
541
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
542
    /* if verbose error messages, use errmsg from CGEN_PARSE_FN */
543
    if (strlen (start) > 50)
544
      /* xgettext:c-format */
545
      sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
546
    else
547
      /* xgettext:c-format */
548
      sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
549
#else
550
    if (strlen (start) > 50)
551
      /* xgettext:c-format */
552
      sprintf (errbuf, _("bad instruction `%.50s...'"), start);
553
    else
554
      /* xgettext:c-format */
555
      sprintf (errbuf, _("bad instruction `%.50s'"), start);
556
#endif
557
 
558
    *errmsg = errbuf;
559
    return NULL;
560
  }
561
}
562
 
563
#if 0 /* This calls back to GAS which we can't do without care.  */
564
 
565
/* Record each member of OPVALS in the assembler's symbol table.
566
   This lets GAS parse registers for us.
567
   ??? Interesting idea but not currently used.  */
568
 
569
/* Record each member of OPVALS in the assembler's symbol table.
570
   FIXME: Not currently used.  */
571
 
572
void
573
m32r_cgen_asm_hash_keywords (cd, opvals)
574
     CGEN_CPU_DESC cd;
575
     CGEN_KEYWORD *opvals;
576
{
577
  CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
578
  const CGEN_KEYWORD_ENTRY * ke;
579
 
580
  while ((ke = cgen_keyword_search_next (& search)) != NULL)
581
    {
582
#if 0 /* Unnecessary, should be done in the search routine.  */
583
      if (! m32r_cgen_opval_supported (ke))
584
        continue;
585
#endif
586
      cgen_asm_record_register (cd, ke->name, ke->value);
587
    }
588
}
589
 
590
#endif /* 0 */

powered by: WebSVN 2.1.0

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