Update the address and phone number of the FSF
[platform/upstream/binutils.git] / opcodes / ip2k-asm.c
1 /* 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 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 "ip2k-desc.h"
34 #include "ip2k-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   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
47 \f
48 /* -- assembler routines inserted here.  */
49
50 /* -- asm.c */
51
52 #define PARSE_FUNC_DECL(name) \
53   static const char *name (CGEN_CPU_DESC, const char **, int, long *)
54 #define PARSE_UFUNC_DECL(name) \
55   static const char *name (CGEN_CPU_DESC, const char **, int, unsigned long *)
56
57 PARSE_UFUNC_DECL (parse_fr);
58 PARSE_UFUNC_DECL (parse_addr16);
59 PARSE_UFUNC_DECL (parse_addr16_cjp);
60 PARSE_FUNC_DECL (parse_lit8);
61 PARSE_UFUNC_DECL (parse_bit3);
62
63
64 static const char *
65 parse_fr (cd, strp, opindex, valuep)
66      CGEN_CPU_DESC cd;
67      const char **strp;
68      int opindex;
69      unsigned long *valuep;
70 {
71   const char *errmsg;
72   const char *old_strp;
73   char *afteroffset; 
74   enum cgen_parse_operand_result result_type;
75   bfd_vma value;
76   extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
77   bfd_vma tempvalue;
78
79   old_strp = *strp;
80   afteroffset = NULL; 
81
82   /* Check here to see if you're about to try parsing a w as the first arg
83      and return an error if you are.  */
84   if ((strncmp (*strp, "w", 1) == 0) || (strncmp (*strp, "W", 1) == 0))
85     {
86       (*strp)++;
87
88       if ((strncmp (*strp, ",", 1) == 0) || ISSPACE (**strp))
89         {
90           /* We've been passed a w.  Return with an error message so that
91              cgen will try the next parsing option.  */
92           errmsg = _("W keyword invalid in FR operand slot.");
93           return errmsg;
94         }
95       *strp = old_strp;
96     }
97
98   /* Attempt parse as register keyword. */
99   errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names,
100                                (long *) valuep);
101   if (*strp != NULL
102       && errmsg == NULL)
103     return errmsg;
104
105   /* Attempt to parse for "(IP)".  */
106   afteroffset = strstr (*strp, "(IP)");
107
108   if (afteroffset == NULL)
109     /* Make sure it's not in lower case.  */
110     afteroffset = strstr (*strp, "(ip)");
111
112   if (afteroffset != NULL)
113     {
114       if (afteroffset != *strp)
115         {
116           /* Invalid offset present.  */
117           errmsg = _("offset(IP) is not a valid form");
118           return errmsg;
119         }
120       else
121         {
122           *strp += 4; 
123           *valuep = 0;
124           errmsg = NULL;
125           return errmsg;
126         }
127     }
128
129   /* Attempt to parse for DP. ex: mov w, offset(DP)
130                                   mov offset(DP),w   */
131
132   /* Try parsing it as an address and see what comes back.  */
133   afteroffset = strstr (*strp, "(DP)");
134
135   if (afteroffset == NULL)
136     /* Maybe it's in lower case.  */
137     afteroffset = strstr (*strp, "(dp)");
138
139   if (afteroffset != NULL)
140     {
141       if (afteroffset == *strp)
142         {
143           /* No offset present. Use 0 by default.  */
144           tempvalue = 0;
145           errmsg = NULL;
146         }
147       else
148         errmsg = cgen_parse_address (cd, strp, opindex,
149                                      BFD_RELOC_IP2K_FR_OFFSET,
150                                      & result_type, & tempvalue);
151
152       if (errmsg == NULL)
153         {
154           if (tempvalue <= 127)
155             {
156               /* Value is ok.  Fix up the first 2 bits and return.  */
157               *valuep = 0x0100 | tempvalue;
158               *strp += 4; /* skip over the (DP) in *strp.  */
159               return errmsg;
160             }
161           else
162             {
163               /* Found something there in front of (DP) but it's out
164                  of range.  */
165               errmsg = _("(DP) offset out of range.");
166               return errmsg;
167             }
168         }
169     }
170
171
172   /* Attempt to parse for SP. ex: mov w, offset(SP)
173                                   mov offset(SP), w.  */
174   afteroffset = strstr (*strp, "(SP)");
175
176   if (afteroffset == NULL)
177     /* Maybe it's in lower case.  */
178     afteroffset = strstr (*strp, "(sp)");
179
180   if (afteroffset != NULL)
181     {
182       if (afteroffset == *strp)
183         {
184           /* No offset present. Use 0 by default.  */
185           tempvalue = 0;
186           errmsg = NULL;
187         }
188       else
189         errmsg = cgen_parse_address (cd, strp, opindex,
190                                      BFD_RELOC_IP2K_FR_OFFSET,
191                                      & result_type, & tempvalue);
192
193       if (errmsg == NULL)
194         {
195           if (tempvalue <= 127)
196             {
197               /* Value is ok.  Fix up the first 2 bits and return.  */
198               *valuep = 0x0180 | tempvalue;
199               *strp += 4; /* skip over the (SP) in *strp.  */
200               return errmsg;
201             }
202           else
203             {
204               /* Found something there in front of (SP) but it's out
205                  of range.  */
206               errmsg = _("(SP) offset out of range.");
207               return errmsg;
208             }
209         }
210     }
211
212   /* Attempt to parse as an address.  */
213   *strp = old_strp;
214   errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9,
215                                & result_type, & value);
216   if (errmsg == NULL)
217     {
218       *valuep = value;
219
220       /* if a parenthesis is found, warn about invalid form.  */
221       if (**strp == '(')
222         errmsg = _("illegal use of parentheses");
223
224       /* if a numeric value is specified, ensure that it is between
225          1 and 255.  */
226       else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
227         {
228           if (value < 0x1 || value > 0xff)
229             errmsg = _("operand out of range (not between 1 and 255)");
230         }
231     }
232   return errmsg;
233 }
234
235 static const char *
236 parse_addr16 (cd, strp, opindex, valuep)
237      CGEN_CPU_DESC cd;
238      const char **strp;
239      int opindex;
240      unsigned long *valuep;
241 {
242   const char *errmsg;
243   enum cgen_parse_operand_result result_type;
244   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
245   bfd_vma value;
246
247   if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16H)
248     code = BFD_RELOC_IP2K_HI8DATA;
249   else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16L)
250     code = BFD_RELOC_IP2K_LO8DATA;
251   else
252     {
253       /* Something is very wrong. opindex has to be one of the above. */
254       errmsg = _("parse_addr16: invalid opindex.");
255       return errmsg;
256     }
257   
258   errmsg = cgen_parse_address (cd, strp, opindex, code,
259                                & result_type, & value);
260   if (errmsg == NULL)
261     {
262       /* We either have a relocation or a number now. */
263       if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
264         {
265           /* We got a number back. */
266           if (code == BFD_RELOC_IP2K_HI8DATA)
267             value >>= 8;
268           else    /* code = BFD_RELOC_IP2K_LOW8DATA */
269             value &= 0x00FF;
270         }   
271       *valuep = value;
272     }
273
274   return errmsg;
275 }
276
277
278 static const char *
279 parse_addr16_cjp (cd, strp, opindex, valuep)
280      CGEN_CPU_DESC cd;
281      const char **strp;
282      int opindex;
283      unsigned long *valuep;
284 {
285   const char *errmsg;
286   enum cgen_parse_operand_result result_type;
287   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
288   bfd_vma value;
289  
290   if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
291     code = BFD_RELOC_IP2K_ADDR16CJP;
292   else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
293     code = BFD_RELOC_IP2K_PAGE3;
294
295   errmsg = cgen_parse_address (cd, strp, opindex, code,
296                                & result_type, & value);
297   if (errmsg == NULL)
298     {
299       if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
300         {
301           if ((value & 0x1) == 0)  /* If the address is even .... */
302             {
303               if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
304                 *valuep = (value >> 1) & 0x1FFF;  /* Should mask be 1FFF? */
305               else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
306                 *valuep = (value >> 14) & 0x7;
307             }
308           else
309             errmsg = _("Byte address required. - must be even.");
310         }
311       else if (result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED)
312         {
313           /* This will happen for things like (s2-s1) where s2 and s1
314              are labels.  */
315           *valuep = value;
316         }
317       else 
318         errmsg = _("cgen_parse_address returned a symbol. Literal required.");
319     }
320   return errmsg; 
321 }
322
323
324 static const char *
325 parse_lit8 (cd, strp, opindex, valuep)
326      CGEN_CPU_DESC cd;
327      const char **strp;
328      int opindex;
329      long *valuep;
330 {
331   const char *errmsg;
332   enum cgen_parse_operand_result result_type;
333   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
334   bfd_vma value;
335
336   /* Parse %OP relocating operators. */
337   if (strncmp (*strp, "%bank", 5) == 0)
338     {
339       *strp += 5;
340       code = BFD_RELOC_IP2K_BANK;
341     }
342   else if (strncmp (*strp, "%lo8data", 8) == 0)
343     {
344       *strp += 8;
345       code = BFD_RELOC_IP2K_LO8DATA;
346     }
347   else if (strncmp (*strp, "%hi8data", 8) == 0)
348     {
349       *strp += 8;
350       code = BFD_RELOC_IP2K_HI8DATA;
351     }
352   else if (strncmp (*strp, "%ex8data", 8) == 0)
353     {
354       *strp += 8;
355       code = BFD_RELOC_IP2K_EX8DATA;
356     }
357   else if (strncmp (*strp, "%lo8insn", 8) == 0)
358     {
359       *strp += 8;
360       code = BFD_RELOC_IP2K_LO8INSN;
361     }
362   else if (strncmp (*strp, "%hi8insn", 8) == 0)
363     {
364       *strp += 8;
365       code = BFD_RELOC_IP2K_HI8INSN;
366     }
367   
368
369   /* Parse %op operand.  */
370   if (code != BFD_RELOC_NONE)
371     {
372       errmsg = cgen_parse_address (cd, strp, opindex, code, 
373                                    & result_type, & value);
374       if ((errmsg == NULL) &&
375           (result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED))
376         errmsg = _("percent-operator operand is not a symbol");
377
378       *valuep = value;
379     }
380   /* Parse as a number.  */
381   else
382     {
383       errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
384
385       /* Truncate to eight bits to accept both signed and unsigned input. */
386       if (errmsg == NULL)
387         *valuep &= 0xFF;
388     }
389
390   return errmsg;
391 }
392
393 static const char *
394 parse_bit3 (cd, strp, opindex, valuep)
395      CGEN_CPU_DESC cd;
396      const char **strp;
397      int opindex;
398      unsigned long *valuep;
399 {
400   const char *errmsg;
401   char mode = 0;
402   long count = 0;
403   unsigned long value;
404
405   if (strncmp (*strp, "%bit", 4) == 0)
406     {
407       *strp += 4;
408       mode = 1;
409     }
410   else if (strncmp (*strp, "%msbbit", 7) == 0)
411     {
412       *strp += 7;
413       mode = 1;
414     }
415   else if (strncmp (*strp, "%lsbbit", 7) == 0)
416     {
417       *strp += 7;
418       mode = 2;
419     }
420
421   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
422   if (errmsg)
423     return errmsg;
424
425   if (mode)
426     {
427       value = * valuep;
428       if (value == 0)
429         {
430           errmsg = _("Attempt to find bit index of 0");
431           return errmsg;
432         }
433     
434       if (mode == 1)
435         {
436           count = 31;
437           while ((value & 0x80000000) == 0)
438             {
439               count--;
440               value <<= 1;
441             }
442         }
443       else if (mode == 2)
444         {
445           count = 0;
446           while ((value & 0x00000001) == 0)
447             {
448               count++;
449               value >>= 1;
450             }
451         }
452     
453       *valuep = count;
454     }
455
456   return errmsg;
457 }
458
459
460 /* -- dis.c */
461
462 const char * ip2k_cgen_parse_operand
463   PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
464
465 /* Main entry point for operand parsing.
466
467    This function is basically just a big switch statement.  Earlier versions
468    used tables to look up the function to use, but
469    - if the table contains both assembler and disassembler functions then
470      the disassembler contains much of the assembler and vice-versa,
471    - there's a lot of inlining possibilities as things grow,
472    - using a switch statement avoids the function call overhead.
473
474    This function could be moved into `parse_insn_normal', but keeping it
475    separate makes clear the interface between `parse_insn_normal' and each of
476    the handlers.  */
477
478 const char *
479 ip2k_cgen_parse_operand (cd, opindex, strp, fields)
480      CGEN_CPU_DESC cd;
481      int opindex;
482      const char ** strp;
483      CGEN_FIELDS * fields;
484 {
485   const char * errmsg = NULL;
486   /* Used by scalar operands that still need to be parsed.  */
487   long junk ATTRIBUTE_UNUSED;
488
489   switch (opindex)
490     {
491     case IP2K_OPERAND_ADDR16CJP :
492       errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16CJP, (unsigned long *) (& fields->f_addr16cjp));
493       break;
494     case IP2K_OPERAND_ADDR16H :
495       errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16H, (unsigned long *) (& fields->f_imm8));
496       break;
497     case IP2K_OPERAND_ADDR16L :
498       errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16L, (unsigned long *) (& fields->f_imm8));
499       break;
500     case IP2K_OPERAND_ADDR16P :
501       errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16P, (unsigned long *) (& fields->f_page3));
502       break;
503     case IP2K_OPERAND_BITNO :
504       errmsg = parse_bit3 (cd, strp, IP2K_OPERAND_BITNO, (unsigned long *) (& fields->f_bitno));
505       break;
506     case IP2K_OPERAND_CBIT :
507       errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_CBIT, (unsigned long *) (& junk));
508       break;
509     case IP2K_OPERAND_DCBIT :
510       errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_DCBIT, (unsigned long *) (& junk));
511       break;
512     case IP2K_OPERAND_FR :
513       errmsg = parse_fr (cd, strp, IP2K_OPERAND_FR, (unsigned long *) (& fields->f_reg));
514       break;
515     case IP2K_OPERAND_LIT8 :
516       errmsg = parse_lit8 (cd, strp, IP2K_OPERAND_LIT8, (long *) (& fields->f_imm8));
517       break;
518     case IP2K_OPERAND_PABITS :
519       errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_PABITS, (unsigned long *) (& junk));
520       break;
521     case IP2K_OPERAND_RETI3 :
522       errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_RETI3, (unsigned long *) (& fields->f_reti3));
523       break;
524     case IP2K_OPERAND_ZBIT :
525       errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_ZBIT, (unsigned long *) (& junk));
526       break;
527
528     default :
529       /* xgettext:c-format */
530       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
531       abort ();
532   }
533
534   return errmsg;
535 }
536
537 cgen_parse_fn * const ip2k_cgen_parse_handlers[] = 
538 {
539   parse_insn_normal,
540 };
541
542 void
543 ip2k_cgen_init_asm (cd)
544      CGEN_CPU_DESC cd;
545 {
546   ip2k_cgen_init_opcode_table (cd);
547   ip2k_cgen_init_ibld_table (cd);
548   cd->parse_handlers = & ip2k_cgen_parse_handlers[0];
549   cd->parse_operand = ip2k_cgen_parse_operand;
550 }
551
552 \f
553
554 /* Regex construction routine.
555
556    This translates an opcode syntax string into a regex string,
557    by replacing any non-character syntax element (such as an
558    opcode) with the pattern '.*'
559
560    It then compiles the regex and stores it in the opcode, for
561    later use by ip2k_cgen_assemble_insn
562
563    Returns NULL for success, an error message for failure.  */
564
565 char * 
566 ip2k_cgen_build_insn_regex (CGEN_INSN *insn)
567 {  
568   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
569   const char *mnem = CGEN_INSN_MNEMONIC (insn);
570   char rxbuf[CGEN_MAX_RX_ELEMENTS];
571   char *rx = rxbuf;
572   const CGEN_SYNTAX_CHAR_TYPE *syn;
573   int reg_err;
574
575   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
576
577   /* Mnemonics come first in the syntax string.  */
578   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
579     return _("missing mnemonic in syntax string");
580   ++syn;
581
582   /* Generate a case sensitive regular expression that emulates case
583      insensitive matching in the "C" locale.  We cannot generate a case
584      insensitive regular expression because in Turkish locales, 'i' and 'I'
585      are not equal modulo case conversion.  */
586
587   /* Copy the literal mnemonic out of the insn.  */
588   for (; *mnem; mnem++)
589     {
590       char c = *mnem;
591
592       if (ISALPHA (c))
593         {
594           *rx++ = '[';
595           *rx++ = TOLOWER (c);
596           *rx++ = TOUPPER (c);
597           *rx++ = ']';
598         }
599       else
600         *rx++ = c;
601     }
602
603   /* Copy any remaining literals from the syntax string into the rx.  */
604   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
605     {
606       if (CGEN_SYNTAX_CHAR_P (* syn)) 
607         {
608           char c = CGEN_SYNTAX_CHAR (* syn);
609
610           switch (c) 
611             {
612               /* Escape any regex metacharacters in the syntax.  */
613             case '.': case '[': case '\\': 
614             case '*': case '^': case '$': 
615
616 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
617             case '?': case '{': case '}': 
618             case '(': case ')': case '*':
619             case '|': case '+': case ']':
620 #endif
621               *rx++ = '\\';
622               *rx++ = c;
623               break;
624
625             default:
626               if (ISALPHA (c))
627                 {
628                   *rx++ = '[';
629                   *rx++ = TOLOWER (c);
630                   *rx++ = TOUPPER (c);
631                   *rx++ = ']';
632                 }
633               else
634                 *rx++ = c;
635               break;
636             }
637         }
638       else
639         {
640           /* Replace non-syntax fields with globs.  */
641           *rx++ = '.';
642           *rx++ = '*';
643         }
644     }
645
646   /* Trailing whitespace ok.  */
647   * rx++ = '['; 
648   * rx++ = ' '; 
649   * rx++ = '\t'; 
650   * rx++ = ']'; 
651   * rx++ = '*'; 
652
653   /* But anchor it after that.  */
654   * rx++ = '$'; 
655   * rx = '\0';
656
657   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
658   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
659
660   if (reg_err == 0) 
661     return NULL;
662   else
663     {
664       static char msg[80];
665
666       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
667       regfree ((regex_t *) CGEN_INSN_RX (insn));
668       free (CGEN_INSN_RX (insn));
669       (CGEN_INSN_RX (insn)) = NULL;
670       return msg;
671     }
672 }
673
674 \f
675 /* Default insn parser.
676
677    The syntax string is scanned and operands are parsed and stored in FIELDS.
678    Relocs are queued as we go via other callbacks.
679
680    ??? Note that this is currently an all-or-nothing parser.  If we fail to
681    parse the instruction, we return 0 and the caller will start over from
682    the beginning.  Backtracking will be necessary in parsing subexpressions,
683    but that can be handled there.  Not handling backtracking here may get
684    expensive in the case of the m68k.  Deal with later.
685
686    Returns NULL for success, an error message for failure.  */
687
688 static const char *
689 parse_insn_normal (CGEN_CPU_DESC cd,
690                    const CGEN_INSN *insn,
691                    const char **strp,
692                    CGEN_FIELDS *fields)
693 {
694   /* ??? Runtime added insns not handled yet.  */
695   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
696   const char *str = *strp;
697   const char *errmsg;
698   const char *p;
699   const CGEN_SYNTAX_CHAR_TYPE * syn;
700 #ifdef CGEN_MNEMONIC_OPERANDS
701   /* FIXME: wip */
702   int past_opcode_p;
703 #endif
704
705   /* For now we assume the mnemonic is first (there are no leading operands).
706      We can parse it without needing to set up operand parsing.
707      GAS's input scrubber will ensure mnemonics are lowercase, but we may
708      not be called from GAS.  */
709   p = CGEN_INSN_MNEMONIC (insn);
710   while (*p && TOLOWER (*p) == TOLOWER (*str))
711     ++p, ++str;
712
713   if (* p)
714     return _("unrecognized instruction");
715
716 #ifndef CGEN_MNEMONIC_OPERANDS
717   if (* str && ! ISSPACE (* str))
718     return _("unrecognized instruction");
719 #endif
720
721   CGEN_INIT_PARSE (cd);
722   cgen_init_parse_operand (cd);
723 #ifdef CGEN_MNEMONIC_OPERANDS
724   past_opcode_p = 0;
725 #endif
726
727   /* We don't check for (*str != '\0') here because we want to parse
728      any trailing fake arguments in the syntax string.  */
729   syn = CGEN_SYNTAX_STRING (syntax);
730
731   /* Mnemonics come first for now, ensure valid string.  */
732   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
733     abort ();
734
735   ++syn;
736
737   while (* syn != 0)
738     {
739       /* Non operand chars must match exactly.  */
740       if (CGEN_SYNTAX_CHAR_P (* syn))
741         {
742           /* FIXME: While we allow for non-GAS callers above, we assume the
743              first char after the mnemonic part is a space.  */
744           /* FIXME: We also take inappropriate advantage of the fact that
745              GAS's input scrubber will remove extraneous blanks.  */
746           if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
747             {
748 #ifdef CGEN_MNEMONIC_OPERANDS
749               if (CGEN_SYNTAX_CHAR(* syn) == ' ')
750                 past_opcode_p = 1;
751 #endif
752               ++ syn;
753               ++ str;
754             }
755           else if (*str)
756             {
757               /* Syntax char didn't match.  Can't be this insn.  */
758               static char msg [80];
759
760               /* xgettext:c-format */
761               sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
762                        CGEN_SYNTAX_CHAR(*syn), *str);
763               return msg;
764             }
765           else
766             {
767               /* Ran out of input.  */
768               static char msg [80];
769
770               /* xgettext:c-format */
771               sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
772                        CGEN_SYNTAX_CHAR(*syn));
773               return msg;
774             }
775           continue;
776         }
777
778       /* We have an operand of some sort.  */
779       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
780                                           &str, fields);
781       if (errmsg)
782         return errmsg;
783
784       /* Done with this operand, continue with next one.  */
785       ++ syn;
786     }
787
788   /* If we're at the end of the syntax string, we're done.  */
789   if (* syn == 0)
790     {
791       /* FIXME: For the moment we assume a valid `str' can only contain
792          blanks now.  IE: We needn't try again with a longer version of
793          the insn and it is assumed that longer versions of insns appear
794          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
795       while (ISSPACE (* str))
796         ++ str;
797
798       if (* str != '\0')
799         return _("junk at end of line"); /* FIXME: would like to include `str' */
800
801       return NULL;
802     }
803
804   /* We couldn't parse it.  */
805   return _("unrecognized instruction");
806 }
807 \f
808 /* Main entry point.
809    This routine is called for each instruction to be assembled.
810    STR points to the insn to be assembled.
811    We assume all necessary tables have been initialized.
812    The assembled instruction, less any fixups, is stored in BUF.
813    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
814    still needs to be converted to target byte order, otherwise BUF is an array
815    of bytes in target byte order.
816    The result is a pointer to the insn's entry in the opcode table,
817    or NULL if an error occured (an error message will have already been
818    printed).
819
820    Note that when processing (non-alias) macro-insns,
821    this function recurses.
822
823    ??? It's possible to make this cpu-independent.
824    One would have to deal with a few minor things.
825    At this point in time doing so would be more of a curiosity than useful
826    [for example this file isn't _that_ big], but keeping the possibility in
827    mind helps keep the design clean.  */
828
829 const CGEN_INSN *
830 ip2k_cgen_assemble_insn (CGEN_CPU_DESC cd,
831                            const char *str,
832                            CGEN_FIELDS *fields,
833                            CGEN_INSN_BYTES_PTR buf,
834                            char **errmsg)
835 {
836   const char *start;
837   CGEN_INSN_LIST *ilist;
838   const char *parse_errmsg = NULL;
839   const char *insert_errmsg = NULL;
840   int recognized_mnemonic = 0;
841
842   /* Skip leading white space.  */
843   while (ISSPACE (* str))
844     ++ str;
845
846   /* The instructions are stored in hashed lists.
847      Get the first in the list.  */
848   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
849
850   /* Keep looking until we find a match.  */
851   start = str;
852   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
853     {
854       const CGEN_INSN *insn = ilist->insn;
855       recognized_mnemonic = 1;
856
857 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
858       /* Not usually needed as unsupported opcodes
859          shouldn't be in the hash lists.  */
860       /* Is this insn supported by the selected cpu?  */
861       if (! ip2k_cgen_insn_supported (cd, insn))
862         continue;
863 #endif
864       /* If the RELAXED attribute is set, this is an insn that shouldn't be
865          chosen immediately.  Instead, it is used during assembler/linker
866          relaxation if possible.  */
867       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
868         continue;
869
870       str = start;
871
872       /* Skip this insn if str doesn't look right lexically.  */
873       if (CGEN_INSN_RX (insn) != NULL &&
874           regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
875         continue;
876
877       /* Allow parse/insert handlers to obtain length of insn.  */
878       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
879
880       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
881       if (parse_errmsg != NULL)
882         continue;
883
884       /* ??? 0 is passed for `pc'.  */
885       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
886                                                  (bfd_vma) 0);
887       if (insert_errmsg != NULL)
888         continue;
889
890       /* It is up to the caller to actually output the insn and any
891          queued relocs.  */
892       return insn;
893     }
894
895   {
896     static char errbuf[150];
897 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
898     const char *tmp_errmsg;
899
900     /* If requesting verbose error messages, use insert_errmsg.
901        Failing that, use parse_errmsg.  */
902     tmp_errmsg = (insert_errmsg ? insert_errmsg :
903                   parse_errmsg ? parse_errmsg :
904                   recognized_mnemonic ?
905                   _("unrecognized form of instruction") :
906                   _("unrecognized instruction"));
907
908     if (strlen (start) > 50)
909       /* xgettext:c-format */
910       sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
911     else 
912       /* xgettext:c-format */
913       sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
914 #else
915     if (strlen (start) > 50)
916       /* xgettext:c-format */
917       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
918     else 
919       /* xgettext:c-format */
920       sprintf (errbuf, _("bad instruction `%.50s'"), start);
921 #endif
922       
923     *errmsg = errbuf;
924     return NULL;
925   }
926 }
927 \f
928 #if 0 /* This calls back to GAS which we can't do without care.  */
929
930 /* Record each member of OPVALS in the assembler's symbol table.
931    This lets GAS parse registers for us.
932    ??? Interesting idea but not currently used.  */
933
934 /* Record each member of OPVALS in the assembler's symbol table.
935    FIXME: Not currently used.  */
936
937 void
938 ip2k_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
939 {
940   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
941   const CGEN_KEYWORD_ENTRY * ke;
942
943   while ((ke = cgen_keyword_search_next (& search)) != NULL)
944     {
945 #if 0 /* Unnecessary, should be done in the search routine.  */
946       if (! ip2k_cgen_opval_supported (ke))
947         continue;
948 #endif
949       cgen_asm_record_register (cd, ke->name, ke->value);
950     }
951 }
952
953 #endif /* 0 */