2003-10-06 Dave Brolley <brolley@redhat.com>
[binutils.git] / opcodes / frv-asm.c
blob1d24b28d405db6f7147b39fd44ece35632c433bf
1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-asm.in isn't
7 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
9 This file is part of the GNU Binutils and GDB, the GNU debugger.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
26 Keep that in mind. */
28 #include "sysdep.h"
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "bfd.h"
32 #include "symcat.h"
33 #include "frv-desc.h"
34 #include "frv-opc.h"
35 #include "opintl.h"
36 #include "xregex.h"
37 #include "libiberty.h"
38 #include "safe-ctype.h"
40 #undef min
41 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #undef max
43 #define max(a,b) ((a) > (b) ? (a) : (b))
45 static const char * parse_insn_normal
46 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
48 /* -- assembler routines inserted here. */
50 /* -- asm.c */
51 static const char * parse_ulo16
52 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
53 static const char * parse_uslo16
54 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
55 static const char * parse_uhi16
56 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
57 static long parse_register_number
58 PARAMS ((const char **));
59 static const char * parse_spr
60 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
61 static const char * parse_d12
62 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
63 static const char * parse_s12
64 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
65 static const char * parse_u12
66 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
67 static const char * parse_even_register
68 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
69 static const char * parse_A0
70 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
71 static const char * parse_A1
72 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
73 static const char * parse_A
74 PARAMS ((CGEN_CPU_DESC, const char **, int, long *, long));
76 static const char *
77 parse_ulo16 (cd, strp, opindex, valuep)
78 CGEN_CPU_DESC cd;
79 const char **strp;
80 int opindex;
81 unsigned long *valuep;
83 const char *errmsg;
84 enum cgen_parse_operand_result result_type;
85 bfd_vma value;
87 if (**strp == '#' || **strp == '%')
89 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
91 *strp += 4;
92 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
93 &result_type, &value);
94 if (**strp != ')')
95 return "missing `)'";
96 ++*strp;
97 if (errmsg == NULL
98 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
99 value &= 0xffff;
100 *valuep = value;
101 return errmsg;
103 if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
105 *strp += 9;
106 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
107 &result_type, &value);
108 if (**strp != ')')
109 return "missing ')'";
110 ++*strp;
111 if (errmsg == NULL
112 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
113 value >>= 16;
114 *valuep = value;
115 return errmsg;
118 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
121 static const char *
122 parse_uslo16 (cd, strp, opindex, valuep)
123 CGEN_CPU_DESC cd;
124 const char **strp;
125 int opindex;
126 unsigned long *valuep;
128 const char *errmsg;
129 enum cgen_parse_operand_result result_type;
130 bfd_vma value;
132 if (**strp == '#' || **strp == '%')
134 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
136 *strp += 4;
137 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
138 &result_type, &value);
139 if (**strp != ')')
140 return "missing `)'";
141 ++*strp;
142 if (errmsg == NULL
143 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
144 value &= 0xffff;
145 *valuep = value;
146 return errmsg;
148 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
150 *strp += 9;
151 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
152 &result_type, &value);
153 if (**strp != ')')
154 return "missing ')'";
155 ++*strp;
156 if (errmsg == NULL
157 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
158 value &= 0xffff;
159 *valuep = value;
160 return errmsg;
163 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
166 static const char *
167 parse_uhi16 (cd, strp, opindex, valuep)
168 CGEN_CPU_DESC cd;
169 const char **strp;
170 int opindex;
171 unsigned long *valuep;
173 const char *errmsg;
174 enum cgen_parse_operand_result result_type;
175 bfd_vma value;
177 if (**strp == '#' || **strp == '%')
179 if (strncasecmp (*strp + 1, "hi(", 3) == 0)
181 *strp += 4;
182 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
183 &result_type, &value);
184 if (**strp != ')')
185 return "missing `)'";
186 ++*strp;
187 if (errmsg == NULL
188 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
189 value >>= 16;
190 *valuep = value;
191 return errmsg;
193 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
195 *strp += 9;
196 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
197 &result_type, &value);
198 if (**strp != ')')
199 return "missing ')'";
200 ++*strp;
201 if (errmsg == NULL
202 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
203 value >>= 16;
204 *valuep = value;
205 return errmsg;
208 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
211 static long
212 parse_register_number (strp)
213 const char **strp;
215 int regno;
216 if (**strp < '0' || **strp > '9')
217 return -1; /* error */
219 regno = **strp - '0';
220 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
221 regno = regno * 10 + (**strp - '0');
223 return regno;
226 static const char *
227 parse_spr (cd, strp, table, valuep)
228 CGEN_CPU_DESC cd;
229 const char **strp;
230 CGEN_KEYWORD * table;
231 long *valuep;
233 const char *save_strp;
234 long regno;
236 /* Check for spr index notation. */
237 if (strncasecmp (*strp, "spr[", 4) == 0)
239 *strp += 4;
240 regno = parse_register_number (strp);
241 if (**strp != ']')
242 return "missing `]'";
243 ++*strp;
244 if (! spr_valid (regno))
245 return "Special purpose register number is out of range";
246 *valuep = regno;
247 return NULL;
250 save_strp = *strp;
251 regno = parse_register_number (strp);
252 if (regno != -1)
254 if (! spr_valid (regno))
255 return "Special purpose register number is out of range";
256 *valuep = regno;
257 return NULL;
260 *strp = save_strp;
261 return cgen_parse_keyword (cd, strp, table, valuep);
264 static const char *
265 parse_d12 (cd, strp, opindex, valuep)
266 CGEN_CPU_DESC cd;
267 const char **strp;
268 int opindex;
269 long *valuep;
271 const char *errmsg;
272 enum cgen_parse_operand_result result_type;
273 bfd_vma value;
275 /* Check for small data reference. */
276 if (**strp == '#' || **strp == '%')
278 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
280 *strp += 9;
281 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
282 &result_type, &value);
283 if (**strp != ')')
284 return "missing `)'";
285 ++*strp;
286 *valuep = value;
287 return errmsg;
290 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
293 static const char *
294 parse_s12 (cd, strp, opindex, valuep)
295 CGEN_CPU_DESC cd;
296 const char **strp;
297 int opindex;
298 long *valuep;
300 const char *errmsg;
301 enum cgen_parse_operand_result result_type;
302 bfd_vma value;
304 /* Check for small data reference. */
305 if ((**strp == '#' || **strp == '%')
306 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
308 *strp += 9;
309 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
310 &result_type, &value);
311 if (**strp != ')')
312 return "missing `)'";
313 ++*strp;
314 *valuep = value;
315 return errmsg;
317 else
319 if (**strp == '#')
320 ++*strp;
321 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
325 static const char *
326 parse_u12 (cd, strp, opindex, valuep)
327 CGEN_CPU_DESC cd;
328 const char **strp;
329 int opindex;
330 long *valuep;
332 const char *errmsg;
333 enum cgen_parse_operand_result result_type;
334 bfd_vma value;
336 /* Check for small data reference. */
337 if ((**strp == '#' || **strp == '%')
338 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
340 *strp += 9;
341 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
342 &result_type, &value);
343 if (**strp != ')')
344 return "missing `)'";
345 ++*strp;
346 *valuep = value;
347 return errmsg;
349 else
351 if (**strp == '#')
352 ++*strp;
353 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
357 static const char *
358 parse_A (cd, strp, opindex, valuep, A)
359 CGEN_CPU_DESC cd;
360 const char **strp;
361 int opindex;
362 long *valuep;
363 long A;
365 const char *errmsg;
367 if (**strp == '#')
368 ++*strp;
370 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
371 if (errmsg)
372 return errmsg;
374 if (*valuep != A)
375 return "Value of A operand must be 0 or 1";
377 return NULL;
380 static const char *
381 parse_A0 (cd, strp, opindex, valuep)
382 CGEN_CPU_DESC cd;
383 const char **strp;
384 int opindex;
385 long *valuep;
387 return parse_A (cd, strp, opindex, valuep, 0);
390 static const char *
391 parse_A1 (cd, strp, opindex, valuep)
392 CGEN_CPU_DESC cd;
393 const char **strp;
394 int opindex;
395 long *valuep;
397 return parse_A (cd, strp, opindex, valuep, 1);
400 static const char *
401 parse_even_register (cd, strP, tableP, valueP)
402 CGEN_CPU_DESC cd;
403 const char ** strP;
404 CGEN_KEYWORD * tableP;
405 long * valueP;
407 const char * errmsg;
408 const char * saved_star_strP = * strP;
410 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
412 if (errmsg == NULL && ((* valueP) & 1))
414 errmsg = _("register number must be even");
415 * strP = saved_star_strP;
418 return errmsg;
420 /* -- */
422 const char * frv_cgen_parse_operand
423 PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
425 /* Main entry point for operand parsing.
427 This function is basically just a big switch statement. Earlier versions
428 used tables to look up the function to use, but
429 - if the table contains both assembler and disassembler functions then
430 the disassembler contains much of the assembler and vice-versa,
431 - there's a lot of inlining possibilities as things grow,
432 - using a switch statement avoids the function call overhead.
434 This function could be moved into `parse_insn_normal', but keeping it
435 separate makes clear the interface between `parse_insn_normal' and each of
436 the handlers. */
438 const char *
439 frv_cgen_parse_operand (cd, opindex, strp, fields)
440 CGEN_CPU_DESC cd;
441 int opindex;
442 const char ** strp;
443 CGEN_FIELDS * fields;
445 const char * errmsg = NULL;
446 /* Used by scalar operands that still need to be parsed. */
447 long junk ATTRIBUTE_UNUSED;
449 switch (opindex)
451 case FRV_OPERAND_A0 :
452 errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, &fields->f_A);
453 break;
454 case FRV_OPERAND_A1 :
455 errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, &fields->f_A);
456 break;
457 case FRV_OPERAND_ACC40SI :
458 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
459 break;
460 case FRV_OPERAND_ACC40SK :
461 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
462 break;
463 case FRV_OPERAND_ACC40UI :
464 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
465 break;
466 case FRV_OPERAND_ACC40UK :
467 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
468 break;
469 case FRV_OPERAND_ACCGI :
470 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
471 break;
472 case FRV_OPERAND_ACCGK :
473 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
474 break;
475 case FRV_OPERAND_CCI :
476 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
477 break;
478 case FRV_OPERAND_CPRDOUBLEK :
479 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
480 break;
481 case FRV_OPERAND_CPRI :
482 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
483 break;
484 case FRV_OPERAND_CPRJ :
485 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
486 break;
487 case FRV_OPERAND_CPRK :
488 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
489 break;
490 case FRV_OPERAND_CRI :
491 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
492 break;
493 case FRV_OPERAND_CRJ :
494 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
495 break;
496 case FRV_OPERAND_CRJ_FLOAT :
497 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
498 break;
499 case FRV_OPERAND_CRJ_INT :
500 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
501 break;
502 case FRV_OPERAND_CRK :
503 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
504 break;
505 case FRV_OPERAND_FCCI_1 :
506 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
507 break;
508 case FRV_OPERAND_FCCI_2 :
509 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
510 break;
511 case FRV_OPERAND_FCCI_3 :
512 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
513 break;
514 case FRV_OPERAND_FCCK :
515 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
516 break;
517 case FRV_OPERAND_FRDOUBLEI :
518 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
519 break;
520 case FRV_OPERAND_FRDOUBLEJ :
521 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
522 break;
523 case FRV_OPERAND_FRDOUBLEK :
524 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
525 break;
526 case FRV_OPERAND_FRI :
527 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
528 break;
529 case FRV_OPERAND_FRINTI :
530 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
531 break;
532 case FRV_OPERAND_FRINTIEVEN :
533 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
534 break;
535 case FRV_OPERAND_FRINTJ :
536 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
537 break;
538 case FRV_OPERAND_FRINTJEVEN :
539 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
540 break;
541 case FRV_OPERAND_FRINTK :
542 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
543 break;
544 case FRV_OPERAND_FRINTKEVEN :
545 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
546 break;
547 case FRV_OPERAND_FRJ :
548 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
549 break;
550 case FRV_OPERAND_FRK :
551 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
552 break;
553 case FRV_OPERAND_FRKHI :
554 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
555 break;
556 case FRV_OPERAND_FRKLO :
557 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
558 break;
559 case FRV_OPERAND_GRDOUBLEK :
560 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
561 break;
562 case FRV_OPERAND_GRI :
563 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
564 break;
565 case FRV_OPERAND_GRJ :
566 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
567 break;
568 case FRV_OPERAND_GRK :
569 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
570 break;
571 case FRV_OPERAND_GRKHI :
572 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
573 break;
574 case FRV_OPERAND_GRKLO :
575 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
576 break;
577 case FRV_OPERAND_ICCI_1 :
578 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
579 break;
580 case FRV_OPERAND_ICCI_2 :
581 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
582 break;
583 case FRV_OPERAND_ICCI_3 :
584 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
585 break;
586 case FRV_OPERAND_LI :
587 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, &fields->f_LI);
588 break;
589 case FRV_OPERAND_AE :
590 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, &fields->f_ae);
591 break;
592 case FRV_OPERAND_CCOND :
593 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, &fields->f_ccond);
594 break;
595 case FRV_OPERAND_COND :
596 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, &fields->f_cond);
597 break;
598 case FRV_OPERAND_D12 :
599 errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, &fields->f_d12);
600 break;
601 case FRV_OPERAND_DEBUG :
602 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, &fields->f_debug);
603 break;
604 case FRV_OPERAND_EIR :
605 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, &fields->f_eir);
606 break;
607 case FRV_OPERAND_HINT :
608 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, &fields->f_hint);
609 break;
610 case FRV_OPERAND_HINT_NOT_TAKEN :
611 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
612 break;
613 case FRV_OPERAND_HINT_TAKEN :
614 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
615 break;
616 case FRV_OPERAND_LABEL16 :
618 bfd_vma value;
619 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value);
620 fields->f_label16 = value;
622 break;
623 case FRV_OPERAND_LABEL24 :
625 bfd_vma value;
626 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value);
627 fields->f_label24 = value;
629 break;
630 case FRV_OPERAND_LOCK :
631 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, &fields->f_lock);
632 break;
633 case FRV_OPERAND_PACK :
634 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
635 break;
636 case FRV_OPERAND_S10 :
637 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, &fields->f_s10);
638 break;
639 case FRV_OPERAND_S12 :
640 errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, &fields->f_d12);
641 break;
642 case FRV_OPERAND_S16 :
643 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, &fields->f_s16);
644 break;
645 case FRV_OPERAND_S5 :
646 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, &fields->f_s5);
647 break;
648 case FRV_OPERAND_S6 :
649 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, &fields->f_s6);
650 break;
651 case FRV_OPERAND_S6_1 :
652 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, &fields->f_s6_1);
653 break;
654 case FRV_OPERAND_SLO16 :
655 errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, &fields->f_s16);
656 break;
657 case FRV_OPERAND_SPR :
658 errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
659 break;
660 case FRV_OPERAND_U12 :
661 errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, &fields->f_u12);
662 break;
663 case FRV_OPERAND_U16 :
664 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, &fields->f_u16);
665 break;
666 case FRV_OPERAND_U6 :
667 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, &fields->f_u6);
668 break;
669 case FRV_OPERAND_UHI16 :
670 errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, &fields->f_u16);
671 break;
672 case FRV_OPERAND_ULO16 :
673 errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, &fields->f_u16);
674 break;
676 default :
677 /* xgettext:c-format */
678 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
679 abort ();
682 return errmsg;
685 cgen_parse_fn * const frv_cgen_parse_handlers[] =
687 parse_insn_normal,
690 void
691 frv_cgen_init_asm (cd)
692 CGEN_CPU_DESC cd;
694 frv_cgen_init_opcode_table (cd);
695 frv_cgen_init_ibld_table (cd);
696 cd->parse_handlers = & frv_cgen_parse_handlers[0];
697 cd->parse_operand = frv_cgen_parse_operand;
702 /* Regex construction routine.
704 This translates an opcode syntax string into a regex string,
705 by replacing any non-character syntax element (such as an
706 opcode) with the pattern '.*'
708 It then compiles the regex and stores it in the opcode, for
709 later use by frv_cgen_assemble_insn
711 Returns NULL for success, an error message for failure. */
713 char *
714 frv_cgen_build_insn_regex (CGEN_INSN *insn)
716 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
717 const char *mnem = CGEN_INSN_MNEMONIC (insn);
718 char rxbuf[CGEN_MAX_RX_ELEMENTS];
719 char *rx = rxbuf;
720 const CGEN_SYNTAX_CHAR_TYPE *syn;
721 int reg_err;
723 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
725 /* Mnemonics come first in the syntax string. */
726 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
727 return _("missing mnemonic in syntax string");
728 ++syn;
730 /* Generate a case sensitive regular expression that emulates case
731 insensitive matching in the "C" locale. We cannot generate a case
732 insensitive regular expression because in Turkish locales, 'i' and 'I'
733 are not equal modulo case conversion. */
735 /* Copy the literal mnemonic out of the insn. */
736 for (; *mnem; mnem++)
738 char c = *mnem;
740 if (ISALPHA (c))
742 *rx++ = '[';
743 *rx++ = TOLOWER (c);
744 *rx++ = TOUPPER (c);
745 *rx++ = ']';
747 else
748 *rx++ = c;
751 /* Copy any remaining literals from the syntax string into the rx. */
752 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
754 if (CGEN_SYNTAX_CHAR_P (* syn))
756 char c = CGEN_SYNTAX_CHAR (* syn);
758 switch (c)
760 /* Escape any regex metacharacters in the syntax. */
761 case '.': case '[': case '\\':
762 case '*': case '^': case '$':
764 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
765 case '?': case '{': case '}':
766 case '(': case ')': case '*':
767 case '|': case '+': case ']':
768 #endif
769 *rx++ = '\\';
770 *rx++ = c;
771 break;
773 default:
774 if (ISALPHA (c))
776 *rx++ = '[';
777 *rx++ = TOLOWER (c);
778 *rx++ = TOUPPER (c);
779 *rx++ = ']';
781 else
782 *rx++ = c;
783 break;
786 else
788 /* Replace non-syntax fields with globs. */
789 *rx++ = '.';
790 *rx++ = '*';
794 /* Trailing whitespace ok. */
795 * rx++ = '[';
796 * rx++ = ' ';
797 * rx++ = '\t';
798 * rx++ = ']';
799 * rx++ = '*';
801 /* But anchor it after that. */
802 * rx++ = '$';
803 * rx = '\0';
805 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
806 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
808 if (reg_err == 0)
809 return NULL;
810 else
812 static char msg[80];
814 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
815 regfree ((regex_t *) CGEN_INSN_RX (insn));
816 free (CGEN_INSN_RX (insn));
817 (CGEN_INSN_RX (insn)) = NULL;
818 return msg;
823 /* Default insn parser.
825 The syntax string is scanned and operands are parsed and stored in FIELDS.
826 Relocs are queued as we go via other callbacks.
828 ??? Note that this is currently an all-or-nothing parser. If we fail to
829 parse the instruction, we return 0 and the caller will start over from
830 the beginning. Backtracking will be necessary in parsing subexpressions,
831 but that can be handled there. Not handling backtracking here may get
832 expensive in the case of the m68k. Deal with later.
834 Returns NULL for success, an error message for failure. */
836 static const char *
837 parse_insn_normal (CGEN_CPU_DESC cd,
838 const CGEN_INSN *insn,
839 const char **strp,
840 CGEN_FIELDS *fields)
842 /* ??? Runtime added insns not handled yet. */
843 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
844 const char *str = *strp;
845 const char *errmsg;
846 const char *p;
847 const CGEN_SYNTAX_CHAR_TYPE * syn;
848 #ifdef CGEN_MNEMONIC_OPERANDS
849 /* FIXME: wip */
850 int past_opcode_p;
851 #endif
853 /* For now we assume the mnemonic is first (there are no leading operands).
854 We can parse it without needing to set up operand parsing.
855 GAS's input scrubber will ensure mnemonics are lowercase, but we may
856 not be called from GAS. */
857 p = CGEN_INSN_MNEMONIC (insn);
858 while (*p && TOLOWER (*p) == TOLOWER (*str))
859 ++p, ++str;
861 if (* p)
862 return _("unrecognized instruction");
864 #ifndef CGEN_MNEMONIC_OPERANDS
865 if (* str && ! ISSPACE (* str))
866 return _("unrecognized instruction");
867 #endif
869 CGEN_INIT_PARSE (cd);
870 cgen_init_parse_operand (cd);
871 #ifdef CGEN_MNEMONIC_OPERANDS
872 past_opcode_p = 0;
873 #endif
875 /* We don't check for (*str != '\0') here because we want to parse
876 any trailing fake arguments in the syntax string. */
877 syn = CGEN_SYNTAX_STRING (syntax);
879 /* Mnemonics come first for now, ensure valid string. */
880 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
881 abort ();
883 ++syn;
885 while (* syn != 0)
887 /* Non operand chars must match exactly. */
888 if (CGEN_SYNTAX_CHAR_P (* syn))
890 /* FIXME: While we allow for non-GAS callers above, we assume the
891 first char after the mnemonic part is a space. */
892 /* FIXME: We also take inappropriate advantage of the fact that
893 GAS's input scrubber will remove extraneous blanks. */
894 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
896 #ifdef CGEN_MNEMONIC_OPERANDS
897 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
898 past_opcode_p = 1;
899 #endif
900 ++ syn;
901 ++ str;
903 else if (*str)
905 /* Syntax char didn't match. Can't be this insn. */
906 static char msg [80];
908 /* xgettext:c-format */
909 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
910 CGEN_SYNTAX_CHAR(*syn), *str);
911 return msg;
913 else
915 /* Ran out of input. */
916 static char msg [80];
918 /* xgettext:c-format */
919 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
920 CGEN_SYNTAX_CHAR(*syn));
921 return msg;
923 continue;
926 /* We have an operand of some sort. */
927 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
928 &str, fields);
929 if (errmsg)
930 return errmsg;
932 /* Done with this operand, continue with next one. */
933 ++ syn;
936 /* If we're at the end of the syntax string, we're done. */
937 if (* syn == 0)
939 /* FIXME: For the moment we assume a valid `str' can only contain
940 blanks now. IE: We needn't try again with a longer version of
941 the insn and it is assumed that longer versions of insns appear
942 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
943 while (ISSPACE (* str))
944 ++ str;
946 if (* str != '\0')
947 return _("junk at end of line"); /* FIXME: would like to include `str' */
949 return NULL;
952 /* We couldn't parse it. */
953 return _("unrecognized instruction");
956 /* Main entry point.
957 This routine is called for each instruction to be assembled.
958 STR points to the insn to be assembled.
959 We assume all necessary tables have been initialized.
960 The assembled instruction, less any fixups, is stored in BUF.
961 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
962 still needs to be converted to target byte order, otherwise BUF is an array
963 of bytes in target byte order.
964 The result is a pointer to the insn's entry in the opcode table,
965 or NULL if an error occured (an error message will have already been
966 printed).
968 Note that when processing (non-alias) macro-insns,
969 this function recurses.
971 ??? It's possible to make this cpu-independent.
972 One would have to deal with a few minor things.
973 At this point in time doing so would be more of a curiosity than useful
974 [for example this file isn't _that_ big], but keeping the possibility in
975 mind helps keep the design clean. */
977 const CGEN_INSN *
978 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
979 const char *str,
980 CGEN_FIELDS *fields,
981 CGEN_INSN_BYTES_PTR buf,
982 char **errmsg)
984 const char *start;
985 CGEN_INSN_LIST *ilist;
986 const char *parse_errmsg = NULL;
987 const char *insert_errmsg = NULL;
988 int recognized_mnemonic = 0;
990 /* Skip leading white space. */
991 while (ISSPACE (* str))
992 ++ str;
994 /* The instructions are stored in hashed lists.
995 Get the first in the list. */
996 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
998 /* Keep looking until we find a match. */
999 start = str;
1000 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1002 const CGEN_INSN *insn = ilist->insn;
1003 recognized_mnemonic = 1;
1005 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1006 /* Not usually needed as unsupported opcodes
1007 shouldn't be in the hash lists. */
1008 /* Is this insn supported by the selected cpu? */
1009 if (! frv_cgen_insn_supported (cd, insn))
1010 continue;
1011 #endif
1012 /* If the RELAXED attribute is set, this is an insn that shouldn't be
1013 chosen immediately. Instead, it is used during assembler/linker
1014 relaxation if possible. */
1015 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1016 continue;
1018 str = start;
1020 /* Skip this insn if str doesn't look right lexically. */
1021 if (CGEN_INSN_RX (insn) != NULL &&
1022 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1023 continue;
1025 /* Allow parse/insert handlers to obtain length of insn. */
1026 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1028 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1029 if (parse_errmsg != NULL)
1030 continue;
1032 /* ??? 0 is passed for `pc'. */
1033 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1034 (bfd_vma) 0);
1035 if (insert_errmsg != NULL)
1036 continue;
1038 /* It is up to the caller to actually output the insn and any
1039 queued relocs. */
1040 return insn;
1044 static char errbuf[150];
1045 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1046 const char *tmp_errmsg;
1048 /* If requesting verbose error messages, use insert_errmsg.
1049 Failing that, use parse_errmsg. */
1050 tmp_errmsg = (insert_errmsg ? insert_errmsg :
1051 parse_errmsg ? parse_errmsg :
1052 recognized_mnemonic ?
1053 _("unrecognized form of instruction") :
1054 _("unrecognized instruction"));
1056 if (strlen (start) > 50)
1057 /* xgettext:c-format */
1058 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1059 else
1060 /* xgettext:c-format */
1061 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1062 #else
1063 if (strlen (start) > 50)
1064 /* xgettext:c-format */
1065 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1066 else
1067 /* xgettext:c-format */
1068 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1069 #endif
1071 *errmsg = errbuf;
1072 return NULL;
1076 #if 0 /* This calls back to GAS which we can't do without care. */
1078 /* Record each member of OPVALS in the assembler's symbol table.
1079 This lets GAS parse registers for us.
1080 ??? Interesting idea but not currently used. */
1082 /* Record each member of OPVALS in the assembler's symbol table.
1083 FIXME: Not currently used. */
1085 void
1086 frv_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
1088 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1089 const CGEN_KEYWORD_ENTRY * ke;
1091 while ((ke = cgen_keyword_search_next (& search)) != NULL)
1093 #if 0 /* Unnecessary, should be done in the search routine. */
1094 if (! frv_cgen_opval_supported (ke))
1095 continue;
1096 #endif
1097 cgen_asm_record_register (cd, ke->name, ke->value);
1101 #endif /* 0 */