1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2    Copyright (C) 2013-2016 Free Software Foundation, Inc.
3    Contributed by Imagination Technologies Ltd.
4 
5    This file is part of GAS, the GNU Assembler.
6 
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11 
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 #include "as.h"
23 #include "subsegs.h"
24 #include "symcat.h"
25 #include "safe-ctype.h"
26 #include "hashtab.h"
27 #include "libbfd.h"
28 
29 #include <stdio.h>
30 
31 #include "opcode/metag.h"
32 
33 const char comment_chars[]        = "!";
34 const char line_comment_chars[]   = "!#";
35 const char line_separator_chars[] = ";";
36 const char FLT_CHARS[]            = "rRsSfFdDxXpP";
37 const char EXP_CHARS[]            = "eE";
38 const char metag_symbol_chars[]   = "[";
39 
40 static char register_chars[256];
41 static char mnemonic_chars[256];
42 
43 #define is_register_char(x) (register_chars[(unsigned char) x])
44 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
45 #define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
46 #define is_space_char(x) ((x) == ' ')
47 
48 #define FPU_PREFIX_CHAR 'f'
49 #define DSP_PREFIX_CHAR 'd'
50 
51 /* Instruction mnemonics that need disambiguating with respect to prefixes.  */
52 #define FFB_INSN        "ffb"
53 #define DCACHE_INSN     "dcache"
54 #define DEFR_INSN       "defr"
55 
56 #define FPU_DOUBLE_CHAR 'd'
57 #define FPU_PAIR_CHAR   'l'
58 
59 #define DSP_DUAL_CHAR	'l'
60 
61 #define END_OF_INSN     '\0'
62 
63 /* Maximum length of a mnemonic including all suffixes.  */
64 #define MAX_MNEMONIC_LEN 16
65 /* Maximum length of a register name.  */
66 #define MAX_REG_LEN      17
67 
68 /* Addressing modes must be enclosed with square brackets.  */
69 #define ADDR_BEGIN_CHAR '['
70 #define ADDR_END_CHAR   ']'
71 /* Immediates must be prefixed with a hash.  */
72 #define IMM_CHAR        '#'
73 
74 #define COMMA           ','
75 #define PLUS            '+'
76 #define MINUS           '-'
77 
78 /* Short units are those that can be encoded with 2 bits.  */
79 #define SHORT_UNITS     "D0, D1, A0 or A1"
80 
81 static unsigned int mcpu_opt = CoreMeta12;
82 static unsigned int mfpu_opt = 0;
83 static unsigned int mdsp_opt = 0;
84 
85 const char * md_shortopts = "m:";
86 
87 struct option md_longopts[] =
88 {
89   {NULL, no_argument, NULL, 0}
90 };
91 size_t md_longopts_size = sizeof (md_longopts);
92 
93 /* Parser hash tables.  */
94 static htab_t mnemonic_htab;
95 static htab_t reg_htab;
96 static htab_t dsp_reg_htab;
97 static htab_t dsp_tmpl_reg_htab[2];
98 static htab_t scond_htab;
99 
100 #define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
101 symbolS * GOT_symbol;
102 
103 enum fpu_insn_width {
104   FPU_WIDTH_SINGLE,
105   FPU_WIDTH_DOUBLE,
106   FPU_WIDTH_PAIR,
107 };
108 
109 #define FPU_ACTION_ABS_CHAR   'a'
110 #define FPU_ACTION_INV_CHAR   'i'
111 #define FPU_ACTION_QUIET_CHAR 'q'
112 #define FPU_ACTION_ZERO_CHAR  'z'
113 
114 #define FPU_ACTION_ABS        0x1
115 #define FPU_ACTION_INV        0x2
116 #define FPU_ACTION_QUIET      0x4
117 #define FPU_ACTION_ZERO       0x8
118 
119 enum dsp_insn_width {
120   DSP_WIDTH_SINGLE,
121   DSP_WIDTH_DUAL,
122 };
123 
124 #define DSP_ACTION_QR64_CHAR     'q'
125 #define DSP_ACTION_UMUL_CHAR     'u'
126 #define DSP_ACTION_ROUND_CHAR    'r'
127 #define DSP_ACTION_CLAMP9_CHAR   'g'
128 #define DSP_ACTION_CLAMP8_CHAR   'b'
129 #define DSP_ACTION_MOD_CHAR      'm'
130 #define DSP_ACTION_ACC_ZERO_CHAR 'z'
131 #define DSP_ACTION_ACC_ADD_CHAR  'p'
132 #define DSP_ACTION_ACC_SUB_CHAR  'n'
133 #define DSP_ACTION_OV_CHAR       'o'
134 
135 #define DSP_ACTION_QR64          0x001
136 #define DSP_ACTION_UMUL          0x002
137 #define DSP_ACTION_ROUND         0x004
138 #define DSP_ACTION_CLAMP9        0x008
139 #define DSP_ACTION_CLAMP8        0x010
140 #define DSP_ACTION_MOD           0x020
141 #define DSP_ACTION_ACC_ZERO      0x040
142 #define DSP_ACTION_ACC_ADD       0x080
143 #define DSP_ACTION_ACC_SUB       0x100
144 #define DSP_ACTION_OV            0x200
145 
146 #define DSP_DAOPPAME_8_CHAR    'b'
147 #define DSP_DAOPPAME_16_CHAR   'w'
148 #define DSP_DAOPPAME_TEMP_CHAR 't'
149 #define DSP_DAOPPAME_HIGH_CHAR 'h'
150 
151 #define DSP_DAOPPAME_8         0x1
152 #define DSP_DAOPPAME_16        0x2
153 #define DSP_DAOPPAME_TEMP      0x4
154 #define DSP_DAOPPAME_HIGH      0x8
155 
156 /* Structure holding information about a parsed instruction.  */
157 typedef struct {
158   /* Instruction type.  */
159   enum insn_type type;
160   /* Split condition code. */
161   enum scond_code scond;
162 
163   /* Instruction bits.  */
164   unsigned int bits;
165   /* Size of the instruction in bytes.  */
166   size_t len;
167 
168   /* FPU instruction encoding.  */
169   enum fpu_insn_width fpu_width;
170   unsigned int fpu_action_flags;
171 
172   /* DSP instruction encoding. */
173   enum dsp_insn_width dsp_width;
174   unsigned int dsp_action_flags;
175   unsigned int dsp_daoppame_flags;
176 
177   /* Reloc encoding information, maximum of one reloc per insn.  */
178   enum bfd_reloc_code_real reloc_type;
179   int reloc_pcrel;
180   expressionS reloc_exp;
181   unsigned int reloc_size;
182 } metag_insn;
183 
184 /* Structure holding information about a parsed addressing mode.  */
185 typedef struct {
186   const metag_reg *base_reg;
187   const metag_reg *offset_reg;
188 
189   expressionS exp;
190 
191   enum bfd_reloc_code_real reloc_type;
192 
193   /* Whether we have an immediate or not.  */
194   unsigned short immediate:1;
195   /* Whether or not the base register is updated.  */
196   unsigned short update:1;
197   /* Whether the operation uses the address pre or post increment.  */
198   unsigned short post_increment:1;
199   /* Whether the immediate should be negated.  */
200   unsigned short negate:1;
201 } metag_addr;
202 
203 /* Linked list of possible parsers for this instruction.  */
204 typedef struct _insn_templates {
205   const insn_template *template;
206   struct _insn_templates *next;
207 } insn_templates;
208 
209 /* Parse an instruction that takes no operands.  */
210 static const char *
parse_none(const char * line,metag_insn * insn,const insn_template * template)211 parse_none (const char *line, metag_insn *insn,
212 	    const insn_template *template)
213 {
214   insn->bits = template->meta_opcode;
215   insn->len = 4;
216   return line;
217 }
218 
219 /* Return the next non-whitespace character in LINE or NULL.  */
220 static const char *
skip_whitespace(const char * line)221 skip_whitespace (const char *line)
222 {
223   const char *l = line;
224 
225   if (is_whitespace_char (*l))
226     {
227       l++;
228     }
229 
230   return l;
231 }
232 
233 /* Return the next non-space character in LINE or NULL.  */
234 static const char *
skip_space(const char * line)235 skip_space (const char *line)
236 {
237   const char *l = line;
238 
239   if (is_space_char (*l))
240     {
241       l++;
242     }
243 
244   return l;
245 }
246 
247 /* Return the character after the current one in LINE if the current
248    character is a comma, otherwise NULL.  */
249 static const char *
skip_comma(const char * line)250 skip_comma (const char *line)
251 {
252   const char *l = line;
253 
254   if (l == NULL || *l != COMMA)
255     return NULL;
256 
257   l++;
258 
259   return l;
260 }
261 
262 /* Return the metag_reg struct corresponding to NAME or NULL if no such
263    register exists.  */
264 static const metag_reg *
parse_gp_reg(const char * name)265 parse_gp_reg (const char *name)
266 {
267   const metag_reg *reg;
268   metag_reg entry;
269 
270   entry.name = name;
271 
272   reg = (const metag_reg *) htab_find (reg_htab, &entry);
273 
274   return reg;
275 }
276 
277 /* Parse a list of up to COUNT GP registers from LINE, returning the
278    registers parsed in REGS and the number parsed in REGS_READ. Return
279    a pointer to the next character or NULL.  */
280 static const char *
parse_gp_regs_list(const char * line,const metag_reg ** regs,size_t count,size_t * regs_read)281 parse_gp_regs_list (const char *line, const metag_reg **regs, size_t count,
282 		    size_t *regs_read)
283 {
284   const char *l = line;
285   char reg_buf[MAX_REG_LEN];
286   int seen_regs = 0;
287   size_t i;
288 
289   for (i = 0; i < count; i++)
290     {
291       size_t len = 0;
292       const char *next;
293 
294       next = l;
295 
296       if (i > 0)
297 	{
298 	  l = skip_comma (l);
299 	  if (l == NULL)
300 	    {
301 	      *regs_read = seen_regs;
302 	      return next;
303 	    }
304 	}
305 
306       while (is_register_char (*l))
307 	{
308 	  reg_buf[len] = *l;
309 	  l++;
310 	  len++;
311 	  if (!(len < MAX_REG_LEN))
312 	    return NULL;
313 	}
314 
315       reg_buf[len] = '\0';
316 
317       if (len)
318 	{
319 	  const metag_reg *reg = parse_gp_reg (reg_buf);
320 
321 	  if (!reg)
322 	    {
323 	      *regs_read = seen_regs;
324 	      return next;
325 	    }
326 	  else
327 	    {
328 	      regs[i] = reg;
329 	      seen_regs++;
330 	    }
331 	}
332       else
333 	{
334 	  *regs_read = seen_regs;
335 	  return next;
336 	}
337     }
338 
339   *regs_read = seen_regs;
340   return l;
341 }
342 
343 /* Parse a list of exactly COUNT GP registers from LINE, returning the
344    registers parsed in REGS. Return a pointer to the next character or NULL.  */
345 static const char *
parse_gp_regs(const char * line,const metag_reg ** regs,size_t count)346 parse_gp_regs (const char *line, const metag_reg **regs, size_t count)
347 {
348   const char *l = line;
349   size_t regs_read = 0;
350 
351   l = parse_gp_regs_list (l, regs, count, &regs_read);
352 
353   if (regs_read != count)
354     return NULL;
355   else
356     return l;
357 }
358 
359 /* Parse a list of exactly COUNT FPU registers from LINE, returning the
360    registers parsed in REGS. Return a pointer to the next character or NULL.  */
361 static const char *
parse_fpu_regs(const char * line,const metag_reg ** regs,size_t count)362 parse_fpu_regs (const char *line, const metag_reg **regs, size_t count)
363 {
364   const char *l = line;
365   size_t regs_read = 0;
366 
367   l = parse_gp_regs_list (l, regs, count, &regs_read);
368 
369   if (regs_read != count)
370     return NULL;
371   else
372     {
373       size_t i;
374       for (i = 0; i < count; i++)
375 	{
376 	  if (regs[i]->unit != UNIT_FX)
377 	    return NULL;
378 	}
379       return l;
380     }
381 }
382 
383 /* Return TRUE if REG1 and REG2 are in paired units.  */
384 static bfd_boolean
is_unit_pair(const metag_reg * reg1,const metag_reg * reg2)385 is_unit_pair (const metag_reg *reg1, const metag_reg *reg2)
386 {
387   if ((reg1->unit == UNIT_A0 &&
388        (reg2->unit == UNIT_A1)) ||
389       (reg1->unit == UNIT_A1 &&
390        (reg2->unit == UNIT_A0)) ||
391       (reg1->unit == UNIT_D0 &&
392        (reg2->unit == UNIT_D1)) ||
393       (reg1->unit == UNIT_D1 &&
394        (reg2->unit == UNIT_D0)))
395     return TRUE;
396 
397   return FALSE;
398 }
399 
400 /* Return TRUE if REG1 and REG2 form a register pair.  */
401 static bfd_boolean
is_reg_pair(const metag_reg * reg1,const metag_reg * reg2)402 is_reg_pair (const metag_reg *reg1, const metag_reg *reg2)
403 {
404   if (reg1->unit == UNIT_FX &&
405       reg2->unit == UNIT_FX &&
406       reg2->no == reg1->no + 1)
407     return TRUE;
408 
409   if (reg1->no != reg2->no)
410     return FALSE;
411 
412   return is_unit_pair (reg1, reg2);
413 }
414 
415 /* Parse a pair of GP registers from LINE, returning the registers parsed
416    in REGS. Return a pointer to the next character or NULL.  */
417 static const char *
parse_pair_gp_regs(const char * line,const metag_reg ** regs)418 parse_pair_gp_regs (const char *line, const metag_reg **regs)
419 {
420   const char *l = line;
421 
422   l = parse_gp_regs (line, regs, 2);
423 
424   if (l == NULL)
425     {
426       l = parse_gp_regs (line, regs, 1);
427 
428       if (l == NULL)
429 	return NULL;
430 
431       if (regs[0]->unit == UNIT_RD)
432 	return l;
433       else
434 	return NULL;
435     }
436 
437   if (is_reg_pair (regs[0], regs[1]))
438     return l;
439 
440   return NULL;
441 }
442 
443 /* Parse a unit-to-unit MOV instruction.  */
444 static const char *
parse_mov_u2u(const char * line,metag_insn * insn,const insn_template * template)445 parse_mov_u2u (const char *line, metag_insn *insn,
446 	       const insn_template *template)
447 {
448   const metag_reg *regs[2];
449 
450   line = parse_gp_regs (line, regs, 2);
451 
452   if (line == NULL)
453     return NULL;
454 
455   if (!mfpu_opt && (regs[0]->unit == UNIT_FX || regs[1]->unit == UNIT_FX))
456     {
457       as_bad (_("no floating point unit specified"));
458       return NULL;
459     }
460 
461   insn->bits = (template->meta_opcode |
462 		(regs[1]->no << 19) |
463 		(regs[0]->no << 14) |
464 		(regs[1]->unit << 10) |
465 		(regs[0]->unit << 5));
466   insn->len = 4;
467   return line;
468 }
469 
470 /* Parse a MOV to port instruction.  */
471 static const char *
parse_mov_port(const char * line,metag_insn * insn,const insn_template * template)472 parse_mov_port (const char *line, metag_insn *insn,
473 		const insn_template *template)
474 {
475   const char *l = line;
476   unsigned int is_movl = MINOR_OPCODE (template->meta_opcode) == MOVL_MINOR;
477   const metag_reg *dest_regs[2];
478   const metag_reg *port_regs[1];
479 
480   if (is_movl)
481     l = parse_gp_regs (l, dest_regs, 2);
482   else
483     l = parse_gp_regs (l, dest_regs, 1);
484 
485   if (l == NULL)
486     return NULL;
487 
488   if (template->insn_type == INSN_FPU && dest_regs[0]->unit != UNIT_FX)
489     return NULL;
490 
491   l = skip_comma (l);
492 
493   if (l == NULL ||
494       *l == END_OF_INSN)
495     return NULL;
496 
497   l = parse_gp_regs (l, port_regs, 1);
498 
499   if (l == NULL)
500     return NULL;
501 
502   if (port_regs[0]->unit != UNIT_RD ||
503       port_regs[0]->no != 0)
504     return NULL;
505 
506   if (is_movl)
507     {
508       if (!is_unit_pair (dest_regs[0], dest_regs[1]))
509 	return NULL;
510 
511       insn->bits = (template->meta_opcode |
512 		    (dest_regs[0]->no << 14) |
513 		    (dest_regs[1]->no << 9) |
514 		    ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 5));
515     }
516   else
517     insn->bits = (template->meta_opcode |
518 		  (dest_regs[0]->no << 14) |
519 		  (dest_regs[0]->unit << 5));
520 
521   insn->len = 4;
522   return l;
523 }
524 
525 /* Parse a MOVL to TTREC instruction.  */
526 static const char *
parse_movl_ttrec(const char * line,metag_insn * insn,const insn_template * template)527 parse_movl_ttrec (const char *line, metag_insn *insn,
528 		  const insn_template *template)
529 {
530   const char *l = line;
531   const metag_reg *src_regs[2];
532   const metag_reg *dest_regs[1];
533 
534   l = parse_gp_regs (l, dest_regs, 1);
535 
536   if (l == NULL)
537     return NULL;
538 
539   if (dest_regs[0]->unit != UNIT_TT ||
540       dest_regs[0]->no != 3)
541     return NULL;
542 
543   l = skip_comma (l);
544 
545   if (l == NULL ||
546       *l == END_OF_INSN)
547     return NULL;
548 
549   l = parse_gp_regs (l, src_regs, 2);
550 
551   if (l == NULL)
552     return NULL;
553 
554   if (!is_unit_pair (src_regs[0], src_regs[1]))
555     return NULL;
556 
557   insn->bits = (template->meta_opcode |
558 		(src_regs[0]->no << 19) |
559 		(src_regs[1]->no << 14) |
560 		((src_regs[0]->unit & SHORT_UNIT_MASK) << 7));
561 
562   insn->len = 4;
563   return l;
564 }
565 
566 /* Parse an incrementing or decrementing addressing mode.  */
567 static const char *
parse_addr_incr_op(const char * line,metag_addr * addr)568 parse_addr_incr_op (const char *line, metag_addr *addr)
569 {
570   const char *l = line;
571   const char *ll;
572 
573   ll = l + 1;
574 
575   if (*l == PLUS &&
576       *ll == PLUS)
577     {
578       addr->update = 1;
579       ll++;
580       return ll;
581     }
582   else if (*l == MINUS &&
583 	   *ll == MINUS)
584     {
585       addr->update = 1;
586       addr->negate = 1;
587       ll++;
588       return ll;
589     }
590   return NULL;
591 }
592 
593 /* Parse an pre-incrementing or pre-decrementing addressing mode.  */
594 static const char *
parse_addr_pre_incr_op(const char * line,metag_addr * addr)595 parse_addr_pre_incr_op (const char *line, metag_addr *addr)
596 {
597   return parse_addr_incr_op (line, addr);
598 }
599 
600 /* Parse an post-incrementing or post-decrementing addressing mode.  */
601 static const char *
parse_addr_post_incr_op(const char * line,metag_addr * addr)602 parse_addr_post_incr_op (const char *line, metag_addr *addr)
603 {
604   const char *l;
605 
606   l = parse_addr_incr_op (line, addr);
607 
608   if (l == NULL)
609     return NULL;
610 
611   addr->post_increment = 1;
612 
613   return l;
614 }
615 
616 /* Parse an infix addressing mode.  */
617 static const char *
parse_addr_op(const char * line,metag_addr * addr)618 parse_addr_op (const char *line, metag_addr *addr)
619 {
620   const char *l = line;
621   const char *ll;
622 
623   ll = l + 1;
624 
625   if (*l == PLUS)
626     {
627       if (*ll == PLUS)
628 	{
629 	  addr->update = 1;
630 	  ll++;
631 	  return ll;
632 	}
633       l++;
634       return l;
635     }
636   return NULL;
637 }
638 
639 /* Parse the immediate portion of an addrssing mode.  */
640 static const char *
parse_imm_addr(const char * line,metag_addr * addr)641 parse_imm_addr (const char *line, metag_addr *addr)
642 {
643   const char *l = line;
644   char *save_input_line_pointer;
645   expressionS *exp = &addr->exp;
646 
647   /* Skip #.  */
648   if (*l == '#')
649     l++;
650   else
651     return NULL;
652 
653   save_input_line_pointer = input_line_pointer;
654   input_line_pointer = (char *) l;
655 
656   expression (exp);
657 
658   l = input_line_pointer;
659   input_line_pointer = save_input_line_pointer;
660 
661   if (exp->X_op == O_absent || exp->X_op == O_big)
662     {
663       return NULL;
664     }
665   else if (exp->X_op == O_constant)
666     {
667       return l;
668     }
669   else
670     {
671       if (exp->X_op == O_PIC_reloc &&
672 	  exp->X_md == BFD_RELOC_METAG_GETSET_GOT)
673 	{
674 	  exp->X_op = O_symbol;
675 	  addr->reloc_type = BFD_RELOC_METAG_GETSET_GOT;
676 	}
677       else if (exp->X_op == O_PIC_reloc &&
678 	       exp->X_md == BFD_RELOC_METAG_TLS_IE)
679 	{
680 	  exp->X_op = O_symbol;
681 	  addr->reloc_type = BFD_RELOC_METAG_TLS_IE;
682 	}
683       else if (exp->X_op == O_PIC_reloc &&
684 	  exp->X_md == BFD_RELOC_METAG_GOTOFF)
685 	{
686 	  exp->X_op = O_symbol;
687 	  addr->reloc_type = BFD_RELOC_METAG_GETSET_GOTOFF;
688 	}
689       else
690 	addr->reloc_type = BFD_RELOC_METAG_GETSETOFF;
691       return l;
692     }
693 }
694 
695 /* Parse the offset portion of an addressing mode (register or immediate).  */
696 static const char *
parse_addr_offset(const char * line,metag_addr * addr,int size)697 parse_addr_offset (const char *line, metag_addr *addr, int size)
698 {
699   const char *l = line;
700   const metag_reg *regs[1];
701 
702   if (*l == IMM_CHAR)
703     {
704       /* ++ is a valid operator in our addressing but not in an expr. Make
705 	 sure that the expression parser never sees it.  */
706       char *ppp = strstr(l, "++");
707       char ppch = '+';
708 
709       if (ppp)
710 	*ppp = '\0';
711 
712       l = parse_imm_addr (l, addr);
713 
714       if (ppp)
715 	*ppp = ppch;
716 
717       if (l == NULL)
718 	return NULL;
719 
720       if (addr->exp.X_add_number % size)
721 	{
722 	  as_bad (_("offset must be a multiple of %d"), size);
723 	  return NULL;
724 	}
725 
726       addr->immediate = 1;
727       return l;
728     }
729   else
730     {
731       l = parse_gp_regs (l, regs, 1);
732 
733       if (l == NULL)
734 	return NULL;
735 
736       if (regs[0]->unit != addr->base_reg->unit)
737 	{
738 	  as_bad (_("offset and base must be from the same unit"));
739 	  return NULL;
740 	}
741 
742       addr->offset_reg = regs[0];
743       return l;
744     }
745 }
746 
747 /* Parse an addressing mode.  */
748 static const char *
parse_addr(const char * line,metag_addr * addr,unsigned int size)749 parse_addr (const char *line, metag_addr *addr, unsigned int size)
750 {
751   const char *l = line;
752   const char *ll;
753   const metag_reg *regs[1];
754 
755   /* Skip opening square bracket.  */
756   l++;
757 
758   ll = parse_addr_pre_incr_op (l, addr);
759 
760   if (ll != NULL)
761     l = ll;
762 
763   l = parse_gp_regs (l, regs, 1);
764 
765   if (l == NULL)
766     return NULL;
767 
768   addr->base_reg = regs[0];
769 
770   if (*l == ADDR_END_CHAR)
771     {
772       addr->exp.X_op = O_constant;
773       addr->exp.X_add_symbol = NULL;
774       addr->exp.X_op_symbol = NULL;
775       if (addr->update == 1)
776 	{
777 	  /* We have a pre increment/decrement.  */
778 	  addr->exp.X_add_number = size;
779 	}
780       else
781 	{
782 	  /* Simple register with no offset (0 immediate).  */
783 	  addr->exp.X_add_number = 0;
784 	}
785       addr->immediate = 1;
786       l++;
787       return l;
788     }
789 
790   /* We already had a pre increment/decrement.  */
791   if (addr->update == 1)
792     return NULL;
793 
794   ll = parse_addr_post_incr_op (l, addr);
795 
796   if (ll && *ll == ADDR_END_CHAR)
797     {
798       if (addr->update == 1)
799 	{
800 	  /* We have a post increment/decrement.  */
801 	  addr->exp.X_op = O_constant;
802 	  addr->exp.X_add_number = size;
803 	  addr->exp.X_add_symbol = NULL;
804 	  addr->exp.X_op_symbol = NULL;
805 	  addr->post_increment = 1;
806 	}
807       addr->immediate = 1;
808       ll++;
809       return ll;
810     }
811 
812   addr->post_increment = 0;
813 
814   l = parse_addr_op (l, addr);
815 
816   if (l == NULL)
817     return NULL;
818 
819   l = parse_addr_offset (l, addr, size);
820 
821   if (l == NULL)
822     return NULL;
823 
824   if (*l == ADDR_END_CHAR)
825     {
826       l++;
827       return l;
828     }
829 
830   /* We already had a pre increment/decrement. */
831   if (addr->update == 1)
832     return NULL;
833 
834   l = parse_addr_post_incr_op (l, addr);
835 
836   if (l == NULL)
837     return NULL;
838 
839   if (*l == ADDR_END_CHAR)
840     {
841       l++;
842       return l;
843     }
844 
845   return NULL;
846 }
847 
848 /* Parse a GET or pipeline MOV instruction.  */
849 static const char *
parse_get(const char * line,const metag_reg ** regs,metag_addr * addr,unsigned int size,bfd_boolean is_mov)850 parse_get (const char *line, const metag_reg **regs, metag_addr *addr,
851 	   unsigned int size, bfd_boolean is_mov)
852 {
853   const char *l = line;
854 
855   if (size == 8)
856     {
857       l = parse_pair_gp_regs (l, regs);
858 
859       if (l == NULL)
860 	  return NULL;
861     }
862   else
863     {
864       l = parse_gp_regs (l, regs, 1);
865 
866       if (l == NULL)
867 	{
868 	  if (!is_mov)
869 	    as_bad (_("invalid destination register"));
870 	  return NULL;
871 	}
872     }
873 
874   l = skip_comma (l);
875 
876   if (l == NULL ||
877       *l == END_OF_INSN)
878     return NULL;
879 
880   l = parse_addr (l, addr, size);
881 
882   if (l == NULL)
883     {
884       if (!is_mov)
885 	as_bad (_("invalid memory operand"));
886       return NULL;
887     }
888 
889   return l;
890 }
891 
892 /* Parse a SET instruction.  */
893 static const char *
parse_set(const char * line,const metag_reg ** regs,metag_addr * addr,unsigned int size)894 parse_set (const char *line, const metag_reg **regs, metag_addr *addr,
895 	   unsigned int size)
896 {
897   const char *l = line;
898 
899   l = parse_addr (l, addr, size);
900 
901   if (l == NULL)
902     {
903 	  as_bad (_("invalid memory operand"));
904 	  return NULL;
905     }
906 
907   l = skip_comma (l);
908 
909   if (l == NULL ||
910       *l == END_OF_INSN)
911     return NULL;
912 
913   if (size == 8)
914     {
915       const char *ll = l;
916 
917       ll = parse_pair_gp_regs (l, regs);
918 
919       if (ll == NULL)
920 	{
921 	  /* Maybe this is an RD register, which is 64 bits wide so needs no
922 	     pair.  */
923 	  l = parse_gp_regs (l, regs, 1);
924 
925 	  if (l == NULL ||
926 	      regs[0]->unit != UNIT_RD)
927 	    {
928 	      return NULL;
929 	    }
930 	}
931       else
932 	l = ll;
933     }
934   else
935     {
936       l = parse_gp_regs (l, regs, 1);
937 
938       if (l == NULL)
939 	{
940 	  as_bad (_("invalid source register"));
941 	  return NULL;
942 	}
943     }
944 
945   return l;
946 }
947 
948 /* Check a signed integer value can be represented in the given number
949    of bits.  */
950 static bfd_boolean
within_signed_range(int value,unsigned int bits)951 within_signed_range (int value, unsigned int bits)
952 {
953   int min_val = -(1 << (bits - 1));
954   int max_val = (1 << (bits - 1)) - 1;
955   return (value <= max_val) && (value >= min_val);
956 }
957 
958 /* Check an unsigned integer value can be represented in the given number
959    of bits.  */
960 static bfd_boolean
within_unsigned_range(unsigned int value,unsigned int bits)961 within_unsigned_range (unsigned int value, unsigned int bits)
962 {
963   return value < (unsigned int)(1 << bits);
964 }
965 
966 /* Return TRUE if UNIT can be expressed using a short code.  */
967 static bfd_boolean
is_short_unit(enum metag_unit unit)968 is_short_unit (enum metag_unit unit)
969 {
970   switch (unit)
971     {
972     case UNIT_A0:
973     case UNIT_A1:
974     case UNIT_D0:
975     case UNIT_D1:
976       return TRUE;
977     default:
978       return FALSE;
979     }
980 }
981 
982 /* Copy reloc data from ADDR to INSN.  */
983 static void
copy_addr_reloc(metag_insn * insn,metag_addr * addr)984 copy_addr_reloc (metag_insn *insn, metag_addr *addr)
985 {
986   memcpy (&insn->reloc_exp, &addr->exp, sizeof(insn->reloc_exp));
987   insn->reloc_type = addr->reloc_type;
988 }
989 
990 /* Parse a GET, SET or pipeline MOV instruction.  */
991 static const char *
parse_get_set(const char * line,metag_insn * insn,const insn_template * template)992 parse_get_set (const char *line, metag_insn *insn,
993 	       const insn_template *template)
994 {
995   const char *l = line;
996   const metag_reg *regs[2];
997   metag_addr addr;
998   unsigned int size = metag_get_set_size_bytes (template->meta_opcode);
999   bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
1000   unsigned int reg_no;
1001 
1002   memset(&addr, 0, sizeof(addr));
1003   addr.reloc_type = BFD_RELOC_UNUSED;
1004 
1005   if (is_get)
1006     {
1007       bfd_boolean is_mov = strncmp (template->name, "MOV", 3) == 0;
1008 
1009       l = parse_get (l, regs, &addr, size, is_mov);
1010 
1011       if (l == NULL)
1012 	return NULL;
1013 
1014       if (!(regs[0]->unit == UNIT_D0 ||
1015 	    regs[0]->unit == UNIT_D1 ||
1016 	    regs[0]->unit == UNIT_A0 ||
1017 	    regs[0]->unit == UNIT_A1 ||
1018 	    (regs[0]->unit == UNIT_RD && is_mov) ||
1019 	    (regs[0]->unit == UNIT_CT && size == 4) ||
1020 	    (regs[0]->unit == UNIT_PC && size == 4) ||
1021 	    (regs[0]->unit == UNIT_TR && size == 4) ||
1022 	    (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1023 	    regs[0]->unit == UNIT_FX))
1024 	{
1025 	  as_bad (_("invalid destination unit"));
1026 	  return NULL;
1027 	}
1028 
1029       if (regs[0]->unit == UNIT_RD)
1030 	{
1031 	  if (regs[0]->no == 0)
1032 	    {
1033 	      as_bad (_("mov cannot use RD port as destination"));
1034 	      return NULL;
1035 	    }
1036 	}
1037 
1038       reg_no = regs[0]->no;
1039     }
1040   else
1041     {
1042       l = parse_set (l, regs, &addr, size);
1043 
1044       if (l == NULL)
1045 	return NULL;
1046 
1047       if (!(regs[0]->unit == UNIT_D0 ||
1048 	    regs[0]->unit == UNIT_D1 ||
1049 	    regs[0]->unit == UNIT_A0 ||
1050 	    regs[0]->unit == UNIT_A1 ||
1051 	    regs[0]->unit == UNIT_RD ||
1052 	    (regs[0]->unit == UNIT_CT && size == 4) ||
1053 	    (regs[0]->unit == UNIT_PC && size == 4) ||
1054 	    (regs[0]->unit == UNIT_TR && size == 4) ||
1055 	    (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1056 	    regs[0]->unit == UNIT_FX))
1057 	{
1058 	  as_bad (_("invalid source unit"));
1059 	  return NULL;
1060 	}
1061 
1062       if (addr.immediate == 0 &&
1063 	  (regs[0]->unit == addr.base_reg->unit ||
1064 	   (size == 8 && is_unit_pair (regs[0], addr.base_reg))))
1065 	{
1066 	  as_bad (_("source and address units must not be shared for this addressing mode"));
1067 	  return NULL;
1068 	}
1069 
1070       if (regs[0]->unit == UNIT_RD)
1071 	{
1072 	  if (regs[0]->no != 0)
1073 	    {
1074 	      as_bad (_("set can only use RD port as source"));
1075 	      return NULL;
1076 	    }
1077 	  reg_no = 16;
1078 	}
1079       else
1080 	reg_no = regs[0]->no;
1081     }
1082 
1083   insn->bits = (template->meta_opcode |
1084 		(reg_no << 19) |
1085 		(regs[0]->unit << 1));
1086 
1087   if (!is_short_unit (addr.base_reg->unit))
1088     {
1089       as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1090       return NULL;
1091     }
1092 
1093   insn->bits |= ((addr.base_reg->no << 14) |
1094 		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1095 
1096   if (addr.immediate)
1097     {
1098       int offset = addr.exp.X_add_number;
1099 
1100       copy_addr_reloc (insn, &addr);
1101 
1102       if (addr.negate)
1103 	offset = -offset;
1104 
1105       offset = offset / (int)size;
1106 
1107       if (!within_signed_range (offset, GET_SET_IMM_BITS))
1108 	{
1109 	  /* We already tried to encode as an extended GET/SET.  */
1110 	  as_bad (_("offset value out of range"));
1111 	  return NULL;
1112 	}
1113 
1114       offset = offset & GET_SET_IMM_MASK;
1115 
1116       insn->bits |= (0x1 << 25);
1117       insn->bits |= (offset << 8);
1118     }
1119   else
1120     {
1121       insn->bits |= (addr.offset_reg->no << 9);
1122     }
1123 
1124   if (addr.update)
1125     insn->bits |= (0x1 << 7);
1126 
1127   if (addr.post_increment)
1128     insn->bits |= 0x1;
1129 
1130   insn->len = 4;
1131   return l;
1132 }
1133 
1134 /* Parse an extended GET or SET instruction.  */
1135 static const char *
parse_get_set_ext(const char * line,metag_insn * insn,const insn_template * template)1136 parse_get_set_ext (const char *line, metag_insn *insn,
1137 		   const insn_template *template)
1138 {
1139   const char *l = line;
1140   const metag_reg *regs[2];
1141   metag_addr addr;
1142   unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
1143   bfd_boolean is_get = MINOR_OPCODE (template->meta_opcode) == GET_EXT_MINOR;
1144   bfd_boolean is_mov = MINOR_OPCODE (template->meta_opcode) == MOV_EXT_MINOR;
1145   unsigned int reg_unit;
1146 
1147   memset(&addr, 0, sizeof(addr));
1148   addr.reloc_type = BFD_RELOC_UNUSED;
1149 
1150   if (is_get || is_mov)
1151     {
1152       l = parse_get (l, regs, &addr, size, is_mov);
1153     }
1154   else
1155     {
1156       l = parse_set (l, regs, &addr, size);
1157     }
1158 
1159   if (l == NULL)
1160     return NULL;
1161 
1162   /* Extended GET/SET does not support incrementing addressing.  */
1163   if (addr.update)
1164     return NULL;
1165 
1166   if (is_mov)
1167     {
1168       if (regs[0]->unit != UNIT_RD)
1169 	{
1170 	  as_bad (_("destination unit must be RD"));
1171 	  return NULL;
1172 	}
1173       reg_unit = 0;
1174     }
1175   else
1176     {
1177       if (!is_short_unit (regs[0]->unit))
1178 	{
1179 	  return NULL;
1180 	}
1181       reg_unit = regs[0]->unit;
1182     }
1183 
1184   insn->bits = (template->meta_opcode |
1185 		(regs[0]->no << 19) |
1186 		((reg_unit & SHORT_UNIT_MASK) << 3));
1187 
1188   if (!is_short_unit (addr.base_reg->unit))
1189     {
1190       as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1191       return NULL;
1192     }
1193 
1194   if (addr.base_reg->no > 1)
1195     {
1196       return NULL;
1197     }
1198 
1199   insn->bits |= ((addr.base_reg->no & EXT_BASE_REG_MASK) |
1200 		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1201 
1202   if (addr.immediate)
1203     {
1204       int offset = addr.exp.X_add_number;
1205 
1206       copy_addr_reloc (insn, &addr);
1207 
1208       if (addr.negate)
1209 	offset = -offset;
1210 
1211       offset = offset / (int)size;
1212 
1213       if (!within_signed_range (offset, GET_SET_EXT_IMM_BITS))
1214 	{
1215 	  /* Parsing as a standard GET/SET provides a smaller offset.  */
1216 	  as_bad (_("offset value out of range"));
1217 	  return NULL;
1218 	}
1219 
1220       offset = offset & GET_SET_EXT_IMM_MASK;
1221 
1222       insn->bits |= (offset << 7);
1223     }
1224   else
1225     {
1226       return NULL;
1227     }
1228 
1229   insn->len = 4;
1230   return l;
1231 }
1232 
1233 /* Parse an MGET or MSET instruction addressing mode.  */
1234 static const char *
parse_mget_mset_addr(const char * line,metag_addr * addr)1235 parse_mget_mset_addr (const char *line, metag_addr *addr)
1236 {
1237   const char *l = line;
1238   const char *ll;
1239   const metag_reg *regs[1];
1240 
1241   /* Skip opening square bracket.  */
1242   l++;
1243 
1244   l = parse_gp_regs (l, regs, 1);
1245 
1246   if (l == NULL)
1247     return NULL;
1248 
1249   addr->base_reg = regs[0];
1250 
1251   ll = parse_addr_post_incr_op (l, addr);
1252 
1253   if (ll != NULL)
1254     l = ll;
1255 
1256   if (addr->negate == 1)
1257     return NULL;
1258 
1259   if (*l == ADDR_END_CHAR)
1260     {
1261       l++;
1262       return l;
1263     }
1264 
1265   return NULL;
1266 }
1267 
1268 /* Parse an MGET instruction.  */
1269 static const char *
parse_mget(const char * line,const metag_reg ** regs,metag_addr * addr,size_t * regs_read)1270 parse_mget (const char *line, const metag_reg **regs, metag_addr *addr,
1271 	    size_t *regs_read)
1272 {
1273   const char *l = line;
1274 
1275   l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1276 
1277   if (l == NULL ||
1278       *regs_read == 0)
1279     {
1280       as_bad (_("invalid destination register list"));
1281       return NULL;
1282     }
1283 
1284   l = skip_comma (l);
1285 
1286   if (l == NULL ||
1287       *l == END_OF_INSN)
1288     return NULL;
1289 
1290   l = parse_mget_mset_addr (l, addr);
1291 
1292   if (l == NULL)
1293     {
1294 	  as_bad (_("invalid memory operand"));
1295 	  return NULL;
1296     }
1297 
1298   return l;
1299 }
1300 
1301 /* Parse an MSET instruction.  */
1302 static const char *
parse_mset(const char * line,const metag_reg ** regs,metag_addr * addr,size_t * regs_read)1303 parse_mset (const char *line, const metag_reg **regs, metag_addr *addr,
1304 	    size_t *regs_read)
1305 {
1306   const char *l = line;
1307 
1308   l = parse_mget_mset_addr (l, addr);
1309 
1310   if (l == NULL)
1311     {
1312 	  as_bad (_("invalid memory operand"));
1313 	  return NULL;
1314     }
1315 
1316   l = skip_comma (l);
1317 
1318   if (l == NULL ||
1319       *l == END_OF_INSN)
1320     return NULL;
1321 
1322   l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1323 
1324   if (l == NULL ||
1325       *regs_read == 0)
1326     {
1327       as_bad (_("invalid source register list"));
1328       return NULL;
1329     }
1330 
1331   return l;
1332 }
1333 
1334 /* Take a register list REGS of size REGS_READ and convert it into an
1335    rmask value if possible. Return the rmask value in RMASK and the
1336    lowest numbered register in LOWEST_REG. Return TRUE if the conversion
1337    was successful.  */
1338 static bfd_boolean
check_rmask(const metag_reg ** regs,size_t regs_read,bfd_boolean is_fpu,bfd_boolean is_64bit,unsigned int * lowest_reg,unsigned int * rmask)1339 check_rmask (const metag_reg **regs, size_t regs_read, bfd_boolean is_fpu,
1340 	     bfd_boolean is_64bit, unsigned int *lowest_reg,
1341 	     unsigned int *rmask)
1342 {
1343   unsigned int reg_unit = regs[0]->unit;
1344   size_t i;
1345 
1346   for (i = 0; i < regs_read; i++)
1347     {
1348       if (is_fpu)
1349 	{
1350 	  if (is_64bit && regs[i]->no % 2)
1351 	    {
1352 	      as_bad (_("register list must be even numbered"));
1353 	      return FALSE;
1354 	    }
1355 	}
1356       else if (regs[i]->unit != reg_unit)
1357 	{
1358 	  as_bad (_("register list must be from the same unit"));
1359 	  return FALSE;
1360 	}
1361 
1362       if (regs[i]->no < *lowest_reg)
1363 	*lowest_reg = regs[i]->no;
1364     }
1365 
1366   for (i = 0; i < regs_read; i++)
1367     {
1368       unsigned int next_bit, next_reg;
1369       if (regs[i]->no == *lowest_reg)
1370 	continue;
1371 
1372       if (is_fpu && is_64bit)
1373 	next_reg = ((regs[i]->no / 2) - ((*lowest_reg / 2) + 1));
1374       else
1375 	next_reg = (regs[i]->no - (*lowest_reg + 1));
1376 
1377       next_bit = (1 << next_reg);
1378 
1379       if (*rmask & next_bit)
1380 	{
1381 	  as_bad (_("register list must not contain duplicates"));
1382 	  return FALSE;
1383 	}
1384 
1385       *rmask |= next_bit;
1386     }
1387 
1388   return TRUE;
1389 }
1390 
1391 /* Parse an MGET or MSET instruction.  */
1392 static const char *
parse_mget_mset(const char * line,metag_insn * insn,const insn_template * template)1393 parse_mget_mset (const char *line, metag_insn *insn,
1394 		 const insn_template *template)
1395 {
1396   const char *l = line;
1397   const metag_reg *regs[MGET_MSET_MAX_REGS];
1398   metag_addr addr;
1399   bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
1400   bfd_boolean is_fpu = (MINOR_OPCODE (template->meta_opcode) & 0x6) == 0x6;
1401   bfd_boolean is_64bit = (MINOR_OPCODE (template->meta_opcode) & 0x1) == 0x1;
1402   size_t regs_read = 0;
1403   unsigned int rmask = 0, reg_unit = 0, lowest_reg = 0xffffffff;
1404 
1405   memset(&addr, 0, sizeof(addr));
1406   addr.reloc_type = BFD_RELOC_UNUSED;
1407 
1408   if (is_get)
1409     {
1410       l = parse_mget (l, regs, &addr, &regs_read);
1411     }
1412   else
1413     {
1414       l = parse_mset (l, regs, &addr, &regs_read);
1415     }
1416 
1417   if (l == NULL)
1418     return NULL;
1419 
1420   if (!check_rmask (regs, regs_read, is_fpu, is_64bit, &lowest_reg, &rmask))
1421     return NULL;
1422 
1423   reg_unit = regs[0]->unit;
1424 
1425   if (is_fpu)
1426     {
1427       if (reg_unit != UNIT_FX)
1428 	return NULL;
1429 
1430       reg_unit = 0;
1431     }
1432   else if (reg_unit == UNIT_FX)
1433     return NULL;
1434 
1435   insn->bits = (template->meta_opcode |
1436 		(lowest_reg << 19) |
1437 		((reg_unit & SHORT_UNIT_MASK) << 3));
1438 
1439   if (!is_short_unit (addr.base_reg->unit))
1440     {
1441       as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1442       return NULL;
1443     }
1444 
1445   insn->bits |= ((addr.base_reg->no << 14) |
1446 		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1447 
1448   insn->bits |= (rmask & RMASK_MASK) << 7;
1449 
1450   insn->len = 4;
1451   return l;
1452 }
1453 
1454 /* Parse a list of registers for MMOV pipeline prime.  */
1455 static const char *
parse_mmov_prime_list(const char * line,const metag_reg ** regs,unsigned int * rmask)1456 parse_mmov_prime_list (const char *line, const metag_reg **regs,
1457 		       unsigned int *rmask)
1458 {
1459   const char *l = line;
1460   const metag_reg *ra_regs[MMOV_MAX_REGS];
1461   size_t regs_read = 0, i;
1462   unsigned int mask = 0;
1463 
1464   l = parse_gp_regs_list (l, regs, 1, &regs_read);
1465 
1466   /* First register must be a port. */
1467   if (l == NULL || regs[0]->unit != UNIT_RD)
1468     return NULL;
1469 
1470   l = skip_comma (l);
1471 
1472   if (l == NULL)
1473     return NULL;
1474 
1475   l = parse_gp_regs_list (l, ra_regs, MMOV_MAX_REGS, &regs_read);
1476 
1477   if (l == NULL)
1478     return NULL;
1479 
1480   /* Check remaining registers match the first.
1481 
1482      Note that we also accept RA (0x10) as input for the remaining registers.
1483      Whilst this doesn't represent the instruction in any way we're stuck
1484      with it because the embedded assembler accepts it.  */
1485   for (i = 0; i < regs_read; i++)
1486     {
1487       if (ra_regs[i]->unit != UNIT_RD ||
1488 	  (ra_regs[i]->no != 0x10 && ra_regs[i]->no != regs[0]->no))
1489 	return NULL;
1490 
1491       mask = (mask << 1) | 0x1;
1492     }
1493 
1494   *rmask = mask;
1495 
1496   return l;
1497 }
1498 
1499 /* Parse a MMOV instruction.  */
1500 static const char *
parse_mmov(const char * line,metag_insn * insn,const insn_template * template)1501 parse_mmov (const char *line, metag_insn *insn,
1502 	    const insn_template *template)
1503 {
1504   const char *l = line;
1505   unsigned int is_fpu = template->insn_type == INSN_FPU;
1506   unsigned int is_prime = ((MINOR_OPCODE (template->meta_opcode) & 0x2) &&
1507 			   !is_fpu);
1508   unsigned int is_64bit = MINOR_OPCODE (template->meta_opcode) & 0x1;
1509   unsigned int rmask = 0;
1510 
1511   if (is_prime)
1512     {
1513       const metag_reg *reg;
1514       metag_addr addr;
1515 
1516       memset (&addr, 0, sizeof(addr));
1517 
1518       l = parse_mmov_prime_list (l, &reg, &rmask);
1519 
1520       if (l == NULL)
1521 	return NULL;
1522 
1523       l = skip_comma (l);
1524 
1525       if (l == NULL)
1526 	return NULL;
1527 
1528       l = parse_mget_mset_addr (l, &addr);
1529 
1530       if (l == NULL)
1531 	{
1532 	  as_bad (_("invalid memory operand"));
1533 	  return NULL;
1534 	}
1535 
1536       insn->bits = (template->meta_opcode |
1537 		    (reg->no << 19) |
1538 		    (addr.base_reg->no << 14) |
1539 		    ((rmask & RMASK_MASK) << 7) |
1540 		    ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1541     }
1542   else
1543     {
1544       const metag_reg *regs[MMOV_MAX_REGS + 1];
1545       unsigned int lowest_reg = 0xffffffff;
1546       size_t regs_read = 0;
1547 
1548       l = parse_gp_regs_list (l, regs, MMOV_MAX_REGS + 1, &regs_read);
1549 
1550       if (l == NULL || regs_read == 0)
1551 	return NULL;
1552 
1553       if (!is_short_unit (regs[0]->unit) &&
1554 	  !(is_fpu && regs[0]->unit == UNIT_FX))
1555 	{
1556 	  return NULL;
1557 	}
1558 
1559       if (!(regs[regs_read-1]->unit == UNIT_RD &&
1560 	    regs[regs_read-1]->no == 0))
1561 	{
1562 	  return NULL;
1563 	}
1564 
1565       if (!check_rmask (regs, regs_read - 1, is_fpu, is_64bit, &lowest_reg,
1566 			&rmask))
1567 	return NULL;
1568 
1569       if (is_fpu)
1570 	{
1571 	  insn->bits = (template->meta_opcode |
1572 			(regs[0]->no << 14) |
1573 			((rmask & RMASK_MASK) << 7));
1574 	}
1575       else
1576 	{
1577 	  insn->bits = (template->meta_opcode |
1578 			(regs[0]->no << 19) |
1579 			((rmask & RMASK_MASK) << 7) |
1580 			((regs[0]->unit & SHORT_UNIT_MASK) << 3));
1581 	}
1582     }
1583 
1584   insn->len = 4;
1585   return l;
1586 }
1587 
1588 /* Parse an immediate constant.  */
1589 static const char *
parse_imm_constant(const char * line,metag_insn * insn,int * value)1590 parse_imm_constant (const char *line, metag_insn *insn, int *value)
1591 {
1592   const char *l = line;
1593   char *save_input_line_pointer;
1594   expressionS *exp = &insn->reloc_exp;
1595 
1596   /* Skip #. */
1597   if (*l == '#')
1598     l++;
1599   else
1600     return NULL;
1601 
1602   save_input_line_pointer = input_line_pointer;
1603   input_line_pointer = (char *) l;
1604 
1605   expression (exp);
1606 
1607   l = input_line_pointer;
1608   input_line_pointer = save_input_line_pointer;
1609 
1610   if (exp->X_op == O_constant)
1611     {
1612       *value = exp->X_add_number;
1613 
1614       return l;
1615     }
1616   else
1617     {
1618       return NULL;
1619     }
1620 }
1621 
1622 /* Parse an MDRD instruction.  */
1623 static const char *
parse_mdrd(const char * line,metag_insn * insn,const insn_template * template)1624 parse_mdrd (const char *line, metag_insn *insn,
1625 	    const insn_template *template)
1626 {
1627   const char *l = line;
1628   unsigned int rmask = 0;
1629   int value = 0, i;
1630 
1631   l = parse_imm_constant (l, insn, &value);
1632 
1633   if (l == NULL)
1634     return NULL;
1635 
1636   if (value < 1 || value > 8)
1637     {
1638       as_bad (_("MDRD value must be between 1 and 8"));
1639       return NULL;
1640     }
1641 
1642   for (i = 1; i < value; i++)
1643     {
1644       rmask <<= 1;
1645       rmask |= 1;
1646     }
1647 
1648   insn->bits = (template->meta_opcode |
1649 		(rmask << 7));
1650 
1651   insn->len = 4;
1652   return l;
1653 }
1654 
1655 /* Parse a conditional SET instruction.  */
1656 static const char *
parse_cond_set(const char * line,metag_insn * insn,const insn_template * template)1657 parse_cond_set (const char *line, metag_insn *insn,
1658 		const insn_template *template)
1659 {
1660   const char *l = line;
1661   const metag_reg *regs[2];
1662   metag_addr addr;
1663   unsigned int size = metag_cond_set_size_bytes (template->meta_opcode);
1664   unsigned int reg_no;
1665 
1666   memset(&addr, 0, sizeof(addr));
1667   addr.reloc_type = BFD_RELOC_UNUSED;
1668 
1669   l = parse_set (l, regs, &addr, size);
1670 
1671   if (l == NULL)
1672     return NULL;
1673 
1674   if (regs[0]->unit == UNIT_RD)
1675     {
1676       if (regs[0]->no != 0)
1677 	{
1678 	  as_bad (_("set can only use RD port as source"));
1679 	  return NULL;
1680 	}
1681       reg_no = 16;
1682     }
1683   else
1684     reg_no = regs[0]->no;
1685 
1686   if (addr.update)
1687     return NULL;
1688 
1689   if (!(addr.immediate &&
1690 	addr.exp.X_add_number == 0))
1691     return NULL;
1692 
1693   insn->bits = (template->meta_opcode |
1694 		(reg_no << 19) |
1695 		(regs[0]->unit << 10));
1696 
1697   if (!is_short_unit (addr.base_reg->unit))
1698     {
1699       as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1700       return NULL;
1701     }
1702 
1703   insn->bits |= ((addr.base_reg->no << 14) |
1704 		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1705 
1706   insn->len = 4;
1707   return l;
1708 }
1709 
1710 /* Parse an XFR instruction.  */
1711 static const char *
parse_xfr(const char * line,metag_insn * insn,const insn_template * template)1712 parse_xfr (const char *line, metag_insn *insn,
1713 	   const insn_template *template)
1714 {
1715   const char *l = line;
1716   metag_addr dest_addr, src_addr;
1717   unsigned int size = 4;
1718 
1719   memset(&dest_addr, 0, sizeof(dest_addr));
1720   memset(&src_addr, 0, sizeof(src_addr));
1721   dest_addr.reloc_type = BFD_RELOC_UNUSED;
1722   src_addr.reloc_type = BFD_RELOC_UNUSED;
1723 
1724   l = parse_addr (l, &dest_addr, size);
1725 
1726   if (l == NULL ||
1727       dest_addr.immediate == 1)
1728     {
1729 	  as_bad (_("invalid destination memory operand"));
1730 	  return NULL;
1731     }
1732 
1733   l = skip_comma (l);
1734 
1735   if (l == NULL ||
1736       *l == END_OF_INSN)
1737     return NULL;
1738 
1739   l = parse_addr (l, &src_addr, size);
1740 
1741   if (l == NULL ||
1742       src_addr.immediate == 1)
1743     {
1744 	  as_bad (_("invalid source memory operand"));
1745 	  return NULL;
1746     }
1747 
1748   if (!is_short_unit (dest_addr.base_reg->unit) ||
1749       !is_short_unit (src_addr.base_reg->unit))
1750     {
1751       as_bad (_("address units must be one of %s"), SHORT_UNITS);
1752       return NULL;
1753     }
1754 
1755   if ((dest_addr.base_reg->unit != dest_addr.offset_reg->unit) ||
1756       (src_addr.base_reg->unit != src_addr.offset_reg->unit))
1757     {
1758       as_bad (_("base and offset must be from the same unit"));
1759       return NULL;
1760     }
1761 
1762   if (dest_addr.update == 1 &&
1763       src_addr.update == 1 &&
1764       dest_addr.post_increment != src_addr.post_increment)
1765     {
1766       as_bad (_("source and destination increment mode must agree"));
1767       return NULL;
1768     }
1769 
1770   insn->bits = (template->meta_opcode |
1771 		(src_addr.base_reg->no << 19) |
1772 		(src_addr.offset_reg->no << 14) |
1773 		((src_addr.base_reg->unit & SHORT_UNIT_MASK) << 2));
1774 
1775   insn->bits |= ((dest_addr.base_reg->no << 9) |
1776 		 (dest_addr.offset_reg->no << 4) |
1777 		 ((dest_addr.base_reg->unit & SHORT_UNIT_MASK)));
1778 
1779   if (dest_addr.update == 1)
1780     insn->bits |= (1 << 26);
1781 
1782   if (src_addr.update == 1)
1783     insn->bits |= (1 << 27);
1784 
1785   if (dest_addr.post_increment == 1 ||
1786       src_addr.post_increment == 1)
1787     insn->bits |= (1 << 24);
1788 
1789   insn->len = 4;
1790   return l;
1791 }
1792 
1793 /* Parse an 8bit immediate value.  */
1794 static const char *
parse_imm8(const char * line,metag_insn * insn,int * value)1795 parse_imm8 (const char *line, metag_insn *insn, int *value)
1796 {
1797   const char *l = line;
1798   char *save_input_line_pointer;
1799   expressionS *exp = &insn->reloc_exp;
1800 
1801   /* Skip #. */
1802   if (*l == '#')
1803     l++;
1804   else
1805     return NULL;
1806 
1807   save_input_line_pointer = input_line_pointer;
1808   input_line_pointer = (char *) l;
1809 
1810   expression (exp);
1811 
1812   l = input_line_pointer;
1813   input_line_pointer = save_input_line_pointer;
1814 
1815   if (exp->X_op == O_absent || exp->X_op == O_big)
1816     {
1817       return NULL;
1818     }
1819   else if (exp->X_op == O_constant)
1820     {
1821       *value = exp->X_add_number;
1822     }
1823   else
1824     {
1825       insn->reloc_type = BFD_RELOC_METAG_REL8;
1826       insn->reloc_pcrel = 0;
1827     }
1828 
1829   return l;
1830 }
1831 
1832 /* Parse a 16bit immediate value.  */
1833 static const char *
parse_imm16(const char * line,metag_insn * insn,int * value)1834 parse_imm16 (const char *line, metag_insn *insn, int *value)
1835 {
1836   const char *l = line;
1837   char *save_input_line_pointer;
1838   expressionS *exp = &insn->reloc_exp;
1839   bfd_boolean is_hi = FALSE;
1840   bfd_boolean is_lo = FALSE;
1841 
1842   /* Skip #. */
1843   if (*l == '#')
1844     l++;
1845   else
1846     return NULL;
1847 
1848   if (strncasecmp (l, "HI", 2) == 0)
1849     {
1850       is_hi = TRUE;
1851       l += 2;
1852     }
1853   else if (strncasecmp (l, "LO", 2) == 0)
1854     {
1855       is_lo = TRUE;
1856       l += 2;
1857     }
1858 
1859   save_input_line_pointer = input_line_pointer;
1860   input_line_pointer = (char *) l;
1861 
1862   expression (exp);
1863 
1864   l = input_line_pointer;
1865   input_line_pointer = save_input_line_pointer;
1866 
1867   if (exp->X_op == O_absent || exp->X_op == O_big)
1868     {
1869       return NULL;
1870     }
1871   else if (exp->X_op == O_constant)
1872     {
1873       if (is_hi)
1874 	*value = (exp->X_add_number >> 16) & IMM16_MASK;
1875       else if (is_lo)
1876 	*value = exp->X_add_number & IMM16_MASK;
1877       else
1878 	*value = exp->X_add_number;
1879     }
1880   else
1881     {
1882       if (exp->X_op == O_PIC_reloc)
1883 	{
1884 	  exp->X_op = O_symbol;
1885 
1886 	  if (exp->X_md == BFD_RELOC_METAG_GOTOFF)
1887 	    {
1888 	      if (is_hi)
1889 		insn->reloc_type = BFD_RELOC_METAG_HI16_GOTOFF;
1890 	      else if (is_lo)
1891 		insn->reloc_type = BFD_RELOC_METAG_LO16_GOTOFF;
1892 	      else
1893 		return NULL;
1894 	    }
1895 	  else if (exp->X_md == BFD_RELOC_METAG_PLT)
1896 	    {
1897 	      if (is_hi)
1898 		insn->reloc_type = BFD_RELOC_METAG_HI16_PLT;
1899 	      else if (is_lo)
1900 		insn->reloc_type = BFD_RELOC_METAG_LO16_PLT;
1901 	      else
1902 		return NULL;
1903 	    }
1904 	  else if (exp->X_md == BFD_RELOC_METAG_TLS_LDO)
1905 	    {
1906 	      if (is_hi)
1907 		insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_HI16;
1908 	      else if (is_lo)
1909 		insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_LO16;
1910 	      else
1911 		return NULL;
1912 	    }
1913 	  else if (exp->X_md == BFD_RELOC_METAG_TLS_IENONPIC)
1914 	    {
1915 	      if (is_hi)
1916 		insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_HI16;
1917 	      else if (is_lo)
1918 		insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_LO16;
1919 	      else
1920 		return NULL;
1921 	    }
1922 	  else if (exp->X_md == BFD_RELOC_METAG_TLS_LE)
1923 	    {
1924 	      if (is_hi)
1925 		insn->reloc_type = BFD_RELOC_METAG_TLS_LE_HI16;
1926 	      else if (is_lo)
1927 		insn->reloc_type = BFD_RELOC_METAG_TLS_LE_LO16;
1928 	      else
1929 		return NULL;
1930 	    }
1931 	  else if (exp->X_md == BFD_RELOC_METAG_TLS_GD ||
1932 		   exp->X_md == BFD_RELOC_METAG_TLS_LDM)
1933 	    insn->reloc_type = exp->X_md;
1934 	}
1935       else
1936 	{
1937 	  if (exp->X_op == O_symbol && exp->X_add_symbol == GOT_symbol)
1938 	    {
1939 	      if (is_hi)
1940 		insn->reloc_type = BFD_RELOC_METAG_HI16_GOTPC;
1941 	      else if (is_lo)
1942 		insn->reloc_type = BFD_RELOC_METAG_LO16_GOTPC;
1943 	      else
1944 		return NULL;
1945 	    }
1946 	  else
1947 	    {
1948 	      if (is_hi)
1949 		insn->reloc_type = BFD_RELOC_METAG_HIADDR16;
1950 	      else if (is_lo)
1951 		insn->reloc_type = BFD_RELOC_METAG_LOADDR16;
1952 	      else
1953 		insn->reloc_type = BFD_RELOC_METAG_REL16;
1954 	    }
1955 	}
1956 
1957       insn->reloc_pcrel = 0;
1958     }
1959 
1960   return l;
1961 }
1962 
1963 /* Parse a MOV to control unit instruction.  */
1964 static const char *
parse_mov_ct(const char * line,metag_insn * insn,const insn_template * template)1965 parse_mov_ct (const char *line, metag_insn *insn,
1966 	      const insn_template *template)
1967 {
1968   const char *l = line;
1969   const metag_reg *regs[1];
1970   unsigned int top = template->meta_opcode & 0x1;
1971   unsigned int is_trace = (template->meta_opcode >> 2) & 0x1;
1972   unsigned int sign_extend = 0;
1973   int value = 0;
1974 
1975   l = parse_gp_regs (l, regs, 1);
1976 
1977   if (l == NULL)
1978     return NULL;
1979 
1980   if (is_trace)
1981     {
1982       if (regs[0]->unit != UNIT_TT)
1983 	return NULL;
1984     }
1985   else
1986     {
1987       if (regs[0]->unit != UNIT_CT)
1988 	return NULL;
1989     }
1990 
1991   l = skip_comma (l);
1992 
1993   if (l == NULL ||
1994       *l == END_OF_INSN)
1995     return NULL;
1996 
1997   l = parse_imm16 (l, insn, &value);
1998 
1999   if (l == NULL)
2000     return NULL;
2001 
2002   if (value < 0)
2003     sign_extend = 1;
2004 
2005   insn->bits = (template->meta_opcode |
2006 		(regs[0]->no << 19) |
2007 		((value & IMM16_MASK) << 3));
2008 
2009   if (sign_extend == 1 && top == 0)
2010     insn->bits |= (1 << 1);
2011 
2012   insn->len = 4;
2013   return l;
2014 }
2015 
2016 /* Parse a SWAP instruction.  */
2017 static const char *
parse_swap(const char * line,metag_insn * insn,const insn_template * template)2018 parse_swap (const char *line, metag_insn *insn,
2019 	    const insn_template *template)
2020 {
2021   const char *l = line;
2022   const metag_reg *regs[2];
2023 
2024   l = parse_gp_regs (l, regs, 2);
2025 
2026   if (l == NULL)
2027     return NULL;
2028 
2029   /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit.  */
2030   switch (regs[0]->unit)
2031     {
2032     case UNIT_PC:
2033     case UNIT_CT:
2034     case UNIT_TR:
2035     case UNIT_TT:
2036       if (regs[1]->unit == UNIT_PC
2037 	  || regs[1]->unit == UNIT_CT
2038 	  || regs[1]->unit == UNIT_TR
2039 	  || regs[1]->unit == UNIT_TT)
2040 	{
2041 	  as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
2042 	  return NULL;
2043 	}
2044 
2045     default:
2046       /* Registers must be in different units.  */
2047       if (regs[0]->unit == regs[1]->unit)
2048 	{
2049 	  as_bad (_("source and destination register must be in different units"));
2050 	  return NULL;
2051 	}
2052       break;
2053     }
2054 
2055   insn->bits = (template->meta_opcode
2056 		| (regs[1]->no << 19)
2057 		| (regs[0]->no << 14)
2058 		| (regs[1]->unit << 10)
2059 		| (regs[0]->unit << 5));
2060 
2061   insn->len = 4;
2062   return l;
2063 }
2064 
2065 /* Parse a JUMP instruction.  */
2066 static const char *
parse_jump(const char * line,metag_insn * insn,const insn_template * template)2067 parse_jump (const char *line, metag_insn *insn,
2068 	    const insn_template *template)
2069 {
2070   const char *l = line;
2071   const metag_reg *regs[1];
2072   int value = 0;
2073 
2074   l = parse_gp_regs (l, regs, 1);
2075 
2076   if (l == NULL)
2077     return NULL;
2078 
2079   if (!is_short_unit (regs[0]->unit))
2080     {
2081       as_bad (_("register unit must be one of %s"), SHORT_UNITS);
2082       return FALSE;
2083     }
2084 
2085   l = skip_comma (l);
2086 
2087   if (l == NULL ||
2088       *l == END_OF_INSN)
2089     return NULL;
2090 
2091   l = parse_imm16 (l, insn, &value);
2092 
2093   if (l == NULL)
2094     return NULL;
2095 
2096   insn->bits = (template->meta_opcode |
2097 		(regs[0]->no << 19) |
2098 		(regs[0]->unit & SHORT_UNIT_MASK) |
2099 		((value & IMM16_MASK) << 3));
2100 
2101   insn->len = 4;
2102   return l;
2103 }
2104 
2105 /* Parse a 19bit immediate value.  */
2106 static const char *
parse_imm19(const char * line,metag_insn * insn,int * value)2107 parse_imm19 (const char *line, metag_insn *insn, int *value)
2108 {
2109   const char *l = line;
2110   char *save_input_line_pointer;
2111   expressionS *exp = &insn->reloc_exp;
2112 
2113   /* Skip #.  */
2114   if (*l == '#')
2115     l++;
2116 
2117   save_input_line_pointer = input_line_pointer;
2118   input_line_pointer = (char *) l;
2119 
2120   expression (exp);
2121 
2122   l = input_line_pointer;
2123   input_line_pointer = save_input_line_pointer;
2124 
2125   if (exp->X_op == O_absent || exp->X_op == O_big)
2126     {
2127       return NULL;
2128     }
2129   else if (exp->X_op == O_constant)
2130     {
2131       *value = exp->X_add_number;
2132     }
2133   else
2134     {
2135       if (exp->X_op == O_PIC_reloc)
2136 	{
2137 	  exp->X_op = O_symbol;
2138 
2139 	  if (exp->X_md == BFD_RELOC_METAG_PLT)
2140 	    insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT;
2141 	  else
2142 	    return NULL;
2143 	}
2144       else
2145 	insn->reloc_type = BFD_RELOC_METAG_RELBRANCH;
2146       insn->reloc_pcrel = 1;
2147     }
2148 
2149   return l;
2150 }
2151 
2152 /* Parse a CALLR instruction.  */
2153 static const char *
parse_callr(const char * line,metag_insn * insn,const insn_template * template)2154 parse_callr (const char *line, metag_insn *insn,
2155 	     const insn_template *template)
2156 {
2157   const char *l = line;
2158   const metag_reg *regs[1];
2159   int value = 0;
2160 
2161   l = parse_gp_regs (l, regs, 1);
2162 
2163   if (l == NULL)
2164     return NULL;
2165 
2166   if (!is_short_unit (regs[0]->unit))
2167     {
2168       as_bad (_("link register unit must be one of %s"), SHORT_UNITS);
2169       return NULL;
2170     }
2171 
2172   if (regs[0]->no & ~CALLR_REG_MASK)
2173     {
2174       as_bad (_("link register must be in a low numbered register"));
2175       return NULL;
2176     }
2177 
2178   l = skip_comma (l);
2179 
2180   if (l == NULL ||
2181       *l == END_OF_INSN)
2182     return NULL;
2183 
2184   l = parse_imm19 (l, insn, &value);
2185 
2186   if (l == NULL)
2187     return NULL;
2188 
2189   if (!within_signed_range (value / 4, IMM19_BITS))
2190     {
2191       as_bad (_("target out of range"));
2192       return NULL;
2193     }
2194 
2195   insn->bits = (template->meta_opcode |
2196 		(regs[0]->no & CALLR_REG_MASK) |
2197 		((regs[0]->unit & SHORT_UNIT_MASK) << 3) |
2198 		((value & IMM19_MASK) << 5));
2199 
2200   insn->len = 4;
2201   return l;
2202 }
2203 
2204 /* Return the value for the register field if we apply the O2R modifier
2205    to operand 2 REG, combined with UNIT_BIT derived from the destination
2206    register or source1. Uses address unit O2R if IS_ADDR is set.  */
2207 static int
lookup_o2r(unsigned int is_addr,unsigned int unit_bit,const metag_reg * reg)2208 lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg)
2209 {
2210   if (reg->no & ~O2R_REG_MASK)
2211     return -1;
2212 
2213   if (is_addr)
2214     {
2215       if (unit_bit)
2216 	{
2217 	  switch (reg->unit)
2218 	    {
2219 	    case UNIT_D1:
2220 	      return reg->no;
2221 	    case UNIT_D0:
2222 	      return (1 << 3) | reg->no;
2223 	    case UNIT_RD:
2224 	      return (2 << 3) | reg->no;
2225 	    case UNIT_A0:
2226 	      return (3 << 3) | reg->no;
2227 	    default:
2228 	      return -1;
2229 	    }
2230 	}
2231       else
2232 	{
2233 	  switch (reg->unit)
2234 	    {
2235 	    case UNIT_A1:
2236 	      return reg->no;
2237 	    case UNIT_D0:
2238 	      return (1 << 3) | reg->no;
2239 	    case UNIT_RD:
2240 	      return (2 << 3) | reg->no;
2241 	    case UNIT_D1:
2242 	      return (3 << 3) | reg->no;
2243 	    default:
2244 	      return -1;
2245 	    }
2246 	}
2247     }
2248   else
2249     {
2250       if (unit_bit)
2251 	{
2252 	  switch (reg->unit)
2253 	    {
2254 	    case UNIT_A1:
2255 	      return reg->no;
2256 	    case UNIT_D0:
2257 	      return (1 << 3) | reg->no;
2258 	    case UNIT_RD:
2259 	      return (2 << 3) | reg->no;
2260 	    case UNIT_A0:
2261 	      return (3 << 3) | reg->no;
2262 	    default:
2263 	      return -1;
2264 	    }
2265 	}
2266       else
2267 	{
2268 	  switch (reg->unit)
2269 	    {
2270 	    case UNIT_A1:
2271 	      return reg->no;
2272 	    case UNIT_D1:
2273 	      return (1 << 3) | reg->no;
2274 	    case UNIT_RD:
2275 	      return (2 << 3) | reg->no;
2276 	    case UNIT_A0:
2277 	      return (3 << 3) | reg->no;
2278 	    default:
2279 	      return -1;
2280 	    }
2281 	}
2282     }
2283 }
2284 
2285 /* Parse GP ALU instruction.  */
2286 static const char *
parse_alu(const char * line,metag_insn * insn,const insn_template * template)2287 parse_alu (const char *line, metag_insn *insn,
2288 	   const insn_template *template)
2289 {
2290   const char *l = line;
2291   const metag_reg *dest_regs[1];
2292   const metag_reg *src_regs[2];
2293   int value = 0;
2294   unsigned int o1z = 0;
2295   unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2296   unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2297   unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2298   unsigned int top = template->meta_opcode & 0x1;
2299   unsigned int sign_extend = 0;
2300   unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR;
2301   unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL;
2302   unsigned int unit_bit = 0;
2303   bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR;
2304 
2305   l = parse_gp_regs (l, dest_regs, 1);
2306 
2307   if (l == NULL)
2308     return NULL;
2309 
2310   l = skip_comma (l);
2311 
2312   if (l == NULL ||
2313       *l == END_OF_INSN)
2314     return NULL;
2315 
2316   if (is_addr_op)
2317     {
2318       if (dest_regs[0]->unit == UNIT_A0)
2319 	unit_bit = 0;
2320       else if (dest_regs[0]->unit == UNIT_A1)
2321 	unit_bit = 1;
2322     }
2323   else
2324     {
2325       if (dest_regs[0]->unit == UNIT_D0)
2326 	unit_bit = 0;
2327       else if (dest_regs[0]->unit == UNIT_D1)
2328 	unit_bit = 1;
2329     }
2330 
2331   if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR ||
2332       MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
2333        MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) &&
2334       ((template->meta_opcode >> 2) & 0x1))
2335     o1z = 1;
2336 
2337   if (imm)
2338     {
2339       if (!cond)
2340 	{
2341 	  if (is_addr_op)
2342 	    {
2343 	      if (dest_regs[0]->unit == UNIT_A0)
2344 		unit_bit = 0;
2345 	      else if (dest_regs[0]->unit == UNIT_A1)
2346 		unit_bit = 1;
2347 	      else
2348 		return NULL;
2349 	    }
2350 	  else
2351 	    {
2352 	      if (dest_regs[0]->unit == UNIT_D0)
2353 		unit_bit = 0;
2354 	      else if (dest_regs[0]->unit == UNIT_D1)
2355 		unit_bit = 1;
2356 	      else
2357 		return NULL;
2358 	    }
2359 	}
2360 
2361       if (cond)
2362 	{
2363 	  l = parse_gp_regs (l, src_regs, 1);
2364 
2365 	  if (l == NULL)
2366 	    return NULL;
2367 
2368 	  l = skip_comma (l);
2369 
2370 	  if (l == NULL ||
2371 	      *l == END_OF_INSN)
2372 	    return NULL;
2373 
2374 	  if (is_addr_op)
2375 	    {
2376 	      if (src_regs[0]->unit == UNIT_A0)
2377 		unit_bit = 0;
2378 	      else if (src_regs[0]->unit == UNIT_A1)
2379 		unit_bit = 1;
2380 	      else
2381 		return NULL;
2382 	    }
2383 	  else
2384 	    {
2385 	      if (src_regs[0]->unit == UNIT_D0)
2386 		unit_bit = 0;
2387 	      else if (src_regs[0]->unit == UNIT_D1)
2388 		unit_bit = 1;
2389 	      else
2390 		return NULL;
2391 	    }
2392 
2393 	  if (src_regs[0]->unit != dest_regs[0]->unit && !ca)
2394 	    return NULL;
2395 
2396 	  l = parse_imm8 (l, insn, &value);
2397 
2398 	  if (l == NULL)
2399 	    return NULL;
2400 
2401 	  if (!within_unsigned_range (value, IMM8_BITS))
2402 	    return NULL;
2403 
2404 	  insn->bits = (template->meta_opcode |
2405 			(dest_regs[0]->no << 19) |
2406 			(src_regs[0]->no << 14) |
2407 			((value & IMM8_MASK) << 6));
2408 
2409 	  if (ca)
2410 	    {
2411 	      if (is_addr_op)
2412 		{
2413 		  if (src_regs[0]->unit == UNIT_A0)
2414 		    unit_bit = 0;
2415 		  else if (src_regs[0]->unit == UNIT_A1)
2416 		    unit_bit = 1;
2417 		  else
2418 		    return NULL;
2419 		}
2420 	      else
2421 		{
2422 		  if (src_regs[0]->unit == UNIT_D0)
2423 		    unit_bit = 0;
2424 		  else if (src_regs[0]->unit == UNIT_D1)
2425 		    unit_bit = 1;
2426 		  else
2427 		    return NULL;
2428 		}
2429 
2430 	      insn->bits |= dest_regs[0]->unit << 1;
2431 	    }
2432 	}
2433       else if (o1z)
2434 	{
2435 	  l = parse_imm16 (l, insn, &value);
2436 
2437 	  if (l == NULL)
2438 	    return NULL;
2439 
2440 	  if (value < 0)
2441 	    {
2442 	      if (!within_signed_range (value, IMM16_BITS))
2443 		{
2444 		  as_bad (_("immediate out of range"));
2445 		  return NULL;
2446 		}
2447 	      sign_extend = 1;
2448 	    }
2449 	  else
2450 	    {
2451 	      if (!within_unsigned_range (value, IMM16_BITS))
2452 		{
2453 		  as_bad (_("immediate out of range"));
2454 		  return NULL;
2455 		}
2456 	    }
2457 
2458 	  insn->bits = (template->meta_opcode |
2459 			(dest_regs[0]->no << 19) |
2460 			((value & IMM16_MASK) << 3));
2461 	}
2462       else
2463 	{
2464 	  l = parse_gp_regs (l, src_regs, 1);
2465 
2466 	  if (l == NULL)
2467 	    return NULL;
2468 
2469 	  if (!(src_regs[0]->unit == dest_regs[0]->unit))
2470 	    return NULL;
2471 
2472 	  /* CPC is valid for address ops. */
2473 	  if (src_regs[0]->no != dest_regs[0]->no &&
2474 	      !(is_addr_op && src_regs[0]->no == 0x10))
2475 	    return NULL;
2476 
2477 	  l = skip_comma (l);
2478 
2479 	  if (l == NULL ||
2480 	      *l == END_OF_INSN)
2481 	    return NULL;
2482 
2483 	  l = parse_imm16 (l, insn, &value);
2484 
2485 	  if (l == NULL)
2486 	    return NULL;
2487 
2488 	  if (value < 0)
2489 	    {
2490 	      if (!within_signed_range (value, IMM16_BITS))
2491 		{
2492 		  as_bad (_("immediate out of range"));
2493 		  return NULL;
2494 		}
2495 	      sign_extend = 1;
2496 	    }
2497 	  else
2498 	    {
2499 	      if (!within_unsigned_range (value, IMM16_BITS))
2500 		{
2501 		  as_bad (_("immediate out of range"));
2502 		  return NULL;
2503 		}
2504 	    }
2505 
2506 	  insn->bits = (template->meta_opcode |
2507 			(dest_regs[0]->no << 19) |
2508 			(src_regs[0]->no << 19) |
2509 			((value & IMM16_MASK) << 3));
2510 	}
2511     }
2512   else
2513     {
2514       unsigned int o2r = 0;
2515       int rs2;
2516 
2517       if (cond || !o1z)
2518 	l = parse_gp_regs (l, src_regs, 2);
2519       else
2520 	l = parse_gp_regs (l, src_regs, 1);
2521 
2522       if (l == NULL)
2523 	return NULL;
2524 
2525       if (cond || !o1z)
2526 	{
2527 	  if (is_addr_op)
2528 	    {
2529 	      if (src_regs[0]->unit == UNIT_A0)
2530 		unit_bit = 0;
2531 	      else if (src_regs[0]->unit == UNIT_A1)
2532 		unit_bit = 1;
2533 	      else
2534 		return NULL;
2535 	    }
2536 	  else
2537 	    {
2538 	      if (src_regs[0]->unit == UNIT_D0)
2539 		unit_bit = 0;
2540 	      else if (src_regs[0]->unit == UNIT_D1)
2541 		unit_bit = 1;
2542 	      else
2543 		return NULL;
2544 	    }
2545 	}
2546       else
2547 	{
2548 	  if (is_addr_op)
2549 	    {
2550 	      if (dest_regs[0]->unit == UNIT_A0)
2551 		unit_bit = 0;
2552 	      else if (dest_regs[0]->unit == UNIT_A1)
2553 		unit_bit = 1;
2554 	      else
2555 		return NULL;
2556 	    }
2557 	  else
2558 	    {
2559 	      if (dest_regs[0]->unit == UNIT_D0)
2560 		unit_bit = 0;
2561 	      else if (dest_regs[0]->unit == UNIT_D1)
2562 		unit_bit = 1;
2563 	      else
2564 		return NULL;
2565 	    }
2566 	}
2567 
2568       if (cond)
2569 	{
2570 	  if (src_regs[0]->unit != src_regs[1]->unit)
2571 	    {
2572 	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2573 
2574 	      if (rs2 < 0)
2575 		return NULL;
2576 
2577 	      o2r = 1;
2578 	    }
2579 	  else
2580 	    {
2581 	      rs2 = src_regs[1]->no;
2582 	    }
2583 
2584 	  insn->bits = (template->meta_opcode |
2585 			(dest_regs[0]->no << 19) |
2586 			(src_regs[0]->no << 14) |
2587 			(rs2 << 9));
2588 
2589 	  if (is_mul)
2590 	    {
2591 	      if (dest_regs[0]->unit != src_regs[0]->unit && is_mul)
2592 		{
2593 		  if (ca)
2594 		    {
2595 		      insn->bits |= dest_regs[0]->unit << 1;
2596 		    }
2597 		  else
2598 		    return NULL;
2599 		}
2600 	    }
2601 	  else
2602 	    insn->bits |= dest_regs[0]->unit << 5;
2603 	}
2604       else if (o1z)
2605 	{
2606 	  if (dest_regs[0]->unit != src_regs[0]->unit)
2607 	    {
2608 	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]);
2609 
2610 	      if (rs2 < 0)
2611 		return NULL;
2612 
2613 	      o2r = 1;
2614 	    }
2615 	  else
2616 	    {
2617 	      rs2 = src_regs[0]->no;
2618 	    }
2619 
2620 	  insn->bits = (template->meta_opcode |
2621 			(dest_regs[0]->no << 19) |
2622 			(rs2 << 9));
2623 	}
2624       else
2625 	{
2626 	  if (dest_regs[0]->unit != src_regs[0]->unit)
2627 	    return NULL;
2628 
2629 	  if (dest_regs[0]->unit != src_regs[1]->unit)
2630 	    {
2631 	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2632 
2633 	      if (rs2 < 0)
2634 		return NULL;
2635 
2636 	      o2r = 1;
2637 	    }
2638 	  else
2639 	    {
2640 	      rs2 = src_regs[1]->no;
2641 	    }
2642 
2643 	  insn->bits = (template->meta_opcode |
2644 			(dest_regs[0]->no << 19) |
2645 			(src_regs[0]->no << 14) |
2646 			(rs2 << 9));
2647 	}
2648 
2649       if (o2r)
2650 	insn->bits |= 1;
2651     }
2652 
2653   if (is_quickrot)
2654     {
2655       const metag_reg *qr_regs[1];
2656       bfd_boolean limit_regs = imm && cond;
2657 
2658       l = skip_comma (l);
2659 
2660       if (l == NULL ||
2661 	  *l == END_OF_INSN)
2662 	return NULL;
2663 
2664       l = parse_gp_regs (l, qr_regs, 1);
2665 
2666       if (l == NULL)
2667 	return NULL;
2668 
2669       if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) ||
2670 	    !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1)))
2671 	{
2672 	  as_bad (_("invalid quickrot unit specified"));
2673 	  return NULL;
2674 	}
2675 
2676       switch (qr_regs[0]->no)
2677 	{
2678 	case 2:
2679 	  break;
2680 	case 3:
2681 	  if (!limit_regs)
2682 	    {
2683 	      insn->bits |= (1 << 7);
2684 	      break;
2685 	    }
2686 	default:
2687 	  as_bad (_("invalid quickrot register specified"));
2688 	  return NULL;
2689 	}
2690     }
2691 
2692   if (sign_extend == 1 && top == 0)
2693     insn->bits |= (1 << 1);
2694 
2695   insn->bits |= unit_bit << 24;
2696   insn->len = 4;
2697   return l;
2698 }
2699 
2700 /* Parse a B instruction.  */
2701 static const char *
parse_branch(const char * line,metag_insn * insn,const insn_template * template)2702 parse_branch (const char *line, metag_insn *insn,
2703 	      const insn_template *template)
2704 {
2705   const char *l = line;
2706   int value = 0;
2707 
2708   l = parse_imm19 (l, insn, &value);
2709 
2710   if (l == NULL)
2711     return NULL;
2712 
2713   if (!within_signed_range (value / 4, IMM19_BITS))
2714     {
2715       as_bad (_("target out of range"));
2716       return NULL;
2717     }
2718 
2719   insn->bits = (template->meta_opcode |
2720 		((value & IMM19_MASK) << 5));
2721 
2722   insn->len = 4;
2723   return l;
2724 }
2725 
2726 /* Parse a KICK instruction.  */
2727 static const char *
parse_kick(const char * line,metag_insn * insn,const insn_template * template)2728 parse_kick (const char *line, metag_insn *insn,
2729 	    const insn_template *template)
2730 {
2731   const char *l = line;
2732   const metag_reg *regs[2];
2733 
2734   l = parse_gp_regs (l, regs, 2);
2735 
2736   if (l == NULL)
2737     return NULL;
2738 
2739   if (regs[1]->unit != UNIT_TR)
2740     {
2741       as_bad (_("source register must be in the trigger unit"));
2742       return NULL;
2743     }
2744 
2745   insn->bits = (template->meta_opcode |
2746 		(regs[1]->no << 19) |
2747 		(regs[0]->no << 14) |
2748 		(regs[0]->unit << 5));
2749 
2750   insn->len = 4;
2751   return l;
2752 }
2753 
2754 /* Parse a SWITCH instruction.  */
2755 static const char *
parse_switch(const char * line,metag_insn * insn,const insn_template * template)2756 parse_switch (const char *line, metag_insn *insn,
2757 	      const insn_template *template)
2758 {
2759   const char *l = line;
2760   int value = 0;
2761 
2762   l = parse_imm_constant (l, insn, &value);
2763 
2764   if (l == NULL)
2765     return NULL;
2766 
2767   if (!within_unsigned_range (value, IMM24_BITS))
2768     {
2769       as_bad (_("target out of range"));
2770       return NULL;
2771     }
2772 
2773   insn->bits = (template->meta_opcode |
2774 		(value & IMM24_MASK));
2775 
2776   insn->len = 4;
2777   return l;
2778 }
2779 
2780 /* Parse a shift instruction.  */
2781 static const char *
parse_shift(const char * line,metag_insn * insn,const insn_template * template)2782 parse_shift (const char *line, metag_insn *insn,
2783 	     const insn_template *template)
2784 {
2785   const char *l = line;
2786   const metag_reg *regs[2];
2787   const metag_reg *src2_regs[1];
2788   int value = 0;
2789   unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2790   unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2791   unsigned int unit_bit = 0;
2792 
2793   l = parse_gp_regs (l, regs, 2);
2794 
2795   if (l == NULL)
2796     return NULL;
2797 
2798   l = skip_comma (l);
2799 
2800   if (l == NULL ||
2801       *l == END_OF_INSN)
2802     return NULL;
2803 
2804   if (regs[1]->unit == UNIT_D0)
2805     unit_bit = 0;
2806   else if (regs[1]->unit == UNIT_D1)
2807     unit_bit = 1;
2808   else
2809     return NULL;
2810 
2811   if (regs[0]->unit != regs[1]->unit && !(cond && ca))
2812     return NULL;
2813 
2814   if (*l == '#')
2815     {
2816       l = parse_imm_constant (l, insn, &value);
2817 
2818       if (l == NULL)
2819 	return NULL;
2820 
2821       if (!within_unsigned_range (value, IMM5_BITS))
2822 	return NULL;
2823 
2824       insn->bits = (template->meta_opcode |
2825 		    (1 << 25) |
2826 		    (regs[0]->no << 19) |
2827 		    (regs[1]->no << 14) |
2828 		    ((value & IMM5_MASK) << 9));
2829     }
2830   else
2831     {
2832       l = parse_gp_regs (l, src2_regs, 1);
2833 
2834       if (l == NULL)
2835 	return NULL;
2836 
2837       insn->bits = (template->meta_opcode |
2838 		    (regs[0]->no << 19) |
2839 		    (regs[1]->no << 14) |
2840 		    (src2_regs[0]->no << 9));
2841 
2842       if (src2_regs[0]->unit != regs[1]->unit)
2843 	{
2844 	  as_bad(_("Source registers must be in the same unit"));
2845 	  return NULL;
2846 	}
2847     }
2848 
2849   if (regs[0]->unit != regs[1]->unit)
2850     {
2851       if (cond && ca)
2852 	{
2853 	  if (regs[1]->unit == UNIT_D0)
2854 	    unit_bit = 0;
2855 	  else if (regs[1]->unit == UNIT_D1)
2856 	    unit_bit = 1;
2857 	  else
2858 	    return NULL;
2859 
2860 	  insn->bits |= ((1 << 5) |
2861 			 (regs[0]->unit << 1));
2862 	}
2863       else
2864 	return NULL;
2865     }
2866 
2867   insn->bits |= unit_bit << 24;
2868   insn->len = 4;
2869   return l;
2870 }
2871 
2872 /* Parse a MIN or MAX instruction.  */
2873 static const char *
parse_min_max(const char * line,metag_insn * insn,const insn_template * template)2874 parse_min_max (const char *line, metag_insn *insn,
2875 	       const insn_template *template)
2876 {
2877   const char *l = line;
2878   const metag_reg *regs[3];
2879 
2880   l = parse_gp_regs (l, regs, 3);
2881 
2882   if (l == NULL)
2883     return NULL;
2884 
2885   if (!(regs[0]->unit == UNIT_D0 ||
2886 	regs[0]->unit == UNIT_D1))
2887       return NULL;
2888 
2889   if (!(regs[0]->unit == regs[1]->unit &&
2890 	regs[1]->unit == regs[2]->unit))
2891       return NULL;
2892 
2893   insn->bits = (template->meta_opcode |
2894 		(regs[0]->no << 19) |
2895 		(regs[1]->no << 14) |
2896 		(regs[2]->no << 9));
2897 
2898   if (regs[0]->unit == UNIT_D1)
2899     insn->bits |= (1 << 24);
2900 
2901   insn->len = 4;
2902   return l;
2903 }
2904 
2905 /* Parse a bit operation instruction.  */
2906 static const char *
parse_bitop(const char * line,metag_insn * insn,const insn_template * template)2907 parse_bitop (const char *line, metag_insn *insn,
2908 	     const insn_template *template)
2909 {
2910   const char *l = line;
2911   const metag_reg *regs[2];
2912   unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC;
2913   unsigned int is_bexl = 0;
2914 
2915   if (swap_inst &&
2916       ((template->meta_opcode >> 1) & 0xb) == 0xa)
2917     is_bexl = 1;
2918 
2919   l = parse_gp_regs (l, regs, 2);
2920 
2921   if (l == NULL)
2922     return NULL;
2923 
2924   if (!(regs[0]->unit == UNIT_D0 ||
2925 	regs[0]->unit == UNIT_D1))
2926       return NULL;
2927 
2928   if (is_bexl)
2929     {
2930       if (regs[0]->unit == UNIT_D0 &&
2931 	  regs[1]->unit != UNIT_D1)
2932 	return NULL;
2933       else if (regs[0]->unit == UNIT_D1 &&
2934 	       regs[1]->unit != UNIT_D0)
2935 	return NULL;
2936     }
2937   else if (!(regs[0]->unit == regs[1]->unit))
2938       return NULL;
2939 
2940   insn->bits = (template->meta_opcode |
2941 		(regs[0]->no << 19) |
2942 		(regs[1]->no << 14));
2943 
2944   if (swap_inst)
2945     {
2946       if (regs[1]->unit == UNIT_D1)
2947 	insn->bits |= 1;
2948     }
2949   else
2950     {
2951       if (regs[1]->unit == UNIT_D1)
2952 	insn->bits |= (1 << 24);
2953     }
2954 
2955   insn->len = 4;
2956   return l;
2957 }
2958 
2959 /* Parse a CMP or TST instruction.  */
2960 static const char *
parse_cmp(const char * line,metag_insn * insn,const insn_template * template)2961 parse_cmp (const char *line, metag_insn *insn,
2962 	   const insn_template *template)
2963 {
2964   const char *l = line;
2965   const metag_reg *dest_regs[1];
2966   const metag_reg *src_regs[1];
2967   int value = 0;
2968   unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2969   unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2970   unsigned int top = template->meta_opcode & 0x1;
2971   unsigned int sign_extend = 0;
2972   unsigned int unit_bit = 0;
2973 
2974   l = parse_gp_regs (l, dest_regs, 1);
2975 
2976   if (l == NULL)
2977     return NULL;
2978 
2979   l = skip_comma (l);
2980 
2981   if (l == NULL ||
2982       *l == END_OF_INSN)
2983     return NULL;
2984 
2985   if (dest_regs[0]->unit == UNIT_D0)
2986     unit_bit = 0;
2987   else if (dest_regs[0]->unit == UNIT_D1)
2988     unit_bit = 1;
2989   else
2990     return NULL;
2991 
2992   if (imm)
2993     {
2994       if (cond)
2995 	{
2996 	  l = parse_imm_constant (l, insn, &value);
2997 
2998 	  if (l == NULL)
2999 	    return NULL;
3000 
3001 	  if (!within_unsigned_range (value, IMM8_BITS))
3002 	    return NULL;
3003 
3004 	  insn->bits = (template->meta_opcode |
3005 			(dest_regs[0]->no << 14) |
3006 			((value & IMM8_MASK) << 6));
3007 
3008 	}
3009       else
3010 	{
3011 	  l = parse_imm16 (l, insn, &value);
3012 
3013 	  if (l == NULL)
3014 	    return NULL;
3015 
3016 	  if (value < 0)
3017 	    {
3018 	      if (!within_signed_range (value, IMM16_BITS))
3019 		{
3020 		  as_bad (_("immediate out of range"));
3021 		  return NULL;
3022 		}
3023 	      sign_extend = 1;
3024 	    }
3025 	  else
3026 	    {
3027 	      if (!within_unsigned_range (value, IMM16_BITS))
3028 		{
3029 		  as_bad (_("immediate out of range"));
3030 		  return NULL;
3031 		}
3032 	    }
3033 
3034 	  insn->bits = (template->meta_opcode |
3035 			(dest_regs[0]->no << 19) |
3036 			((value & IMM16_MASK) << 3));
3037 	}
3038     }
3039   else
3040     {
3041       unsigned int o2r = 0;
3042       int rs2;
3043 
3044       l = parse_gp_regs (l, src_regs, 1);
3045 
3046       if (l == NULL)
3047 	return NULL;
3048 
3049       if (dest_regs[0]->unit != src_regs[0]->unit)
3050 	{
3051 	  rs2 = lookup_o2r (0, unit_bit, src_regs[0]);
3052 
3053 	  if (rs2 < 0)
3054 	    return NULL;
3055 
3056 	  o2r = 1;
3057 	}
3058       else
3059 	{
3060 	  rs2 = src_regs[0]->no;
3061 	}
3062 
3063       insn->bits = (template->meta_opcode |
3064 		    (dest_regs[0]->no << 14) |
3065 		    (rs2 << 9));
3066 
3067       if (o2r)
3068 	insn->bits |= 1;
3069     }
3070 
3071   if (sign_extend == 1 && top == 0)
3072     insn->bits |= (1 << 1);
3073 
3074   insn->bits |= unit_bit << 24;
3075   insn->len = 4;
3076   return l;
3077 }
3078 
3079 /* Parse a CACHEW instruction.  */
3080 static const char *
parse_cachew(const char * line,metag_insn * insn,const insn_template * template)3081 parse_cachew (const char *line, metag_insn *insn,
3082 	      const insn_template *template)
3083 {
3084   const char *l = line;
3085   const metag_reg *src_regs[2];
3086   unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3087   metag_addr addr;
3088   int offset;
3089 
3090   memset(&addr, 0, sizeof(addr));
3091   addr.reloc_type = BFD_RELOC_UNUSED;
3092 
3093   l = parse_addr (l, &addr, size);
3094 
3095   if (l == NULL ||
3096       !is_short_unit (addr.base_reg->unit) ||
3097       addr.update ||
3098       !addr.immediate)
3099     {
3100 	  as_bad (_("invalid memory operand"));
3101 	  return NULL;
3102     }
3103 
3104   l = skip_comma (l);
3105 
3106   if (l == NULL ||
3107       *l == END_OF_INSN)
3108     return NULL;
3109 
3110   if (size == 4)
3111     l = parse_gp_regs (l, src_regs, 1);
3112   else
3113     l = parse_pair_gp_regs (l, src_regs);
3114 
3115   if (l == NULL ||
3116       !is_short_unit (src_regs[0]->unit))
3117     {
3118       as_bad (_("invalid source register"));
3119       return NULL;
3120     }
3121 
3122   offset = addr.exp.X_add_number;
3123 
3124   if (addr.negate)
3125     offset = -offset;
3126 
3127   offset = offset / 64;
3128 
3129   if (!within_signed_range (offset, GET_SET_IMM_BITS))
3130     {
3131       as_bad (_("offset value out of range"));
3132       return NULL;
3133     }
3134 
3135   insn->bits = (template->meta_opcode |
3136 		(src_regs[0]->no << 19) |
3137 		(addr.base_reg->no << 14) |
3138 		((offset & GET_SET_IMM_MASK) << 8) |
3139 		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3140 		((src_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3141 
3142   insn->len = 4;
3143   return l;
3144 }
3145 
3146 /* Parse a CACHEW instruction.  */
3147 static const char *
parse_cacher(const char * line,metag_insn * insn,const insn_template * template)3148 parse_cacher (const char *line, metag_insn *insn,
3149 	      const insn_template *template)
3150 {
3151   const char *l = line;
3152   const metag_reg *dest_regs[2];
3153   unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3154   metag_addr addr;
3155   int offset;
3156 
3157   memset(&addr, 0, sizeof(addr));
3158   addr.reloc_type = BFD_RELOC_UNUSED;
3159 
3160   if (size == 4)
3161     l = parse_gp_regs (l, dest_regs, 1);
3162   else
3163     l = parse_pair_gp_regs (l, dest_regs);
3164 
3165   if (l == NULL ||
3166       !is_short_unit (dest_regs[0]->unit))
3167     {
3168       as_bad (_("invalid destination register"));
3169       return NULL;
3170     }
3171 
3172   l = skip_comma (l);
3173 
3174   if (l == NULL ||
3175       *l == END_OF_INSN)
3176     return NULL;
3177 
3178   l = parse_addr (l, &addr, size);
3179 
3180   if (l == NULL ||
3181       !is_short_unit (addr.base_reg->unit) ||
3182       addr.update ||
3183       !addr.immediate)
3184     {
3185 	  as_bad (_("invalid memory operand"));
3186 	  return NULL;
3187     }
3188 
3189   offset = addr.exp.X_add_number;
3190 
3191   if (addr.negate)
3192     offset = -offset;
3193 
3194   offset = offset / (int)size;
3195 
3196   if (!within_signed_range (offset, GET_SET_IMM_BITS))
3197     {
3198       as_bad (_("offset value out of range"));
3199       return NULL;
3200     }
3201 
3202   insn->bits = (template->meta_opcode |
3203 		(dest_regs[0]->no << 19) |
3204 		(addr.base_reg->no << 14) |
3205 		((offset & GET_SET_IMM_MASK) << 8) |
3206 		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3207 		((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3208 
3209   insn->len = 4;
3210   return l;
3211 }
3212 
3213 /* Parse an ICACHE instruction.  */
3214 static const char *
parse_icache(const char * line,metag_insn * insn,const insn_template * template)3215 parse_icache (const char *line, metag_insn *insn,
3216 	      const insn_template *template)
3217 {
3218   const char *l = line;
3219   int offset;
3220   int pfcount;
3221 
3222   l = parse_imm_constant (l, insn, &offset);
3223 
3224   if (l == NULL)
3225     return NULL;
3226 
3227   if (!within_signed_range (offset, IMM15_BITS))
3228     return NULL;
3229 
3230   l = skip_comma (l);
3231 
3232   l = parse_imm_constant (l, insn, &pfcount);
3233 
3234   if (l == NULL)
3235     return NULL;
3236 
3237   if (!within_unsigned_range (pfcount, IMM4_BITS))
3238     return NULL;
3239 
3240   insn->bits = (template->meta_opcode |
3241 		((offset & IMM15_MASK) << 9) |
3242 		((pfcount & IMM4_MASK) << 1));
3243 
3244   insn->len = 4;
3245   return l;
3246 }
3247 
3248 /* Parse a LNKGET instruction.  */
3249 static const char *
parse_lnkget(const char * line,metag_insn * insn,const insn_template * template)3250 parse_lnkget (const char *line, metag_insn *insn,
3251 	      const insn_template *template)
3252 {
3253   const char *l = line;
3254   const metag_reg *dest_regs[2];
3255   unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
3256   metag_addr addr;
3257   int offset;
3258 
3259   memset(&addr, 0, sizeof(addr));
3260   addr.reloc_type = BFD_RELOC_UNUSED;
3261 
3262   if (size == 8)
3263     l = parse_pair_gp_regs (l, dest_regs);
3264   else
3265     l = parse_gp_regs (l, dest_regs, 1);
3266 
3267   if (l == NULL ||
3268       !is_short_unit (dest_regs[0]->unit))
3269     {
3270       as_bad (_("invalid destination register"));
3271       return NULL;
3272     }
3273 
3274   l = skip_comma (l);
3275 
3276   if (l == NULL ||
3277       *l == END_OF_INSN)
3278     return NULL;
3279 
3280   l = parse_addr (l, &addr, size);
3281 
3282   if (l == NULL ||
3283       !is_short_unit (addr.base_reg->unit) ||
3284       addr.update ||
3285       !addr.immediate)
3286     {
3287 	  as_bad (_("invalid memory operand"));
3288 	  return NULL;
3289     }
3290 
3291   offset = addr.exp.X_add_number;
3292 
3293   if (addr.negate)
3294     offset = -offset;
3295 
3296   offset = offset / size;
3297 
3298   if (!within_signed_range (offset, GET_SET_IMM_BITS))
3299     {
3300       as_bad (_("offset value out of range"));
3301       return NULL;
3302     }
3303 
3304   insn->bits = (template->meta_opcode |
3305 		(dest_regs[0]->no << 19) |
3306 		(addr.base_reg->no << 14) |
3307 		((offset & GET_SET_IMM_MASK) << 8) |
3308 		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3309 		((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3310 
3311   insn->len = 4;
3312   return l;
3313 }
3314 
3315 /* Parse an FPU MOV instruction.  */
3316 static const char *
parse_fmov(const char * line,metag_insn * insn,const insn_template * template)3317 parse_fmov (const char *line, metag_insn *insn,
3318 	    const insn_template *template)
3319 {
3320   const char *l = line;
3321   const metag_reg *regs[2];
3322 
3323   l = parse_fpu_regs (l, regs, 2);
3324 
3325   if (l == NULL)
3326     return NULL;
3327 
3328   insn->bits = (template->meta_opcode |
3329 		(regs[0]->no << 19) |
3330 		(regs[1]->no << 14));
3331 
3332   if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3333     insn->bits |= (1 << 5);
3334   else if (insn->fpu_width == FPU_WIDTH_PAIR)
3335     insn->bits |= (1 << 6);
3336 
3337   insn->len = 4;
3338   return l;
3339 }
3340 
3341 /* Parse an FPU MMOV instruction.  */
3342 static const char *
parse_fmmov(const char * line,metag_insn * insn,const insn_template * template)3343 parse_fmmov (const char *line, metag_insn *insn,
3344 	     const insn_template *template)
3345 {
3346   const char *l = line;
3347   bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
3348   bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1;
3349   size_t regs_read = 0;
3350   const metag_reg *regs[16];
3351   unsigned int lowest_data_reg = 0xffffffff;
3352   unsigned int lowest_fpu_reg = 0xffffffff;
3353   unsigned int rmask = 0, data_unit;
3354   size_t i;
3355   int last_reg = -1;
3356 
3357   if (insn->fpu_width != FPU_WIDTH_SINGLE)
3358     return NULL;
3359 
3360   l = parse_gp_regs_list (l, regs, 16, &regs_read);
3361 
3362   if (l == NULL)
3363     return NULL;
3364 
3365   if (regs_read % 2)
3366     return NULL;
3367 
3368   if (to_fpu)
3369     {
3370       for (i = 0; i < regs_read / 2; i++)
3371 	{
3372 	  if (regs[i]->unit != UNIT_FX)
3373 	    return NULL;
3374 
3375 	  if (last_reg == -1)
3376 	    {
3377 	      last_reg = regs[i]->no;
3378 	      lowest_fpu_reg = last_reg;
3379 	    }
3380 	  else
3381 	    {
3382 	      if (is_mmovl)
3383 		{
3384 		  if (regs[i]->no != (unsigned int)(last_reg + 2))
3385 		    return NULL;
3386 		}
3387 	      else if (regs[i]->no != (unsigned int)(last_reg + 1))
3388 		return NULL;
3389 
3390 	      last_reg = regs[i]->no;
3391 	    }
3392 	}
3393 
3394       if (regs[i]->unit == UNIT_D0)
3395 	data_unit = 0;
3396       else if (regs[i]->unit == UNIT_D1)
3397 	data_unit = 1;
3398       else
3399 	return NULL;
3400 
3401       if (!check_rmask (&regs[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3402 			&rmask))
3403 	return NULL;
3404     }
3405   else
3406     {
3407       if (regs[0]->unit == UNIT_D0)
3408 	data_unit = 0;
3409       else if (regs[0]->unit == UNIT_D1)
3410 	data_unit = 1;
3411       else
3412 	return NULL;
3413 
3414       if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3415 			&rmask))
3416 	return NULL;
3417 
3418       for (i = regs_read / 2; i < regs_read; i++)
3419 	{
3420 	  if (regs[i]->unit != UNIT_FX)
3421 	    return NULL;
3422 
3423 	  if (last_reg == -1)
3424 	    {
3425 	      last_reg = regs[i]->no;
3426 	      lowest_fpu_reg = last_reg;
3427 	    }
3428 	  else
3429 	    {
3430 	      if (is_mmovl)
3431 		{
3432 		  if (regs[i]->no != (unsigned int)(last_reg + 2))
3433 		    return NULL;
3434 		}
3435 	      else if (regs[i]->no != (unsigned int)(last_reg + 1))
3436 		return NULL;
3437 
3438 	      last_reg = regs[i]->no;
3439 	    }
3440 	}
3441     }
3442 
3443   insn->bits = (template->meta_opcode |
3444 		((lowest_data_reg & REG_MASK) << 19) |
3445 		((lowest_fpu_reg & REG_MASK) << 14) |
3446 		((rmask & RMASK_MASK) << 7) |
3447 		data_unit);
3448 
3449   insn->len = 4;
3450   return l;
3451 }
3452 
3453 /* Parse an FPU data unit MOV instruction.  */
3454 static const char *
parse_fmov_data(const char * line,metag_insn * insn,const insn_template * template)3455 parse_fmov_data (const char *line, metag_insn *insn,
3456 	    const insn_template *template)
3457 {
3458   const char *l = line;
3459   unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1);
3460   const metag_reg *regs[2];
3461   unsigned int base_unit;
3462 
3463   if (insn->fpu_width == FPU_WIDTH_PAIR)
3464     return NULL;
3465 
3466   l = parse_gp_regs (l, regs, 2);
3467 
3468   if (l == NULL)
3469     return NULL;
3470 
3471   if (to_fpu)
3472     {
3473       if (regs[0]->unit != UNIT_FX)
3474 	return NULL;
3475 
3476       if (regs[1]->unit == UNIT_D0)
3477 	base_unit = 0;
3478       else if (regs[1]->unit == UNIT_D1)
3479 	base_unit = 1;
3480       else
3481 	return NULL;
3482     }
3483   else
3484     {
3485       if (regs[0]->unit == UNIT_D0)
3486 	base_unit = 0;
3487       else if (regs[0]->unit == UNIT_D1)
3488 	base_unit = 1;
3489       else
3490 	return NULL;
3491 
3492       if (regs[1]->unit != UNIT_FX)
3493 	return NULL;
3494     }
3495 
3496   insn->bits = (template->meta_opcode |
3497 		(base_unit << 24) |
3498 		(regs[0]->no << 19) |
3499 		(regs[1]->no << 9));
3500 
3501   insn->len = 4;
3502   return l;
3503 }
3504 
3505 /* Parse an FPU immediate MOV instruction.  */
3506 static const char *
parse_fmov_i(const char * line,metag_insn * insn,const insn_template * template)3507 parse_fmov_i (const char *line, metag_insn *insn,
3508 	      const insn_template *template)
3509 {
3510   const char *l = line;
3511   const metag_reg *regs[1];
3512   int value = 0;
3513 
3514   l = parse_fpu_regs (l, regs, 1);
3515 
3516   l = skip_comma (l);
3517 
3518   if (l == NULL ||
3519       *l == END_OF_INSN)
3520     return NULL;
3521 
3522   l = parse_imm16 (l, insn, &value);
3523 
3524   if (l == NULL)
3525     return NULL;
3526 
3527   insn->bits = (template->meta_opcode |
3528 		(regs[0]->no << 19) |
3529 		((value & IMM16_MASK) << 3));
3530 
3531   if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3532     insn->bits |= (1 << 1);
3533   else if (insn->fpu_width == FPU_WIDTH_PAIR)
3534     insn->bits |= (1 << 2);
3535 
3536   insn->len = 4;
3537   return l;
3538 }
3539 
3540 /* Parse an FPU PACK instruction.  */
3541 static const char *
parse_fpack(const char * line,metag_insn * insn,const insn_template * template)3542 parse_fpack (const char *line, metag_insn *insn,
3543 	     const insn_template *template)
3544 {
3545   const char *l = line;
3546   const metag_reg *regs[3];
3547 
3548   l = parse_fpu_regs (l, regs, 3);
3549 
3550   if (l == NULL)
3551     return NULL;
3552 
3553   if (regs[0]->no % 2)
3554     {
3555       as_bad (_("destination register should be even numbered"));
3556       return NULL;
3557     }
3558 
3559   insn->bits = (template->meta_opcode |
3560 		(regs[0]->no << 19) |
3561 		(regs[1]->no << 14) |
3562 		(regs[2]->no << 9));
3563 
3564   insn->len = 4;
3565   return l;
3566 }
3567 
3568 /* Parse an FPU SWAP instruction.  */
3569 static const char *
parse_fswap(const char * line,metag_insn * insn,const insn_template * template)3570 parse_fswap (const char *line, metag_insn *insn,
3571 	     const insn_template *template)
3572 {
3573   const char *l = line;
3574   const metag_reg *regs[2];
3575 
3576   if (insn->fpu_width != FPU_WIDTH_PAIR)
3577     return NULL;
3578 
3579   l = parse_fpu_regs (l, regs, 2);
3580 
3581   if (l == NULL)
3582     return NULL;
3583 
3584   if (regs[0]->no % 2)
3585     return NULL;
3586 
3587   if (regs[1]->no % 2)
3588     return NULL;
3589 
3590   insn->bits = (template->meta_opcode |
3591 		(regs[0]->no << 19) |
3592 		(regs[1]->no << 14));
3593 
3594   insn->len = 4;
3595   return l;
3596 }
3597 
3598 /* Parse an FPU CMP instruction.  */
3599 static const char *
parse_fcmp(const char * line,metag_insn * insn,const insn_template * template)3600 parse_fcmp (const char *line, metag_insn *insn,
3601 	    const insn_template *template)
3602 {
3603   const char *l = line, *l2;
3604   const metag_reg *regs1[1];
3605   const metag_reg *regs2[1];
3606 
3607   l = parse_fpu_regs (l, regs1, 1);
3608 
3609   l = skip_comma (l);
3610 
3611   if (l == NULL ||
3612       *l == END_OF_INSN)
3613     return NULL;
3614 
3615   l2 = parse_fpu_regs (l, regs2, 1);
3616 
3617   if (l2 != NULL)
3618     {
3619       insn->bits = (regs2[0]->no << 9);
3620     }
3621   else
3622     {
3623       int constant = 0;
3624       l2 = parse_imm_constant (l, insn, &constant);
3625       if (!l2 || constant != 0)
3626 	{
3627 	  as_bad (_("comparison must be with register or #0"));
3628 	  return NULL;
3629 	}
3630       insn->bits = (1 << 8);
3631     }
3632 
3633   insn->bits |= (template->meta_opcode |
3634 		 (regs1[0]->no << 14));
3635 
3636   if (insn->fpu_action_flags & FPU_ACTION_ABS)
3637     insn->bits |= (1 << 19);
3638 
3639   if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3640     insn->bits |= (1 << 7);
3641 
3642   if (insn->fpu_width == FPU_WIDTH_PAIR)
3643     insn->bits |= (1 << 6);
3644   else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3645     insn->bits |= (1 << 5);
3646 
3647   insn->len = 4;
3648   return l2;
3649 }
3650 
3651 /* Parse an FPU MIN or MAX instruction.  */
3652 static const char *
parse_fminmax(const char * line,metag_insn * insn,const insn_template * template)3653 parse_fminmax (const char *line, metag_insn *insn,
3654 	       const insn_template *template)
3655 {
3656   const char *l = line;
3657   const metag_reg *regs[3];
3658 
3659   l = parse_fpu_regs (l, regs, 3);
3660 
3661   if (l == NULL)
3662     return NULL;
3663 
3664   insn->bits = (template->meta_opcode |
3665 		(regs[0]->no << 19) |
3666 		(regs[1]->no << 14) |
3667 		(regs[2]->no << 9));
3668 
3669   if (insn->fpu_width == FPU_WIDTH_PAIR)
3670     insn->bits |= (1 << 6);
3671   else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3672     insn->bits |= (1 << 5);
3673 
3674   insn->len = 4;
3675   return l;
3676 }
3677 
3678 /* Parse an FPU data conversion instruction.  */
3679 static const char *
parse_fconv(const char * line,metag_insn * insn,const insn_template * template)3680 parse_fconv (const char *line, metag_insn *insn,
3681 	     const insn_template *template)
3682 {
3683   const char *l = line;
3684   const metag_reg *regs[2];
3685 
3686   if (insn->fpu_width == FPU_WIDTH_PAIR)
3687     {
3688       if (strncasecmp (template->name, "FTOH", 4) &&
3689 	  strncasecmp (template->name, "HTOF", 4) &&
3690 	  strncasecmp (template->name, "FTOI", 4) &&
3691 	  strncasecmp (template->name, "ITOF", 4))
3692 	{
3693 	  as_bad (_("instruction cannot operate on pair values"));
3694 	  return NULL;
3695 	}
3696     }
3697 
3698   if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3699     {
3700       if (strncasecmp (template->name, "FTOI", 4) &&
3701 	  strncasecmp (template->name, "DTOI", 4) &&
3702 	  strncasecmp (template->name, "DTOL", 4))
3703 	{
3704 	  as_bad (_("zero flag is not valid for this instruction"));
3705 	  return NULL;
3706 	}
3707     }
3708 
3709   l = parse_fpu_regs (l, regs, 2);
3710 
3711   if (l == NULL)
3712     return NULL;
3713 
3714   if (!strncasecmp (template->name, "DTOL", 4) ||
3715       !strncasecmp (template->name, "LTOD", 4))
3716     {
3717       if (regs[0]->no % 2)
3718 	{
3719 	  as_bad (_("destination register should be even numbered"));
3720 	  return NULL;
3721 	}
3722 
3723       if (regs[1]->no % 2)
3724 	{
3725 	  as_bad (_("source register should be even numbered"));
3726 	  return NULL;
3727 	}
3728     }
3729 
3730   insn->bits = (template->meta_opcode |
3731 		(regs[0]->no << 19) |
3732 		(regs[1]->no << 14));
3733 
3734   if (insn->fpu_width == FPU_WIDTH_PAIR)
3735     insn->bits |= (1 << 6);
3736 
3737   if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3738     insn->bits |= (1 << 12);
3739 
3740   insn->len = 4;
3741   return l;
3742 }
3743 
3744 /* Parse an FPU extended data conversion instruction.  */
3745 static const char *
parse_fconvx(const char * line,metag_insn * insn,const insn_template * template)3746 parse_fconvx (const char *line, metag_insn *insn,
3747 	      const insn_template *template)
3748 {
3749   const char *l = line;
3750   const metag_reg *regs[2];
3751   int fraction_bits = 0;
3752 
3753   if (insn->fpu_width == FPU_WIDTH_PAIR)
3754     {
3755       if (strncasecmp (template->name, "FTOX", 4) &&
3756 	  strncasecmp (template->name, "XTOF", 4))
3757 	{
3758 	  as_bad (_("instruction cannot operate on pair values"));
3759 	  return NULL;
3760 	}
3761     }
3762 
3763   l = parse_fpu_regs (l, regs, 2);
3764 
3765   l = skip_comma (l);
3766 
3767   if (l == NULL ||
3768       *l == END_OF_INSN)
3769     return NULL;
3770 
3771   l = parse_imm_constant (l, insn, &fraction_bits);
3772 
3773   if (l == NULL)
3774     return NULL;
3775 
3776   insn->bits = (template->meta_opcode |
3777 		(regs[0]->no << 19) |
3778 		(regs[1]->no << 14));
3779 
3780   if (strncasecmp (template->name, "DTOXL", 5) &&
3781       strncasecmp (template->name, "XLTOD", 5))
3782     {
3783       if (!within_unsigned_range (fraction_bits, IMM5_BITS))
3784 	{
3785 	  as_bad (_("fraction bits value out of range"));
3786 	  return NULL;
3787 	}
3788       insn->bits |= ((fraction_bits & IMM5_MASK) << 9);
3789     }
3790   else
3791     {
3792       if (!within_unsigned_range (fraction_bits, IMM6_BITS))
3793 	{
3794 	  as_bad (_("fraction bits value out of range"));
3795 	  return NULL;
3796 	}
3797       insn->bits |= ((fraction_bits & IMM6_MASK) << 8);
3798     }
3799 
3800   if (insn->fpu_width == FPU_WIDTH_PAIR)
3801     insn->bits |= (1 << 6);
3802 
3803   insn->len = 4;
3804   return l;
3805 }
3806 
3807 /* Parse an FPU basic arithmetic instruction.  */
3808 static const char *
parse_fbarith(const char * line,metag_insn * insn,const insn_template * template)3809 parse_fbarith (const char *line, metag_insn *insn,
3810 	       const insn_template *template)
3811 {
3812   const char *l = line;
3813   const metag_reg *regs[3];
3814 
3815   l = parse_fpu_regs (l, regs, 3);
3816 
3817   if (l == NULL)
3818     return NULL;
3819 
3820   insn->bits = (template->meta_opcode |
3821 		(regs[0]->no << 19) |
3822 		(regs[1]->no << 14) |
3823 		(regs[2]->no << 9));
3824 
3825   if (insn->fpu_width == FPU_WIDTH_PAIR)
3826     insn->bits |= (1 << 6);
3827   else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3828     insn->bits |= (1 << 5);
3829 
3830   if (insn->fpu_action_flags & FPU_ACTION_INV)
3831     insn->bits |= (1 << 7);
3832 
3833   insn->len = 4;
3834   return l;
3835 }
3836 
3837 /* Parse a floating point accumulator name.  */
3838 static const char *
parse_acf(const char * line,int * part)3839 parse_acf (const char *line, int *part)
3840 {
3841   const char *l = line;
3842   size_t i;
3843 
3844   for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++)
3845     {
3846       const metag_acf *acf = &metag_acftab[i];
3847       size_t name_len = strlen (acf->name);
3848 
3849       if (strncasecmp (l, acf->name, name_len) == 0)
3850 	{
3851 	  l += name_len;
3852 	  *part = acf->part;
3853 	  return l;
3854 	}
3855     }
3856   return NULL;
3857 }
3858 
3859 /* Parse an FPU extended arithmetic instruction.  */
3860 static const char *
parse_fearith(const char * line,metag_insn * insn,const insn_template * template)3861 parse_fearith (const char *line, metag_insn *insn,
3862 	       const insn_template *template)
3863 {
3864   const char *l = line;
3865   const metag_reg *regs[3];
3866   bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 &&
3867 			((template->meta_opcode >> 4) & 0x1));
3868   unsigned int is_o3o = template->meta_opcode & 0x1;
3869   unsigned int is_mac = 0;
3870   unsigned int is_maw = 0;
3871 
3872   if (!strncasecmp (template->name, "MAW", 3))
3873     is_maw = 1;
3874 
3875   if (!strncasecmp (template->name, "MAC", 3))
3876     {
3877       int part;
3878       l = parse_acf (l, &part);
3879 
3880       if (l == NULL || part != 0)
3881 	return NULL;
3882 
3883       l = skip_comma (l);
3884 
3885       l = parse_fpu_regs (l, &regs[1], 2);
3886 
3887       is_mac = 1;
3888     }
3889   else
3890     {
3891       if (is_o3o && is_maw)
3892 	l = parse_fpu_regs (l, regs, 2);
3893       else
3894 	l = parse_fpu_regs (l, regs, 3);
3895     }
3896 
3897   if (l == NULL)
3898     return NULL;
3899 
3900   if (is_o3o && is_maw)
3901     insn->bits = (template->meta_opcode |
3902 		  (regs[1]->no << 9));
3903   else
3904     insn->bits = (template->meta_opcode |
3905 		  (regs[1]->no << 14));
3906 
3907   if (!(is_o3o && is_maw))
3908     insn->bits |= (regs[2]->no << 9);
3909 
3910   if (is_o3o && is_maw)
3911     insn->bits |= (regs[0]->no << 14);
3912   else if (!is_mac)
3913     insn->bits |= (regs[0]->no << 19);
3914 
3915   if (insn->fpu_width == FPU_WIDTH_PAIR)
3916     insn->bits |= (1 << 6);
3917   else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3918     insn->bits |= (1 << 5);
3919 
3920   if (!is_mac && !is_maw)
3921     if (insn->fpu_action_flags & FPU_ACTION_INV)
3922       insn->bits |= (1 << 7);
3923 
3924   if (is_muz)
3925     if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3926       insn->bits |= (1 << 1);
3927 
3928   insn->len = 4;
3929   return l;
3930 }
3931 
3932 /* Parse an FPU RCP or RSQ instruction.  */
3933 static const char *
parse_frec(const char * line,metag_insn * insn,const insn_template * template)3934 parse_frec (const char *line, metag_insn *insn,
3935 	    const insn_template *template)
3936 {
3937   const char *l = line;
3938   const metag_reg *regs[2];
3939 
3940   l = parse_fpu_regs (l, regs, 2);
3941 
3942   if (l == NULL)
3943     return NULL;
3944 
3945   insn->bits = (template->meta_opcode |
3946 		(regs[0]->no << 19) |
3947 		(regs[1]->no << 14));
3948 
3949   if (insn->fpu_width == FPU_WIDTH_PAIR)
3950     insn->bits |= (1 << 6);
3951   else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3952     insn->bits |= (1 << 5);
3953 
3954   if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3955     insn->bits |= (1 << 10);
3956   else if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3957     insn->bits |= (1 << 9);
3958 
3959   if (insn->fpu_action_flags & FPU_ACTION_INV)
3960     insn->bits |= (1 << 7);
3961 
3962   insn->len = 4;
3963   return l;
3964 }
3965 
3966 /* Parse an FPU vector arithmetic instruction.  */
3967 static const char *
parse_fsimd(const char * line,metag_insn * insn,const insn_template * template)3968 parse_fsimd (const char *line, metag_insn *insn,
3969 	     const insn_template *template)
3970 {
3971   const char *l = line;
3972   const metag_reg *regs[3];
3973 
3974   if (insn->fpu_width != FPU_WIDTH_PAIR)
3975     {
3976       as_bad (_("simd instructions operate on pair values (L prefix)"));
3977       return NULL;
3978     }
3979 
3980   l = parse_fpu_regs (l, regs, 3);
3981 
3982   if (l == NULL)
3983     return NULL;
3984 
3985   if (regs[0]->no % 2)
3986     {
3987       as_bad (_("destination register should be even numbered"));
3988       return NULL;
3989     }
3990 
3991   if ((regs[1]->no % 2) ||
3992       (regs[2]->no % 2))
3993     {
3994       as_bad (_("source registers should be even numbered"));
3995       return NULL;
3996     }
3997 
3998   insn->bits = (template->meta_opcode |
3999 		(regs[0]->no << 19) |
4000 		(regs[1]->no << 14) |
4001 		(regs[2]->no << 9));
4002 
4003   if (insn->fpu_action_flags & FPU_ACTION_INV)
4004     insn->bits |= (1 << 7);
4005 
4006   insn->len = 4;
4007   return l;
4008 }
4009 
4010 /* Parse an FPU accumulator GET or SET instruction. */
4011 static const char *
parse_fget_set_acf(const char * line,metag_insn * insn,const insn_template * template)4012 parse_fget_set_acf (const char *line, metag_insn *insn,
4013 		    const insn_template *template)
4014 {
4015   const char *l = line;
4016   int part;
4017   metag_addr addr;
4018   bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
4019 
4020   memset(&addr, 0, sizeof(addr));
4021   addr.reloc_type = BFD_RELOC_UNUSED;
4022 
4023   if (is_get)
4024     {
4025       l = parse_acf (l, &part);
4026 
4027       l = skip_comma (l);
4028 
4029       if (l == NULL)
4030 	return NULL;
4031 
4032       l = parse_mget_mset_addr (l, &addr);
4033     }
4034   else
4035     {
4036       l = parse_mget_mset_addr (l, &addr);
4037 
4038       l = skip_comma (l);
4039 
4040       if (l == NULL)
4041 	return NULL;
4042 
4043       l = parse_acf (l, &part);
4044     }
4045 
4046   if (l == NULL)
4047     return NULL;
4048 
4049   insn->bits = (template->meta_opcode |
4050 		(part << 19));
4051 
4052   if (!is_short_unit (addr.base_reg->unit))
4053     {
4054       as_bad (_("base unit must be one of %s"), SHORT_UNITS);
4055       return NULL;
4056     }
4057 
4058   insn->bits |= ((addr.base_reg->no << 14) |
4059 		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
4060 
4061   insn->len = 4;
4062   return l;
4063 }
4064 
4065 /* Copy the name of the next register in LINE to REG_BUF.  */
4066 static size_t
strip_reg_name(const char * line,char * reg_buf)4067 strip_reg_name(const char *line, char *reg_buf)
4068 {
4069   const char *l = line;
4070   size_t len = 0;
4071 
4072   while (is_register_char (*l))
4073     {
4074       reg_buf[len] = *l;
4075       l++;
4076       len++;
4077       if (!(len < MAX_REG_LEN))
4078 	return 0;
4079     }
4080 
4081   if (len)
4082     reg_buf[len] = '\0';
4083 
4084   return len;
4085 }
4086 
4087 /* Parse a DSP register from LINE into REG using only the registers
4088    from DSP_REGTAB. Return the next character or NULL.  */
4089 static const char *
__parse_dsp_reg(const char * line,const metag_reg ** reg,htab_t dsp_regtab)4090 __parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab)
4091 {
4092   const char *l = line;
4093   char name[MAX_REG_LEN];
4094   size_t len = 0;
4095   metag_reg entry;
4096   const metag_reg *_reg;
4097 
4098   /* We don't entirely strip the register name because we might
4099      actually want to match whole string in the register table,
4100      e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4101      entry limits our comaprison to a reasonable bound anyway.  */
4102   while (is_register_char (*l) || *l == PLUS)
4103     {
4104       name[len] = *l;
4105       l++;
4106       len++;
4107       if (!(len < MAX_REG_LEN))
4108 	return NULL;
4109     }
4110 
4111   if (!len)
4112     return NULL;
4113 
4114   name[len] = '\0';
4115   entry.name = name;
4116 
4117   _reg = (const metag_reg *) htab_find (dsp_regtab, &entry);
4118   if (!_reg)
4119     return NULL;
4120 
4121   *reg = _reg;
4122 
4123   return l;
4124 }
4125 
4126 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4127    member is suitable for encoding into a DSP insn register field.  */
4128 static const char *
parse_dsp_insn_reg(const char * line,const metag_reg ** reg)4129 parse_dsp_insn_reg (const char *line, const metag_reg **reg)
4130 {
4131   return __parse_dsp_reg (line, reg, dsp_reg_htab);
4132 }
4133 
4134 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4135    member is suitable for encoding into a DSP template definition insn
4136    register field.
4137 
4138    There is a separate table for whether we're doing a load or a store
4139    definition. "load" specifies which table to look at.  */
4140 static const char *
parse_dsp_template_reg(const char * line,const metag_reg ** reg,bfd_boolean load)4141 parse_dsp_template_reg (const char *line, const metag_reg **reg,
4142 			bfd_boolean load)
4143 {
4144   return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]);
4145 }
4146 
4147 /* Parse a single DSP register from LINE.  */
4148 static const char *
parse_dsp_reg(const char * line,const metag_reg ** reg,bfd_boolean tmpl,bfd_boolean load)4149 parse_dsp_reg (const char *line, const metag_reg **reg,
4150 	       bfd_boolean tmpl, bfd_boolean load)
4151 {
4152   if (tmpl)
4153     return parse_dsp_template_reg (line, reg, load);
4154   else
4155     return parse_dsp_insn_reg (line, reg);
4156 }
4157 
4158 /* Return TRUE if UNIT is an address unit.  */
4159 static bfd_boolean
is_addr_unit(enum metag_unit unit)4160 is_addr_unit (enum metag_unit unit)
4161 {
4162   switch (unit)
4163     {
4164     case UNIT_A0:
4165     case UNIT_A1:
4166       return TRUE;
4167     default:
4168       return FALSE;
4169     }
4170 }
4171 
4172 /* Return TRUE if UNIT1 and UNIT2 are equivalent units.  */
4173 static bfd_boolean
is_same_data_unit(enum metag_unit unit1,enum metag_unit unit2)4174 is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2)
4175 {
4176   if (unit1 == unit2)
4177     return TRUE;
4178 
4179   switch (unit1)
4180     {
4181     case UNIT_D0:
4182       if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0)
4183 	return TRUE;
4184       break;
4185     case UNIT_D1:
4186       if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1)
4187 	return TRUE;
4188       break;
4189     case UNIT_ACC_D0:
4190       if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0)
4191 	return TRUE;
4192       break;
4193     case UNIT_ACC_D1:
4194       if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1)
4195 	return TRUE;
4196       break;
4197     case UNIT_RAM_D0:
4198       if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0)
4199 	return TRUE;
4200       break;
4201     case UNIT_RAM_D1:
4202       if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1)
4203 	return TRUE;
4204       break;
4205     default:
4206       return FALSE;
4207     }
4208 
4209   return FALSE;
4210 }
4211 
4212 /* Return TRUE if the register NUM is a quickrot control register.  */
4213 static bfd_boolean
is_quickrot_reg(unsigned int num)4214 is_quickrot_reg (unsigned int num)
4215 {
4216   switch (num)
4217     {
4218     case 2:
4219     case 3:
4220       return TRUE;
4221     }
4222 
4223   return FALSE;
4224 }
4225 
4226 /* Return TRUE if REG is an accumulator register.  */
4227 static bfd_boolean
is_accumulator_reg(const metag_reg * reg)4228 is_accumulator_reg (const metag_reg *reg)
4229 {
4230   if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1)
4231     return TRUE;
4232 
4233   return FALSE;
4234 }
4235 
4236 /* Return TRUE if REG is a DSP RAM register.  */
4237 static bfd_boolean
is_dspram_reg(const metag_reg * reg)4238 is_dspram_reg (const metag_reg *reg)
4239 {
4240   if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1)
4241       return TRUE;
4242 
4243   return FALSE;
4244 }
4245 
4246 static const char *
__parse_gp_reg(const char * line,const metag_reg ** reg,bfd_boolean load)4247 __parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load)
4248 {
4249   const char *l = line;
4250   char reg_buf[MAX_REG_LEN];
4251   size_t len = 0;
4252 
4253   if (l == NULL)
4254     return NULL;
4255 
4256   /* Parse [DSPRAM.x].  */
4257   if (*l == ADDR_BEGIN_CHAR)
4258     {
4259       l++;
4260 
4261       if (l == NULL)
4262 	return NULL;
4263 
4264       l = parse_dsp_reg (l, reg, TRUE, load);
4265       if (l == NULL)
4266 	return NULL;
4267 
4268       if (*l == ADDR_END_CHAR)
4269 	l++;
4270       else
4271 	{
4272 	  as_bad (_("expected ']', not %c in %s"), *l, l);
4273 	  return NULL;
4274 	}
4275 
4276       return l;
4277     }
4278   else
4279     {
4280 
4281       len = strip_reg_name (l, reg_buf);
4282       if (!len)
4283 	return NULL;
4284 
4285       l += len;
4286       *reg = parse_gp_reg (reg_buf);
4287       if (*reg == NULL)
4288 	return NULL;
4289     }
4290 
4291   return l;
4292 }
4293 
4294 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4295    should try to parse the register as a general-purpose register if
4296    we fail to parse it as a DSP one. TMPL indicates whether the
4297    registers are part of a template definition instruction. If this is
4298    a template definition instruction LOAD says whether it's a load
4299    template insn. FIRST_DST indicates whether the first register is
4300    a destination operand.  */
4301 static const char *
parse_dsp_regs_list(const char * line,const metag_reg ** regs,size_t count,size_t * regs_read,bfd_boolean try_gp,bfd_boolean tmpl,bfd_boolean load,bfd_boolean first_dst)4302 parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count,
4303 		     size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl,
4304 		     bfd_boolean load, bfd_boolean first_dst)
4305 {
4306   const char *l = line;
4307   int seen_regs = 0;
4308   size_t i;
4309   const metag_reg *reg;
4310 
4311   for (i = 0; i < count; i++)
4312     {
4313       const char *next, *ll;
4314 
4315       next = l;
4316 
4317       if (i > 0)
4318 	{
4319 	  l = skip_comma (l);
4320 	  if (l == NULL)
4321 	    {
4322 	      *regs_read = seen_regs;
4323 	      return next;
4324 	    }
4325 	}
4326 
4327       ll = parse_dsp_reg (l, &reg, tmpl, load);
4328 
4329       if (!ll)
4330 	{
4331 	  if (try_gp)
4332 	    {
4333 	      l = __parse_gp_reg (l, &reg, !(first_dst && i == 0));
4334 	      if (l == NULL)
4335 		{
4336 		  *regs_read = seen_regs;
4337 		  return next;
4338 		}
4339 	      regs[i] = reg;
4340 	      seen_regs++;
4341 	    }
4342 	  else
4343 	    {
4344 	      *regs_read = seen_regs;
4345 	      return l;
4346 	    }
4347 	}
4348       else
4349 	{
4350 	  regs[i] = reg;
4351 	  seen_regs++;
4352 	  l = ll;
4353 	}
4354     }
4355 
4356   *regs_read = seen_regs;
4357   return l;
4358 }
4359 
4360 /* Parse the following memory references:
4361 
4362      - [Ax.r]
4363      - [Ax.r++]
4364      - [Ax.r--]
4365      - [Ax.r+Ax.r++]
4366      - [Ax.r-Ax.r--]
4367 
4368      - [DSPRam]
4369      - [DSPRam++]
4370      - [DSPRam+DSPRam++]
4371      - [DSPRam-DSPRam--]  */
4372 static const char *
parse_dsp_addr(const char * line,metag_addr * addr,unsigned int size,bfd_boolean load)4373 parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size,
4374 		bfd_boolean load)
4375 {
4376   const char *l = line, *ll;
4377   const metag_reg *regs[1];
4378   size_t regs_read;
4379 
4380   /* Skip opening square bracket.  */
4381   l++;
4382 
4383   l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4384 
4385   if (l == NULL)
4386     return NULL;
4387 
4388   if (!is_addr_unit (regs[0]->unit) &&
4389       !is_dspram_reg (regs[0]))
4390     {
4391       as_bad (_("invalid register for memory access"));
4392       return NULL;
4393     }
4394 
4395   addr->base_reg = regs[0];
4396 
4397   if (*l == ADDR_END_CHAR)
4398     {
4399       addr->exp.X_op = O_constant;
4400       addr->exp.X_add_symbol = NULL;
4401       addr->exp.X_op_symbol = NULL;
4402 
4403       /* Simple register with no offset (0 immediate).  */
4404       addr->exp.X_add_number = 0;
4405 
4406       addr->immediate = 1;
4407       l++;
4408 
4409       return l;
4410     }
4411 
4412   ll = parse_addr_post_incr_op (l, addr);
4413 
4414   if (ll && *ll == ADDR_END_CHAR)
4415     {
4416       if (addr->update == 1)
4417 	{
4418 	  /* We have a post increment/decrement.  */
4419 	  addr->exp.X_op = O_constant;
4420 	  addr->exp.X_add_number = size;
4421 	  addr->exp.X_add_symbol = NULL;
4422 	  addr->exp.X_op_symbol = NULL;
4423 	  addr->post_increment = 1;
4424 	}
4425       addr->immediate = 1;
4426       ll++;
4427       return ll;
4428     }
4429 
4430   addr->post_increment = 0;
4431 
4432   l = parse_addr_op (l, addr);
4433 
4434   if (l == NULL)
4435     return NULL;
4436 
4437   l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4438 
4439   if (l == NULL)
4440     return NULL;
4441 
4442   if (regs[0]->unit != addr->base_reg->unit)
4443     {
4444       as_bad (_("offset and base must be from the same unit"));
4445       return NULL;
4446     }
4447 
4448   addr->offset_reg = regs[0];
4449 
4450   if (*l == ADDR_END_CHAR)
4451     {
4452       l++;
4453       return l;
4454     }
4455 
4456   l = parse_addr_post_incr_op (l, addr);
4457 
4458   if (l == NULL)
4459     return NULL;
4460 
4461   if (*l == ADDR_END_CHAR)
4462     {
4463       l++;
4464       return l;
4465     }
4466 
4467   return NULL;
4468 }
4469 
4470 /* Parse a DSP GET or SET instruction.  */
4471 static const char *
parse_dget_set(const char * line,metag_insn * insn,const insn_template * template)4472 parse_dget_set (const char *line, metag_insn *insn,
4473 		const insn_template *template)
4474 {
4475   const char *l = line;
4476   metag_addr addr;
4477   int unit = 0;
4478   int rd_reg = 0;
4479   bfd_boolean is_get = (template->meta_opcode & 0x100);
4480   bfd_boolean is_dual = (template->meta_opcode & 0x4);
4481   bfd_boolean is_template = FALSE;
4482   const metag_reg *regs[2];
4483   unsigned int size;
4484   size_t count, regs_read;
4485 
4486   memset(&addr, 0, sizeof(addr));
4487   addr.reloc_type = BFD_RELOC_UNUSED;
4488 
4489   size = is_dual ? 8 : 4;
4490   count = is_dual ? 2 : 1;
4491 
4492   if (is_get)
4493     {
4494       /* GETL can be used on one template table entry.  */
4495       if (*l == 'T')
4496 	count = 1;
4497 
4498       l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE,
4499 			       FALSE, FALSE, FALSE);
4500       l = skip_comma (l);
4501 
4502       if (l == NULL)
4503 	{
4504 	  as_bad (_("unexpected end of line"));
4505 	  return NULL;
4506 	}
4507 
4508       l = parse_addr (l, &addr, size);
4509     }
4510   else
4511     {
4512       l = parse_addr (l, &addr, size);
4513 
4514       l = skip_comma (l);
4515 
4516       if (l == NULL)
4517 	return NULL;
4518 
4519       /* GETL can be used on one template table entry.  */
4520       if (*l == 'T')
4521 	count = 1;
4522 
4523       l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE, FALSE,
4524 			       FALSE, FALSE);
4525     }
4526 
4527   if (l == NULL)
4528     return NULL;
4529 
4530   /* The first register dictates the unit.  */
4531   if (regs[0]->unit == UNIT_DT)
4532       is_template = TRUE;
4533   else
4534     {
4535       if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 ||
4536 	  regs[0]->unit == UNIT_ACC_D0)
4537 	unit = 0;
4538       else
4539 	unit = 1;
4540     }
4541 
4542   rd_reg = regs[0]->no;
4543 
4544   /* The 'H' modifier allows a DSP GET/SET instruction to target the
4545      upper 8-bits of an accumulator. It is _only_ valid for the
4546      accumulators.  */
4547   if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH)
4548     {
4549       if (is_template || !(rd_reg >= 16 && rd_reg < 20))
4550 	{
4551 	  as_bad (_("'H' modifier only valid for accumulator registers"));
4552 	  return NULL;
4553 	}
4554 
4555       /* Top 8-bits of the accumulator.  */
4556       rd_reg |= 8;
4557     }
4558 
4559   if (is_template)
4560     {
4561       insn->bits = (template->meta_opcode | (1 << 1));
4562     }
4563   else
4564     {
4565       insn->bits = (template->meta_opcode | unit);
4566     }
4567 
4568   insn->bits |= (rd_reg << 19);
4569 
4570   if (addr.immediate)
4571     {
4572       int offset = addr.exp.X_add_number;
4573 
4574       if (addr.negate)
4575 	offset = -offset;
4576 
4577       offset = offset / (int)size;
4578 
4579       if (!within_signed_range (offset, DGET_SET_IMM_BITS))
4580 	{
4581 	  as_bad (_("offset value out of range"));
4582 	  return NULL;
4583 	}
4584 
4585       offset = offset & DGET_SET_IMM_MASK;
4586 
4587       insn->bits |= (1 << 13);
4588       insn->bits |= (offset << 9);
4589     }
4590   else
4591     {
4592       int au = (addr.base_reg->unit == UNIT_A1);
4593 
4594       insn->bits |= (au << 18);
4595       insn->bits |= ((addr.base_reg->no & REG_MASK) << 14);
4596       insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9);
4597     }
4598 
4599   if (is_dual)
4600       insn->bits |= (1 << 2);
4601 
4602   if (!is_addr_unit (addr.base_reg->unit))
4603     {
4604       as_bad (_("base unit must be either A0 or A1"));
4605       return NULL;
4606     }
4607 
4608   unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1;
4609   insn->bits |= ((addr.base_reg->no << 14) | (unit << 18));
4610 
4611   insn->len = 4;
4612 
4613   return l;
4614 }
4615 
4616 /* Parse a DSP template instruction.  */
4617 static const char *
parse_dtemplate(const char * line,metag_insn * insn,const insn_template * template)4618 parse_dtemplate (const char *line, metag_insn *insn,
4619 		 const insn_template *template)
4620 {
4621   const char *l = line;
4622   const metag_reg *regs[TEMPLATE_NUM_REGS];
4623   bfd_boolean daop_only = FALSE;
4624   int regs_val[4];
4625   int regs_which[4] = { -1, -1, -1, -1};	/* Register or immediate?  */
4626   int i;
4627 
4628   for (i = 0; i < TEMPLATE_NUM_REGS; i++)
4629     {
4630       if (l == NULL)
4631 	{
4632 	  as_bad (_("unexpected end of line"));
4633 	  return NULL;
4634 	}
4635 
4636       /* We may only have 3 register operands.  */
4637       if (*l == END_OF_INSN && i == 3)
4638 	{
4639 	  daop_only = TRUE;
4640 	  break;
4641 	}
4642 
4643       if (i != 0)
4644 	{
4645 	  l = skip_comma (l);
4646 	  if (l == NULL)
4647 	    return NULL;
4648 	}
4649 
4650       if (*l == IMM_CHAR)
4651 	{
4652 	  l = parse_imm_constant (l, insn, &regs_val[i]);
4653 	  if (l == NULL)
4654 	    {
4655 	      as_bad (_("invalid immediate"));
4656 	      return NULL;
4657 	    }
4658 	  regs_which[i] = 0;
4659 	}
4660       else
4661 	{
4662 	  /* We can't tell from the template instantiation whether
4663 	     this is a load or store. So we have to try looking up the
4664 	     register name in both the load and store tables.  */
4665 	  const char *l2 = l;
4666 	  l = __parse_gp_reg (l, &regs[i], TRUE);
4667 	  if (l == NULL)
4668 	    {
4669 	      /* Try the store table too.  */
4670 	      l = __parse_gp_reg (l2, &regs[i], FALSE);
4671 	      if (l == NULL)
4672 		{
4673 		  /* Then try a DSP register.  */
4674 		  l = parse_dsp_insn_reg (l2, &regs[i]);
4675 		  if (l == NULL || regs[i]->unit == UNIT_DT)
4676 		    {
4677 		      as_bad (_("invalid register"));
4678 		      return NULL;
4679 		    }
4680 		}
4681 	    }
4682 	  regs_which[i] = 1;
4683 	}
4684     }
4685 
4686   insn->bits = template->meta_opcode;
4687 
4688   if (regs_which[0] == 0)
4689     insn->bits |= (regs_val[0] << 19);
4690   else if (regs_which[0] == 1)
4691     insn->bits |= (regs[0]->no << 19);
4692 
4693   if (regs_which[1] == 0)
4694     insn->bits |= (regs_val[1] << 14);
4695   else if (regs_which[1] == 1)
4696     insn->bits |= (regs[1]->no << 14);
4697 
4698   if (regs_which[2] == 0)
4699     insn->bits |= (regs_val[2] << 9);
4700   else if (regs_which[2] == 1)
4701     insn->bits |= (regs[2]->no << 9);
4702 
4703   if (regs_which[3] == 0)
4704     insn->bits |= (regs_val[3] << 4);
4705   else if (regs_which[3] == 1)
4706     insn->bits |= (regs[3]->no << 4);
4707 
4708   /* DaOp only.  */
4709   if (daop_only)
4710     insn->bits |= (0x3 << 24); /* Set the minor opcode.  */
4711   else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store.  */
4712     insn->bits |= (0x5 << 24); /* Set the minor opcode.  */
4713 
4714   insn->len = 4;
4715 
4716   return l;
4717 }
4718 
4719 /* Parse a DSP Template definiton memory reference, e.g
4720    [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4721    template definition is a DSP RAM template definition.  */
4722 static const char *
template_mem_ref(const char * line,metag_addr * addr,bfd_boolean * dspram,int size,bfd_boolean load)4723 template_mem_ref(const char *line, metag_addr *addr,
4724 		 bfd_boolean *dspram, int size, bfd_boolean load)
4725 {
4726   const char *l = line;
4727 
4728   l = parse_dsp_addr (l, addr, size, load);
4729 
4730   if (l != NULL)
4731     {
4732       if (is_addr_unit(addr->base_reg->unit))
4733 	*dspram = FALSE;
4734       else
4735 	*dspram = TRUE;
4736     }
4737 
4738   return l;
4739 }
4740 
4741 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4742    it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT.  */
4743 static const char *
parse_template_regs(const char * line,bfd_boolean * load,unsigned int * addr_unit,const metag_reg ** template_reg,metag_addr * addr,bfd_boolean * dspram,int size)4744 parse_template_regs (const char *line, bfd_boolean *load,
4745 		     unsigned int *addr_unit,
4746 		     const metag_reg **template_reg, metag_addr *addr,
4747 		     bfd_boolean *dspram, int size)
4748 {
4749   const char *l = line;
4750 
4751   if (l == NULL)
4752     return NULL;
4753 
4754   /* DSP Template load definition (Tx, [Ax]) */
4755   if (*l == 'T')
4756     {
4757       *load = TRUE;
4758       l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4759       if (l == NULL)
4760 	return NULL;
4761 
4762       l = skip_comma (l);
4763 
4764       l = template_mem_ref (l, addr, dspram, size, *load);
4765 
4766       if (addr->base_reg->unit == UNIT_A1)
4767 	*addr_unit = 1;
4768 
4769     }
4770   else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */
4771     {
4772       *load = FALSE;
4773       l = template_mem_ref (l, addr, dspram, size, *load);
4774       l = skip_comma(l);
4775 
4776       if (l == NULL)
4777 	return NULL;
4778 
4779       l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4780       if (l == NULL)
4781 	return NULL;
4782 
4783       if (addr->base_reg->unit == UNIT_A1)
4784 	*addr_unit = 1;
4785     }
4786   else
4787     {
4788       as_bad (_("invalid register operand"));
4789       return NULL;
4790     }
4791 
4792   return l;
4793 }
4794 
4795 #define INVALID_SHIFT (-1)
4796 
4797 static metag_reg _reg;
4798 
4799 /* Parse a template instruction definition.  */
4800 static const char *
interpret_template_regs(const char * line,metag_insn * insn,const metag_reg ** regs,int * regs_shift,bfd_boolean * load,bfd_boolean * dspram,int size,int * ls_shift,int * au_shift,unsigned int * au,int * imm,int * imm_shift,unsigned int * imm_mask)4801 interpret_template_regs(const char *line, metag_insn *insn,
4802 			const metag_reg **regs,
4803 			int *regs_shift, bfd_boolean *load, bfd_boolean *dspram,
4804 			int size, int *ls_shift, int *au_shift,
4805 			unsigned int *au, int *imm, int *imm_shift,
4806 			unsigned int *imm_mask)
4807 {
4808   const char *l = line;
4809   metag_addr addr;
4810   const metag_reg *template_reg[1];
4811 
4812   memset (&addr, 0, sizeof(addr));
4813 
4814   regs_shift[0] = 19;
4815   regs_shift[1] = INVALID_SHIFT;
4816 
4817   insn->bits |= (1 << 1);
4818 
4819   l = skip_whitespace (l);
4820 
4821   l = parse_template_regs (l, load, au, template_reg,
4822 			   &addr, dspram, size);
4823   if (l == NULL)
4824     {
4825       as_bad (_("could not parse template definition"));
4826       return NULL;
4827     }
4828 
4829   regs[2] = template_reg[0];
4830   regs_shift[2] = 9;
4831 
4832   /* DSPRAM definition.  */
4833   if (*dspram)
4834     {
4835 
4836       _reg = *addr.base_reg;
4837 
4838       if (addr.immediate)
4839 	{
4840 	  /* Set the post-increment bit in the register field.  */
4841 	  if (addr.update)
4842 	    _reg.no |= 0x1;
4843 	}
4844       else
4845 	{
4846 	  /* The bottom bit of the increment register tells us
4847 	     whether it's increment register 0 or 1.  */
4848 	  if (addr.offset_reg->no & 0x1)
4849 	    _reg.no |= 0x3;
4850 	  else
4851 	    _reg.no |= 0x2;
4852 	}
4853 
4854       regs[0] = &_reg;
4855 
4856       insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition.  */
4857     }
4858   else /* DaOpPaMe definition.  */
4859     {
4860       regs[0] = addr.base_reg;
4861       if (addr.immediate)
4862 	{
4863 	  /* Set the I bit.  */
4864 	  insn->bits |= (1 << 18);
4865 
4866 	  if (addr.update == 1)
4867 	    {
4868 	      if (addr.negate == 1)
4869 		*imm = 0x3;
4870 	      else
4871 		*imm = 0x1;
4872 	    }
4873 
4874 	  *imm_shift = 14;
4875 	  *imm_mask = 0x3;
4876 	}
4877       else
4878 	{
4879 	  /* Setup the offset register.  */
4880 	  regs[1] = addr.offset_reg;
4881 	  regs_shift[1] = 14;
4882 	}
4883       *au_shift = 23;
4884     }
4885 
4886   *ls_shift = 13;
4887 
4888   return l;
4889 }
4890 
4891 /* Does this combination of units need the O2R bit and can it be encoded?  */
4892 static bfd_boolean
units_need_o2r(enum metag_unit unit1,enum metag_unit unit2)4893 units_need_o2r (enum metag_unit unit1, enum metag_unit unit2)
4894 {
4895   if (unit1 == unit2)
4896     return FALSE;
4897 
4898   if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0)
4899     {
4900       if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0)
4901 	return FALSE;
4902 
4903       switch (unit2)
4904 	{
4905 	case UNIT_A1:
4906 	case UNIT_D1:
4907 	case UNIT_RD:
4908 	case UNIT_A0:
4909 	  return TRUE;
4910 	default:
4911 	  return FALSE;
4912 	}
4913     }
4914 
4915   if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1)
4916     {
4917       if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1)
4918 	return FALSE;
4919 
4920       switch (unit2)
4921 	{
4922 	case UNIT_A1:
4923 	case UNIT_D0:
4924 	case UNIT_RD:
4925 	case UNIT_A0:
4926 	  return TRUE;
4927 	default:
4928 	  return FALSE;
4929 	}
4930     }
4931 
4932   return FALSE;
4933 }
4934 
4935 /* Return TRUE if this is a DSP data unit.  */
4936 static bfd_boolean
is_dsp_data_unit(const metag_reg * reg)4937 is_dsp_data_unit (const metag_reg *reg)
4938 {
4939   switch (reg->unit)
4940     {
4941     case UNIT_D0:
4942     case UNIT_D1:
4943     case UNIT_ACC_D0:
4944     case UNIT_ACC_D1:
4945     case UNIT_RAM_D0:
4946     case UNIT_RAM_D1:
4947       return TRUE;
4948     default:
4949       return FALSE;
4950     }
4951 }
4952 
4953 static metag_reg o2r_reg;
4954 
4955 /* Parse a DaOpPaMe load template definition.  */
4956 static const char *
parse_dalu(const char * line,metag_insn * insn,const insn_template * template)4957 parse_dalu (const char *line, metag_insn *insn,
4958 	    const insn_template *template)
4959 {
4960   const char *l = line;
4961   const char *ll;
4962   const metag_reg *regs[4];
4963   metag_addr addr;
4964   size_t regs_read;
4965   bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD;
4966   bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) &&
4967 			((template->meta_opcode & 0xee) == 0));
4968   bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL);
4969   bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0);
4970   int l1_shift = INVALID_SHIFT;
4971   bfd_boolean load = FALSE;
4972   int ls_shift = INVALID_SHIFT;
4973   bfd_boolean ar = FALSE;
4974   int ar_shift = INVALID_SHIFT;
4975   int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT };
4976   int imm = 0;
4977   int imm_shift = INVALID_SHIFT;
4978   unsigned int imm_mask = 0;
4979   unsigned int au = 0;
4980   int au_shift = INVALID_SHIFT;
4981   unsigned int du = 0;
4982   int du_shift = INVALID_SHIFT;
4983   unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0);
4984   int sc_shift = INVALID_SHIFT;
4985   unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0);
4986   int om_shift = INVALID_SHIFT;
4987   unsigned int o2r = 0;
4988   int o2r_shift = INVALID_SHIFT;
4989   unsigned int qr = 0;
4990   int qr_shift = INVALID_SHIFT;
4991   int qd_shift = INVALID_SHIFT;
4992   unsigned int qn = 0;
4993   int qn_shift = INVALID_SHIFT;
4994   unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0);
4995   int a1_shift = INVALID_SHIFT;
4996   unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0);
4997   int a2_shift = INVALID_SHIFT;
4998   unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0);
4999   int su_shift = INVALID_SHIFT;
5000   unsigned int ac;
5001   int ac_shift = INVALID_SHIFT;
5002   unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) ||
5003 		     (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0);
5004   int mx_shift = INVALID_SHIFT;
5005   int size = is_dual ? 8 : 4;
5006   bfd_boolean dspram;
5007   bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4);
5008 
5009   /* XFIXME: check the flags are valid with the instruction.  */
5010   if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR))
5011     {
5012       as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5013       return NULL;
5014     }
5015 
5016   insn->bits = template->meta_opcode;
5017 
5018   memset (regs, 0, sizeof (regs));
5019   memset (&addr, 0, sizeof (addr));
5020 
5021   /* There are the following forms of DSP ALU instructions,
5022 
5023    * Group 1:
5024       19. D[T]  Op    De.r,Dx.r,De.r
5025       1.  D[T]  Op    De.r,Dx.r,De.r|ACe.r	[Accumulator in src 2]
5026       3.  D[T]  Op    De.r,Dx.r,De.r[,Ae.r]	[QUICKRoT]
5027       2.  D[T]  Op    ACe.e,ACx.r,ACo.e		[cross-unit accumulator op]
5028       5.  D[T]  Op    De.r|ACe.r,Dx.r,De.r
5029       20. D[T]  Op    De.r,Dx.r|ACx.r,De.r
5030       8.  D     Opcc  De.r,Dx.r,Rx.r
5031       6.  D     Op    De.r,Dx.r,Rx.r|RD
5032       17. D     Op    De.r|ACe.r,Dx.r,Rx.r|RD
5033       7.  D     Op    De.e,Dx.r,#I16
5034 
5035    * Group 2:
5036       4.  D[T]  Op    Dx.r,De.r
5037       10. D     Op    Dx.r,Rx.r|RD
5038       13. D     Op    Dx.r,Rx.r
5039       11. D     Op    Dx.r,#I16
5040       12. D[T]  Op    De.r,Dx.r
5041       14. D     Op    DSPe.r,Dx.r
5042       15. D     Op    DSPx.r,#I16
5043       16. D     Op    De.r,DSPx.r
5044       18. D     Op    De.r,Dx.r|ACx.r
5045 
5046    * Group 3:
5047       22. D     Op    De.r,Dx.r|ACx.r,De.r|#I5
5048       23. D     Op    Ux.r,Dx.r|ACx.r,De.r|#I5
5049       21. D     Op    De.r,Dx.r|ACx.r,#I5  */
5050 
5051   /* Group 1.  */
5052   if (template->arg_type & DSP_ARGS_1)
5053     {
5054       du_shift = 24;
5055 
5056       /* Could this be a cross-unit accumulator op,
5057 	 e.g. ACe.e,ACx.r,ACo.e */
5058       if (template->arg_type & DSP_ARGS_XACC)
5059 	{
5060 	  ll = parse_dsp_regs_list (l, regs, 3, &regs_read, FALSE, FALSE,
5061 				    FALSE, FALSE);
5062 	  if (ll != NULL && regs_read == 3
5063 	      && is_accumulator_reg (regs[0]))
5064 	    {
5065 	      if (regs[0]->unit != regs[1]->unit ||
5066 		  regs[2]->unit == regs[1]->unit)
5067 		{
5068 		  as_bad (_("invalid operands for cross-unit op"));
5069 		  return NULL;
5070 		}
5071 
5072 	      du = (regs[1]->unit == UNIT_ACC_D1);
5073 	      regs_shift[1] = 19;
5074 	      l = ll;
5075 
5076 	      /* All cross-unit accumulator ops have bits 8 and 6 set.  */
5077 	      insn->bits |= (5 << 6);
5078 
5079 	      goto check_for_template;
5080 	    }
5081 
5082 	  /* If we reach here, this instruction is not a
5083 	     cross-unit accumulator op.  */
5084 	}
5085 
5086       if (template->arg_type & DSP_ARGS_SPLIT8)
5087 	om_shift = 7;
5088 
5089       sc_shift = 5;
5090       l1_shift = 4;
5091       o2r_shift = 0;
5092 
5093       /* De.r|ACe.r,Dx.r,De.r */
5094       if (template->arg_type & DSP_ARGS_DACC)
5095 	{
5096 	  /* XFIXME: these need moving?  */
5097 	  a2_shift = 7;
5098 	  su_shift = 6;
5099 	  a1_shift = 2;
5100 	  om_shift = 3;
5101 
5102 	  ll = parse_dsp_reg (l, &regs[0], FALSE, FALSE);
5103 	  if (ll != NULL)
5104 	    {
5105 	      /* Using ACe.r as the dst requires one of the P,N or Z
5106 		 flags to be used.  */
5107 	      if (!(insn->dsp_action_flags &
5108 		    (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5109 		{
5110 		  as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5111 		  return NULL;
5112 		}
5113 
5114 	      l = ll;
5115 	      l = skip_comma (l);
5116 	      l = parse_dsp_regs_list (l, &regs[1], 2, &regs_read,
5117 				       TRUE, FALSE, FALSE, FALSE);
5118 	      if (l == NULL || regs_read != 2)
5119 		{
5120 		  as_bad (_("invalid register"));
5121 		  return NULL;
5122 		}
5123 
5124 	      if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5125 		du = 1;
5126 
5127 	      regs_shift[0] = 19;
5128 	      regs_shift[1] = 14;
5129 	      regs_shift[2] = 9;
5130 	      goto check_for_template;
5131 	    }
5132 
5133 	  /* If we reach here, this instruction does not use the
5134 	     accumulator as the destination register.  */
5135 	  if ((insn->dsp_action_flags &
5136 	       (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5137 	    {
5138 	      as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5139 	      return NULL;
5140 	    }
5141 	}
5142 
5143       regs_shift[0] = 19;
5144 
5145 
5146       l = parse_dsp_regs_list (l, regs, 2, &regs_read, TRUE, FALSE, FALSE, TRUE);
5147       if (l == NULL || regs_read != 2)
5148 	return NULL;
5149 
5150       l = skip_comma (l);
5151       if (l == NULL)
5152 	return NULL;
5153 
5154       if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5155 	du = 1;
5156 
5157       if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC))
5158        {
5159 	 as_bad (_("accumulator not a valid destination"));
5160 	 return NULL;
5161        }
5162 
5163       /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5164       if (*l == IMM_CHAR)
5165 	{
5166 	  l = parse_imm16 (l, insn, &imm);
5167 	  if (l == NULL)
5168 	    {
5169 	      as_bad (_("invalid immediate value"));
5170 	      return NULL;
5171 	    }
5172 
5173 	  if (!within_signed_range (imm, IMM16_BITS))
5174 	    {
5175 	      as_bad (_("immediate value out of range"));
5176 	      return NULL;
5177 	    }
5178 
5179 	  if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no)
5180 	    {
5181 	      as_bad (_("immediate value not allowed when source & dest differ"));
5182 	      return NULL;
5183 	    }
5184 
5185 	  imm_mask = 0xffff;
5186 	  imm_shift = 3;
5187 
5188 	  /* Set the I-bit */
5189 	  insn->bits |= (1 << 25);
5190 
5191 	  insn->bits |= (0x3 << 0);
5192 
5193 	  l1_shift = 2;
5194 
5195 	  /* Remove any bits that have been set in the immediate
5196 	     field.  */
5197 	  insn->bits &= ~(imm_mask << imm_shift);
5198 	}
5199       else
5200 	{
5201 
5202 	  regs_shift[1] = 14;
5203 	  regs_shift[2] = 9;
5204 
5205 	  /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5206 	  ll = parse_dsp_reg (l, &regs[2], FALSE, FALSE);
5207 	  if (ll != NULL)
5208 	    {
5209 	      l = ll;
5210 
5211 	      if (!(template->arg_type & DSP_ARGS_ACC2))
5212 		{
5213 		  as_bad (_("invalid register operand: %s"), regs[2]->name);
5214 		  return NULL;
5215 		}
5216 
5217 	      om_shift = 3;
5218 	      ar_shift = 7;
5219 	      ar = TRUE;
5220 	    }
5221 	  else
5222 	    {
5223 	      /* De.r,Dx.r,De.r */
5224 	      l = __parse_gp_reg (l, &regs[2], TRUE);
5225 	      if (l == NULL)
5226 		return NULL;
5227 	    }
5228 
5229 	  if (template->arg_type & DSP_ARGS_ACC2)
5230 	    om_shift = 3;
5231 
5232 	  /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5233 	  if (template->arg_type & DSP_ARGS_QR)
5234 	    {
5235 	      if (conditional)
5236 		qn_shift = 5;
5237 	      else
5238 		{
5239 		  qn_shift = 7;
5240 		  qr_shift = 6;
5241 		  qd_shift = 5;
5242 		}
5243 
5244 	      l = skip_comma (l);
5245 	      if (l == NULL)
5246 		{
5247 		  as_bad (_("QUICKRoT extension requires 4 registers"));
5248 		  return NULL;
5249 		}
5250 
5251 	      l = __parse_gp_reg (l, &regs[3], TRUE);
5252 	      if (l == NULL)
5253 		{
5254 		  as_bad (_("invalid fourth register"));
5255 		  return NULL;
5256 		}
5257 
5258 	      if (!is_addr_unit (regs[3]->unit) ||
5259 		  !is_quickrot_reg (regs[3]->no))
5260 		{
5261 		  as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5262 		  return NULL;
5263 		}
5264 
5265 	      qn = (regs[3]->no == 3);
5266 	    }
5267 	}
5268 
5269     check_for_template:
5270       /* This is the common exit path. Check for o2r.  */
5271       if (regs[2] != NULL)
5272 	{
5273 	  o2r = units_need_o2r (regs[1]->unit, regs[2]->unit);
5274 	  if (o2r)
5275 	    {
5276 	      o2r_reg.no = lookup_o2r (0, du, regs[2]);
5277 	      o2r_reg.unit = regs[2]->unit;
5278 	      regs[2] = &o2r_reg;
5279 	    }
5280 	}
5281 
5282       /* Check any DSP RAM pointers are valid for this unit.  */
5283       if ((du && (regs[0]->unit == UNIT_RAM_D0)) ||
5284 	  (!du && (regs[0]->unit == UNIT_RAM_D1)) ||
5285 	  (du && (regs[1]->unit == UNIT_RAM_D0)) ||
5286 	  (!du && (regs[1]->unit == UNIT_RAM_D1)) ||
5287 	  (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) ||
5288 	  (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) {
5289 	as_bad (_("DSP RAM pointer in incorrect unit"));
5290 	return NULL;
5291       }
5292 
5293       /* Is this a template definition?  */
5294       if (IS_TEMPLATE_DEF (insn))
5295 	{
5296 	  l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5297 				      &dspram, size, &ls_shift, &au_shift,
5298 				      &au, &imm, &imm_shift, &imm_mask);
5299 
5300 	  if (l == NULL)
5301 	    return NULL;
5302 
5303 	  if (!dspram)
5304 	    mx_shift = 0;
5305 	}
5306 
5307       goto matched;
5308     }
5309 
5310   /* Group 2.  */
5311   if (template->arg_type & DSP_ARGS_2)
5312     {
5313       bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) &&
5314 			    (MINOR_OPCODE (template->meta_opcode) == 0xa));
5315       bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU;
5316       bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1;
5317 
5318       if (is_xsd)
5319 	du_shift = 0;
5320       else
5321 	du_shift = 24;
5322 
5323       l1_shift = 4;
5324 
5325       /* CMPs and TSTs don't store to their destination operand.  */
5326       ll = __parse_gp_reg (l, regs, is_cmp);
5327       if (ll == NULL)
5328 	{
5329 	  /* DSPe.r,Dx.r or DSPx.r,#I16 */
5330 	  if (template->arg_type & DSP_ARGS_DSP_SRC1)
5331 	    {
5332 	      l = parse_dsp_reg (l, regs, FALSE, FALSE);
5333 	      if (l == NULL)
5334 		{
5335 		  as_bad (_("invalid register operand #1"));
5336 		  return NULL;
5337 		}
5338 
5339 	      /* Only MOV instructions have a DSP register as a
5340 		 destination. Set the MOV DSPe.r opcode. The simple
5341 		 OR'ing is OK because the usual MOV opcode is 0x00.  */
5342 	      insn->bits = (0x91 << 24);
5343 	      du_shift = 0;
5344 	      l1_shift = 2;
5345 	      regs_shift[0] = 19;
5346 	    }
5347 	  else
5348 	    {
5349 	      as_bad (_("invalid register operand #2"));
5350 	      return NULL;
5351 	    }
5352 	}
5353       else
5354 	{
5355 	  l = ll;
5356 
5357 	  /* Everything but CMP and TST.  */
5358 	  if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
5359 	      MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5360 	      MAJOR_OPCODE (insn->bits) == OPC_9 ||
5361 	      MAJOR_OPCODE (template->meta_opcode) == OPC_MISC ||
5362 	      ((template->meta_opcode & 0x0000002c) != 0))
5363 	    regs_shift[0] = 19;
5364 	  else
5365 	    regs_shift[0] = 14;
5366 	}
5367 
5368       if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX &&
5369 					   is_fpu_mov && to_fpu))
5370 	return NULL;
5371 
5372       du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 ||
5373 	    regs[0]->unit == UNIT_ACC_D1);
5374 
5375       l = skip_comma (l);
5376 
5377       if (*l == IMM_CHAR)
5378 	{
5379 	  if (template->arg_type & DSP_ARGS_IMM &&
5380 	      !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)))
5381 	    {
5382 	      l = parse_imm16 (l, insn, &imm);
5383 	      if (l == NULL)
5384 		{
5385 		  as_bad (_("invalid immediate value"));
5386 		  return NULL;
5387 		}
5388 
5389 	      if (!within_signed_range (imm, IMM16_BITS))
5390 		return NULL;
5391 
5392 	      l1_shift = 2;
5393 	      regs_shift[0] = 19;
5394 
5395 	      imm_mask = 0xffff;
5396 	      imm_shift = 3;
5397 
5398 	      /* Set the I-bit unless it's a MOV because they're
5399 		 different.  */
5400 	      if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9))
5401 		insn->bits |= (1 << 25);
5402 
5403 	      /* All instructions that takes immediates also have bit 1 set.  */
5404 	      insn->bits |= (1 << 1);
5405 
5406 	      if (MAJOR_OPCODE (insn->bits) != OPC_9)
5407 		insn->bits |= (1 << 0);
5408 
5409 	      insn->bits &= ~(1 << 8);
5410 	    }
5411 	  else
5412 	    {
5413 	      as_bad (_("this instruction does not accept an immediate"));
5414 	      return NULL;
5415 	    }
5416 	}
5417       else
5418 	{
5419 	  if (MAJOR_OPCODE (insn->bits) != OPC_9)
5420 	    {
5421 	      insn->bits |= (1 << 8);
5422 	      l1_shift = 4;
5423 	    }
5424 
5425 	  ll = __parse_gp_reg (l, &regs[1], TRUE);
5426 	  if (ll == NULL)
5427 	    {
5428 	      if (template->arg_type & DSP_ARGS_DSP_SRC2)
5429 		{
5430 		  l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5431 		  if (l == NULL)
5432 		    {
5433 		      as_bad (_("invalid register operand #3"));
5434 		      return NULL;
5435 		    }
5436 
5437 		  /* MOV and NEG.  */
5438 		  if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) ||
5439 		      MAJOR_OPCODE (template->meta_opcode) == OPC_SUB)
5440 		    {
5441 		      if (is_accumulator_reg (regs[1]))
5442 			{
5443 			  if (is_fpu_mov)
5444 			    {
5445 			      as_bad (_("this instruction does not accept an accumulator"));
5446 			      return NULL;
5447 			    }
5448 			  ar_shift = 7;
5449 			  ar = 1;
5450 			  regs_shift[1] = 9;
5451 			}
5452 		      else
5453 			{
5454 			  du_shift = 0;
5455 			  l1_shift = 2;
5456 			  regs_shift[1] = 14;
5457 			  insn->bits = (0x92 << 24); /* Set opcode.  */
5458 			}
5459 		    }
5460 		}
5461 	      else
5462 		{
5463 		  as_bad (_("invalid register operand #4"));
5464 		  return NULL;
5465 		}
5466 	    }
5467 	  else
5468 	    {
5469 	      /* Set the o2r bit if required.  */
5470 	      if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit))
5471 		{
5472 		  o2r_reg = *regs[1];
5473 		  o2r_reg.no = lookup_o2r (0, du, regs[1]);
5474 		  regs[1] = &o2r_reg;
5475 		  o2r_shift = 0;
5476 		  o2r = 1;
5477 		}
5478 	      else if (!is_dsp_data_unit (regs[1]) &&
5479 		       !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX))
5480 		return NULL;
5481 
5482 	      if (is_fpu_mov && to_fpu)
5483 		du = (regs[1]->unit == UNIT_D1 ||
5484 		      regs[1]->unit == UNIT_RAM_D1 ||
5485 		      regs[1]->unit == UNIT_ACC_D1);
5486 
5487 	      l = ll;
5488 
5489 	      if (MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5490 		  MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5491 		  (((template->meta_opcode & 0x0000002c) == 0) &&
5492 		   MAJOR_OPCODE (template->meta_opcode) != OPC_MISC))
5493 		regs_shift[1] = 9;
5494 	      else
5495 		regs_shift[1] = 14;
5496 	    }
5497 	}
5498 
5499       /* If it's an 0x0 MOV or NEG set some lower bits.  */
5500       if ((MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5501 	   MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov)
5502 	{
5503 	  om_shift = 3;
5504 	  sc_shift = 5;
5505 	  insn->bits |= (1 << 2);
5506 	}
5507 
5508       /* Check for template definitons.  */
5509       if (IS_TEMPLATE_DEF (insn))
5510 	{
5511 	  l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5512 				      &dspram, size, &ls_shift, &au_shift,
5513 				      &au, &imm, &imm_shift, &imm_mask);
5514 	  mx_shift = 0;
5515 
5516 	  if (l == NULL)
5517 	    return NULL;
5518 	}
5519       goto matched;
5520     }
5521 
5522   /* Group 3.  */
5523   du_shift = 24;
5524   l1_shift = 4;
5525 
5526   l = __parse_gp_reg (l, regs, FALSE);
5527   if (l == NULL)
5528     {
5529       as_bad (_("invalid register operand"));
5530       return NULL;
5531     }
5532 
5533   l = skip_comma (l);
5534 
5535   if (*l == 'A')
5536     {
5537       l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5538       if (l == NULL)
5539 	{
5540 	  as_bad (_("invalid accumulator register"));
5541 	  return NULL;
5542 	}
5543       ac = 1;
5544       ac_shift = 0;
5545     }
5546   else
5547     {
5548       l = __parse_gp_reg (l, &regs[1], TRUE);
5549       if (l == NULL)
5550 	{
5551 	  as_bad (_("invalid register operand"));
5552 	  return NULL;
5553 	}
5554     }
5555 
5556   regs_shift[0] = 19;
5557   regs_shift[1] = 14;
5558 
5559   du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1
5560 	|| regs[1]->unit == UNIT_RAM_D1);
5561 
5562   l = skip_comma (l);
5563 
5564   if (*l == IMM_CHAR)
5565     {
5566       l = parse_imm_constant (l, insn, &imm);
5567       if (l == NULL)
5568 	{
5569 	  as_bad (_("invalid immediate value"));
5570 	  return NULL;
5571 	}
5572 
5573       if (!within_unsigned_range (imm, IMM5_BITS))
5574 	return NULL;
5575 
5576       imm_mask = 0x1f;
5577       imm_shift = 9;
5578 
5579       /* Set the I-bit */
5580       insn->bits |= (1 << 25);
5581     }
5582   else
5583     {
5584       regs_shift[2] = 9;
5585       l = __parse_gp_reg (l, &regs[2], TRUE);
5586       if (l == NULL)
5587 	return NULL;
5588     }
5589 
5590   /* Check for post-processing R,G,B flags. Conditional instructions
5591      do not have these bits.  */
5592   if (insn->dsp_action_flags & DSP_ACTION_CLAMP9)
5593     {
5594       if ((template->meta_opcode >> 26) & 0x1)
5595 	{
5596 	  as_bad (_("conditional instruction cannot use G flag"));
5597 	  return NULL;
5598 	}
5599 
5600       insn->bits |= (1 << 3);
5601     }
5602 
5603   if (insn->dsp_action_flags & DSP_ACTION_CLAMP8)
5604     {
5605       if ((template->meta_opcode >> 26) & 0x1)
5606 	{
5607 	  as_bad (_("conditional instruction cannot use B flag"));
5608 	  return NULL;
5609 	}
5610 
5611       insn->bits |= (0x3 << 2);
5612     }
5613 
5614   if (insn->dsp_action_flags & DSP_ACTION_ROUND)
5615     {
5616       if ((template->meta_opcode >> 26) & 0x1)
5617 	{
5618 	  as_bad (_("conditional instruction cannot use R flag"));
5619 	  return NULL;
5620 	}
5621       insn->bits |= (1 << 2);
5622     }
5623 
5624   /* Conditional Data Unit Shift instructions cannot be dual unit.  */
5625   if ((template->meta_opcode >> 26) & 0x1)
5626     ls_shift = INVALID_SHIFT;
5627 
5628   /* The Condition Is Always (CA) bit must be set if we're targetting a
5629      Ux.r register as the destination. This means that we can't have
5630      any other condition bits set.  */
5631   if (!is_same_data_unit (regs[1]->unit, regs[0]->unit))
5632     {
5633       /* Set both the Conditional bit and the Condition is Always bit.  */
5634       insn->bits |= (1 << 26);
5635       insn->bits |= (1 << 5);
5636 
5637       /* Fill out the Ud field.  */
5638       insn->bits |= (regs[0]->unit << 1);
5639     }
5640 
5641   if (IS_TEMPLATE_DEF (insn))
5642     {
5643       l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5644 				  &dspram, size, &ls_shift, &au_shift,
5645 				  &au, &imm, &imm_shift, &imm_mask);
5646 
5647       if (l == NULL)
5648 	return NULL;
5649 
5650       if (!dspram)
5651 	mx_shift = 5;
5652     }
5653 
5654   /* Fall through.  */
5655  matched:
5656 
5657   /* Set the registers and immediate values.  */
5658   if (regs_shift[0] != INVALID_SHIFT)
5659     insn->bits |= (regs[0]->no << regs_shift[0]);
5660 
5661   if (regs_shift[1] != INVALID_SHIFT)
5662     insn->bits |= (regs[1]->no << regs_shift[1]);
5663 
5664   if (regs_shift[2] != INVALID_SHIFT)
5665     insn->bits |= (regs[2]->no << regs_shift[2]);
5666 
5667   /* Does this insn have an 'IMM' bit? The immediate value should
5668      already have been masked.  */
5669   if (imm_shift != INVALID_SHIFT)
5670     insn->bits |= ((imm & imm_mask) << imm_shift);
5671 
5672   /* Does this insn have an 'AU' bit? */
5673   if (au_shift != INVALID_SHIFT)
5674     insn->bits |= (au << au_shift);
5675 
5676   /* Does this instruction have an 'LS' bit?  */
5677   if (ls_shift != INVALID_SHIFT)
5678     insn->bits |= (load << ls_shift);
5679 
5680   /* Does this instruction have an 'AR' bit?  */
5681   if (ar)
5682       insn->bits |= (1 << ar_shift);
5683 
5684   if (du_shift != INVALID_SHIFT)
5685     insn->bits |= (du << du_shift);
5686 
5687   if (sc_shift != INVALID_SHIFT)
5688     insn->bits |= (sc << sc_shift);
5689 
5690   if (om_shift != INVALID_SHIFT)
5691     insn->bits |= (om << om_shift);
5692 
5693   if (o2r_shift != INVALID_SHIFT)
5694     insn->bits |= (o2r << o2r_shift);
5695 
5696   if (qn_shift != INVALID_SHIFT)
5697     insn->bits |= (qn << qn_shift);
5698 
5699   if (qr_shift != INVALID_SHIFT)
5700     insn->bits |= (qr << qr_shift);
5701 
5702   if (qd_shift != INVALID_SHIFT)
5703     insn->bits |= (is_quickrot64 << qd_shift);
5704 
5705   if (a1_shift != INVALID_SHIFT)
5706     insn->bits |= (a1 << a1_shift);
5707 
5708   if (a2_shift != INVALID_SHIFT)
5709     insn->bits |= (a2 << a2_shift);
5710 
5711   if (su_shift != INVALID_SHIFT)
5712     insn->bits |= (su << su_shift);
5713 
5714   if (imm_shift != INVALID_SHIFT)
5715     insn->bits |= ((imm & imm_mask) << imm_shift);
5716 
5717   if (ac_shift != INVALID_SHIFT)
5718     insn->bits |= (ac << ac_shift);
5719 
5720   if (mx_shift != INVALID_SHIFT)
5721     insn->bits |= (mx << mx_shift);
5722 
5723   if (is_dual)
5724     {
5725       if (l1_shift == INVALID_SHIFT)
5726 	{
5727 	  as_bad (_("'L' modifier not valid for this instruction"));
5728 	  return NULL;
5729 	}
5730 
5731       insn->bits |= (1 << l1_shift);
5732     }
5733 
5734   insn->len = 4;
5735 
5736   return l;
5737 }
5738 
5739 typedef const char *(*insn_parser)(const char *, metag_insn *,
5740 				   const insn_template *);
5741 
5742 /* Parser table.  */
5743 static const insn_parser insn_parsers[ENC_MAX] =
5744   {
5745     [ENC_NONE] = parse_none,
5746     [ENC_MOV_U2U] = parse_mov_u2u,
5747     [ENC_MOV_PORT] = parse_mov_port,
5748     [ENC_MMOV] = parse_mmov,
5749     [ENC_MDRD] = parse_mdrd,
5750     [ENC_MOVL_TTREC] = parse_movl_ttrec,
5751     [ENC_GET_SET] = parse_get_set,
5752     [ENC_GET_SET_EXT] = parse_get_set_ext,
5753     [ENC_MGET_MSET] = parse_mget_mset,
5754     [ENC_COND_SET] = parse_cond_set,
5755     [ENC_XFR] = parse_xfr,
5756     [ENC_MOV_CT] = parse_mov_ct,
5757     [ENC_SWAP] = parse_swap,
5758     [ENC_JUMP] = parse_jump,
5759     [ENC_CALLR] = parse_callr,
5760     [ENC_ALU] = parse_alu,
5761     [ENC_SHIFT] = parse_shift,
5762     [ENC_MIN_MAX] = parse_min_max,
5763     [ENC_BITOP] = parse_bitop,
5764     [ENC_CMP] = parse_cmp,
5765     [ENC_BRANCH] = parse_branch,
5766     [ENC_KICK] = parse_kick,
5767     [ENC_SWITCH] = parse_switch,
5768     [ENC_CACHER] = parse_cacher,
5769     [ENC_CACHEW] = parse_cachew,
5770     [ENC_ICACHE] = parse_icache,
5771     [ENC_LNKGET] = parse_lnkget,
5772     [ENC_FMOV] = parse_fmov,
5773     [ENC_FMMOV] = parse_fmmov,
5774     [ENC_FMOV_DATA] = parse_fmov_data,
5775     [ENC_FMOV_I] = parse_fmov_i,
5776     [ENC_FPACK] = parse_fpack,
5777     [ENC_FSWAP] = parse_fswap,
5778     [ENC_FCMP] = parse_fcmp,
5779     [ENC_FMINMAX] = parse_fminmax,
5780     [ENC_FCONV] = parse_fconv,
5781     [ENC_FCONVX] = parse_fconvx,
5782     [ENC_FBARITH] = parse_fbarith,
5783     [ENC_FEARITH] = parse_fearith,
5784     [ENC_FREC] = parse_frec,
5785     [ENC_FSIMD] = parse_fsimd,
5786     [ENC_FGET_SET_ACF] = parse_fget_set_acf,
5787     [ENC_DGET_SET] = parse_dget_set,
5788     [ENC_DTEMPLATE] = parse_dtemplate,
5789     [ENC_DALU] = parse_dalu,
5790   };
5791 
5792 struct metag_core_option
5793 {
5794   const char *name;
5795   unsigned int value;
5796 };
5797 
5798 /* CPU type options.  */
5799 static const struct metag_core_option metag_cpus[] =
5800   {
5801     {"all",               CoreMeta11|CoreMeta12|CoreMeta21},
5802     {"metac11",           CoreMeta11},
5803     {"metac12",           CoreMeta12},
5804     {"metac21",           CoreMeta21},
5805     {NULL,                0},
5806   };
5807 
5808 /* FPU type options.  */
5809 static const struct metag_core_option metag_fpus[] =
5810   {
5811     {"metac21",           FpuMeta21},
5812     {NULL,                0},
5813   };
5814 
5815 /* DSP type options.  */
5816 static const struct metag_core_option metag_dsps[] =
5817   {
5818     {"metac21",           DspMeta21},
5819     {NULL,                0},
5820   };
5821 
5822 /* Parse a CPU command line option.  */
5823 static int
metag_parse_cpu(const char * str)5824 metag_parse_cpu (const char * str)
5825 {
5826   const struct metag_core_option * opt;
5827   int optlen;
5828 
5829   optlen = strlen (str);
5830 
5831   if (optlen == 0)
5832     {
5833       as_bad (_("missing cpu name `%s'"), str);
5834       return 0;
5835     }
5836 
5837   for (opt = metag_cpus; opt->name != NULL; opt++)
5838     if (strncmp (opt->name, str, optlen) == 0)
5839       {
5840 	mcpu_opt = opt->value;
5841 	return 1;
5842       }
5843 
5844   as_bad (_("unknown cpu `%s'"), str);
5845   return 0;
5846 }
5847 
5848 /* Parse an FPU command line option.  */
5849 static int
metag_parse_fpu(const char * str)5850 metag_parse_fpu (const char * str)
5851 {
5852   const struct metag_core_option * opt;
5853   int optlen;
5854 
5855   optlen = strlen (str);
5856 
5857   if (optlen == 0)
5858     {
5859       as_bad (_("missing fpu name `%s'"), str);
5860       return 0;
5861     }
5862 
5863   for (opt = metag_fpus; opt->name != NULL; opt++)
5864     if (strncmp (opt->name, str, optlen) == 0)
5865       {
5866 	mfpu_opt = opt->value;
5867 	return 1;
5868       }
5869 
5870   as_bad (_("unknown fpu `%s'"), str);
5871   return 0;
5872 }
5873 
5874 /* Parse a DSP command line option.  */
5875 static int
metag_parse_dsp(const char * str)5876 metag_parse_dsp (const char * str)
5877 {
5878   const struct metag_core_option * opt;
5879   int optlen;
5880 
5881   optlen = strlen (str);
5882 
5883   if (optlen == 0)
5884     {
5885       as_bad (_("missing DSP name `%s'"), str);
5886       return 0;
5887     }
5888 
5889   for (opt = metag_dsps; opt->name != NULL; opt++)
5890     if (strncmp (opt->name, str, optlen) == 0)
5891       {
5892 	mdsp_opt = opt->value;
5893 	return 1;
5894       }
5895 
5896   as_bad (_("unknown DSP `%s'"), str);
5897   return 0;
5898 }
5899 
5900 struct metag_long_option
5901 {
5902   const char * option;                /* Substring to match.  */
5903   const char * help;                  /* Help information.  */
5904   int (* func) (const char * subopt); /* Function to decode sub-option.  */
5905   const char * deprecated;            /* If non-null, print this message.  */
5906 };
5907 
5908 struct metag_long_option metag_long_opts[] =
5909   {
5910     {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
5911      metag_parse_cpu, NULL},
5912     {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
5913      metag_parse_fpu, NULL},
5914     {"mdsp=", N_("<dsp name>\t  assemble for DSP architecture <dsp name>"),
5915      metag_parse_dsp, NULL},
5916     {NULL, NULL, 0, NULL}
5917   };
5918 
5919 int
md_parse_option(int c,const char * arg)5920 md_parse_option (int c, const char * arg)
5921 {
5922   struct metag_long_option *lopt;
5923 
5924   for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5925     {
5926       /* These options are expected to have an argument.  */
5927       if (c == lopt->option[0]
5928 	  && arg != NULL
5929 	  && strncmp (arg, lopt->option + 1,
5930 		      strlen (lopt->option + 1)) == 0)
5931 	{
5932 #if WARN_DEPRECATED
5933 	      /* If the option is deprecated, tell the user.  */
5934 	      if (lopt->deprecated != NULL)
5935 		as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
5936 			   _(lopt->deprecated));
5937 #endif
5938 
5939 	      /* Call the sup-option parser.  */
5940 	      return lopt->func (arg + strlen (lopt->option) - 1);
5941 	}
5942     }
5943 
5944   return 0;
5945 }
5946 
5947 void
md_show_usage(FILE * stream)5948 md_show_usage (FILE * stream)
5949 {
5950   struct metag_long_option *lopt;
5951 
5952   fprintf (stream, _(" Meta specific command line options:\n"));
5953 
5954   for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5955     if (lopt->help != NULL)
5956       fprintf (stream, "  -%s%s\n", lopt->option, _(lopt->help));
5957 }
5958 
5959 /* The target specific pseudo-ops which we support.  */
5960 const pseudo_typeS md_pseudo_table[] =
5961 {
5962   { "word",	cons,		2 },
5963   { NULL, 	NULL, 		0 }
5964 };
5965 
5966 void
md_begin(void)5967 md_begin (void)
5968 {
5969   int c;
5970 
5971   for (c = 0; c < 256; c++)
5972     {
5973       if (ISDIGIT (c))
5974 	{
5975 	  register_chars[c] = c;
5976 	  /* LOCK0, LOCK1, LOCK2.  */
5977 	  mnemonic_chars[c] = c;
5978 	}
5979       else if (ISLOWER (c))
5980 	{
5981 	  register_chars[c] = c;
5982 	  mnemonic_chars[c] = c;
5983 	}
5984       else if (ISUPPER (c))
5985 	{
5986 	  register_chars[c] = c;
5987 	  mnemonic_chars[c] = c;
5988 	}
5989       else if (c == '.')
5990 	{
5991 	  register_chars[c] = c;
5992 	}
5993     }
5994 }
5995 
5996 /* Parse a split condition code prefix.  */
5997 static const char *
parse_split_condition(const char * line,metag_insn * insn)5998 parse_split_condition (const char *line, metag_insn *insn)
5999 {
6000   const char *l = line;
6001   const split_condition *scond;
6002   split_condition entry;
6003   char buf[4];
6004 
6005   memcpy (buf, l, 4);
6006   buf[3] = '\0';
6007 
6008   entry.name = buf;
6009 
6010   scond = (const split_condition *) htab_find (scond_htab, &entry);
6011 
6012   if (!scond)
6013     return NULL;
6014 
6015   insn->scond = scond->code;
6016 
6017   return l + strlen (scond->name);
6018 }
6019 
6020 /* Parse an instruction prefix - F for float, D for DSP - and associated
6021    flags and condition codes.  */
6022 static const char *
parse_prefix(const char * line,metag_insn * insn)6023 parse_prefix (const char *line, metag_insn *insn)
6024 {
6025   const char *l = line;
6026 
6027   l = skip_whitespace (l);
6028 
6029   insn->type = INSN_GP;
6030 
6031   if (TOLOWER (*l) == FPU_PREFIX_CHAR)
6032     {
6033       if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN)))
6034 	{
6035 	  insn->type = INSN_FPU;
6036 
6037 	  l++;
6038 
6039 	  if (*l == END_OF_INSN)
6040 	    {
6041 	      as_bad (_("premature end of floating point prefix"));
6042 	      return NULL;
6043 	    }
6044 
6045 	  if (TOLOWER (*l) == FPU_DOUBLE_CHAR)
6046 	    {
6047 	      insn->fpu_width = FPU_WIDTH_DOUBLE;
6048 	      l++;
6049 	    }
6050 	  else if (TOLOWER (*l) == FPU_PAIR_CHAR)
6051 	    {
6052 	      const char *l2 = l;
6053 
6054 	      /* Check this isn't a split condition beginning with L.  */
6055 	      l2 = parse_split_condition (l2, insn);
6056 
6057 	      if (l2 && is_whitespace_char (*l2))
6058 		{
6059 		  l = l2;
6060 		}
6061 	      else
6062 		{
6063 		  insn->fpu_width = FPU_WIDTH_PAIR;
6064 		  l++;
6065 		}
6066 	    }
6067 	  else
6068 	    {
6069 	      insn->fpu_width = FPU_WIDTH_SINGLE;
6070 	    }
6071 
6072 	  if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR)
6073 	    {
6074 	      insn->fpu_action_flags |= FPU_ACTION_ABS;
6075 	      l++;
6076 	    }
6077 	  else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR)
6078 	    {
6079 	      insn->fpu_action_flags |= FPU_ACTION_INV;
6080 	      l++;
6081 	    }
6082 
6083 	  if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR)
6084 	    {
6085 	      insn->fpu_action_flags |= FPU_ACTION_QUIET;
6086 	      l++;
6087 	    }
6088 
6089 	  if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR)
6090 	    {
6091 	      insn->fpu_action_flags |= FPU_ACTION_ZERO;
6092 	      l++;
6093 	    }
6094 
6095 	  if (! is_whitespace_char (*l))
6096 	    {
6097 	      l = parse_split_condition (l, insn);
6098 
6099 	      if (!l)
6100 		{
6101 		  as_bad (_("unknown floating point prefix character"));
6102 		  return NULL;
6103 		}
6104 	    }
6105 
6106 	  l = skip_space (l);
6107 	}
6108     }
6109   else if (TOLOWER (*l) == DSP_PREFIX_CHAR)
6110     {
6111       if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) &&
6112 	  strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN)))
6113 	{
6114 	  const char *ll = l;
6115 	  insn->type = INSN_DSP;
6116 
6117 	  l++;
6118 
6119 	  insn->dsp_width = DSP_WIDTH_SINGLE;
6120 
6121 	  while (!is_whitespace_char (*l))
6122 	    {
6123 	      /* We have to check for split condition codes first
6124 		 because they are the longest strings to match,
6125 		 e.g. if the string contains "LLS" we want it to match
6126 		 the split condition code "LLS", not the dual unit
6127 		 character "L".  */
6128 	      ll = l;
6129 	      l = parse_split_condition (l, insn);
6130 
6131 	      if (l == NULL)
6132 		l = ll;
6133 	      else
6134 		continue;
6135 
6136 	      /* Accept an FPU prefix char which may be used when doing
6137 		 template MOV with FPU registers. */
6138 	      if (TOLOWER(*l) == FPU_PREFIX_CHAR)
6139 		{
6140 		  insn->type = INSN_DSP_FPU;
6141 		  l++;
6142 		  continue;
6143 		}
6144 
6145 	      if (TOLOWER(*l) == DSP_DUAL_CHAR)
6146 		{
6147 		  insn->dsp_width = DSP_WIDTH_DUAL;
6148 		  l++;
6149 		  continue;
6150 		}
6151 
6152 	      if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR)
6153 		{
6154 		  insn->dsp_action_flags |= DSP_ACTION_QR64;
6155 		  l++;
6156 		  continue;
6157 		}
6158 
6159 	      if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR)
6160 		{
6161 		  insn->dsp_action_flags |= DSP_ACTION_UMUL;
6162 		  l++;
6163 		  continue;
6164 		}
6165 
6166 	      if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR)
6167 		{
6168 		  insn->dsp_action_flags |= DSP_ACTION_ROUND;
6169 		  l++;
6170 		  continue;
6171 		}
6172 
6173 	      if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR)
6174 		{
6175 		  insn->dsp_action_flags |= DSP_ACTION_CLAMP9;
6176 		  l++;
6177 		  continue;
6178 		}
6179 
6180 	      if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR)
6181 		{
6182 		  insn->dsp_action_flags |= DSP_ACTION_CLAMP8;
6183 		  l++;
6184 		  continue;
6185 		}
6186 
6187 	      if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR)
6188 		{
6189 		  insn->dsp_action_flags |= DSP_ACTION_MOD;
6190 		  l++;
6191 		  continue;
6192 		}
6193 
6194 	      if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR)
6195 		{
6196 		  insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO;
6197 		  l++;
6198 		  continue;
6199 		}
6200 
6201 	      if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR)
6202 		{
6203 		  insn->dsp_action_flags |= DSP_ACTION_ACC_ADD;
6204 		  l++;
6205 		  continue;
6206 		}
6207 
6208 	      if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR)
6209 		{
6210 		  insn->dsp_action_flags |= DSP_ACTION_ACC_SUB;
6211 		  l++;
6212 		  continue;
6213 		}
6214 
6215 	      if (TOLOWER(*l) == DSP_ACTION_OV_CHAR)
6216 		{
6217 		  insn->dsp_action_flags |= DSP_ACTION_OV;
6218 		  l++;
6219 		  continue;
6220 		}
6221 
6222 	      if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR)
6223 		{
6224 		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_8;
6225 		  l++;
6226 		  continue;
6227 		}
6228 
6229 	      if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR)
6230 		{
6231 		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_16;
6232 		  l++;
6233 		  continue;
6234 		}
6235 
6236 	      if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR)
6237 		{
6238 		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP;
6239 		  l++;
6240 		  continue;
6241 		}
6242 
6243 	      if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR)
6244 		{
6245 		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH;
6246 		  l++;
6247 		  continue;
6248 		}
6249 
6250 	      as_bad (_("unknown DSP prefix character %c %s"), *l, l);
6251 	      return NULL;
6252 	    }
6253 
6254 	  l = skip_space (l);
6255 	}
6256     }
6257 
6258   return l;
6259 }
6260 
6261 /* Return a list of appropriate instruction parsers for MNEMONIC.  */
6262 static insn_templates *
find_insn_templates(const char * mnemonic)6263 find_insn_templates (const char *mnemonic)
6264 {
6265   insn_template template;
6266   insn_templates entry;
6267   insn_templates *slot;
6268 
6269   entry.template = &template;
6270 
6271   memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *));
6272 
6273   slot = (insn_templates *) htab_find (mnemonic_htab, &entry);
6274 
6275   if (slot)
6276     return slot;
6277 
6278   return NULL;
6279 }
6280 
6281 /* Make an uppercase copy of SRC into DST and return DST.  */
6282 static char *
strupper(char * dst,const char * src)6283 strupper (char * dst, const char *src)
6284 {
6285   size_t i = 0;
6286 
6287   while (src[i])
6288     {
6289       dst[i] = TOUPPER (src[i]);
6290       i++;
6291     }
6292 
6293   dst[i] = 0;
6294 
6295   return dst;
6296 }
6297 
6298 /* Calculate a hash value for a template. */
6299 static hashval_t
hash_templates(const void * p)6300 hash_templates (const void *p)
6301 {
6302   insn_templates *tp = (insn_templates *)p;
6303   char buf[MAX_MNEMONIC_LEN];
6304 
6305   strupper (buf, tp->template->name);
6306 
6307   return htab_hash_string (buf);
6308 }
6309 
6310 /* Check if two templates are equal.  */
6311 static int
eq_templates(const void * a,const void * b)6312 eq_templates (const void *a, const void *b)
6313 {
6314   insn_templates *ta = (insn_templates *)a;
6315   insn_templates *tb = (insn_templates *)b;
6316   return strcasecmp (ta->template->name, tb->template->name) == 0;
6317 }
6318 
6319 /* Create the hash table required for parsing instructions.  */
6320 static void
create_mnemonic_htab(void)6321 create_mnemonic_htab (void)
6322 {
6323   size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]);
6324 
6325   mnemonic_htab = htab_create_alloc (num_templates, hash_templates,
6326 				     eq_templates, NULL, xcalloc, free);
6327 
6328   for (i = 0; i < num_templates; i++)
6329     {
6330       const insn_template *template = &metag_optab[i];
6331       insn_templates **slot = NULL;
6332       insn_templates *new_entry;
6333 
6334       new_entry = XNEW (insn_templates);
6335 
6336       new_entry->template = template;
6337       new_entry->next = NULL;
6338 
6339       slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry,
6340 						 INSERT);
6341 
6342       if (*slot)
6343 	{
6344 	  insn_templates *last_entry = *slot;
6345 
6346 	  while (last_entry->next)
6347 	    last_entry = last_entry->next;
6348 
6349 	  last_entry->next = new_entry;
6350 	}
6351       else
6352 	{
6353 	  *slot = new_entry;
6354 	}
6355     }
6356 }
6357 
6358 /* Calculate a hash value for a register. */
6359 static hashval_t
hash_regs(const void * p)6360 hash_regs (const void *p)
6361 {
6362   metag_reg *rp = (metag_reg *)p;
6363   char buf[MAX_REG_LEN];
6364 
6365   strupper (buf, rp->name);
6366 
6367   return htab_hash_string (buf);
6368 }
6369 
6370 /* Check if two registers are equal.  */
6371 static int
eq_regs(const void * a,const void * b)6372 eq_regs (const void *a, const void *b)
6373 {
6374   metag_reg *ra = (metag_reg *)a;
6375   metag_reg *rb = (metag_reg *)b;
6376   return strcasecmp (ra->name, rb->name) == 0;
6377 }
6378 
6379 /* Create the hash table required for parsing registers.  */
6380 static void
create_reg_htab(void)6381 create_reg_htab (void)
6382 {
6383   size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]);
6384 
6385   reg_htab = htab_create_alloc (num_regs, hash_regs,
6386 				eq_regs, NULL, xcalloc, free);
6387 
6388   for (i = 0; i < num_regs; i++)
6389     {
6390       const metag_reg *reg = &metag_regtab[i];
6391       const metag_reg **slot;
6392 
6393       slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT);
6394 
6395       if (!*slot)
6396 	*slot = reg;
6397     }
6398 }
6399 
6400 /* Create the hash table required for parsing DSP registers.  */
6401 static void
create_dspreg_htabs(void)6402 create_dspreg_htabs (void)
6403 {
6404   size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]);
6405   size_t h;
6406 
6407   dsp_reg_htab = htab_create_alloc (num_regs, hash_regs,
6408 				    eq_regs, NULL, xcalloc, free);
6409 
6410   for (i = 0; i < num_regs; i++)
6411     {
6412       const metag_reg *reg = &metag_dsp_regtab[i];
6413       const metag_reg **slot;
6414 
6415       slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT);
6416 
6417       /* Make sure there are no hash table collisions, which would
6418 	 require chaining entries.  */
6419       BFD_ASSERT (*slot == NULL);
6420       *slot = reg;
6421     }
6422 
6423   num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]);
6424 
6425   for (h = 0; h < 2; h++)
6426     {
6427       dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs,
6428 						eq_regs, NULL, xcalloc, free);
6429     }
6430 
6431   for (h = 0; h < 2; h++)
6432     {
6433       for (i = 0; i < num_regs; i++)
6434 	{
6435 	  const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i];
6436 	  const metag_reg **slot;
6437 	  slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h],
6438 						      reg, INSERT);
6439 
6440 	  /* Make sure there are no hash table collisions, which would
6441 	     require chaining entries.  */
6442 	  BFD_ASSERT (*slot == NULL);
6443 	  *slot = reg;
6444 	}
6445     }
6446 }
6447 
6448 /* Calculate a hash value for a split condition code. */
6449 static hashval_t
hash_scond(const void * p)6450 hash_scond (const void *p)
6451 {
6452   split_condition *cp = (split_condition *)p;
6453   char buf[4];
6454 
6455   strupper (buf, cp->name);
6456 
6457   return htab_hash_string (buf);
6458 }
6459 
6460 /* Check if two split condition codes are equal.  */
6461 static int
eq_scond(const void * a,const void * b)6462 eq_scond (const void *a, const void *b)
6463 {
6464   split_condition *ra = (split_condition *)a;
6465   split_condition *rb = (split_condition *)b;
6466 
6467   return strcasecmp (ra->name, rb->name) == 0;
6468 }
6469 
6470 /* Create the hash table required for parsing split condition codes.  */
6471 static void
create_scond_htab(void)6472 create_scond_htab (void)
6473 {
6474   size_t i, nentries;
6475 
6476   nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]);
6477 
6478   scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond,
6479 				  NULL, xcalloc, free);
6480   for (i = 0; i < nentries; i++)
6481     {
6482       const split_condition *scond = &metag_scondtab[i];
6483       const split_condition **slot;
6484 
6485       slot = (const split_condition **) htab_find_slot (scond_htab,
6486 							scond, INSERT);
6487       /* Make sure there are no hash table collisions, which would
6488 	 require chaining entries.  */
6489       BFD_ASSERT (*slot == NULL);
6490       *slot = scond;
6491     }
6492 }
6493 
6494 /* Entry point for instruction parsing.  */
6495 static bfd_boolean
parse_insn(const char * line,metag_insn * insn)6496 parse_insn (const char *line, metag_insn *insn)
6497 {
6498   char mnemonic[MAX_MNEMONIC_LEN];
6499   const char *l = line;
6500   size_t mnemonic_len = 0;
6501   insn_templates *templates;
6502 
6503   l = skip_space (l);
6504 
6505   while (is_mnemonic_char(*l))
6506     {
6507       l++;
6508       mnemonic_len++;
6509     }
6510 
6511   if (mnemonic_len >= MAX_MNEMONIC_LEN)
6512     {
6513       as_bad (_("instruction mnemonic too long: %s"), line);
6514       return FALSE;
6515     }
6516 
6517   strncpy(mnemonic, line, mnemonic_len);
6518 
6519   mnemonic[mnemonic_len] = '\0';
6520 
6521   templates = find_insn_templates (mnemonic);
6522 
6523   if (templates)
6524     {
6525       insn_templates *current_template = templates;
6526 
6527       l = skip_space (l);
6528 
6529       while (current_template)
6530 	{
6531 	  const insn_template *template = current_template->template;
6532 	  enum insn_encoding encoding = template->encoding;
6533 	  insn_parser parser = insn_parsers[encoding];
6534 
6535 	  current_template = current_template->next;
6536 
6537 	  if (template->insn_type == INSN_GP &&
6538 	      !(template->core_flags & mcpu_opt))
6539 	    continue;
6540 
6541 	  if (template->insn_type == INSN_FPU &&
6542 	      !(template->core_flags & mfpu_opt))
6543 	    continue;
6544 
6545 	  if (template->insn_type == INSN_DSP &&
6546 	      !(template->core_flags & mdsp_opt))
6547 	    continue;
6548 
6549 	  if (template->insn_type == INSN_DSP_FPU &&
6550 	      !((template->core_flags & mdsp_opt) &&
6551 		(template->core_flags & mfpu_opt)))
6552 	    continue;
6553 
6554 	  /* DSP instructions always require special decoding */
6555 	  if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) ||
6556 	      ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) ||
6557 	      (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) ||
6558 	      ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU))
6559 	    continue;
6560 
6561 	  if (parser)
6562 	    {
6563 	      const char *end = parser(l, insn, template);
6564 
6565 	      if (end != NULL)
6566 		{
6567 		  if (*end != END_OF_INSN)
6568 		    as_bad (_("junk at end of line: \"%s\""), line);
6569 		  else
6570 		    return TRUE;
6571 		}
6572 	    }
6573 	}
6574 
6575       as_bad (_("failed to assemble instruction: \"%s\""), line);
6576     }
6577   else
6578     {
6579       if (insn->type == INSN_FPU)
6580 	as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic);
6581       else
6582 	as_bad (_("unknown mnemonic: \"%s\""), mnemonic);
6583     }
6584   return FALSE;
6585 }
6586 
6587 static void
output_insn(metag_insn * insn)6588 output_insn (metag_insn *insn)
6589 {
6590   char *output;
6591 
6592   output = frag_more (insn->len);
6593   dwarf2_emit_insn (insn->len);
6594 
6595   if (insn->reloc_type != BFD_RELOC_UNUSED)
6596     {
6597       fix_new_exp (frag_now, output - frag_now->fr_literal,
6598 		   insn->reloc_size, &insn->reloc_exp,
6599 		   insn->reloc_pcrel, insn->reloc_type);
6600     }
6601 
6602   md_number_to_chars (output, insn->bits, insn->len);
6603 }
6604 
6605 void
md_assemble(char * line)6606 md_assemble (char *line)
6607 {
6608   const char *l = line;
6609   metag_insn insn;
6610 
6611   memset (&insn, 0, sizeof(insn));
6612 
6613   insn.reloc_type = BFD_RELOC_UNUSED;
6614   insn.reloc_pcrel = 0;
6615   insn.reloc_size = 4;
6616 
6617   if (!mnemonic_htab)
6618     {
6619       create_mnemonic_htab ();
6620       create_reg_htab ();
6621       create_dspreg_htabs ();
6622       create_scond_htab ();
6623     }
6624 
6625   l = parse_prefix (l, &insn);
6626 
6627   if (l == NULL)
6628     return;
6629 
6630   if (insn.type == INSN_DSP &&
6631       !mdsp_opt)
6632     {
6633       as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6634 	      line);
6635       return;
6636     }
6637   else if (insn.type == INSN_FPU &&
6638 	   !mfpu_opt)
6639     {
6640       as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6641 	      line);
6642       return;
6643     }
6644 
6645   if (!parse_insn (l, &insn))
6646     return;
6647 
6648   output_insn (&insn);
6649 }
6650 
6651 void
md_operand(expressionS * expressionP)6652 md_operand (expressionS * expressionP)
6653 {
6654   if (* input_line_pointer == IMM_CHAR)
6655     {
6656       input_line_pointer ++;
6657       expression (expressionP);
6658     }
6659 }
6660 
6661 valueT
md_section_align(segT segment ATTRIBUTE_UNUSED,valueT size)6662 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
6663 {
6664   return size;
6665 }
6666 
6667 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)6668 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
6669 {
6670   return NULL;
6671 }
6672 
6673 /* Functions concerning relocs.  */
6674 
6675 /* The location from which a PC relative jump should be calculated,
6676    given a PC relative reloc.  */
6677 
6678 long
md_pcrel_from_section(fixS * fixP,segT sec)6679 md_pcrel_from_section (fixS * fixP, segT sec)
6680 {
6681   if ((fixP->fx_addsy != (symbolS *) NULL
6682        && (! S_IS_DEFINED (fixP->fx_addsy)
6683 	   || S_GET_SEGMENT (fixP->fx_addsy) != sec))
6684       || metag_force_relocation (fixP))
6685     {
6686       /* The symbol is undefined (or is defined but not in this section).
6687 	 Let the linker figure it out.  */
6688       return 0;
6689     }
6690 
6691   return fixP->fx_frag->fr_address + fixP->fx_where;
6692 }
6693 
6694 /* Write a value out to the object file, using the appropriate endianness.  */
6695 
6696 void
md_number_to_chars(char * buf,valueT val,int n)6697 md_number_to_chars (char * buf, valueT val, int n)
6698 {
6699   number_to_chars_littleendian (buf, val, n);
6700 }
6701 
6702 /* Turn a string in input_line_pointer into a floating point constant of type
6703    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
6704    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
6705 */
6706 
6707 /* Equal to MAX_PRECISION in atof-ieee.c */
6708 #define MAX_LITTLENUMS 6
6709 
6710 const char *
md_atof(int type,char * litP,int * sizeP)6711 md_atof (int type, char * litP, int * sizeP)
6712 {
6713   int              i;
6714   int              prec;
6715   LITTLENUM_TYPE   words [MAX_LITTLENUMS];
6716   char *           t;
6717 
6718   switch (type)
6719     {
6720     case 'f':
6721     case 'F':
6722     case 's':
6723     case 'S':
6724       prec = 2;
6725       break;
6726 
6727     case 'd':
6728     case 'D':
6729     case 'r':
6730     case 'R':
6731       prec = 4;
6732       break;
6733 
6734    /* FIXME: Some targets allow other format chars for bigger sizes here.  */
6735 
6736     default:
6737       * sizeP = 0;
6738       return _("Bad call to md_atof()");
6739     }
6740 
6741   t = atof_ieee (input_line_pointer, type, words);
6742   if (t)
6743     input_line_pointer = t;
6744   * sizeP = prec * sizeof (LITTLENUM_TYPE);
6745 
6746   for (i = 0; i < prec; i++)
6747     {
6748       md_number_to_chars (litP, (valueT) words[i],
6749 			  sizeof (LITTLENUM_TYPE));
6750       litP += sizeof (LITTLENUM_TYPE);
6751     }
6752 
6753   return 0;
6754 }
6755 
6756 /* If this function returns non-zero, it prevents the relocation
6757    against symbol(s) in the FIXP from being replaced with relocations
6758    against section symbols, and guarantees that a relocation will be
6759    emitted even when the value can be resolved locally.  */
6760 
6761 int
metag_force_relocation(fixS * fix)6762 metag_force_relocation (fixS * fix)
6763 {
6764   switch (fix->fx_r_type)
6765     {
6766     case BFD_RELOC_METAG_RELBRANCH_PLT:
6767     case BFD_RELOC_METAG_TLS_LE:
6768     case BFD_RELOC_METAG_TLS_IE:
6769     case BFD_RELOC_METAG_TLS_LDO:
6770     case BFD_RELOC_METAG_TLS_LDM:
6771     case BFD_RELOC_METAG_TLS_GD:
6772       return 1;
6773     default:
6774       ;
6775     }
6776 
6777   return generic_force_reloc (fix);
6778 }
6779 
6780 bfd_boolean
metag_fix_adjustable(fixS * fixP)6781 metag_fix_adjustable (fixS * fixP)
6782 {
6783   if (fixP->fx_addsy == NULL)
6784     return 1;
6785 
6786   /* Prevent all adjustments to global symbols.  */
6787   if (S_IS_EXTERNAL (fixP->fx_addsy))
6788     return 0;
6789   if (S_IS_WEAK (fixP->fx_addsy))
6790     return 0;
6791 
6792   if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF ||
6793       fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF ||
6794       fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF ||
6795       fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT ||
6796       fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC ||
6797       fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC ||
6798       fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT ||
6799       fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT ||
6800       fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT)
6801     return 0;
6802 
6803   /* We need the symbol name for the VTABLE entries.  */
6804   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6805       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6806     return 0;
6807 
6808   return 1;
6809 }
6810 
6811 /* Return an initial guess of the length by which a fragment must grow to
6812    hold a branch to reach its destination.
6813    Also updates fr_type/fr_subtype as necessary.
6814 
6815    Called just before doing relaxation.
6816    Any symbol that is now undefined will not become defined.
6817    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6818    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6819    Although it may not be explicit in the frag, pretend fr_var starts with a
6820    0 value.  */
6821 
6822 int
md_estimate_size_before_relax(fragS * fragP ATTRIBUTE_UNUSED,segT segment ATTRIBUTE_UNUSED)6823 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
6824 			       segT    segment ATTRIBUTE_UNUSED)
6825 {
6826   /* No assembler relaxation is defined (or necessary) for this port.  */
6827   abort ();
6828 }
6829 
6830 /* *fragP has been relaxed to its final size, and now needs to have
6831    the bytes inside it modified to conform to the new size.
6832 
6833    Called after relaxation is finished.
6834    fragP->fr_type == rs_machine_dependent.
6835    fragP->fr_subtype is the subtype of what the address relaxed to.  */
6836 
6837 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec ATTRIBUTE_UNUSED,fragS * fragP ATTRIBUTE_UNUSED)6838 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
6839 		 fragS * fragP ATTRIBUTE_UNUSED)
6840 {
6841   /* No assembler relaxation is defined (or necessary) for this port.  */
6842   abort ();
6843 }
6844 
6845 /* This is called from HANDLE_ALIGN in tc-metag.h.  */
6846 
6847 void
metag_handle_align(fragS * fragP)6848 metag_handle_align (fragS * fragP)
6849 {
6850   static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6851   int bytes, fix;
6852   char *p;
6853 
6854   if (fragP->fr_type != rs_align_code)
6855     return;
6856 
6857   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
6858   p = fragP->fr_literal + fragP->fr_fix;
6859   fix = 0;
6860 
6861   if (bytes & 3)
6862     {
6863       fix = bytes & 3;
6864       memset (p, 0, fix);
6865       p += fix;
6866       bytes -= fix;
6867     }
6868 
6869   while (bytes >= 4)
6870     {
6871       memcpy (p, noop, 4);
6872       p += 4;
6873       bytes -= 4;
6874       fix += 4;
6875     }
6876 
6877   fragP->fr_fix += fix;
6878   fragP->fr_var = 4;
6879 }
6880 
6881 static char *
metag_end_of_match(char * cont,const char * what)6882 metag_end_of_match (char * cont, const char * what)
6883 {
6884   int len = strlen (what);
6885 
6886   if (strncasecmp (cont, what, strlen (what)) == 0
6887       && ! is_part_of_name (cont[len]))
6888     return cont + len;
6889 
6890   return NULL;
6891 }
6892 
6893 int
metag_parse_name(char const * name,expressionS * exprP,enum expr_mode mode,char * nextcharP)6894 metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
6895 		  char * nextcharP)
6896 {
6897   char *next = input_line_pointer;
6898   char *next_end;
6899   int reloc_type;
6900   operatorT op_type;
6901   segT segment;
6902 
6903   exprP->X_op_symbol = NULL;
6904   exprP->X_md = BFD_RELOC_UNUSED;
6905 
6906   if (strcmp (name, GOT_NAME) == 0)
6907     {
6908       if (! GOT_symbol)
6909 	GOT_symbol = symbol_find_or_make (name);
6910 
6911       exprP->X_add_symbol = GOT_symbol;
6912     no_suffix:
6913       /* If we have an absolute symbol or a
6914 	 reg, then we know its value now.  */
6915       segment = S_GET_SEGMENT (exprP->X_add_symbol);
6916       if (mode != expr_defer && segment == absolute_section)
6917 	{
6918 	  exprP->X_op = O_constant;
6919 	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6920 	  exprP->X_add_symbol = NULL;
6921 	}
6922       else if (mode != expr_defer && segment == reg_section)
6923 	{
6924 	  exprP->X_op = O_register;
6925 	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6926 	  exprP->X_add_symbol = NULL;
6927 	}
6928       else
6929 	{
6930 	  exprP->X_op = O_symbol;
6931 	  exprP->X_add_number = 0;
6932 	}
6933 
6934       return 1;
6935     }
6936 
6937   exprP->X_add_symbol = symbol_find_or_make (name);
6938 
6939   if (*nextcharP != '@')
6940     goto no_suffix;
6941   else if ((next_end = metag_end_of_match (next + 1, "GOTOFF")))
6942     {
6943       reloc_type = BFD_RELOC_METAG_GOTOFF;
6944       op_type = O_PIC_reloc;
6945     }
6946   else if ((next_end = metag_end_of_match (next + 1, "GOT")))
6947     {
6948       reloc_type = BFD_RELOC_METAG_GETSET_GOT;
6949       op_type = O_PIC_reloc;
6950     }
6951   else if ((next_end = metag_end_of_match (next + 1, "PLT")))
6952     {
6953       reloc_type = BFD_RELOC_METAG_PLT;
6954       op_type = O_PIC_reloc;
6955     }
6956   else if ((next_end = metag_end_of_match (next + 1, "TLSGD")))
6957     {
6958       reloc_type = BFD_RELOC_METAG_TLS_GD;
6959       op_type = O_PIC_reloc;
6960     }
6961   else if ((next_end = metag_end_of_match (next + 1, "TLSLDM")))
6962     {
6963       reloc_type = BFD_RELOC_METAG_TLS_LDM;
6964       op_type = O_PIC_reloc;
6965     }
6966   else if ((next_end = metag_end_of_match (next + 1, "TLSLDO")))
6967     {
6968       reloc_type = BFD_RELOC_METAG_TLS_LDO;
6969       op_type = O_PIC_reloc;
6970     }
6971   else if ((next_end = metag_end_of_match (next + 1, "TLSIE")))
6972     {
6973       reloc_type = BFD_RELOC_METAG_TLS_IE;
6974       op_type = O_PIC_reloc;
6975     }
6976   else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC")))
6977     {
6978       reloc_type = BFD_RELOC_METAG_TLS_IENONPIC;
6979       op_type = O_PIC_reloc;	/* FIXME: is this correct? */
6980     }
6981   else if ((next_end = metag_end_of_match (next + 1, "TLSLE")))
6982     {
6983       reloc_type = BFD_RELOC_METAG_TLS_LE;
6984       op_type = O_PIC_reloc;
6985     }
6986   else
6987     goto no_suffix;
6988 
6989   *input_line_pointer = *nextcharP;
6990   input_line_pointer = next_end;
6991   *nextcharP = *input_line_pointer;
6992   *input_line_pointer = '\0';
6993 
6994   exprP->X_op = op_type;
6995   exprP->X_add_number = 0;
6996   exprP->X_md = reloc_type;
6997 
6998   return 1;
6999 }
7000 
7001 /* If while processing a fixup, a reloc really needs to be created
7002    then it is done here.  */
7003 
7004 arelent *
tc_gen_reloc(asection * seg ATTRIBUTE_UNUSED,fixS * fixp)7005 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
7006 {
7007   arelent *reloc;
7008 
7009   reloc		      = XNEW (arelent);
7010   reloc->sym_ptr_ptr  = XNEW (asymbol *);
7011   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7012   reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
7013 
7014   reloc->addend = fixp->fx_offset;
7015   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
7016 
7017   if (reloc->howto == (reloc_howto_type *) NULL)
7018     {
7019       as_bad_where (fixp->fx_file, fixp->fx_line,
7020 		    /* xgettext:c-format.  */
7021 		    _("reloc %d not supported by object file format"),
7022 		    (int) fixp->fx_r_type);
7023 
7024       xfree (reloc);
7025 
7026       return NULL;
7027     }
7028 
7029   return reloc;
7030 }
7031 
7032 static unsigned int
md_chars_to_number(char * val,int n)7033 md_chars_to_number (char *val, int n)
7034 {
7035   int retval;
7036   unsigned char * where = (unsigned char *) val;
7037 
7038   for (retval = 0; n--;)
7039     {
7040       retval <<= 8;
7041       retval |= where[n];
7042     }
7043   return retval;
7044 }
7045 
7046 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)7047 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
7048 {
7049   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7050   int value = (int)*valP;
7051 
7052   switch (fixP->fx_r_type)
7053     {
7054     case BFD_RELOC_METAG_TLS_GD:
7055     case BFD_RELOC_METAG_TLS_LE_HI16:
7056     case BFD_RELOC_METAG_TLS_LE_LO16:
7057     case BFD_RELOC_METAG_TLS_IE:
7058     case BFD_RELOC_METAG_TLS_IENONPIC_HI16:
7059     case BFD_RELOC_METAG_TLS_IENONPIC_LO16:
7060     case BFD_RELOC_METAG_TLS_LDM:
7061     case BFD_RELOC_METAG_TLS_LDO_HI16:
7062     case BFD_RELOC_METAG_TLS_LDO_LO16:
7063       S_SET_THREAD_LOCAL (fixP->fx_addsy);
7064       /* Fall through */
7065 
7066     case BFD_RELOC_METAG_HIADDR16:
7067     case BFD_RELOC_METAG_LOADDR16:
7068     case BFD_RELOC_VTABLE_INHERIT:
7069     case BFD_RELOC_VTABLE_ENTRY:
7070       fixP->fx_done = FALSE;
7071       break;
7072 
7073     case BFD_RELOC_METAG_REL8:
7074       if (!within_unsigned_range (value, IMM8_BITS))
7075 	{
7076 	  as_bad_where (fixP->fx_file, fixP->fx_line,
7077 			"rel8 out of range %d", value);
7078 	}
7079       else
7080 	{
7081 	  unsigned int newval;
7082 	  newval = md_chars_to_number (buf, 4);
7083 	  newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6);
7084 	  md_number_to_chars (buf, newval, 4);
7085 	}
7086       break;
7087     case BFD_RELOC_METAG_REL16:
7088       if (!within_unsigned_range (value, IMM16_BITS))
7089 	{
7090 	  as_bad_where (fixP->fx_file, fixP->fx_line,
7091 			"rel16 out of range %d", value);
7092 	}
7093       else
7094 	{
7095 	  unsigned int newval;
7096 	  newval = md_chars_to_number (buf, 4);
7097 	  newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3);
7098 	  md_number_to_chars (buf, newval, 4);
7099 	}
7100       break;
7101 
7102     case BFD_RELOC_8:
7103       md_number_to_chars (buf, value, 1);
7104       break;
7105     case BFD_RELOC_16:
7106       md_number_to_chars (buf, value, 2);
7107       break;
7108     case BFD_RELOC_32:
7109       md_number_to_chars (buf, value, 4);
7110       break;
7111     case BFD_RELOC_64:
7112       md_number_to_chars (buf, value, 8);
7113 
7114     case BFD_RELOC_METAG_RELBRANCH:
7115       if (!value)
7116 	break;
7117 
7118       value = value / 4;
7119 
7120       if (!within_signed_range (value, IMM19_BITS))
7121 	{
7122 	  as_bad_where (fixP->fx_file, fixP->fx_line,
7123 			"relbranch out of range %d", value);
7124 	}
7125       else
7126 	{
7127 	  unsigned int newval;
7128 	  newval = md_chars_to_number (buf, 4);
7129 	  newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
7130 	  md_number_to_chars (buf, newval, 4);
7131 	}
7132 	break;
7133     default:
7134       break;
7135     }
7136 
7137   if (fixP->fx_addsy == NULL)
7138     fixP->fx_done = TRUE;
7139 }
7140