Don't include libbfd.h outside of bfd, part 1
[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 }
2043
2044 default:
2045 /* Registers must be in different units. */
2046 if (regs[0]->unit == regs[1]->unit)
2047 {
2048 as_bad (_("source and destination register must be in different units"));
2049 return NULL;
2050 }
2051 break;
2052 }
2053
2054 insn->bits = (template->meta_opcode
2055 | (regs[1]->no << 19)
2056 | (regs[0]->no << 14)
2057 | (regs[1]->unit << 10)
2058 | (regs[0]->unit << 5));
a3c62988
NC
2059
2060 insn->len = 4;
2061 return l;
2062}
2063
2064/* Parse a JUMP instruction. */
2065static const char *
2066parse_jump (const char *line, metag_insn *insn,
2067 const insn_template *template)
2068{
2069 const char *l = line;
2070 const metag_reg *regs[1];
2071 int value = 0;
2072
2073 l = parse_gp_regs (l, regs, 1);
2074
2075 if (l == NULL)
2076 return NULL;
2077
2078 if (!is_short_unit (regs[0]->unit))
2079 {
2080 as_bad (_("register unit must be one of %s"), SHORT_UNITS);
2081 return FALSE;
2082 }
2083
2084 l = skip_comma (l);
2085
2086 if (l == NULL ||
2087 *l == END_OF_INSN)
2088 return NULL;
2089
2090 l = parse_imm16 (l, insn, &value);
2091
2092 if (l == NULL)
2093 return NULL;
2094
2095 insn->bits = (template->meta_opcode |
2096 (regs[0]->no << 19) |
2097 (regs[0]->unit & SHORT_UNIT_MASK) |
2098 ((value & IMM16_MASK) << 3));
2099
2100 insn->len = 4;
2101 return l;
2102}
2103
2104/* Parse a 19bit immediate value. */
2105static const char *
2106parse_imm19 (const char *line, metag_insn *insn, int *value)
2107{
2108 const char *l = line;
2109 char *save_input_line_pointer;
2110 expressionS *exp = &insn->reloc_exp;
2111
2112 /* Skip #. */
2113 if (*l == '#')
2114 l++;
2115
2116 save_input_line_pointer = input_line_pointer;
2117 input_line_pointer = (char *) l;
2118
2119 expression (exp);
2120
2121 l = input_line_pointer;
2122 input_line_pointer = save_input_line_pointer;
2123
2124 if (exp->X_op == O_absent || exp->X_op == O_big)
2125 {
2126 return NULL;
2127 }
2128 else if (exp->X_op == O_constant)
2129 {
2130 *value = exp->X_add_number;
2131 }
2132 else
2133 {
2134 if (exp->X_op == O_PIC_reloc)
2135 {
2136 exp->X_op = O_symbol;
2137
2138 if (exp->X_md == BFD_RELOC_METAG_PLT)
2139 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT;
2140 else
2141 return NULL;
2142 }
2143 else
2144 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH;
2145 insn->reloc_pcrel = 1;
2146 }
2147
2148 return l;
2149}
2150
2151/* Parse a CALLR instruction. */
2152static const char *
2153parse_callr (const char *line, metag_insn *insn,
2154 const insn_template *template)
2155{
2156 const char *l = line;
2157 const metag_reg *regs[1];
2158 int value = 0;
2159
2160 l = parse_gp_regs (l, regs, 1);
2161
2162 if (l == NULL)
2163 return NULL;
2164
2165 if (!is_short_unit (regs[0]->unit))
2166 {
2167 as_bad (_("link register unit must be one of %s"), SHORT_UNITS);
2168 return NULL;
2169 }
2170
2171 if (regs[0]->no & ~CALLR_REG_MASK)
2172 {
2173 as_bad (_("link register must be in a low numbered register"));
2174 return NULL;
2175 }
2176
2177 l = skip_comma (l);
2178
2179 if (l == NULL ||
2180 *l == END_OF_INSN)
2181 return NULL;
2182
2183 l = parse_imm19 (l, insn, &value);
2184
2185 if (l == NULL)
2186 return NULL;
2187
2188 if (!within_signed_range (value / 4, IMM19_BITS))
2189 {
2190 as_bad (_("target out of range"));
2191 return NULL;
2192 }
2193
2194 insn->bits = (template->meta_opcode |
2195 (regs[0]->no & CALLR_REG_MASK) |
2196 ((regs[0]->unit & SHORT_UNIT_MASK) << 3) |
2197 ((value & IMM19_MASK) << 5));
2198
2199 insn->len = 4;
2200 return l;
2201}
2202
2203/* Return the value for the register field if we apply the O2R modifier
2204 to operand 2 REG, combined with UNIT_BIT derived from the destination
2205 register or source1. Uses address unit O2R if IS_ADDR is set. */
2206static int
2207lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg)
2208{
2209 if (reg->no & ~O2R_REG_MASK)
2210 return -1;
2211
2212 if (is_addr)
2213 {
2214 if (unit_bit)
2215 {
2216 switch (reg->unit)
2217 {
2218 case UNIT_D1:
2219 return reg->no;
2220 case UNIT_D0:
2221 return (1 << 3) | reg->no;
2222 case UNIT_RD:
2223 return (2 << 3) | reg->no;
2224 case UNIT_A0:
2225 return (3 << 3) | reg->no;
2226 default:
2227 return -1;
2228 }
2229 }
2230 else
2231 {
2232 switch (reg->unit)
2233 {
2234 case UNIT_A1:
2235 return reg->no;
2236 case UNIT_D0:
2237 return (1 << 3) | reg->no;
2238 case UNIT_RD:
2239 return (2 << 3) | reg->no;
2240 case UNIT_D1:
2241 return (3 << 3) | reg->no;
2242 default:
2243 return -1;
2244 }
2245 }
2246 }
2247 else
2248 {
2249 if (unit_bit)
2250 {
2251 switch (reg->unit)
2252 {
2253 case UNIT_A1:
2254 return reg->no;
2255 case UNIT_D0:
2256 return (1 << 3) | reg->no;
2257 case UNIT_RD:
2258 return (2 << 3) | reg->no;
2259 case UNIT_A0:
2260 return (3 << 3) | reg->no;
2261 default:
2262 return -1;
2263 }
2264 }
2265 else
2266 {
2267 switch (reg->unit)
2268 {
2269 case UNIT_A1:
2270 return reg->no;
2271 case UNIT_D1:
2272 return (1 << 3) | reg->no;
2273 case UNIT_RD:
2274 return (2 << 3) | reg->no;
2275 case UNIT_A0:
2276 return (3 << 3) | reg->no;
2277 default:
2278 return -1;
2279 }
2280 }
2281 }
2282}
2283
2284/* Parse GP ALU instruction. */
2285static const char *
2286parse_alu (const char *line, metag_insn *insn,
2287 const insn_template *template)
2288{
2289 const char *l = line;
2290 const metag_reg *dest_regs[1];
2291 const metag_reg *src_regs[2];
2292 int value = 0;
2293 unsigned int o1z = 0;
2294 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2295 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2296 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2297 unsigned int top = template->meta_opcode & 0x1;
2298 unsigned int sign_extend = 0;
2299 unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR;
2300 unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL;
2301 unsigned int unit_bit = 0;
2302 bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR;
2303
2304 l = parse_gp_regs (l, dest_regs, 1);
2305
2306 if (l == NULL)
2307 return NULL;
2308
2309 l = skip_comma (l);
2310
2311 if (l == NULL ||
2312 *l == END_OF_INSN)
2313 return NULL;
2314
2315 if (is_addr_op)
2316 {
2317 if (dest_regs[0]->unit == UNIT_A0)
2318 unit_bit = 0;
2319 else if (dest_regs[0]->unit == UNIT_A1)
2320 unit_bit = 1;
2321 }
2322 else
2323 {
2324 if (dest_regs[0]->unit == UNIT_D0)
2325 unit_bit = 0;
2326 else if (dest_regs[0]->unit == UNIT_D1)
2327 unit_bit = 1;
2328 }
2329
2330 if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR ||
2331 MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
2332 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) &&
2333 ((template->meta_opcode >> 2) & 0x1))
2334 o1z = 1;
2335
2336 if (imm)
2337 {
2338 if (!cond)
2339 {
2340 if (is_addr_op)
2341 {
2342 if (dest_regs[0]->unit == UNIT_A0)
2343 unit_bit = 0;
2344 else if (dest_regs[0]->unit == UNIT_A1)
2345 unit_bit = 1;
2346 else
2347 return NULL;
2348 }
2349 else
2350 {
2351 if (dest_regs[0]->unit == UNIT_D0)
2352 unit_bit = 0;
2353 else if (dest_regs[0]->unit == UNIT_D1)
2354 unit_bit = 1;
2355 else
2356 return NULL;
2357 }
2358 }
2359
2360 if (cond)
2361 {
2362 l = parse_gp_regs (l, src_regs, 1);
2363
2364 if (l == NULL)
2365 return NULL;
2366
2367 l = skip_comma (l);
2368
2369 if (l == NULL ||
2370 *l == END_OF_INSN)
2371 return NULL;
2372
2373 if (is_addr_op)
2374 {
2375 if (src_regs[0]->unit == UNIT_A0)
2376 unit_bit = 0;
2377 else if (src_regs[0]->unit == UNIT_A1)
2378 unit_bit = 1;
2379 else
2380 return NULL;
2381 }
2382 else
2383 {
2384 if (src_regs[0]->unit == UNIT_D0)
2385 unit_bit = 0;
2386 else if (src_regs[0]->unit == UNIT_D1)
2387 unit_bit = 1;
2388 else
2389 return NULL;
2390 }
2391
2392 if (src_regs[0]->unit != dest_regs[0]->unit && !ca)
2393 return NULL;
2394
2395 l = parse_imm8 (l, insn, &value);
2396
2397 if (l == NULL)
2398 return NULL;
2399
2400 if (!within_unsigned_range (value, IMM8_BITS))
2401 return NULL;
2402
2403 insn->bits = (template->meta_opcode |
2404 (dest_regs[0]->no << 19) |
2405 (src_regs[0]->no << 14) |
2406 ((value & IMM8_MASK) << 6));
2407
2408 if (ca)
2409 {
2410 if (is_addr_op)
2411 {
2412 if (src_regs[0]->unit == UNIT_A0)
2413 unit_bit = 0;
2414 else if (src_regs[0]->unit == UNIT_A1)
2415 unit_bit = 1;
2416 else
2417 return NULL;
2418 }
2419 else
2420 {
2421 if (src_regs[0]->unit == UNIT_D0)
2422 unit_bit = 0;
2423 else if (src_regs[0]->unit == UNIT_D1)
2424 unit_bit = 1;
2425 else
2426 return NULL;
2427 }
2428
2429 insn->bits |= dest_regs[0]->unit << 1;
2430 }
2431 }
2432 else if (o1z)
2433 {
2434 l = parse_imm16 (l, insn, &value);
2435
2436 if (l == NULL)
2437 return NULL;
2438
2439 if (value < 0)
2440 {
2441 if (!within_signed_range (value, IMM16_BITS))
2442 {
2443 as_bad (_("immediate out of range"));
2444 return NULL;
2445 }
2446 sign_extend = 1;
2447 }
2448 else
2449 {
2450 if (!within_unsigned_range (value, IMM16_BITS))
2451 {
2452 as_bad (_("immediate out of range"));
2453 return NULL;
2454 }
2455 }
2456
2457 insn->bits = (template->meta_opcode |
2458 (dest_regs[0]->no << 19) |
2459 ((value & IMM16_MASK) << 3));
2460 }
2461 else
2462 {
2463 l = parse_gp_regs (l, src_regs, 1);
2464
2465 if (l == NULL)
2466 return NULL;
2467
2468 if (!(src_regs[0]->unit == dest_regs[0]->unit))
2469 return NULL;
2470
2471 /* CPC is valid for address ops. */
2472 if (src_regs[0]->no != dest_regs[0]->no &&
2473 !(is_addr_op && src_regs[0]->no == 0x10))
2474 return NULL;
2475
2476 l = skip_comma (l);
2477
2478 if (l == NULL ||
2479 *l == END_OF_INSN)
2480 return NULL;
2481
2482 l = parse_imm16 (l, insn, &value);
2483
2484 if (l == NULL)
2485 return NULL;
2486
2487 if (value < 0)
2488 {
2489 if (!within_signed_range (value, IMM16_BITS))
2490 {
2491 as_bad (_("immediate out of range"));
2492 return NULL;
2493 }
2494 sign_extend = 1;
2495 }
2496 else
2497 {
2498 if (!within_unsigned_range (value, IMM16_BITS))
2499 {
2500 as_bad (_("immediate out of range"));
2501 return NULL;
2502 }
2503 }
2504
2505 insn->bits = (template->meta_opcode |
2506 (dest_regs[0]->no << 19) |
2507 (src_regs[0]->no << 19) |
2508 ((value & IMM16_MASK) << 3));
2509 }
2510 }
2511 else
2512 {
2513 unsigned int o2r = 0;
2514 int rs2;
2515
2516 if (cond || !o1z)
2517 l = parse_gp_regs (l, src_regs, 2);
2518 else
2519 l = parse_gp_regs (l, src_regs, 1);
2520
2521 if (l == NULL)
2522 return NULL;
2523
2524 if (cond || !o1z)
2525 {
2526 if (is_addr_op)
2527 {
2528 if (src_regs[0]->unit == UNIT_A0)
2529 unit_bit = 0;
2530 else if (src_regs[0]->unit == UNIT_A1)
2531 unit_bit = 1;
2532 else
2533 return NULL;
2534 }
2535 else
2536 {
2537 if (src_regs[0]->unit == UNIT_D0)
2538 unit_bit = 0;
2539 else if (src_regs[0]->unit == UNIT_D1)
2540 unit_bit = 1;
2541 else
2542 return NULL;
2543 }
2544 }
2545 else
2546 {
2547 if (is_addr_op)
2548 {
2549 if (dest_regs[0]->unit == UNIT_A0)
2550 unit_bit = 0;
2551 else if (dest_regs[0]->unit == UNIT_A1)
2552 unit_bit = 1;
2553 else
2554 return NULL;
2555 }
2556 else
2557 {
2558 if (dest_regs[0]->unit == UNIT_D0)
2559 unit_bit = 0;
2560 else if (dest_regs[0]->unit == UNIT_D1)
2561 unit_bit = 1;
2562 else
2563 return NULL;
2564 }
2565 }
2566
2567 if (cond)
2568 {
2569 if (src_regs[0]->unit != src_regs[1]->unit)
2570 {
2571 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2572
2573 if (rs2 < 0)
2574 return NULL;
2575
2576 o2r = 1;
2577 }
2578 else
2579 {
2580 rs2 = src_regs[1]->no;
2581 }
2582
2583 insn->bits = (template->meta_opcode |
2584 (dest_regs[0]->no << 19) |
2585 (src_regs[0]->no << 14) |
2586 (rs2 << 9));
2587
2588 if (is_mul)
2589 {
2590 if (dest_regs[0]->unit != src_regs[0]->unit && is_mul)
2591 {
2592 if (ca)
2593 {
2594 insn->bits |= dest_regs[0]->unit << 1;
2595 }
2596 else
2597 return NULL;
2598 }
2599 }
2600 else
2601 insn->bits |= dest_regs[0]->unit << 5;
2602 }
2603 else if (o1z)
2604 {
2605 if (dest_regs[0]->unit != src_regs[0]->unit)
2606 {
2607 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]);
2608
2609 if (rs2 < 0)
2610 return NULL;
2611
2612 o2r = 1;
2613 }
2614 else
2615 {
2616 rs2 = src_regs[0]->no;
2617 }
2618
2619 insn->bits = (template->meta_opcode |
2620 (dest_regs[0]->no << 19) |
2621 (rs2 << 9));
2622 }
2623 else
2624 {
2625 if (dest_regs[0]->unit != src_regs[0]->unit)
2626 return NULL;
2627
2628 if (dest_regs[0]->unit != src_regs[1]->unit)
2629 {
2630 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2631
2632 if (rs2 < 0)
2633 return NULL;
2634
2635 o2r = 1;
2636 }
2637 else
2638 {
2639 rs2 = src_regs[1]->no;
2640 }
2641
2642 insn->bits = (template->meta_opcode |
2643 (dest_regs[0]->no << 19) |
2644 (src_regs[0]->no << 14) |
2645 (rs2 << 9));
2646 }
2647
2648 if (o2r)
2649 insn->bits |= 1;
2650 }
2651
2652 if (is_quickrot)
2653 {
2654 const metag_reg *qr_regs[1];
2655 bfd_boolean limit_regs = imm && cond;
2656
2657 l = skip_comma (l);
2658
2659 if (l == NULL ||
2660 *l == END_OF_INSN)
2661 return NULL;
2662
2663 l = parse_gp_regs (l, qr_regs, 1);
2664
2665 if (l == NULL)
2666 return NULL;
2667
2668 if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) ||
2669 !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1)))
2670 {
2671 as_bad (_("invalid quickrot unit specified"));
2672 return NULL;
2673 }
2674
2675 switch (qr_regs[0]->no)
2676 {
2677 case 2:
2678 break;
2679 case 3:
2680 if (!limit_regs)
2681 {
2682 insn->bits |= (1 << 7);
2683 break;
2684 }
2685 default:
2686 as_bad (_("invalid quickrot register specified"));
2687 return NULL;
2688 }
2689 }
2690
2691 if (sign_extend == 1 && top == 0)
2692 insn->bits |= (1 << 1);
2693
2694 insn->bits |= unit_bit << 24;
2695 insn->len = 4;
2696 return l;
2697}
2698
2699/* Parse a B instruction. */
2700static const char *
2701parse_branch (const char *line, metag_insn *insn,
2702 const insn_template *template)
2703{
2704 const char *l = line;
2705 int value = 0;
2706
2707 l = parse_imm19 (l, insn, &value);
2708
2709 if (l == NULL)
2710 return NULL;
2711
2712 if (!within_signed_range (value / 4, IMM19_BITS))
2713 {
2714 as_bad (_("target out of range"));
2715 return NULL;
2716 }
2717
2718 insn->bits = (template->meta_opcode |
2719 ((value & IMM19_MASK) << 5));
2720
2721 insn->len = 4;
2722 return l;
2723}
2724
2725/* Parse a KICK instruction. */
2726static const char *
2727parse_kick (const char *line, metag_insn *insn,
2728 const insn_template *template)
2729{
2730 const char *l = line;
2731 const metag_reg *regs[2];
2732
2733 l = parse_gp_regs (l, regs, 2);
2734
2735 if (l == NULL)
2736 return NULL;
2737
2738 if (regs[1]->unit != UNIT_TR)
2739 {
2740 as_bad (_("source register must be in the trigger unit"));
2741 return NULL;
2742 }
2743
2744 insn->bits = (template->meta_opcode |
2745 (regs[1]->no << 19) |
2746 (regs[0]->no << 14) |
2747 (regs[0]->unit << 5));
2748
2749 insn->len = 4;
2750 return l;
2751}
2752
2753/* Parse a SWITCH instruction. */
2754static const char *
2755parse_switch (const char *line, metag_insn *insn,
2756 const insn_template *template)
2757{
2758 const char *l = line;
2759 int value = 0;
2760
2761 l = parse_imm_constant (l, insn, &value);
2762
2763 if (l == NULL)
2764 return NULL;
2765
2766 if (!within_unsigned_range (value, IMM24_BITS))
2767 {
2768 as_bad (_("target out of range"));
2769 return NULL;
2770 }
2771
2772 insn->bits = (template->meta_opcode |
2773 (value & IMM24_MASK));
2774
2775 insn->len = 4;
2776 return l;
2777}
2778
2779/* Parse a shift instruction. */
2780static const char *
2781parse_shift (const char *line, metag_insn *insn,
2782 const insn_template *template)
2783{
2784 const char *l = line;
2785 const metag_reg *regs[2];
2786 const metag_reg *src2_regs[1];
2787 int value = 0;
2788 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2789 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2790 unsigned int unit_bit = 0;
2791
2792 l = parse_gp_regs (l, regs, 2);
2793
2794 if (l == NULL)
2795 return NULL;
2796
2797 l = skip_comma (l);
2798
2799 if (l == NULL ||
2800 *l == END_OF_INSN)
2801 return NULL;
2802
2803 if (regs[1]->unit == UNIT_D0)
2804 unit_bit = 0;
2805 else if (regs[1]->unit == UNIT_D1)
2806 unit_bit = 1;
2807 else
2808 return NULL;
2809
2810 if (regs[0]->unit != regs[1]->unit && !(cond && ca))
2811 return NULL;
2812
2813 if (*l == '#')
2814 {
2815 l = parse_imm_constant (l, insn, &value);
2816
2817 if (l == NULL)
2818 return NULL;
2819
2820 if (!within_unsigned_range (value, IMM5_BITS))
2821 return NULL;
2822
2823 insn->bits = (template->meta_opcode |
2824 (1 << 25) |
2825 (regs[0]->no << 19) |
2826 (regs[1]->no << 14) |
2827 ((value & IMM5_MASK) << 9));
2828 }
2829 else
2830 {
2831 l = parse_gp_regs (l, src2_regs, 1);
2832
2833 if (l == NULL)
2834 return NULL;
2835
2836 insn->bits = (template->meta_opcode |
2837 (regs[0]->no << 19) |
2838 (regs[1]->no << 14) |
2839 (src2_regs[0]->no << 9));
2840
2841 if (src2_regs[0]->unit != regs[1]->unit)
2842 {
2843 as_bad(_("Source registers must be in the same unit"));
2844 return NULL;
2845 }
2846 }
2847
2848 if (regs[0]->unit != regs[1]->unit)
2849 {
2850 if (cond && ca)
2851 {
2852 if (regs[1]->unit == UNIT_D0)
2853 unit_bit = 0;
2854 else if (regs[1]->unit == UNIT_D1)
2855 unit_bit = 1;
2856 else
2857 return NULL;
2858
2859 insn->bits |= ((1 << 5) |
2860 (regs[0]->unit << 1));
2861 }
2862 else
2863 return NULL;
2864 }
2865
2866 insn->bits |= unit_bit << 24;
2867 insn->len = 4;
2868 return l;
2869}
2870
2871/* Parse a MIN or MAX instruction. */
2872static const char *
2873parse_min_max (const char *line, metag_insn *insn,
2874 const insn_template *template)
2875{
2876 const char *l = line;
2877 const metag_reg *regs[3];
2878
2879 l = parse_gp_regs (l, regs, 3);
2880
2881 if (l == NULL)
2882 return NULL;
2883
2884 if (!(regs[0]->unit == UNIT_D0 ||
2885 regs[0]->unit == UNIT_D1))
2886 return NULL;
2887
2888 if (!(regs[0]->unit == regs[1]->unit &&
2889 regs[1]->unit == regs[2]->unit))
2890 return NULL;
2891
2892 insn->bits = (template->meta_opcode |
2893 (regs[0]->no << 19) |
2894 (regs[1]->no << 14) |
2895 (regs[2]->no << 9));
2896
2897 if (regs[0]->unit == UNIT_D1)
2898 insn->bits |= (1 << 24);
2899
2900 insn->len = 4;
2901 return l;
2902}
2903
2904/* Parse a bit operation instruction. */
2905static const char *
2906parse_bitop (const char *line, metag_insn *insn,
2907 const insn_template *template)
2908{
2909 const char *l = line;
2910 const metag_reg *regs[2];
2911 unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC;
2912 unsigned int is_bexl = 0;
2913
2914 if (swap_inst &&
2915 ((template->meta_opcode >> 1) & 0xb) == 0xa)
2916 is_bexl = 1;
2917
2918 l = parse_gp_regs (l, regs, 2);
2919
2920 if (l == NULL)
2921 return NULL;
2922
2923 if (!(regs[0]->unit == UNIT_D0 ||
2924 regs[0]->unit == UNIT_D1))
2925 return NULL;
2926
2927 if (is_bexl)
2928 {
2929 if (regs[0]->unit == UNIT_D0 &&
2930 regs[1]->unit != UNIT_D1)
2931 return NULL;
2932 else if (regs[0]->unit == UNIT_D1 &&
2933 regs[1]->unit != UNIT_D0)
2934 return NULL;
2935 }
2936 else if (!(regs[0]->unit == regs[1]->unit))
2937 return NULL;
2938
2939 insn->bits = (template->meta_opcode |
2940 (regs[0]->no << 19) |
2941 (regs[1]->no << 14));
2942
2943 if (swap_inst)
2944 {
2945 if (regs[1]->unit == UNIT_D1)
2946 insn->bits |= 1;
2947 }
2948 else
2949 {
2950 if (regs[1]->unit == UNIT_D1)
2951 insn->bits |= (1 << 24);
2952 }
2953
2954 insn->len = 4;
2955 return l;
2956}
2957
2958/* Parse a CMP or TST instruction. */
2959static const char *
2960parse_cmp (const char *line, metag_insn *insn,
2961 const insn_template *template)
2962{
2963 const char *l = line;
2964 const metag_reg *dest_regs[1];
2965 const metag_reg *src_regs[1];
2966 int value = 0;
2967 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2968 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2969 unsigned int top = template->meta_opcode & 0x1;
2970 unsigned int sign_extend = 0;
2971 unsigned int unit_bit = 0;
2972
2973 l = parse_gp_regs (l, dest_regs, 1);
2974
2975 if (l == NULL)
2976 return NULL;
2977
2978 l = skip_comma (l);
2979
2980 if (l == NULL ||
2981 *l == END_OF_INSN)
2982 return NULL;
2983
2984 if (dest_regs[0]->unit == UNIT_D0)
2985 unit_bit = 0;
2986 else if (dest_regs[0]->unit == UNIT_D1)
2987 unit_bit = 1;
2988 else
2989 return NULL;
2990
2991 if (imm)
2992 {
2993 if (cond)
2994 {
2995 l = parse_imm_constant (l, insn, &value);
2996
2997 if (l == NULL)
2998 return NULL;
2999
3000 if (!within_unsigned_range (value, IMM8_BITS))
3001 return NULL;
3002
3003 insn->bits = (template->meta_opcode |
3004 (dest_regs[0]->no << 14) |
3005 ((value & IMM8_MASK) << 6));
3006
3007 }
3008 else
3009 {
3010 l = parse_imm16 (l, insn, &value);
3011
3012 if (l == NULL)
3013 return NULL;
3014
3015 if (value < 0)
3016 {
3017 if (!within_signed_range (value, IMM16_BITS))
3018 {
3019 as_bad (_("immediate out of range"));
3020 return NULL;
3021 }
3022 sign_extend = 1;
3023 }
3024 else
3025 {
3026 if (!within_unsigned_range (value, IMM16_BITS))
3027 {
3028 as_bad (_("immediate out of range"));
3029 return NULL;
3030 }
3031 }
3032
3033 insn->bits = (template->meta_opcode |
3034 (dest_regs[0]->no << 19) |
3035 ((value & IMM16_MASK) << 3));
3036 }
3037 }
3038 else
3039 {
3040 unsigned int o2r = 0;
3041 int rs2;
3042
3043 l = parse_gp_regs (l, src_regs, 1);
3044
3045 if (l == NULL)
3046 return NULL;
3047
3048 if (dest_regs[0]->unit != src_regs[0]->unit)
3049 {
3050 rs2 = lookup_o2r (0, unit_bit, src_regs[0]);
3051
3052 if (rs2 < 0)
3053 return NULL;
3054
3055 o2r = 1;
3056 }
3057 else
3058 {
3059 rs2 = src_regs[0]->no;
3060 }
3061
3062 insn->bits = (template->meta_opcode |
3063 (dest_regs[0]->no << 14) |
3064 (rs2 << 9));
3065
3066 if (o2r)
3067 insn->bits |= 1;
3068 }
3069
3070 if (sign_extend == 1 && top == 0)
3071 insn->bits |= (1 << 1);
3072
3073 insn->bits |= unit_bit << 24;
3074 insn->len = 4;
3075 return l;
3076}
3077
3078/* Parse a CACHEW instruction. */
3079static const char *
3080parse_cachew (const char *line, metag_insn *insn,
3081 const insn_template *template)
3082{
3083 const char *l = line;
3084 const metag_reg *src_regs[2];
3085 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3086 metag_addr addr;
3087 int offset;
3088
3089 memset(&addr, 0, sizeof(addr));
3090 addr.reloc_type = BFD_RELOC_UNUSED;
3091
3092 l = parse_addr (l, &addr, size);
3093
3094 if (l == NULL ||
3095 !is_short_unit (addr.base_reg->unit) ||
3096 addr.update ||
3097 !addr.immediate)
3098 {
3099 as_bad (_("invalid memory operand"));
3100 return NULL;
3101 }
3102
3103 l = skip_comma (l);
3104
3105 if (l == NULL ||
3106 *l == END_OF_INSN)
3107 return NULL;
3108
3109 if (size == 4)
3110 l = parse_gp_regs (l, src_regs, 1);
3111 else
3112 l = parse_pair_gp_regs (l, src_regs);
3113
3114 if (l == NULL ||
3115 !is_short_unit (src_regs[0]->unit))
3116 {
3117 as_bad (_("invalid source register"));
3118 return NULL;
3119 }
3120
3121 offset = addr.exp.X_add_number;
3122
3123 if (addr.negate)
3124 offset = -offset;
3125
3126 offset = offset / 64;
3127
3128 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3129 {
3130 as_bad (_("offset value out of range"));
3131 return NULL;
3132 }
3133
3134 insn->bits = (template->meta_opcode |
3135 (src_regs[0]->no << 19) |
3136 (addr.base_reg->no << 14) |
3137 ((offset & GET_SET_IMM_MASK) << 8) |
3138 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3139 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3140
3141 insn->len = 4;
3142 return l;
3143}
3144
3145/* Parse a CACHEW instruction. */
3146static const char *
3147parse_cacher (const char *line, metag_insn *insn,
3148 const insn_template *template)
3149{
3150 const char *l = line;
3151 const metag_reg *dest_regs[2];
3152 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3153 metag_addr addr;
3154 int offset;
3155
3156 memset(&addr, 0, sizeof(addr));
3157 addr.reloc_type = BFD_RELOC_UNUSED;
3158
3159 if (size == 4)
3160 l = parse_gp_regs (l, dest_regs, 1);
3161 else
3162 l = parse_pair_gp_regs (l, dest_regs);
3163
3164 if (l == NULL ||
3165 !is_short_unit (dest_regs[0]->unit))
3166 {
3167 as_bad (_("invalid destination register"));
3168 return NULL;
3169 }
3170
3171 l = skip_comma (l);
3172
3173 if (l == NULL ||
3174 *l == END_OF_INSN)
3175 return NULL;
3176
3177 l = parse_addr (l, &addr, size);
3178
3179 if (l == NULL ||
3180 !is_short_unit (addr.base_reg->unit) ||
3181 addr.update ||
3182 !addr.immediate)
3183 {
3184 as_bad (_("invalid memory operand"));
3185 return NULL;
3186 }
3187
3188 offset = addr.exp.X_add_number;
3189
3190 if (addr.negate)
3191 offset = -offset;
3192
3193 offset = offset / (int)size;
3194
3195 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3196 {
3197 as_bad (_("offset value out of range"));
3198 return NULL;
3199 }
3200
3201 insn->bits = (template->meta_opcode |
3202 (dest_regs[0]->no << 19) |
3203 (addr.base_reg->no << 14) |
3204 ((offset & GET_SET_IMM_MASK) << 8) |
3205 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3206 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3207
3208 insn->len = 4;
3209 return l;
3210}
3211
3212/* Parse an ICACHE instruction. */
3213static const char *
3214parse_icache (const char *line, metag_insn *insn,
3215 const insn_template *template)
3216{
3217 const char *l = line;
3218 int offset;
3219 int pfcount;
3220
3221 l = parse_imm_constant (l, insn, &offset);
3222
3223 if (l == NULL)
3224 return NULL;
3225
3226 if (!within_signed_range (offset, IMM15_BITS))
3227 return NULL;
3228
3229 l = skip_comma (l);
3230
3231 l = parse_imm_constant (l, insn, &pfcount);
3232
3233 if (l == NULL)
3234 return NULL;
3235
3236 if (!within_unsigned_range (pfcount, IMM4_BITS))
3237 return NULL;
3238
3239 insn->bits = (template->meta_opcode |
3240 ((offset & IMM15_MASK) << 9) |
3241 ((pfcount & IMM4_MASK) << 1));
3242
3243 insn->len = 4;
3244 return l;
3245}
3246
3247/* Parse a LNKGET instruction. */
3248static const char *
3249parse_lnkget (const char *line, metag_insn *insn,
3250 const insn_template *template)
3251{
3252 const char *l = line;
3253 const metag_reg *dest_regs[2];
3254 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
3255 metag_addr addr;
3256 int offset;
3257
3258 memset(&addr, 0, sizeof(addr));
3259 addr.reloc_type = BFD_RELOC_UNUSED;
3260
3261 if (size == 8)
3262 l = parse_pair_gp_regs (l, dest_regs);
3263 else
3264 l = parse_gp_regs (l, dest_regs, 1);
3265
3266 if (l == NULL ||
3267 !is_short_unit (dest_regs[0]->unit))
3268 {
3269 as_bad (_("invalid destination register"));
3270 return NULL;
3271 }
3272
3273 l = skip_comma (l);
3274
3275 if (l == NULL ||
3276 *l == END_OF_INSN)
3277 return NULL;
3278
3279 l = parse_addr (l, &addr, size);
3280
3281 if (l == NULL ||
3282 !is_short_unit (addr.base_reg->unit) ||
3283 addr.update ||
3284 !addr.immediate)
3285 {
3286 as_bad (_("invalid memory operand"));
3287 return NULL;
3288 }
3289
3290 offset = addr.exp.X_add_number;
3291
3292 if (addr.negate)
3293 offset = -offset;
3294
3295 offset = offset / size;
3296
3297 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3298 {
3299 as_bad (_("offset value out of range"));
3300 return NULL;
3301 }
3302
3303 insn->bits = (template->meta_opcode |
3304 (dest_regs[0]->no << 19) |
3305 (addr.base_reg->no << 14) |
3306 ((offset & GET_SET_IMM_MASK) << 8) |
3307 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3308 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3309
3310 insn->len = 4;
3311 return l;
3312}
3313
3314/* Parse an FPU MOV instruction. */
3315static const char *
3316parse_fmov (const char *line, metag_insn *insn,
3317 const insn_template *template)
3318{
3319 const char *l = line;
3320 const metag_reg *regs[2];
3321
3322 l = parse_fpu_regs (l, regs, 2);
3323
3324 if (l == NULL)
3325 return NULL;
3326
3327 insn->bits = (template->meta_opcode |
3328 (regs[0]->no << 19) |
3329 (regs[1]->no << 14));
3330
3331 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3332 insn->bits |= (1 << 5);
3333 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3334 insn->bits |= (1 << 6);
3335
3336 insn->len = 4;
3337 return l;
3338}
3339
3340/* Parse an FPU MMOV instruction. */
3341static const char *
3342parse_fmmov (const char *line, metag_insn *insn,
3343 const insn_template *template)
3344{
3345 const char *l = line;
3346 bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
3347 bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1;
3348 size_t regs_read = 0;
3349 const metag_reg *regs[16];
3350 unsigned int lowest_data_reg = 0xffffffff;
3351 unsigned int lowest_fpu_reg = 0xffffffff;
3352 unsigned int rmask = 0, data_unit;
3353 size_t i;
3354 int last_reg = -1;
3355
3356 if (insn->fpu_width != FPU_WIDTH_SINGLE)
3357 return NULL;
3358
3359 l = parse_gp_regs_list (l, regs, 16, &regs_read);
3360
3361 if (l == NULL)
3362 return NULL;
3363
3364 if (regs_read % 2)
3365 return NULL;
3366
3367 if (to_fpu)
3368 {
3369 for (i = 0; i < regs_read / 2; i++)
3370 {
3371 if (regs[i]->unit != UNIT_FX)
3372 return NULL;
3373
3374 if (last_reg == -1)
3375 {
3376 last_reg = regs[i]->no;
3377 lowest_fpu_reg = last_reg;
3378 }
3379 else
3380 {
3381 if (is_mmovl)
3382 {
3383 if (regs[i]->no != (unsigned int)(last_reg + 2))
3384 return NULL;
3385 }
3386 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3387 return NULL;
3388
3389 last_reg = regs[i]->no;
3390 }
3391 }
3392
3393 if (regs[i]->unit == UNIT_D0)
3394 data_unit = 0;
3395 else if (regs[i]->unit == UNIT_D1)
3396 data_unit = 1;
3397 else
3398 return NULL;
3399
3400 if (!check_rmask (&regs[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3401 &rmask))
3402 return NULL;
3403 }
3404 else
3405 {
3406 if (regs[0]->unit == UNIT_D0)
3407 data_unit = 0;
3408 else if (regs[0]->unit == UNIT_D1)
3409 data_unit = 1;
3410 else
3411 return NULL;
3412
3413 if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3414 &rmask))
3415 return NULL;
3416
3417 for (i = regs_read / 2; i < regs_read; i++)
3418 {
3419 if (regs[i]->unit != UNIT_FX)
3420 return NULL;
3421
3422 if (last_reg == -1)
3423 {
3424 last_reg = regs[i]->no;
3425 lowest_fpu_reg = last_reg;
3426 }
3427 else
3428 {
3429 if (is_mmovl)
3430 {
3431 if (regs[i]->no != (unsigned int)(last_reg + 2))
3432 return NULL;
3433 }
3434 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3435 return NULL;
3436
3437 last_reg = regs[i]->no;
3438 }
3439 }
3440 }
3441
3442 insn->bits = (template->meta_opcode |
3443 ((lowest_data_reg & REG_MASK) << 19) |
3444 ((lowest_fpu_reg & REG_MASK) << 14) |
3445 ((rmask & RMASK_MASK) << 7) |
3446 data_unit);
3447
3448 insn->len = 4;
3449 return l;
3450}
3451
3452/* Parse an FPU data unit MOV instruction. */
3453static const char *
3454parse_fmov_data (const char *line, metag_insn *insn,
3455 const insn_template *template)
3456{
3457 const char *l = line;
3458 unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1);
3459 const metag_reg *regs[2];
3460 unsigned int base_unit;
3461
3462 if (insn->fpu_width == FPU_WIDTH_PAIR)
3463 return NULL;
3464
3465 l = parse_gp_regs (l, regs, 2);
3466
3467 if (l == NULL)
3468 return NULL;
3469
3470 if (to_fpu)
3471 {
3472 if (regs[0]->unit != UNIT_FX)
3473 return NULL;
3474
3475 if (regs[1]->unit == UNIT_D0)
3476 base_unit = 0;
3477 else if (regs[1]->unit == UNIT_D1)
3478 base_unit = 1;
3479 else
3480 return NULL;
3481 }
3482 else
3483 {
3484 if (regs[0]->unit == UNIT_D0)
3485 base_unit = 0;
3486 else if (regs[0]->unit == UNIT_D1)
3487 base_unit = 1;
3488 else
3489 return NULL;
3490
3491 if (regs[1]->unit != UNIT_FX)
3492 return NULL;
3493 }
3494
3495 insn->bits = (template->meta_opcode |
3496 (base_unit << 24) |
3497 (regs[0]->no << 19) |
3498 (regs[1]->no << 9));
3499
3500 insn->len = 4;
3501 return l;
3502}
3503
3504/* Parse an FPU immediate MOV instruction. */
3505static const char *
3506parse_fmov_i (const char *line, metag_insn *insn,
3507 const insn_template *template)
3508{
3509 const char *l = line;
3510 const metag_reg *regs[1];
3511 int value = 0;
3512
3513 l = parse_fpu_regs (l, regs, 1);
3514
3515 l = skip_comma (l);
3516
3517 if (l == NULL ||
3518 *l == END_OF_INSN)
3519 return NULL;
3520
3521 l = parse_imm16 (l, insn, &value);
3522
3523 if (l == NULL)
3524 return NULL;
3525
3526 insn->bits = (template->meta_opcode |
3527 (regs[0]->no << 19) |
3528 ((value & IMM16_MASK) << 3));
3529
3530 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3531 insn->bits |= (1 << 1);
3532 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3533 insn->bits |= (1 << 2);
3534
3535 insn->len = 4;
3536 return l;
3537}
3538
3539/* Parse an FPU PACK instruction. */
3540static const char *
3541parse_fpack (const char *line, metag_insn *insn,
3542 const insn_template *template)
3543{
3544 const char *l = line;
3545 const metag_reg *regs[3];
3546
3547 l = parse_fpu_regs (l, regs, 3);
3548
3549 if (l == NULL)
3550 return NULL;
3551
3552 if (regs[0]->no % 2)
3553 {
3554 as_bad (_("destination register should be even numbered"));
3555 return NULL;
3556 }
3557
3558 insn->bits = (template->meta_opcode |
3559 (regs[0]->no << 19) |
3560 (regs[1]->no << 14) |
3561 (regs[2]->no << 9));
3562
3563 insn->len = 4;
3564 return l;
3565}
3566
3567/* Parse an FPU SWAP instruction. */
3568static const char *
3569parse_fswap (const char *line, metag_insn *insn,
3570 const insn_template *template)
3571{
3572 const char *l = line;
3573 const metag_reg *regs[2];
3574
3575 if (insn->fpu_width != FPU_WIDTH_PAIR)
3576 return NULL;
3577
3578 l = parse_fpu_regs (l, regs, 2);
3579
3580 if (l == NULL)
3581 return NULL;
3582
3583 if (regs[0]->no % 2)
3584 return NULL;
3585
3586 if (regs[1]->no % 2)
3587 return NULL;
3588
3589 insn->bits = (template->meta_opcode |
3590 (regs[0]->no << 19) |
3591 (regs[1]->no << 14));
3592
3593 insn->len = 4;
3594 return l;
3595}
3596
3597/* Parse an FPU CMP instruction. */
3598static const char *
3599parse_fcmp (const char *line, metag_insn *insn,
3600 const insn_template *template)
3601{
3602 const char *l = line, *l2;
3603 const metag_reg *regs1[1];
3604 const metag_reg *regs2[1];
3605
3606 l = parse_fpu_regs (l, regs1, 1);
3607
3608 l = skip_comma (l);
3609
3610 if (l == NULL ||
3611 *l == END_OF_INSN)
3612 return NULL;
3613
3614 l2 = parse_fpu_regs (l, regs2, 1);
3615
3616 if (l2 != NULL)
3617 {
3618 insn->bits = (regs2[0]->no << 9);
3619 }
3620 else
3621 {
3622 int constant = 0;
3623 l2 = parse_imm_constant (l, insn, &constant);
3624 if (!l2 || constant != 0)
3625 {
3626 as_bad (_("comparison must be with register or #0"));
3627 return NULL;
3628 }
3629 insn->bits = (1 << 8);
3630 }
3631
3632 insn->bits |= (template->meta_opcode |
3633 (regs1[0]->no << 14));
3634
3635 if (insn->fpu_action_flags & FPU_ACTION_ABS)
3636 insn->bits |= (1 << 19);
3637
3638 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3639 insn->bits |= (1 << 7);
3640
3641 if (insn->fpu_width == FPU_WIDTH_PAIR)
3642 insn->bits |= (1 << 6);
3643 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3644 insn->bits |= (1 << 5);
3645
3646 insn->len = 4;
3647 return l2;
3648}
3649
3650/* Parse an FPU MIN or MAX instruction. */
3651static const char *
3652parse_fminmax (const char *line, metag_insn *insn,
3653 const insn_template *template)
3654{
3655 const char *l = line;
3656 const metag_reg *regs[3];
3657
3658 l = parse_fpu_regs (l, regs, 3);
3659
3660 if (l == NULL)
3661 return NULL;
3662
3663 insn->bits = (template->meta_opcode |
3664 (regs[0]->no << 19) |
3665 (regs[1]->no << 14) |
3666 (regs[2]->no << 9));
3667
3668 if (insn->fpu_width == FPU_WIDTH_PAIR)
3669 insn->bits |= (1 << 6);
3670 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3671 insn->bits |= (1 << 5);
3672
3673 insn->len = 4;
3674 return l;
3675}
3676
3677/* Parse an FPU data conversion instruction. */
3678static const char *
3679parse_fconv (const char *line, metag_insn *insn,
3680 const insn_template *template)
3681{
3682 const char *l = line;
3683 const metag_reg *regs[2];
3684
3685 if (insn->fpu_width == FPU_WIDTH_PAIR)
3686 {
3687 if (strncasecmp (template->name, "FTOH", 4) &&
3688 strncasecmp (template->name, "HTOF", 4) &&
3689 strncasecmp (template->name, "FTOI", 4) &&
3690 strncasecmp (template->name, "ITOF", 4))
3691 {
3692 as_bad (_("instruction cannot operate on pair values"));
3693 return NULL;
3694 }
3695 }
3696
3697 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3698 {
3699 if (strncasecmp (template->name, "FTOI", 4) &&
3700 strncasecmp (template->name, "DTOI", 4) &&
3701 strncasecmp (template->name, "DTOL", 4))
3702 {
3703 as_bad (_("zero flag is not valid for this instruction"));
3704 return NULL;
3705 }
3706 }
3707
3708 l = parse_fpu_regs (l, regs, 2);
3709
3710 if (l == NULL)
3711 return NULL;
3712
3713 if (!strncasecmp (template->name, "DTOL", 4) ||
3714 !strncasecmp (template->name, "LTOD", 4))
3715 {
3716 if (regs[0]->no % 2)
3717 {
3718 as_bad (_("destination register should be even numbered"));
3719 return NULL;
3720 }
3721
3722 if (regs[1]->no % 2)
3723 {
3724 as_bad (_("source register should be even numbered"));
3725 return NULL;
3726 }
3727 }
3728
3729 insn->bits = (template->meta_opcode |
3730 (regs[0]->no << 19) |
3731 (regs[1]->no << 14));
3732
3733 if (insn->fpu_width == FPU_WIDTH_PAIR)
3734 insn->bits |= (1 << 6);
3735
3736 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3737 insn->bits |= (1 << 12);
3738
3739 insn->len = 4;
3740 return l;
3741}
3742
3743/* Parse an FPU extended data conversion instruction. */
3744static const char *
3745parse_fconvx (const char *line, metag_insn *insn,
3746 const insn_template *template)
3747{
3748 const char *l = line;
3749 const metag_reg *regs[2];
3750 int fraction_bits = 0;
3751
3752 if (insn->fpu_width == FPU_WIDTH_PAIR)
3753 {
3754 if (strncasecmp (template->name, "FTOX", 4) &&
3755 strncasecmp (template->name, "XTOF", 4))
3756 {
3757 as_bad (_("instruction cannot operate on pair values"));
3758 return NULL;
3759 }
3760 }
3761
3762 l = parse_fpu_regs (l, regs, 2);
3763
3764 l = skip_comma (l);
3765
3766 if (l == NULL ||
3767 *l == END_OF_INSN)
3768 return NULL;
3769
3770 l = parse_imm_constant (l, insn, &fraction_bits);
3771
3772 if (l == NULL)
3773 return NULL;
3774
3775 insn->bits = (template->meta_opcode |
3776 (regs[0]->no << 19) |
3777 (regs[1]->no << 14));
3778
3779 if (strncasecmp (template->name, "DTOXL", 5) &&
3780 strncasecmp (template->name, "XLTOD", 5))
3781 {
3782 if (!within_unsigned_range (fraction_bits, IMM5_BITS))
3783 {
3784 as_bad (_("fraction bits value out of range"));
3785 return NULL;
3786 }
3787 insn->bits |= ((fraction_bits & IMM5_MASK) << 9);
3788 }
3789 else
3790 {
3791 if (!within_unsigned_range (fraction_bits, IMM6_BITS))
3792 {
3793 as_bad (_("fraction bits value out of range"));
3794 return NULL;
3795 }
3796 insn->bits |= ((fraction_bits & IMM6_MASK) << 8);
3797 }
3798
3799 if (insn->fpu_width == FPU_WIDTH_PAIR)
3800 insn->bits |= (1 << 6);
3801
3802 insn->len = 4;
3803 return l;
3804}
3805
3806/* Parse an FPU basic arithmetic instruction. */
3807static const char *
3808parse_fbarith (const char *line, metag_insn *insn,
3809 const insn_template *template)
3810{
3811 const char *l = line;
3812 const metag_reg *regs[3];
3813
3814 l = parse_fpu_regs (l, regs, 3);
3815
3816 if (l == NULL)
3817 return NULL;
3818
3819 insn->bits = (template->meta_opcode |
3820 (regs[0]->no << 19) |
3821 (regs[1]->no << 14) |
3822 (regs[2]->no << 9));
3823
3824 if (insn->fpu_width == FPU_WIDTH_PAIR)
3825 insn->bits |= (1 << 6);
3826 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3827 insn->bits |= (1 << 5);
3828
3829 if (insn->fpu_action_flags & FPU_ACTION_INV)
3830 insn->bits |= (1 << 7);
3831
3832 insn->len = 4;
3833 return l;
3834}
3835
3836/* Parse a floating point accumulator name. */
3837static const char *
3838parse_acf (const char *line, int *part)
3839{
3840 const char *l = line;
3841 size_t i;
3842
3843 for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++)
3844 {
3845 const metag_acf *acf = &metag_acftab[i];
3846 size_t name_len = strlen (acf->name);
3847
3848 if (strncasecmp (l, acf->name, name_len) == 0)
3849 {
3850 l += name_len;
3851 *part = acf->part;
3852 return l;
3853 }
3854 }
3855 return NULL;
3856}
3857
3858/* Parse an FPU extended arithmetic instruction. */
3859static const char *
3860parse_fearith (const char *line, metag_insn *insn,
3861 const insn_template *template)
3862{
3863 const char *l = line;
3864 const metag_reg *regs[3];
3865 bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 &&
3866 ((template->meta_opcode >> 4) & 0x1));
3867 unsigned int is_o3o = template->meta_opcode & 0x1;
3868 unsigned int is_mac = 0;
3869 unsigned int is_maw = 0;
3870
3871 if (!strncasecmp (template->name, "MAW", 3))
3872 is_maw = 1;
3873
3874 if (!strncasecmp (template->name, "MAC", 3))
3875 {
3876 int part;
3877 l = parse_acf (l, &part);
3878
3879 if (l == NULL || part != 0)
3880 return NULL;
3881
3882 l = skip_comma (l);
3883
3884 l = parse_fpu_regs (l, &regs[1], 2);
3885
3886 is_mac = 1;
3887 }
3888 else
3889 {
3890 if (is_o3o && is_maw)
3891 l = parse_fpu_regs (l, regs, 2);
3892 else
3893 l = parse_fpu_regs (l, regs, 3);
3894 }
3895
3896 if (l == NULL)
3897 return NULL;
3898
3899 if (is_o3o && is_maw)
3900 insn->bits = (template->meta_opcode |
3901 (regs[1]->no << 9));
3902 else
3903 insn->bits = (template->meta_opcode |
3904 (regs[1]->no << 14));
3905
3906 if (!(is_o3o && is_maw))
3907 insn->bits |= (regs[2]->no << 9);
3908
3909 if (is_o3o && is_maw)
3910 insn->bits |= (regs[0]->no << 14);
3911 else if (!is_mac)
3912 insn->bits |= (regs[0]->no << 19);
3913
3914 if (insn->fpu_width == FPU_WIDTH_PAIR)
3915 insn->bits |= (1 << 6);
3916 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3917 insn->bits |= (1 << 5);
3918
3919 if (!is_mac && !is_maw)
3920 if (insn->fpu_action_flags & FPU_ACTION_INV)
3921 insn->bits |= (1 << 7);
3922
3923 if (is_muz)
3924 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3925 insn->bits |= (1 << 1);
3926
3927 insn->len = 4;
3928 return l;
3929}
3930
3931/* Parse an FPU RCP or RSQ instruction. */
3932static const char *
3933parse_frec (const char *line, metag_insn *insn,
3934 const insn_template *template)
3935{
3936 const char *l = line;
3937 const metag_reg *regs[2];
3938
3939 l = parse_fpu_regs (l, regs, 2);
3940
3941 if (l == NULL)
3942 return NULL;
3943
3944 insn->bits = (template->meta_opcode |
3945 (regs[0]->no << 19) |
3946 (regs[1]->no << 14));
3947
3948 if (insn->fpu_width == FPU_WIDTH_PAIR)
3949 insn->bits |= (1 << 6);
3950 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3951 insn->bits |= (1 << 5);
3952
3953 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3954 insn->bits |= (1 << 10);
3955 else if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3956 insn->bits |= (1 << 9);
3957
3958 if (insn->fpu_action_flags & FPU_ACTION_INV)
3959 insn->bits |= (1 << 7);
3960
3961 insn->len = 4;
3962 return l;
3963}
3964
3965/* Parse an FPU vector arithmetic instruction. */
3966static const char *
3967parse_fsimd (const char *line, metag_insn *insn,
3968 const insn_template *template)
3969{
3970 const char *l = line;
3971 const metag_reg *regs[3];
3972
3973 if (insn->fpu_width != FPU_WIDTH_PAIR)
3974 {
3975 as_bad (_("simd instructions operate on pair values (L prefix)"));
3976 return NULL;
3977 }
3978
3979 l = parse_fpu_regs (l, regs, 3);
3980
3981 if (l == NULL)
3982 return NULL;
3983
3984 if (regs[0]->no % 2)
3985 {
3986 as_bad (_("destination register should be even numbered"));
3987 return NULL;
3988 }
3989
3990 if ((regs[1]->no % 2) ||
3991 (regs[2]->no % 2))
3992 {
3993 as_bad (_("source registers should be even numbered"));
3994 return NULL;
3995 }
3996
3997 insn->bits = (template->meta_opcode |
3998 (regs[0]->no << 19) |
3999 (regs[1]->no << 14) |
4000 (regs[2]->no << 9));
4001
4002 if (insn->fpu_action_flags & FPU_ACTION_INV)
4003 insn->bits |= (1 << 7);
4004
4005 insn->len = 4;
4006 return l;
4007}
4008
4009/* Parse an FPU accumulator GET or SET instruction. */
4010static const char *
4011parse_fget_set_acf (const char *line, metag_insn *insn,
4012 const insn_template *template)
4013{
4014 const char *l = line;
4015 int part;
4016 metag_addr addr;
4017 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
4018
4019 memset(&addr, 0, sizeof(addr));
4020 addr.reloc_type = BFD_RELOC_UNUSED;
4021
4022 if (is_get)
4023 {
4024 l = parse_acf (l, &part);
4025
4026 l = skip_comma (l);
4027
4028 if (l == NULL)
4029 return NULL;
4030
4031 l = parse_mget_mset_addr (l, &addr);
4032 }
4033 else
4034 {
4035 l = parse_mget_mset_addr (l, &addr);
4036
4037 l = skip_comma (l);
4038
4039 if (l == NULL)
4040 return NULL;
4041
4042 l = parse_acf (l, &part);
4043 }
4044
4045 if (l == NULL)
4046 return NULL;
4047
4048 insn->bits = (template->meta_opcode |
4049 (part << 19));
4050
4051 if (!is_short_unit (addr.base_reg->unit))
4052 {
4053 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
4054 return NULL;
4055 }
4056
4057 insn->bits |= ((addr.base_reg->no << 14) |
4058 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
4059
4060 insn->len = 4;
4061 return l;
4062}
4063
4064/* Copy the name of the next register in LINE to REG_BUF. */
4065static size_t
4066strip_reg_name(const char *line, char *reg_buf)
4067{
4068 const char *l = line;
4069 size_t len = 0;
4070
4071 while (is_register_char (*l))
4072 {
4073 reg_buf[len] = *l;
4074 l++;
4075 len++;
4076 if (!(len < MAX_REG_LEN))
4077 return 0;
4078 }
4079
4080 if (len)
4081 reg_buf[len] = '\0';
4082
4083 return len;
4084}
4085
4086/* Parse a DSP register from LINE into REG using only the registers
4087 from DSP_REGTAB. Return the next character or NULL. */
4088static const char *
4089__parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab)
4090{
4091 const char *l = line;
4092 char name[MAX_REG_LEN];
4093 size_t len = 0;
4094 metag_reg entry;
4095 const metag_reg *_reg;
4096
4097 /* We don't entirely strip the register name because we might
4098 actually want to match whole string in the register table,
4099 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4100 entry limits our comaprison to a reasonable bound anyway. */
4101 while (is_register_char (*l) || *l == PLUS)
4102 {
4103 name[len] = *l;
4104 l++;
4105 len++;
4106 if (!(len < MAX_REG_LEN))
4107 return NULL;
4108 }
4109
4110 if (!len)
4111 return NULL;
4112
4113 name[len] = '\0';
4114 entry.name = name;
4115
4116 _reg = (const metag_reg *) htab_find (dsp_regtab, &entry);
4117 if (!_reg)
4118 return NULL;
4119
4120 *reg = _reg;
4121
4122 return l;
4123}
4124
4125/* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4126 member is suitable for encoding into a DSP insn register field. */
4127static const char *
4128parse_dsp_insn_reg (const char *line, const metag_reg **reg)
4129{
4130 return __parse_dsp_reg (line, reg, dsp_reg_htab);
4131}
4132
4133/* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4134 member is suitable for encoding into a DSP template definition insn
4135 register field.
4136
4137 There is a separate table for whether we're doing a load or a store
4138 definition. "load" specifies which table to look at. */
4139static const char *
4140parse_dsp_template_reg (const char *line, const metag_reg **reg,
4141 bfd_boolean load)
4142{
4143 return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]);
4144}
4145
4146/* Parse a single DSP register from LINE. */
4147static const char *
4148parse_dsp_reg (const char *line, const metag_reg **reg,
4149 bfd_boolean tmpl, bfd_boolean load)
4150{
4151 if (tmpl)
4152 return parse_dsp_template_reg (line, reg, load);
4153 else
4154 return parse_dsp_insn_reg (line, reg);
4155}
4156
4157/* Return TRUE if UNIT is an address unit. */
4158static bfd_boolean
4159is_addr_unit (enum metag_unit unit)
4160{
4161 switch (unit)
4162 {
4163 case UNIT_A0:
4164 case UNIT_A1:
4165 return TRUE;
4166 default:
4167 return FALSE;
4168 }
4169}
4170
4171/* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4172static bfd_boolean
4173is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2)
4174{
4175 if (unit1 == unit2)
4176 return TRUE;
4177
4178 switch (unit1)
4179 {
4180 case UNIT_D0:
4181 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0)
4182 return TRUE;
4183 break;
4184 case UNIT_D1:
4185 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1)
4186 return TRUE;
4187 break;
4188 case UNIT_ACC_D0:
4189 if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0)
4190 return TRUE;
4191 break;
4192 case UNIT_ACC_D1:
4193 if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1)
4194 return TRUE;
4195 break;
4196 case UNIT_RAM_D0:
4197 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0)
4198 return TRUE;
4199 break;
4200 case UNIT_RAM_D1:
4201 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1)
4202 return TRUE;
4203 break;
4204 default:
4205 return FALSE;
4206 }
4207
4208 return FALSE;
4209}
4210
4211/* Return TRUE if the register NUM is a quickrot control register. */
4212static bfd_boolean
4213is_quickrot_reg (unsigned int num)
4214{
4215 switch (num)
4216 {
4217 case 2:
4218 case 3:
4219 return TRUE;
4220 }
4221
4222 return FALSE;
4223}
4224
4225/* Return TRUE if REG is an accumulator register. */
4226static bfd_boolean
4227is_accumulator_reg (const metag_reg *reg)
4228{
4229 if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1)
4230 return TRUE;
4231
4232 return FALSE;
4233}
4234
4235/* Return TRUE if REG is a DSP RAM register. */
4236static bfd_boolean
4237is_dspram_reg (const metag_reg *reg)
4238{
4239 if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1)
4240 return TRUE;
4241
4242 return FALSE;
4243}
4244
4245static const char *
4246__parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load)
4247{
4248 const char *l = line;
4249 char reg_buf[MAX_REG_LEN];
4250 size_t len = 0;
4251
4252 if (l == NULL)
4253 return NULL;
4254
4255 /* Parse [DSPRAM.x]. */
4256 if (*l == ADDR_BEGIN_CHAR)
4257 {
4258 l++;
4259
4260 if (l == NULL)
4261 return NULL;
4262
4263 l = parse_dsp_reg (l, reg, TRUE, load);
4264 if (l == NULL)
4265 return NULL;
4266
4267 if (*l == ADDR_END_CHAR)
4268 l++;
4269 else
4270 {
4271 as_bad (_("expected ']', not %c in %s"), *l, l);
4272 return NULL;
4273 }
4274
4275 return l;
4276 }
4277 else
4278 {
4279
4280 len = strip_reg_name (l, reg_buf);
4281 if (!len)
4282 return NULL;
4283
4284 l += len;
4285 *reg = parse_gp_reg (reg_buf);
4286 if (*reg == NULL)
4287 return NULL;
4288 }
4289
4290 return l;
4291}
4292
4293/* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4294 should try to parse the register as a general-purpose register if
4295 we fail to parse it as a DSP one. TMPL indicates whether the
4296 registers are part of a template definition instruction. If this is
4297 a template definition instruction LOAD says whether it's a load
4298 template insn. FIRST_DST indicates whether the first register is
4299 a destination operand. */
4300static const char *
4301parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count,
4302 size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl,
4303 bfd_boolean load, bfd_boolean first_dst)
4304{
4305 const char *l = line;
4306 int seen_regs = 0;
4307 size_t i;
4308 const metag_reg *reg;
4309
4310 for (i = 0; i < count; i++)
4311 {
4312 const char *next, *ll;
4313
4314 next = l;
4315
4316 if (i > 0)
4317 {
4318 l = skip_comma (l);
4319 if (l == NULL)
4320 {
4321 *regs_read = seen_regs;
4322 return next;
4323 }
4324 }
4325
4326 ll = parse_dsp_reg (l, &reg, tmpl, load);
4327
4328 if (!ll)
4329 {
4330 if (try_gp)
4331 {
4332 l = __parse_gp_reg (l, &reg, !(first_dst && i == 0));
4333 if (l == NULL)
4334 {
4335 *regs_read = seen_regs;
4336 return next;
4337 }
4338 regs[i] = reg;
4339 seen_regs++;
4340 }
4341 else
4342 {
4343 *regs_read = seen_regs;
4344 return l;
4345 }
4346 }
4347 else
4348 {
4349 regs[i] = reg;
4350 seen_regs++;
4351 l = ll;
4352 }
4353 }
4354
4355 *regs_read = seen_regs;
4356 return l;
4357}
4358
4359/* Parse the following memory references:
4360
4361 - [Ax.r]
4362 - [Ax.r++]
4363 - [Ax.r--]
4364 - [Ax.r+Ax.r++]
4365 - [Ax.r-Ax.r--]
4366
4367 - [DSPRam]
4368 - [DSPRam++]
4369 - [DSPRam+DSPRam++]
4370 - [DSPRam-DSPRam--] */
4371static const char *
4372parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size,
4373 bfd_boolean load)
4374{
4375 const char *l = line, *ll;
4376 const metag_reg *regs[1];
4377 size_t regs_read;
4378
4379 /* Skip opening square bracket. */
4380 l++;
4381
4382 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4383
4384 if (l == NULL)
4385 return NULL;
4386
4387 if (!is_addr_unit (regs[0]->unit) &&
4388 !is_dspram_reg (regs[0]))
4389 {
4390 as_bad (_("invalid register for memory access"));
4391 return NULL;
4392 }
4393
4394 addr->base_reg = regs[0];
4395
4396 if (*l == ADDR_END_CHAR)
4397 {
4398 addr->exp.X_op = O_constant;
4399 addr->exp.X_add_symbol = NULL;
4400 addr->exp.X_op_symbol = NULL;
4401
4402 /* Simple register with no offset (0 immediate). */
4403 addr->exp.X_add_number = 0;
4404
4405 addr->immediate = 1;
4406 l++;
4407
4408 return l;
4409 }
4410
4411 ll = parse_addr_post_incr_op (l, addr);
4412
4413 if (ll && *ll == ADDR_END_CHAR)
4414 {
4415 if (addr->update == 1)
4416 {
4417 /* We have a post increment/decrement. */
4418 addr->exp.X_op = O_constant;
4419 addr->exp.X_add_number = size;
4420 addr->exp.X_add_symbol = NULL;
4421 addr->exp.X_op_symbol = NULL;
4422 addr->post_increment = 1;
4423 }
4424 addr->immediate = 1;
4425 ll++;
4426 return ll;
4427 }
4428
4429 addr->post_increment = 0;
4430
4431 l = parse_addr_op (l, addr);
4432
4433 if (l == NULL)
4434 return NULL;
4435
4436 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4437
4438 if (l == NULL)
4439 return NULL;
4440
4441 if (regs[0]->unit != addr->base_reg->unit)
4442 {
4443 as_bad (_("offset and base must be from the same unit"));
4444 return NULL;
4445 }
4446
4447 addr->offset_reg = regs[0];
4448
4449 if (*l == ADDR_END_CHAR)
4450 {
4451 l++;
4452 return l;
4453 }
4454
4455 l = parse_addr_post_incr_op (l, addr);
4456
4457 if (l == NULL)
4458 return NULL;
4459
4460 if (*l == ADDR_END_CHAR)
4461 {
4462 l++;
4463 return l;
4464 }
4465
4466 return NULL;
4467}
4468
4469/* Parse a DSP GET or SET instruction. */
4470static const char *
4471parse_dget_set (const char *line, metag_insn *insn,
4472 const insn_template *template)
4473{
4474 const char *l = line;
4475 metag_addr addr;
4476 int unit = 0;
4477 int rd_reg = 0;
4478 bfd_boolean is_get = (template->meta_opcode & 0x100);
4479 bfd_boolean is_dual = (template->meta_opcode & 0x4);
4480 bfd_boolean is_template = FALSE;
4481 const metag_reg *regs[2];
4482 unsigned int size;
4483 size_t count, regs_read;
4484
4485 memset(&addr, 0, sizeof(addr));
4486 addr.reloc_type = BFD_RELOC_UNUSED;
4487
4488 size = is_dual ? 8 : 4;
4489 count = is_dual ? 2 : 1;
4490
4491 if (is_get)
4492 {
4493 /* GETL can be used on one template table entry. */
4494 if (*l == 'T')
4495 count = 1;
4496
4497 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE,
4498 FALSE, FALSE, FALSE);
4499 l = skip_comma (l);
4500
4501 if (l == NULL)
4502 {
4503 as_bad (_("unexpected end of line"));
4504 return NULL;
4505 }
4506
4507 l = parse_addr (l, &addr, size);
4508 }
4509 else
4510 {
4511 l = parse_addr (l, &addr, size);
4512
4513 l = skip_comma (l);
4514
4515 if (l == NULL)
4516 return NULL;
4517
4518 /* GETL can be used on one template table entry. */
4519 if (*l == 'T')
4520 count = 1;
4521
4522 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE, FALSE,
4523 FALSE, FALSE);
4524 }
4525
4526 if (l == NULL)
4527 return NULL;
4528
4529 /* The first register dictates the unit. */
4530 if (regs[0]->unit == UNIT_DT)
4531 is_template = TRUE;
4532 else
4533 {
4534 if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 ||
4535 regs[0]->unit == UNIT_ACC_D0)
4536 unit = 0;
4537 else
4538 unit = 1;
4539 }
4540
4541 rd_reg = regs[0]->no;
4542
4543 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4544 upper 8-bits of an accumulator. It is _only_ valid for the
4545 accumulators. */
4546 if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH)
4547 {
4548 if (is_template || !(rd_reg >= 16 && rd_reg < 20))
4549 {
4550 as_bad (_("'H' modifier only valid for accumulator registers"));
4551 return NULL;
4552 }
4553
4554 /* Top 8-bits of the accumulator. */
4555 rd_reg |= 8;
4556 }
4557
4558 if (is_template)
4559 {
4560 insn->bits = (template->meta_opcode | (1 << 1));
4561 }
4562 else
4563 {
4564 insn->bits = (template->meta_opcode | unit);
4565 }
4566
4567 insn->bits |= (rd_reg << 19);
4568
4569 if (addr.immediate)
4570 {
4571 int offset = addr.exp.X_add_number;
4572
4573 if (addr.negate)
4574 offset = -offset;
4575
4576 offset = offset / (int)size;
4577
4578 if (!within_signed_range (offset, DGET_SET_IMM_BITS))
4579 {
4580 as_bad (_("offset value out of range"));
4581 return NULL;
4582 }
4583
4584 offset = offset & DGET_SET_IMM_MASK;
4585
4586 insn->bits |= (1 << 13);
4587 insn->bits |= (offset << 9);
4588 }
4589 else
4590 {
4591 int au = (addr.base_reg->unit == UNIT_A1);
4592
4593 insn->bits |= (au << 18);
4594 insn->bits |= ((addr.base_reg->no & REG_MASK) << 14);
4595 insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9);
4596 }
4597
4598 if (is_dual)
4599 insn->bits |= (1 << 2);
4600
4601 if (!is_addr_unit (addr.base_reg->unit))
4602 {
4603 as_bad (_("base unit must be either A0 or A1"));
4604 return NULL;
4605 }
4606
4607 unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1;
4608 insn->bits |= ((addr.base_reg->no << 14) | (unit << 18));
4609
4610 insn->len = 4;
4611
4612 return l;
4613}
4614
4615/* Parse a DSP template instruction. */
4616static const char *
4617parse_dtemplate (const char *line, metag_insn *insn,
4618 const insn_template *template)
4619{
4620 const char *l = line;
4621 const metag_reg *regs[TEMPLATE_NUM_REGS];
4622 bfd_boolean daop_only = FALSE;
4623 int regs_val[4];
4624 int regs_which[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4625 int i;
4626
4627 for (i = 0; i < TEMPLATE_NUM_REGS; i++)
4628 {
4629 if (l == NULL)
4630 {
4631 as_bad (_("unexpected end of line"));
4632 return NULL;
4633 }
4634
4635 /* We may only have 3 register operands. */
4636 if (*l == END_OF_INSN && i == 3)
4637 {
4638 daop_only = TRUE;
4639 break;
4640 }
4641
4642 if (i != 0)
4643 {
4644 l = skip_comma (l);
4645 if (l == NULL)
4646 return NULL;
4647 }
4648
4649 if (*l == IMM_CHAR)
4650 {
4651 l = parse_imm_constant (l, insn, &regs_val[i]);
4652 if (l == NULL)
4653 {
4654 as_bad (_("invalid immediate"));
4655 return NULL;
4656 }
4657 regs_which[i] = 0;
4658 }
4659 else
4660 {
4661 /* We can't tell from the template instantiation whether
4662 this is a load or store. So we have to try looking up the
4663 register name in both the load and store tables. */
4664 const char *l2 = l;
4665 l = __parse_gp_reg (l, &regs[i], TRUE);
4666 if (l == NULL)
4667 {
4668 /* Try the store table too. */
4669 l = __parse_gp_reg (l2, &regs[i], FALSE);
4670 if (l == NULL)
4671 {
4672 /* Then try a DSP register. */
4673 l = parse_dsp_insn_reg (l2, &regs[i]);
4674 if (l == NULL || regs[i]->unit == UNIT_DT)
4675 {
4676 as_bad (_("invalid register"));
4677 return NULL;
4678 }
4679 }
4680 }
4681 regs_which[i] = 1;
4682 }
4683 }
4684
4685 insn->bits = template->meta_opcode;
4686
4687 if (regs_which[0] == 0)
4688 insn->bits |= (regs_val[0] << 19);
4689 else if (regs_which[0] == 1)
4690 insn->bits |= (regs[0]->no << 19);
4691
4692 if (regs_which[1] == 0)
4693 insn->bits |= (regs_val[1] << 14);
4694 else if (regs_which[1] == 1)
4695 insn->bits |= (regs[1]->no << 14);
4696
4697 if (regs_which[2] == 0)
4698 insn->bits |= (regs_val[2] << 9);
4699 else if (regs_which[2] == 1)
4700 insn->bits |= (regs[2]->no << 9);
4701
4702 if (regs_which[3] == 0)
4703 insn->bits |= (regs_val[3] << 4);
4704 else if (regs_which[3] == 1)
4705 insn->bits |= (regs[3]->no << 4);
4706
4707 /* DaOp only. */
4708 if (daop_only)
4709 insn->bits |= (0x3 << 24); /* Set the minor opcode. */
4710 else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store. */
4711 insn->bits |= (0x5 << 24); /* Set the minor opcode. */
4712
4713 insn->len = 4;
4714
4715 return l;
4716}
4717
4718/* Parse a DSP Template definiton memory reference, e.g
4719 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4720 template definition is a DSP RAM template definition. */
4721static const char *
4722template_mem_ref(const char *line, metag_addr *addr,
4723 bfd_boolean *dspram, int size, bfd_boolean load)
4724{
4725 const char *l = line;
4726
4727 l = parse_dsp_addr (l, addr, size, load);
4728
4729 if (l != NULL)
4730 {
4731 if (is_addr_unit(addr->base_reg->unit))
4732 *dspram = FALSE;
4733 else
4734 *dspram = TRUE;
4735 }
4736
4737 return l;
4738}
4739
4740/* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4741 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4742static const char *
4743parse_template_regs (const char *line, bfd_boolean *load,
4744 unsigned int *addr_unit,
4745 const metag_reg **template_reg, metag_addr *addr,
4746 bfd_boolean *dspram, int size)
4747{
4748 const char *l = line;
4749
4750 if (l == NULL)
4751 return NULL;
4752
4753 /* DSP Template load definition (Tx, [Ax]) */
4754 if (*l == 'T')
4755 {
4756 *load = TRUE;
4757 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4758 if (l == NULL)
4759 return NULL;
4760
4761 l = skip_comma (l);
4762
4763 l = template_mem_ref (l, addr, dspram, size, *load);
4764
4765 if (addr->base_reg->unit == UNIT_A1)
4766 *addr_unit = 1;
4767
4768 }
4769 else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */
4770 {
4771 *load = FALSE;
4772 l = template_mem_ref (l, addr, dspram, size, *load);
4773 l = skip_comma(l);
4774
4775 if (l == NULL)
4776 return NULL;
4777
4778 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4779 if (l == NULL)
4780 return NULL;
4781
4782 if (addr->base_reg->unit == UNIT_A1)
4783 *addr_unit = 1;
4784 }
4785 else
4786 {
4787 as_bad (_("invalid register operand"));
4788 return NULL;
4789 }
4790
4791 return l;
4792}
4793
4794#define INVALID_SHIFT (-1)
4795
4796static metag_reg _reg;
4797
4798/* Parse a template instruction definition. */
4799static const char *
4800interpret_template_regs(const char *line, metag_insn *insn,
4801 const metag_reg **regs,
4802 int *regs_shift, bfd_boolean *load, bfd_boolean *dspram,
4803 int size, int *ls_shift, int *au_shift,
4804 unsigned int *au, int *imm, int *imm_shift,
4805 unsigned int *imm_mask)
4806{
4807 const char *l = line;
4808 metag_addr addr;
4809 const metag_reg *template_reg[1];
4810
4811 memset (&addr, 0, sizeof(addr));
4812
4813 regs_shift[0] = 19;
4814 regs_shift[1] = INVALID_SHIFT;
4815
4816 insn->bits |= (1 << 1);
4817
4818 l = skip_whitespace (l);
4819
4820 l = parse_template_regs (l, load, au, template_reg,
4821 &addr, dspram, size);
4822 if (l == NULL)
4823 {
4824 as_bad (_("could not parse template definition"));
4825 return NULL;
4826 }
4827
4828 regs[2] = template_reg[0];
4829 regs_shift[2] = 9;
4830
4831 /* DSPRAM definition. */
4832 if (*dspram)
4833 {
4834
4835 _reg = *addr.base_reg;
4836
4837 if (addr.immediate)
4838 {
4839 /* Set the post-increment bit in the register field. */
4840 if (addr.update)
4841 _reg.no |= 0x1;
4842 }
4843 else
4844 {
4845 /* The bottom bit of the increment register tells us
4846 whether it's increment register 0 or 1. */
4847 if (addr.offset_reg->no & 0x1)
4848 _reg.no |= 0x3;
4849 else
4850 _reg.no |= 0x2;
4851 }
4852
4853 regs[0] = &_reg;
4854
4855 insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition. */
4856 }
4857 else /* DaOpPaMe definition. */
4858 {
4859 regs[0] = addr.base_reg;
4860 if (addr.immediate)
4861 {
4862 /* Set the I bit. */
4863 insn->bits |= (1 << 18);
4864
4865 if (addr.update == 1)
4866 {
4867 if (addr.negate == 1)
4868 *imm = 0x3;
4869 else
4870 *imm = 0x1;
4871 }
4872
4873 *imm_shift = 14;
4874 *imm_mask = 0x3;
4875 }
4876 else
4877 {
4878 /* Setup the offset register. */
4879 regs[1] = addr.offset_reg;
4880 regs_shift[1] = 14;
4881 }
4882 *au_shift = 23;
4883 }
4884
4885 *ls_shift = 13;
4886
4887 return l;
4888}
4889
4890/* Does this combination of units need the O2R bit and can it be encoded? */
4891static bfd_boolean
4892units_need_o2r (enum metag_unit unit1, enum metag_unit unit2)
4893{
4894 if (unit1 == unit2)
4895 return FALSE;
4896
4897 if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0)
4898 {
4899 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0)
4900 return FALSE;
4901
4902 switch (unit2)
4903 {
4904 case UNIT_A1:
4905 case UNIT_D1:
4906 case UNIT_RD:
4907 case UNIT_A0:
4908 return TRUE;
4909 default:
4910 return FALSE;
4911 }
4912 }
4913
4914 if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1)
4915 {
4916 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1)
4917 return FALSE;
4918
4919 switch (unit2)
4920 {
4921 case UNIT_A1:
4922 case UNIT_D0:
4923 case UNIT_RD:
4924 case UNIT_A0:
4925 return TRUE;
4926 default:
4927 return FALSE;
4928 }
4929 }
4930
4931 return FALSE;
4932}
4933
4934/* Return TRUE if this is a DSP data unit. */
4935static bfd_boolean
4936is_dsp_data_unit (const metag_reg *reg)
4937{
4938 switch (reg->unit)
4939 {
4940 case UNIT_D0:
4941 case UNIT_D1:
4942 case UNIT_ACC_D0:
4943 case UNIT_ACC_D1:
4944 case UNIT_RAM_D0:
4945 case UNIT_RAM_D1:
4946 return TRUE;
4947 default:
4948 return FALSE;
4949 }
4950}
4951
4952static metag_reg o2r_reg;
4953
4954/* Parse a DaOpPaMe load template definition. */
4955static const char *
4956parse_dalu (const char *line, metag_insn *insn,
4957 const insn_template *template)
4958{
4959 const char *l = line;
4960 const char *ll;
4961 const metag_reg *regs[4];
4962 metag_addr addr;
4963 size_t regs_read;
4964 bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD;
4965 bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) &&
4966 ((template->meta_opcode & 0xee) == 0));
4967 bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL);
4968 bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0);
4969 int l1_shift = INVALID_SHIFT;
4970 bfd_boolean load = FALSE;
4971 int ls_shift = INVALID_SHIFT;
4972 bfd_boolean ar = FALSE;
4973 int ar_shift = INVALID_SHIFT;
4974 int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT };
4975 int imm = 0;
4976 int imm_shift = INVALID_SHIFT;
4977 unsigned int imm_mask = 0;
4978 unsigned int au = 0;
4979 int au_shift = INVALID_SHIFT;
4980 unsigned int du = 0;
4981 int du_shift = INVALID_SHIFT;
4982 unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0);
4983 int sc_shift = INVALID_SHIFT;
4984 unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0);
4985 int om_shift = INVALID_SHIFT;
4986 unsigned int o2r = 0;
4987 int o2r_shift = INVALID_SHIFT;
4988 unsigned int qr = 0;
4989 int qr_shift = INVALID_SHIFT;
4990 int qd_shift = INVALID_SHIFT;
4991 unsigned int qn = 0;
4992 int qn_shift = INVALID_SHIFT;
4993 unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0);
4994 int a1_shift = INVALID_SHIFT;
4995 unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0);
4996 int a2_shift = INVALID_SHIFT;
4997 unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0);
4998 int su_shift = INVALID_SHIFT;
4999 unsigned int ac;
5000 int ac_shift = INVALID_SHIFT;
5001 unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) ||
5002 (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0);
5003 int mx_shift = INVALID_SHIFT;
5004 int size = is_dual ? 8 : 4;
5005 bfd_boolean dspram;
5006 bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4);
5007
5008 /* XFIXME: check the flags are valid with the instruction. */
5009 if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR))
5010 {
5011 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5012 return NULL;
5013 }
5014
5015 insn->bits = template->meta_opcode;
5016
5017 memset (regs, 0, sizeof (regs));
5018 memset (&addr, 0, sizeof (addr));
5019
5020 /* There are the following forms of DSP ALU instructions,
5021
5022 * Group 1:
5023 19. D[T] Op De.r,Dx.r,De.r
5024 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5025 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5026 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5027 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5028 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5029 8. D Opcc De.r,Dx.r,Rx.r
5030 6. D Op De.r,Dx.r,Rx.r|RD
5031 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5032 7. D Op De.e,Dx.r,#I16
5033
5034 * Group 2:
5035 4. D[T] Op Dx.r,De.r
5036 10. D Op Dx.r,Rx.r|RD
5037 13. D Op Dx.r,Rx.r
5038 11. D Op Dx.r,#I16
5039 12. D[T] Op De.r,Dx.r
5040 14. D Op DSPe.r,Dx.r
5041 15. D Op DSPx.r,#I16
5042 16. D Op De.r,DSPx.r
5043 18. D Op De.r,Dx.r|ACx.r
5044
5045 * Group 3:
5046 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5047 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5048 21. D Op De.r,Dx.r|ACx.r,#I5 */
5049
5050 /* Group 1. */
5051 if (template->arg_type & DSP_ARGS_1)
5052 {
5053 du_shift = 24;
5054
5055 /* Could this be a cross-unit accumulator op,
5056 e.g. ACe.e,ACx.r,ACo.e */
5057 if (template->arg_type & DSP_ARGS_XACC)
5058 {
5059 ll = parse_dsp_regs_list (l, regs, 3, &regs_read, FALSE, FALSE,
5060 FALSE, FALSE);
5061 if (ll != NULL && regs_read == 3
5062 && is_accumulator_reg (regs[0]))
5063 {
5064 if (regs[0]->unit != regs[1]->unit ||
5065 regs[2]->unit == regs[1]->unit)
5066 {
5067 as_bad (_("invalid operands for cross-unit op"));
5068 return NULL;
5069 }
5070
5071 du = (regs[1]->unit == UNIT_ACC_D1);
5072 regs_shift[1] = 19;
5073 l = ll;
5074
5075 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5076 insn->bits |= (5 << 6);
5077
5078 goto check_for_template;
5079 }
5080
5081 /* If we reach here, this instruction is not a
5082 cross-unit accumulator op. */
5083 }
5084
5085 if (template->arg_type & DSP_ARGS_SPLIT8)
5086 om_shift = 7;
5087
5088 sc_shift = 5;
5089 l1_shift = 4;
5090 o2r_shift = 0;
5091
5092 /* De.r|ACe.r,Dx.r,De.r */
5093 if (template->arg_type & DSP_ARGS_DACC)
5094 {
5095 /* XFIXME: these need moving? */
5096 a2_shift = 7;
5097 su_shift = 6;
5098 a1_shift = 2;
5099 om_shift = 3;
5100
5101 ll = parse_dsp_reg (l, &regs[0], FALSE, FALSE);
5102 if (ll != NULL)
5103 {
5104 /* Using ACe.r as the dst requires one of the P,N or Z
5105 flags to be used. */
5106 if (!(insn->dsp_action_flags &
5107 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5108 {
5109 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5110 return NULL;
5111 }
5112
5113 l = ll;
5114 l = skip_comma (l);
5115 l = parse_dsp_regs_list (l, &regs[1], 2, &regs_read,
5116 TRUE, FALSE, FALSE, FALSE);
5117 if (l == NULL || regs_read != 2)
5118 {
5119 as_bad (_("invalid register"));
5120 return NULL;
5121 }
5122
5123 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5124 du = 1;
5125
5126 regs_shift[0] = 19;
5127 regs_shift[1] = 14;
5128 regs_shift[2] = 9;
5129 goto check_for_template;
5130 }
5131
5132 /* If we reach here, this instruction does not use the
5133 accumulator as the destination register. */
5134 if ((insn->dsp_action_flags &
5135 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5136 {
5137 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5138 return NULL;
5139 }
5140 }
5141
5142 regs_shift[0] = 19;
5143
5144
5145 l = parse_dsp_regs_list (l, regs, 2, &regs_read, TRUE, FALSE, FALSE, TRUE);
5146 if (l == NULL || regs_read != 2)
5147 return NULL;
5148
5149 l = skip_comma (l);
5150 if (l == NULL)
5151 return NULL;
5152
5153 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5154 du = 1;
5155
5156 if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC))
5157 {
5158 as_bad (_("accumulator not a valid destination"));
5159 return NULL;
5160 }
5161
5162 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5163 if (*l == IMM_CHAR)
5164 {
5165 l = parse_imm16 (l, insn, &imm);
5166 if (l == NULL)
5167 {
5168 as_bad (_("invalid immediate value"));
5169 return NULL;
5170 }
5171
5172 if (!within_signed_range (imm, IMM16_BITS))
5173 {
5174 as_bad (_("immediate value out of range"));
5175 return NULL;
5176 }
5177
5178 if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no)
5179 {
5180 as_bad (_("immediate value not allowed when source & dest differ"));
5181 return NULL;
5182 }
5183
5184 imm_mask = 0xffff;
5185 imm_shift = 3;
5186
5187 /* Set the I-bit */
5188 insn->bits |= (1 << 25);
5189
5190 insn->bits |= (0x3 << 0);
5191
5192 l1_shift = 2;
5193
5194 /* Remove any bits that have been set in the immediate
5195 field. */
5196 insn->bits &= ~(imm_mask << imm_shift);
5197 }
5198 else
5199 {
5200
5201 regs_shift[1] = 14;
5202 regs_shift[2] = 9;
5203
5204 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5205 ll = parse_dsp_reg (l, &regs[2], FALSE, FALSE);
5206 if (ll != NULL)
5207 {
5208 l = ll;
5209
5210 if (!(template->arg_type & DSP_ARGS_ACC2))
5211 {
5212 as_bad (_("invalid register operand: %s"), regs[2]->name);
5213 return NULL;
5214 }
5215
5216 om_shift = 3;
5217 ar_shift = 7;
5218 ar = TRUE;
5219 }
5220 else
5221 {
5222 /* De.r,Dx.r,De.r */
5223 l = __parse_gp_reg (l, &regs[2], TRUE);
5224 if (l == NULL)
5225 return NULL;
5226 }
5227
5228 if (template->arg_type & DSP_ARGS_ACC2)
5229 om_shift = 3;
5230
5231 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5232 if (template->arg_type & DSP_ARGS_QR)
5233 {
5234 if (conditional)
5235 qn_shift = 5;
5236 else
5237 {
5238 qn_shift = 7;
5239 qr_shift = 6;
5240 qd_shift = 5;
5241 }
5242
5243 l = skip_comma (l);
5244 if (l == NULL)
5245 {
5246 as_bad (_("QUICKRoT extension requires 4 registers"));
5247 return NULL;
5248 }
5249
5250 l = __parse_gp_reg (l, &regs[3], TRUE);
5251 if (l == NULL)
5252 {
5253 as_bad (_("invalid fourth register"));
5254 return NULL;
5255 }
5256
5257 if (!is_addr_unit (regs[3]->unit) ||
5258 !is_quickrot_reg (regs[3]->no))
5259 {
5260 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5261 return NULL;
5262 }
5263
5264 qn = (regs[3]->no == 3);
5265 }
5266 }
5267
5268 check_for_template:
5269 /* This is the common exit path. Check for o2r. */
5270 if (regs[2] != NULL)
5271 {
5272 o2r = units_need_o2r (regs[1]->unit, regs[2]->unit);
5273 if (o2r)
5274 {
5275 o2r_reg.no = lookup_o2r (0, du, regs[2]);
5276 o2r_reg.unit = regs[2]->unit;
5277 regs[2] = &o2r_reg;
5278 }
5279 }
5280
5281 /* Check any DSP RAM pointers are valid for this unit. */
5282 if ((du && (regs[0]->unit == UNIT_RAM_D0)) ||
5283 (!du && (regs[0]->unit == UNIT_RAM_D1)) ||
5284 (du && (regs[1]->unit == UNIT_RAM_D0)) ||
5285 (!du && (regs[1]->unit == UNIT_RAM_D1)) ||
5286 (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) ||
5287 (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) {
5288 as_bad (_("DSP RAM pointer in incorrect unit"));
5289 return NULL;
5290 }
5291
5292 /* Is this a template definition? */
5293 if (IS_TEMPLATE_DEF (insn))
5294 {
5295 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5296 &dspram, size, &ls_shift, &au_shift,
5297 &au, &imm, &imm_shift, &imm_mask);
5298
5299 if (l == NULL)
5300 return NULL;
5301
5302 if (!dspram)
5303 mx_shift = 0;
5304 }
5305
5306 goto matched;
5307 }
5308
5309 /* Group 2. */
5310 if (template->arg_type & DSP_ARGS_2)
5311 {
5312 bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) &&
5313 (MINOR_OPCODE (template->meta_opcode) == 0xa));
5314 bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU;
5315 bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1;
5316
5317 if (is_xsd)
5318 du_shift = 0;
5319 else
5320 du_shift = 24;
5321
5322 l1_shift = 4;
5323
5324 /* CMPs and TSTs don't store to their destination operand. */
5325 ll = __parse_gp_reg (l, regs, is_cmp);
5326 if (ll == NULL)
5327 {
5328 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5329 if (template->arg_type & DSP_ARGS_DSP_SRC1)
5330 {
5331 l = parse_dsp_reg (l, regs, FALSE, FALSE);
5332 if (l == NULL)
5333 {
5334 as_bad (_("invalid register operand #1"));
5335 return NULL;
5336 }
5337
5338 /* Only MOV instructions have a DSP register as a
5339 destination. Set the MOV DSPe.r opcode. The simple
5340 OR'ing is OK because the usual MOV opcode is 0x00. */
5341 insn->bits = (0x91 << 24);
5342 du_shift = 0;
5343 l1_shift = 2;
5344 regs_shift[0] = 19;
5345 }
5346 else
5347 {
5348 as_bad (_("invalid register operand #2"));
5349 return NULL;
5350 }
5351 }
5352 else
5353 {
5354 l = ll;
5355
5356 /* Everything but CMP and TST. */
5357 if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
5358 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5359 MAJOR_OPCODE (insn->bits) == OPC_9 ||
5360 MAJOR_OPCODE (template->meta_opcode) == OPC_MISC ||
5361 ((template->meta_opcode & 0x0000002c) != 0))
5362 regs_shift[0] = 19;
5363 else
5364 regs_shift[0] = 14;
5365 }
5366
5367 if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX &&
5368 is_fpu_mov && to_fpu))
5369 return NULL;
5370
5371 du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 ||
5372 regs[0]->unit == UNIT_ACC_D1);
5373
5374 l = skip_comma (l);
5375
5376 if (*l == IMM_CHAR)
5377 {
5378 if (template->arg_type & DSP_ARGS_IMM &&
5379 !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)))
5380 {
5381 l = parse_imm16 (l, insn, &imm);
5382 if (l == NULL)
5383 {
5384 as_bad (_("invalid immediate value"));
5385 return NULL;
5386 }
5387
5388 if (!within_signed_range (imm, IMM16_BITS))
5389 return NULL;
5390
5391 l1_shift = 2;
5392 regs_shift[0] = 19;
5393
5394 imm_mask = 0xffff;
5395 imm_shift = 3;
5396
5397 /* Set the I-bit unless it's a MOV because they're
5398 different. */
5399 if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9))
5400 insn->bits |= (1 << 25);
5401
5402 /* All instructions that takes immediates also have bit 1 set. */
5403 insn->bits |= (1 << 1);
5404
5405 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5406 insn->bits |= (1 << 0);
5407
5408 insn->bits &= ~(1 << 8);
5409 }
5410 else
5411 {
5412 as_bad (_("this instruction does not accept an immediate"));
5413 return NULL;
5414 }
5415 }
5416 else
5417 {
5418 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5419 {
5420 insn->bits |= (1 << 8);
5421 l1_shift = 4;
5422 }
5423
5424 ll = __parse_gp_reg (l, &regs[1], TRUE);
5425 if (ll == NULL)
5426 {
5427 if (template->arg_type & DSP_ARGS_DSP_SRC2)
5428 {
5429 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5430 if (l == NULL)
5431 {
5432 as_bad (_("invalid register operand #3"));
5433 return NULL;
5434 }
5435
5436 /* MOV and NEG. */
5437 if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) ||
5438 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB)
5439 {
5440 if (is_accumulator_reg (regs[1]))
5441 {
5442 if (is_fpu_mov)
5443 {
5444 as_bad (_("this instruction does not accept an accumulator"));
5445 return NULL;
5446 }
5447 ar_shift = 7;
5448 ar = 1;
5449 regs_shift[1] = 9;
5450 }
5451 else
5452 {
5453 du_shift = 0;
5454 l1_shift = 2;
5455 regs_shift[1] = 14;
5456 insn->bits = (0x92 << 24); /* Set opcode. */
5457 }
5458 }
5459 }
5460 else
5461 {
5462 as_bad (_("invalid register operand #4"));
5463 return NULL;
5464 }
5465 }
5466 else
5467 {
5468 /* Set the o2r bit if required. */
5469 if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit))
5470 {
5471 o2r_reg = *regs[1];
5472 o2r_reg.no = lookup_o2r (0, du, regs[1]);
5473 regs[1] = &o2r_reg;
5474 o2r_shift = 0;
5475 o2r = 1;
5476 }
5477 else if (!is_dsp_data_unit (regs[1]) &&
5478 !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX))
5479 return NULL;
5480
5481 if (is_fpu_mov && to_fpu)
5482 du = (regs[1]->unit == UNIT_D1 ||
5483 regs[1]->unit == UNIT_RAM_D1 ||
5484 regs[1]->unit == UNIT_ACC_D1);
5485
5486 l = ll;
5487
5488 if (MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5489 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5490 (((template->meta_opcode & 0x0000002c) == 0) &&
5491 MAJOR_OPCODE (template->meta_opcode) != OPC_MISC))
5492 regs_shift[1] = 9;
5493 else
5494 regs_shift[1] = 14;
5495 }
5496 }
5497
5498 /* If it's an 0x0 MOV or NEG set some lower bits. */
5499 if ((MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5500 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov)
5501 {
5502 om_shift = 3;
5503 sc_shift = 5;
5504 insn->bits |= (1 << 2);
5505 }
5506
5507 /* Check for template definitons. */
5508 if (IS_TEMPLATE_DEF (insn))
5509 {
5510 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5511 &dspram, size, &ls_shift, &au_shift,
5512 &au, &imm, &imm_shift, &imm_mask);
5513 mx_shift = 0;
5514
5515 if (l == NULL)
5516 return NULL;
5517 }
5518 goto matched;
5519 }
5520
5521 /* Group 3. */
5522 du_shift = 24;
5523 l1_shift = 4;
5524
5525 l = __parse_gp_reg (l, regs, FALSE);
5526 if (l == NULL)
5527 {
5528 as_bad (_("invalid register operand"));
5529 return NULL;
5530 }
5531
5532 l = skip_comma (l);
5533
5534 if (*l == 'A')
5535 {
5536 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5537 if (l == NULL)
5538 {
5539 as_bad (_("invalid accumulator register"));
5540 return NULL;
5541 }
5542 ac = 1;
5543 ac_shift = 0;
5544 }
5545 else
5546 {
5547 l = __parse_gp_reg (l, &regs[1], TRUE);
5548 if (l == NULL)
5549 {
5550 as_bad (_("invalid register operand"));
5551 return NULL;
5552 }
5553 }
5554
5555 regs_shift[0] = 19;
5556 regs_shift[1] = 14;
5557
5558 du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1
5559 || regs[1]->unit == UNIT_RAM_D1);
5560
5561 l = skip_comma (l);
5562
5563 if (*l == IMM_CHAR)
5564 {
5565 l = parse_imm_constant (l, insn, &imm);
5566 if (l == NULL)
5567 {
5568 as_bad (_("invalid immediate value"));
5569 return NULL;
5570 }
5571
5572 if (!within_unsigned_range (imm, IMM5_BITS))
5573 return NULL;
5574
5575 imm_mask = 0x1f;
5576 imm_shift = 9;
5577
5578 /* Set the I-bit */
5579 insn->bits |= (1 << 25);
5580 }
5581 else
5582 {
5583 regs_shift[2] = 9;
5584 l = __parse_gp_reg (l, &regs[2], TRUE);
5585 if (l == NULL)
5586 return NULL;
5587 }
5588
5589 /* Check for post-processing R,G,B flags. Conditional instructions
5590 do not have these bits. */
5591 if (insn->dsp_action_flags & DSP_ACTION_CLAMP9)
5592 {
5593 if ((template->meta_opcode >> 26) & 0x1)
5594 {
5595 as_bad (_("conditional instruction cannot use G flag"));
5596 return NULL;
5597 }
5598
5599 insn->bits |= (1 << 3);
5600 }
5601
5602 if (insn->dsp_action_flags & DSP_ACTION_CLAMP8)
5603 {
5604 if ((template->meta_opcode >> 26) & 0x1)
5605 {
5606 as_bad (_("conditional instruction cannot use B flag"));
5607 return NULL;
5608 }
5609
5610 insn->bits |= (0x3 << 2);
5611 }
5612
5613 if (insn->dsp_action_flags & DSP_ACTION_ROUND)
5614 {
5615 if ((template->meta_opcode >> 26) & 0x1)
5616 {
5617 as_bad (_("conditional instruction cannot use R flag"));
5618 return NULL;
5619 }
5620 insn->bits |= (1 << 2);
5621 }
5622
5623 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5624 if ((template->meta_opcode >> 26) & 0x1)
5625 ls_shift = INVALID_SHIFT;
5626
5627 /* The Condition Is Always (CA) bit must be set if we're targetting a
5628 Ux.r register as the destination. This means that we can't have
5629 any other condition bits set. */
5630 if (!is_same_data_unit (regs[1]->unit, regs[0]->unit))
5631 {
5632 /* Set both the Conditional bit and the Condition is Always bit. */
5633 insn->bits |= (1 << 26);
5634 insn->bits |= (1 << 5);
5635
5636 /* Fill out the Ud field. */
5637 insn->bits |= (regs[0]->unit << 1);
5638 }
5639
5640 if (IS_TEMPLATE_DEF (insn))
5641 {
5642 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5643 &dspram, size, &ls_shift, &au_shift,
5644 &au, &imm, &imm_shift, &imm_mask);
5645
5646 if (l == NULL)
5647 return NULL;
5648
5649 if (!dspram)
5650 mx_shift = 5;
5651 }
5652
5653 /* Fall through. */
5654 matched:
5655
5656 /* Set the registers and immediate values. */
5657 if (regs_shift[0] != INVALID_SHIFT)
5658 insn->bits |= (regs[0]->no << regs_shift[0]);
5659
5660 if (regs_shift[1] != INVALID_SHIFT)
5661 insn->bits |= (regs[1]->no << regs_shift[1]);
5662
5663 if (regs_shift[2] != INVALID_SHIFT)
5664 insn->bits |= (regs[2]->no << regs_shift[2]);
5665
5666 /* Does this insn have an 'IMM' bit? The immediate value should
5667 already have been masked. */
5668 if (imm_shift != INVALID_SHIFT)
5669 insn->bits |= ((imm & imm_mask) << imm_shift);
5670
5671 /* Does this insn have an 'AU' bit? */
5672 if (au_shift != INVALID_SHIFT)
5673 insn->bits |= (au << au_shift);
5674
5675 /* Does this instruction have an 'LS' bit? */
5676 if (ls_shift != INVALID_SHIFT)
5677 insn->bits |= (load << ls_shift);
5678
5679 /* Does this instruction have an 'AR' bit? */
5680 if (ar)
5681 insn->bits |= (1 << ar_shift);
5682
5683 if (du_shift != INVALID_SHIFT)
5684 insn->bits |= (du << du_shift);
5685
5686 if (sc_shift != INVALID_SHIFT)
5687 insn->bits |= (sc << sc_shift);
5688
5689 if (om_shift != INVALID_SHIFT)
5690 insn->bits |= (om << om_shift);
5691
5692 if (o2r_shift != INVALID_SHIFT)
5693 insn->bits |= (o2r << o2r_shift);
5694
5695 if (qn_shift != INVALID_SHIFT)
5696 insn->bits |= (qn << qn_shift);
5697
5698 if (qr_shift != INVALID_SHIFT)
5699 insn->bits |= (qr << qr_shift);
5700
5701 if (qd_shift != INVALID_SHIFT)
5702 insn->bits |= (is_quickrot64 << qd_shift);
5703
5704 if (a1_shift != INVALID_SHIFT)
5705 insn->bits |= (a1 << a1_shift);
5706
5707 if (a2_shift != INVALID_SHIFT)
5708 insn->bits |= (a2 << a2_shift);
5709
5710 if (su_shift != INVALID_SHIFT)
5711 insn->bits |= (su << su_shift);
5712
5713 if (imm_shift != INVALID_SHIFT)
5714 insn->bits |= ((imm & imm_mask) << imm_shift);
5715
5716 if (ac_shift != INVALID_SHIFT)
5717 insn->bits |= (ac << ac_shift);
5718
5719 if (mx_shift != INVALID_SHIFT)
5720 insn->bits |= (mx << mx_shift);
5721
5722 if (is_dual)
5723 {
5724 if (l1_shift == INVALID_SHIFT)
5725 {
5726 as_bad (_("'L' modifier not valid for this instruction"));
5727 return NULL;
5728 }
5729
5730 insn->bits |= (1 << l1_shift);
5731 }
5732
5733 insn->len = 4;
5734
5735 return l;
5736}
5737
5738typedef const char *(*insn_parser)(const char *, metag_insn *,
5739 const insn_template *);
5740
5741/* Parser table. */
5742static const insn_parser insn_parsers[ENC_MAX] =
5743 {
5744 [ENC_NONE] = parse_none,
5745 [ENC_MOV_U2U] = parse_mov_u2u,
5746 [ENC_MOV_PORT] = parse_mov_port,
5747 [ENC_MMOV] = parse_mmov,
5748 [ENC_MDRD] = parse_mdrd,
5749 [ENC_MOVL_TTREC] = parse_movl_ttrec,
5750 [ENC_GET_SET] = parse_get_set,
5751 [ENC_GET_SET_EXT] = parse_get_set_ext,
5752 [ENC_MGET_MSET] = parse_mget_mset,
5753 [ENC_COND_SET] = parse_cond_set,
5754 [ENC_XFR] = parse_xfr,
5755 [ENC_MOV_CT] = parse_mov_ct,
5756 [ENC_SWAP] = parse_swap,
5757 [ENC_JUMP] = parse_jump,
5758 [ENC_CALLR] = parse_callr,
5759 [ENC_ALU] = parse_alu,
5760 [ENC_SHIFT] = parse_shift,
5761 [ENC_MIN_MAX] = parse_min_max,
5762 [ENC_BITOP] = parse_bitop,
5763 [ENC_CMP] = parse_cmp,
5764 [ENC_BRANCH] = parse_branch,
5765 [ENC_KICK] = parse_kick,
5766 [ENC_SWITCH] = parse_switch,
5767 [ENC_CACHER] = parse_cacher,
5768 [ENC_CACHEW] = parse_cachew,
5769 [ENC_ICACHE] = parse_icache,
5770 [ENC_LNKGET] = parse_lnkget,
5771 [ENC_FMOV] = parse_fmov,
5772 [ENC_FMMOV] = parse_fmmov,
5773 [ENC_FMOV_DATA] = parse_fmov_data,
5774 [ENC_FMOV_I] = parse_fmov_i,
5775 [ENC_FPACK] = parse_fpack,
5776 [ENC_FSWAP] = parse_fswap,
5777 [ENC_FCMP] = parse_fcmp,
5778 [ENC_FMINMAX] = parse_fminmax,
5779 [ENC_FCONV] = parse_fconv,
5780 [ENC_FCONVX] = parse_fconvx,
5781 [ENC_FBARITH] = parse_fbarith,
5782 [ENC_FEARITH] = parse_fearith,
5783 [ENC_FREC] = parse_frec,
5784 [ENC_FSIMD] = parse_fsimd,
5785 [ENC_FGET_SET_ACF] = parse_fget_set_acf,
5786 [ENC_DGET_SET] = parse_dget_set,
5787 [ENC_DTEMPLATE] = parse_dtemplate,
5788 [ENC_DALU] = parse_dalu,
5789 };
5790
5791struct metag_core_option
5792{
e0471c16 5793 const char *name;
a3c62988
NC
5794 unsigned int value;
5795};
5796
5797/* CPU type options. */
5798static const struct metag_core_option metag_cpus[] =
5799 {
5800 {"all", CoreMeta11|CoreMeta12|CoreMeta21},
5801 {"metac11", CoreMeta11},
5802 {"metac12", CoreMeta12},
5803 {"metac21", CoreMeta21},
5804 {NULL, 0},
5805 };
5806
5807/* FPU type options. */
5808static const struct metag_core_option metag_fpus[] =
5809 {
5810 {"metac21", FpuMeta21},
5811 {NULL, 0},
5812 };
5813
5814/* DSP type options. */
5815static const struct metag_core_option metag_dsps[] =
5816 {
5817 {"metac21", DspMeta21},
5818 {NULL, 0},
5819 };
5820
5821/* Parse a CPU command line option. */
5822static int
17b9d67d 5823metag_parse_cpu (const char * str)
a3c62988
NC
5824{
5825 const struct metag_core_option * opt;
5826 int optlen;
5827
5828 optlen = strlen (str);
5829
5830 if (optlen == 0)
5831 {
5832 as_bad (_("missing cpu name `%s'"), str);
5833 return 0;
5834 }
5835
5836 for (opt = metag_cpus; opt->name != NULL; opt++)
5837 if (strncmp (opt->name, str, optlen) == 0)
5838 {
5839 mcpu_opt = opt->value;
5840 return 1;
5841 }
5842
5843 as_bad (_("unknown cpu `%s'"), str);
5844 return 0;
5845}
5846
5847/* Parse an FPU command line option. */
5848static int
17b9d67d 5849metag_parse_fpu (const char * str)
a3c62988
NC
5850{
5851 const struct metag_core_option * opt;
5852 int optlen;
5853
5854 optlen = strlen (str);
5855
5856 if (optlen == 0)
5857 {
5858 as_bad (_("missing fpu name `%s'"), str);
5859 return 0;
5860 }
5861
5862 for (opt = metag_fpus; opt->name != NULL; opt++)
5863 if (strncmp (opt->name, str, optlen) == 0)
5864 {
5865 mfpu_opt = opt->value;
5866 return 1;
5867 }
5868
5869 as_bad (_("unknown fpu `%s'"), str);
5870 return 0;
5871}
5872
5873/* Parse a DSP command line option. */
5874static int
17b9d67d 5875metag_parse_dsp (const char * str)
a3c62988
NC
5876{
5877 const struct metag_core_option * opt;
5878 int optlen;
5879
5880 optlen = strlen (str);
5881
5882 if (optlen == 0)
5883 {
5884 as_bad (_("missing DSP name `%s'"), str);
5885 return 0;
5886 }
5887
5888 for (opt = metag_dsps; opt->name != NULL; opt++)
5889 if (strncmp (opt->name, str, optlen) == 0)
5890 {
5891 mdsp_opt = opt->value;
5892 return 1;
5893 }
5894
5895 as_bad (_("unknown DSP `%s'"), str);
5896 return 0;
5897}
5898
5899struct metag_long_option
5900{
e0471c16
TS
5901 const char * option; /* Substring to match. */
5902 const char * help; /* Help information. */
17b9d67d 5903 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 5904 const char * deprecated; /* If non-null, print this message. */
a3c62988
NC
5905};
5906
5907struct metag_long_option metag_long_opts[] =
5908 {
5909 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5910 metag_parse_cpu, NULL},
5911 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5912 metag_parse_fpu, NULL},
5913 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5914 metag_parse_dsp, NULL},
5915 {NULL, NULL, 0, NULL}
5916 };
5917
5918int
17b9d67d 5919md_parse_option (int c, const char * arg)
a3c62988
NC
5920{
5921 struct metag_long_option *lopt;
5922
5923 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5924 {
5925 /* These options are expected to have an argument. */
5926 if (c == lopt->option[0]
5927 && arg != NULL
5928 && strncmp (arg, lopt->option + 1,
5929 strlen (lopt->option + 1)) == 0)
5930 {
5931#if WARN_DEPRECATED
5932 /* If the option is deprecated, tell the user. */
5933 if (lopt->deprecated != NULL)
5934 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
5935 _(lopt->deprecated));
5936#endif
5937
5938 /* Call the sup-option parser. */
5939 return lopt->func (arg + strlen (lopt->option) - 1);
5940 }
5941 }
5942
5943 return 0;
5944}
5945
5946void
5947md_show_usage (FILE * stream)
5948{
5949 struct metag_long_option *lopt;
5950
5951 fprintf (stream, _(" Meta specific command line options:\n"));
5952
5953 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5954 if (lopt->help != NULL)
5955 fprintf (stream, " -%s%s\n", lopt->option, _(lopt->help));
5956}
5957
5958/* The target specific pseudo-ops which we support. */
5959const pseudo_typeS md_pseudo_table[] =
5960{
5961 { "word", cons, 2 },
5962 { NULL, NULL, 0 }
5963};
5964
5965void
5966md_begin (void)
5967{
5968 int c;
5969
5970 for (c = 0; c < 256; c++)
5971 {
5972 if (ISDIGIT (c))
5973 {
5974 register_chars[c] = c;
5975 /* LOCK0, LOCK1, LOCK2. */
5976 mnemonic_chars[c] = c;
5977 }
5978 else if (ISLOWER (c))
5979 {
5980 register_chars[c] = c;
5981 mnemonic_chars[c] = c;
5982 }
5983 else if (ISUPPER (c))
5984 {
5985 register_chars[c] = c;
5986 mnemonic_chars[c] = c;
5987 }
5988 else if (c == '.')
5989 {
5990 register_chars[c] = c;
5991 }
5992 }
5993}
5994
5995/* Parse a split condition code prefix. */
5996static const char *
5997parse_split_condition (const char *line, metag_insn *insn)
5998{
5999 const char *l = line;
6000 const split_condition *scond;
6001 split_condition entry;
6002 char buf[4];
6003
6004 memcpy (buf, l, 4);
6005 buf[3] = '\0';
6006
6007 entry.name = buf;
6008
6009 scond = (const split_condition *) htab_find (scond_htab, &entry);
6010
6011 if (!scond)
6012 return NULL;
6013
6014 insn->scond = scond->code;
6015
6016 return l + strlen (scond->name);
6017}
6018
6019/* Parse an instruction prefix - F for float, D for DSP - and associated
6020 flags and condition codes. */
6021static const char *
6022parse_prefix (const char *line, metag_insn *insn)
6023{
6024 const char *l = line;
6025
6026 l = skip_whitespace (l);
6027
6028 insn->type = INSN_GP;
6029
6030 if (TOLOWER (*l) == FPU_PREFIX_CHAR)
6031 {
6032 if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN)))
6033 {
6034 insn->type = INSN_FPU;
6035
6036 l++;
6037
6038 if (*l == END_OF_INSN)
6039 {
6040 as_bad (_("premature end of floating point prefix"));
6041 return NULL;
6042 }
6043
6044 if (TOLOWER (*l) == FPU_DOUBLE_CHAR)
6045 {
6046 insn->fpu_width = FPU_WIDTH_DOUBLE;
6047 l++;
6048 }
6049 else if (TOLOWER (*l) == FPU_PAIR_CHAR)
6050 {
6051 const char *l2 = l;
6052
6053 /* Check this isn't a split condition beginning with L. */
6054 l2 = parse_split_condition (l2, insn);
6055
6056 if (l2 && is_whitespace_char (*l2))
6057 {
6058 l = l2;
6059 }
6060 else
6061 {
6062 insn->fpu_width = FPU_WIDTH_PAIR;
6063 l++;
6064 }
6065 }
6066 else
6067 {
6068 insn->fpu_width = FPU_WIDTH_SINGLE;
6069 }
6070
6071 if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR)
6072 {
6073 insn->fpu_action_flags |= FPU_ACTION_ABS;
6074 l++;
6075 }
6076 else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR)
6077 {
6078 insn->fpu_action_flags |= FPU_ACTION_INV;
6079 l++;
6080 }
6081
6082 if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR)
6083 {
6084 insn->fpu_action_flags |= FPU_ACTION_QUIET;
6085 l++;
6086 }
6087
6088 if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR)
6089 {
6090 insn->fpu_action_flags |= FPU_ACTION_ZERO;
6091 l++;
6092 }
6093
6094 if (! is_whitespace_char (*l))
6095 {
6096 l = parse_split_condition (l, insn);
6097
6098 if (!l)
6099 {
6100 as_bad (_("unknown floating point prefix character"));
6101 return NULL;
6102 }
6103 }
6104
6105 l = skip_space (l);
6106 }
6107 }
6108 else if (TOLOWER (*l) == DSP_PREFIX_CHAR)
6109 {
6110 if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) &&
6111 strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN)))
6112 {
6113 const char *ll = l;
6114 insn->type = INSN_DSP;
6115
6116 l++;
6117
6118 insn->dsp_width = DSP_WIDTH_SINGLE;
6119
6120 while (!is_whitespace_char (*l))
6121 {
6122 /* We have to check for split condition codes first
6123 because they are the longest strings to match,
6124 e.g. if the string contains "LLS" we want it to match
6125 the split condition code "LLS", not the dual unit
6126 character "L". */
6127 ll = l;
6128 l = parse_split_condition (l, insn);
6129
6130 if (l == NULL)
6131 l = ll;
6132 else
6133 continue;
6134
6135 /* Accept an FPU prefix char which may be used when doing
6136 template MOV with FPU registers. */
6137 if (TOLOWER(*l) == FPU_PREFIX_CHAR)
6138 {
6139 insn->type = INSN_DSP_FPU;
6140 l++;
6141 continue;
6142 }
6143
6144 if (TOLOWER(*l) == DSP_DUAL_CHAR)
6145 {
6146 insn->dsp_width = DSP_WIDTH_DUAL;
6147 l++;
6148 continue;
6149 }
6150
6151 if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR)
6152 {
6153 insn->dsp_action_flags |= DSP_ACTION_QR64;
6154 l++;
6155 continue;
6156 }
6157
6158 if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR)
6159 {
6160 insn->dsp_action_flags |= DSP_ACTION_UMUL;
6161 l++;
6162 continue;
6163 }
6164
6165 if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR)
6166 {
6167 insn->dsp_action_flags |= DSP_ACTION_ROUND;
6168 l++;
6169 continue;
6170 }
6171
6172 if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR)
6173 {
6174 insn->dsp_action_flags |= DSP_ACTION_CLAMP9;
6175 l++;
6176 continue;
6177 }
6178
6179 if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR)
6180 {
6181 insn->dsp_action_flags |= DSP_ACTION_CLAMP8;
6182 l++;
6183 continue;
6184 }
6185
6186 if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR)
6187 {
6188 insn->dsp_action_flags |= DSP_ACTION_MOD;
6189 l++;
6190 continue;
6191 }
6192
6193 if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR)
6194 {
6195 insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO;
6196 l++;
6197 continue;
6198 }
6199
6200 if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR)
6201 {
6202 insn->dsp_action_flags |= DSP_ACTION_ACC_ADD;
6203 l++;
6204 continue;
6205 }
6206
6207 if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR)
6208 {
6209 insn->dsp_action_flags |= DSP_ACTION_ACC_SUB;
6210 l++;
6211 continue;
6212 }
6213
6214 if (TOLOWER(*l) == DSP_ACTION_OV_CHAR)
6215 {
6216 insn->dsp_action_flags |= DSP_ACTION_OV;
6217 l++;
6218 continue;
6219 }
6220
6221 if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR)
6222 {
6223 insn->dsp_daoppame_flags |= DSP_DAOPPAME_8;
6224 l++;
6225 continue;
6226 }
6227
6228 if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR)
6229 {
6230 insn->dsp_daoppame_flags |= DSP_DAOPPAME_16;
6231 l++;
6232 continue;
6233 }
6234
6235 if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR)
6236 {
6237 insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP;
6238 l++;
6239 continue;
6240 }
6241
6242 if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR)
6243 {
6244 insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH;
6245 l++;
6246 continue;
6247 }
6248
6249 as_bad (_("unknown DSP prefix character %c %s"), *l, l);
6250 return NULL;
6251 }
6252
6253 l = skip_space (l);
6254 }
6255 }
6256
6257 return l;
6258}
6259
6260/* Return a list of appropriate instruction parsers for MNEMONIC. */
6261static insn_templates *
6262find_insn_templates (const char *mnemonic)
6263{
6264 insn_template template;
6265 insn_templates entry;
6266 insn_templates *slot;
6267
6268 entry.template = &template;
6269
6270 memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *));
6271
6272 slot = (insn_templates *) htab_find (mnemonic_htab, &entry);
6273
6274 if (slot)
6275 return slot;
6276
6277 return NULL;
6278}
6279
6280/* Make an uppercase copy of SRC into DST and return DST. */
6281static char *
6282strupper (char * dst, const char *src)
6283{
6284 size_t i = 0;
6285
6286 while (src[i])
6287 {
6288 dst[i] = TOUPPER (src[i]);
6289 i++;
6290 }
6291
6292 dst[i] = 0;
6293
6294 return dst;
6295}
6296
6297/* Calculate a hash value for a template. */
6298static hashval_t
6299hash_templates (const void *p)
6300{
6301 insn_templates *tp = (insn_templates *)p;
6302 char buf[MAX_MNEMONIC_LEN];
6303
6304 strupper (buf, tp->template->name);
6305
6306 return htab_hash_string (buf);
6307}
6308
6309/* Check if two templates are equal. */
6310static int
6311eq_templates (const void *a, const void *b)
6312{
6313 insn_templates *ta = (insn_templates *)a;
6314 insn_templates *tb = (insn_templates *)b;
6315 return strcasecmp (ta->template->name, tb->template->name) == 0;
6316}
6317
6318/* Create the hash table required for parsing instructions. */
6319static void
6320create_mnemonic_htab (void)
6321{
6322 size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]);
6323
6324 mnemonic_htab = htab_create_alloc (num_templates, hash_templates,
6325 eq_templates, NULL, xcalloc, free);
6326
6327 for (i = 0; i < num_templates; i++)
6328 {
6329 const insn_template *template = &metag_optab[i];
6330 insn_templates **slot = NULL;
6331 insn_templates *new_entry;
6332
add39d23 6333 new_entry = XNEW (insn_templates);
a3c62988
NC
6334
6335 new_entry->template = template;
6336 new_entry->next = NULL;
6337
6338 slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry,
6339 INSERT);
6340
6341 if (*slot)
6342 {
6343 insn_templates *last_entry = *slot;
6344
6345 while (last_entry->next)
6346 last_entry = last_entry->next;
6347
6348 last_entry->next = new_entry;
6349 }
6350 else
6351 {
6352 *slot = new_entry;
6353 }
6354 }
6355}
6356
6357/* Calculate a hash value for a register. */
6358static hashval_t
6359hash_regs (const void *p)
6360{
6361 metag_reg *rp = (metag_reg *)p;
6362 char buf[MAX_REG_LEN];
6363
6364 strupper (buf, rp->name);
6365
6366 return htab_hash_string (buf);
6367}
6368
6369/* Check if two registers are equal. */
6370static int
6371eq_regs (const void *a, const void *b)
6372{
6373 metag_reg *ra = (metag_reg *)a;
6374 metag_reg *rb = (metag_reg *)b;
6375 return strcasecmp (ra->name, rb->name) == 0;
6376}
6377
6378/* Create the hash table required for parsing registers. */
6379static void
6380create_reg_htab (void)
6381{
6382 size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]);
6383
6384 reg_htab = htab_create_alloc (num_regs, hash_regs,
6385 eq_regs, NULL, xcalloc, free);
6386
6387 for (i = 0; i < num_regs; i++)
6388 {
6389 const metag_reg *reg = &metag_regtab[i];
6390 const metag_reg **slot;
6391
6392 slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT);
6393
6394 if (!*slot)
6395 *slot = reg;
6396 }
6397}
6398
6399/* Create the hash table required for parsing DSP registers. */
6400static void
6401create_dspreg_htabs (void)
6402{
6403 size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]);
6404 size_t h;
6405
6406 dsp_reg_htab = htab_create_alloc (num_regs, hash_regs,
6407 eq_regs, NULL, xcalloc, free);
6408
6409 for (i = 0; i < num_regs; i++)
6410 {
6411 const metag_reg *reg = &metag_dsp_regtab[i];
6412 const metag_reg **slot;
6413
6414 slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT);
6415
6416 /* Make sure there are no hash table collisions, which would
6417 require chaining entries. */
76e7a751 6418 gas_assert (*slot == NULL);
a3c62988
NC
6419 *slot = reg;
6420 }
6421
6422 num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]);
6423
6424 for (h = 0; h < 2; h++)
6425 {
6426 dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs,
6427 eq_regs, NULL, xcalloc, free);
6428 }
6429
6430 for (h = 0; h < 2; h++)
6431 {
6432 for (i = 0; i < num_regs; i++)
6433 {
6434 const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i];
6435 const metag_reg **slot;
6436 slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h],
6437 reg, INSERT);
6438
6439 /* Make sure there are no hash table collisions, which would
6440 require chaining entries. */
76e7a751 6441 gas_assert (*slot == NULL);
a3c62988
NC
6442 *slot = reg;
6443 }
6444 }
6445}
6446
6447/* Calculate a hash value for a split condition code. */
6448static hashval_t
6449hash_scond (const void *p)
6450{
6451 split_condition *cp = (split_condition *)p;
6452 char buf[4];
6453
6454 strupper (buf, cp->name);
6455
6456 return htab_hash_string (buf);
6457}
6458
6459/* Check if two split condition codes are equal. */
6460static int
6461eq_scond (const void *a, const void *b)
6462{
6463 split_condition *ra = (split_condition *)a;
6464 split_condition *rb = (split_condition *)b;
6465
6466 return strcasecmp (ra->name, rb->name) == 0;
6467}
6468
6469/* Create the hash table required for parsing split condition codes. */
6470static void
6471create_scond_htab (void)
6472{
6473 size_t i, nentries;
6474
6475 nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]);
6476
6477 scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond,
6478 NULL, xcalloc, free);
6479 for (i = 0; i < nentries; i++)
6480 {
6481 const split_condition *scond = &metag_scondtab[i];
6482 const split_condition **slot;
6483
6484 slot = (const split_condition **) htab_find_slot (scond_htab,
6485 scond, INSERT);
6486 /* Make sure there are no hash table collisions, which would
6487 require chaining entries. */
76e7a751 6488 gas_assert (*slot == NULL);
a3c62988
NC
6489 *slot = scond;
6490 }
6491}
6492
6493/* Entry point for instruction parsing. */
6494static bfd_boolean
6495parse_insn (const char *line, metag_insn *insn)
6496{
6497 char mnemonic[MAX_MNEMONIC_LEN];
6498 const char *l = line;
6499 size_t mnemonic_len = 0;
6500 insn_templates *templates;
6501
6502 l = skip_space (l);
6503
6504 while (is_mnemonic_char(*l))
6505 {
6506 l++;
6507 mnemonic_len++;
6508 }
6509
6510 if (mnemonic_len >= MAX_MNEMONIC_LEN)
6511 {
6512 as_bad (_("instruction mnemonic too long: %s"), line);
6513 return FALSE;
6514 }
6515
6516 strncpy(mnemonic, line, mnemonic_len);
6517
6518 mnemonic[mnemonic_len] = '\0';
6519
6520 templates = find_insn_templates (mnemonic);
6521
6522 if (templates)
6523 {
6524 insn_templates *current_template = templates;
6525
6526 l = skip_space (l);
6527
6528 while (current_template)
6529 {
6530 const insn_template *template = current_template->template;
6531 enum insn_encoding encoding = template->encoding;
6532 insn_parser parser = insn_parsers[encoding];
6533
6534 current_template = current_template->next;
6535
6536 if (template->insn_type == INSN_GP &&
6537 !(template->core_flags & mcpu_opt))
6538 continue;
6539
6540 if (template->insn_type == INSN_FPU &&
6541 !(template->core_flags & mfpu_opt))
6542 continue;
6543
6544 if (template->insn_type == INSN_DSP &&
6545 !(template->core_flags & mdsp_opt))
6546 continue;
6547
6548 if (template->insn_type == INSN_DSP_FPU &&
6549 !((template->core_flags & mdsp_opt) &&
6550 (template->core_flags & mfpu_opt)))
6551 continue;
6552
6553 /* DSP instructions always require special decoding */
6554 if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) ||
6555 ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) ||
6556 (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) ||
6557 ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU))
6558 continue;
6559
6560 if (parser)
6561 {
6562 const char *end = parser(l, insn, template);
6563
6564 if (end != NULL)
6565 {
6566 if (*end != END_OF_INSN)
6567 as_bad (_("junk at end of line: \"%s\""), line);
6568 else
6569 return TRUE;
6570 }
6571 }
6572 }
6573
6574 as_bad (_("failed to assemble instruction: \"%s\""), line);
6575 }
6576 else
6577 {
6578 if (insn->type == INSN_FPU)
6579 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic);
6580 else
6581 as_bad (_("unknown mnemonic: \"%s\""), mnemonic);
6582 }
6583 return FALSE;
6584}
6585
6586static void
6587output_insn (metag_insn *insn)
6588{
6589 char *output;
6590
6591 output = frag_more (insn->len);
6592 dwarf2_emit_insn (insn->len);
6593
6594 if (insn->reloc_type != BFD_RELOC_UNUSED)
6595 {
6596 fix_new_exp (frag_now, output - frag_now->fr_literal,
6597 insn->reloc_size, &insn->reloc_exp,
6598 insn->reloc_pcrel, insn->reloc_type);
6599 }
6600
6601 md_number_to_chars (output, insn->bits, insn->len);
6602}
6603
6604void
6605md_assemble (char *line)
6606{
6607 const char *l = line;
6608 metag_insn insn;
6609
6610 memset (&insn, 0, sizeof(insn));
6611
6612 insn.reloc_type = BFD_RELOC_UNUSED;
6613 insn.reloc_pcrel = 0;
6614 insn.reloc_size = 4;
6615
6616 if (!mnemonic_htab)
6617 {
6618 create_mnemonic_htab ();
6619 create_reg_htab ();
6620 create_dspreg_htabs ();
6621 create_scond_htab ();
6622 }
6623
6624 l = parse_prefix (l, &insn);
6625
6626 if (l == NULL)
6627 return;
6628
6629 if (insn.type == INSN_DSP &&
6630 !mdsp_opt)
6631 {
6632 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6633 line);
6634 return;
6635 }
6636 else if (insn.type == INSN_FPU &&
6637 !mfpu_opt)
6638 {
6639 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6640 line);
6641 return;
6642 }
6643
6644 if (!parse_insn (l, &insn))
6645 return;
6646
6647 output_insn (&insn);
6648}
6649
6650void
6651md_operand (expressionS * expressionP)
6652{
6653 if (* input_line_pointer == IMM_CHAR)
6654 {
6655 input_line_pointer ++;
6656 expression (expressionP);
6657 }
6658}
6659
6660valueT
6661md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
6662{
6663 return size;
6664}
6665
6666symbolS *
6667md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
6668{
6669 return NULL;
6670}
6671
6672/* Functions concerning relocs. */
6673
6674/* The location from which a PC relative jump should be calculated,
6675 given a PC relative reloc. */
6676
6677long
6678md_pcrel_from_section (fixS * fixP, segT sec)
6679{
6680 if ((fixP->fx_addsy != (symbolS *) NULL
6681 && (! S_IS_DEFINED (fixP->fx_addsy)
6682 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
6683 || metag_force_relocation (fixP))
6684 {
6685 /* The symbol is undefined (or is defined but not in this section).
6686 Let the linker figure it out. */
6687 return 0;
6688 }
6689
6690 return fixP->fx_frag->fr_address + fixP->fx_where;
6691}
6692
6693/* Write a value out to the object file, using the appropriate endianness. */
6694
6695void
6696md_number_to_chars (char * buf, valueT val, int n)
6697{
6698 number_to_chars_littleendian (buf, val, n);
6699}
6700
6701/* Turn a string in input_line_pointer into a floating point constant of type
6702 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6703 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6704*/
6705
6706/* Equal to MAX_PRECISION in atof-ieee.c */
6707#define MAX_LITTLENUMS 6
6708
6d4af3c2 6709const char *
a3c62988
NC
6710md_atof (int type, char * litP, int * sizeP)
6711{
6712 int i;
6713 int prec;
6714 LITTLENUM_TYPE words [MAX_LITTLENUMS];
6715 char * t;
6716
6717 switch (type)
6718 {
6719 case 'f':
6720 case 'F':
6721 case 's':
6722 case 'S':
6723 prec = 2;
6724 break;
6725
6726 case 'd':
6727 case 'D':
6728 case 'r':
6729 case 'R':
6730 prec = 4;
6731 break;
6732
6733 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6734
6735 default:
6736 * sizeP = 0;
6737 return _("Bad call to md_atof()");
6738 }
6739
6740 t = atof_ieee (input_line_pointer, type, words);
6741 if (t)
6742 input_line_pointer = t;
6743 * sizeP = prec * sizeof (LITTLENUM_TYPE);
6744
6745 for (i = 0; i < prec; i++)
6746 {
6747 md_number_to_chars (litP, (valueT) words[i],
6748 sizeof (LITTLENUM_TYPE));
6749 litP += sizeof (LITTLENUM_TYPE);
6750 }
6751
6752 return 0;
6753}
6754
6755/* If this function returns non-zero, it prevents the relocation
6756 against symbol(s) in the FIXP from being replaced with relocations
6757 against section symbols, and guarantees that a relocation will be
6758 emitted even when the value can be resolved locally. */
6759
6760int
6761metag_force_relocation (fixS * fix)
6762{
6763 switch (fix->fx_r_type)
6764 {
6765 case BFD_RELOC_METAG_RELBRANCH_PLT:
6766 case BFD_RELOC_METAG_TLS_LE:
6767 case BFD_RELOC_METAG_TLS_IE:
6768 case BFD_RELOC_METAG_TLS_LDO:
6769 case BFD_RELOC_METAG_TLS_LDM:
6770 case BFD_RELOC_METAG_TLS_GD:
6771 return 1;
6772 default:
6773 ;
6774 }
6775
6776 return generic_force_reloc (fix);
6777}
6778
6779bfd_boolean
6780metag_fix_adjustable (fixS * fixP)
6781{
6782 if (fixP->fx_addsy == NULL)
6783 return 1;
6784
6785 /* Prevent all adjustments to global symbols. */
6786 if (S_IS_EXTERNAL (fixP->fx_addsy))
6787 return 0;
6788 if (S_IS_WEAK (fixP->fx_addsy))
6789 return 0;
6790
6791 if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF ||
6792 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF ||
6793 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF ||
6794 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT ||
6795 fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC ||
6796 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC ||
6797 fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT ||
6798 fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT ||
6799 fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT)
6800 return 0;
6801
6802 /* We need the symbol name for the VTABLE entries. */
6803 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6804 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6805 return 0;
6806
6807 return 1;
6808}
6809
6810/* Return an initial guess of the length by which a fragment must grow to
6811 hold a branch to reach its destination.
6812 Also updates fr_type/fr_subtype as necessary.
6813
6814 Called just before doing relaxation.
6815 Any symbol that is now undefined will not become defined.
6816 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6817 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6818 Although it may not be explicit in the frag, pretend fr_var starts with a
6819 0 value. */
6820
6821int
6822md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
6823 segT segment ATTRIBUTE_UNUSED)
6824{
6825 /* No assembler relaxation is defined (or necessary) for this port. */
6826 abort ();
6827}
6828
6829/* *fragP has been relaxed to its final size, and now needs to have
6830 the bytes inside it modified to conform to the new size.
6831
6832 Called after relaxation is finished.
6833 fragP->fr_type == rs_machine_dependent.
6834 fragP->fr_subtype is the subtype of what the address relaxed to. */
6835
6836void
6837md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
6838 fragS * fragP ATTRIBUTE_UNUSED)
6839{
6840 /* No assembler relaxation is defined (or necessary) for this port. */
6841 abort ();
6842}
6843
6844/* This is called from HANDLE_ALIGN in tc-metag.h. */
6845
6846void
6847metag_handle_align (fragS * fragP)
6848{
81cead6f 6849 static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
a3c62988
NC
6850 int bytes, fix;
6851 char *p;
6852
6853 if (fragP->fr_type != rs_align_code)
6854 return;
6855
6856 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
6857 p = fragP->fr_literal + fragP->fr_fix;
6858 fix = 0;
6859
6860 if (bytes & 3)
6861 {
6862 fix = bytes & 3;
6863 memset (p, 0, fix);
6864 p += fix;
6865 bytes -= fix;
6866 }
6867
6868 while (bytes >= 4)
6869 {
6870 memcpy (p, noop, 4);
6871 p += 4;
6872 bytes -= 4;
6873 fix += 4;
6874 }
6875
6876 fragP->fr_fix += fix;
6877 fragP->fr_var = 4;
6878}
6879
6880static char *
e0471c16 6881metag_end_of_match (char * cont, const char * what)
a3c62988
NC
6882{
6883 int len = strlen (what);
6884
6885 if (strncasecmp (cont, what, strlen (what)) == 0
6886 && ! is_part_of_name (cont[len]))
6887 return cont + len;
6888
6889 return NULL;
6890}
6891
6892int
6893metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
6894 char * nextcharP)
6895{
6896 char *next = input_line_pointer;
6897 char *next_end;
6898 int reloc_type;
6899 operatorT op_type;
6900 segT segment;
6901
6902 exprP->X_op_symbol = NULL;
6903 exprP->X_md = BFD_RELOC_UNUSED;
6904
6905 if (strcmp (name, GOT_NAME) == 0)
6906 {
6907 if (! GOT_symbol)
6908 GOT_symbol = symbol_find_or_make (name);
6909
6910 exprP->X_add_symbol = GOT_symbol;
6911 no_suffix:
6912 /* If we have an absolute symbol or a
6913 reg, then we know its value now. */
6914 segment = S_GET_SEGMENT (exprP->X_add_symbol);
6915 if (mode != expr_defer && segment == absolute_section)
6916 {
6917 exprP->X_op = O_constant;
6918 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6919 exprP->X_add_symbol = NULL;
6920 }
6921 else if (mode != expr_defer && segment == reg_section)
6922 {
6923 exprP->X_op = O_register;
6924 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6925 exprP->X_add_symbol = NULL;
6926 }
6927 else
6928 {
6929 exprP->X_op = O_symbol;
6930 exprP->X_add_number = 0;
6931 }
6932
6933 return 1;
6934 }
6935
6936 exprP->X_add_symbol = symbol_find_or_make (name);
6937
6938 if (*nextcharP != '@')
6939 goto no_suffix;
6940 else if ((next_end = metag_end_of_match (next + 1, "GOTOFF")))
6941 {
6942 reloc_type = BFD_RELOC_METAG_GOTOFF;
6943 op_type = O_PIC_reloc;
6944 }
6945 else if ((next_end = metag_end_of_match (next + 1, "GOT")))
6946 {
6947 reloc_type = BFD_RELOC_METAG_GETSET_GOT;
6948 op_type = O_PIC_reloc;
6949 }
6950 else if ((next_end = metag_end_of_match (next + 1, "PLT")))
6951 {
6952 reloc_type = BFD_RELOC_METAG_PLT;
6953 op_type = O_PIC_reloc;
6954 }
6955 else if ((next_end = metag_end_of_match (next + 1, "TLSGD")))
6956 {
6957 reloc_type = BFD_RELOC_METAG_TLS_GD;
6958 op_type = O_PIC_reloc;
6959 }
6960 else if ((next_end = metag_end_of_match (next + 1, "TLSLDM")))
6961 {
6962 reloc_type = BFD_RELOC_METAG_TLS_LDM;
6963 op_type = O_PIC_reloc;
6964 }
6965 else if ((next_end = metag_end_of_match (next + 1, "TLSLDO")))
6966 {
6967 reloc_type = BFD_RELOC_METAG_TLS_LDO;
6968 op_type = O_PIC_reloc;
6969 }
6970 else if ((next_end = metag_end_of_match (next + 1, "TLSIE")))
6971 {
6972 reloc_type = BFD_RELOC_METAG_TLS_IE;
6973 op_type = O_PIC_reloc;
6974 }
6975 else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC")))
6976 {
6977 reloc_type = BFD_RELOC_METAG_TLS_IENONPIC;
6978 op_type = O_PIC_reloc; /* FIXME: is this correct? */
6979 }
6980 else if ((next_end = metag_end_of_match (next + 1, "TLSLE")))
6981 {
6982 reloc_type = BFD_RELOC_METAG_TLS_LE;
6983 op_type = O_PIC_reloc;
6984 }
6985 else
6986 goto no_suffix;
6987
6988 *input_line_pointer = *nextcharP;
6989 input_line_pointer = next_end;
6990 *nextcharP = *input_line_pointer;
6991 *input_line_pointer = '\0';
6992
6993 exprP->X_op = op_type;
6994 exprP->X_add_number = 0;
6995 exprP->X_md = reloc_type;
6996
6997 return 1;
6998}
6999
7000/* If while processing a fixup, a reloc really needs to be created
7001 then it is done here. */
7002
7003arelent *
e6c7cdec 7004tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
a3c62988
NC
7005{
7006 arelent *reloc;
7007
add39d23
TS
7008 reloc = XNEW (arelent);
7009 reloc->sym_ptr_ptr = XNEW (asymbol *);
a3c62988
NC
7010 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7011 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
7012
7013 reloc->addend = fixp->fx_offset;
7014 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
7015
7016 if (reloc->howto == (reloc_howto_type *) NULL)
7017 {
7018 as_bad_where (fixp->fx_file, fixp->fx_line,
7019 /* xgettext:c-format. */
7020 _("reloc %d not supported by object file format"),
7021 (int) fixp->fx_r_type);
7022
7023 xfree (reloc);
7024
7025 return NULL;
7026 }
7027
7028 return reloc;
7029}
7030
7031static unsigned int
7032md_chars_to_number (char *val, int n)
7033{
7034 int retval;
7035 unsigned char * where = (unsigned char *) val;
7036
7037 for (retval = 0; n--;)
7038 {
7039 retval <<= 8;
7040 retval |= where[n];
7041 }
7042 return retval;
7043}
7044
7045void
7046md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
7047{
7048 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7049 int value = (int)*valP;
7050
7051 switch (fixP->fx_r_type)
7052 {
7053 case BFD_RELOC_METAG_TLS_GD:
7054 case BFD_RELOC_METAG_TLS_LE_HI16:
7055 case BFD_RELOC_METAG_TLS_LE_LO16:
7056 case BFD_RELOC_METAG_TLS_IE:
7057 case BFD_RELOC_METAG_TLS_IENONPIC_HI16:
7058 case BFD_RELOC_METAG_TLS_IENONPIC_LO16:
7059 case BFD_RELOC_METAG_TLS_LDM:
7060 case BFD_RELOC_METAG_TLS_LDO_HI16:
7061 case BFD_RELOC_METAG_TLS_LDO_LO16:
7062 S_SET_THREAD_LOCAL (fixP->fx_addsy);
7063 /* Fall through */
7064
7065 case BFD_RELOC_METAG_HIADDR16:
7066 case BFD_RELOC_METAG_LOADDR16:
7067 case BFD_RELOC_VTABLE_INHERIT:
7068 case BFD_RELOC_VTABLE_ENTRY:
7069 fixP->fx_done = FALSE;
7070 break;
7071
7072 case BFD_RELOC_METAG_REL8:
7073 if (!within_unsigned_range (value, IMM8_BITS))
7074 {
7075 as_bad_where (fixP->fx_file, fixP->fx_line,
7076 "rel8 out of range %d", value);
7077 }
7078 else
7079 {
7080 unsigned int newval;
7081 newval = md_chars_to_number (buf, 4);
7082 newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6);
7083 md_number_to_chars (buf, newval, 4);
7084 }
7085 break;
7086 case BFD_RELOC_METAG_REL16:
7087 if (!within_unsigned_range (value, IMM16_BITS))
7088 {
7089 as_bad_where (fixP->fx_file, fixP->fx_line,
7090 "rel16 out of range %d", value);
7091 }
7092 else
7093 {
7094 unsigned int newval;
7095 newval = md_chars_to_number (buf, 4);
7096 newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3);
7097 md_number_to_chars (buf, newval, 4);
7098 }
7099 break;
7100
7101 case BFD_RELOC_8:
7102 md_number_to_chars (buf, value, 1);
7103 break;
7104 case BFD_RELOC_16:
7105 md_number_to_chars (buf, value, 2);
7106 break;
7107 case BFD_RELOC_32:
7108 md_number_to_chars (buf, value, 4);
7109 break;
7110 case BFD_RELOC_64:
7111 md_number_to_chars (buf, value, 8);
7112
7113 case BFD_RELOC_METAG_RELBRANCH:
7114 if (!value)
7115 break;
7116
7117 value = value / 4;
7118
7119 if (!within_signed_range (value, IMM19_BITS))
7120 {
7121 as_bad_where (fixP->fx_file, fixP->fx_line,
7122 "relbranch out of range %d", value);
7123 }
7124 else
7125 {
7126 unsigned int newval;
7127 newval = md_chars_to_number (buf, 4);
7128 newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
7129 md_number_to_chars (buf, newval, 4);
7130 }
7131 break;
7132 default:
7133 break;
7134 }
7135
7136 if (fixP->fx_addsy == NULL)
7137 fixP->fx_done = TRUE;
7138}
This page took 0.473598 seconds and 4 git commands to generate.