1dc268d07Schristos /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2a1ba9ba4Schristos /* Assembler interface for targets using CGEN. -*- C -*-
3a1ba9ba4Schristos    CGEN: Cpu tools GENerator
4a1ba9ba4Schristos 
5a1ba9ba4Schristos    THIS FILE IS MACHINE GENERATED WITH CGEN.
6a1ba9ba4Schristos    - the resultant file is machine generated, cgen-asm.in isn't
7a1ba9ba4Schristos 
8*184b2d41Schristos    Copyright (C) 1996-2020 Free Software Foundation, Inc.
9a1ba9ba4Schristos 
10a1ba9ba4Schristos    This file is part of libopcodes.
11a1ba9ba4Schristos 
12a1ba9ba4Schristos    This library is free software; you can redistribute it and/or modify
13a1ba9ba4Schristos    it under the terms of the GNU General Public License as published by
14a1ba9ba4Schristos    the Free Software Foundation; either version 3, or (at your option)
15a1ba9ba4Schristos    any later version.
16a1ba9ba4Schristos 
17a1ba9ba4Schristos    It is distributed in the hope that it will be useful, but WITHOUT
18a1ba9ba4Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19a1ba9ba4Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20a1ba9ba4Schristos    License for more details.
21a1ba9ba4Schristos 
22a1ba9ba4Schristos    You should have received a copy of the GNU General Public License
23a1ba9ba4Schristos    along with this program; if not, write to the Free Software Foundation, Inc.,
24a1ba9ba4Schristos    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25a1ba9ba4Schristos 
26a1ba9ba4Schristos 
27a1ba9ba4Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
28a1ba9ba4Schristos    Keep that in mind.  */
29a1ba9ba4Schristos 
30a1ba9ba4Schristos #include "sysdep.h"
31a1ba9ba4Schristos #include <stdio.h>
32a1ba9ba4Schristos #include "ansidecl.h"
33a1ba9ba4Schristos #include "bfd.h"
34a1ba9ba4Schristos #include "symcat.h"
35a1ba9ba4Schristos #include "mep-desc.h"
36a1ba9ba4Schristos #include "mep-opc.h"
37a1ba9ba4Schristos #include "opintl.h"
38a1ba9ba4Schristos #include "xregex.h"
39a1ba9ba4Schristos #include "libiberty.h"
40a1ba9ba4Schristos #include "safe-ctype.h"
41a1ba9ba4Schristos 
42a1ba9ba4Schristos #undef  min
43a1ba9ba4Schristos #define min(a,b) ((a) < (b) ? (a) : (b))
44a1ba9ba4Schristos #undef  max
45a1ba9ba4Schristos #define max(a,b) ((a) > (b) ? (a) : (b))
46a1ba9ba4Schristos 
47a1ba9ba4Schristos static const char * parse_insn_normal
48a1ba9ba4Schristos   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
49a1ba9ba4Schristos 
50a1ba9ba4Schristos /* -- assembler routines inserted here.  */
51a1ba9ba4Schristos 
52a1ba9ba4Schristos /* -- asm.c */
53a1ba9ba4Schristos 
54a1ba9ba4Schristos #include "elf/mep.h"
55a1ba9ba4Schristos 
56a1ba9ba4Schristos #define CGEN_VALIDATE_INSN_SUPPORTED
57a1ba9ba4Schristos #define mep_cgen_insn_supported mep_cgen_insn_supported_asm
58a1ba9ba4Schristos 
59a1ba9ba4Schristos        const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
60a1ba9ba4Schristos        const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
61a1ba9ba4Schristos        const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
62a1ba9ba4Schristos        const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
63a1ba9ba4Schristos        const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
64a1ba9ba4Schristos static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
65a1ba9ba4Schristos static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
66a1ba9ba4Schristos static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
67a1ba9ba4Schristos static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
68a1ba9ba4Schristos static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
69a1ba9ba4Schristos static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
70a1ba9ba4Schristos static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
71a1ba9ba4Schristos 
72a1ba9ba4Schristos const char *
parse_csrn(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * keyword_table,long * field)73a1ba9ba4Schristos parse_csrn (CGEN_CPU_DESC cd, const char **strp,
74a1ba9ba4Schristos 	    CGEN_KEYWORD *keyword_table, long *field)
75a1ba9ba4Schristos {
76a1ba9ba4Schristos   const char *err;
77a1ba9ba4Schristos   unsigned long value;
78a1ba9ba4Schristos 
79a1ba9ba4Schristos   err = cgen_parse_keyword (cd, strp, keyword_table, field);
80a1ba9ba4Schristos   if (!err)
81a1ba9ba4Schristos     return NULL;
82a1ba9ba4Schristos 
83a1ba9ba4Schristos   err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
84a1ba9ba4Schristos   if (err)
85a1ba9ba4Schristos     return err;
86a1ba9ba4Schristos   *field = value;
87a1ba9ba4Schristos   return NULL;
88a1ba9ba4Schristos }
89a1ba9ba4Schristos 
90a1ba9ba4Schristos /* begin-cop-ip-parse-handlers */
91a1ba9ba4Schristos static const char *
92a1ba9ba4Schristos parse_ivc2_cr (CGEN_CPU_DESC,
93a1ba9ba4Schristos 	const char **,
94a1ba9ba4Schristos 	CGEN_KEYWORD *,
95a1ba9ba4Schristos 	long *) ATTRIBUTE_UNUSED;
96a1ba9ba4Schristos static const char *
parse_ivc2_cr(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * keyword_table ATTRIBUTE_UNUSED,long * field)97a1ba9ba4Schristos parse_ivc2_cr (CGEN_CPU_DESC cd,
98a1ba9ba4Schristos 	const char **strp,
99a1ba9ba4Schristos 	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
100a1ba9ba4Schristos 	long *field)
101a1ba9ba4Schristos {
102a1ba9ba4Schristos   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
103a1ba9ba4Schristos }
104a1ba9ba4Schristos static const char *
105a1ba9ba4Schristos parse_ivc2_ccr (CGEN_CPU_DESC,
106a1ba9ba4Schristos 	const char **,
107a1ba9ba4Schristos 	CGEN_KEYWORD *,
108a1ba9ba4Schristos 	long *) ATTRIBUTE_UNUSED;
109a1ba9ba4Schristos static const char *
parse_ivc2_ccr(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * keyword_table ATTRIBUTE_UNUSED,long * field)110a1ba9ba4Schristos parse_ivc2_ccr (CGEN_CPU_DESC cd,
111a1ba9ba4Schristos 	const char **strp,
112a1ba9ba4Schristos 	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
113a1ba9ba4Schristos 	long *field)
114a1ba9ba4Schristos {
115a1ba9ba4Schristos   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
116a1ba9ba4Schristos }
117a1ba9ba4Schristos /* end-cop-ip-parse-handlers */
118a1ba9ba4Schristos 
119a1ba9ba4Schristos const char *
parse_tpreg(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * keyword_table,long * field)120a1ba9ba4Schristos parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
121a1ba9ba4Schristos 	     CGEN_KEYWORD *keyword_table, long *field)
122a1ba9ba4Schristos {
123a1ba9ba4Schristos   const char *err;
124a1ba9ba4Schristos 
125a1ba9ba4Schristos   err = cgen_parse_keyword (cd, strp, keyword_table, field);
126a1ba9ba4Schristos   if (err)
127a1ba9ba4Schristos     return err;
128a1ba9ba4Schristos   if (*field != 13)
129a1ba9ba4Schristos     return _("Only $tp or $13 allowed for this opcode");
130a1ba9ba4Schristos   return NULL;
131a1ba9ba4Schristos }
132a1ba9ba4Schristos 
133a1ba9ba4Schristos const char *
parse_spreg(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * keyword_table,long * field)134a1ba9ba4Schristos parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
135a1ba9ba4Schristos 	     CGEN_KEYWORD *keyword_table, long *field)
136a1ba9ba4Schristos {
137a1ba9ba4Schristos   const char *err;
138a1ba9ba4Schristos 
139a1ba9ba4Schristos   err = cgen_parse_keyword (cd, strp, keyword_table, field);
140a1ba9ba4Schristos   if (err)
141a1ba9ba4Schristos     return err;
142a1ba9ba4Schristos   if (*field != 15)
143a1ba9ba4Schristos     return _("Only $sp or $15 allowed for this opcode");
144a1ba9ba4Schristos   return NULL;
145a1ba9ba4Schristos }
146a1ba9ba4Schristos 
147a1ba9ba4Schristos const char *
parse_mep_align(CGEN_CPU_DESC cd,const char ** strp,enum cgen_operand_type type,long * field)148a1ba9ba4Schristos parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
149a1ba9ba4Schristos 		 enum cgen_operand_type type, long *field)
150a1ba9ba4Schristos {
151a1ba9ba4Schristos   long lsbs = 0;
152a1ba9ba4Schristos   const char *err;
153a1ba9ba4Schristos 
154a1ba9ba4Schristos   switch (type)
155a1ba9ba4Schristos     {
156a1ba9ba4Schristos     case MEP_OPERAND_PCREL8A2:
157a1ba9ba4Schristos     case MEP_OPERAND_PCREL12A2:
158a1ba9ba4Schristos     case MEP_OPERAND_PCREL17A2:
159a1ba9ba4Schristos     case MEP_OPERAND_PCREL24A2:
160a1ba9ba4Schristos       err = cgen_parse_signed_integer   (cd, strp, type, field);
161a1ba9ba4Schristos       break;
162a1ba9ba4Schristos     case MEP_OPERAND_PCABS24A2:
163a1ba9ba4Schristos     case MEP_OPERAND_UDISP7:
164a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A2:
165a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A4:
166a1ba9ba4Schristos     case MEP_OPERAND_UIMM7A4:
167a1ba9ba4Schristos     case MEP_OPERAND_ADDR24A4:
168a1ba9ba4Schristos       err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
169a1ba9ba4Schristos       break;
170a1ba9ba4Schristos     default:
171a1ba9ba4Schristos       abort();
172a1ba9ba4Schristos     }
173a1ba9ba4Schristos   if (err)
174a1ba9ba4Schristos     return err;
175a1ba9ba4Schristos   switch (type)
176a1ba9ba4Schristos     {
177a1ba9ba4Schristos     case MEP_OPERAND_UDISP7:
178a1ba9ba4Schristos       lsbs = 0;
179a1ba9ba4Schristos       break;
180a1ba9ba4Schristos     case MEP_OPERAND_PCREL8A2:
181a1ba9ba4Schristos     case MEP_OPERAND_PCREL12A2:
182a1ba9ba4Schristos     case MEP_OPERAND_PCREL17A2:
183a1ba9ba4Schristos     case MEP_OPERAND_PCREL24A2:
184a1ba9ba4Schristos     case MEP_OPERAND_PCABS24A2:
185a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A2:
186a1ba9ba4Schristos       lsbs = *field & 1;
187a1ba9ba4Schristos       break;
188a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A4:
189a1ba9ba4Schristos     case MEP_OPERAND_UIMM7A4:
190a1ba9ba4Schristos     case MEP_OPERAND_ADDR24A4:
191a1ba9ba4Schristos       lsbs = *field & 3;
192a1ba9ba4Schristos       break;
193a1ba9ba4Schristos       lsbs = *field & 7;
194a1ba9ba4Schristos       break;
195a1ba9ba4Schristos     default:
196a1ba9ba4Schristos       /* Safe assumption?  */
197a1ba9ba4Schristos       abort ();
198a1ba9ba4Schristos     }
199a1ba9ba4Schristos   if (lsbs)
200a1ba9ba4Schristos     return "Value is not aligned enough";
201a1ba9ba4Schristos   return NULL;
202a1ba9ba4Schristos }
203a1ba9ba4Schristos 
204a1ba9ba4Schristos const char *
parse_mep_alignu(CGEN_CPU_DESC cd,const char ** strp,enum cgen_operand_type type,unsigned long * field)205a1ba9ba4Schristos parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
206a1ba9ba4Schristos 		 enum cgen_operand_type type, unsigned long *field)
207a1ba9ba4Schristos {
208a1ba9ba4Schristos   return parse_mep_align (cd, strp, type, (long *) field);
209a1ba9ba4Schristos }
210a1ba9ba4Schristos 
211a1ba9ba4Schristos 
212a1ba9ba4Schristos /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
213a1ba9ba4Schristos    constants in a signed context.  */
214a1ba9ba4Schristos 
215a1ba9ba4Schristos static const char *
parse_signed16(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)216a1ba9ba4Schristos parse_signed16 (CGEN_CPU_DESC cd,
217a1ba9ba4Schristos 		const char **strp,
218a1ba9ba4Schristos 		int opindex,
219a1ba9ba4Schristos 		long *valuep)
220a1ba9ba4Schristos {
221a1ba9ba4Schristos   return parse_lo16 (cd, strp, opindex, valuep, 1);
222a1ba9ba4Schristos }
223a1ba9ba4Schristos 
224a1ba9ba4Schristos static const char *
parse_lo16(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep,long signedp)225a1ba9ba4Schristos parse_lo16 (CGEN_CPU_DESC cd,
226a1ba9ba4Schristos 	    const char **strp,
227a1ba9ba4Schristos 	    int opindex,
228a1ba9ba4Schristos 	    long *valuep,
229a1ba9ba4Schristos 	    long signedp)
230a1ba9ba4Schristos {
231a1ba9ba4Schristos   const char *errmsg;
232a1ba9ba4Schristos   enum cgen_parse_operand_result result_type;
233a1ba9ba4Schristos   bfd_vma value;
234a1ba9ba4Schristos 
235a1ba9ba4Schristos   if (strncasecmp (*strp, "%lo(", 4) == 0)
236a1ba9ba4Schristos     {
237a1ba9ba4Schristos       *strp += 4;
238a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
239a1ba9ba4Schristos 				   & result_type, & value);
240a1ba9ba4Schristos       if (**strp != ')')
241a1ba9ba4Schristos 	return _("missing `)'");
242a1ba9ba4Schristos       ++*strp;
243a1ba9ba4Schristos       if (errmsg == NULL
244a1ba9ba4Schristos 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
245a1ba9ba4Schristos 	value &= 0xffff;
246a1ba9ba4Schristos       if (signedp)
247a1ba9ba4Schristos 	*valuep = (long)(short) value;
248a1ba9ba4Schristos       else
249a1ba9ba4Schristos 	*valuep = value;
250a1ba9ba4Schristos       return errmsg;
251a1ba9ba4Schristos     }
252a1ba9ba4Schristos 
253a1ba9ba4Schristos   if (strncasecmp (*strp, "%hi(", 4) == 0)
254a1ba9ba4Schristos     {
255a1ba9ba4Schristos       *strp += 4;
256a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
257a1ba9ba4Schristos 				   & result_type, & value);
258a1ba9ba4Schristos       if (**strp != ')')
259a1ba9ba4Schristos 	return _("missing `)'");
260a1ba9ba4Schristos       ++*strp;
261a1ba9ba4Schristos       if (errmsg == NULL
262a1ba9ba4Schristos 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
263a1ba9ba4Schristos 	value = (value + 0x8000) >> 16;
264a1ba9ba4Schristos       *valuep = value;
265a1ba9ba4Schristos       return errmsg;
266a1ba9ba4Schristos     }
267a1ba9ba4Schristos 
268a1ba9ba4Schristos   if (strncasecmp (*strp, "%uhi(", 5) == 0)
269a1ba9ba4Schristos     {
270a1ba9ba4Schristos       *strp += 5;
271a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
272a1ba9ba4Schristos 				   & result_type, & value);
273a1ba9ba4Schristos       if (**strp != ')')
274a1ba9ba4Schristos 	return _("missing `)'");
275a1ba9ba4Schristos       ++*strp;
276a1ba9ba4Schristos       if (errmsg == NULL
277a1ba9ba4Schristos 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
278a1ba9ba4Schristos 	value = value >> 16;
279a1ba9ba4Schristos       *valuep = value;
280a1ba9ba4Schristos       return errmsg;
281a1ba9ba4Schristos     }
282a1ba9ba4Schristos 
283a1ba9ba4Schristos   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
284a1ba9ba4Schristos     {
285a1ba9ba4Schristos       *strp += 8;
286a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
287a1ba9ba4Schristos 				   NULL, & value);
288a1ba9ba4Schristos       if (**strp != ')')
289a1ba9ba4Schristos 	return _("missing `)'");
290a1ba9ba4Schristos       ++*strp;
291a1ba9ba4Schristos       *valuep = value;
292a1ba9ba4Schristos       return errmsg;
293a1ba9ba4Schristos     }
294a1ba9ba4Schristos 
295a1ba9ba4Schristos   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
296a1ba9ba4Schristos     {
297a1ba9ba4Schristos       *strp += 7;
298a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
299a1ba9ba4Schristos 				   NULL, & value);
300a1ba9ba4Schristos       if (**strp != ')')
301a1ba9ba4Schristos 	return _("missing `)'");
302a1ba9ba4Schristos       ++*strp;
303a1ba9ba4Schristos       *valuep = value;
304a1ba9ba4Schristos       return errmsg;
305a1ba9ba4Schristos     }
306a1ba9ba4Schristos 
307a1ba9ba4Schristos   if (**strp == '%')
308a1ba9ba4Schristos     return _("invalid %function() here");
309a1ba9ba4Schristos 
310a1ba9ba4Schristos   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
311a1ba9ba4Schristos }
312a1ba9ba4Schristos 
313a1ba9ba4Schristos static const char *
parse_unsigned16(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)314a1ba9ba4Schristos parse_unsigned16 (CGEN_CPU_DESC cd,
315a1ba9ba4Schristos 		  const char **strp,
316a1ba9ba4Schristos 		  int opindex,
317a1ba9ba4Schristos 		  unsigned long *valuep)
318a1ba9ba4Schristos {
319a1ba9ba4Schristos   return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
320a1ba9ba4Schristos }
321a1ba9ba4Schristos 
322a1ba9ba4Schristos static const char *
parse_signed16_range(CGEN_CPU_DESC cd,const char ** strp,int opindex,signed long * valuep)323a1ba9ba4Schristos parse_signed16_range (CGEN_CPU_DESC cd,
324a1ba9ba4Schristos 		      const char **strp,
325a1ba9ba4Schristos 		      int opindex,
326a1ba9ba4Schristos 		      signed long *valuep)
327a1ba9ba4Schristos {
328a1ba9ba4Schristos   const char *errmsg = 0;
329a1ba9ba4Schristos   signed long value;
330a1ba9ba4Schristos 
331a1ba9ba4Schristos   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
332a1ba9ba4Schristos   if (errmsg)
333a1ba9ba4Schristos     return errmsg;
334a1ba9ba4Schristos 
335a1ba9ba4Schristos   if (value < -32768 || value > 32767)
336a1ba9ba4Schristos     return _("Immediate is out of range -32768 to 32767");
337a1ba9ba4Schristos 
338a1ba9ba4Schristos   *valuep = value;
339a1ba9ba4Schristos   return 0;
340a1ba9ba4Schristos }
341a1ba9ba4Schristos 
342a1ba9ba4Schristos static const char *
parse_unsigned16_range(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)343a1ba9ba4Schristos parse_unsigned16_range (CGEN_CPU_DESC cd,
344a1ba9ba4Schristos 			const char **strp,
345a1ba9ba4Schristos 			int opindex,
346a1ba9ba4Schristos 			unsigned long *valuep)
347a1ba9ba4Schristos {
348a1ba9ba4Schristos   const char *errmsg = 0;
349a1ba9ba4Schristos   unsigned long value;
350a1ba9ba4Schristos 
351a1ba9ba4Schristos   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
352a1ba9ba4Schristos   if (errmsg)
353a1ba9ba4Schristos     return errmsg;
354a1ba9ba4Schristos 
355a1ba9ba4Schristos   if (value > 65535)
356a1ba9ba4Schristos     return _("Immediate is out of range 0 to 65535");
357a1ba9ba4Schristos 
358a1ba9ba4Schristos   *valuep = value;
359a1ba9ba4Schristos   return 0;
360a1ba9ba4Schristos }
361a1ba9ba4Schristos 
362a1ba9ba4Schristos /* A special case of parse_signed16 which accepts only the value zero.  */
363a1ba9ba4Schristos 
364a1ba9ba4Schristos static const char *
parse_zero(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)365a1ba9ba4Schristos parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
366a1ba9ba4Schristos {
367a1ba9ba4Schristos   const char *errmsg;
368a1ba9ba4Schristos   enum cgen_parse_operand_result result_type;
369a1ba9ba4Schristos   bfd_vma value;
370a1ba9ba4Schristos 
371a1ba9ba4Schristos   /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
372a1ba9ba4Schristos 
373a1ba9ba4Schristos   /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
374a1ba9ba4Schristos      It will fail and cause ry to be listed as an undefined symbol in the
375a1ba9ba4Schristos      listing.  */
376a1ba9ba4Schristos   if (strncmp (*strp, "($", 2) == 0)
377a1ba9ba4Schristos     return "not zero"; /* any string will do -- will never be seen.  */
378a1ba9ba4Schristos 
379a1ba9ba4Schristos   if (strncasecmp (*strp, "%lo(", 4) == 0)
380a1ba9ba4Schristos     {
381a1ba9ba4Schristos       *strp += 4;
382a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
383a1ba9ba4Schristos 				   &result_type, &value);
384a1ba9ba4Schristos       if (**strp != ')')
385a1ba9ba4Schristos 	return "missing `)'";
386a1ba9ba4Schristos       ++*strp;
387a1ba9ba4Schristos       if (errmsg == NULL
388a1ba9ba4Schristos 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
389a1ba9ba4Schristos 	return "not zero"; /* any string will do -- will never be seen.  */
390a1ba9ba4Schristos       *valuep = value;
391a1ba9ba4Schristos       return errmsg;
392a1ba9ba4Schristos     }
393a1ba9ba4Schristos 
394a1ba9ba4Schristos   if (strncasecmp (*strp, "%hi(", 4) == 0)
395a1ba9ba4Schristos     {
396a1ba9ba4Schristos       *strp += 4;
397a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
398a1ba9ba4Schristos 				   &result_type, &value);
399a1ba9ba4Schristos       if (**strp != ')')
400a1ba9ba4Schristos 	return "missing `)'";
401a1ba9ba4Schristos       ++*strp;
402a1ba9ba4Schristos       if (errmsg == NULL
403a1ba9ba4Schristos 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
404a1ba9ba4Schristos 	return "not zero"; /* any string will do -- will never be seen.  */
405a1ba9ba4Schristos       *valuep = value;
406a1ba9ba4Schristos       return errmsg;
407a1ba9ba4Schristos     }
408a1ba9ba4Schristos 
409a1ba9ba4Schristos   if (strncasecmp (*strp, "%uhi(", 5) == 0)
410a1ba9ba4Schristos     {
411a1ba9ba4Schristos       *strp += 5;
412a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
413a1ba9ba4Schristos 				   &result_type, &value);
414a1ba9ba4Schristos       if (**strp != ')')
415a1ba9ba4Schristos 	return "missing `)'";
416a1ba9ba4Schristos       ++*strp;
417a1ba9ba4Schristos       if (errmsg == NULL
418a1ba9ba4Schristos 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
419a1ba9ba4Schristos 	return "not zero"; /* any string will do -- will never be seen.  */
420a1ba9ba4Schristos       *valuep = value;
421a1ba9ba4Schristos       return errmsg;
422a1ba9ba4Schristos     }
423a1ba9ba4Schristos 
424a1ba9ba4Schristos   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
425a1ba9ba4Schristos     {
426a1ba9ba4Schristos       *strp += 8;
427a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
428a1ba9ba4Schristos 				   &result_type, &value);
429a1ba9ba4Schristos       if (**strp != ')')
430a1ba9ba4Schristos 	return "missing `)'";
431a1ba9ba4Schristos       ++*strp;
432a1ba9ba4Schristos       if (errmsg == NULL
433a1ba9ba4Schristos 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
434a1ba9ba4Schristos 	return "not zero"; /* any string will do -- will never be seen.  */
435a1ba9ba4Schristos       *valuep = value;
436a1ba9ba4Schristos       return errmsg;
437a1ba9ba4Schristos     }
438a1ba9ba4Schristos 
439a1ba9ba4Schristos   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
440a1ba9ba4Schristos     {
441a1ba9ba4Schristos       *strp += 7;
442a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
443a1ba9ba4Schristos 				   &result_type, &value);
444a1ba9ba4Schristos       if (**strp != ')')
445a1ba9ba4Schristos 	return "missing `)'";
446a1ba9ba4Schristos       ++*strp;
447a1ba9ba4Schristos       if (errmsg == NULL
448a1ba9ba4Schristos 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
449a1ba9ba4Schristos 	return "not zero"; /* any string will do -- will never be seen.  */
450a1ba9ba4Schristos       *valuep = value;
451a1ba9ba4Schristos       return errmsg;
452a1ba9ba4Schristos     }
453a1ba9ba4Schristos 
454a1ba9ba4Schristos   if (**strp == '%')
455a1ba9ba4Schristos     return "invalid %function() here";
456a1ba9ba4Schristos 
457a1ba9ba4Schristos   errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
458a1ba9ba4Schristos 			       &result_type, &value);
459a1ba9ba4Schristos   if (errmsg == NULL
460a1ba9ba4Schristos       && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
461a1ba9ba4Schristos     return "not zero"; /* any string will do -- will never be seen.  */
462a1ba9ba4Schristos 
463a1ba9ba4Schristos   return errmsg;
464a1ba9ba4Schristos }
465a1ba9ba4Schristos 
466a1ba9ba4Schristos static const char *
parse_unsigned7(CGEN_CPU_DESC cd,const char ** strp,enum cgen_operand_type opindex,unsigned long * valuep)467a1ba9ba4Schristos parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
468a1ba9ba4Schristos 		 enum cgen_operand_type opindex, unsigned long *valuep)
469a1ba9ba4Schristos {
470a1ba9ba4Schristos   const char *errmsg;
471a1ba9ba4Schristos   bfd_vma value;
472a1ba9ba4Schristos 
473a1ba9ba4Schristos   /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
474a1ba9ba4Schristos 
475a1ba9ba4Schristos   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
476a1ba9ba4Schristos     {
477a1ba9ba4Schristos       int reloc;
478a1ba9ba4Schristos       *strp += 7;
479a1ba9ba4Schristos       switch (opindex)
480a1ba9ba4Schristos 	{
481a1ba9ba4Schristos 	case MEP_OPERAND_UDISP7:
482a1ba9ba4Schristos 	  reloc = BFD_RELOC_MEP_TPREL7;
483a1ba9ba4Schristos 	  break;
484a1ba9ba4Schristos 	case MEP_OPERAND_UDISP7A2:
485a1ba9ba4Schristos 	  reloc = BFD_RELOC_MEP_TPREL7A2;
486a1ba9ba4Schristos 	  break;
487a1ba9ba4Schristos 	case MEP_OPERAND_UDISP7A4:
488a1ba9ba4Schristos 	  reloc = BFD_RELOC_MEP_TPREL7A4;
489a1ba9ba4Schristos 	  break;
490a1ba9ba4Schristos 	default:
491a1ba9ba4Schristos 	  /* Safe assumption?  */
492a1ba9ba4Schristos 	  abort ();
493a1ba9ba4Schristos 	}
494a1ba9ba4Schristos       errmsg = cgen_parse_address (cd, strp, opindex, reloc,
495a1ba9ba4Schristos 				   NULL, &value);
496a1ba9ba4Schristos       if (**strp != ')')
497a1ba9ba4Schristos 	return "missing `)'";
498a1ba9ba4Schristos       ++*strp;
499a1ba9ba4Schristos       *valuep = value;
500a1ba9ba4Schristos       return errmsg;
501a1ba9ba4Schristos     }
502a1ba9ba4Schristos 
503a1ba9ba4Schristos   if (**strp == '%')
504a1ba9ba4Schristos     return _("invalid %function() here");
505a1ba9ba4Schristos 
506a1ba9ba4Schristos   return parse_mep_alignu (cd, strp, opindex, valuep);
507a1ba9ba4Schristos }
508a1ba9ba4Schristos 
509a1ba9ba4Schristos static ATTRIBUTE_UNUSED const char *
parse_cdisp10(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)510a1ba9ba4Schristos parse_cdisp10 (CGEN_CPU_DESC cd,
511a1ba9ba4Schristos 	       const char **strp,
512a1ba9ba4Schristos 	       int opindex,
513a1ba9ba4Schristos 	       long *valuep)
514a1ba9ba4Schristos {
515a1ba9ba4Schristos   const char *errmsg = 0;
516a1ba9ba4Schristos   signed long value;
517a1ba9ba4Schristos   long have_zero = 0;
518a1ba9ba4Schristos   int wide = 0;
519a1ba9ba4Schristos   int alignment;
520a1ba9ba4Schristos 
521a1ba9ba4Schristos   switch (opindex)
522a1ba9ba4Schristos     {
523a1ba9ba4Schristos     case MEP_OPERAND_CDISP10A4:
524a1ba9ba4Schristos       alignment = 2;
525a1ba9ba4Schristos       break;
526a1ba9ba4Schristos     case MEP_OPERAND_CDISP10A2:
527a1ba9ba4Schristos       alignment = 1;
528a1ba9ba4Schristos       break;
529a1ba9ba4Schristos     case MEP_OPERAND_CDISP10:
530a1ba9ba4Schristos     default:
531a1ba9ba4Schristos       alignment = 0;
532a1ba9ba4Schristos       break;
533a1ba9ba4Schristos     }
534a1ba9ba4Schristos 
535a1ba9ba4Schristos   if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
536a1ba9ba4Schristos     wide = 1;
537a1ba9ba4Schristos 
538a1ba9ba4Schristos   if (strncmp (*strp, "0x0", 3) == 0
539a1ba9ba4Schristos       || (**strp == '0' && *(*strp + 1) != 'x'))
540a1ba9ba4Schristos     have_zero = 1;
541a1ba9ba4Schristos 
542a1ba9ba4Schristos   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
543a1ba9ba4Schristos   if (errmsg)
544a1ba9ba4Schristos     return errmsg;
545a1ba9ba4Schristos 
546a1ba9ba4Schristos   if (wide)
547a1ba9ba4Schristos     {
548a1ba9ba4Schristos       if (value < -512 || value > 511)
549a1ba9ba4Schristos 	return _("Immediate is out of range -512 to 511");
550a1ba9ba4Schristos     }
551a1ba9ba4Schristos   else
552a1ba9ba4Schristos     {
553a1ba9ba4Schristos       if (value < -128 || value > 127)
554a1ba9ba4Schristos 	return _("Immediate is out of range -128 to 127");
555a1ba9ba4Schristos     }
556a1ba9ba4Schristos 
557a1ba9ba4Schristos   if (value & ((1<<alignment)-1))
558a1ba9ba4Schristos     return _("Value is not aligned enough");
559a1ba9ba4Schristos 
560a1ba9ba4Schristos   /* If this field may require a relocation then use larger dsp16.  */
561a1ba9ba4Schristos   if (! have_zero && value == 0)
562a1ba9ba4Schristos     return (wide ? _("Immediate is out of range -512 to 511")
563a1ba9ba4Schristos 	    : _("Immediate is out of range -128 to 127"));
564a1ba9ba4Schristos 
565a1ba9ba4Schristos   *valuep = value;
566a1ba9ba4Schristos   return 0;
567a1ba9ba4Schristos }
568a1ba9ba4Schristos 
569a1ba9ba4Schristos /* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
570a1ba9ba4Schristos 
571a1ba9ba4Schristos #define MAXARGS 9
572a1ba9ba4Schristos 
573a1ba9ba4Schristos typedef struct
574a1ba9ba4Schristos {
575a1ba9ba4Schristos   char *name;
576a1ba9ba4Schristos   char *expansion;
577a1ba9ba4Schristos }  macro;
578a1ba9ba4Schristos 
579a1ba9ba4Schristos typedef struct
580a1ba9ba4Schristos {
581a1ba9ba4Schristos   const char *start;
582a1ba9ba4Schristos   int len;
583a1ba9ba4Schristos } arg;
584a1ba9ba4Schristos 
585a1ba9ba4Schristos macro macros[] =
586a1ba9ba4Schristos {
587a1ba9ba4Schristos   { "sizeof", "(`1.end + (- `1))"},
588a1ba9ba4Schristos   { "startof", "(`1 | 0)" },
589a1ba9ba4Schristos   { "align4", "(`1&(~3))"},
590a1ba9ba4Schristos /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
591a1ba9ba4Schristos /*{ "lo", "(`1 & 0xffff)" },  */
592a1ba9ba4Schristos /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
593a1ba9ba4Schristos /*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
594a1ba9ba4Schristos   { 0,0 }
595a1ba9ba4Schristos };
596a1ba9ba4Schristos 
597a1ba9ba4Schristos static char  * expand_string    (const char *, int);
598a1ba9ba4Schristos 
599a1ba9ba4Schristos static const char *
600a1ba9ba4Schristos mep_cgen_expand_macros_and_parse_operand
601a1ba9ba4Schristos   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
602a1ba9ba4Schristos 
603a1ba9ba4Schristos static char *
str_append(char * dest,const char * input,int len)604a1ba9ba4Schristos str_append (char *dest, const char *input, int len)
605a1ba9ba4Schristos {
606a1ba9ba4Schristos   char *new_dest;
607a1ba9ba4Schristos   int oldlen;
608a1ba9ba4Schristos 
609a1ba9ba4Schristos   if (len == 0)
610a1ba9ba4Schristos     return dest;
611a1ba9ba4Schristos   /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
612a1ba9ba4Schristos   oldlen = (dest ? strlen(dest) : 0);
613a1ba9ba4Schristos   new_dest = realloc (dest, oldlen + len + 1);
614a1ba9ba4Schristos   memset (new_dest + oldlen, 0, len + 1);
615a1ba9ba4Schristos   return strncat (new_dest, input, len);
616a1ba9ba4Schristos }
617a1ba9ba4Schristos 
618a1ba9ba4Schristos static macro *
lookup_macro(const char * name)619a1ba9ba4Schristos lookup_macro (const char *name)
620a1ba9ba4Schristos {
621a1ba9ba4Schristos   macro *m;
622a1ba9ba4Schristos 
623a1ba9ba4Schristos   for (m = macros; m->name; ++m)
624a1ba9ba4Schristos     if (strncmp (m->name, name, strlen(m->name)) == 0)
625a1ba9ba4Schristos       return m;
626a1ba9ba4Schristos 
627a1ba9ba4Schristos   return 0;
628a1ba9ba4Schristos }
629a1ba9ba4Schristos 
630a1ba9ba4Schristos static char *
expand_macro(arg * args,int narg,macro * mac)631a1ba9ba4Schristos expand_macro (arg *args, int narg, macro *mac)
632a1ba9ba4Schristos {
633a1ba9ba4Schristos   char *result = 0, *rescanned_result = 0;
634a1ba9ba4Schristos   char *e = mac->expansion;
635a1ba9ba4Schristos   char *mark = e;
636a1ba9ba4Schristos   int mac_arg = 0;
637a1ba9ba4Schristos 
638a1ba9ba4Schristos   /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
639a1ba9ba4Schristos   while (*e)
640a1ba9ba4Schristos     {
641a1ba9ba4Schristos       if (*e == '`' &&
642a1ba9ba4Schristos 	  (*e+1) &&
643a1ba9ba4Schristos 	  ((*(e + 1) - '1') <= MAXARGS) &&
644a1ba9ba4Schristos 	  ((*(e + 1) - '1') <= narg))
645a1ba9ba4Schristos 	{
646a1ba9ba4Schristos 	  result = str_append (result, mark, e - mark);
647a1ba9ba4Schristos 	  mac_arg = (*(e + 1) - '1');
648a1ba9ba4Schristos 	  /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
649a1ba9ba4Schristos 	  result = str_append (result, args[mac_arg].start, args[mac_arg].len);
650a1ba9ba4Schristos 	  ++e;
651a1ba9ba4Schristos 	  mark = e+1;
652a1ba9ba4Schristos 	}
653a1ba9ba4Schristos       ++e;
654a1ba9ba4Schristos     }
655a1ba9ba4Schristos 
656a1ba9ba4Schristos   if (mark != e)
657a1ba9ba4Schristos     result = str_append (result, mark, e - mark);
658a1ba9ba4Schristos 
659a1ba9ba4Schristos   if (result)
660a1ba9ba4Schristos     {
661a1ba9ba4Schristos       rescanned_result = expand_string (result, 0);
662a1ba9ba4Schristos       free (result);
663a1ba9ba4Schristos       return rescanned_result;
664a1ba9ba4Schristos     }
665a1ba9ba4Schristos   else
666a1ba9ba4Schristos     return result;
667a1ba9ba4Schristos }
668a1ba9ba4Schristos 
669a1ba9ba4Schristos #define IN_TEXT 0
670a1ba9ba4Schristos #define IN_ARGS 1
671a1ba9ba4Schristos 
672a1ba9ba4Schristos static char *
expand_string(const char * in,int first_only)673a1ba9ba4Schristos expand_string (const char *in, int first_only)
674a1ba9ba4Schristos {
675a1ba9ba4Schristos   int num_expansions = 0;
676a1ba9ba4Schristos   int depth = 0;
677a1ba9ba4Schristos   int narg = -1;
678a1ba9ba4Schristos   arg args[MAXARGS];
679a1ba9ba4Schristos   int state = IN_TEXT;
680a1ba9ba4Schristos   const char *mark = in;
681a1ba9ba4Schristos   macro *pmacro = NULL;
682a1ba9ba4Schristos   char *expansion = 0;
683a1ba9ba4Schristos   char *result = 0;
684a1ba9ba4Schristos 
685a1ba9ba4Schristos   while (*in)
686a1ba9ba4Schristos     {
687a1ba9ba4Schristos       switch (state)
688a1ba9ba4Schristos 	{
689a1ba9ba4Schristos 	case IN_TEXT:
690a1ba9ba4Schristos 	  if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
691a1ba9ba4Schristos 	    {
692a1ba9ba4Schristos 	      pmacro = lookup_macro (in + 1);
693a1ba9ba4Schristos 	      if (pmacro)
694a1ba9ba4Schristos 		{
695a1ba9ba4Schristos 		  /* printf("entering state %d at '%s'...\n", state, in); */
696a1ba9ba4Schristos 		  result = str_append (result, mark, in - mark);
697a1ba9ba4Schristos 		  mark = in;
698a1ba9ba4Schristos 		  in += 1 + strlen (pmacro->name);
699a1ba9ba4Schristos 		  while (*in == ' ') ++in;
700a1ba9ba4Schristos 		  if (*in != '(')
701a1ba9ba4Schristos 		    {
702a1ba9ba4Schristos 		      state = IN_TEXT;
703a1ba9ba4Schristos 		      pmacro = NULL;
704a1ba9ba4Schristos 		    }
705a1ba9ba4Schristos 		  else
706a1ba9ba4Schristos 		    {
707a1ba9ba4Schristos 		      state = IN_ARGS;
708a1ba9ba4Schristos 		      narg = 0;
709a1ba9ba4Schristos 		      args[narg].start = in + 1;
710a1ba9ba4Schristos 		      args[narg].len = 0;
711a1ba9ba4Schristos 		      mark = in + 1;
712a1ba9ba4Schristos 		    }
713a1ba9ba4Schristos 		}
714a1ba9ba4Schristos 	    }
715a1ba9ba4Schristos 	  break;
716a1ba9ba4Schristos 	case IN_ARGS:
717a1ba9ba4Schristos 	  if (depth == 0)
718a1ba9ba4Schristos 	    {
719a1ba9ba4Schristos 	      switch (*in)
720a1ba9ba4Schristos 		{
721a1ba9ba4Schristos 		case ',':
722a1ba9ba4Schristos 		  narg++;
723a1ba9ba4Schristos 		  args[narg].start = (in + 1);
724a1ba9ba4Schristos 		  args[narg].len = 0;
725a1ba9ba4Schristos 		  break;
726a1ba9ba4Schristos 		case ')':
727a1ba9ba4Schristos 		  state = IN_TEXT;
728a1ba9ba4Schristos 		  /* printf("entering state %d at '%s'...\n", state, in); */
729a1ba9ba4Schristos 		  if (pmacro)
730a1ba9ba4Schristos 		    {
731a1ba9ba4Schristos 		      expansion = 0;
732a1ba9ba4Schristos 		      expansion = expand_macro (args, narg, pmacro);
733a1ba9ba4Schristos 		      num_expansions++;
734a1ba9ba4Schristos 		      if (expansion)
735a1ba9ba4Schristos 			{
736a1ba9ba4Schristos 			  result = str_append (result, expansion, strlen (expansion));
737a1ba9ba4Schristos 			  free (expansion);
738a1ba9ba4Schristos 			}
739a1ba9ba4Schristos 		    }
740a1ba9ba4Schristos 		  else
741a1ba9ba4Schristos 		    {
742a1ba9ba4Schristos 		      result = str_append (result, mark, in - mark);
743a1ba9ba4Schristos 		    }
744a1ba9ba4Schristos 		  pmacro = NULL;
745a1ba9ba4Schristos 		  mark = in + 1;
746a1ba9ba4Schristos 		  break;
747a1ba9ba4Schristos 		case '(':
748a1ba9ba4Schristos 		  depth++;
74915d8e94aSchristos 		  /* Fall through.  */
750a1ba9ba4Schristos 		default:
751a1ba9ba4Schristos 		  args[narg].len++;
752a1ba9ba4Schristos 		  break;
753a1ba9ba4Schristos 		}
754a1ba9ba4Schristos 	    }
755a1ba9ba4Schristos 	  else
756a1ba9ba4Schristos 	    {
757a1ba9ba4Schristos 	      if (*in == ')')
758a1ba9ba4Schristos 		depth--;
759a1ba9ba4Schristos 	      if (narg > -1)
760a1ba9ba4Schristos 		args[narg].len++;
761a1ba9ba4Schristos 	    }
762a1ba9ba4Schristos 
763a1ba9ba4Schristos 	}
764a1ba9ba4Schristos       ++in;
765a1ba9ba4Schristos     }
766a1ba9ba4Schristos 
767a1ba9ba4Schristos   if (mark != in)
768a1ba9ba4Schristos     result = str_append (result, mark, in - mark);
769a1ba9ba4Schristos 
770a1ba9ba4Schristos   return result;
771a1ba9ba4Schristos }
772a1ba9ba4Schristos 
773a1ba9ba4Schristos #undef IN_ARGS
774a1ba9ba4Schristos #undef IN_TEXT
775a1ba9ba4Schristos #undef MAXARGS
776a1ba9ba4Schristos 
777a1ba9ba4Schristos 
778a1ba9ba4Schristos /* END LIGHTWEIGHT MACRO PROCESSOR.  */
779a1ba9ba4Schristos 
780a1ba9ba4Schristos const char * mep_cgen_parse_operand
781a1ba9ba4Schristos   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
782a1ba9ba4Schristos 
783a1ba9ba4Schristos const char *
mep_cgen_expand_macros_and_parse_operand(CGEN_CPU_DESC cd,int opindex,const char ** strp_in,CGEN_FIELDS * fields)784a1ba9ba4Schristos mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
785a1ba9ba4Schristos 					  const char ** strp_in, CGEN_FIELDS * fields)
786a1ba9ba4Schristos {
787a1ba9ba4Schristos   const char * errmsg = NULL;
788a1ba9ba4Schristos   char *str = 0, *hold = 0;
789a1ba9ba4Schristos   const char **strp = 0;
790a1ba9ba4Schristos 
791a1ba9ba4Schristos   /* Set up a new pointer to macro-expanded string.  */
792a1ba9ba4Schristos   str = expand_string (*strp_in, 1);
793a1ba9ba4Schristos   /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
794a1ba9ba4Schristos 
795a1ba9ba4Schristos   hold = str;
796a1ba9ba4Schristos   strp = (const char **)(&str);
797a1ba9ba4Schristos 
798a1ba9ba4Schristos   errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
799a1ba9ba4Schristos 
800a1ba9ba4Schristos   /* Now work out the advance.  */
801a1ba9ba4Schristos   if (strlen (str) == 0)
802a1ba9ba4Schristos     *strp_in += strlen (*strp_in);
803a1ba9ba4Schristos 
804a1ba9ba4Schristos   else
805a1ba9ba4Schristos     {
806a1ba9ba4Schristos       if (strstr (*strp_in, str))
807a1ba9ba4Schristos 	/* A macro-expansion was pulled off the front.  */
808a1ba9ba4Schristos 	*strp_in = strstr (*strp_in, str);
809a1ba9ba4Schristos       else
810a1ba9ba4Schristos 	/* A non-macro-expansion was pulled off the front.  */
811a1ba9ba4Schristos 	*strp_in += (str - hold);
812a1ba9ba4Schristos     }
813a1ba9ba4Schristos 
814a1ba9ba4Schristos   free (hold);
815a1ba9ba4Schristos 
816a1ba9ba4Schristos   return errmsg;
817a1ba9ba4Schristos }
818a1ba9ba4Schristos 
819a1ba9ba4Schristos #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
820a1ba9ba4Schristos 
821a1ba9ba4Schristos /* -- dis.c */
822a1ba9ba4Schristos 
823a1ba9ba4Schristos const char * mep_cgen_parse_operand
824a1ba9ba4Schristos   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
825a1ba9ba4Schristos 
826a1ba9ba4Schristos /* Main entry point for operand parsing.
827a1ba9ba4Schristos 
828a1ba9ba4Schristos    This function is basically just a big switch statement.  Earlier versions
829a1ba9ba4Schristos    used tables to look up the function to use, but
830a1ba9ba4Schristos    - if the table contains both assembler and disassembler functions then
831a1ba9ba4Schristos      the disassembler contains much of the assembler and vice-versa,
832a1ba9ba4Schristos    - there's a lot of inlining possibilities as things grow,
833a1ba9ba4Schristos    - using a switch statement avoids the function call overhead.
834a1ba9ba4Schristos 
835a1ba9ba4Schristos    This function could be moved into `parse_insn_normal', but keeping it
836a1ba9ba4Schristos    separate makes clear the interface between `parse_insn_normal' and each of
837a1ba9ba4Schristos    the handlers.  */
838a1ba9ba4Schristos 
839a1ba9ba4Schristos const char *
mep_cgen_parse_operand(CGEN_CPU_DESC cd,int opindex,const char ** strp,CGEN_FIELDS * fields)840a1ba9ba4Schristos mep_cgen_parse_operand (CGEN_CPU_DESC cd,
841a1ba9ba4Schristos 			   int opindex,
842a1ba9ba4Schristos 			   const char ** strp,
843a1ba9ba4Schristos 			   CGEN_FIELDS * fields)
844a1ba9ba4Schristos {
845a1ba9ba4Schristos   const char * errmsg = NULL;
846a1ba9ba4Schristos   /* Used by scalar operands that still need to be parsed.  */
847a1ba9ba4Schristos   long junk ATTRIBUTE_UNUSED;
848a1ba9ba4Schristos 
849a1ba9ba4Schristos   switch (opindex)
850a1ba9ba4Schristos     {
851a1ba9ba4Schristos     case MEP_OPERAND_ADDR24A4 :
852a1ba9ba4Schristos       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
853a1ba9ba4Schristos       break;
854a1ba9ba4Schristos     case MEP_OPERAND_C5RMUIMM20 :
855a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
856a1ba9ba4Schristos       break;
857a1ba9ba4Schristos     case MEP_OPERAND_C5RNMUIMM24 :
858a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
859a1ba9ba4Schristos       break;
860a1ba9ba4Schristos     case MEP_OPERAND_CALLNUM :
861a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
862a1ba9ba4Schristos       break;
863a1ba9ba4Schristos     case MEP_OPERAND_CCCC :
864a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
865a1ba9ba4Schristos       break;
866a1ba9ba4Schristos     case MEP_OPERAND_CCRN :
867a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
868a1ba9ba4Schristos       break;
869a1ba9ba4Schristos     case MEP_OPERAND_CDISP10 :
870a1ba9ba4Schristos       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
871a1ba9ba4Schristos       break;
872a1ba9ba4Schristos     case MEP_OPERAND_CDISP10A2 :
873a1ba9ba4Schristos       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
874a1ba9ba4Schristos       break;
875a1ba9ba4Schristos     case MEP_OPERAND_CDISP10A4 :
876a1ba9ba4Schristos       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
877a1ba9ba4Schristos       break;
878a1ba9ba4Schristos     case MEP_OPERAND_CDISP10A8 :
879a1ba9ba4Schristos       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
880a1ba9ba4Schristos       break;
881a1ba9ba4Schristos     case MEP_OPERAND_CDISP12 :
882a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
883a1ba9ba4Schristos       break;
884a1ba9ba4Schristos     case MEP_OPERAND_CIMM4 :
885a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
886a1ba9ba4Schristos       break;
887a1ba9ba4Schristos     case MEP_OPERAND_CIMM5 :
888a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
889a1ba9ba4Schristos       break;
890a1ba9ba4Schristos     case MEP_OPERAND_CODE16 :
891a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
892a1ba9ba4Schristos       break;
893a1ba9ba4Schristos     case MEP_OPERAND_CODE24 :
894a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
895a1ba9ba4Schristos       break;
896a1ba9ba4Schristos     case MEP_OPERAND_CP_FLAG :
897a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
898a1ba9ba4Schristos       break;
899a1ba9ba4Schristos     case MEP_OPERAND_CRN :
900a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
901a1ba9ba4Schristos       break;
902a1ba9ba4Schristos     case MEP_OPERAND_CRN64 :
903a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
904a1ba9ba4Schristos       break;
905a1ba9ba4Schristos     case MEP_OPERAND_CRNX :
906a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
907a1ba9ba4Schristos       break;
908a1ba9ba4Schristos     case MEP_OPERAND_CRNX64 :
909a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
910a1ba9ba4Schristos       break;
911a1ba9ba4Schristos     case MEP_OPERAND_CROC :
912a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u7);
913a1ba9ba4Schristos       break;
914a1ba9ba4Schristos     case MEP_OPERAND_CROP :
915a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u23);
916a1ba9ba4Schristos       break;
917a1ba9ba4Schristos     case MEP_OPERAND_CRPC :
918a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u26);
919a1ba9ba4Schristos       break;
920a1ba9ba4Schristos     case MEP_OPERAND_CRPP :
921a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u18);
922a1ba9ba4Schristos       break;
923a1ba9ba4Schristos     case MEP_OPERAND_CRQC :
924a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u21);
925a1ba9ba4Schristos       break;
926a1ba9ba4Schristos     case MEP_OPERAND_CRQP :
927a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u13);
928a1ba9ba4Schristos       break;
929a1ba9ba4Schristos     case MEP_OPERAND_CSRN :
930a1ba9ba4Schristos       errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
931a1ba9ba4Schristos       break;
932a1ba9ba4Schristos     case MEP_OPERAND_CSRN_IDX :
933a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
934a1ba9ba4Schristos       break;
935a1ba9ba4Schristos     case MEP_OPERAND_DBG :
936a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
937a1ba9ba4Schristos       break;
938a1ba9ba4Schristos     case MEP_OPERAND_DEPC :
939a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
940a1ba9ba4Schristos       break;
941a1ba9ba4Schristos     case MEP_OPERAND_EPC :
942a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
943a1ba9ba4Schristos       break;
944a1ba9ba4Schristos     case MEP_OPERAND_EXC :
945a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
946a1ba9ba4Schristos       break;
947a1ba9ba4Schristos     case MEP_OPERAND_HI :
948a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
949a1ba9ba4Schristos       break;
950a1ba9ba4Schristos     case MEP_OPERAND_IMM16P0 :
951a1ba9ba4Schristos       errmsg = parse_unsigned16_range (cd, strp, MEP_OPERAND_IMM16P0, (unsigned long *) (& fields->f_ivc2_imm16p0));
952a1ba9ba4Schristos       break;
953a1ba9ba4Schristos     case MEP_OPERAND_IMM3P12 :
954a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P12, (unsigned long *) (& fields->f_ivc2_3u12));
955a1ba9ba4Schristos       break;
956a1ba9ba4Schristos     case MEP_OPERAND_IMM3P25 :
957a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P25, (unsigned long *) (& fields->f_ivc2_3u25));
958a1ba9ba4Schristos       break;
959a1ba9ba4Schristos     case MEP_OPERAND_IMM3P4 :
960a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P4, (unsigned long *) (& fields->f_ivc2_3u4));
961a1ba9ba4Schristos       break;
962a1ba9ba4Schristos     case MEP_OPERAND_IMM3P5 :
963a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P5, (unsigned long *) (& fields->f_ivc2_3u5));
964a1ba9ba4Schristos       break;
965a1ba9ba4Schristos     case MEP_OPERAND_IMM3P9 :
966a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P9, (unsigned long *) (& fields->f_ivc2_3u9));
967a1ba9ba4Schristos       break;
968a1ba9ba4Schristos     case MEP_OPERAND_IMM4P10 :
969a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P10, (unsigned long *) (& fields->f_ivc2_4u10));
970a1ba9ba4Schristos       break;
971a1ba9ba4Schristos     case MEP_OPERAND_IMM4P4 :
972a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P4, (unsigned long *) (& fields->f_ivc2_4u4));
973a1ba9ba4Schristos       break;
974a1ba9ba4Schristos     case MEP_OPERAND_IMM4P8 :
975a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P8, (unsigned long *) (& fields->f_ivc2_4u8));
976a1ba9ba4Schristos       break;
977a1ba9ba4Schristos     case MEP_OPERAND_IMM5P23 :
978a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P23, (unsigned long *) (& fields->f_ivc2_5u23));
979a1ba9ba4Schristos       break;
980a1ba9ba4Schristos     case MEP_OPERAND_IMM5P3 :
981a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P3, (unsigned long *) (& fields->f_ivc2_5u3));
982a1ba9ba4Schristos       break;
983a1ba9ba4Schristos     case MEP_OPERAND_IMM5P7 :
984a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P7, (unsigned long *) (& fields->f_ivc2_5u7));
985a1ba9ba4Schristos       break;
986a1ba9ba4Schristos     case MEP_OPERAND_IMM5P8 :
987a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P8, (unsigned long *) (& fields->f_ivc2_5u8));
988a1ba9ba4Schristos       break;
989a1ba9ba4Schristos     case MEP_OPERAND_IMM6P2 :
990a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P2, (unsigned long *) (& fields->f_ivc2_6u2));
991a1ba9ba4Schristos       break;
992a1ba9ba4Schristos     case MEP_OPERAND_IMM6P6 :
993a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P6, (unsigned long *) (& fields->f_ivc2_6u6));
994a1ba9ba4Schristos       break;
995a1ba9ba4Schristos     case MEP_OPERAND_IMM8P0 :
996a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P0, (unsigned long *) (& fields->f_ivc2_8u0));
997a1ba9ba4Schristos       break;
998a1ba9ba4Schristos     case MEP_OPERAND_IMM8P20 :
999a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P20, (unsigned long *) (& fields->f_ivc2_8u20));
1000a1ba9ba4Schristos       break;
1001a1ba9ba4Schristos     case MEP_OPERAND_IMM8P4 :
1002a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P4, (unsigned long *) (& fields->f_ivc2_8u4));
1003a1ba9ba4Schristos       break;
1004a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_0_2 :
1005a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_2, (unsigned long *) (& fields->f_ivc2_2u0));
1006a1ba9ba4Schristos       break;
1007a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_0_3 :
1008a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_3, (unsigned long *) (& fields->f_ivc2_3u0));
1009a1ba9ba4Schristos       break;
1010a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_0_4 :
1011a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_4, (unsigned long *) (& fields->f_ivc2_4u0));
1012a1ba9ba4Schristos       break;
1013a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_0_5 :
1014a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_5, (unsigned long *) (& fields->f_ivc2_5u0));
1015a1ba9ba4Schristos       break;
1016a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_6_1 :
1017a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_1, (unsigned long *) (& fields->f_ivc2_1u6));
1018a1ba9ba4Schristos       break;
1019a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_6_2 :
1020a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_2, (unsigned long *) (& fields->f_ivc2_2u6));
1021a1ba9ba4Schristos       break;
1022a1ba9ba4Schristos     case MEP_OPERAND_IVC_X_6_3 :
1023a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_3, (unsigned long *) (& fields->f_ivc2_3u6));
1024a1ba9ba4Schristos       break;
1025a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_0 :
1026a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1027a1ba9ba4Schristos       break;
1028a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_1 :
1029a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1030a1ba9ba4Schristos       break;
1031a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_2 :
1032a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1033a1ba9ba4Schristos       break;
1034a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_3 :
1035a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1036a1ba9ba4Schristos       break;
1037a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_4 :
1038a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1039a1ba9ba4Schristos       break;
1040a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_5 :
1041a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1042a1ba9ba4Schristos       break;
1043a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_6 :
1044a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1045a1ba9ba4Schristos       break;
1046a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC0_7 :
1047a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1048a1ba9ba4Schristos       break;
1049a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_0 :
1050a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1051a1ba9ba4Schristos       break;
1052a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_1 :
1053a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1054a1ba9ba4Schristos       break;
1055a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_2 :
1056a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1057a1ba9ba4Schristos       break;
1058a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_3 :
1059a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1060a1ba9ba4Schristos       break;
1061a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_4 :
1062a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1063a1ba9ba4Schristos       break;
1064a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_5 :
1065a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1066a1ba9ba4Schristos       break;
1067a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_6 :
1068a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1069a1ba9ba4Schristos       break;
1070a1ba9ba4Schristos     case MEP_OPERAND_IVC2_ACC1_7 :
1071a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1072a1ba9ba4Schristos       break;
1073a1ba9ba4Schristos     case MEP_OPERAND_IVC2_CC :
1074a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1075a1ba9ba4Schristos       break;
1076a1ba9ba4Schristos     case MEP_OPERAND_IVC2_COFA0 :
1077a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1078a1ba9ba4Schristos       break;
1079a1ba9ba4Schristos     case MEP_OPERAND_IVC2_COFA1 :
1080a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1081a1ba9ba4Schristos       break;
1082a1ba9ba4Schristos     case MEP_OPERAND_IVC2_COFR0 :
1083a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1084a1ba9ba4Schristos       break;
1085a1ba9ba4Schristos     case MEP_OPERAND_IVC2_COFR1 :
1086a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1087a1ba9ba4Schristos       break;
1088a1ba9ba4Schristos     case MEP_OPERAND_IVC2_CSAR0 :
1089a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1090a1ba9ba4Schristos       break;
1091a1ba9ba4Schristos     case MEP_OPERAND_IVC2_CSAR1 :
1092a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1093a1ba9ba4Schristos       break;
1094a1ba9ba4Schristos     case MEP_OPERAND_IVC2C3CCRN :
1095a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn_c3);
1096a1ba9ba4Schristos       break;
1097a1ba9ba4Schristos     case MEP_OPERAND_IVC2CCRN :
1098a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn);
1099a1ba9ba4Schristos       break;
1100a1ba9ba4Schristos     case MEP_OPERAND_IVC2CRN :
1101a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_crnx);
1102a1ba9ba4Schristos       break;
1103a1ba9ba4Schristos     case MEP_OPERAND_IVC2RM :
1104a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_ivc2_crm);
1105a1ba9ba4Schristos       break;
1106a1ba9ba4Schristos     case MEP_OPERAND_LO :
1107a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1108a1ba9ba4Schristos       break;
1109a1ba9ba4Schristos     case MEP_OPERAND_LP :
1110a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1111a1ba9ba4Schristos       break;
1112a1ba9ba4Schristos     case MEP_OPERAND_MB0 :
1113a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1114a1ba9ba4Schristos       break;
1115a1ba9ba4Schristos     case MEP_OPERAND_MB1 :
1116a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1117a1ba9ba4Schristos       break;
1118a1ba9ba4Schristos     case MEP_OPERAND_ME0 :
1119a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1120a1ba9ba4Schristos       break;
1121a1ba9ba4Schristos     case MEP_OPERAND_ME1 :
1122a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1123a1ba9ba4Schristos       break;
1124a1ba9ba4Schristos     case MEP_OPERAND_NPC :
1125a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1126a1ba9ba4Schristos       break;
1127a1ba9ba4Schristos     case MEP_OPERAND_OPT :
1128a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1129a1ba9ba4Schristos       break;
1130a1ba9ba4Schristos     case MEP_OPERAND_PCABS24A2 :
1131a1ba9ba4Schristos       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
1132a1ba9ba4Schristos       break;
1133a1ba9ba4Schristos     case MEP_OPERAND_PCREL12A2 :
1134a1ba9ba4Schristos       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
1135a1ba9ba4Schristos       break;
1136a1ba9ba4Schristos     case MEP_OPERAND_PCREL17A2 :
1137a1ba9ba4Schristos       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
1138a1ba9ba4Schristos       break;
1139a1ba9ba4Schristos     case MEP_OPERAND_PCREL24A2 :
1140a1ba9ba4Schristos       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
1141a1ba9ba4Schristos       break;
1142a1ba9ba4Schristos     case MEP_OPERAND_PCREL8A2 :
1143a1ba9ba4Schristos       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
1144a1ba9ba4Schristos       break;
1145a1ba9ba4Schristos     case MEP_OPERAND_PSW :
1146a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1147a1ba9ba4Schristos       break;
1148a1ba9ba4Schristos     case MEP_OPERAND_R0 :
1149a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1150a1ba9ba4Schristos       break;
1151a1ba9ba4Schristos     case MEP_OPERAND_R1 :
1152a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1153a1ba9ba4Schristos       break;
1154a1ba9ba4Schristos     case MEP_OPERAND_RL :
1155a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
1156a1ba9ba4Schristos       break;
1157a1ba9ba4Schristos     case MEP_OPERAND_RL5 :
1158a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
1159a1ba9ba4Schristos       break;
1160a1ba9ba4Schristos     case MEP_OPERAND_RM :
1161a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1162a1ba9ba4Schristos       break;
1163a1ba9ba4Schristos     case MEP_OPERAND_RMA :
1164a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1165a1ba9ba4Schristos       break;
1166a1ba9ba4Schristos     case MEP_OPERAND_RN :
1167a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1168a1ba9ba4Schristos       break;
1169a1ba9ba4Schristos     case MEP_OPERAND_RN3 :
1170a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1171a1ba9ba4Schristos       break;
1172a1ba9ba4Schristos     case MEP_OPERAND_RN3C :
1173a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1174a1ba9ba4Schristos       break;
1175a1ba9ba4Schristos     case MEP_OPERAND_RN3L :
1176a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1177a1ba9ba4Schristos       break;
1178a1ba9ba4Schristos     case MEP_OPERAND_RN3S :
1179a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1180a1ba9ba4Schristos       break;
1181a1ba9ba4Schristos     case MEP_OPERAND_RN3UC :
1182a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1183a1ba9ba4Schristos       break;
1184a1ba9ba4Schristos     case MEP_OPERAND_RN3UL :
1185a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1186a1ba9ba4Schristos       break;
1187a1ba9ba4Schristos     case MEP_OPERAND_RN3US :
1188a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1189a1ba9ba4Schristos       break;
1190a1ba9ba4Schristos     case MEP_OPERAND_RNC :
1191a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1192a1ba9ba4Schristos       break;
1193a1ba9ba4Schristos     case MEP_OPERAND_RNL :
1194a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1195a1ba9ba4Schristos       break;
1196a1ba9ba4Schristos     case MEP_OPERAND_RNS :
1197a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1198a1ba9ba4Schristos       break;
1199a1ba9ba4Schristos     case MEP_OPERAND_RNUC :
1200a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1201a1ba9ba4Schristos       break;
1202a1ba9ba4Schristos     case MEP_OPERAND_RNUL :
1203a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1204a1ba9ba4Schristos       break;
1205a1ba9ba4Schristos     case MEP_OPERAND_RNUS :
1206a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1207a1ba9ba4Schristos       break;
1208a1ba9ba4Schristos     case MEP_OPERAND_SAR :
1209a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1210a1ba9ba4Schristos       break;
1211a1ba9ba4Schristos     case MEP_OPERAND_SDISP16 :
1212a1ba9ba4Schristos       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
1213a1ba9ba4Schristos       break;
1214a1ba9ba4Schristos     case MEP_OPERAND_SIMM16 :
1215a1ba9ba4Schristos       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
1216a1ba9ba4Schristos       break;
1217a1ba9ba4Schristos     case MEP_OPERAND_SIMM16P0 :
1218a1ba9ba4Schristos       errmsg = parse_signed16_range (cd, strp, MEP_OPERAND_SIMM16P0, (long *) (& fields->f_ivc2_simm16p0));
1219a1ba9ba4Schristos       break;
1220a1ba9ba4Schristos     case MEP_OPERAND_SIMM6 :
1221a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
1222a1ba9ba4Schristos       break;
1223a1ba9ba4Schristos     case MEP_OPERAND_SIMM8 :
1224a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
1225a1ba9ba4Schristos       break;
1226a1ba9ba4Schristos     case MEP_OPERAND_SIMM8P0 :
1227a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P0, (long *) (& fields->f_ivc2_8s0));
1228a1ba9ba4Schristos       break;
1229a1ba9ba4Schristos     case MEP_OPERAND_SIMM8P20 :
1230a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P20, (long *) (& fields->f_ivc2_8s20));
1231a1ba9ba4Schristos       break;
1232a1ba9ba4Schristos     case MEP_OPERAND_SIMM8P4 :
1233a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P4, (long *) (& fields->f_ivc2_8s4));
1234a1ba9ba4Schristos       break;
1235a1ba9ba4Schristos     case MEP_OPERAND_SP :
1236a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1237a1ba9ba4Schristos       break;
1238a1ba9ba4Schristos     case MEP_OPERAND_SPR :
1239a1ba9ba4Schristos       errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1240a1ba9ba4Schristos       break;
1241a1ba9ba4Schristos     case MEP_OPERAND_TP :
1242a1ba9ba4Schristos       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1243a1ba9ba4Schristos       break;
1244a1ba9ba4Schristos     case MEP_OPERAND_TPR :
1245a1ba9ba4Schristos       errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1246a1ba9ba4Schristos       break;
1247a1ba9ba4Schristos     case MEP_OPERAND_UDISP2 :
1248a1ba9ba4Schristos       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
1249a1ba9ba4Schristos       break;
1250a1ba9ba4Schristos     case MEP_OPERAND_UDISP7 :
1251a1ba9ba4Schristos       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
1252a1ba9ba4Schristos       break;
1253a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A2 :
1254a1ba9ba4Schristos       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1255a1ba9ba4Schristos       break;
1256a1ba9ba4Schristos     case MEP_OPERAND_UDISP7A4 :
1257a1ba9ba4Schristos       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1258a1ba9ba4Schristos       break;
1259a1ba9ba4Schristos     case MEP_OPERAND_UIMM16 :
1260a1ba9ba4Schristos       errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1261a1ba9ba4Schristos       break;
1262a1ba9ba4Schristos     case MEP_OPERAND_UIMM2 :
1263a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1264a1ba9ba4Schristos       break;
1265a1ba9ba4Schristos     case MEP_OPERAND_UIMM24 :
1266a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1267a1ba9ba4Schristos       break;
1268a1ba9ba4Schristos     case MEP_OPERAND_UIMM3 :
1269a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1270a1ba9ba4Schristos       break;
1271a1ba9ba4Schristos     case MEP_OPERAND_UIMM4 :
1272a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1273a1ba9ba4Schristos       break;
1274a1ba9ba4Schristos     case MEP_OPERAND_UIMM5 :
1275a1ba9ba4Schristos       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1276a1ba9ba4Schristos       break;
1277a1ba9ba4Schristos     case MEP_OPERAND_UIMM7A4 :
1278a1ba9ba4Schristos       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1279a1ba9ba4Schristos       break;
1280a1ba9ba4Schristos     case MEP_OPERAND_ZERO :
1281a1ba9ba4Schristos       errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1282a1ba9ba4Schristos       break;
1283a1ba9ba4Schristos 
1284a1ba9ba4Schristos     default :
1285a1ba9ba4Schristos       /* xgettext:c-format */
1286dc268d07Schristos       opcodes_error_handler
1287dc268d07Schristos 	(_("internal error: unrecognized field %d while parsing"),
1288dc268d07Schristos 	 opindex);
1289a1ba9ba4Schristos       abort ();
1290a1ba9ba4Schristos   }
1291a1ba9ba4Schristos 
1292a1ba9ba4Schristos   return errmsg;
1293a1ba9ba4Schristos }
1294a1ba9ba4Schristos 
1295a1ba9ba4Schristos cgen_parse_fn * const mep_cgen_parse_handlers[] =
1296a1ba9ba4Schristos {
1297a1ba9ba4Schristos   parse_insn_normal,
1298a1ba9ba4Schristos };
1299a1ba9ba4Schristos 
1300a1ba9ba4Schristos void
mep_cgen_init_asm(CGEN_CPU_DESC cd)1301a1ba9ba4Schristos mep_cgen_init_asm (CGEN_CPU_DESC cd)
1302a1ba9ba4Schristos {
1303a1ba9ba4Schristos   mep_cgen_init_opcode_table (cd);
1304a1ba9ba4Schristos   mep_cgen_init_ibld_table (cd);
1305a1ba9ba4Schristos   cd->parse_handlers = & mep_cgen_parse_handlers[0];
1306a1ba9ba4Schristos   cd->parse_operand = mep_cgen_parse_operand;
1307a1ba9ba4Schristos #ifdef CGEN_ASM_INIT_HOOK
1308a1ba9ba4Schristos CGEN_ASM_INIT_HOOK
1309a1ba9ba4Schristos #endif
1310a1ba9ba4Schristos }
1311a1ba9ba4Schristos 
1312a1ba9ba4Schristos 
1313a1ba9ba4Schristos 
1314a1ba9ba4Schristos /* Regex construction routine.
1315a1ba9ba4Schristos 
1316a1ba9ba4Schristos    This translates an opcode syntax string into a regex string,
1317a1ba9ba4Schristos    by replacing any non-character syntax element (such as an
1318a1ba9ba4Schristos    opcode) with the pattern '.*'
1319a1ba9ba4Schristos 
1320a1ba9ba4Schristos    It then compiles the regex and stores it in the opcode, for
1321a1ba9ba4Schristos    later use by mep_cgen_assemble_insn
1322a1ba9ba4Schristos 
1323a1ba9ba4Schristos    Returns NULL for success, an error message for failure.  */
1324a1ba9ba4Schristos 
1325a1ba9ba4Schristos char *
mep_cgen_build_insn_regex(CGEN_INSN * insn)1326a1ba9ba4Schristos mep_cgen_build_insn_regex (CGEN_INSN *insn)
1327a1ba9ba4Schristos {
1328a1ba9ba4Schristos   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1329a1ba9ba4Schristos   const char *mnem = CGEN_INSN_MNEMONIC (insn);
1330a1ba9ba4Schristos   char rxbuf[CGEN_MAX_RX_ELEMENTS];
1331a1ba9ba4Schristos   char *rx = rxbuf;
1332a1ba9ba4Schristos   const CGEN_SYNTAX_CHAR_TYPE *syn;
1333a1ba9ba4Schristos   int reg_err;
1334a1ba9ba4Schristos 
1335a1ba9ba4Schristos   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1336a1ba9ba4Schristos 
1337a1ba9ba4Schristos   /* Mnemonics come first in the syntax string.  */
1338a1ba9ba4Schristos   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1339a1ba9ba4Schristos     return _("missing mnemonic in syntax string");
1340a1ba9ba4Schristos   ++syn;
1341a1ba9ba4Schristos 
1342a1ba9ba4Schristos   /* Generate a case sensitive regular expression that emulates case
1343a1ba9ba4Schristos      insensitive matching in the "C" locale.  We cannot generate a case
1344a1ba9ba4Schristos      insensitive regular expression because in Turkish locales, 'i' and 'I'
1345a1ba9ba4Schristos      are not equal modulo case conversion.  */
1346a1ba9ba4Schristos 
1347a1ba9ba4Schristos   /* Copy the literal mnemonic out of the insn.  */
1348a1ba9ba4Schristos   for (; *mnem; mnem++)
1349a1ba9ba4Schristos     {
1350a1ba9ba4Schristos       char c = *mnem;
1351a1ba9ba4Schristos 
1352a1ba9ba4Schristos       if (ISALPHA (c))
1353a1ba9ba4Schristos 	{
1354a1ba9ba4Schristos 	  *rx++ = '[';
1355a1ba9ba4Schristos 	  *rx++ = TOLOWER (c);
1356a1ba9ba4Schristos 	  *rx++ = TOUPPER (c);
1357a1ba9ba4Schristos 	  *rx++ = ']';
1358a1ba9ba4Schristos 	}
1359a1ba9ba4Schristos       else
1360a1ba9ba4Schristos 	*rx++ = c;
1361a1ba9ba4Schristos     }
1362a1ba9ba4Schristos 
1363a1ba9ba4Schristos   /* Copy any remaining literals from the syntax string into the rx.  */
1364a1ba9ba4Schristos   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1365a1ba9ba4Schristos     {
1366a1ba9ba4Schristos       if (CGEN_SYNTAX_CHAR_P (* syn))
1367a1ba9ba4Schristos 	{
1368a1ba9ba4Schristos 	  char c = CGEN_SYNTAX_CHAR (* syn);
1369a1ba9ba4Schristos 
1370a1ba9ba4Schristos 	  switch (c)
1371a1ba9ba4Schristos 	    {
1372a1ba9ba4Schristos 	      /* Escape any regex metacharacters in the syntax.  */
1373a1ba9ba4Schristos 	    case '.': case '[': case '\\':
1374a1ba9ba4Schristos 	    case '*': case '^': case '$':
1375a1ba9ba4Schristos 
1376a1ba9ba4Schristos #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1377a1ba9ba4Schristos 	    case '?': case '{': case '}':
1378a1ba9ba4Schristos 	    case '(': case ')': case '*':
1379a1ba9ba4Schristos 	    case '|': case '+': case ']':
1380a1ba9ba4Schristos #endif
1381a1ba9ba4Schristos 	      *rx++ = '\\';
1382a1ba9ba4Schristos 	      *rx++ = c;
1383a1ba9ba4Schristos 	      break;
1384a1ba9ba4Schristos 
1385a1ba9ba4Schristos 	    default:
1386a1ba9ba4Schristos 	      if (ISALPHA (c))
1387a1ba9ba4Schristos 		{
1388a1ba9ba4Schristos 		  *rx++ = '[';
1389a1ba9ba4Schristos 		  *rx++ = TOLOWER (c);
1390a1ba9ba4Schristos 		  *rx++ = TOUPPER (c);
1391a1ba9ba4Schristos 		  *rx++ = ']';
1392a1ba9ba4Schristos 		}
1393a1ba9ba4Schristos 	      else
1394a1ba9ba4Schristos 		*rx++ = c;
1395a1ba9ba4Schristos 	      break;
1396a1ba9ba4Schristos 	    }
1397a1ba9ba4Schristos 	}
1398a1ba9ba4Schristos       else
1399a1ba9ba4Schristos 	{
1400a1ba9ba4Schristos 	  /* Replace non-syntax fields with globs.  */
1401a1ba9ba4Schristos 	  *rx++ = '.';
1402a1ba9ba4Schristos 	  *rx++ = '*';
1403a1ba9ba4Schristos 	}
1404a1ba9ba4Schristos     }
1405a1ba9ba4Schristos 
1406a1ba9ba4Schristos   /* Trailing whitespace ok.  */
1407a1ba9ba4Schristos   * rx++ = '[';
1408a1ba9ba4Schristos   * rx++ = ' ';
1409a1ba9ba4Schristos   * rx++ = '\t';
1410a1ba9ba4Schristos   * rx++ = ']';
1411a1ba9ba4Schristos   * rx++ = '*';
1412a1ba9ba4Schristos 
1413a1ba9ba4Schristos   /* But anchor it after that.  */
1414a1ba9ba4Schristos   * rx++ = '$';
1415a1ba9ba4Schristos   * rx = '\0';
1416a1ba9ba4Schristos 
1417a1ba9ba4Schristos   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1418a1ba9ba4Schristos   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1419a1ba9ba4Schristos 
1420a1ba9ba4Schristos   if (reg_err == 0)
1421a1ba9ba4Schristos     return NULL;
1422a1ba9ba4Schristos   else
1423a1ba9ba4Schristos     {
1424a1ba9ba4Schristos       static char msg[80];
1425a1ba9ba4Schristos 
1426a1ba9ba4Schristos       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1427a1ba9ba4Schristos       regfree ((regex_t *) CGEN_INSN_RX (insn));
1428a1ba9ba4Schristos       free (CGEN_INSN_RX (insn));
1429a1ba9ba4Schristos       (CGEN_INSN_RX (insn)) = NULL;
1430a1ba9ba4Schristos       return msg;
1431a1ba9ba4Schristos     }
1432a1ba9ba4Schristos }
1433a1ba9ba4Schristos 
1434a1ba9ba4Schristos 
1435a1ba9ba4Schristos /* Default insn parser.
1436a1ba9ba4Schristos 
1437a1ba9ba4Schristos    The syntax string is scanned and operands are parsed and stored in FIELDS.
1438a1ba9ba4Schristos    Relocs are queued as we go via other callbacks.
1439a1ba9ba4Schristos 
1440a1ba9ba4Schristos    ??? Note that this is currently an all-or-nothing parser.  If we fail to
1441a1ba9ba4Schristos    parse the instruction, we return 0 and the caller will start over from
1442a1ba9ba4Schristos    the beginning.  Backtracking will be necessary in parsing subexpressions,
1443a1ba9ba4Schristos    but that can be handled there.  Not handling backtracking here may get
1444a1ba9ba4Schristos    expensive in the case of the m68k.  Deal with later.
1445a1ba9ba4Schristos 
1446a1ba9ba4Schristos    Returns NULL for success, an error message for failure.  */
1447a1ba9ba4Schristos 
1448a1ba9ba4Schristos static const char *
parse_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,const char ** strp,CGEN_FIELDS * fields)1449a1ba9ba4Schristos parse_insn_normal (CGEN_CPU_DESC cd,
1450a1ba9ba4Schristos 		   const CGEN_INSN *insn,
1451a1ba9ba4Schristos 		   const char **strp,
1452a1ba9ba4Schristos 		   CGEN_FIELDS *fields)
1453a1ba9ba4Schristos {
1454a1ba9ba4Schristos   /* ??? Runtime added insns not handled yet.  */
1455a1ba9ba4Schristos   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1456a1ba9ba4Schristos   const char *str = *strp;
1457a1ba9ba4Schristos   const char *errmsg;
1458a1ba9ba4Schristos   const char *p;
1459a1ba9ba4Schristos   const CGEN_SYNTAX_CHAR_TYPE * syn;
1460a1ba9ba4Schristos #ifdef CGEN_MNEMONIC_OPERANDS
1461a1ba9ba4Schristos   /* FIXME: wip */
1462a1ba9ba4Schristos   int past_opcode_p;
1463a1ba9ba4Schristos #endif
1464a1ba9ba4Schristos 
1465a1ba9ba4Schristos   /* For now we assume the mnemonic is first (there are no leading operands).
1466a1ba9ba4Schristos      We can parse it without needing to set up operand parsing.
1467a1ba9ba4Schristos      GAS's input scrubber will ensure mnemonics are lowercase, but we may
1468a1ba9ba4Schristos      not be called from GAS.  */
1469a1ba9ba4Schristos   p = CGEN_INSN_MNEMONIC (insn);
1470a1ba9ba4Schristos   while (*p && TOLOWER (*p) == TOLOWER (*str))
1471a1ba9ba4Schristos     ++p, ++str;
1472a1ba9ba4Schristos 
1473a1ba9ba4Schristos   if (* p)
1474a1ba9ba4Schristos     return _("unrecognized instruction");
1475a1ba9ba4Schristos 
1476a1ba9ba4Schristos #ifndef CGEN_MNEMONIC_OPERANDS
1477a1ba9ba4Schristos   if (* str && ! ISSPACE (* str))
1478a1ba9ba4Schristos     return _("unrecognized instruction");
1479a1ba9ba4Schristos #endif
1480a1ba9ba4Schristos 
1481a1ba9ba4Schristos   CGEN_INIT_PARSE (cd);
1482a1ba9ba4Schristos   cgen_init_parse_operand (cd);
1483a1ba9ba4Schristos #ifdef CGEN_MNEMONIC_OPERANDS
1484a1ba9ba4Schristos   past_opcode_p = 0;
1485a1ba9ba4Schristos #endif
1486a1ba9ba4Schristos 
1487a1ba9ba4Schristos   /* We don't check for (*str != '\0') here because we want to parse
1488a1ba9ba4Schristos      any trailing fake arguments in the syntax string.  */
1489a1ba9ba4Schristos   syn = CGEN_SYNTAX_STRING (syntax);
1490a1ba9ba4Schristos 
1491a1ba9ba4Schristos   /* Mnemonics come first for now, ensure valid string.  */
1492a1ba9ba4Schristos   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1493a1ba9ba4Schristos     abort ();
1494a1ba9ba4Schristos 
1495a1ba9ba4Schristos   ++syn;
1496a1ba9ba4Schristos 
1497a1ba9ba4Schristos   while (* syn != 0)
1498a1ba9ba4Schristos     {
1499a1ba9ba4Schristos       /* Non operand chars must match exactly.  */
1500a1ba9ba4Schristos       if (CGEN_SYNTAX_CHAR_P (* syn))
1501a1ba9ba4Schristos 	{
1502a1ba9ba4Schristos 	  /* FIXME: While we allow for non-GAS callers above, we assume the
1503a1ba9ba4Schristos 	     first char after the mnemonic part is a space.  */
1504a1ba9ba4Schristos 	  /* FIXME: We also take inappropriate advantage of the fact that
1505a1ba9ba4Schristos 	     GAS's input scrubber will remove extraneous blanks.  */
1506a1ba9ba4Schristos 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1507a1ba9ba4Schristos 	    {
1508a1ba9ba4Schristos #ifdef CGEN_MNEMONIC_OPERANDS
1509a1ba9ba4Schristos 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1510a1ba9ba4Schristos 		past_opcode_p = 1;
1511a1ba9ba4Schristos #endif
1512a1ba9ba4Schristos 	      ++ syn;
1513a1ba9ba4Schristos 	      ++ str;
1514a1ba9ba4Schristos 	    }
1515a1ba9ba4Schristos 	  else if (*str)
1516a1ba9ba4Schristos 	    {
1517a1ba9ba4Schristos 	      /* Syntax char didn't match.  Can't be this insn.  */
1518a1ba9ba4Schristos 	      static char msg [80];
1519a1ba9ba4Schristos 
1520a1ba9ba4Schristos 	      /* xgettext:c-format */
1521a1ba9ba4Schristos 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1522a1ba9ba4Schristos 		       CGEN_SYNTAX_CHAR(*syn), *str);
1523a1ba9ba4Schristos 	      return msg;
1524a1ba9ba4Schristos 	    }
1525a1ba9ba4Schristos 	  else
1526a1ba9ba4Schristos 	    {
1527a1ba9ba4Schristos 	      /* Ran out of input.  */
1528a1ba9ba4Schristos 	      static char msg [80];
1529a1ba9ba4Schristos 
1530a1ba9ba4Schristos 	      /* xgettext:c-format */
1531a1ba9ba4Schristos 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1532a1ba9ba4Schristos 		       CGEN_SYNTAX_CHAR(*syn));
1533a1ba9ba4Schristos 	      return msg;
1534a1ba9ba4Schristos 	    }
1535a1ba9ba4Schristos 	  continue;
1536a1ba9ba4Schristos 	}
1537a1ba9ba4Schristos 
1538a1ba9ba4Schristos #ifdef CGEN_MNEMONIC_OPERANDS
1539a1ba9ba4Schristos       (void) past_opcode_p;
1540a1ba9ba4Schristos #endif
1541a1ba9ba4Schristos       /* We have an operand of some sort.  */
1542a1ba9ba4Schristos       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1543a1ba9ba4Schristos       if (errmsg)
1544a1ba9ba4Schristos 	return errmsg;
1545a1ba9ba4Schristos 
1546a1ba9ba4Schristos       /* Done with this operand, continue with next one.  */
1547a1ba9ba4Schristos       ++ syn;
1548a1ba9ba4Schristos     }
1549a1ba9ba4Schristos 
1550a1ba9ba4Schristos   /* If we're at the end of the syntax string, we're done.  */
1551a1ba9ba4Schristos   if (* syn == 0)
1552a1ba9ba4Schristos     {
1553a1ba9ba4Schristos       /* FIXME: For the moment we assume a valid `str' can only contain
1554a1ba9ba4Schristos 	 blanks now.  IE: We needn't try again with a longer version of
1555a1ba9ba4Schristos 	 the insn and it is assumed that longer versions of insns appear
1556a1ba9ba4Schristos 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1557a1ba9ba4Schristos       while (ISSPACE (* str))
1558a1ba9ba4Schristos 	++ str;
1559a1ba9ba4Schristos 
1560a1ba9ba4Schristos       if (* str != '\0')
1561a1ba9ba4Schristos 	return _("junk at end of line"); /* FIXME: would like to include `str' */
1562a1ba9ba4Schristos 
1563a1ba9ba4Schristos       return NULL;
1564a1ba9ba4Schristos     }
1565a1ba9ba4Schristos 
1566a1ba9ba4Schristos   /* We couldn't parse it.  */
1567a1ba9ba4Schristos   return _("unrecognized instruction");
1568a1ba9ba4Schristos }
1569a1ba9ba4Schristos 
1570a1ba9ba4Schristos /* Main entry point.
1571a1ba9ba4Schristos    This routine is called for each instruction to be assembled.
1572a1ba9ba4Schristos    STR points to the insn to be assembled.
1573a1ba9ba4Schristos    We assume all necessary tables have been initialized.
1574a1ba9ba4Schristos    The assembled instruction, less any fixups, is stored in BUF.
1575a1ba9ba4Schristos    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1576a1ba9ba4Schristos    still needs to be converted to target byte order, otherwise BUF is an array
1577a1ba9ba4Schristos    of bytes in target byte order.
1578a1ba9ba4Schristos    The result is a pointer to the insn's entry in the opcode table,
1579a1ba9ba4Schristos    or NULL if an error occured (an error message will have already been
1580a1ba9ba4Schristos    printed).
1581a1ba9ba4Schristos 
1582a1ba9ba4Schristos    Note that when processing (non-alias) macro-insns,
1583a1ba9ba4Schristos    this function recurses.
1584a1ba9ba4Schristos 
1585a1ba9ba4Schristos    ??? It's possible to make this cpu-independent.
1586a1ba9ba4Schristos    One would have to deal with a few minor things.
1587a1ba9ba4Schristos    At this point in time doing so would be more of a curiosity than useful
1588a1ba9ba4Schristos    [for example this file isn't _that_ big], but keeping the possibility in
1589a1ba9ba4Schristos    mind helps keep the design clean.  */
1590a1ba9ba4Schristos 
1591a1ba9ba4Schristos const CGEN_INSN *
mep_cgen_assemble_insn(CGEN_CPU_DESC cd,const char * str,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buf,char ** errmsg)1592a1ba9ba4Schristos mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1593a1ba9ba4Schristos 			   const char *str,
1594a1ba9ba4Schristos 			   CGEN_FIELDS *fields,
1595a1ba9ba4Schristos 			   CGEN_INSN_BYTES_PTR buf,
1596a1ba9ba4Schristos 			   char **errmsg)
1597a1ba9ba4Schristos {
1598a1ba9ba4Schristos   const char *start;
1599a1ba9ba4Schristos   CGEN_INSN_LIST *ilist;
1600a1ba9ba4Schristos   const char *parse_errmsg = NULL;
1601a1ba9ba4Schristos   const char *insert_errmsg = NULL;
1602a1ba9ba4Schristos   int recognized_mnemonic = 0;
1603a1ba9ba4Schristos 
1604a1ba9ba4Schristos   /* Skip leading white space.  */
1605a1ba9ba4Schristos   while (ISSPACE (* str))
1606a1ba9ba4Schristos     ++ str;
1607a1ba9ba4Schristos 
1608a1ba9ba4Schristos   /* The instructions are stored in hashed lists.
1609a1ba9ba4Schristos      Get the first in the list.  */
1610a1ba9ba4Schristos   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1611a1ba9ba4Schristos 
1612a1ba9ba4Schristos   /* Keep looking until we find a match.  */
1613a1ba9ba4Schristos   start = str;
1614a1ba9ba4Schristos   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1615a1ba9ba4Schristos     {
1616a1ba9ba4Schristos       const CGEN_INSN *insn = ilist->insn;
1617a1ba9ba4Schristos       recognized_mnemonic = 1;
1618a1ba9ba4Schristos 
1619a1ba9ba4Schristos #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1620a1ba9ba4Schristos       /* Not usually needed as unsupported opcodes
1621a1ba9ba4Schristos 	 shouldn't be in the hash lists.  */
1622a1ba9ba4Schristos       /* Is this insn supported by the selected cpu?  */
1623a1ba9ba4Schristos       if (! mep_cgen_insn_supported (cd, insn))
1624a1ba9ba4Schristos 	continue;
1625a1ba9ba4Schristos #endif
1626a1ba9ba4Schristos       /* If the RELAXED attribute is set, this is an insn that shouldn't be
1627a1ba9ba4Schristos 	 chosen immediately.  Instead, it is used during assembler/linker
1628a1ba9ba4Schristos 	 relaxation if possible.  */
1629a1ba9ba4Schristos       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1630a1ba9ba4Schristos 	continue;
1631a1ba9ba4Schristos 
1632a1ba9ba4Schristos       str = start;
1633a1ba9ba4Schristos 
1634a1ba9ba4Schristos       /* Skip this insn if str doesn't look right lexically.  */
1635a1ba9ba4Schristos       if (CGEN_INSN_RX (insn) != NULL &&
1636a1ba9ba4Schristos 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1637a1ba9ba4Schristos 	continue;
1638a1ba9ba4Schristos 
1639a1ba9ba4Schristos       /* Allow parse/insert handlers to obtain length of insn.  */
1640a1ba9ba4Schristos       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1641a1ba9ba4Schristos 
1642a1ba9ba4Schristos       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1643a1ba9ba4Schristos       if (parse_errmsg != NULL)
1644a1ba9ba4Schristos 	continue;
1645a1ba9ba4Schristos 
1646a1ba9ba4Schristos       /* ??? 0 is passed for `pc'.  */
1647a1ba9ba4Schristos       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1648a1ba9ba4Schristos 						 (bfd_vma) 0);
1649a1ba9ba4Schristos       if (insert_errmsg != NULL)
1650a1ba9ba4Schristos         continue;
1651a1ba9ba4Schristos 
1652a1ba9ba4Schristos       /* It is up to the caller to actually output the insn and any
1653a1ba9ba4Schristos          queued relocs.  */
1654a1ba9ba4Schristos       return insn;
1655a1ba9ba4Schristos     }
1656a1ba9ba4Schristos 
1657a1ba9ba4Schristos   {
1658a1ba9ba4Schristos     static char errbuf[150];
1659a1ba9ba4Schristos     const char *tmp_errmsg;
1660a1ba9ba4Schristos #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1661a1ba9ba4Schristos #define be_verbose 1
1662a1ba9ba4Schristos #else
1663a1ba9ba4Schristos #define be_verbose 0
1664a1ba9ba4Schristos #endif
1665a1ba9ba4Schristos 
1666a1ba9ba4Schristos     if (be_verbose)
1667a1ba9ba4Schristos       {
1668a1ba9ba4Schristos 	/* If requesting verbose error messages, use insert_errmsg.
1669a1ba9ba4Schristos 	   Failing that, use parse_errmsg.  */
1670a1ba9ba4Schristos 	tmp_errmsg = (insert_errmsg ? insert_errmsg :
1671a1ba9ba4Schristos 		      parse_errmsg ? parse_errmsg :
1672a1ba9ba4Schristos 		      recognized_mnemonic ?
1673a1ba9ba4Schristos 		      _("unrecognized form of instruction") :
1674a1ba9ba4Schristos 		      _("unrecognized instruction"));
1675a1ba9ba4Schristos 
1676a1ba9ba4Schristos 	if (strlen (start) > 50)
1677a1ba9ba4Schristos 	  /* xgettext:c-format */
1678a1ba9ba4Schristos 	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1679a1ba9ba4Schristos 	else
1680a1ba9ba4Schristos 	  /* xgettext:c-format */
1681a1ba9ba4Schristos 	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1682a1ba9ba4Schristos       }
1683a1ba9ba4Schristos     else
1684a1ba9ba4Schristos       {
1685a1ba9ba4Schristos 	if (strlen (start) > 50)
1686a1ba9ba4Schristos 	  /* xgettext:c-format */
1687a1ba9ba4Schristos 	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1688a1ba9ba4Schristos 	else
1689a1ba9ba4Schristos 	  /* xgettext:c-format */
1690a1ba9ba4Schristos 	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
1691a1ba9ba4Schristos       }
1692a1ba9ba4Schristos 
1693a1ba9ba4Schristos     *errmsg = errbuf;
1694a1ba9ba4Schristos     return NULL;
1695a1ba9ba4Schristos   }
1696a1ba9ba4Schristos }
1697