-Wimplicit-fallthrough error fixes
[deliverable/binutils-gdb.git] / gas / config / tc-metag.c
CommitLineData
a3c62988 1/* tc-metag.c -- Assembler for the Imagination Technologies Meta.
6f2750fe 2 Copyright (C) 2013-2016 Free Software Foundation, Inc.
a3c62988
NC
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"
a3c62988
NC
27
28#include <stdio.h>
29
30#include "opcode/metag.h"
31
32const char comment_chars[] = "!";
33const char line_comment_chars[] = "!#";
34const char line_separator_chars[] = ";";
35const char FLT_CHARS[] = "rRsSfFdDxXpP";
36const char EXP_CHARS[] = "eE";
37const char metag_symbol_chars[] = "[";
38
39static char register_chars[256];
40static char mnemonic_chars[256];
41
42#define is_register_char(x) (register_chars[(unsigned char) x])
43#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
44#define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
45#define is_space_char(x) ((x) == ' ')
46
47#define FPU_PREFIX_CHAR 'f'
48#define DSP_PREFIX_CHAR 'd'
49
50/* Instruction mnemonics that need disambiguating with respect to prefixes. */
51#define FFB_INSN "ffb"
52#define DCACHE_INSN "dcache"
53#define DEFR_INSN "defr"
54
55#define FPU_DOUBLE_CHAR 'd'
56#define FPU_PAIR_CHAR 'l'
57
58#define DSP_DUAL_CHAR 'l'
59
60#define END_OF_INSN '\0'
61
62/* Maximum length of a mnemonic including all suffixes. */
63#define MAX_MNEMONIC_LEN 16
64/* Maximum length of a register name. */
65#define MAX_REG_LEN 17
66
67/* Addressing modes must be enclosed with square brackets. */
68#define ADDR_BEGIN_CHAR '['
69#define ADDR_END_CHAR ']'
70/* Immediates must be prefixed with a hash. */
71#define IMM_CHAR '#'
72
73#define COMMA ','
74#define PLUS '+'
75#define MINUS '-'
76
77/* Short units are those that can be encoded with 2 bits. */
78#define SHORT_UNITS "D0, D1, A0 or A1"
79
80static unsigned int mcpu_opt = CoreMeta12;
81static unsigned int mfpu_opt = 0;
82static unsigned int mdsp_opt = 0;
83
84const char * md_shortopts = "m:";
85
86struct option md_longopts[] =
87{
88 {NULL, no_argument, NULL, 0}
89};
90size_t md_longopts_size = sizeof (md_longopts);
91
92/* Parser hash tables. */
93static htab_t mnemonic_htab;
94static htab_t reg_htab;
95static htab_t dsp_reg_htab;
96static htab_t dsp_tmpl_reg_htab[2];
97static htab_t scond_htab;
98
99#define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
100symbolS * GOT_symbol;
101
102enum fpu_insn_width {
103 FPU_WIDTH_SINGLE,
104 FPU_WIDTH_DOUBLE,
105 FPU_WIDTH_PAIR,
106};
107
108#define FPU_ACTION_ABS_CHAR 'a'
109#define FPU_ACTION_INV_CHAR 'i'
110#define FPU_ACTION_QUIET_CHAR 'q'
111#define FPU_ACTION_ZERO_CHAR 'z'
112
113#define FPU_ACTION_ABS 0x1
114#define FPU_ACTION_INV 0x2
115#define FPU_ACTION_QUIET 0x4
116#define FPU_ACTION_ZERO 0x8
117
118enum dsp_insn_width {
119 DSP_WIDTH_SINGLE,
120 DSP_WIDTH_DUAL,
121};
122
123#define DSP_ACTION_QR64_CHAR 'q'
124#define DSP_ACTION_UMUL_CHAR 'u'
125#define DSP_ACTION_ROUND_CHAR 'r'
126#define DSP_ACTION_CLAMP9_CHAR 'g'
127#define DSP_ACTION_CLAMP8_CHAR 'b'
128#define DSP_ACTION_MOD_CHAR 'm'
129#define DSP_ACTION_ACC_ZERO_CHAR 'z'
130#define DSP_ACTION_ACC_ADD_CHAR 'p'
131#define DSP_ACTION_ACC_SUB_CHAR 'n'
132#define DSP_ACTION_OV_CHAR 'o'
133
134#define DSP_ACTION_QR64 0x001
135#define DSP_ACTION_UMUL 0x002
136#define DSP_ACTION_ROUND 0x004
137#define DSP_ACTION_CLAMP9 0x008
138#define DSP_ACTION_CLAMP8 0x010
139#define DSP_ACTION_MOD 0x020
140#define DSP_ACTION_ACC_ZERO 0x040
141#define DSP_ACTION_ACC_ADD 0x080
142#define DSP_ACTION_ACC_SUB 0x100
143#define DSP_ACTION_OV 0x200
144
145#define DSP_DAOPPAME_8_CHAR 'b'
146#define DSP_DAOPPAME_16_CHAR 'w'
147#define DSP_DAOPPAME_TEMP_CHAR 't'
148#define DSP_DAOPPAME_HIGH_CHAR 'h'
149
150#define DSP_DAOPPAME_8 0x1
151#define DSP_DAOPPAME_16 0x2
152#define DSP_DAOPPAME_TEMP 0x4
153#define DSP_DAOPPAME_HIGH 0x8
154
155/* Structure holding information about a parsed instruction. */
156typedef struct {
157 /* Instruction type. */
158 enum insn_type type;
159 /* Split condition code. */
160 enum scond_code scond;
161
162 /* Instruction bits. */
163 unsigned int bits;
164 /* Size of the instruction in bytes. */
165 size_t len;
166
167 /* FPU instruction encoding. */
168 enum fpu_insn_width fpu_width;
169 unsigned int fpu_action_flags;
170
171 /* DSP instruction encoding. */
172 enum dsp_insn_width dsp_width;
173 unsigned int dsp_action_flags;
174 unsigned int dsp_daoppame_flags;
175
176 /* Reloc encoding information, maximum of one reloc per insn. */
177 enum bfd_reloc_code_real reloc_type;
178 int reloc_pcrel;
179 expressionS reloc_exp;
180 unsigned int reloc_size;
181} metag_insn;
182
183/* Structure holding information about a parsed addressing mode. */
184typedef struct {
185 const metag_reg *base_reg;
186 const metag_reg *offset_reg;
187
188 expressionS exp;
189
190 enum bfd_reloc_code_real reloc_type;
191
192 /* Whether we have an immediate or not. */
193 unsigned short immediate:1;
194 /* Whether or not the base register is updated. */
195 unsigned short update:1;
196 /* Whether the operation uses the address pre or post increment. */
197 unsigned short post_increment:1;
198 /* Whether the immediate should be negated. */
199 unsigned short negate:1;
200} metag_addr;
201
202/* Linked list of possible parsers for this instruction. */
203typedef struct _insn_templates {
204 const insn_template *template;
205 struct _insn_templates *next;
206} insn_templates;
207
208/* Parse an instruction that takes no operands. */
209static const char *
210parse_none (const char *line, metag_insn *insn,
211 const insn_template *template)
212{
213 insn->bits = template->meta_opcode;
214 insn->len = 4;
215 return line;
216}
217
218/* Return the next non-whitespace character in LINE or NULL. */
219static const char *
220skip_whitespace (const char *line)
221{
222 const char *l = line;
223
224 if (is_whitespace_char (*l))
225 {
226 l++;
227 }
228
229 return l;
230}
231
232/* Return the next non-space character in LINE or NULL. */
233static const char *
234skip_space (const char *line)
235{
236 const char *l = line;
237
238 if (is_space_char (*l))
239 {
240 l++;
241 }
242
243 return l;
244}
245
246/* Return the character after the current one in LINE if the current
247 character is a comma, otherwise NULL. */
248static const char *
249skip_comma (const char *line)
250{
251 const char *l = line;
252
253 if (l == NULL || *l != COMMA)
254 return NULL;
255
256 l++;
257
258 return l;
259}
260
261/* Return the metag_reg struct corresponding to NAME or NULL if no such
262 register exists. */
263static const metag_reg *
264parse_gp_reg (const char *name)
265{
266 const metag_reg *reg;
267 metag_reg entry;
268
269 entry.name = name;
270
271 reg = (const metag_reg *) htab_find (reg_htab, &entry);
272
273 return reg;
274}
275
276/* Parse a list of up to COUNT GP registers from LINE, returning the
277 registers parsed in REGS and the number parsed in REGS_READ. Return
278 a pointer to the next character or NULL. */
279static const char *
280parse_gp_regs_list (const char *line, const metag_reg **regs, size_t count,
281 size_t *regs_read)
282{
283 const char *l = line;
284 char reg_buf[MAX_REG_LEN];
285 int seen_regs = 0;
286 size_t i;
287
288 for (i = 0; i < count; i++)
289 {
290 size_t len = 0;
291 const char *next;
292
293 next = l;
294
295 if (i > 0)
296 {
297 l = skip_comma (l);
298 if (l == NULL)
299 {
300 *regs_read = seen_regs;
301 return next;
302 }
303 }
304
305 while (is_register_char (*l))
306 {
307 reg_buf[len] = *l;
308 l++;
309 len++;
310 if (!(len < MAX_REG_LEN))
311 return NULL;
312 }
313
314 reg_buf[len] = '\0';
315
316 if (len)
317 {
318 const metag_reg *reg = parse_gp_reg (reg_buf);
319
320 if (!reg)
321 {
322 *regs_read = seen_regs;
323 return next;
324 }
325 else
326 {
327 regs[i] = reg;
328 seen_regs++;
329 }
330 }
331 else
332 {
333 *regs_read = seen_regs;
334 return next;
335 }
336 }
337
338 *regs_read = seen_regs;
339 return l;
340}
341
342/* Parse a list of exactly COUNT GP registers from LINE, returning the
343 registers parsed in REGS. Return a pointer to the next character or NULL. */
344static const char *
345parse_gp_regs (const char *line, const metag_reg **regs, size_t count)
346{
347 const char *l = line;
348 size_t regs_read = 0;
349
350 l = parse_gp_regs_list (l, regs, count, &regs_read);
351
352 if (regs_read != count)
353 return NULL;
354 else
355 return l;
356}
357
358/* Parse a list of exactly COUNT FPU registers from LINE, returning the
359 registers parsed in REGS. Return a pointer to the next character or NULL. */
360static const char *
361parse_fpu_regs (const char *line, const metag_reg **regs, size_t count)
362{
363 const char *l = line;
364 size_t regs_read = 0;
365
366 l = parse_gp_regs_list (l, regs, count, &regs_read);
367
368 if (regs_read != count)
369 return NULL;
370 else
371 {
372 size_t i;
373 for (i = 0; i < count; i++)
374 {
375 if (regs[i]->unit != UNIT_FX)
376 return NULL;
377 }
378 return l;
379 }
380}
381
382/* Return TRUE if REG1 and REG2 are in paired units. */
383static bfd_boolean
384is_unit_pair (const metag_reg *reg1, const metag_reg *reg2)
385{
386 if ((reg1->unit == UNIT_A0 &&
387 (reg2->unit == UNIT_A1)) ||
388 (reg1->unit == UNIT_A1 &&
389 (reg2->unit == UNIT_A0)) ||
390 (reg1->unit == UNIT_D0 &&
391 (reg2->unit == UNIT_D1)) ||
392 (reg1->unit == UNIT_D1 &&
393 (reg2->unit == UNIT_D0)))
394 return TRUE;
395
396 return FALSE;
397}
398
399/* Return TRUE if REG1 and REG2 form a register pair. */
400static bfd_boolean
401is_reg_pair (const metag_reg *reg1, const metag_reg *reg2)
402{
403 if (reg1->unit == UNIT_FX &&
404 reg2->unit == UNIT_FX &&
405 reg2->no == reg1->no + 1)
406 return TRUE;
407
408 if (reg1->no != reg2->no)
409 return FALSE;
410
411 return is_unit_pair (reg1, reg2);
412}
413
414/* Parse a pair of GP registers from LINE, returning the registers parsed
415 in REGS. Return a pointer to the next character or NULL. */
416static const char *
417parse_pair_gp_regs (const char *line, const metag_reg **regs)
418{
419 const char *l = line;
420
421 l = parse_gp_regs (line, regs, 2);
422
423 if (l == NULL)
424 {
425 l = parse_gp_regs (line, regs, 1);
426
427 if (l == NULL)
428 return NULL;
429
430 if (regs[0]->unit == UNIT_RD)
431 return l;
432 else
433 return NULL;
434 }
435
436 if (is_reg_pair (regs[0], regs[1]))
437 return l;
438
439 return NULL;
440}
441
442/* Parse a unit-to-unit MOV instruction. */
443static const char *
444parse_mov_u2u (const char *line, metag_insn *insn,
445 const insn_template *template)
446{
447 const metag_reg *regs[2];
448
449 line = parse_gp_regs (line, regs, 2);
450
451 if (line == NULL)
452 return NULL;
453
454 if (!mfpu_opt && (regs[0]->unit == UNIT_FX || regs[1]->unit == UNIT_FX))
455 {
456 as_bad (_("no floating point unit specified"));
457 return NULL;
458 }
459
460 insn->bits = (template->meta_opcode |
461 (regs[1]->no << 19) |
462 (regs[0]->no << 14) |
463 (regs[1]->unit << 10) |
464 (regs[0]->unit << 5));
465 insn->len = 4;
466 return line;
467}
468
469/* Parse a MOV to port instruction. */
470static const char *
471parse_mov_port (const char *line, metag_insn *insn,
472 const insn_template *template)
473{
474 const char *l = line;
475 unsigned int is_movl = MINOR_OPCODE (template->meta_opcode) == MOVL_MINOR;
476 const metag_reg *dest_regs[2];
477 const metag_reg *port_regs[1];
478
479 if (is_movl)
480 l = parse_gp_regs (l, dest_regs, 2);
481 else
482 l = parse_gp_regs (l, dest_regs, 1);
483
484 if (l == NULL)
485 return NULL;
486
487 if (template->insn_type == INSN_FPU && dest_regs[0]->unit != UNIT_FX)
488 return NULL;
489
490 l = skip_comma (l);
491
492 if (l == NULL ||
493 *l == END_OF_INSN)
494 return NULL;
495
496 l = parse_gp_regs (l, port_regs, 1);
497
498 if (l == NULL)
499 return NULL;
500
501 if (port_regs[0]->unit != UNIT_RD ||
502 port_regs[0]->no != 0)
503 return NULL;
504
505 if (is_movl)
506 {
507 if (!is_unit_pair (dest_regs[0], dest_regs[1]))
508 return NULL;
509
510 insn->bits = (template->meta_opcode |
511 (dest_regs[0]->no << 14) |
512 (dest_regs[1]->no << 9) |
513 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 5));
514 }
515 else
516 insn->bits = (template->meta_opcode |
517 (dest_regs[0]->no << 14) |
518 (dest_regs[0]->unit << 5));
519
520 insn->len = 4;
521 return l;
522}
523
524/* Parse a MOVL to TTREC instruction. */
525static const char *
526parse_movl_ttrec (const char *line, metag_insn *insn,
527 const insn_template *template)
528{
529 const char *l = line;
530 const metag_reg *src_regs[2];
531 const metag_reg *dest_regs[1];
532
533 l = parse_gp_regs (l, dest_regs, 1);
534
535 if (l == NULL)
536 return NULL;
537
538 if (dest_regs[0]->unit != UNIT_TT ||
539 dest_regs[0]->no != 3)
540 return NULL;
541
542 l = skip_comma (l);
543
544 if (l == NULL ||
545 *l == END_OF_INSN)
546 return NULL;
547
548 l = parse_gp_regs (l, src_regs, 2);
549
550 if (l == NULL)
551 return NULL;
552
553 if (!is_unit_pair (src_regs[0], src_regs[1]))
554 return NULL;
555
556 insn->bits = (template->meta_opcode |
557 (src_regs[0]->no << 19) |
558 (src_regs[1]->no << 14) |
559 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 7));
560
561 insn->len = 4;
562 return l;
563}
564
565/* Parse an incrementing or decrementing addressing mode. */
566static const char *
567parse_addr_incr_op (const char *line, metag_addr *addr)
568{
569 const char *l = line;
570 const char *ll;
571
572 ll = l + 1;
573
574 if (*l == PLUS &&
575 *ll == PLUS)
576 {
577 addr->update = 1;
578 ll++;
579 return ll;
580 }
581 else if (*l == MINUS &&
582 *ll == MINUS)
583 {
584 addr->update = 1;
585 addr->negate = 1;
586 ll++;
587 return ll;
588 }
589 return NULL;
590}
591
592/* Parse an pre-incrementing or pre-decrementing addressing mode. */
593static const char *
594parse_addr_pre_incr_op (const char *line, metag_addr *addr)
595{
596 return parse_addr_incr_op (line, addr);
597}
598
599/* Parse an post-incrementing or post-decrementing addressing mode. */
600static const char *
601parse_addr_post_incr_op (const char *line, metag_addr *addr)
602{
603 const char *l;
604
605 l = parse_addr_incr_op (line, addr);
606
607 if (l == NULL)
608 return NULL;
609
610 addr->post_increment = 1;
611
612 return l;
613}
614
615/* Parse an infix addressing mode. */
616static const char *
617parse_addr_op (const char *line, metag_addr *addr)
618{
619 const char *l = line;
620 const char *ll;
621
622 ll = l + 1;
623
624 if (*l == PLUS)
625 {
626 if (*ll == PLUS)
627 {
628 addr->update = 1;
629 ll++;
630 return ll;
631 }
632 l++;
633 return l;
634 }
635 return NULL;
636}
637
638/* Parse the immediate portion of an addrssing mode. */
639static const char *
640parse_imm_addr (const char *line, metag_addr *addr)
641{
642 const char *l = line;
643 char *save_input_line_pointer;
644 expressionS *exp = &addr->exp;
645
646 /* Skip #. */
647 if (*l == '#')
648 l++;
649 else
650 return NULL;
651
652 save_input_line_pointer = input_line_pointer;
653 input_line_pointer = (char *) l;
654
655 expression (exp);
656
657 l = input_line_pointer;
658 input_line_pointer = save_input_line_pointer;
659
660 if (exp->X_op == O_absent || exp->X_op == O_big)
661 {
662 return NULL;
663 }
664 else if (exp->X_op == O_constant)
665 {
666 return l;
667 }
668 else
669 {
670 if (exp->X_op == O_PIC_reloc &&
671 exp->X_md == BFD_RELOC_METAG_GETSET_GOT)
672 {
673 exp->X_op = O_symbol;
674 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOT;
675 }
676 else if (exp->X_op == O_PIC_reloc &&
677 exp->X_md == BFD_RELOC_METAG_TLS_IE)
678 {
679 exp->X_op = O_symbol;
680 addr->reloc_type = BFD_RELOC_METAG_TLS_IE;
681 }
682 else if (exp->X_op == O_PIC_reloc &&
683 exp->X_md == BFD_RELOC_METAG_GOTOFF)
684 {
685 exp->X_op = O_symbol;
686 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOTOFF;
687 }
688 else
689 addr->reloc_type = BFD_RELOC_METAG_GETSETOFF;
690 return l;
691 }
692}
693
694/* Parse the offset portion of an addressing mode (register or immediate). */
695static const char *
696parse_addr_offset (const char *line, metag_addr *addr, int size)
697{
698 const char *l = line;
699 const metag_reg *regs[1];
700
701 if (*l == IMM_CHAR)
702 {
703 /* ++ is a valid operator in our addressing but not in an expr. Make
704 sure that the expression parser never sees it. */
705 char *ppp = strstr(l, "++");
706 char ppch = '+';
707
708 if (ppp)
709 *ppp = '\0';
710
711 l = parse_imm_addr (l, addr);
712
713 if (ppp)
714 *ppp = ppch;
715
716 if (l == NULL)
717 return NULL;
718
719 if (addr->exp.X_add_number % size)
720 {
721 as_bad (_("offset must be a multiple of %d"), size);
722 return NULL;
723 }
724
725 addr->immediate = 1;
726 return l;
727 }
728 else
729 {
730 l = parse_gp_regs (l, regs, 1);
731
732 if (l == NULL)
733 return NULL;
734
735 if (regs[0]->unit != addr->base_reg->unit)
736 {
737 as_bad (_("offset and base must be from the same unit"));
738 return NULL;
739 }
740
741 addr->offset_reg = regs[0];
742 return l;
743 }
744}
745
746/* Parse an addressing mode. */
747static const char *
748parse_addr (const char *line, metag_addr *addr, unsigned int size)
749{
750 const char *l = line;
751 const char *ll;
752 const metag_reg *regs[1];
753
754 /* Skip opening square bracket. */
755 l++;
756
757 ll = parse_addr_pre_incr_op (l, addr);
758
759 if (ll != NULL)
760 l = ll;
761
762 l = parse_gp_regs (l, regs, 1);
763
764 if (l == NULL)
765 return NULL;
766
767 addr->base_reg = regs[0];
768
769 if (*l == ADDR_END_CHAR)
770 {
771 addr->exp.X_op = O_constant;
772 addr->exp.X_add_symbol = NULL;
773 addr->exp.X_op_symbol = NULL;
774 if (addr->update == 1)
775 {
776 /* We have a pre increment/decrement. */
777 addr->exp.X_add_number = size;
778 }
779 else
780 {
781 /* Simple register with no offset (0 immediate). */
782 addr->exp.X_add_number = 0;
783 }
784 addr->immediate = 1;
785 l++;
786 return l;
787 }
788
789 /* We already had a pre increment/decrement. */
790 if (addr->update == 1)
791 return NULL;
792
793 ll = parse_addr_post_incr_op (l, addr);
794
795 if (ll && *ll == ADDR_END_CHAR)
796 {
797 if (addr->update == 1)
798 {
799 /* We have a post increment/decrement. */
800 addr->exp.X_op = O_constant;
801 addr->exp.X_add_number = size;
802 addr->exp.X_add_symbol = NULL;
803 addr->exp.X_op_symbol = NULL;
804 addr->post_increment = 1;
805 }
806 addr->immediate = 1;
807 ll++;
808 return ll;
809 }
810
811 addr->post_increment = 0;
812
813 l = parse_addr_op (l, addr);
814
815 if (l == NULL)
816 return NULL;
817
818 l = parse_addr_offset (l, addr, size);
819
820 if (l == NULL)
821 return NULL;
822
823 if (*l == ADDR_END_CHAR)
824 {
825 l++;
826 return l;
827 }
828
829 /* We already had a pre increment/decrement. */
830 if (addr->update == 1)
831 return NULL;
832
833 l = parse_addr_post_incr_op (l, addr);
834
835 if (l == NULL)
836 return NULL;
837
838 if (*l == ADDR_END_CHAR)
839 {
840 l++;
841 return l;
842 }
843
844 return NULL;
845}
846
847/* Parse a GET or pipeline MOV instruction. */
848static const char *
849parse_get (const char *line, const metag_reg **regs, metag_addr *addr,
850 unsigned int size, bfd_boolean is_mov)
851{
852 const char *l = line;
853
854 if (size == 8)
855 {
856 l = parse_pair_gp_regs (l, regs);
857
858 if (l == NULL)
859 return NULL;
860 }
861 else
862 {
863 l = parse_gp_regs (l, regs, 1);
864
865 if (l == NULL)
866 {
867 if (!is_mov)
868 as_bad (_("invalid destination register"));
869 return NULL;
870 }
871 }
872
873 l = skip_comma (l);
874
875 if (l == NULL ||
876 *l == END_OF_INSN)
877 return NULL;
878
879 l = parse_addr (l, addr, size);
880
881 if (l == NULL)
882 {
883 if (!is_mov)
884 as_bad (_("invalid memory operand"));
885 return NULL;
886 }
887
888 return l;
889}
890
891/* Parse a SET instruction. */
892static const char *
893parse_set (const char *line, const metag_reg **regs, metag_addr *addr,
894 unsigned int size)
895{
896 const char *l = line;
897
898 l = parse_addr (l, addr, size);
899
900 if (l == NULL)
901 {
902 as_bad (_("invalid memory operand"));
903 return NULL;
904 }
905
906 l = skip_comma (l);
907
908 if (l == NULL ||
909 *l == END_OF_INSN)
910 return NULL;
911
912 if (size == 8)
913 {
914 const char *ll = l;
915
916 ll = parse_pair_gp_regs (l, regs);
917
918 if (ll == NULL)
919 {
920 /* Maybe this is an RD register, which is 64 bits wide so needs no
921 pair. */
922 l = parse_gp_regs (l, regs, 1);
923
924 if (l == NULL ||
925 regs[0]->unit != UNIT_RD)
926 {
927 return NULL;
928 }
929 }
930 else
931 l = ll;
932 }
933 else
934 {
935 l = parse_gp_regs (l, regs, 1);
936
937 if (l == NULL)
938 {
939 as_bad (_("invalid source register"));
940 return NULL;
941 }
942 }
943
944 return l;
945}
946
947/* Check a signed integer value can be represented in the given number
948 of bits. */
949static bfd_boolean
950within_signed_range (int value, unsigned int bits)
951{
952 int min_val = -(1 << (bits - 1));
953 int max_val = (1 << (bits - 1)) - 1;
954 return (value <= max_val) && (value >= min_val);
955}
956
957/* Check an unsigned integer value can be represented in the given number
958 of bits. */
959static bfd_boolean
960within_unsigned_range (unsigned int value, unsigned int bits)
961{
962 return value < (unsigned int)(1 << bits);
963}
964
965/* Return TRUE if UNIT can be expressed using a short code. */
966static bfd_boolean
967is_short_unit (enum metag_unit unit)
968{
969 switch (unit)
970 {
971 case UNIT_A0:
972 case UNIT_A1:
973 case UNIT_D0:
974 case UNIT_D1:
975 return TRUE;
976 default:
977 return FALSE;
978 }
979}
980
981/* Copy reloc data from ADDR to INSN. */
982static void
983copy_addr_reloc (metag_insn *insn, metag_addr *addr)
984{
985 memcpy (&insn->reloc_exp, &addr->exp, sizeof(insn->reloc_exp));
986 insn->reloc_type = addr->reloc_type;
987}
988
989/* Parse a GET, SET or pipeline MOV instruction. */
990static const char *
991parse_get_set (const char *line, metag_insn *insn,
992 const insn_template *template)
993{
994 const char *l = line;
995 const metag_reg *regs[2];
996 metag_addr addr;
997 unsigned int size = metag_get_set_size_bytes (template->meta_opcode);
998 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
999 unsigned int reg_no;
1000
1001 memset(&addr, 0, sizeof(addr));
1002 addr.reloc_type = BFD_RELOC_UNUSED;
1003
1004 if (is_get)
1005 {
1006 bfd_boolean is_mov = strncmp (template->name, "MOV", 3) == 0;
1007
1008 l = parse_get (l, regs, &addr, size, is_mov);
1009
1010 if (l == NULL)
1011 return NULL;
1012
1013 if (!(regs[0]->unit == UNIT_D0 ||
1014 regs[0]->unit == UNIT_D1 ||
1015 regs[0]->unit == UNIT_A0 ||
1016 regs[0]->unit == UNIT_A1 ||
1017 (regs[0]->unit == UNIT_RD && is_mov) ||
1018 (regs[0]->unit == UNIT_CT && size == 4) ||
1019 (regs[0]->unit == UNIT_PC && size == 4) ||
1020 (regs[0]->unit == UNIT_TR && size == 4) ||
1021 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1022 regs[0]->unit == UNIT_FX))
1023 {
1024 as_bad (_("invalid destination unit"));
1025 return NULL;
1026 }
1027
1028 if (regs[0]->unit == UNIT_RD)
1029 {
1030 if (regs[0]->no == 0)
1031 {
1032 as_bad (_("mov cannot use RD port as destination"));
1033 return NULL;
1034 }
1035 }
1036
1037 reg_no = regs[0]->no;
1038 }
1039 else
1040 {
1041 l = parse_set (l, regs, &addr, size);
1042
1043 if (l == NULL)
1044 return NULL;
1045
1046 if (!(regs[0]->unit == UNIT_D0 ||
1047 regs[0]->unit == UNIT_D1 ||
1048 regs[0]->unit == UNIT_A0 ||
1049 regs[0]->unit == UNIT_A1 ||
1050 regs[0]->unit == UNIT_RD ||
1051 (regs[0]->unit == UNIT_CT && size == 4) ||
1052 (regs[0]->unit == UNIT_PC && size == 4) ||
1053 (regs[0]->unit == UNIT_TR && size == 4) ||
1054 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1055 regs[0]->unit == UNIT_FX))
1056 {
1057 as_bad (_("invalid source unit"));
1058 return NULL;
1059 }
1060
1061 if (addr.immediate == 0 &&
1062 (regs[0]->unit == addr.base_reg->unit ||
1063 (size == 8 && is_unit_pair (regs[0], addr.base_reg))))
1064 {
1065 as_bad (_("source and address units must not be shared for this addressing mode"));
1066 return NULL;
1067 }
1068
1069 if (regs[0]->unit == UNIT_RD)
1070 {
1071 if (regs[0]->no != 0)
1072 {
1073 as_bad (_("set can only use RD port as source"));
1074 return NULL;
1075 }
1076 reg_no = 16;
1077 }
1078 else
1079 reg_no = regs[0]->no;
1080 }
1081
1082 insn->bits = (template->meta_opcode |
1083 (reg_no << 19) |
1084 (regs[0]->unit << 1));
1085
1086 if (!is_short_unit (addr.base_reg->unit))
1087 {
1088 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1089 return NULL;
1090 }
1091
1092 insn->bits |= ((addr.base_reg->no << 14) |
1093 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1094
1095 if (addr.immediate)
1096 {
1097 int offset = addr.exp.X_add_number;
1098
1099 copy_addr_reloc (insn, &addr);
1100
1101 if (addr.negate)
1102 offset = -offset;
1103
1104 offset = offset / (int)size;
1105
1106 if (!within_signed_range (offset, GET_SET_IMM_BITS))
1107 {
1108 /* We already tried to encode as an extended GET/SET. */
1109 as_bad (_("offset value out of range"));
1110 return NULL;
1111 }
1112
1113 offset = offset & GET_SET_IMM_MASK;
1114
1115 insn->bits |= (0x1 << 25);
1116 insn->bits |= (offset << 8);
1117 }
1118 else
1119 {
1120 insn->bits |= (addr.offset_reg->no << 9);
1121 }
1122
1123 if (addr.update)
1124 insn->bits |= (0x1 << 7);
1125
1126 if (addr.post_increment)
1127 insn->bits |= 0x1;
1128
1129 insn->len = 4;
1130 return l;
1131}
1132
1133/* Parse an extended GET or SET instruction. */
1134static const char *
1135parse_get_set_ext (const char *line, metag_insn *insn,
1136 const insn_template *template)
1137{
1138 const char *l = line;
1139 const metag_reg *regs[2];
1140 metag_addr addr;
1141 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
1142 bfd_boolean is_get = MINOR_OPCODE (template->meta_opcode) == GET_EXT_MINOR;
1143 bfd_boolean is_mov = MINOR_OPCODE (template->meta_opcode) == MOV_EXT_MINOR;
1144 unsigned int reg_unit;
1145
1146 memset(&addr, 0, sizeof(addr));
1147 addr.reloc_type = BFD_RELOC_UNUSED;
1148
1149 if (is_get || is_mov)
1150 {
1151 l = parse_get (l, regs, &addr, size, is_mov);
1152 }
1153 else
1154 {
1155 l = parse_set (l, regs, &addr, size);
1156 }
1157
1158 if (l == NULL)
1159 return NULL;
1160
1161 /* Extended GET/SET does not support incrementing addressing. */
1162 if (addr.update)
1163 return NULL;
1164
1165 if (is_mov)
1166 {
1167 if (regs[0]->unit != UNIT_RD)
1168 {
1169 as_bad (_("destination unit must be RD"));
1170 return NULL;
1171 }
1172 reg_unit = 0;
1173 }
1174 else
1175 {
1176 if (!is_short_unit (regs[0]->unit))
1177 {
1178 return NULL;
1179 }
1180 reg_unit = regs[0]->unit;
1181 }
1182
1183 insn->bits = (template->meta_opcode |
1184 (regs[0]->no << 19) |
1185 ((reg_unit & SHORT_UNIT_MASK) << 3));
1186
1187 if (!is_short_unit (addr.base_reg->unit))
1188 {
1189 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1190 return NULL;
1191 }
1192
1193 if (addr.base_reg->no > 1)
1194 {
1195 return NULL;
1196 }
1197
1198 insn->bits |= ((addr.base_reg->no & EXT_BASE_REG_MASK) |
1199 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1200
1201 if (addr.immediate)
1202 {
1203 int offset = addr.exp.X_add_number;
1204
1205 copy_addr_reloc (insn, &addr);
1206
1207 if (addr.negate)
1208 offset = -offset;
1209
1210 offset = offset / (int)size;
1211
1212 if (!within_signed_range (offset, GET_SET_EXT_IMM_BITS))
1213 {
1214 /* Parsing as a standard GET/SET provides a smaller offset. */
1215 as_bad (_("offset value out of range"));
1216 return NULL;
1217 }
1218
1219 offset = offset & GET_SET_EXT_IMM_MASK;
1220
1221 insn->bits |= (offset << 7);
1222 }
1223 else
1224 {
1225 return NULL;
1226 }
1227
1228 insn->len = 4;
1229 return l;
1230}
1231
1232/* Parse an MGET or MSET instruction addressing mode. */
1233static const char *
1234parse_mget_mset_addr (const char *line, metag_addr *addr)
1235{
1236 const char *l = line;
1237 const char *ll;
1238 const metag_reg *regs[1];
1239
1240 /* Skip opening square bracket. */
1241 l++;
1242
1243 l = parse_gp_regs (l, regs, 1);
1244
1245 if (l == NULL)
1246 return NULL;
1247
1248 addr->base_reg = regs[0];
1249
1250 ll = parse_addr_post_incr_op (l, addr);
1251
1252 if (ll != NULL)
1253 l = ll;
1254
1255 if (addr->negate == 1)
1256 return NULL;
1257
1258 if (*l == ADDR_END_CHAR)
1259 {
1260 l++;
1261 return l;
1262 }
1263
1264 return NULL;
1265}
1266
1267/* Parse an MGET instruction. */
1268static const char *
1269parse_mget (const char *line, const metag_reg **regs, metag_addr *addr,
1270 size_t *regs_read)
1271{
1272 const char *l = line;
1273
1274 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1275
1276 if (l == NULL ||
1277 *regs_read == 0)
1278 {
1279 as_bad (_("invalid destination register list"));
1280 return NULL;
1281 }
1282
1283 l = skip_comma (l);
1284
1285 if (l == NULL ||
1286 *l == END_OF_INSN)
1287 return NULL;
1288
1289 l = parse_mget_mset_addr (l, addr);
1290
1291 if (l == NULL)
1292 {
1293 as_bad (_("invalid memory operand"));
1294 return NULL;
1295 }
1296
1297 return l;
1298}
1299
1300/* Parse an MSET instruction. */
1301static const char *
1302parse_mset (const char *line, const metag_reg **regs, metag_addr *addr,
1303 size_t *regs_read)
1304{
1305 const char *l = line;
1306
1307 l = parse_mget_mset_addr (l, addr);
1308
1309 if (l == NULL)
1310 {
1311 as_bad (_("invalid memory operand"));
1312 return NULL;
1313 }
1314
1315 l = skip_comma (l);
1316
1317 if (l == NULL ||
1318 *l == END_OF_INSN)
1319 return NULL;
1320
1321 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1322
1323 if (l == NULL ||
1324 *regs_read == 0)
1325 {
1326 as_bad (_("invalid source register list"));
1327 return NULL;
1328 }
1329
1330 return l;
1331}
1332
1333/* Take a register list REGS of size REGS_READ and convert it into an
1334 rmask value if possible. Return the rmask value in RMASK and the
1335 lowest numbered register in LOWEST_REG. Return TRUE if the conversion
1336 was successful. */
1337static bfd_boolean
1338check_rmask (const metag_reg **regs, size_t regs_read, bfd_boolean is_fpu,
1339 bfd_boolean is_64bit, unsigned int *lowest_reg,
1340 unsigned int *rmask)
1341{
1342 unsigned int reg_unit = regs[0]->unit;
1343 size_t i;
1344
1345 for (i = 0; i < regs_read; i++)
1346 {
1347 if (is_fpu)
1348 {
1349 if (is_64bit && regs[i]->no % 2)
1350 {
1351 as_bad (_("register list must be even numbered"));
1352 return FALSE;
1353 }
1354 }
1355 else if (regs[i]->unit != reg_unit)
1356 {
1357 as_bad (_("register list must be from the same unit"));
1358 return FALSE;
1359 }
1360
1361 if (regs[i]->no < *lowest_reg)
1362 *lowest_reg = regs[i]->no;
1363 }
1364
1365 for (i = 0; i < regs_read; i++)
1366 {
1367 unsigned int next_bit, next_reg;
1368 if (regs[i]->no == *lowest_reg)
1369 continue;
1370
1371 if (is_fpu && is_64bit)
1372 next_reg = ((regs[i]->no / 2) - ((*lowest_reg / 2) + 1));
1373 else
1374 next_reg = (regs[i]->no - (*lowest_reg + 1));
1375
1376 next_bit = (1 << next_reg);
1377
1378 if (*rmask & next_bit)
1379 {
1380 as_bad (_("register list must not contain duplicates"));
1381 return FALSE;
1382 }
1383
1384 *rmask |= next_bit;
1385 }
1386
1387 return TRUE;
1388}
1389
1390/* Parse an MGET or MSET instruction. */
1391static const char *
1392parse_mget_mset (const char *line, metag_insn *insn,
1393 const insn_template *template)
1394{
1395 const char *l = line;
1396 const metag_reg *regs[MGET_MSET_MAX_REGS];
1397 metag_addr addr;
1398 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
1399 bfd_boolean is_fpu = (MINOR_OPCODE (template->meta_opcode) & 0x6) == 0x6;
1400 bfd_boolean is_64bit = (MINOR_OPCODE (template->meta_opcode) & 0x1) == 0x1;
1401 size_t regs_read = 0;
1402 unsigned int rmask = 0, reg_unit = 0, lowest_reg = 0xffffffff;
1403
1404 memset(&addr, 0, sizeof(addr));
1405 addr.reloc_type = BFD_RELOC_UNUSED;
1406
1407 if (is_get)
1408 {
1409 l = parse_mget (l, regs, &addr, &regs_read);
1410 }
1411 else
1412 {
1413 l = parse_mset (l, regs, &addr, &regs_read);
1414 }
1415
1416 if (l == NULL)
1417 return NULL;
1418
1419 if (!check_rmask (regs, regs_read, is_fpu, is_64bit, &lowest_reg, &rmask))
1420 return NULL;
1421
1422 reg_unit = regs[0]->unit;
1423
1424 if (is_fpu)
1425 {
1426 if (reg_unit != UNIT_FX)
1427 return NULL;
1428
1429 reg_unit = 0;
1430 }
1431 else if (reg_unit == UNIT_FX)
1432 return NULL;
1433
1434 insn->bits = (template->meta_opcode |
1435 (lowest_reg << 19) |
1436 ((reg_unit & SHORT_UNIT_MASK) << 3));
1437
1438 if (!is_short_unit (addr.base_reg->unit))
1439 {
1440 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1441 return NULL;
1442 }
1443
1444 insn->bits |= ((addr.base_reg->no << 14) |
1445 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1446
1447 insn->bits |= (rmask & RMASK_MASK) << 7;
1448
1449 insn->len = 4;
1450 return l;
1451}
1452
1453/* Parse a list of registers for MMOV pipeline prime. */
1454static const char *
1455parse_mmov_prime_list (const char *line, const metag_reg **regs,
1456 unsigned int *rmask)
1457{
1458 const char *l = line;
1459 const metag_reg *ra_regs[MMOV_MAX_REGS];
1460 size_t regs_read = 0, i;
1461 unsigned int mask = 0;
1462
1463 l = parse_gp_regs_list (l, regs, 1, &regs_read);
1464
1465 /* First register must be a port. */
1466 if (l == NULL || regs[0]->unit != UNIT_RD)
1467 return NULL;
1468
1469 l = skip_comma (l);
1470
1471 if (l == NULL)
1472 return NULL;
1473
1474 l = parse_gp_regs_list (l, ra_regs, MMOV_MAX_REGS, &regs_read);
1475
1476 if (l == NULL)
1477 return NULL;
1478
1479 /* Check remaining registers match the first.
1480
1481 Note that we also accept RA (0x10) as input for the remaining registers.
1482 Whilst this doesn't represent the instruction in any way we're stuck
1483 with it because the embedded assembler accepts it. */
1484 for (i = 0; i < regs_read; i++)
1485 {
1486 if (ra_regs[i]->unit != UNIT_RD ||
1487 (ra_regs[i]->no != 0x10 && ra_regs[i]->no != regs[0]->no))
1488 return NULL;
1489
1490 mask = (mask << 1) | 0x1;
1491 }
1492
1493 *rmask = mask;
1494
1495 return l;
1496}
1497
1498/* Parse a MMOV instruction. */
1499static const char *
1500parse_mmov (const char *line, metag_insn *insn,
1501 const insn_template *template)
1502{
1503 const char *l = line;
1504 unsigned int is_fpu = template->insn_type == INSN_FPU;
1505 unsigned int is_prime = ((MINOR_OPCODE (template->meta_opcode) & 0x2) &&
1506 !is_fpu);
1507 unsigned int is_64bit = MINOR_OPCODE (template->meta_opcode) & 0x1;
1508 unsigned int rmask = 0;
1509
1510 if (is_prime)
1511 {
1512 const metag_reg *reg;
1513 metag_addr addr;
1514
1515 memset (&addr, 0, sizeof(addr));
1516
1517 l = parse_mmov_prime_list (l, &reg, &rmask);
1518
1519 if (l == NULL)
1520 return NULL;
1521
1522 l = skip_comma (l);
1523
1524 if (l == NULL)
1525 return NULL;
1526
1527 l = parse_mget_mset_addr (l, &addr);
1528
1529 if (l == NULL)
1530 {
1531 as_bad (_("invalid memory operand"));
1532 return NULL;
1533 }
1534
1535 insn->bits = (template->meta_opcode |
1536 (reg->no << 19) |
1537 (addr.base_reg->no << 14) |
1538 ((rmask & RMASK_MASK) << 7) |
1539 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1540 }
1541 else
1542 {
1543 const metag_reg *regs[MMOV_MAX_REGS + 1];
1544 unsigned int lowest_reg = 0xffffffff;
1545 size_t regs_read = 0;
1546
1547 l = parse_gp_regs_list (l, regs, MMOV_MAX_REGS + 1, &regs_read);
1548
1549 if (l == NULL || regs_read == 0)
1550 return NULL;
1551
1552 if (!is_short_unit (regs[0]->unit) &&
1553 !(is_fpu && regs[0]->unit == UNIT_FX))
1554 {
1555 return NULL;
1556 }
1557
1558 if (!(regs[regs_read-1]->unit == UNIT_RD &&
1559 regs[regs_read-1]->no == 0))
1560 {
1561 return NULL;
1562 }
1563
1564 if (!check_rmask (regs, regs_read - 1, is_fpu, is_64bit, &lowest_reg,
1565 &rmask))
1566 return NULL;
1567
1568 if (is_fpu)
1569 {
1570 insn->bits = (template->meta_opcode |
1571 (regs[0]->no << 14) |
1572 ((rmask & RMASK_MASK) << 7));
1573 }
1574 else
1575 {
1576 insn->bits = (template->meta_opcode |
1577 (regs[0]->no << 19) |
1578 ((rmask & RMASK_MASK) << 7) |
1579 ((regs[0]->unit & SHORT_UNIT_MASK) << 3));
1580 }
1581 }
1582
1583 insn->len = 4;
1584 return l;
1585}
1586
1587/* Parse an immediate constant. */
1588static const char *
1589parse_imm_constant (const char *line, metag_insn *insn, int *value)
1590{
1591 const char *l = line;
1592 char *save_input_line_pointer;
1593 expressionS *exp = &insn->reloc_exp;
1594
1595 /* Skip #. */
1596 if (*l == '#')
1597 l++;
1598 else
1599 return NULL;
1600
1601 save_input_line_pointer = input_line_pointer;
1602 input_line_pointer = (char *) l;
1603
1604 expression (exp);
1605
1606 l = input_line_pointer;
1607 input_line_pointer = save_input_line_pointer;
1608
1609 if (exp->X_op == O_constant)
1610 {
1611 *value = exp->X_add_number;
1612
1613 return l;
1614 }
1615 else
1616 {
1617 return NULL;
1618 }
1619}
1620
1621/* Parse an MDRD instruction. */
1622static const char *
1623parse_mdrd (const char *line, metag_insn *insn,
1624 const insn_template *template)
1625{
1626 const char *l = line;
1627 unsigned int rmask = 0;
1628 int value = 0, i;
1629
1630 l = parse_imm_constant (l, insn, &value);
1631
1632 if (l == NULL)
1633 return NULL;
1634
1635 if (value < 1 || value > 8)
1636 {
1637 as_bad (_("MDRD value must be between 1 and 8"));
1638 return NULL;
1639 }
1640
1641 for (i = 1; i < value; i++)
1642 {
1643 rmask <<= 1;
1644 rmask |= 1;
1645 }
1646
1647 insn->bits = (template->meta_opcode |
1648 (rmask << 7));
1649
1650 insn->len = 4;
1651 return l;
1652}
1653
1654/* Parse a conditional SET instruction. */
1655static const char *
1656parse_cond_set (const char *line, metag_insn *insn,
1657 const insn_template *template)
1658{
1659 const char *l = line;
1660 const metag_reg *regs[2];
1661 metag_addr addr;
1662 unsigned int size = metag_cond_set_size_bytes (template->meta_opcode);
1663 unsigned int reg_no;
1664
1665 memset(&addr, 0, sizeof(addr));
1666 addr.reloc_type = BFD_RELOC_UNUSED;
1667
1668 l = parse_set (l, regs, &addr, size);
1669
1670 if (l == NULL)
1671 return NULL;
1672
1673 if (regs[0]->unit == UNIT_RD)
1674 {
1675 if (regs[0]->no != 0)
1676 {
1677 as_bad (_("set can only use RD port as source"));
1678 return NULL;
1679 }
1680 reg_no = 16;
1681 }
1682 else
1683 reg_no = regs[0]->no;
1684
1685 if (addr.update)
1686 return NULL;
1687
1688 if (!(addr.immediate &&
1689 addr.exp.X_add_number == 0))
1690 return NULL;
1691
1692 insn->bits = (template->meta_opcode |
1693 (reg_no << 19) |
1694 (regs[0]->unit << 10));
1695
1696 if (!is_short_unit (addr.base_reg->unit))
1697 {
1698 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1699 return NULL;
1700 }
1701
1702 insn->bits |= ((addr.base_reg->no << 14) |
1703 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1704
1705 insn->len = 4;
1706 return l;
1707}
1708
1709/* Parse an XFR instruction. */
1710static const char *
1711parse_xfr (const char *line, metag_insn *insn,
1712 const insn_template *template)
1713{
1714 const char *l = line;
1715 metag_addr dest_addr, src_addr;
1716 unsigned int size = 4;
1717
1718 memset(&dest_addr, 0, sizeof(dest_addr));
1719 memset(&src_addr, 0, sizeof(src_addr));
1720 dest_addr.reloc_type = BFD_RELOC_UNUSED;
1721 src_addr.reloc_type = BFD_RELOC_UNUSED;
1722
1723 l = parse_addr (l, &dest_addr, size);
1724
1725 if (l == NULL ||
1726 dest_addr.immediate == 1)
1727 {
1728 as_bad (_("invalid destination memory operand"));
1729 return NULL;
1730 }
1731
1732 l = skip_comma (l);
1733
1734 if (l == NULL ||
1735 *l == END_OF_INSN)
1736 return NULL;
1737
1738 l = parse_addr (l, &src_addr, size);
1739
1740 if (l == NULL ||
1741 src_addr.immediate == 1)
1742 {
1743 as_bad (_("invalid source memory operand"));
1744 return NULL;
1745 }
1746
1747 if (!is_short_unit (dest_addr.base_reg->unit) ||
1748 !is_short_unit (src_addr.base_reg->unit))
1749 {
1750 as_bad (_("address units must be one of %s"), SHORT_UNITS);
1751 return NULL;
1752 }
1753
1754 if ((dest_addr.base_reg->unit != dest_addr.offset_reg->unit) ||
1755 (src_addr.base_reg->unit != src_addr.offset_reg->unit))
1756 {
1757 as_bad (_("base and offset must be from the same unit"));
1758 return NULL;
1759 }
1760
1761 if (dest_addr.update == 1 &&
1762 src_addr.update == 1 &&
1763 dest_addr.post_increment != src_addr.post_increment)
1764 {
1765 as_bad (_("source and destination increment mode must agree"));
1766 return NULL;
1767 }
1768
1769 insn->bits = (template->meta_opcode |
1770 (src_addr.base_reg->no << 19) |
1771 (src_addr.offset_reg->no << 14) |
1772 ((src_addr.base_reg->unit & SHORT_UNIT_MASK) << 2));
1773
1774 insn->bits |= ((dest_addr.base_reg->no << 9) |
1775 (dest_addr.offset_reg->no << 4) |
1776 ((dest_addr.base_reg->unit & SHORT_UNIT_MASK)));
1777
1778 if (dest_addr.update == 1)
1779 insn->bits |= (1 << 26);
1780
1781 if (src_addr.update == 1)
1782 insn->bits |= (1 << 27);
1783
1784 if (dest_addr.post_increment == 1 ||
1785 src_addr.post_increment == 1)
1786 insn->bits |= (1 << 24);
1787
1788 insn->len = 4;
1789 return l;
1790}
1791
1792/* Parse an 8bit immediate value. */
1793static const char *
1794parse_imm8 (const char *line, metag_insn *insn, int *value)
1795{
1796 const char *l = line;
1797 char *save_input_line_pointer;
1798 expressionS *exp = &insn->reloc_exp;
1799
1800 /* Skip #. */
1801 if (*l == '#')
1802 l++;
1803 else
1804 return NULL;
1805
1806 save_input_line_pointer = input_line_pointer;
1807 input_line_pointer = (char *) l;
1808
1809 expression (exp);
1810
1811 l = input_line_pointer;
1812 input_line_pointer = save_input_line_pointer;
1813
1814 if (exp->X_op == O_absent || exp->X_op == O_big)
1815 {
1816 return NULL;
1817 }
1818 else if (exp->X_op == O_constant)
1819 {
1820 *value = exp->X_add_number;
1821 }
1822 else
1823 {
1824 insn->reloc_type = BFD_RELOC_METAG_REL8;
1825 insn->reloc_pcrel = 0;
1826 }
1827
1828 return l;
1829}
1830
1831/* Parse a 16bit immediate value. */
1832static const char *
1833parse_imm16 (const char *line, metag_insn *insn, int *value)
1834{
1835 const char *l = line;
1836 char *save_input_line_pointer;
1837 expressionS *exp = &insn->reloc_exp;
1838 bfd_boolean is_hi = FALSE;
1839 bfd_boolean is_lo = FALSE;
1840
1841 /* Skip #. */
1842 if (*l == '#')
1843 l++;
1844 else
1845 return NULL;
1846
1847 if (strncasecmp (l, "HI", 2) == 0)
1848 {
1849 is_hi = TRUE;
1850 l += 2;
1851 }
1852 else if (strncasecmp (l, "LO", 2) == 0)
1853 {
1854 is_lo = TRUE;
1855 l += 2;
1856 }
1857
1858 save_input_line_pointer = input_line_pointer;
1859 input_line_pointer = (char *) l;
1860
1861 expression (exp);
1862
1863 l = input_line_pointer;
1864 input_line_pointer = save_input_line_pointer;
1865
1866 if (exp->X_op == O_absent || exp->X_op == O_big)
1867 {
1868 return NULL;
1869 }
1870 else if (exp->X_op == O_constant)
1871 {
1872 if (is_hi)
1873 *value = (exp->X_add_number >> 16) & IMM16_MASK;
1874 else if (is_lo)
1875 *value = exp->X_add_number & IMM16_MASK;
1876 else
1877 *value = exp->X_add_number;
1878 }
1879 else
1880 {
1881 if (exp->X_op == O_PIC_reloc)
1882 {
1883 exp->X_op = O_symbol;
1884
1885 if (exp->X_md == BFD_RELOC_METAG_GOTOFF)
1886 {
1887 if (is_hi)
1888 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTOFF;
1889 else if (is_lo)
1890 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTOFF;
1891 else
1892 return NULL;
1893 }
1894 else if (exp->X_md == BFD_RELOC_METAG_PLT)
1895 {
1896 if (is_hi)
1897 insn->reloc_type = BFD_RELOC_METAG_HI16_PLT;
1898 else if (is_lo)
1899 insn->reloc_type = BFD_RELOC_METAG_LO16_PLT;
1900 else
1901 return NULL;
1902 }
1903 else if (exp->X_md == BFD_RELOC_METAG_TLS_LDO)
1904 {
1905 if (is_hi)
1906 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_HI16;
1907 else if (is_lo)
1908 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_LO16;
1909 else
1910 return NULL;
1911 }
1912 else if (exp->X_md == BFD_RELOC_METAG_TLS_IENONPIC)
1913 {
1914 if (is_hi)
1915 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_HI16;
1916 else if (is_lo)
1917 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_LO16;
1918 else
1919 return NULL;
1920 }
1921 else if (exp->X_md == BFD_RELOC_METAG_TLS_LE)
1922 {
1923 if (is_hi)
1924 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_HI16;
1925 else if (is_lo)
1926 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_LO16;
1927 else
1928 return NULL;
1929 }
1930 else if (exp->X_md == BFD_RELOC_METAG_TLS_GD ||
1931 exp->X_md == BFD_RELOC_METAG_TLS_LDM)
1932 insn->reloc_type = exp->X_md;
1933 }
1934 else
1935 {
1936 if (exp->X_op == O_symbol && exp->X_add_symbol == GOT_symbol)
1937 {
1938 if (is_hi)
1939 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTPC;
1940 else if (is_lo)
1941 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTPC;
1942 else
1943 return NULL;
1944 }
1945 else
1946 {
1947 if (is_hi)
1948 insn->reloc_type = BFD_RELOC_METAG_HIADDR16;
1949 else if (is_lo)
1950 insn->reloc_type = BFD_RELOC_METAG_LOADDR16;
1951 else
1952 insn->reloc_type = BFD_RELOC_METAG_REL16;
1953 }
1954 }
1955
1956 insn->reloc_pcrel = 0;
1957 }
1958
1959 return l;
1960}
1961
1962/* Parse a MOV to control unit instruction. */
1963static const char *
1964parse_mov_ct (const char *line, metag_insn *insn,
1965 const insn_template *template)
1966{
1967 const char *l = line;
1968 const metag_reg *regs[1];
1969 unsigned int top = template->meta_opcode & 0x1;
1970 unsigned int is_trace = (template->meta_opcode >> 2) & 0x1;
1971 unsigned int sign_extend = 0;
1972 int value = 0;
1973
1974 l = parse_gp_regs (l, regs, 1);
1975
1976 if (l == NULL)
1977 return NULL;
1978
1979 if (is_trace)
1980 {
1981 if (regs[0]->unit != UNIT_TT)
1982 return NULL;
1983 }
1984 else
1985 {
1986 if (regs[0]->unit != UNIT_CT)
1987 return NULL;
1988 }
1989
1990 l = skip_comma (l);
1991
1992 if (l == NULL ||
1993 *l == END_OF_INSN)
1994 return NULL;
1995
1996 l = parse_imm16 (l, insn, &value);
1997
1998 if (l == NULL)
1999 return NULL;
2000
2001 if (value < 0)
2002 sign_extend = 1;
2003
2004 insn->bits = (template->meta_opcode |
2005 (regs[0]->no << 19) |
2006 ((value & IMM16_MASK) << 3));
2007
2008 if (sign_extend == 1 && top == 0)
2009 insn->bits |= (1 << 1);
2010
2011 insn->len = 4;
2012 return l;
2013}
2014
2015/* Parse a SWAP instruction. */
2016static const char *
2017parse_swap (const char *line, metag_insn *insn,
2018 const insn_template *template)
2019{
2020 const char *l = line;
2021 const metag_reg *regs[2];
2022
2023 l = parse_gp_regs (l, regs, 2);
2024
2025 if (l == NULL)
2026 return NULL;
2027
f9b2d544
NC
2028 /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit. */
2029 switch (regs[0]->unit)
2030 {
2031 case UNIT_PC:
2032 case UNIT_CT:
2033 case UNIT_TR:
2034 case UNIT_TT:
2035 if (regs[1]->unit == UNIT_PC
2036 || regs[1]->unit == UNIT_CT
2037 || regs[1]->unit == UNIT_TR
2038 || regs[1]->unit == UNIT_TT)
2039 {
2040 as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
2041 return NULL;
2042 }
2b804145 2043 break;
f9b2d544
NC
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));
a3c62988
NC
2060
2061 insn->len = 4;
2062 return l;
2063}
2064
2065/* Parse a JUMP instruction. */
2066static const char *
2067parse_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. */
2106static const char *
2107parse_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. */
2153static const char *
2154parse_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. */
2207static int
2208lookup_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. */
2286static const char *
2287parse_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. */
2701static const char *
2702parse_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. */
2727static const char *
2728parse_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. */
2755static const char *
2756parse_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. */
2781static const char *
2782parse_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. */
2873static const char *
2874parse_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. */
2906static const char *
2907parse_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. */
2960static const char *
2961parse_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. */
3080static const char *
3081parse_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. */
3147static const char *
3148parse_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. */
3214static const char *
3215parse_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. */
3249static const char *
3250parse_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. */
3316static const char *
3317parse_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. */
3342static const char *
3343parse_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. */
3454static const char *
3455parse_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. */
3506static const char *
3507parse_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. */
3541static const char *
3542parse_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. */
3569static const char *
3570parse_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. */
3599static const char *
3600parse_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. */
3652static const char *
3653parse_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. */
3679static const char *
3680parse_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. */
3745static const char *
3746parse_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. */
3808static const char *
3809parse_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. */
3838static const char *
3839parse_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. */
3860static const char *
3861parse_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. */
3933static const char *
3934parse_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. */
3967static const char *
3968parse_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. */
4011static const char *
4012parse_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. */
4066static size_t
4067strip_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. */
4089static const char *
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. */
4128static const char *
4129parse_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. */
4140static const char *
4141parse_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. */
4148static const char *
4149parse_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. */
4159static bfd_boolean
4160is_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. */
4173static bfd_boolean
4174is_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. */
4213static bfd_boolean
4214is_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. */
4227static bfd_boolean
4228is_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. */
4237static bfd_boolean
4238is_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
4246static const char *
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. */
4301static const char *
4302parse_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--] */
4372static const char *
4373parse_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. */
4471static const char *
4472parse_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. */
4617static const char *
4618parse_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. */
4722static const char *
4723template_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. */
4743static const char *
4744parse_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
4797static metag_reg _reg;
4798
4799/* Parse a template instruction definition. */
4800static const char *
4801interpret_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? */
4892static bfd_boolean
4893units_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. */
4936static bfd_boolean
4937is_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
4953static metag_reg o2r_reg;
4954
4955/* Parse a DaOpPaMe load template definition. */
4956static const char *
4957parse_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
5739typedef const char *(*insn_parser)(const char *, metag_insn *,
5740 const insn_template *);
5741
5742/* Parser table. */
5743static 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
5792struct metag_core_option
5793{
e0471c16 5794 const char *name;
a3c62988
NC
5795 unsigned int value;
5796};
5797
5798/* CPU type options. */
5799static 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. */
5809static const struct metag_core_option metag_fpus[] =
5810 {
5811 {"metac21", FpuMeta21},
5812 {NULL, 0},
5813 };
5814
5815/* DSP type options. */
5816static const struct metag_core_option metag_dsps[] =
5817 {
5818 {"metac21", DspMeta21},
5819 {NULL, 0},
5820 };
5821
5822/* Parse a CPU command line option. */
5823static int
17b9d67d 5824metag_parse_cpu (const char * str)
a3c62988
NC
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. */
5849static int
17b9d67d 5850metag_parse_fpu (const char * str)
a3c62988
NC
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. */
5875static int
17b9d67d 5876metag_parse_dsp (const char * str)
a3c62988
NC
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
5900struct metag_long_option
5901{
e0471c16
TS
5902 const char * option; /* Substring to match. */
5903 const char * help; /* Help information. */
17b9d67d 5904 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 5905 const char * deprecated; /* If non-null, print this message. */
a3c62988
NC
5906};
5907
5908struct 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
5919int
17b9d67d 5920md_parse_option (int c, const char * arg)
a3c62988
NC
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
5947void
5948md_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. */
5960const pseudo_typeS md_pseudo_table[] =
5961{
5962 { "word", cons, 2 },
5963 { NULL, NULL, 0 }
5964};
5965
5966void
5967md_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. */
5997static const char *
5998parse_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. */
6022static const char *
6023parse_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. */
6262static insn_templates *
6263find_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. */
6282static char *
6283strupper (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. */
6299static hashval_t
6300hash_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. */
6311static int
6312eq_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. */
6320static void
6321create_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
add39d23 6334 new_entry = XNEW (insn_templates);
a3c62988
NC
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. */
6359static hashval_t
6360hash_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. */
6371static int
6372eq_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. */
6380static void
6381create_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. */
6401static void
6402create_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. */
76e7a751 6419 gas_assert (*slot == NULL);
a3c62988
NC
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. */
76e7a751 6442 gas_assert (*slot == NULL);
a3c62988
NC
6443 *slot = reg;
6444 }
6445 }
6446}
6447
6448/* Calculate a hash value for a split condition code. */
6449static hashval_t
6450hash_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. */
6461static int
6462eq_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. */
6471static void
6472create_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. */
76e7a751 6489 gas_assert (*slot == NULL);
a3c62988
NC
6490 *slot = scond;
6491 }
6492}
6493
6494/* Entry point for instruction parsing. */
6495static bfd_boolean
6496parse_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
6587static void
6588output_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
6605void
6606md_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
6651void
6652md_operand (expressionS * expressionP)
6653{
6654 if (* input_line_pointer == IMM_CHAR)
6655 {
6656 input_line_pointer ++;
6657 expression (expressionP);
6658 }
6659}
6660
6661valueT
6662md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
6663{
6664 return size;
6665}
6666
6667symbolS *
6668md_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
6678long
6679md_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
6696void
6697md_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
6d4af3c2 6710const char *
a3c62988
NC
6711md_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
6761int
6762metag_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
6780bfd_boolean
6781metag_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
6822int
6823md_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
6837void
6838md_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
6847void
6848metag_handle_align (fragS * fragP)
6849{
81cead6f 6850 static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
a3c62988
NC
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
6881static char *
e0471c16 6882metag_end_of_match (char * cont, const char * what)
a3c62988
NC
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
6893int
6894metag_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
7004arelent *
e6c7cdec 7005tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
a3c62988
NC
7006{
7007 arelent *reloc;
7008
add39d23
TS
7009 reloc = XNEW (arelent);
7010 reloc->sym_ptr_ptr = XNEW (asymbol *);
a3c62988
NC
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
7032static unsigned int
7033md_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
7046void
7047md_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);
2b804145 7113 break;
a3c62988
NC
7114
7115 case BFD_RELOC_METAG_RELBRANCH:
7116 if (!value)
7117 break;
7118
7119 value = value / 4;
7120
7121 if (!within_signed_range (value, IMM19_BITS))
7122 {
7123 as_bad_where (fixP->fx_file, fixP->fx_line,
7124 "relbranch out of range %d", value);
7125 }
7126 else
7127 {
7128 unsigned int newval;
7129 newval = md_chars_to_number (buf, 4);
7130 newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
7131 md_number_to_chars (buf, newval, 4);
7132 }
7133 break;
7134 default:
7135 break;
7136 }
7137
7138 if (fixP->fx_addsy == NULL)
7139 fixP->fx_done = TRUE;
7140}
This page took 0.437304 seconds and 4 git commands to generate.