1 /* Assembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3 
4    THIS FILE IS MACHINE GENERATED WITH CGEN.
5    - the resultant file is machine generated, cgen-asm.in isn't
6 
7    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005
8    Free Software Foundation, Inc.
9 
10    This file is part of the GNU Binutils and GDB, the GNU debugger.
11 
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2, or (at your option)
15    any later version.
16 
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software Foundation, Inc.,
24    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25 
26 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
27    Keep that in mind.  */
28 
29 #include "sysdep.h"
30 #include <stdio.h>
31 #include "ansidecl.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "frv-desc.h"
35 #include "frv-opc.h"
36 #include "opintl.h"
37 #include "xregex.h"
38 #include "libiberty.h"
39 #include "safe-ctype.h"
40 
41 #undef  min
42 #define min(a,b) ((a) < (b) ? (a) : (b))
43 #undef  max
44 #define max(a,b) ((a) > (b) ? (a) : (b))
45 
46 static const char * parse_insn_normal
47   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
48 
49 /* -- assembler routines inserted here.  */
50 
51 /* -- asm.c */
52 inline static const char *
parse_symbolic_address(CGEN_CPU_DESC cd,const char ** strp,int opindex,int opinfo,enum cgen_parse_operand_result * resultp,bfd_vma * valuep)53 parse_symbolic_address (CGEN_CPU_DESC cd,
54 			const char **strp,
55 			int opindex,
56 			int opinfo,
57 			enum cgen_parse_operand_result *resultp,
58 			bfd_vma *valuep)
59 {
60   enum cgen_parse_operand_result result_type;
61   const char *errmsg = (* cd->parse_operand_fn)
62     (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
63      &result_type, valuep);
64 
65   if (errmsg == NULL
66       && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
67     return "symbolic expression required";
68 
69   if (resultp)
70     *resultp = result_type;
71 
72   return errmsg;
73 }
74 
75 static const char *
parse_ldd_annotation(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)76 parse_ldd_annotation (CGEN_CPU_DESC cd,
77 		      const char **strp,
78 		      int opindex,
79 		      unsigned long *valuep)
80 {
81   const char *errmsg;
82   enum cgen_parse_operand_result result_type;
83   bfd_vma value;
84 
85   if (**strp == '#' || **strp == '%')
86     {
87       if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
88 	{
89 	  *strp += 9;
90 	  errmsg = parse_symbolic_address (cd, strp, opindex,
91 					   BFD_RELOC_FRV_TLSDESC_RELAX,
92 					   &result_type, &value);
93 	  if (**strp != ')')
94 	    return "missing ')'";
95 	  if (valuep)
96 	    *valuep = value;
97 	  ++*strp;
98 	  if (errmsg)
99 	    return errmsg;
100 	}
101     }
102 
103   while (**strp == ' ' || **strp == '\t')
104     ++*strp;
105 
106   if (**strp != '@')
107     return "missing `@'";
108 
109   ++*strp;
110 
111   return NULL;
112 }
113 
114 static const char *
parse_call_annotation(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)115 parse_call_annotation (CGEN_CPU_DESC cd,
116 		       const char **strp,
117 		       int opindex,
118 		       unsigned long *valuep)
119 {
120   const char *errmsg;
121   enum cgen_parse_operand_result result_type;
122   bfd_vma value;
123 
124   if (**strp == '#' || **strp == '%')
125     {
126       if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
127 	{
128 	  *strp += 11;
129 	  errmsg = parse_symbolic_address (cd, strp, opindex,
130 					   BFD_RELOC_FRV_GETTLSOFF_RELAX,
131 					   &result_type, &value);
132 	  if (**strp != ')')
133 	    return "missing ')'";
134 	  if (valuep)
135 	    *valuep = value;
136 	  ++*strp;
137 	  if (errmsg)
138 	    return errmsg;
139 	}
140     }
141 
142   while (**strp == ' ' || **strp == '\t')
143     ++*strp;
144 
145   if (**strp != '@')
146     return "missing `@'";
147 
148   ++*strp;
149 
150   return NULL;
151 }
152 
153 static const char *
parse_ld_annotation(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)154 parse_ld_annotation (CGEN_CPU_DESC cd,
155 		     const char **strp,
156 		     int opindex,
157 		     unsigned long *valuep)
158 {
159   const char *errmsg;
160   enum cgen_parse_operand_result result_type;
161   bfd_vma value;
162 
163   if (**strp == '#' || **strp == '%')
164     {
165       if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
166 	{
167 	  *strp += 8;
168 	  errmsg = parse_symbolic_address (cd, strp, opindex,
169 					   BFD_RELOC_FRV_TLSOFF_RELAX,
170 					   &result_type, &value);
171 	  if (**strp != ')')
172 	    return "missing ')'";
173 	  if (valuep)
174 	    *valuep = value;
175 	  ++*strp;
176 	  if (errmsg)
177 	    return errmsg;
178 	}
179     }
180 
181   while (**strp == ' ' || **strp == '\t')
182     ++*strp;
183 
184   if (**strp != '@')
185     return "missing `@'";
186 
187   ++*strp;
188 
189   return NULL;
190 }
191 
192 static const char *
parse_ulo16(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)193 parse_ulo16 (CGEN_CPU_DESC cd,
194 	     const char **strp,
195 	     int opindex,
196 	     unsigned long *valuep)
197 {
198   const char *errmsg;
199   enum cgen_parse_operand_result result_type;
200   bfd_vma value;
201 
202   if (**strp == '#' || **strp == '%')
203     {
204       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
205 	{
206 	  *strp += 4;
207 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
208 				       & result_type, & value);
209 	  if (**strp != ')')
210 	    return "missing `)'";
211 	  ++*strp;
212 	  if (errmsg == NULL
213 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
214 	    value &= 0xffff;
215 	  *valuep = value;
216 	  return errmsg;
217 	}
218       if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
219 	{
220 	  *strp += 9;
221 	  errmsg = parse_symbolic_address (cd, strp, opindex,
222 					   BFD_RELOC_FRV_GPRELLO,
223 					   & result_type, & value);
224 	  if (**strp != ')')
225 	    return "missing ')'";
226 	  ++*strp;
227 	  *valuep = value;
228 	  return errmsg;
229 	}
230       else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
231 	{
232 	  *strp += 7;
233 	  errmsg = parse_symbolic_address (cd, strp, opindex,
234 					   BFD_RELOC_FRV_GOTLO,
235 					   & result_type, & value);
236 	  if (**strp != ')')
237 	    return "missing ')'";
238 	  ++*strp;
239 	  *valuep = value;
240 	  return errmsg;
241 	}
242       else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
243 	{
244 	  *strp += 15;
245 	  errmsg = parse_symbolic_address (cd, strp, opindex,
246 					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
247 					   & result_type, & value);
248 	  if (**strp != ')')
249 	    return "missing ')'";
250 	  ++*strp;
251 	  *valuep = value;
252 	  return errmsg;
253 	}
254       else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
255 	{
256 	  *strp += 10;
257 	  errmsg = parse_symbolic_address (cd, strp, opindex,
258 					   BFD_RELOC_FRV_GOTOFFLO,
259 					   & result_type, & value);
260 	  if (**strp != ')')
261 	    return "missing ')'";
262 	  ++*strp;
263 	  *valuep = value;
264 	  return errmsg;
265 	}
266       else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
267 	{
268 	  *strp += 18;
269 	  errmsg = parse_symbolic_address (cd, strp, opindex,
270 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
271 					   & result_type, & value);
272 	  if (**strp != ')')
273 	    return "missing ')'";
274 	  ++*strp;
275 	  *valuep = value;
276 	  return errmsg;
277 	}
278       else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
279 	{
280 	  *strp += 14;
281 	  errmsg = parse_symbolic_address (cd, strp, opindex,
282 					   BFD_RELOC_FRV_GOTTLSDESCLO,
283 					   & result_type, & value);
284 	  if (**strp != ')')
285 	    return "missing ')'";
286 	  ++*strp;
287 	  *valuep = value;
288 	  return errmsg;
289 	}
290       else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
291 	{
292 	  *strp += 11;
293 	  errmsg = parse_symbolic_address (cd, strp, opindex,
294 					   BFD_RELOC_FRV_TLSMOFFLO,
295 					   & result_type, & value);
296 	  if (**strp != ')')
297 	    return "missing ')'";
298 	  ++*strp;
299 	  *valuep = value;
300 	  return errmsg;
301 	}
302       else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
303 	{
304 	  *strp += 13;
305 	  errmsg = parse_symbolic_address (cd, strp, opindex,
306 					   BFD_RELOC_FRV_GOTTLSOFFLO,
307 					   & result_type, & value);
308 	  if (**strp != ')')
309 	    return "missing ')'";
310 	  ++*strp;
311 	  *valuep = value;
312 	  return errmsg;
313 	}
314     }
315   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
316 }
317 
318 static const char *
parse_uslo16(CGEN_CPU_DESC cd,const char ** strp,int opindex,signed long * valuep)319 parse_uslo16 (CGEN_CPU_DESC cd,
320 	      const char **strp,
321 	      int opindex,
322 	      signed long *valuep)
323 {
324   const char *errmsg;
325   enum cgen_parse_operand_result result_type;
326   bfd_vma value;
327 
328   if (**strp == '#' || **strp == '%')
329     {
330       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
331 	{
332 	  *strp += 4;
333 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
334 				       & result_type, & value);
335 	  if (**strp != ')')
336 	    return "missing `)'";
337 	  ++*strp;
338 	  if (errmsg == NULL
339 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
340 	    value &= 0xffff;
341 	  *valuep = value;
342 	  return errmsg;
343 	}
344       else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
345 	{
346 	  *strp += 9;
347 	  errmsg = parse_symbolic_address (cd, strp, opindex,
348 					   BFD_RELOC_FRV_GPRELLO,
349 					   & result_type, & value);
350 	  if (**strp != ')')
351 	    return "missing ')'";
352 	  ++*strp;
353 	  *valuep = value;
354 	  return errmsg;
355 	}
356       else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
357 	{
358 	  *strp += 7;
359 	  errmsg = parse_symbolic_address (cd, strp, opindex,
360 					   BFD_RELOC_FRV_GOTLO,
361 					   & result_type, & value);
362 	  if (**strp != ')')
363 	    return "missing ')'";
364 	  ++*strp;
365 	  *valuep = value;
366 	  return errmsg;
367 	}
368       else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
369 	{
370 	  *strp += 15;
371 	  errmsg = parse_symbolic_address (cd, strp, opindex,
372 					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
373 					   & result_type, & value);
374 	  if (**strp != ')')
375 	    return "missing ')'";
376 	  ++*strp;
377 	  *valuep = value;
378 	  return errmsg;
379 	}
380       else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
381 	{
382 	  *strp += 10;
383 	  errmsg = parse_symbolic_address (cd, strp, opindex,
384 					   BFD_RELOC_FRV_GOTOFFLO,
385 					   & result_type, & value);
386 	  if (**strp != ')')
387 	    return "missing ')'";
388 	  ++*strp;
389 	  *valuep = value;
390 	  return errmsg;
391 	}
392       else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
393 	{
394 	  *strp += 18;
395 	  errmsg = parse_symbolic_address (cd, strp, opindex,
396 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
397 					   & result_type, & value);
398 	  if (**strp != ')')
399 	    return "missing ')'";
400 	  ++*strp;
401 	  *valuep = value;
402 	  return errmsg;
403 	}
404       else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
405 	{
406 	  *strp += 14;
407 	  errmsg = parse_symbolic_address (cd, strp, opindex,
408 					   BFD_RELOC_FRV_GOTTLSDESCLO,
409 					   & result_type, & value);
410 	  if (**strp != ')')
411 	    return "missing ')'";
412 	  ++*strp;
413 	  *valuep = value;
414 	  return errmsg;
415 	}
416       else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
417 	{
418 	  *strp += 11;
419 	  errmsg = parse_symbolic_address (cd, strp, opindex,
420 					   BFD_RELOC_FRV_TLSMOFFLO,
421 					   & result_type, & value);
422 	  if (**strp != ')')
423 	    return "missing ')'";
424 	  ++*strp;
425 	  *valuep = value;
426 	  return errmsg;
427 	}
428       else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
429 	{
430 	  *strp += 13;
431 	  errmsg = parse_symbolic_address (cd, strp, opindex,
432 					   BFD_RELOC_FRV_GOTTLSOFFLO,
433 					   & result_type, & value);
434 	  if (**strp != ')')
435 	    return "missing ')'";
436 	  ++*strp;
437 	  *valuep = value;
438 	  return errmsg;
439 	}
440     }
441   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
442 }
443 
444 static const char *
parse_uhi16(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)445 parse_uhi16 (CGEN_CPU_DESC cd,
446 	     const char **strp,
447 	     int opindex,
448 	     unsigned long *valuep)
449 {
450   const char *errmsg;
451   enum cgen_parse_operand_result result_type;
452   bfd_vma value;
453 
454   if (**strp == '#' || **strp == '%')
455     {
456       if (strncasecmp (*strp + 1, "hi(", 3) == 0)
457 	{
458 	  *strp += 4;
459 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
460 				       & result_type, & value);
461 	  if (**strp != ')')
462 	    return "missing `)'";
463 	  ++*strp;
464 	  if (errmsg == NULL
465 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
466 	    {
467 	      /* If bfd_vma is wider than 32 bits, but we have a sign-
468 		 or zero-extension, truncate it.  */
469 	      if (value >= - ((bfd_vma)1 << 31)
470 		  || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
471 		value &= (((bfd_vma)1 << 16) << 16) - 1;
472 	      value >>= 16;
473 	    }
474 	  *valuep = value;
475 	  return errmsg;
476 	}
477       else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
478 	{
479 	  *strp += 9;
480 	  errmsg = parse_symbolic_address (cd, strp, opindex,
481 					   BFD_RELOC_FRV_GPRELHI,
482 					   & result_type, & value);
483 	  if (**strp != ')')
484 	    return "missing ')'";
485 	  ++*strp;
486 	  *valuep = value;
487 	  return errmsg;
488 	}
489       else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
490 	{
491 	  *strp += 7;
492 	  errmsg = parse_symbolic_address (cd, strp, opindex,
493 					   BFD_RELOC_FRV_GOTHI,
494 					   & result_type, & value);
495 	  if (**strp != ')')
496 	    return "missing ')'";
497 	  ++*strp;
498 	  *valuep = value;
499 	  return errmsg;
500 	}
501       else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
502 	{
503 	  *strp += 15;
504 	  errmsg = parse_symbolic_address (cd, strp, opindex,
505 					   BFD_RELOC_FRV_FUNCDESC_GOTHI,
506 					   & result_type, & value);
507 	  if (**strp != ')')
508 	    return "missing ')'";
509 	  ++*strp;
510 	  *valuep = value;
511 	  return errmsg;
512 	}
513       else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
514 	{
515 	  *strp += 10;
516 	  errmsg = parse_symbolic_address (cd, strp, opindex,
517 					   BFD_RELOC_FRV_GOTOFFHI,
518 					   & result_type, & value);
519 	  if (**strp != ')')
520 	    return "missing ')'";
521 	  ++*strp;
522 	  *valuep = value;
523 	  return errmsg;
524 	}
525       else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
526 	{
527 	  *strp += 18;
528 	  errmsg = parse_symbolic_address (cd, strp, opindex,
529 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
530 					   & result_type, & value);
531 	  if (**strp != ')')
532 	    return "missing ')'";
533 	  ++*strp;
534 	  *valuep = value;
535 	  return errmsg;
536 	}
537       else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
538 	{
539 	  *strp += 14;
540 	  errmsg = parse_symbolic_address (cd, strp, opindex,
541 					   BFD_RELOC_FRV_GOTTLSDESCHI,
542 					   &result_type, &value);
543 	  if (**strp != ')')
544 	    return "missing ')'";
545 	  ++*strp;
546 	  *valuep = value;
547 	  return errmsg;
548 	}
549       else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
550 	{
551 	  *strp += 11;
552 	  errmsg = parse_symbolic_address (cd, strp, opindex,
553 					   BFD_RELOC_FRV_TLSMOFFHI,
554 					   & result_type, & value);
555 	  if (**strp != ')')
556 	    return "missing ')'";
557 	  ++*strp;
558 	  *valuep = value;
559 	  return errmsg;
560 	}
561       else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
562 	{
563 	  *strp += 13;
564 	  errmsg = parse_symbolic_address (cd, strp, opindex,
565 					   BFD_RELOC_FRV_GOTTLSOFFHI,
566 					   & result_type, & value);
567 	  if (**strp != ')')
568 	    return "missing ')'";
569 	  ++*strp;
570 	  *valuep = value;
571 	  return errmsg;
572 	}
573     }
574   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
575 }
576 
577 static long
parse_register_number(const char ** strp)578 parse_register_number (const char **strp)
579 {
580   int regno;
581 
582   if (**strp < '0' || **strp > '9')
583     return -1; /* error */
584 
585   regno = **strp - '0';
586   for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
587     regno = regno * 10 + (**strp - '0');
588 
589   return regno;
590 }
591 
592 static const char *
parse_spr(CGEN_CPU_DESC cd,const char ** strp,CGEN_KEYWORD * table,long * valuep)593 parse_spr (CGEN_CPU_DESC cd,
594 	   const char **strp,
595 	   CGEN_KEYWORD * table,
596 	   long *valuep)
597 {
598   const char *save_strp;
599   long regno;
600 
601   /* Check for spr index notation.  */
602   if (strncasecmp (*strp, "spr[", 4) == 0)
603     {
604       *strp += 4;
605       regno = parse_register_number (strp);
606       if (**strp != ']')
607         return _("missing `]'");
608       ++*strp;
609       if (! spr_valid (regno))
610 	return _("Special purpose register number is out of range");
611       *valuep = regno;
612       return NULL;
613     }
614 
615   save_strp = *strp;
616   regno = parse_register_number (strp);
617   if (regno != -1)
618     {
619       if (! spr_valid (regno))
620 	return _("Special purpose register number is out of range");
621       *valuep = regno;
622       return NULL;
623     }
624 
625   *strp = save_strp;
626   return cgen_parse_keyword (cd, strp, table, valuep);
627 }
628 
629 static const char *
parse_d12(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)630 parse_d12 (CGEN_CPU_DESC cd,
631 	   const char **strp,
632 	   int opindex,
633 	   long *valuep)
634 {
635   const char *errmsg;
636   enum cgen_parse_operand_result result_type;
637   bfd_vma value;
638 
639   /* Check for small data reference.  */
640   if (**strp == '#' || **strp == '%')
641     {
642       if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
643         {
644           *strp += 9;
645           errmsg = parse_symbolic_address (cd, strp, opindex,
646 					   BFD_RELOC_FRV_GPREL12,
647 					   & result_type, & value);
648           if (**strp != ')')
649             return "missing `)'";
650           ++*strp;
651           *valuep = value;
652           return errmsg;
653         }
654       else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
655 	{
656 	  *strp += 7;
657 	  errmsg = parse_symbolic_address (cd, strp, opindex,
658 					   BFD_RELOC_FRV_GOT12,
659 					   & result_type, & value);
660 	  if (**strp != ')')
661 	    return "missing ')'";
662 	  ++*strp;
663 	  *valuep = value;
664 	  return errmsg;
665 	}
666       else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
667 	{
668 	  *strp += 15;
669 	  errmsg = parse_symbolic_address (cd, strp, opindex,
670 					   BFD_RELOC_FRV_FUNCDESC_GOT12,
671 					   & result_type, & value);
672 	  if (**strp != ')')
673 	    return "missing ')'";
674 	  ++*strp;
675 	  *valuep = value;
676 	  return errmsg;
677 	}
678       else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
679 	{
680 	  *strp += 10;
681 	  errmsg = parse_symbolic_address (cd, strp, opindex,
682 					   BFD_RELOC_FRV_GOTOFF12,
683 					   & result_type, & value);
684 	  if (**strp != ')')
685 	    return "missing ')'";
686 	  ++*strp;
687 	  *valuep = value;
688 	  return errmsg;
689 	}
690       else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
691 	{
692 	  *strp += 18;
693 	  errmsg = parse_symbolic_address (cd, strp, opindex,
694 					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
695 					   & result_type, & value);
696 	  if (**strp != ')')
697 	    return "missing ')'";
698 	  ++*strp;
699 	  *valuep = value;
700 	  return errmsg;
701 	}
702       else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
703 	{
704 	  *strp += 14;
705 	  errmsg = parse_symbolic_address (cd, strp, opindex,
706 					   BFD_RELOC_FRV_GOTTLSDESC12,
707 					   & result_type, & value);
708 	  if (**strp != ')')
709 	    return "missing ')'";
710 	  ++*strp;
711 	  *valuep = value;
712 	  return errmsg;
713 	}
714       else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
715 	{
716 	  *strp += 11;
717 	  errmsg = parse_symbolic_address (cd, strp, opindex,
718 					   BFD_RELOC_FRV_TLSMOFF12,
719 					   & result_type, & value);
720 	  if (**strp != ')')
721 	    return "missing ')'";
722 	  ++*strp;
723 	  *valuep = value;
724 	  return errmsg;
725 	}
726       else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
727 	{
728 	  *strp += 13;
729 	  errmsg = parse_symbolic_address (cd, strp, opindex,
730 					   BFD_RELOC_FRV_GOTTLSOFF12,
731 					   & result_type, & value);
732 	  if (**strp != ')')
733 	    return "missing ')'";
734 	  ++*strp;
735 	  *valuep = value;
736 	  return errmsg;
737 	}
738     }
739   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
740 }
741 
742 static const char *
parse_s12(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)743 parse_s12 (CGEN_CPU_DESC cd,
744 	   const char **strp,
745 	   int opindex,
746 	   long *valuep)
747 {
748   const char *errmsg;
749   enum cgen_parse_operand_result result_type;
750   bfd_vma value;
751 
752   /* Check for small data reference.  */
753   if (**strp == '#' || **strp == '%')
754     {
755       if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
756 	{
757 	  *strp += 9;
758 	  errmsg = parse_symbolic_address (cd, strp, opindex,
759 					   BFD_RELOC_FRV_GPREL12,
760 					   & result_type, & value);
761 	  if (**strp != ')')
762 	    return "missing `)'";
763 	  ++*strp;
764 	  *valuep = value;
765 	  return errmsg;
766 	}
767       else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
768 	{
769 	  *strp += 7;
770 	  errmsg = parse_symbolic_address (cd, strp, opindex,
771 					   BFD_RELOC_FRV_GOT12,
772 					   & result_type, & value);
773 	  if (**strp != ')')
774 	    return "missing ')'";
775 	  ++*strp;
776 	  *valuep = value;
777 	  return errmsg;
778 	}
779       else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
780 	{
781 	  *strp += 15;
782 	  errmsg = parse_symbolic_address (cd, strp, opindex,
783 					   BFD_RELOC_FRV_FUNCDESC_GOT12,
784 					   & result_type, & value);
785 	  if (**strp != ')')
786 	    return "missing ')'";
787 	  ++*strp;
788 	  *valuep = value;
789 	  return errmsg;
790 	}
791       else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
792 	{
793 	  *strp += 10;
794 	  errmsg = parse_symbolic_address (cd, strp, opindex,
795 					   BFD_RELOC_FRV_GOTOFF12,
796 					   & result_type, & value);
797 	  if (**strp != ')')
798 	    return "missing ')'";
799 	  ++*strp;
800 	  *valuep = value;
801 	  return errmsg;
802 	}
803       else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
804 	{
805 	  *strp += 18;
806 	  errmsg = parse_symbolic_address (cd, strp, opindex,
807 					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
808 					   & result_type, & value);
809 	  if (**strp != ')')
810 	    return "missing ')'";
811 	  ++*strp;
812 	  *valuep = value;
813 	  return errmsg;
814 	}
815       else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
816 	{
817 	  *strp += 14;
818 	  errmsg = parse_symbolic_address (cd, strp, opindex,
819 					   BFD_RELOC_FRV_GOTTLSDESC12,
820 					   & result_type, & value);
821 	  if (**strp != ')')
822 	    return "missing ')'";
823 	  ++*strp;
824 	  *valuep = value;
825 	  return errmsg;
826 	}
827       else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
828 	{
829 	  *strp += 11;
830 	  errmsg = parse_symbolic_address (cd, strp, opindex,
831 					   BFD_RELOC_FRV_TLSMOFF12,
832 					   & result_type, & value);
833 	  if (**strp != ')')
834 	    return "missing ')'";
835 	  ++*strp;
836 	  *valuep = value;
837 	  return errmsg;
838 	}
839       else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
840 	{
841 	  *strp += 13;
842 	  errmsg = parse_symbolic_address (cd, strp, opindex,
843 					   BFD_RELOC_FRV_GOTTLSOFF12,
844 					   & result_type, & value);
845 	  if (**strp != ')')
846 	    return "missing ')'";
847 	  ++*strp;
848 	  *valuep = value;
849 	  return errmsg;
850 	}
851     }
852 
853   if (**strp == '#')
854     ++*strp;
855   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
856 }
857 
858 static const char *
parse_u12(CGEN_CPU_DESC cd,const char ** strp,int opindex,long * valuep)859 parse_u12 (CGEN_CPU_DESC cd,
860 	   const char **strp,
861 	   int opindex,
862 	   long *valuep)
863 {
864   const char *errmsg;
865   enum cgen_parse_operand_result result_type;
866   bfd_vma value;
867 
868   /* Check for small data reference.  */
869   if ((**strp == '#' || **strp == '%')
870       && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
871     {
872       *strp += 9;
873       errmsg = parse_symbolic_address (cd, strp, opindex,
874 				       BFD_RELOC_FRV_GPRELU12,
875 				       & result_type, & value);
876       if (**strp != ')')
877         return "missing `)'";
878       ++*strp;
879       *valuep = value;
880       return errmsg;
881     }
882   else
883     {
884       if (**strp == '#')
885         ++*strp;
886       return cgen_parse_signed_integer (cd, strp, opindex, valuep);
887     }
888 }
889 
890 static const char *
parse_A(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep,unsigned long A)891 parse_A (CGEN_CPU_DESC cd,
892 	 const char **strp,
893 	 int opindex,
894 	 unsigned long *valuep,
895 	 unsigned long A)
896 {
897   const char *errmsg;
898 
899   if (**strp == '#')
900     ++*strp;
901 
902   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
903   if (errmsg)
904     return errmsg;
905 
906   if (*valuep != A)
907     return _("Value of A operand must be 0 or 1");
908 
909   return NULL;
910 }
911 
912 static const char *
parse_A0(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)913 parse_A0 (CGEN_CPU_DESC cd,
914 	  const char **strp,
915 	  int opindex,
916 	  unsigned long *valuep)
917 {
918   return parse_A (cd, strp, opindex, valuep, 0);
919 }
920 
921 static const char *
parse_A1(CGEN_CPU_DESC cd,const char ** strp,int opindex,unsigned long * valuep)922 parse_A1 (CGEN_CPU_DESC cd,
923 	  const char **strp,
924 	  int opindex,
925 	  unsigned long *valuep)
926 {
927   return parse_A (cd, strp, opindex, valuep, 1);
928 }
929 
930 static const char *
parse_even_register(CGEN_CPU_DESC cd,const char ** strP,CGEN_KEYWORD * tableP,long * valueP)931 parse_even_register (CGEN_CPU_DESC  cd,
932 		     const char **  strP,
933 		     CGEN_KEYWORD * tableP,
934 		     long *         valueP)
935 {
936   const char * errmsg;
937   const char * saved_star_strP = * strP;
938 
939   errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
940 
941   if (errmsg == NULL && ((* valueP) & 1))
942     {
943       errmsg = _("register number must be even");
944       * strP = saved_star_strP;
945     }
946 
947   return errmsg;
948 }
949 
950 static const char *
parse_call_label(CGEN_CPU_DESC cd,const char ** strp,int opindex,int opinfo,enum cgen_parse_operand_result * resultp,bfd_vma * valuep)951 parse_call_label (CGEN_CPU_DESC cd,
952 		  const char **strp,
953 		  int opindex,
954 		  int opinfo,
955 		  enum cgen_parse_operand_result *resultp,
956 		  bfd_vma *valuep)
957 {
958   const char *errmsg;
959   bfd_vma value;
960 
961   /* Check for small data reference.  */
962   if (opinfo == 0 && (**strp == '#' || **strp == '%'))
963     {
964       if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
965 	{
966 	  *strp += 11;
967 	  errmsg = parse_symbolic_address (cd, strp, opindex,
968 					   BFD_RELOC_FRV_GETTLSOFF,
969 					   resultp, &value);
970 	  if (**strp != ')')
971 	    return _("missing `)'");
972 	  ++*strp;
973 	  *valuep = value;
974 	  return errmsg;
975 	}
976     }
977 
978   return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
979 }
980 
981 /* -- */
982 
983 const char * frv_cgen_parse_operand
984   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
985 
986 /* Main entry point for operand parsing.
987 
988    This function is basically just a big switch statement.  Earlier versions
989    used tables to look up the function to use, but
990    - if the table contains both assembler and disassembler functions then
991      the disassembler contains much of the assembler and vice-versa,
992    - there's a lot of inlining possibilities as things grow,
993    - using a switch statement avoids the function call overhead.
994 
995    This function could be moved into `parse_insn_normal', but keeping it
996    separate makes clear the interface between `parse_insn_normal' and each of
997    the handlers.  */
998 
999 const char *
frv_cgen_parse_operand(CGEN_CPU_DESC cd,int opindex,const char ** strp,CGEN_FIELDS * fields)1000 frv_cgen_parse_operand (CGEN_CPU_DESC cd,
1001 			   int opindex,
1002 			   const char ** strp,
1003 			   CGEN_FIELDS * fields)
1004 {
1005   const char * errmsg = NULL;
1006   /* Used by scalar operands that still need to be parsed.  */
1007   long junk ATTRIBUTE_UNUSED;
1008 
1009   switch (opindex)
1010     {
1011     case FRV_OPERAND_A0 :
1012       errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
1013       break;
1014     case FRV_OPERAND_A1 :
1015       errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
1016       break;
1017     case FRV_OPERAND_ACC40SI :
1018       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
1019       break;
1020     case FRV_OPERAND_ACC40SK :
1021       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
1022       break;
1023     case FRV_OPERAND_ACC40UI :
1024       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
1025       break;
1026     case FRV_OPERAND_ACC40UK :
1027       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
1028       break;
1029     case FRV_OPERAND_ACCGI :
1030       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
1031       break;
1032     case FRV_OPERAND_ACCGK :
1033       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
1034       break;
1035     case FRV_OPERAND_CCI :
1036       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
1037       break;
1038     case FRV_OPERAND_CPRDOUBLEK :
1039       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1040       break;
1041     case FRV_OPERAND_CPRI :
1042       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
1043       break;
1044     case FRV_OPERAND_CPRJ :
1045       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
1046       break;
1047     case FRV_OPERAND_CPRK :
1048       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1049       break;
1050     case FRV_OPERAND_CRI :
1051       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
1052       break;
1053     case FRV_OPERAND_CRJ :
1054       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
1055       break;
1056     case FRV_OPERAND_CRJ_FLOAT :
1057       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
1058       break;
1059     case FRV_OPERAND_CRJ_INT :
1060       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
1061       break;
1062     case FRV_OPERAND_CRK :
1063       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
1064       break;
1065     case FRV_OPERAND_FCCI_1 :
1066       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
1067       break;
1068     case FRV_OPERAND_FCCI_2 :
1069       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
1070       break;
1071     case FRV_OPERAND_FCCI_3 :
1072       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
1073       break;
1074     case FRV_OPERAND_FCCK :
1075       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
1076       break;
1077     case FRV_OPERAND_FRDOUBLEI :
1078       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1079       break;
1080     case FRV_OPERAND_FRDOUBLEJ :
1081       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1082       break;
1083     case FRV_OPERAND_FRDOUBLEK :
1084       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1085       break;
1086     case FRV_OPERAND_FRI :
1087       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1088       break;
1089     case FRV_OPERAND_FRINTI :
1090       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1091       break;
1092     case FRV_OPERAND_FRINTIEVEN :
1093       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1094       break;
1095     case FRV_OPERAND_FRINTJ :
1096       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1097       break;
1098     case FRV_OPERAND_FRINTJEVEN :
1099       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1100       break;
1101     case FRV_OPERAND_FRINTK :
1102       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1103       break;
1104     case FRV_OPERAND_FRINTKEVEN :
1105       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1106       break;
1107     case FRV_OPERAND_FRJ :
1108       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1109       break;
1110     case FRV_OPERAND_FRK :
1111       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1112       break;
1113     case FRV_OPERAND_FRKHI :
1114       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1115       break;
1116     case FRV_OPERAND_FRKLO :
1117       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1118       break;
1119     case FRV_OPERAND_GRDOUBLEK :
1120       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1121       break;
1122     case FRV_OPERAND_GRI :
1123       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
1124       break;
1125     case FRV_OPERAND_GRJ :
1126       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
1127       break;
1128     case FRV_OPERAND_GRK :
1129       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1130       break;
1131     case FRV_OPERAND_GRKHI :
1132       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1133       break;
1134     case FRV_OPERAND_GRKLO :
1135       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1136       break;
1137     case FRV_OPERAND_ICCI_1 :
1138       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
1139       break;
1140     case FRV_OPERAND_ICCI_2 :
1141       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
1142       break;
1143     case FRV_OPERAND_ICCI_3 :
1144       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
1145       break;
1146     case FRV_OPERAND_LI :
1147       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
1148       break;
1149     case FRV_OPERAND_LRAD :
1150       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
1151       break;
1152     case FRV_OPERAND_LRAE :
1153       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
1154       break;
1155     case FRV_OPERAND_LRAS :
1156       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
1157       break;
1158     case FRV_OPERAND_TLBPRL :
1159       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
1160       break;
1161     case FRV_OPERAND_TLBPROPX :
1162       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
1163       break;
1164     case FRV_OPERAND_AE :
1165       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
1166       break;
1167     case FRV_OPERAND_CALLANN :
1168       errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
1169       break;
1170     case FRV_OPERAND_CCOND :
1171       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
1172       break;
1173     case FRV_OPERAND_COND :
1174       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
1175       break;
1176     case FRV_OPERAND_D12 :
1177       errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
1178       break;
1179     case FRV_OPERAND_DEBUG :
1180       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
1181       break;
1182     case FRV_OPERAND_EIR :
1183       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
1184       break;
1185     case FRV_OPERAND_HINT :
1186       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
1187       break;
1188     case FRV_OPERAND_HINT_NOT_TAKEN :
1189       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
1190       break;
1191     case FRV_OPERAND_HINT_TAKEN :
1192       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
1193       break;
1194     case FRV_OPERAND_LABEL16 :
1195       {
1196         bfd_vma value = 0;
1197         errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
1198         fields->f_label16 = value;
1199       }
1200       break;
1201     case FRV_OPERAND_LABEL24 :
1202       {
1203         bfd_vma value = 0;
1204         errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
1205         fields->f_label24 = value;
1206       }
1207       break;
1208     case FRV_OPERAND_LDANN :
1209       errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
1210       break;
1211     case FRV_OPERAND_LDDANN :
1212       errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
1213       break;
1214     case FRV_OPERAND_LOCK :
1215       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
1216       break;
1217     case FRV_OPERAND_PACK :
1218       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
1219       break;
1220     case FRV_OPERAND_S10 :
1221       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
1222       break;
1223     case FRV_OPERAND_S12 :
1224       errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
1225       break;
1226     case FRV_OPERAND_S16 :
1227       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
1228       break;
1229     case FRV_OPERAND_S5 :
1230       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
1231       break;
1232     case FRV_OPERAND_S6 :
1233       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
1234       break;
1235     case FRV_OPERAND_S6_1 :
1236       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
1237       break;
1238     case FRV_OPERAND_SLO16 :
1239       errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
1240       break;
1241     case FRV_OPERAND_SPR :
1242       errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
1243       break;
1244     case FRV_OPERAND_U12 :
1245       errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
1246       break;
1247     case FRV_OPERAND_U16 :
1248       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
1249       break;
1250     case FRV_OPERAND_U6 :
1251       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
1252       break;
1253     case FRV_OPERAND_UHI16 :
1254       errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
1255       break;
1256     case FRV_OPERAND_ULO16 :
1257       errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
1258       break;
1259 
1260     default :
1261       /* xgettext:c-format */
1262       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1263       abort ();
1264   }
1265 
1266   return errmsg;
1267 }
1268 
1269 cgen_parse_fn * const frv_cgen_parse_handlers[] =
1270 {
1271   parse_insn_normal,
1272 };
1273 
1274 void
frv_cgen_init_asm(CGEN_CPU_DESC cd)1275 frv_cgen_init_asm (CGEN_CPU_DESC cd)
1276 {
1277   frv_cgen_init_opcode_table (cd);
1278   frv_cgen_init_ibld_table (cd);
1279   cd->parse_handlers = & frv_cgen_parse_handlers[0];
1280   cd->parse_operand = frv_cgen_parse_operand;
1281 }
1282 
1283 
1284 
1285 /* Regex construction routine.
1286 
1287    This translates an opcode syntax string into a regex string,
1288    by replacing any non-character syntax element (such as an
1289    opcode) with the pattern '.*'
1290 
1291    It then compiles the regex and stores it in the opcode, for
1292    later use by frv_cgen_assemble_insn
1293 
1294    Returns NULL for success, an error message for failure.  */
1295 
1296 char *
frv_cgen_build_insn_regex(CGEN_INSN * insn)1297 frv_cgen_build_insn_regex (CGEN_INSN *insn)
1298 {
1299   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1300   const char *mnem = CGEN_INSN_MNEMONIC (insn);
1301   char rxbuf[CGEN_MAX_RX_ELEMENTS];
1302   char *rx = rxbuf;
1303   const CGEN_SYNTAX_CHAR_TYPE *syn;
1304   int reg_err;
1305 
1306   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1307 
1308   /* Mnemonics come first in the syntax string.  */
1309   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1310     return _("missing mnemonic in syntax string");
1311   ++syn;
1312 
1313   /* Generate a case sensitive regular expression that emulates case
1314      insensitive matching in the "C" locale.  We cannot generate a case
1315      insensitive regular expression because in Turkish locales, 'i' and 'I'
1316      are not equal modulo case conversion.  */
1317 
1318   /* Copy the literal mnemonic out of the insn.  */
1319   for (; *mnem; mnem++)
1320     {
1321       char c = *mnem;
1322 
1323       if (ISALPHA (c))
1324 	{
1325 	  *rx++ = '[';
1326 	  *rx++ = TOLOWER (c);
1327 	  *rx++ = TOUPPER (c);
1328 	  *rx++ = ']';
1329 	}
1330       else
1331 	*rx++ = c;
1332     }
1333 
1334   /* Copy any remaining literals from the syntax string into the rx.  */
1335   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1336     {
1337       if (CGEN_SYNTAX_CHAR_P (* syn))
1338 	{
1339 	  char c = CGEN_SYNTAX_CHAR (* syn);
1340 
1341 	  switch (c)
1342 	    {
1343 	      /* Escape any regex metacharacters in the syntax.  */
1344 	    case '.': case '[': case '\\':
1345 	    case '*': case '^': case '$':
1346 
1347 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1348 	    case '?': case '{': case '}':
1349 	    case '(': case ')': case '*':
1350 	    case '|': case '+': case ']':
1351 #endif
1352 	      *rx++ = '\\';
1353 	      *rx++ = c;
1354 	      break;
1355 
1356 	    default:
1357 	      if (ISALPHA (c))
1358 		{
1359 		  *rx++ = '[';
1360 		  *rx++ = TOLOWER (c);
1361 		  *rx++ = TOUPPER (c);
1362 		  *rx++ = ']';
1363 		}
1364 	      else
1365 		*rx++ = c;
1366 	      break;
1367 	    }
1368 	}
1369       else
1370 	{
1371 	  /* Replace non-syntax fields with globs.  */
1372 	  *rx++ = '.';
1373 	  *rx++ = '*';
1374 	}
1375     }
1376 
1377   /* Trailing whitespace ok.  */
1378   * rx++ = '[';
1379   * rx++ = ' ';
1380   * rx++ = '\t';
1381   * rx++ = ']';
1382   * rx++ = '*';
1383 
1384   /* But anchor it after that.  */
1385   * rx++ = '$';
1386   * rx = '\0';
1387 
1388   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1389   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1390 
1391   if (reg_err == 0)
1392     return NULL;
1393   else
1394     {
1395       static char msg[80];
1396 
1397       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1398       regfree ((regex_t *) CGEN_INSN_RX (insn));
1399       free (CGEN_INSN_RX (insn));
1400       (CGEN_INSN_RX (insn)) = NULL;
1401       return msg;
1402     }
1403 }
1404 
1405 
1406 /* Default insn parser.
1407 
1408    The syntax string is scanned and operands are parsed and stored in FIELDS.
1409    Relocs are queued as we go via other callbacks.
1410 
1411    ??? Note that this is currently an all-or-nothing parser.  If we fail to
1412    parse the instruction, we return 0 and the caller will start over from
1413    the beginning.  Backtracking will be necessary in parsing subexpressions,
1414    but that can be handled there.  Not handling backtracking here may get
1415    expensive in the case of the m68k.  Deal with later.
1416 
1417    Returns NULL for success, an error message for failure.  */
1418 
1419 static const char *
parse_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,const char ** strp,CGEN_FIELDS * fields)1420 parse_insn_normal (CGEN_CPU_DESC cd,
1421 		   const CGEN_INSN *insn,
1422 		   const char **strp,
1423 		   CGEN_FIELDS *fields)
1424 {
1425   /* ??? Runtime added insns not handled yet.  */
1426   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1427   const char *str = *strp;
1428   const char *errmsg;
1429   const char *p;
1430   const CGEN_SYNTAX_CHAR_TYPE * syn;
1431 #ifdef CGEN_MNEMONIC_OPERANDS
1432   /* FIXME: wip */
1433   int past_opcode_p;
1434 #endif
1435 
1436   /* For now we assume the mnemonic is first (there are no leading operands).
1437      We can parse it without needing to set up operand parsing.
1438      GAS's input scrubber will ensure mnemonics are lowercase, but we may
1439      not be called from GAS.  */
1440   p = CGEN_INSN_MNEMONIC (insn);
1441   while (*p && TOLOWER (*p) == TOLOWER (*str))
1442     ++p, ++str;
1443 
1444   if (* p)
1445     return _("unrecognized instruction");
1446 
1447 #ifndef CGEN_MNEMONIC_OPERANDS
1448   if (* str && ! ISSPACE (* str))
1449     return _("unrecognized instruction");
1450 #endif
1451 
1452   CGEN_INIT_PARSE (cd);
1453   cgen_init_parse_operand (cd);
1454 #ifdef CGEN_MNEMONIC_OPERANDS
1455   past_opcode_p = 0;
1456 #endif
1457 
1458   /* We don't check for (*str != '\0') here because we want to parse
1459      any trailing fake arguments in the syntax string.  */
1460   syn = CGEN_SYNTAX_STRING (syntax);
1461 
1462   /* Mnemonics come first for now, ensure valid string.  */
1463   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1464     abort ();
1465 
1466   ++syn;
1467 
1468   while (* syn != 0)
1469     {
1470       /* Non operand chars must match exactly.  */
1471       if (CGEN_SYNTAX_CHAR_P (* syn))
1472 	{
1473 	  /* FIXME: While we allow for non-GAS callers above, we assume the
1474 	     first char after the mnemonic part is a space.  */
1475 	  /* FIXME: We also take inappropriate advantage of the fact that
1476 	     GAS's input scrubber will remove extraneous blanks.  */
1477 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1478 	    {
1479 #ifdef CGEN_MNEMONIC_OPERANDS
1480 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1481 		past_opcode_p = 1;
1482 #endif
1483 	      ++ syn;
1484 	      ++ str;
1485 	    }
1486 	  else if (*str)
1487 	    {
1488 	      /* Syntax char didn't match.  Can't be this insn.  */
1489 	      static char msg [80];
1490 
1491 	      /* xgettext:c-format */
1492 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1493 		       CGEN_SYNTAX_CHAR(*syn), *str);
1494 	      return msg;
1495 	    }
1496 	  else
1497 	    {
1498 	      /* Ran out of input.  */
1499 	      static char msg [80];
1500 
1501 	      /* xgettext:c-format */
1502 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1503 		       CGEN_SYNTAX_CHAR(*syn));
1504 	      return msg;
1505 	    }
1506 	  continue;
1507 	}
1508 
1509       /* We have an operand of some sort.  */
1510       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1511 					  &str, fields);
1512       if (errmsg)
1513 	return errmsg;
1514 
1515       /* Done with this operand, continue with next one.  */
1516       ++ syn;
1517     }
1518 
1519   /* If we're at the end of the syntax string, we're done.  */
1520   if (* syn == 0)
1521     {
1522       /* FIXME: For the moment we assume a valid `str' can only contain
1523 	 blanks now.  IE: We needn't try again with a longer version of
1524 	 the insn and it is assumed that longer versions of insns appear
1525 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1526       while (ISSPACE (* str))
1527 	++ str;
1528 
1529       if (* str != '\0')
1530 	return _("junk at end of line"); /* FIXME: would like to include `str' */
1531 
1532       return NULL;
1533     }
1534 
1535   /* We couldn't parse it.  */
1536   return _("unrecognized instruction");
1537 }
1538 
1539 /* Main entry point.
1540    This routine is called for each instruction to be assembled.
1541    STR points to the insn to be assembled.
1542    We assume all necessary tables have been initialized.
1543    The assembled instruction, less any fixups, is stored in BUF.
1544    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1545    still needs to be converted to target byte order, otherwise BUF is an array
1546    of bytes in target byte order.
1547    The result is a pointer to the insn's entry in the opcode table,
1548    or NULL if an error occured (an error message will have already been
1549    printed).
1550 
1551    Note that when processing (non-alias) macro-insns,
1552    this function recurses.
1553 
1554    ??? It's possible to make this cpu-independent.
1555    One would have to deal with a few minor things.
1556    At this point in time doing so would be more of a curiosity than useful
1557    [for example this file isn't _that_ big], but keeping the possibility in
1558    mind helps keep the design clean.  */
1559 
1560 const CGEN_INSN *
frv_cgen_assemble_insn(CGEN_CPU_DESC cd,const char * str,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buf,char ** errmsg)1561 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
1562 			   const char *str,
1563 			   CGEN_FIELDS *fields,
1564 			   CGEN_INSN_BYTES_PTR buf,
1565 			   char **errmsg)
1566 {
1567   const char *start;
1568   CGEN_INSN_LIST *ilist;
1569   const char *parse_errmsg = NULL;
1570   const char *insert_errmsg = NULL;
1571   int recognized_mnemonic = 0;
1572 
1573   /* Skip leading white space.  */
1574   while (ISSPACE (* str))
1575     ++ str;
1576 
1577   /* The instructions are stored in hashed lists.
1578      Get the first in the list.  */
1579   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1580 
1581   /* Keep looking until we find a match.  */
1582   start = str;
1583   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1584     {
1585       const CGEN_INSN *insn = ilist->insn;
1586       recognized_mnemonic = 1;
1587 
1588 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1589       /* Not usually needed as unsupported opcodes
1590 	 shouldn't be in the hash lists.  */
1591       /* Is this insn supported by the selected cpu?  */
1592       if (! frv_cgen_insn_supported (cd, insn))
1593 	continue;
1594 #endif
1595       /* If the RELAXED attribute is set, this is an insn that shouldn't be
1596 	 chosen immediately.  Instead, it is used during assembler/linker
1597 	 relaxation if possible.  */
1598       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1599 	continue;
1600 
1601       str = start;
1602 
1603       /* Skip this insn if str doesn't look right lexically.  */
1604       if (CGEN_INSN_RX (insn) != NULL &&
1605 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1606 	continue;
1607 
1608       /* Allow parse/insert handlers to obtain length of insn.  */
1609       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1610 
1611       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1612       if (parse_errmsg != NULL)
1613 	continue;
1614 
1615       /* ??? 0 is passed for `pc'.  */
1616       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1617 						 (bfd_vma) 0);
1618       if (insert_errmsg != NULL)
1619         continue;
1620 
1621       /* It is up to the caller to actually output the insn and any
1622          queued relocs.  */
1623       return insn;
1624     }
1625 
1626   {
1627     static char errbuf[150];
1628 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1629     const char *tmp_errmsg;
1630 
1631     /* If requesting verbose error messages, use insert_errmsg.
1632        Failing that, use parse_errmsg.  */
1633     tmp_errmsg = (insert_errmsg ? insert_errmsg :
1634 		  parse_errmsg ? parse_errmsg :
1635 		  recognized_mnemonic ?
1636 		  _("unrecognized form of instruction") :
1637 		  _("unrecognized instruction"));
1638 
1639     if (strlen (start) > 50)
1640       /* xgettext:c-format */
1641       sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1642     else
1643       /* xgettext:c-format */
1644       sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1645 #else
1646     if (strlen (start) > 50)
1647       /* xgettext:c-format */
1648       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1649     else
1650       /* xgettext:c-format */
1651       sprintf (errbuf, _("bad instruction `%.50s'"), start);
1652 #endif
1653 
1654     *errmsg = errbuf;
1655     return NULL;
1656   }
1657 }
1658