or1k: Add relocations for high-signed and low-stores
[external/binutils.git] / opcodes / or1k-asm.c
1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2 /* Assembler interface for targets using CGEN. -*- C -*-
3    CGEN: Cpu tools GENerator
4
5    THIS FILE IS MACHINE GENERATED WITH CGEN.
6    - the resultant file is machine generated, cgen-asm.in isn't
7
8    Copyright (C) 1996-2018 Free Software Foundation, Inc.
9
10    This file is part of libopcodes.
11
12    This library is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3, or (at your option)
15    any later version.
16
17    It is distributed in the hope that it will be useful, but WITHOUT
18    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20    License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software Foundation, Inc.,
24    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25
26
27 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
28    Keep that in mind.  */
29
30 #include "sysdep.h"
31 #include <stdio.h>
32 #include "ansidecl.h"
33 #include "bfd.h"
34 #include "symcat.h"
35 #include "or1k-desc.h"
36 #include "or1k-opc.h"
37 #include "opintl.h"
38 #include "xregex.h"
39 #include "libiberty.h"
40 #include "safe-ctype.h"
41
42 #undef  min
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #undef  max
45 #define max(a,b) ((a) > (b) ? (a) : (b))
46
47 static const char * parse_insn_normal
48   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
49 \f
50 /* -- assembler routines inserted here.  */
51
52 /* -- asm.c */
53
54 static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
55 static const char * INVALID_STORE_RELOC = N_("relocation invalid for store");
56 static const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid");
57
58 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
59
60 static const char *
61 parse_disp26 (CGEN_CPU_DESC cd,
62               const char ** strp,
63               int opindex,
64               int opinfo,
65               enum cgen_parse_operand_result * resultp,
66               bfd_vma * valuep)
67 {
68   const char *errmsg = NULL;
69   enum cgen_parse_operand_result result_type;
70
71   if (strncasecmp (*strp, "plt(", 4) == 0)
72     {
73       bfd_vma value;
74
75       *strp += 4;
76       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
77                                    & result_type, & value);
78       if (**strp != ')')
79         return MISSING_CLOSING_PARENTHESIS;
80       ++*strp;
81       if (errmsg == NULL
82           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
83         value = (value >> 2) & 0xffff;
84       *valuep = value;
85       return errmsg;
86     }
87   return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
88 }
89
90 enum {
91   RTYPE_LO = 0,
92   RTYPE_HI = 1,
93   RTYPE_AHI = 2,
94   RTYPE_SLO = 3,
95
96   RTYPE_GOT      = (1 << 2),
97   RTYPE_GOTPC    = (2 << 2),
98   RTYPE_GOTOFF   = (3 << 2),
99   RTYPE_TLSGD    = (4 << 2),
100   RTYPE_TLSLDM   = (5 << 2),
101   RTYPE_DTPOFF   = (6 << 2),
102   RTYPE_GOTTPOFF = (7 << 2),
103   RTYPE_TPOFF    = (8 << 2),
104 };
105
106 static const bfd_reloc_code_real_type or1k_imm16_relocs[][4] = {
107   { BFD_RELOC_LO16,
108     BFD_RELOC_HI16,
109     BFD_RELOC_HI16_S,
110     BFD_RELOC_OR1K_SLO16 },
111   { BFD_RELOC_OR1K_GOT16,
112     BFD_RELOC_UNUSED,
113     BFD_RELOC_UNUSED,
114     BFD_RELOC_UNUSED },
115   { BFD_RELOC_OR1K_GOTPC_LO16,
116     BFD_RELOC_OR1K_GOTPC_HI16,
117     BFD_RELOC_UNUSED,
118     BFD_RELOC_UNUSED },
119   { BFD_RELOC_LO16_GOTOFF,
120     BFD_RELOC_HI16_GOTOFF,
121     BFD_RELOC_HI16_S_GOTOFF,
122     BFD_RELOC_OR1K_GOTOFF_SLO16 },
123   { BFD_RELOC_OR1K_TLS_GD_LO16,
124     BFD_RELOC_OR1K_TLS_GD_HI16,
125     BFD_RELOC_UNUSED,
126     BFD_RELOC_UNUSED },
127   { BFD_RELOC_OR1K_TLS_LDM_LO16,
128     BFD_RELOC_OR1K_TLS_LDM_HI16,
129     BFD_RELOC_UNUSED,
130     BFD_RELOC_UNUSED },
131   { BFD_RELOC_OR1K_TLS_LDO_LO16,
132     BFD_RELOC_OR1K_TLS_LDO_HI16,
133     BFD_RELOC_UNUSED,
134     BFD_RELOC_UNUSED },
135   { BFD_RELOC_OR1K_TLS_IE_LO16,
136     BFD_RELOC_OR1K_TLS_IE_HI16,
137     BFD_RELOC_OR1K_TLS_IE_AHI16,
138     BFD_RELOC_UNUSED },
139   { BFD_RELOC_OR1K_TLS_LE_LO16,
140     BFD_RELOC_OR1K_TLS_LE_HI16,
141     BFD_RELOC_OR1K_TLS_LE_AHI16,
142     BFD_RELOC_OR1K_TLS_LE_SLO16 }
143 };
144
145 static int
146 parse_reloc(const char **strp)
147 {
148     const char *str = *strp;
149     int ret = 0;
150
151     if (strncasecmp (str, "got(", 4) == 0)
152         {
153         *strp = str + 4;
154         return RTYPE_GOT | RTYPE_LO;
155         }
156
157     if (strncasecmp (str, "gotpc", 5) == 0)
158         {
159         str += 5;
160         ret = RTYPE_GOTPC;
161         }
162     else if (strncasecmp (str, "gotoff", 6) == 0)
163     {
164         str += 6;
165         ret = RTYPE_GOTOFF;
166     }
167     else if (strncasecmp (str, "tlsgd", 5) == 0)
168     {
169         str += 5;
170         ret = RTYPE_TLSGD;
171     }
172     else if (strncasecmp (str, "tlsldm", 6) == 0)
173     {
174         str += 6;
175         ret = RTYPE_TLSLDM;
176     }
177     else if (strncasecmp (str, "dtpoff", 6) == 0)
178     {
179         str += 6;
180         ret = RTYPE_DTPOFF;
181     }
182     else if (strncasecmp (str, "gottpoff", 8) == 0)
183     {
184         str += 8;
185         ret = RTYPE_GOTTPOFF;
186     }
187     else if (strncasecmp (str, "tpoff", 5) == 0)
188     {
189         str += 5;
190         ret = RTYPE_TPOFF;
191     }
192
193     if (strncasecmp (str, "hi(", 3) == 0)
194     {
195         str += 3;
196         ret |= RTYPE_HI;
197     }
198     else if (strncasecmp (str, "lo(", 3) == 0)
199     {
200         str += 3;
201         ret |= RTYPE_LO;
202     }
203     else if (strncasecmp (str, "ha(", 3) == 0)
204     {
205         str += 3;
206         ret |= RTYPE_AHI;
207     }
208     else
209       return -1;
210
211     *strp = str;
212     return ret;
213 }
214
215 static const char *
216 parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
217              long *valuep, int splitp)
218 {
219   const char *errmsg;
220   enum cgen_parse_operand_result result_type;
221   bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
222   int reloc_type;
223   bfd_vma ret;
224
225   if (**strp == '#')
226       ++*strp;
227
228   reloc_type = parse_reloc (strp);
229   if (reloc_type >= 0)
230     {
231       if (splitp)
232         {
233           if ((reloc_type & 3) == RTYPE_LO && reloc_type != RTYPE_GOT)
234             reloc_type |= RTYPE_SLO;
235           else
236             return INVALID_STORE_RELOC;
237     }
238       reloc = or1k_imm16_relocs[reloc_type >> 2][reloc_type & 3];
239     }
240
241   if (reloc != BFD_RELOC_UNUSED)
242     {
243       bfd_vma value;
244
245       errmsg = cgen_parse_address (cd, strp, opindex, reloc,
246                                    &result_type, &value);
247       if (**strp != ')')
248         errmsg = MISSING_CLOSING_PARENTHESIS;
249       ++*strp;
250
251       ret = value;
252
253       if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
254         switch (reloc_type & 3)
255     {
256           case RTYPE_AHI:
257             ret += 0x8000;
258             /* FALLTHRU */
259           case RTYPE_HI:
260             ret >>= 16;
261             /* FALLTHRU */
262           case RTYPE_LO:
263           case RTYPE_SLO:
264             ret &= 0xffff;
265             ret = (ret ^ 0x8000) - 0x8000;
266             break;
267           default:
268             errmsg = INVALID_RELOC_TYPE;
269           }
270     }
271   else
272     {
273       long value;
274       errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
275       ret = value;
276     }
277
278   if (errmsg == NULL)
279     *valuep = ret;
280
281   return errmsg;
282 }
283
284 static const char *
285 parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
286 {
287   return parse_imm16(cd, strp, opindex, (long *) valuep, 0);
288 }
289
290 static const char *
291 parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
292                     long *valuep)
293 {
294   return parse_imm16(cd, strp, opindex, (long *) valuep, 1);
295 }
296
297 static const char *
298 parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
299               unsigned long *valuep)
300 {
301   const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0);
302   if (errmsg == NULL)
303     *valuep &= 0xffff;
304   return errmsg;
305 }
306
307 static const char *
308 parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
309                     unsigned long *valuep)
310 {
311   const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1);
312   if (errmsg == NULL)
313     *valuep &= 0xffff;
314   return errmsg;
315 }
316
317 /* -- */
318
319 const char * or1k_cgen_parse_operand
320   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
321
322 /* Main entry point for operand parsing.
323
324    This function is basically just a big switch statement.  Earlier versions
325    used tables to look up the function to use, but
326    - if the table contains both assembler and disassembler functions then
327      the disassembler contains much of the assembler and vice-versa,
328    - there's a lot of inlining possibilities as things grow,
329    - using a switch statement avoids the function call overhead.
330
331    This function could be moved into `parse_insn_normal', but keeping it
332    separate makes clear the interface between `parse_insn_normal' and each of
333    the handlers.  */
334
335 const char *
336 or1k_cgen_parse_operand (CGEN_CPU_DESC cd,
337                            int opindex,
338                            const char ** strp,
339                            CGEN_FIELDS * fields)
340 {
341   const char * errmsg = NULL;
342   /* Used by scalar operands that still need to be parsed.  */
343   long junk ATTRIBUTE_UNUSED;
344
345   switch (opindex)
346     {
347     case OR1K_OPERAND_DISP26 :
348       {
349         bfd_vma value = 0;
350         errmsg = parse_disp26 (cd, strp, OR1K_OPERAND_DISP26, 0, NULL,  & value);
351         fields->f_disp26 = value;
352       }
353       break;
354     case OR1K_OPERAND_RA :
355       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r2);
356       break;
357     case OR1K_OPERAND_RADF :
358       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
359       break;
360     case OR1K_OPERAND_RASF :
361       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r2);
362       break;
363     case OR1K_OPERAND_RB :
364       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r3);
365       break;
366     case OR1K_OPERAND_RBDF :
367       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
368       break;
369     case OR1K_OPERAND_RBSF :
370       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r3);
371       break;
372     case OR1K_OPERAND_RD :
373       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r1);
374       break;
375     case OR1K_OPERAND_RDDF :
376       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
377       break;
378     case OR1K_OPERAND_RDSF :
379       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r1);
380       break;
381     case OR1K_OPERAND_SIMM16 :
382       errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16, (long *) (& fields->f_simm16));
383       break;
384     case OR1K_OPERAND_SIMM16_SPLIT :
385       errmsg = parse_simm16_split (cd, strp, OR1K_OPERAND_SIMM16_SPLIT, (long *) (& fields->f_simm16_split));
386       break;
387     case OR1K_OPERAND_UIMM16 :
388       errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16));
389       break;
390     case OR1K_OPERAND_UIMM16_SPLIT :
391       errmsg = parse_uimm16_split (cd, strp, OR1K_OPERAND_UIMM16_SPLIT, (unsigned long *) (& fields->f_uimm16_split));
392       break;
393     case OR1K_OPERAND_UIMM6 :
394       errmsg = cgen_parse_unsigned_integer (cd, strp, OR1K_OPERAND_UIMM6, (unsigned long *) (& fields->f_uimm6));
395       break;
396
397     default :
398       /* xgettext:c-format */
399       opcodes_error_handler
400         (_("internal error: unrecognized field %d while parsing"),
401          opindex);
402       abort ();
403   }
404
405   return errmsg;
406 }
407
408 cgen_parse_fn * const or1k_cgen_parse_handlers[] =
409 {
410   parse_insn_normal,
411 };
412
413 void
414 or1k_cgen_init_asm (CGEN_CPU_DESC cd)
415 {
416   or1k_cgen_init_opcode_table (cd);
417   or1k_cgen_init_ibld_table (cd);
418   cd->parse_handlers = & or1k_cgen_parse_handlers[0];
419   cd->parse_operand = or1k_cgen_parse_operand;
420 #ifdef CGEN_ASM_INIT_HOOK
421 CGEN_ASM_INIT_HOOK
422 #endif
423 }
424
425 \f
426
427 /* Regex construction routine.
428
429    This translates an opcode syntax string into a regex string,
430    by replacing any non-character syntax element (such as an
431    opcode) with the pattern '.*'
432
433    It then compiles the regex and stores it in the opcode, for
434    later use by or1k_cgen_assemble_insn
435
436    Returns NULL for success, an error message for failure.  */
437
438 char *
439 or1k_cgen_build_insn_regex (CGEN_INSN *insn)
440 {
441   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
442   const char *mnem = CGEN_INSN_MNEMONIC (insn);
443   char rxbuf[CGEN_MAX_RX_ELEMENTS];
444   char *rx = rxbuf;
445   const CGEN_SYNTAX_CHAR_TYPE *syn;
446   int reg_err;
447
448   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
449
450   /* Mnemonics come first in the syntax string.  */
451   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
452     return _("missing mnemonic in syntax string");
453   ++syn;
454
455   /* Generate a case sensitive regular expression that emulates case
456      insensitive matching in the "C" locale.  We cannot generate a case
457      insensitive regular expression because in Turkish locales, 'i' and 'I'
458      are not equal modulo case conversion.  */
459
460   /* Copy the literal mnemonic out of the insn.  */
461   for (; *mnem; mnem++)
462     {
463       char c = *mnem;
464
465       if (ISALPHA (c))
466         {
467           *rx++ = '[';
468           *rx++ = TOLOWER (c);
469           *rx++ = TOUPPER (c);
470           *rx++ = ']';
471         }
472       else
473         *rx++ = c;
474     }
475
476   /* Copy any remaining literals from the syntax string into the rx.  */
477   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
478     {
479       if (CGEN_SYNTAX_CHAR_P (* syn))
480         {
481           char c = CGEN_SYNTAX_CHAR (* syn);
482
483           switch (c)
484             {
485               /* Escape any regex metacharacters in the syntax.  */
486             case '.': case '[': case '\\':
487             case '*': case '^': case '$':
488
489 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
490             case '?': case '{': case '}':
491             case '(': case ')': case '*':
492             case '|': case '+': case ']':
493 #endif
494               *rx++ = '\\';
495               *rx++ = c;
496               break;
497
498             default:
499               if (ISALPHA (c))
500                 {
501                   *rx++ = '[';
502                   *rx++ = TOLOWER (c);
503                   *rx++ = TOUPPER (c);
504                   *rx++ = ']';
505                 }
506               else
507                 *rx++ = c;
508               break;
509             }
510         }
511       else
512         {
513           /* Replace non-syntax fields with globs.  */
514           *rx++ = '.';
515           *rx++ = '*';
516         }
517     }
518
519   /* Trailing whitespace ok.  */
520   * rx++ = '[';
521   * rx++ = ' ';
522   * rx++ = '\t';
523   * rx++ = ']';
524   * rx++ = '*';
525
526   /* But anchor it after that.  */
527   * rx++ = '$';
528   * rx = '\0';
529
530   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
531   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
532
533   if (reg_err == 0)
534     return NULL;
535   else
536     {
537       static char msg[80];
538
539       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
540       regfree ((regex_t *) CGEN_INSN_RX (insn));
541       free (CGEN_INSN_RX (insn));
542       (CGEN_INSN_RX (insn)) = NULL;
543       return msg;
544     }
545 }
546
547 \f
548 /* Default insn parser.
549
550    The syntax string is scanned and operands are parsed and stored in FIELDS.
551    Relocs are queued as we go via other callbacks.
552
553    ??? Note that this is currently an all-or-nothing parser.  If we fail to
554    parse the instruction, we return 0 and the caller will start over from
555    the beginning.  Backtracking will be necessary in parsing subexpressions,
556    but that can be handled there.  Not handling backtracking here may get
557    expensive in the case of the m68k.  Deal with later.
558
559    Returns NULL for success, an error message for failure.  */
560
561 static const char *
562 parse_insn_normal (CGEN_CPU_DESC cd,
563                    const CGEN_INSN *insn,
564                    const char **strp,
565                    CGEN_FIELDS *fields)
566 {
567   /* ??? Runtime added insns not handled yet.  */
568   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
569   const char *str = *strp;
570   const char *errmsg;
571   const char *p;
572   const CGEN_SYNTAX_CHAR_TYPE * syn;
573 #ifdef CGEN_MNEMONIC_OPERANDS
574   /* FIXME: wip */
575   int past_opcode_p;
576 #endif
577
578   /* For now we assume the mnemonic is first (there are no leading operands).
579      We can parse it without needing to set up operand parsing.
580      GAS's input scrubber will ensure mnemonics are lowercase, but we may
581      not be called from GAS.  */
582   p = CGEN_INSN_MNEMONIC (insn);
583   while (*p && TOLOWER (*p) == TOLOWER (*str))
584     ++p, ++str;
585
586   if (* p)
587     return _("unrecognized instruction");
588
589 #ifndef CGEN_MNEMONIC_OPERANDS
590   if (* str && ! ISSPACE (* str))
591     return _("unrecognized instruction");
592 #endif
593
594   CGEN_INIT_PARSE (cd);
595   cgen_init_parse_operand (cd);
596 #ifdef CGEN_MNEMONIC_OPERANDS
597   past_opcode_p = 0;
598 #endif
599
600   /* We don't check for (*str != '\0') here because we want to parse
601      any trailing fake arguments in the syntax string.  */
602   syn = CGEN_SYNTAX_STRING (syntax);
603
604   /* Mnemonics come first for now, ensure valid string.  */
605   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
606     abort ();
607
608   ++syn;
609
610   while (* syn != 0)
611     {
612       /* Non operand chars must match exactly.  */
613       if (CGEN_SYNTAX_CHAR_P (* syn))
614         {
615           /* FIXME: While we allow for non-GAS callers above, we assume the
616              first char after the mnemonic part is a space.  */
617           /* FIXME: We also take inappropriate advantage of the fact that
618              GAS's input scrubber will remove extraneous blanks.  */
619           if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
620             {
621 #ifdef CGEN_MNEMONIC_OPERANDS
622               if (CGEN_SYNTAX_CHAR(* syn) == ' ')
623                 past_opcode_p = 1;
624 #endif
625               ++ syn;
626               ++ str;
627             }
628           else if (*str)
629             {
630               /* Syntax char didn't match.  Can't be this insn.  */
631               static char msg [80];
632
633               /* xgettext:c-format */
634               sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
635                        CGEN_SYNTAX_CHAR(*syn), *str);
636               return msg;
637             }
638           else
639             {
640               /* Ran out of input.  */
641               static char msg [80];
642
643               /* xgettext:c-format */
644               sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
645                        CGEN_SYNTAX_CHAR(*syn));
646               return msg;
647             }
648           continue;
649         }
650
651 #ifdef CGEN_MNEMONIC_OPERANDS
652       (void) past_opcode_p;
653 #endif
654       /* We have an operand of some sort.  */
655       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
656       if (errmsg)
657         return errmsg;
658
659       /* Done with this operand, continue with next one.  */
660       ++ syn;
661     }
662
663   /* If we're at the end of the syntax string, we're done.  */
664   if (* syn == 0)
665     {
666       /* FIXME: For the moment we assume a valid `str' can only contain
667          blanks now.  IE: We needn't try again with a longer version of
668          the insn and it is assumed that longer versions of insns appear
669          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
670       while (ISSPACE (* str))
671         ++ str;
672
673       if (* str != '\0')
674         return _("junk at end of line"); /* FIXME: would like to include `str' */
675
676       return NULL;
677     }
678
679   /* We couldn't parse it.  */
680   return _("unrecognized instruction");
681 }
682 \f
683 /* Main entry point.
684    This routine is called for each instruction to be assembled.
685    STR points to the insn to be assembled.
686    We assume all necessary tables have been initialized.
687    The assembled instruction, less any fixups, is stored in BUF.
688    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
689    still needs to be converted to target byte order, otherwise BUF is an array
690    of bytes in target byte order.
691    The result is a pointer to the insn's entry in the opcode table,
692    or NULL if an error occured (an error message will have already been
693    printed).
694
695    Note that when processing (non-alias) macro-insns,
696    this function recurses.
697
698    ??? It's possible to make this cpu-independent.
699    One would have to deal with a few minor things.
700    At this point in time doing so would be more of a curiosity than useful
701    [for example this file isn't _that_ big], but keeping the possibility in
702    mind helps keep the design clean.  */
703
704 const CGEN_INSN *
705 or1k_cgen_assemble_insn (CGEN_CPU_DESC cd,
706                            const char *str,
707                            CGEN_FIELDS *fields,
708                            CGEN_INSN_BYTES_PTR buf,
709                            char **errmsg)
710 {
711   const char *start;
712   CGEN_INSN_LIST *ilist;
713   const char *parse_errmsg = NULL;
714   const char *insert_errmsg = NULL;
715   int recognized_mnemonic = 0;
716
717   /* Skip leading white space.  */
718   while (ISSPACE (* str))
719     ++ str;
720
721   /* The instructions are stored in hashed lists.
722      Get the first in the list.  */
723   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
724
725   /* Keep looking until we find a match.  */
726   start = str;
727   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
728     {
729       const CGEN_INSN *insn = ilist->insn;
730       recognized_mnemonic = 1;
731
732 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
733       /* Not usually needed as unsupported opcodes
734          shouldn't be in the hash lists.  */
735       /* Is this insn supported by the selected cpu?  */
736       if (! or1k_cgen_insn_supported (cd, insn))
737         continue;
738 #endif
739       /* If the RELAXED attribute is set, this is an insn that shouldn't be
740          chosen immediately.  Instead, it is used during assembler/linker
741          relaxation if possible.  */
742       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
743         continue;
744
745       str = start;
746
747       /* Skip this insn if str doesn't look right lexically.  */
748       if (CGEN_INSN_RX (insn) != NULL &&
749           regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
750         continue;
751
752       /* Allow parse/insert handlers to obtain length of insn.  */
753       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
754
755       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
756       if (parse_errmsg != NULL)
757         continue;
758
759       /* ??? 0 is passed for `pc'.  */
760       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
761                                                  (bfd_vma) 0);
762       if (insert_errmsg != NULL)
763         continue;
764
765       /* It is up to the caller to actually output the insn and any
766          queued relocs.  */
767       return insn;
768     }
769
770   {
771     static char errbuf[150];
772     const char *tmp_errmsg;
773 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
774 #define be_verbose 1
775 #else
776 #define be_verbose 0
777 #endif
778
779     if (be_verbose)
780       {
781         /* If requesting verbose error messages, use insert_errmsg.
782            Failing that, use parse_errmsg.  */
783         tmp_errmsg = (insert_errmsg ? insert_errmsg :
784                       parse_errmsg ? parse_errmsg :
785                       recognized_mnemonic ?
786                       _("unrecognized form of instruction") :
787                       _("unrecognized instruction"));
788
789         if (strlen (start) > 50)
790           /* xgettext:c-format */
791           sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
792         else
793           /* xgettext:c-format */
794           sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
795       }
796     else
797       {
798         if (strlen (start) > 50)
799           /* xgettext:c-format */
800           sprintf (errbuf, _("bad instruction `%.50s...'"), start);
801         else
802           /* xgettext:c-format */
803           sprintf (errbuf, _("bad instruction `%.50s'"), start);
804       }
805
806     *errmsg = errbuf;
807     return NULL;
808   }
809 }