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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [openrisc-asm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* 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 1996, 1997, 1998, 1999, 2000, 2001 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 <stdio.h>
30
#include "ansidecl.h"
31
#include "bfd.h"
32
#include "symcat.h"
33
#include "openrisc-desc.h"
34
#include "openrisc-opc.h"
35
#include "opintl.h"
36
#include "xregex.h"
37
#include "libiberty.h"
38
#include "safe-ctype.h"
39
 
40
#undef  min
41
#define min(a,b) ((a) < (b) ? (a) : (b))
42
#undef  max
43
#define max(a,b) ((a) > (b) ? (a) : (b))
44
 
45
static const char * parse_insn_normal
46
     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
47
 
48
/* -- assembler routines inserted here.  */
49
 
50
/* -- asm.c */
51
 
52
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
53
 
54
static const char * parse_hi16
55
  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
56
static const char * parse_lo16
57
  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
58
 
59
long
60
openrisc_sign_extend_16bit (value)
61
     long value;
62
{
63
  return (long) (short) value;
64
}
65
 
66
/* Handle hi().  */
67
 
68
static const char *
69
parse_hi16 (cd, strp, opindex, valuep)
70
     CGEN_CPU_DESC cd;
71
     const char **strp;
72
     int opindex;
73
     unsigned long *valuep;
74
{
75
  const char *errmsg;
76
  enum cgen_parse_operand_result result_type;
77
  bfd_vma value;
78
 
79
  if (**strp == '#')
80
    ++*strp;
81
 
82
  if (strncasecmp (*strp, "hi(", 3) == 0)
83
    {
84
      *strp += 3;
85
 
86
#if 0
87
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
88
      if (errmsg != NULL)
89
        fprintf (stderr, "parse_hi: %s\n", errmsg);
90
      if (errmsg != NULL)
91
#endif
92
        errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
93
                                     &result_type, &value);
94
      if (**strp != ')')
95
        return "missing `)'";
96
      ++*strp;
97
      if (errmsg == NULL
98
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
99
        value >>= 16;
100
      *valuep = (long) (short) value;
101
 
102
      return errmsg;
103
    }
104
  else
105
    {
106
      if (**strp == '-')
107
        errmsg = cgen_parse_signed_integer (cd, strp, opindex, (long *) &value);
108
      else
109
        errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) &value);
110
    }
111
  *valuep = (long) (short) (value & 0xffff);
112
  return errmsg;
113
}
114
 
115
/* Handle lo().  */
116
 
117
static const char *
118
parse_lo16 (cd, strp, opindex, valuep)
119
     CGEN_CPU_DESC cd;
120
     const char **strp;
121
     int opindex;
122
     unsigned long *valuep;
123
{
124
  const char *errmsg;
125
  enum cgen_parse_operand_result result_type;
126
  bfd_vma value;
127
 
128
  if (**strp == '#')
129
    ++*strp;
130
 
131
  if (strncasecmp (*strp, "lo(", 3) == 0)
132
    {
133
      *strp += 3;
134
 
135
#if 0 
136
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
137
      if (errmsg != NULL)
138
        fprintf (stderr, "parse_lo: %s\n", errmsg);
139
 
140
      if (errmsg != NULL)
141
#endif
142
        errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
143
                                     &result_type, &value);
144
      if (**strp != ')')
145
        return "missing `)'";
146
      ++*strp;
147
      if (errmsg == NULL
148
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
149
        value &= 0xffff;
150
      *valuep = (long) (short) value;
151
 
152
      return errmsg;
153
    }
154
 
155
  if (**strp == '-')
156
    errmsg = cgen_parse_signed_integer (cd, strp, opindex, (long *) &value);
157
  else
158
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) &value);
159
  *valuep = (long) (short) (value & 0xffff);
160
  return errmsg;
161
}
162
 
163
/* -- */
164
 
165
const char * openrisc_cgen_parse_operand
166
  PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
167
 
168
/* Main entry point for operand parsing.
169
 
170
   This function is basically just a big switch statement.  Earlier versions
171
   used tables to look up the function to use, but
172
   - if the table contains both assembler and disassembler functions then
173
     the disassembler contains much of the assembler and vice-versa,
174
   - there's a lot of inlining possibilities as things grow,
175
   - using a switch statement avoids the function call overhead.
176
 
177
   This function could be moved into `parse_insn_normal', but keeping it
178
   separate makes clear the interface between `parse_insn_normal' and each of
179
   the handlers.  */
180
 
181
const char *
182
openrisc_cgen_parse_operand (cd, opindex, strp, fields)
183
     CGEN_CPU_DESC cd;
184
     int opindex;
185
     const char ** strp;
186
     CGEN_FIELDS * fields;
187
{
188
  const char * errmsg = NULL;
189
  /* Used by scalar operands that still need to be parsed.  */
190
  long junk ATTRIBUTE_UNUSED;
191
 
192
  switch (opindex)
193
    {
194
    case OPENRISC_OPERAND_ABS_26 :
195
      {
196
        bfd_vma value;
197
        errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_ABS_26, 0, NULL,  & value);
198
        fields->f_abs26 = value;
199
      }
200
      break;
201
    case OPENRISC_OPERAND_DISP_26 :
202
      {
203
        bfd_vma value;
204
        errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_DISP_26, 0, NULL,  & value);
205
        fields->f_disp26 = value;
206
      }
207
      break;
208
    case OPENRISC_OPERAND_HI16 :
209
      errmsg = parse_hi16 (cd, strp, OPENRISC_OPERAND_HI16, &fields->f_simm16);
210
      break;
211
    case OPENRISC_OPERAND_LO16 :
212
      errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_LO16, &fields->f_lo16);
213
      break;
214
    case OPENRISC_OPERAND_OP_F_23 :
215
      errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_23, &fields->f_op4);
216
      break;
217
    case OPENRISC_OPERAND_OP_F_3 :
218
      errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_3, &fields->f_op5);
219
      break;
220
    case OPENRISC_OPERAND_RA :
221
      errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r2);
222
      break;
223
    case OPENRISC_OPERAND_RB :
224
      errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r3);
225
      break;
226
    case OPENRISC_OPERAND_RD :
227
      errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r1);
228
      break;
229
    case OPENRISC_OPERAND_SIMM_16 :
230
      errmsg = cgen_parse_signed_integer (cd, strp, OPENRISC_OPERAND_SIMM_16, &fields->f_simm16);
231
      break;
232
    case OPENRISC_OPERAND_UI16NC :
233
      errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_UI16NC, &fields->f_i16nc);
234
      break;
235
    case OPENRISC_OPERAND_UIMM_16 :
236
      errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_16, &fields->f_uimm16);
237
      break;
238
    case OPENRISC_OPERAND_UIMM_5 :
239
      errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_5, &fields->f_uimm5);
240
      break;
241
 
242
    default :
243
      /* xgettext:c-format */
244
      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
245
      abort ();
246
  }
247
 
248
  return errmsg;
249
}
250
 
251
cgen_parse_fn * const openrisc_cgen_parse_handlers[] =
252
{
253
  parse_insn_normal,
254
};
255
 
256
void
257
openrisc_cgen_init_asm (cd)
258
     CGEN_CPU_DESC cd;
259
{
260
  openrisc_cgen_init_opcode_table (cd);
261
  openrisc_cgen_init_ibld_table (cd);
262
  cd->parse_handlers = & openrisc_cgen_parse_handlers[0];
263
  cd->parse_operand = openrisc_cgen_parse_operand;
264
}
265
 
266
 
267
 
268
/* Regex construction routine.
269
 
270
   This translates an opcode syntax string into a regex string,
271
   by replacing any non-character syntax element (such as an
272
   opcode) with the pattern '.*'
273
 
274
   It then compiles the regex and stores it in the opcode, for
275
   later use by openrisc_cgen_assemble_insn
276
 
277
   Returns NULL for success, an error message for failure.  */
278
 
279
char *
280
openrisc_cgen_build_insn_regex (insn)
281
     CGEN_INSN *insn;
282
{
283
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
284
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
285
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
286
  char *rx = rxbuf;
287
  const CGEN_SYNTAX_CHAR_TYPE *syn;
288
  int reg_err;
289
 
290
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
291
 
292
  /* Mnemonics come first in the syntax string.  */
293
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
294
    return _("missing mnemonic in syntax string");
295
  ++syn;
296
 
297
  /* Generate a case sensitive regular expression that emulates case
298
     insensitive matching in the "C" locale.  We cannot generate a case
299
     insensitive regular expression because in Turkish locales, 'i' and 'I'
300
     are not equal modulo case conversion.  */
301
 
302
  /* Copy the literal mnemonic out of the insn.  */
303
  for (; *mnem; mnem++)
304
    {
305
      char c = *mnem;
306
 
307
      if (ISALPHA (c))
308
        {
309
          *rx++ = '[';
310
          *rx++ = TOLOWER (c);
311
          *rx++ = TOUPPER (c);
312
          *rx++ = ']';
313
        }
314
      else
315
        *rx++ = c;
316
    }
317
 
318
  /* Copy any remaining literals from the syntax string into the rx.  */
319
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
320
    {
321
      if (CGEN_SYNTAX_CHAR_P (* syn))
322
        {
323
          char c = CGEN_SYNTAX_CHAR (* syn);
324
 
325
          switch (c)
326
            {
327
              /* Escape any regex metacharacters in the syntax.  */
328
            case '.': case '[': case '\\':
329
            case '*': case '^': case '$':
330
 
331
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
332
            case '?': case '{': case '}':
333
            case '(': case ')': case '*':
334
            case '|': case '+': case ']':
335
#endif
336
              *rx++ = '\\';
337
              *rx++ = c;
338
              break;
339
 
340
            default:
341
              if (ISALPHA (c))
342
                {
343
                  *rx++ = '[';
344
                  *rx++ = TOLOWER (c);
345
                  *rx++ = TOUPPER (c);
346
                  *rx++ = ']';
347
                }
348
              else
349
                *rx++ = c;
350
              break;
351
            }
352
        }
353
      else
354
        {
355
          /* Replace non-syntax fields with globs.  */
356
          *rx++ = '.';
357
          *rx++ = '*';
358
        }
359
    }
360
 
361
  /* Trailing whitespace ok.  */
362
  * rx++ = '[';
363
  * rx++ = ' ';
364
  * rx++ = '\t';
365
  * rx++ = ']';
366
  * rx++ = '*';
367
 
368
  /* But anchor it after that.  */
369
  * rx++ = '$';
370
  * rx = '\0';
371
 
372
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
373
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
374
 
375
  if (reg_err == 0)
376
    return NULL;
377
  else
378
    {
379
      static char msg[80];
380
 
381
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
382
      regfree ((regex_t *) CGEN_INSN_RX (insn));
383
      free (CGEN_INSN_RX (insn));
384
      (CGEN_INSN_RX (insn)) = NULL;
385
      return msg;
386
    }
387
}
388
 
389
 
390
/* Default insn parser.
391
 
392
   The syntax string is scanned and operands are parsed and stored in FIELDS.
393
   Relocs are queued as we go via other callbacks.
394
 
395
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
396
   parse the instruction, we return 0 and the caller will start over from
397
   the beginning.  Backtracking will be necessary in parsing subexpressions,
398
   but that can be handled there.  Not handling backtracking here may get
399
   expensive in the case of the m68k.  Deal with later.
400
 
401
   Returns NULL for success, an error message for failure.  */
402
 
403
static const char *
404
parse_insn_normal (cd, insn, strp, fields)
405
     CGEN_CPU_DESC cd;
406
     const CGEN_INSN *insn;
407
     const char **strp;
408
     CGEN_FIELDS *fields;
409
{
410
  /* ??? Runtime added insns not handled yet.  */
411
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
412
  const char *str = *strp;
413
  const char *errmsg;
414
  const char *p;
415
  const CGEN_SYNTAX_CHAR_TYPE * syn;
416
#ifdef CGEN_MNEMONIC_OPERANDS
417
  /* FIXME: wip */
418
  int past_opcode_p;
419
#endif
420
 
421
  /* For now we assume the mnemonic is first (there are no leading operands).
422
     We can parse it without needing to set up operand parsing.
423
     GAS's input scrubber will ensure mnemonics are lowercase, but we may
424
     not be called from GAS.  */
425
  p = CGEN_INSN_MNEMONIC (insn);
426
  while (*p && TOLOWER (*p) == TOLOWER (*str))
427
    ++p, ++str;
428
 
429
  if (* p)
430
    return _("unrecognized instruction");
431
 
432
#ifndef CGEN_MNEMONIC_OPERANDS
433
  if (* str && ! ISSPACE (* str))
434
    return _("unrecognized instruction");
435
#endif
436
 
437
  CGEN_INIT_PARSE (cd);
438
  cgen_init_parse_operand (cd);
439
#ifdef CGEN_MNEMONIC_OPERANDS
440
  past_opcode_p = 0;
441
#endif
442
 
443
  /* We don't check for (*str != '\0') here because we want to parse
444
     any trailing fake arguments in the syntax string.  */
445
  syn = CGEN_SYNTAX_STRING (syntax);
446
 
447
  /* Mnemonics come first for now, ensure valid string.  */
448
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
449
    abort ();
450
 
451
  ++syn;
452
 
453
  while (* syn != 0)
454
    {
455
      /* Non operand chars must match exactly.  */
456
      if (CGEN_SYNTAX_CHAR_P (* syn))
457
        {
458
          /* FIXME: While we allow for non-GAS callers above, we assume the
459
             first char after the mnemonic part is a space.  */
460
          /* FIXME: We also take inappropriate advantage of the fact that
461
             GAS's input scrubber will remove extraneous blanks.  */
462
          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
463
            {
464
#ifdef CGEN_MNEMONIC_OPERANDS
465
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
466
                past_opcode_p = 1;
467
#endif
468
              ++ syn;
469
              ++ str;
470
            }
471
          else if (*str)
472
            {
473
              /* Syntax char didn't match.  Can't be this insn.  */
474
              static char msg [80];
475
 
476
              /* xgettext:c-format */
477
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
478
                       CGEN_SYNTAX_CHAR(*syn), *str);
479
              return msg;
480
            }
481
          else
482
            {
483
              /* Ran out of input.  */
484
              static char msg [80];
485
 
486
              /* xgettext:c-format */
487
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
488
                       CGEN_SYNTAX_CHAR(*syn));
489
              return msg;
490
            }
491
          continue;
492
        }
493
 
494
      /* We have an operand of some sort.  */
495
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
496
                                          &str, fields);
497
      if (errmsg)
498
        return errmsg;
499
 
500
      /* Done with this operand, continue with next one.  */
501
      ++ syn;
502
    }
503
 
504
  /* If we're at the end of the syntax string, we're done.  */
505
  if (* syn == 0)
506
    {
507
      /* FIXME: For the moment we assume a valid `str' can only contain
508
         blanks now.  IE: We needn't try again with a longer version of
509
         the insn and it is assumed that longer versions of insns appear
510
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
511
      while (ISSPACE (* str))
512
        ++ str;
513
 
514
      if (* str != '\0')
515
        return _("junk at end of line"); /* FIXME: would like to include `str' */
516
 
517
      return NULL;
518
    }
519
 
520
  /* We couldn't parse it.  */
521
  return _("unrecognized instruction");
522
}
523
 
524
/* Main entry point.
525
   This routine is called for each instruction to be assembled.
526
   STR points to the insn to be assembled.
527
   We assume all necessary tables have been initialized.
528
   The assembled instruction, less any fixups, is stored in BUF.
529
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
530
   still needs to be converted to target byte order, otherwise BUF is an array
531
   of bytes in target byte order.
532
   The result is a pointer to the insn's entry in the opcode table,
533
   or NULL if an error occured (an error message will have already been
534
   printed).
535
 
536
   Note that when processing (non-alias) macro-insns,
537
   this function recurses.
538
 
539
   ??? It's possible to make this cpu-independent.
540
   One would have to deal with a few minor things.
541
   At this point in time doing so would be more of a curiosity than useful
542
   [for example this file isn't _that_ big], but keeping the possibility in
543
   mind helps keep the design clean.  */
544
 
545
const CGEN_INSN *
546
openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
547
     CGEN_CPU_DESC cd;
548
     const char *str;
549
     CGEN_FIELDS *fields;
550
     CGEN_INSN_BYTES_PTR buf;
551
     char **errmsg;
552
{
553
  const char *start;
554
  CGEN_INSN_LIST *ilist;
555
  const char *parse_errmsg = NULL;
556
  const char *insert_errmsg = NULL;
557
  int recognized_mnemonic = 0;
558
 
559
  /* Skip leading white space.  */
560
  while (ISSPACE (* str))
561
    ++ str;
562
 
563
  /* The instructions are stored in hashed lists.
564
     Get the first in the list.  */
565
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
566
 
567
  /* Keep looking until we find a match.  */
568
  start = str;
569
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
570
    {
571
      const CGEN_INSN *insn = ilist->insn;
572
      recognized_mnemonic = 1;
573
 
574
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
575
      /* Not usually needed as unsupported opcodes
576
         shouldn't be in the hash lists.  */
577
      /* Is this insn supported by the selected cpu?  */
578
      if (! openrisc_cgen_insn_supported (cd, insn))
579
        continue;
580
#endif
581
      /* If the RELAX attribute is set, this is an insn that shouldn't be
582
         chosen immediately.  Instead, it is used during assembler/linker
583
         relaxation if possible.  */
584
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
585
        continue;
586
 
587
      str = start;
588
 
589
      /* Skip this insn if str doesn't look right lexically.  */
590
      if (CGEN_INSN_RX (insn) != NULL &&
591
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
592
        continue;
593
 
594
      /* Allow parse/insert handlers to obtain length of insn.  */
595
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
596
 
597
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
598
      if (parse_errmsg != NULL)
599
        continue;
600
 
601
      /* ??? 0 is passed for `pc'.  */
602
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
603
                                                 (bfd_vma) 0);
604
      if (insert_errmsg != NULL)
605
        continue;
606
 
607
      /* It is up to the caller to actually output the insn and any
608
         queued relocs.  */
609
      return insn;
610
    }
611
 
612
  {
613
    static char errbuf[150];
614
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
615
    const char *tmp_errmsg;
616
 
617
    /* If requesting verbose error messages, use insert_errmsg.
618
       Failing that, use parse_errmsg.  */
619
    tmp_errmsg = (insert_errmsg ? insert_errmsg :
620
                  parse_errmsg ? parse_errmsg :
621
                  recognized_mnemonic ?
622
                  _("unrecognized form of instruction") :
623
                  _("unrecognized instruction"));
624
 
625
    if (strlen (start) > 50)
626
      /* xgettext:c-format */
627
      sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
628
    else
629
      /* xgettext:c-format */
630
      sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
631
#else
632
    if (strlen (start) > 50)
633
      /* xgettext:c-format */
634
      sprintf (errbuf, _("bad instruction `%.50s...'"), start);
635
    else
636
      /* xgettext:c-format */
637
      sprintf (errbuf, _("bad instruction `%.50s'"), start);
638
#endif
639
 
640
    *errmsg = errbuf;
641
    return NULL;
642
  }
643
}
644
 
645
#if 0 /* This calls back to GAS which we can't do without care.  */
646
 
647
/* Record each member of OPVALS in the assembler's symbol table.
648
   This lets GAS parse registers for us.
649
   ??? Interesting idea but not currently used.  */
650
 
651
/* Record each member of OPVALS in the assembler's symbol table.
652
   FIXME: Not currently used.  */
653
 
654
void
655
openrisc_cgen_asm_hash_keywords (cd, opvals)
656
     CGEN_CPU_DESC cd;
657
     CGEN_KEYWORD *opvals;
658
{
659
  CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
660
  const CGEN_KEYWORD_ENTRY * ke;
661
 
662
  while ((ke = cgen_keyword_search_next (& search)) != NULL)
663
    {
664
#if 0 /* Unnecessary, should be done in the search routine.  */
665
      if (! openrisc_cgen_opval_supported (ke))
666
        continue;
667
#endif
668
      cgen_asm_record_register (cd, ke->name, ke->value);
669
    }
670
}
671
 
672
#endif /* 0 */

powered by: WebSVN 2.1.0

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