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