1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2 Copyright (C) 2013 Free Software Foundation, Inc.
3 Contributed by Imagination Technologies Ltd.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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
25 #include "safe-ctype.h"
31 #include "opcode/metag.h"
33 const char comment_chars
[] = "!";
34 const char line_comment_chars
[] = "!#";
35 const char line_separator_chars
[] = ";";
36 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
37 const char EXP_CHARS
[] = "eE";
38 const char metag_symbol_chars
[] = "[";
40 static char register_chars
[256];
41 static char mnemonic_chars
[256];
43 #define is_register_char(x) (register_chars[(unsigned char) x])
44 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
45 #define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
46 #define is_space_char(x) ((x) == ' ')
48 #define FPU_PREFIX_CHAR 'f'
49 #define DSP_PREFIX_CHAR 'd'
51 /* Instruction mnemonics that need disambiguating with respect to prefixes. */
52 #define FFB_INSN "ffb"
53 #define DCACHE_INSN "dcache"
54 #define DEFR_INSN "defr"
56 #define FPU_DOUBLE_CHAR 'd'
57 #define FPU_PAIR_CHAR 'l'
59 #define DSP_DUAL_CHAR 'l'
61 #define END_OF_INSN '\0'
63 /* Maximum length of a mnemonic including all suffixes. */
64 #define MAX_MNEMONIC_LEN 16
65 /* Maximum length of a register name. */
66 #define MAX_REG_LEN 17
68 /* Addressing modes must be enclosed with square brackets. */
69 #define ADDR_BEGIN_CHAR '['
70 #define ADDR_END_CHAR ']'
71 /* Immediates must be prefixed with a hash. */
78 /* Short units are those that can be encoded with 2 bits. */
79 #define SHORT_UNITS "D0, D1, A0 or A1"
81 static unsigned int mcpu_opt
= CoreMeta12
;
82 static unsigned int mfpu_opt
= 0;
83 static unsigned int mdsp_opt
= 0;
85 const char * md_shortopts
= "m:";
87 struct option md_longopts
[] =
89 {NULL
, no_argument
, NULL
, 0}
91 size_t md_longopts_size
= sizeof (md_longopts
);
93 /* Parser hash tables. */
94 static htab_t mnemonic_htab
;
95 static htab_t reg_htab
;
96 static htab_t dsp_reg_htab
;
97 static htab_t dsp_tmpl_reg_htab
[2];
98 static htab_t scond_htab
;
100 #define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
101 symbolS
* GOT_symbol
;
103 enum fpu_insn_width
{
109 #define FPU_ACTION_ABS_CHAR 'a'
110 #define FPU_ACTION_INV_CHAR 'i'
111 #define FPU_ACTION_QUIET_CHAR 'q'
112 #define FPU_ACTION_ZERO_CHAR 'z'
114 #define FPU_ACTION_ABS 0x1
115 #define FPU_ACTION_INV 0x2
116 #define FPU_ACTION_QUIET 0x4
117 #define FPU_ACTION_ZERO 0x8
119 enum dsp_insn_width
{
124 #define DSP_ACTION_QR64_CHAR 'q'
125 #define DSP_ACTION_UMUL_CHAR 'u'
126 #define DSP_ACTION_ROUND_CHAR 'r'
127 #define DSP_ACTION_CLAMP9_CHAR 'g'
128 #define DSP_ACTION_CLAMP8_CHAR 'b'
129 #define DSP_ACTION_MOD_CHAR 'm'
130 #define DSP_ACTION_ACC_ZERO_CHAR 'z'
131 #define DSP_ACTION_ACC_ADD_CHAR 'p'
132 #define DSP_ACTION_ACC_SUB_CHAR 'n'
133 #define DSP_ACTION_OV_CHAR 'o'
135 #define DSP_ACTION_QR64 0x001
136 #define DSP_ACTION_UMUL 0x002
137 #define DSP_ACTION_ROUND 0x004
138 #define DSP_ACTION_CLAMP9 0x008
139 #define DSP_ACTION_CLAMP8 0x010
140 #define DSP_ACTION_MOD 0x020
141 #define DSP_ACTION_ACC_ZERO 0x040
142 #define DSP_ACTION_ACC_ADD 0x080
143 #define DSP_ACTION_ACC_SUB 0x100
144 #define DSP_ACTION_OV 0x200
146 #define DSP_DAOPPAME_8_CHAR 'b'
147 #define DSP_DAOPPAME_16_CHAR 'w'
148 #define DSP_DAOPPAME_TEMP_CHAR 't'
149 #define DSP_DAOPPAME_HIGH_CHAR 'h'
151 #define DSP_DAOPPAME_8 0x1
152 #define DSP_DAOPPAME_16 0x2
153 #define DSP_DAOPPAME_TEMP 0x4
154 #define DSP_DAOPPAME_HIGH 0x8
156 /* Structure holding information about a parsed instruction. */
158 /* Instruction type. */
160 /* Split condition code. */
161 enum scond_code scond
;
163 /* Instruction bits. */
165 /* Size of the instruction in bytes. */
168 /* FPU instruction encoding. */
169 enum fpu_insn_width fpu_width
;
170 unsigned int fpu_action_flags
;
172 /* DSP instruction encoding. */
173 enum dsp_insn_width dsp_width
;
174 unsigned int dsp_action_flags
;
175 unsigned int dsp_daoppame_flags
;
177 /* Reloc encoding information, maximum of one reloc per insn. */
178 enum bfd_reloc_code_real reloc_type
;
180 expressionS reloc_exp
;
181 unsigned int reloc_size
;
184 /* Structure holding information about a parsed addressing mode. */
186 const metag_reg
*base_reg
;
187 const metag_reg
*offset_reg
;
191 enum bfd_reloc_code_real reloc_type
;
193 /* Whether we have an immediate or not. */
194 unsigned short immediate
:1;
195 /* Whether or not the base register is updated. */
196 unsigned short update
:1;
197 /* Whether the operation uses the address pre or post increment. */
198 unsigned short post_increment
:1;
199 /* Whether the immediate should be negated. */
200 unsigned short negate
:1;
203 /* Linked list of possible parsers for this instruction. */
204 typedef struct _insn_templates
{
205 const insn_template
*template;
206 struct _insn_templates
*next
;
209 /* Parse an instruction that takes no operands. */
211 parse_none (const char *line
, metag_insn
*insn
,
212 const insn_template
*template)
214 insn
->bits
= template->meta_opcode
;
219 /* Return the next non-whitespace character in LINE or NULL. */
221 skip_whitespace (const char *line
)
223 const char *l
= line
;
225 if (is_whitespace_char (*l
))
233 /* Return the next non-space character in LINE or NULL. */
235 skip_space (const char *line
)
237 const char *l
= line
;
239 if (is_space_char (*l
))
247 /* Return the character after the current one in LINE if the current
248 character is a comma, otherwise NULL. */
250 skip_comma (const char *line
)
252 const char *l
= line
;
254 if (l
== NULL
|| *l
!= COMMA
)
262 /* Return the metag_reg struct corresponding to NAME or NULL if no such
264 static const metag_reg
*
265 parse_gp_reg (const char *name
)
267 const metag_reg
*reg
;
272 reg
= (const metag_reg
*) htab_find (reg_htab
, &entry
);
277 /* Parse a list of up to COUNT GP registers from LINE, returning the
278 registers parsed in REGS and the number parsed in REGS_READ. Return
279 a pointer to the next character or NULL. */
281 parse_gp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
284 const char *l
= line
;
285 char reg_buf
[MAX_REG_LEN
];
289 for (i
= 0; i
< count
; i
++)
301 *regs_read
= seen_regs
;
306 while (is_register_char (*l
))
311 if (!(len
< MAX_REG_LEN
))
319 const metag_reg
*reg
= parse_gp_reg (reg_buf
);
323 *regs_read
= seen_regs
;
334 *regs_read
= seen_regs
;
339 *regs_read
= seen_regs
;
343 /* Parse a list of exactly COUNT GP registers from LINE, returning the
344 registers parsed in REGS. Return a pointer to the next character or NULL. */
346 parse_gp_regs (const char *line
, const metag_reg
**regs
, size_t count
)
348 const char *l
= line
;
349 size_t regs_read
= 0;
351 l
= parse_gp_regs_list (l
, regs
, count
, ®s_read
);
353 if (regs_read
!= count
)
359 /* Parse a list of exactly COUNT FPU registers from LINE, returning the
360 registers parsed in REGS. Return a pointer to the next character or NULL. */
362 parse_fpu_regs (const char *line
, const metag_reg
**regs
, size_t count
)
364 const char *l
= line
;
365 size_t regs_read
= 0;
367 l
= parse_gp_regs_list (l
, regs
, count
, ®s_read
);
369 if (regs_read
!= count
)
374 for (i
= 0; i
< count
; i
++)
376 if (regs
[i
]->unit
!= UNIT_FX
)
383 /* Return TRUE if REG1 and REG2 are in paired units. */
385 is_unit_pair (const metag_reg
*reg1
, const metag_reg
*reg2
)
387 if ((reg1
->unit
== UNIT_A0
&&
388 (reg2
->unit
== UNIT_A1
)) ||
389 (reg1
->unit
== UNIT_A1
&&
390 (reg2
->unit
== UNIT_A0
)) ||
391 (reg1
->unit
== UNIT_D0
&&
392 (reg2
->unit
== UNIT_D1
)) ||
393 (reg1
->unit
== UNIT_D1
&&
394 (reg2
->unit
== UNIT_D0
)))
400 /* Return TRUE if REG1 and REG2 form a register pair. */
402 is_reg_pair (const metag_reg
*reg1
, const metag_reg
*reg2
)
404 if (reg1
->unit
== UNIT_FX
&&
405 reg2
->unit
== UNIT_FX
&&
406 reg2
->no
== reg1
->no
+ 1)
409 if (reg1
->no
!= reg2
->no
)
412 return is_unit_pair (reg1
, reg2
);
415 /* Parse a pair of GP registers from LINE, returning the registers parsed
416 in REGS. Return a pointer to the next character or NULL. */
418 parse_pair_gp_regs (const char *line
, const metag_reg
**regs
)
420 const char *l
= line
;
422 l
= parse_gp_regs (line
, regs
, 2);
426 l
= parse_gp_regs (line
, regs
, 1);
431 if (regs
[0]->unit
== UNIT_RD
)
437 if (is_reg_pair (regs
[0], regs
[1]))
443 /* Parse a unit-to-unit MOV instruction. */
445 parse_mov_u2u (const char *line
, metag_insn
*insn
,
446 const insn_template
*template)
448 const metag_reg
*regs
[2];
450 line
= parse_gp_regs (line
, regs
, 2);
455 if (!mfpu_opt
&& (regs
[0]->unit
== UNIT_FX
|| regs
[1]->unit
== UNIT_FX
))
457 as_bad (_("no floating point unit specified"));
461 insn
->bits
= (template->meta_opcode
|
462 (regs
[1]->no
<< 19) |
463 (regs
[0]->no
<< 14) |
464 (regs
[1]->unit
<< 10) |
465 (regs
[0]->unit
<< 5));
470 /* Parse a MOV to port instruction. */
472 parse_mov_port (const char *line
, metag_insn
*insn
,
473 const insn_template
*template)
475 const char *l
= line
;
476 unsigned int is_movl
= MINOR_OPCODE (template->meta_opcode
) == MOVL_MINOR
;
477 const metag_reg
*dest_regs
[2];
478 const metag_reg
*port_regs
[1];
481 l
= parse_gp_regs (l
, dest_regs
, 2);
483 l
= parse_gp_regs (l
, dest_regs
, 1);
488 if (template->insn_type
== INSN_FPU
&& dest_regs
[0]->unit
!= UNIT_FX
)
497 l
= parse_gp_regs (l
, port_regs
, 1);
502 if (port_regs
[0]->unit
!= UNIT_RD
||
503 port_regs
[0]->no
!= 0)
508 if (!is_unit_pair (dest_regs
[0], dest_regs
[1]))
511 insn
->bits
= (template->meta_opcode
|
512 (dest_regs
[0]->no
<< 14) |
513 (dest_regs
[1]->no
<< 9) |
514 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 5));
517 insn
->bits
= (template->meta_opcode
|
518 (dest_regs
[0]->no
<< 14) |
519 (dest_regs
[0]->unit
<< 5));
525 /* Parse a MOVL to TTREC instruction. */
527 parse_movl_ttrec (const char *line
, metag_insn
*insn
,
528 const insn_template
*template)
530 const char *l
= line
;
531 const metag_reg
*src_regs
[2];
532 const metag_reg
*dest_regs
[1];
534 l
= parse_gp_regs (l
, dest_regs
, 1);
539 if (dest_regs
[0]->unit
!= UNIT_TT
||
540 dest_regs
[0]->no
!= 3)
549 l
= parse_gp_regs (l
, src_regs
, 2);
554 if (!is_unit_pair (src_regs
[0], src_regs
[1]))
557 insn
->bits
= (template->meta_opcode
|
558 (src_regs
[0]->no
<< 19) |
559 (src_regs
[1]->no
<< 14) |
560 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 7));
566 /* Parse an incrementing or decrementing addressing mode. */
568 parse_addr_incr_op (const char *line
, metag_addr
*addr
)
570 const char *l
= line
;
582 else if (*l
== MINUS
&&
593 /* Parse an pre-incrementing or pre-decrementing addressing mode. */
595 parse_addr_pre_incr_op (const char *line
, metag_addr
*addr
)
597 return parse_addr_incr_op (line
, addr
);
600 /* Parse an post-incrementing or post-decrementing addressing mode. */
602 parse_addr_post_incr_op (const char *line
, metag_addr
*addr
)
606 l
= parse_addr_incr_op (line
, addr
);
611 addr
->post_increment
= 1;
616 /* Parse an infix addressing mode. */
618 parse_addr_op (const char *line
, metag_addr
*addr
)
620 const char *l
= line
;
639 /* Parse the immediate portion of an addrssing mode. */
641 parse_imm_addr (const char *line
, metag_addr
*addr
)
643 const char *l
= line
;
644 char *save_input_line_pointer
;
645 expressionS
*exp
= &addr
->exp
;
653 save_input_line_pointer
= input_line_pointer
;
654 input_line_pointer
= (char *) l
;
658 l
= input_line_pointer
;
659 input_line_pointer
= save_input_line_pointer
;
661 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
665 else if (exp
->X_op
== O_constant
)
671 if (exp
->X_op
== O_PIC_reloc
&&
672 exp
->X_md
== BFD_RELOC_METAG_GETSET_GOT
)
674 exp
->X_op
= O_symbol
;
675 addr
->reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
677 else if (exp
->X_op
== O_PIC_reloc
&&
678 exp
->X_md
== BFD_RELOC_METAG_TLS_IE
)
680 exp
->X_op
= O_symbol
;
681 addr
->reloc_type
= BFD_RELOC_METAG_TLS_IE
;
683 else if (exp
->X_op
== O_PIC_reloc
&&
684 exp
->X_md
== BFD_RELOC_METAG_GOTOFF
)
686 exp
->X_op
= O_symbol
;
687 addr
->reloc_type
= BFD_RELOC_METAG_GETSET_GOTOFF
;
690 addr
->reloc_type
= BFD_RELOC_METAG_GETSETOFF
;
695 /* Parse the offset portion of an addressing mode (register or immediate). */
697 parse_addr_offset (const char *line
, metag_addr
*addr
, int size
)
699 const char *l
= line
;
700 const metag_reg
*regs
[1];
704 /* ++ is a valid operator in our addressing but not in an expr. Make
705 sure that the expression parser never sees it. */
706 char *ppp
= strstr(l
, "++");
712 l
= parse_imm_addr (l
, addr
);
720 if (addr
->exp
.X_add_number
% size
)
722 as_bad (_("offset must be a multiple of %d"), size
);
731 l
= parse_gp_regs (l
, regs
, 1);
736 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
738 as_bad (_("offset and base must be from the same unit"));
742 addr
->offset_reg
= regs
[0];
747 /* Parse an addressing mode. */
749 parse_addr (const char *line
, metag_addr
*addr
, unsigned int size
)
751 const char *l
= line
;
753 const metag_reg
*regs
[1];
755 /* Skip opening square bracket. */
758 ll
= parse_addr_pre_incr_op (l
, addr
);
763 l
= parse_gp_regs (l
, regs
, 1);
768 addr
->base_reg
= regs
[0];
770 if (*l
== ADDR_END_CHAR
)
772 addr
->exp
.X_op
= O_constant
;
773 addr
->exp
.X_add_symbol
= NULL
;
774 addr
->exp
.X_op_symbol
= NULL
;
775 if (addr
->update
== 1)
777 /* We have a pre increment/decrement. */
778 addr
->exp
.X_add_number
= size
;
782 /* Simple register with no offset (0 immediate). */
783 addr
->exp
.X_add_number
= 0;
790 /* We already had a pre increment/decrement. */
791 if (addr
->update
== 1)
794 ll
= parse_addr_post_incr_op (l
, addr
);
796 if (ll
&& *ll
== ADDR_END_CHAR
)
798 if (addr
->update
== 1)
800 /* We have a post increment/decrement. */
801 addr
->exp
.X_op
= O_constant
;
802 addr
->exp
.X_add_number
= size
;
803 addr
->exp
.X_add_symbol
= NULL
;
804 addr
->exp
.X_op_symbol
= NULL
;
805 addr
->post_increment
= 1;
812 addr
->post_increment
= 0;
814 l
= parse_addr_op (l
, addr
);
819 l
= parse_addr_offset (l
, addr
, size
);
824 if (*l
== ADDR_END_CHAR
)
830 /* We already had a pre increment/decrement. */
831 if (addr
->update
== 1)
834 l
= parse_addr_post_incr_op (l
, addr
);
839 if (*l
== ADDR_END_CHAR
)
848 /* Parse a GET or pipeline MOV instruction. */
850 parse_get (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
851 unsigned int size
, bfd_boolean is_mov
)
853 const char *l
= line
;
857 l
= parse_pair_gp_regs (l
, regs
);
864 l
= parse_gp_regs (l
, regs
, 1);
869 as_bad (_("invalid destination register"));
880 l
= parse_addr (l
, addr
, size
);
885 as_bad (_("invalid memory operand"));
892 /* Parse a SET instruction. */
894 parse_set (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
897 const char *l
= line
;
899 l
= parse_addr (l
, addr
, size
);
903 as_bad (_("invalid memory operand"));
917 ll
= parse_pair_gp_regs (l
, regs
);
921 /* Maybe this is an RD register, which is 64 bits wide so needs no
923 l
= parse_gp_regs (l
, regs
, 1);
926 regs
[0]->unit
!= UNIT_RD
)
936 l
= parse_gp_regs (l
, regs
, 1);
940 as_bad (_("invalid source register"));
948 /* Check a signed integer value can be represented in the given number
951 within_signed_range (int value
, unsigned int bits
)
953 int min_val
= -(1 << (bits
- 1));
954 int max_val
= (1 << (bits
- 1)) - 1;
955 return (value
<= max_val
) && (value
>= min_val
);
958 /* Check an unsigned integer value can be represented in the given number
961 within_unsigned_range (unsigned int value
, unsigned int bits
)
963 return value
< (unsigned int)(1 << bits
);
966 /* Return TRUE if UNIT can be expressed using a short code. */
968 is_short_unit (enum metag_unit unit
)
982 /* Copy reloc data from ADDR to INSN. */
984 copy_addr_reloc (metag_insn
*insn
, metag_addr
*addr
)
986 memcpy (&insn
->reloc_exp
, &addr
->exp
, sizeof(insn
->reloc_exp
));
987 insn
->reloc_type
= addr
->reloc_type
;
990 /* Parse a GET, SET or pipeline MOV instruction. */
992 parse_get_set (const char *line
, metag_insn
*insn
,
993 const insn_template
*template)
995 const char *l
= line
;
996 const metag_reg
*regs
[2];
998 unsigned int size
= metag_get_set_size_bytes (template->meta_opcode
);
999 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
1000 unsigned int reg_no
;
1002 memset(&addr
, 0, sizeof(addr
));
1003 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1007 bfd_boolean is_mov
= strncmp (template->name
, "MOV", 3) == 0;
1009 l
= parse_get (l
, regs
, &addr
, size
, is_mov
);
1014 if (!(regs
[0]->unit
== UNIT_D0
||
1015 regs
[0]->unit
== UNIT_D1
||
1016 regs
[0]->unit
== UNIT_A0
||
1017 regs
[0]->unit
== UNIT_A1
||
1018 (regs
[0]->unit
== UNIT_RD
&& is_mov
) ||
1019 (regs
[0]->unit
== UNIT_CT
&& size
== 4) ||
1020 (regs
[0]->unit
== UNIT_PC
&& size
== 4) ||
1021 (regs
[0]->unit
== UNIT_TR
&& size
== 4) ||
1022 (regs
[0]->unit
== UNIT_TT
&& (size
== 4 || size
== 8)) ||
1023 regs
[0]->unit
== UNIT_FX
))
1025 as_bad (_("invalid destination unit"));
1029 if (regs
[0]->unit
== UNIT_RD
)
1031 if (regs
[0]->no
== 0)
1033 as_bad (_("mov cannot use RD port as destination"));
1038 reg_no
= regs
[0]->no
;
1042 l
= parse_set (l
, regs
, &addr
, size
);
1047 if (!(regs
[0]->unit
== UNIT_D0
||
1048 regs
[0]->unit
== UNIT_D1
||
1049 regs
[0]->unit
== UNIT_A0
||
1050 regs
[0]->unit
== UNIT_A1
||
1051 regs
[0]->unit
== UNIT_RD
||
1052 (regs
[0]->unit
== UNIT_CT
&& size
== 4) ||
1053 (regs
[0]->unit
== UNIT_PC
&& size
== 4) ||
1054 (regs
[0]->unit
== UNIT_TR
&& size
== 4) ||
1055 (regs
[0]->unit
== UNIT_TT
&& (size
== 4 || size
== 8)) ||
1056 regs
[0]->unit
== UNIT_FX
))
1058 as_bad (_("invalid source unit"));
1062 if (addr
.immediate
== 0 &&
1063 (regs
[0]->unit
== addr
.base_reg
->unit
||
1064 (size
== 8 && is_unit_pair (regs
[0], addr
.base_reg
))))
1066 as_bad (_("source and address units must not be shared for this addressing mode"));
1070 if (regs
[0]->unit
== UNIT_RD
)
1072 if (regs
[0]->no
!= 0)
1074 as_bad (_("set can only use RD port as source"));
1080 reg_no
= regs
[0]->no
;
1083 insn
->bits
= (template->meta_opcode
|
1085 (regs
[0]->unit
<< 1));
1087 if (!is_short_unit (addr
.base_reg
->unit
))
1089 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1093 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1094 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1098 int offset
= addr
.exp
.X_add_number
;
1100 copy_addr_reloc (insn
, &addr
);
1105 offset
= offset
/ (int)size
;
1107 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
1109 /* We already tried to encode as an extended GET/SET. */
1110 as_bad (_("offset value out of range"));
1114 offset
= offset
& GET_SET_IMM_MASK
;
1116 insn
->bits
|= (0x1 << 25);
1117 insn
->bits
|= (offset
<< 8);
1121 insn
->bits
|= (addr
.offset_reg
->no
<< 9);
1125 insn
->bits
|= (0x1 << 7);
1127 if (addr
.post_increment
)
1134 /* Parse an extended GET or SET instruction. */
1136 parse_get_set_ext (const char *line
, metag_insn
*insn
,
1137 const insn_template
*template)
1139 const char *l
= line
;
1140 const metag_reg
*regs
[2];
1142 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
1143 bfd_boolean is_get
= MINOR_OPCODE (template->meta_opcode
) == GET_EXT_MINOR
;
1144 bfd_boolean is_mov
= MINOR_OPCODE (template->meta_opcode
) == MOV_EXT_MINOR
;
1145 unsigned int reg_unit
;
1147 memset(&addr
, 0, sizeof(addr
));
1148 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1150 if (is_get
|| is_mov
)
1152 l
= parse_get (l
, regs
, &addr
, size
, is_mov
);
1156 l
= parse_set (l
, regs
, &addr
, size
);
1162 /* Extended GET/SET does not support incrementing addressing. */
1168 if (regs
[0]->unit
!= UNIT_RD
)
1170 as_bad (_("destination unit must be RD"));
1177 if (!is_short_unit (regs
[0]->unit
))
1181 reg_unit
= regs
[0]->unit
;
1184 insn
->bits
= (template->meta_opcode
|
1185 (regs
[0]->no
<< 19) |
1186 ((reg_unit
& SHORT_UNIT_MASK
) << 3));
1188 if (!is_short_unit (addr
.base_reg
->unit
))
1190 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1194 if (addr
.base_reg
->no
> 1)
1199 insn
->bits
|= ((addr
.base_reg
->no
& EXT_BASE_REG_MASK
) |
1200 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1204 int offset
= addr
.exp
.X_add_number
;
1206 copy_addr_reloc (insn
, &addr
);
1211 offset
= offset
/ (int)size
;
1213 if (!within_signed_range (offset
, GET_SET_EXT_IMM_BITS
))
1215 /* Parsing as a standard GET/SET provides a smaller offset. */
1216 as_bad (_("offset value out of range"));
1220 offset
= offset
& GET_SET_EXT_IMM_MASK
;
1222 insn
->bits
|= (offset
<< 7);
1233 /* Parse an MGET or MSET instruction addressing mode. */
1235 parse_mget_mset_addr (const char *line
, metag_addr
*addr
)
1237 const char *l
= line
;
1239 const metag_reg
*regs
[1];
1241 /* Skip opening square bracket. */
1244 l
= parse_gp_regs (l
, regs
, 1);
1249 addr
->base_reg
= regs
[0];
1251 ll
= parse_addr_post_incr_op (l
, addr
);
1256 if (addr
->negate
== 1)
1259 if (*l
== ADDR_END_CHAR
)
1268 /* Parse an MGET instruction. */
1270 parse_mget (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
1273 const char *l
= line
;
1275 l
= parse_gp_regs_list (l
, regs
, MGET_MSET_MAX_REGS
, regs_read
);
1280 as_bad (_("invalid destination register list"));
1290 l
= parse_mget_mset_addr (l
, addr
);
1294 as_bad (_("invalid memory operand"));
1301 /* Parse an MSET instruction. */
1303 parse_mset (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
1306 const char *l
= line
;
1308 l
= parse_mget_mset_addr (l
, addr
);
1312 as_bad (_("invalid memory operand"));
1322 l
= parse_gp_regs_list (l
, regs
, MGET_MSET_MAX_REGS
, regs_read
);
1327 as_bad (_("invalid source register list"));
1334 /* Take a register list REGS of size REGS_READ and convert it into an
1335 rmask value if possible. Return the rmask value in RMASK and the
1336 lowest numbered register in LOWEST_REG. Return TRUE if the conversion
1339 check_rmask (const metag_reg
**regs
, size_t regs_read
, bfd_boolean is_fpu
,
1340 bfd_boolean is_64bit
, unsigned int *lowest_reg
,
1341 unsigned int *rmask
)
1343 unsigned int reg_unit
= regs
[0]->unit
;
1346 for (i
= 0; i
< regs_read
; i
++)
1350 if (is_64bit
&& regs
[i
]->no
% 2)
1352 as_bad (_("register list must be even numbered"));
1356 else if (regs
[i
]->unit
!= reg_unit
)
1358 as_bad (_("register list must be from the same unit"));
1362 if (regs
[i
]->no
< *lowest_reg
)
1363 *lowest_reg
= regs
[i
]->no
;
1366 for (i
= 0; i
< regs_read
; i
++)
1368 unsigned int next_bit
, next_reg
;
1369 if (regs
[i
]->no
== *lowest_reg
)
1372 if (is_fpu
&& is_64bit
)
1373 next_reg
= ((regs
[i
]->no
/ 2) - ((*lowest_reg
/ 2) + 1));
1375 next_reg
= (regs
[i
]->no
- (*lowest_reg
+ 1));
1377 next_bit
= (1 << next_reg
);
1379 if (*rmask
& next_bit
)
1381 as_bad (_("register list must not contain duplicates"));
1391 /* Parse an MGET or MSET instruction. */
1393 parse_mget_mset (const char *line
, metag_insn
*insn
,
1394 const insn_template
*template)
1396 const char *l
= line
;
1397 const metag_reg
*regs
[MGET_MSET_MAX_REGS
];
1399 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
1400 bfd_boolean is_fpu
= (MINOR_OPCODE (template->meta_opcode
) & 0x6) == 0x6;
1401 bfd_boolean is_64bit
= (MINOR_OPCODE (template->meta_opcode
) & 0x1) == 0x1;
1402 size_t regs_read
= 0;
1403 unsigned int rmask
= 0, reg_unit
= 0, lowest_reg
= 0xffffffff;
1405 memset(&addr
, 0, sizeof(addr
));
1406 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1410 l
= parse_mget (l
, regs
, &addr
, ®s_read
);
1414 l
= parse_mset (l
, regs
, &addr
, ®s_read
);
1420 if (!check_rmask (regs
, regs_read
, is_fpu
, is_64bit
, &lowest_reg
, &rmask
))
1423 reg_unit
= regs
[0]->unit
;
1427 if (reg_unit
!= UNIT_FX
)
1432 else if (reg_unit
== UNIT_FX
)
1435 insn
->bits
= (template->meta_opcode
|
1436 (lowest_reg
<< 19) |
1437 ((reg_unit
& SHORT_UNIT_MASK
) << 3));
1439 if (!is_short_unit (addr
.base_reg
->unit
))
1441 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1445 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1446 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1448 insn
->bits
|= (rmask
& RMASK_MASK
) << 7;
1454 /* Parse a list of registers for MMOV pipeline prime. */
1456 parse_mmov_prime_list (const char *line
, const metag_reg
**regs
,
1457 unsigned int *rmask
)
1459 const char *l
= line
;
1460 const metag_reg
*ra_regs
[MMOV_MAX_REGS
];
1461 size_t regs_read
= 0, i
;
1462 unsigned int mask
= 0;
1464 l
= parse_gp_regs_list (l
, regs
, 1, ®s_read
);
1466 /* First register must be a port. */
1467 if (l
== NULL
|| regs
[0]->unit
!= UNIT_RD
)
1475 l
= parse_gp_regs_list (l
, ra_regs
, MMOV_MAX_REGS
, ®s_read
);
1480 /* Check remaining registers match the first.
1482 Note that we also accept RA (0x10) as input for the remaining registers.
1483 Whilst this doesn't represent the instruction in any way we're stuck
1484 with it because the embedded assembler accepts it. */
1485 for (i
= 0; i
< regs_read
; i
++)
1487 if (ra_regs
[i
]->unit
!= UNIT_RD
||
1488 (ra_regs
[i
]->no
!= 0x10 && ra_regs
[i
]->no
!= regs
[0]->no
))
1491 mask
= (mask
<< 1) | 0x1;
1499 /* Parse a MMOV instruction. */
1501 parse_mmov (const char *line
, metag_insn
*insn
,
1502 const insn_template
*template)
1504 const char *l
= line
;
1505 unsigned int is_fpu
= template->insn_type
== INSN_FPU
;
1506 unsigned int is_prime
= ((MINOR_OPCODE (template->meta_opcode
) & 0x2) &&
1508 unsigned int is_64bit
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
1509 unsigned int rmask
= 0;
1513 const metag_reg
*reg
;
1516 memset (&addr
, 0, sizeof(addr
));
1518 l
= parse_mmov_prime_list (l
, ®
, &rmask
);
1528 l
= parse_mget_mset_addr (l
, &addr
);
1532 as_bad (_("invalid memory operand"));
1536 insn
->bits
= (template->meta_opcode
|
1538 (addr
.base_reg
->no
<< 14) |
1539 ((rmask
& RMASK_MASK
) << 7) |
1540 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1544 const metag_reg
*regs
[MMOV_MAX_REGS
+ 1];
1545 unsigned int lowest_reg
= 0xffffffff;
1546 size_t regs_read
= 0;
1548 l
= parse_gp_regs_list (l
, regs
, MMOV_MAX_REGS
+ 1, ®s_read
);
1550 if (l
== NULL
|| regs_read
== 0)
1553 if (!is_short_unit (regs
[0]->unit
) &&
1554 !(is_fpu
&& regs
[0]->unit
== UNIT_FX
))
1559 if (!(regs
[regs_read
-1]->unit
== UNIT_RD
&&
1560 regs
[regs_read
-1]->no
== 0))
1565 if (!check_rmask (regs
, regs_read
- 1, is_fpu
, is_64bit
, &lowest_reg
,
1571 insn
->bits
= (template->meta_opcode
|
1572 (regs
[0]->no
<< 14) |
1573 ((rmask
& RMASK_MASK
) << 7));
1577 insn
->bits
= (template->meta_opcode
|
1578 (regs
[0]->no
<< 19) |
1579 ((rmask
& RMASK_MASK
) << 7) |
1580 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
1588 /* Parse an immediate constant. */
1590 parse_imm_constant (const char *line
, metag_insn
*insn
, int *value
)
1592 const char *l
= line
;
1593 char *save_input_line_pointer
;
1594 expressionS
*exp
= &insn
->reloc_exp
;
1602 save_input_line_pointer
= input_line_pointer
;
1603 input_line_pointer
= (char *) l
;
1607 l
= input_line_pointer
;
1608 input_line_pointer
= save_input_line_pointer
;
1610 if (exp
->X_op
== O_constant
)
1612 *value
= exp
->X_add_number
;
1622 /* Parse an MDRD instruction. */
1624 parse_mdrd (const char *line
, metag_insn
*insn
,
1625 const insn_template
*template)
1627 const char *l
= line
;
1628 unsigned int rmask
= 0;
1631 l
= parse_imm_constant (l
, insn
, &value
);
1636 if (value
< 1 || value
> 8)
1638 as_bad (_("MDRD value must be between 1 and 8"));
1642 for (i
= 1; i
< value
; i
++)
1648 insn
->bits
= (template->meta_opcode
|
1655 /* Parse a conditional SET instruction. */
1657 parse_cond_set (const char *line
, metag_insn
*insn
,
1658 const insn_template
*template)
1660 const char *l
= line
;
1661 const metag_reg
*regs
[2];
1663 unsigned int size
= metag_cond_set_size_bytes (template->meta_opcode
);
1664 unsigned int reg_no
;
1666 memset(&addr
, 0, sizeof(addr
));
1667 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1669 l
= parse_set (l
, regs
, &addr
, size
);
1674 if (regs
[0]->unit
== UNIT_RD
)
1676 if (regs
[0]->no
!= 0)
1678 as_bad (_("set can only use RD port as source"));
1684 reg_no
= regs
[0]->no
;
1689 if (!(addr
.immediate
&&
1690 addr
.exp
.X_add_number
== 0))
1693 insn
->bits
= (template->meta_opcode
|
1695 (regs
[0]->unit
<< 10));
1697 if (!is_short_unit (addr
.base_reg
->unit
))
1699 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1703 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1704 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1710 /* Parse an XFR instruction. */
1712 parse_xfr (const char *line
, metag_insn
*insn
,
1713 const insn_template
*template)
1715 const char *l
= line
;
1716 metag_addr dest_addr
, src_addr
;
1717 unsigned int size
= 4;
1719 memset(&dest_addr
, 0, sizeof(dest_addr
));
1720 memset(&src_addr
, 0, sizeof(src_addr
));
1721 dest_addr
.reloc_type
= BFD_RELOC_UNUSED
;
1722 src_addr
.reloc_type
= BFD_RELOC_UNUSED
;
1724 l
= parse_addr (l
, &dest_addr
, size
);
1727 dest_addr
.immediate
== 1)
1729 as_bad (_("invalid destination memory operand"));
1739 l
= parse_addr (l
, &src_addr
, size
);
1742 src_addr
.immediate
== 1)
1744 as_bad (_("invalid source memory operand"));
1748 if (!is_short_unit (dest_addr
.base_reg
->unit
) ||
1749 !is_short_unit (src_addr
.base_reg
->unit
))
1751 as_bad (_("address units must be one of %s"), SHORT_UNITS
);
1755 if ((dest_addr
.base_reg
->unit
!= dest_addr
.offset_reg
->unit
) ||
1756 (src_addr
.base_reg
->unit
!= src_addr
.offset_reg
->unit
))
1758 as_bad (_("base and offset must be from the same unit"));
1762 if (dest_addr
.update
== 1 &&
1763 src_addr
.update
== 1 &&
1764 dest_addr
.post_increment
!= src_addr
.post_increment
)
1766 as_bad (_("source and destination increment mode must agree"));
1770 insn
->bits
= (template->meta_opcode
|
1771 (src_addr
.base_reg
->no
<< 19) |
1772 (src_addr
.offset_reg
->no
<< 14) |
1773 ((src_addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 2));
1775 insn
->bits
|= ((dest_addr
.base_reg
->no
<< 9) |
1776 (dest_addr
.offset_reg
->no
<< 4) |
1777 ((dest_addr
.base_reg
->unit
& SHORT_UNIT_MASK
)));
1779 if (dest_addr
.update
== 1)
1780 insn
->bits
|= (1 << 26);
1782 if (src_addr
.update
== 1)
1783 insn
->bits
|= (1 << 27);
1785 if (dest_addr
.post_increment
== 1 ||
1786 src_addr
.post_increment
== 1)
1787 insn
->bits
|= (1 << 24);
1793 /* Parse an 8bit immediate value. */
1795 parse_imm8 (const char *line
, metag_insn
*insn
, int *value
)
1797 const char *l
= line
;
1798 char *save_input_line_pointer
;
1799 expressionS
*exp
= &insn
->reloc_exp
;
1807 save_input_line_pointer
= input_line_pointer
;
1808 input_line_pointer
= (char *) l
;
1812 l
= input_line_pointer
;
1813 input_line_pointer
= save_input_line_pointer
;
1815 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1819 else if (exp
->X_op
== O_constant
)
1821 *value
= exp
->X_add_number
;
1825 insn
->reloc_type
= BFD_RELOC_METAG_REL8
;
1826 insn
->reloc_pcrel
= 0;
1832 /* Parse a 16bit immediate value. */
1834 parse_imm16 (const char *line
, metag_insn
*insn
, int *value
)
1836 const char *l
= line
;
1837 char *save_input_line_pointer
;
1838 expressionS
*exp
= &insn
->reloc_exp
;
1839 bfd_boolean is_hi
= FALSE
;
1840 bfd_boolean is_lo
= FALSE
;
1848 if (strncasecmp (l
, "HI", 2) == 0)
1853 else if (strncasecmp (l
, "LO", 2) == 0)
1859 save_input_line_pointer
= input_line_pointer
;
1860 input_line_pointer
= (char *) l
;
1864 l
= input_line_pointer
;
1865 input_line_pointer
= save_input_line_pointer
;
1867 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1871 else if (exp
->X_op
== O_constant
)
1874 *value
= (exp
->X_add_number
>> 16) & IMM16_MASK
;
1876 *value
= exp
->X_add_number
& IMM16_MASK
;
1878 *value
= exp
->X_add_number
;
1882 if (exp
->X_op
== O_PIC_reloc
)
1884 exp
->X_op
= O_symbol
;
1886 if (exp
->X_md
== BFD_RELOC_METAG_GOTOFF
)
1889 insn
->reloc_type
= BFD_RELOC_METAG_HI16_GOTOFF
;
1891 insn
->reloc_type
= BFD_RELOC_METAG_LO16_GOTOFF
;
1895 else if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
1898 insn
->reloc_type
= BFD_RELOC_METAG_HI16_PLT
;
1900 insn
->reloc_type
= BFD_RELOC_METAG_LO16_PLT
;
1904 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_LDO
)
1907 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LDO_HI16
;
1909 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LDO_LO16
;
1913 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_IENONPIC
)
1916 insn
->reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC_HI16
;
1918 insn
->reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC_LO16
;
1922 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_LE
)
1925 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LE_HI16
;
1927 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LE_LO16
;
1931 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_GD
||
1932 exp
->X_md
== BFD_RELOC_METAG_TLS_LDM
)
1933 insn
->reloc_type
= exp
->X_md
;
1937 if (exp
->X_op
== O_symbol
&& exp
->X_add_symbol
== GOT_symbol
)
1940 insn
->reloc_type
= BFD_RELOC_METAG_HI16_GOTPC
;
1942 insn
->reloc_type
= BFD_RELOC_METAG_LO16_GOTPC
;
1949 insn
->reloc_type
= BFD_RELOC_METAG_HIADDR16
;
1951 insn
->reloc_type
= BFD_RELOC_METAG_LOADDR16
;
1953 insn
->reloc_type
= BFD_RELOC_METAG_REL16
;
1957 insn
->reloc_pcrel
= 0;
1963 /* Parse a MOV to control unit instruction. */
1965 parse_mov_ct (const char *line
, metag_insn
*insn
,
1966 const insn_template
*template)
1968 const char *l
= line
;
1969 const metag_reg
*regs
[1];
1970 unsigned int top
= template->meta_opcode
& 0x1;
1971 unsigned int is_trace
= (template->meta_opcode
>> 2) & 0x1;
1972 unsigned int sign_extend
= 0;
1975 l
= parse_gp_regs (l
, regs
, 1);
1982 if (regs
[0]->unit
!= UNIT_TT
)
1987 if (regs
[0]->unit
!= UNIT_CT
)
1997 l
= parse_imm16 (l
, insn
, &value
);
2005 insn
->bits
= (template->meta_opcode
|
2006 (regs
[0]->no
<< 19) |
2007 ((value
& IMM16_MASK
) << 3));
2009 if (sign_extend
== 1 && top
== 0)
2010 insn
->bits
|= (1 << 1);
2016 /* Parse a SWAP instruction. */
2018 parse_swap (const char *line
, metag_insn
*insn
,
2019 const insn_template
*template)
2021 const char *l
= line
;
2022 const metag_reg
*regs
[2];
2024 l
= parse_gp_regs (l
, regs
, 2);
2029 insn
->bits
= (template->meta_opcode
|
2030 (regs
[1]->no
<< 19) |
2031 (regs
[0]->no
<< 14) |
2032 (regs
[1]->unit
<< 10) |
2033 (regs
[0]->unit
<< 5));
2039 /* Parse a JUMP instruction. */
2041 parse_jump (const char *line
, metag_insn
*insn
,
2042 const insn_template
*template)
2044 const char *l
= line
;
2045 const metag_reg
*regs
[1];
2048 l
= parse_gp_regs (l
, regs
, 1);
2053 if (!is_short_unit (regs
[0]->unit
))
2055 as_bad (_("register unit must be one of %s"), SHORT_UNITS
);
2065 l
= parse_imm16 (l
, insn
, &value
);
2070 insn
->bits
= (template->meta_opcode
|
2071 (regs
[0]->no
<< 19) |
2072 (regs
[0]->unit
& SHORT_UNIT_MASK
) |
2073 ((value
& IMM16_MASK
) << 3));
2079 /* Parse a 19bit immediate value. */
2081 parse_imm19 (const char *line
, metag_insn
*insn
, int *value
)
2083 const char *l
= line
;
2084 char *save_input_line_pointer
;
2085 expressionS
*exp
= &insn
->reloc_exp
;
2091 save_input_line_pointer
= input_line_pointer
;
2092 input_line_pointer
= (char *) l
;
2096 l
= input_line_pointer
;
2097 input_line_pointer
= save_input_line_pointer
;
2099 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
2103 else if (exp
->X_op
== O_constant
)
2105 *value
= exp
->X_add_number
;
2109 if (exp
->X_op
== O_PIC_reloc
)
2111 exp
->X_op
= O_symbol
;
2113 if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
2114 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH_PLT
;
2119 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH
;
2120 insn
->reloc_pcrel
= 1;
2126 /* Parse a CALLR instruction. */
2128 parse_callr (const char *line
, metag_insn
*insn
,
2129 const insn_template
*template)
2131 const char *l
= line
;
2132 const metag_reg
*regs
[1];
2135 l
= parse_gp_regs (l
, regs
, 1);
2140 if (!is_short_unit (regs
[0]->unit
))
2142 as_bad (_("link register unit must be one of %s"), SHORT_UNITS
);
2146 if (regs
[0]->no
& ~CALLR_REG_MASK
)
2148 as_bad (_("link register must be in a low numbered register"));
2158 l
= parse_imm19 (l
, insn
, &value
);
2163 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2165 as_bad (_("target out of range"));
2169 insn
->bits
= (template->meta_opcode
|
2170 (regs
[0]->no
& CALLR_REG_MASK
) |
2171 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3) |
2172 ((value
& IMM19_MASK
) << 5));
2178 /* Return the value for the register field if we apply the O2R modifier
2179 to operand 2 REG, combined with UNIT_BIT derived from the destination
2180 register or source1. Uses address unit O2R if IS_ADDR is set. */
2182 lookup_o2r (unsigned int is_addr
, unsigned int unit_bit
, const metag_reg
*reg
)
2184 if (reg
->no
& ~O2R_REG_MASK
)
2196 return (1 << 3) | reg
->no
;
2198 return (2 << 3) | reg
->no
;
2200 return (3 << 3) | reg
->no
;
2212 return (1 << 3) | reg
->no
;
2214 return (2 << 3) | reg
->no
;
2216 return (3 << 3) | reg
->no
;
2231 return (1 << 3) | reg
->no
;
2233 return (2 << 3) | reg
->no
;
2235 return (3 << 3) | reg
->no
;
2247 return (1 << 3) | reg
->no
;
2249 return (2 << 3) | reg
->no
;
2251 return (3 << 3) | reg
->no
;
2259 /* Parse GP ALU instruction. */
2261 parse_alu (const char *line
, metag_insn
*insn
,
2262 const insn_template
*template)
2264 const char *l
= line
;
2265 const metag_reg
*dest_regs
[1];
2266 const metag_reg
*src_regs
[2];
2268 unsigned int o1z
= 0;
2269 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2270 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2271 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2272 unsigned int top
= template->meta_opcode
& 0x1;
2273 unsigned int sign_extend
= 0;
2274 unsigned int is_addr_op
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
;
2275 unsigned int is_mul
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MUL
;
2276 unsigned int unit_bit
= 0;
2277 bfd_boolean is_quickrot
= template->arg_type
& GP_ARGS_QR
;
2279 l
= parse_gp_regs (l
, dest_regs
, 1);
2292 if (dest_regs
[0]->unit
== UNIT_A0
)
2294 else if (dest_regs
[0]->unit
== UNIT_A1
)
2299 if (dest_regs
[0]->unit
== UNIT_D0
)
2301 else if (dest_regs
[0]->unit
== UNIT_D1
)
2305 if ((MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
||
2306 MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
2307 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) &&
2308 ((template->meta_opcode
>> 2) & 0x1))
2317 if (dest_regs
[0]->unit
== UNIT_A0
)
2319 else if (dest_regs
[0]->unit
== UNIT_A1
)
2326 if (dest_regs
[0]->unit
== UNIT_D0
)
2328 else if (dest_regs
[0]->unit
== UNIT_D1
)
2337 l
= parse_gp_regs (l
, src_regs
, 1);
2350 if (src_regs
[0]->unit
== UNIT_A0
)
2352 else if (src_regs
[0]->unit
== UNIT_A1
)
2359 if (src_regs
[0]->unit
== UNIT_D0
)
2361 else if (src_regs
[0]->unit
== UNIT_D1
)
2367 if (src_regs
[0]->unit
!= dest_regs
[0]->unit
&& !ca
)
2370 l
= parse_imm8 (l
, insn
, &value
);
2375 if (!within_unsigned_range (value
, IMM8_BITS
))
2378 insn
->bits
= (template->meta_opcode
|
2379 (dest_regs
[0]->no
<< 19) |
2380 (src_regs
[0]->no
<< 14) |
2381 ((value
& IMM8_MASK
) << 6));
2387 if (src_regs
[0]->unit
== UNIT_A0
)
2389 else if (src_regs
[0]->unit
== UNIT_A1
)
2396 if (src_regs
[0]->unit
== UNIT_D0
)
2398 else if (src_regs
[0]->unit
== UNIT_D1
)
2404 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2409 l
= parse_imm16 (l
, insn
, &value
);
2416 if (!within_signed_range (value
, IMM16_BITS
))
2418 as_bad (_("immediate out of range"));
2425 if (!within_unsigned_range (value
, IMM16_BITS
))
2427 as_bad (_("immediate out of range"));
2432 insn
->bits
= (template->meta_opcode
|
2433 (dest_regs
[0]->no
<< 19) |
2434 ((value
& IMM16_MASK
) << 3));
2438 l
= parse_gp_regs (l
, src_regs
, 1);
2443 if (!(src_regs
[0]->unit
== dest_regs
[0]->unit
))
2446 /* CPC is valid for address ops. */
2447 if (src_regs
[0]->no
!= dest_regs
[0]->no
&&
2448 !(is_addr_op
&& src_regs
[0]->no
== 0x10))
2457 l
= parse_imm16 (l
, insn
, &value
);
2464 if (!within_signed_range (value
, IMM16_BITS
))
2466 as_bad (_("immediate out of range"));
2473 if (!within_unsigned_range (value
, IMM16_BITS
))
2475 as_bad (_("immediate out of range"));
2480 insn
->bits
= (template->meta_opcode
|
2481 (dest_regs
[0]->no
<< 19) |
2482 (src_regs
[0]->no
<< 19) |
2483 ((value
& IMM16_MASK
) << 3));
2488 unsigned int o2r
= 0;
2492 l
= parse_gp_regs (l
, src_regs
, 2);
2494 l
= parse_gp_regs (l
, src_regs
, 1);
2503 if (src_regs
[0]->unit
== UNIT_A0
)
2505 else if (src_regs
[0]->unit
== UNIT_A1
)
2512 if (src_regs
[0]->unit
== UNIT_D0
)
2514 else if (src_regs
[0]->unit
== UNIT_D1
)
2524 if (dest_regs
[0]->unit
== UNIT_A0
)
2526 else if (dest_regs
[0]->unit
== UNIT_A1
)
2533 if (dest_regs
[0]->unit
== UNIT_D0
)
2535 else if (dest_regs
[0]->unit
== UNIT_D1
)
2544 if (src_regs
[0]->unit
!= src_regs
[1]->unit
)
2546 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2555 rs2
= src_regs
[1]->no
;
2558 insn
->bits
= (template->meta_opcode
|
2559 (dest_regs
[0]->no
<< 19) |
2560 (src_regs
[0]->no
<< 14) |
2565 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
&& is_mul
)
2569 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2576 insn
->bits
|= dest_regs
[0]->unit
<< 5;
2580 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2582 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[0]);
2591 rs2
= src_regs
[0]->no
;
2594 insn
->bits
= (template->meta_opcode
|
2595 (dest_regs
[0]->no
<< 19) |
2600 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2603 if (dest_regs
[0]->unit
!= src_regs
[1]->unit
)
2605 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2614 rs2
= src_regs
[1]->no
;
2617 insn
->bits
= (template->meta_opcode
|
2618 (dest_regs
[0]->no
<< 19) |
2619 (src_regs
[0]->no
<< 14) |
2629 const metag_reg
*qr_regs
[1];
2630 bfd_boolean limit_regs
= imm
&& cond
;
2638 l
= parse_gp_regs (l
, qr_regs
, 1);
2643 if (!((unit_bit
== 0 && qr_regs
[0]->unit
!= UNIT_A0
) ||
2644 !(unit_bit
== 1 && qr_regs
[0]->unit
!= UNIT_A1
)))
2646 as_bad (_("invalid quickrot unit specified"));
2650 switch (qr_regs
[0]->no
)
2657 insn
->bits
|= (1 << 7);
2661 as_bad (_("invalid quickrot register specified"));
2666 if (sign_extend
== 1 && top
== 0)
2667 insn
->bits
|= (1 << 1);
2669 insn
->bits
|= unit_bit
<< 24;
2674 /* Parse a B instruction. */
2676 parse_branch (const char *line
, metag_insn
*insn
,
2677 const insn_template
*template)
2679 const char *l
= line
;
2682 l
= parse_imm19 (l
, insn
, &value
);
2687 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2689 as_bad (_("target out of range"));
2693 insn
->bits
= (template->meta_opcode
|
2694 ((value
& IMM19_MASK
) << 5));
2700 /* Parse a KICK instruction. */
2702 parse_kick (const char *line
, metag_insn
*insn
,
2703 const insn_template
*template)
2705 const char *l
= line
;
2706 const metag_reg
*regs
[2];
2708 l
= parse_gp_regs (l
, regs
, 2);
2713 if (regs
[1]->unit
!= UNIT_TR
)
2715 as_bad (_("source register must be in the trigger unit"));
2719 insn
->bits
= (template->meta_opcode
|
2720 (regs
[1]->no
<< 19) |
2721 (regs
[0]->no
<< 14) |
2722 (regs
[0]->unit
<< 5));
2728 /* Parse a SWITCH instruction. */
2730 parse_switch (const char *line
, metag_insn
*insn
,
2731 const insn_template
*template)
2733 const char *l
= line
;
2736 l
= parse_imm_constant (l
, insn
, &value
);
2741 if (!within_unsigned_range (value
, IMM24_BITS
))
2743 as_bad (_("target out of range"));
2747 insn
->bits
= (template->meta_opcode
|
2748 (value
& IMM24_MASK
));
2754 /* Parse a shift instruction. */
2756 parse_shift (const char *line
, metag_insn
*insn
,
2757 const insn_template
*template)
2759 const char *l
= line
;
2760 const metag_reg
*regs
[2];
2761 const metag_reg
*src2_regs
[1];
2763 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2764 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2765 unsigned int unit_bit
= 0;
2767 l
= parse_gp_regs (l
, regs
, 2);
2778 if (regs
[1]->unit
== UNIT_D0
)
2780 else if (regs
[1]->unit
== UNIT_D1
)
2785 if (regs
[0]->unit
!= regs
[1]->unit
&& !(cond
&& ca
))
2790 l
= parse_imm_constant (l
, insn
, &value
);
2795 if (!within_unsigned_range (value
, IMM5_BITS
))
2798 insn
->bits
= (template->meta_opcode
|
2800 (regs
[0]->no
<< 19) |
2801 (regs
[1]->no
<< 14) |
2802 ((value
& IMM5_MASK
) << 9));
2806 l
= parse_gp_regs (l
, src2_regs
, 1);
2811 insn
->bits
= (template->meta_opcode
|
2812 (regs
[0]->no
<< 19) |
2813 (regs
[1]->no
<< 14) |
2814 (src2_regs
[0]->no
<< 9));
2816 if (src2_regs
[0]->unit
!= regs
[1]->unit
)
2818 as_bad(_("Source registers must be in the same unit"));
2823 if (regs
[0]->unit
!= regs
[1]->unit
)
2827 if (regs
[1]->unit
== UNIT_D0
)
2829 else if (regs
[1]->unit
== UNIT_D1
)
2834 insn
->bits
|= ((1 << 5) |
2835 (regs
[0]->unit
<< 1));
2841 insn
->bits
|= unit_bit
<< 24;
2846 /* Parse a MIN or MAX instruction. */
2848 parse_min_max (const char *line
, metag_insn
*insn
,
2849 const insn_template
*template)
2851 const char *l
= line
;
2852 const metag_reg
*regs
[3];
2854 l
= parse_gp_regs (l
, regs
, 3);
2859 if (!(regs
[0]->unit
== UNIT_D0
||
2860 regs
[0]->unit
== UNIT_D1
))
2863 if (!(regs
[0]->unit
== regs
[1]->unit
&&
2864 regs
[1]->unit
== regs
[2]->unit
))
2867 insn
->bits
= (template->meta_opcode
|
2868 (regs
[0]->no
<< 19) |
2869 (regs
[1]->no
<< 14) |
2870 (regs
[2]->no
<< 9));
2872 if (regs
[0]->unit
== UNIT_D1
)
2873 insn
->bits
|= (1 << 24);
2879 /* Parse a bit operation instruction. */
2881 parse_bitop (const char *line
, metag_insn
*insn
,
2882 const insn_template
*template)
2884 const char *l
= line
;
2885 const metag_reg
*regs
[2];
2886 unsigned int swap_inst
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
;
2887 unsigned int is_bexl
= 0;
2890 ((template->meta_opcode
>> 1) & 0xb) == 0xa)
2893 l
= parse_gp_regs (l
, regs
, 2);
2898 if (!(regs
[0]->unit
== UNIT_D0
||
2899 regs
[0]->unit
== UNIT_D1
))
2904 if (regs
[0]->unit
== UNIT_D0
&&
2905 regs
[1]->unit
!= UNIT_D1
)
2907 else if (regs
[0]->unit
== UNIT_D1
&&
2908 regs
[1]->unit
!= UNIT_D0
)
2911 else if (!(regs
[0]->unit
== regs
[1]->unit
))
2914 insn
->bits
= (template->meta_opcode
|
2915 (regs
[0]->no
<< 19) |
2916 (regs
[1]->no
<< 14));
2920 if (regs
[1]->unit
== UNIT_D1
)
2925 if (regs
[1]->unit
== UNIT_D1
)
2926 insn
->bits
|= (1 << 24);
2933 /* Parse a CMP or TST instruction. */
2935 parse_cmp (const char *line
, metag_insn
*insn
,
2936 const insn_template
*template)
2938 const char *l
= line
;
2939 const metag_reg
*dest_regs
[1];
2940 const metag_reg
*src_regs
[1];
2942 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2943 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2944 unsigned int top
= template->meta_opcode
& 0x1;
2945 unsigned int sign_extend
= 0;
2946 unsigned int unit_bit
= 0;
2948 l
= parse_gp_regs (l
, dest_regs
, 1);
2959 if (dest_regs
[0]->unit
== UNIT_D0
)
2961 else if (dest_regs
[0]->unit
== UNIT_D1
)
2970 l
= parse_imm_constant (l
, insn
, &value
);
2975 if (!within_unsigned_range (value
, IMM8_BITS
))
2978 insn
->bits
= (template->meta_opcode
|
2979 (dest_regs
[0]->no
<< 14) |
2980 ((value
& IMM8_MASK
) << 6));
2985 l
= parse_imm16 (l
, insn
, &value
);
2992 if (!within_signed_range (value
, IMM16_BITS
))
2994 as_bad (_("immediate out of range"));
3001 if (!within_unsigned_range (value
, IMM16_BITS
))
3003 as_bad (_("immediate out of range"));
3008 insn
->bits
= (template->meta_opcode
|
3009 (dest_regs
[0]->no
<< 19) |
3010 ((value
& IMM16_MASK
) << 3));
3015 unsigned int o2r
= 0;
3018 l
= parse_gp_regs (l
, src_regs
, 1);
3023 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
3025 rs2
= lookup_o2r (0, unit_bit
, src_regs
[0]);
3034 rs2
= src_regs
[0]->no
;
3037 insn
->bits
= (template->meta_opcode
|
3038 (dest_regs
[0]->no
<< 14) |
3045 if (sign_extend
== 1 && top
== 0)
3046 insn
->bits
|= (1 << 1);
3048 insn
->bits
|= unit_bit
<< 24;
3053 /* Parse a CACHEW instruction. */
3055 parse_cachew (const char *line
, metag_insn
*insn
,
3056 const insn_template
*template)
3058 const char *l
= line
;
3059 const metag_reg
*src_regs
[2];
3060 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3064 memset(&addr
, 0, sizeof(addr
));
3065 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3067 l
= parse_addr (l
, &addr
, size
);
3070 !is_short_unit (addr
.base_reg
->unit
) ||
3074 as_bad (_("invalid memory operand"));
3085 l
= parse_gp_regs (l
, src_regs
, 1);
3087 l
= parse_pair_gp_regs (l
, src_regs
);
3090 !is_short_unit (src_regs
[0]->unit
))
3092 as_bad (_("invalid source register"));
3096 offset
= addr
.exp
.X_add_number
;
3101 offset
= offset
/ 64;
3103 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3105 as_bad (_("offset value out of range"));
3109 insn
->bits
= (template->meta_opcode
|
3110 (src_regs
[0]->no
<< 19) |
3111 (addr
.base_reg
->no
<< 14) |
3112 ((offset
& GET_SET_IMM_MASK
) << 8) |
3113 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3114 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3120 /* Parse a CACHEW instruction. */
3122 parse_cacher (const char *line
, metag_insn
*insn
,
3123 const insn_template
*template)
3125 const char *l
= line
;
3126 const metag_reg
*dest_regs
[2];
3127 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3131 memset(&addr
, 0, sizeof(addr
));
3132 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3135 l
= parse_gp_regs (l
, dest_regs
, 1);
3137 l
= parse_pair_gp_regs (l
, dest_regs
);
3140 !is_short_unit (dest_regs
[0]->unit
))
3142 as_bad (_("invalid destination register"));
3152 l
= parse_addr (l
, &addr
, size
);
3155 !is_short_unit (addr
.base_reg
->unit
) ||
3159 as_bad (_("invalid memory operand"));
3163 offset
= addr
.exp
.X_add_number
;
3168 offset
= offset
/ (int)size
;
3170 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3172 as_bad (_("offset value out of range"));
3176 insn
->bits
= (template->meta_opcode
|
3177 (dest_regs
[0]->no
<< 19) |
3178 (addr
.base_reg
->no
<< 14) |
3179 ((offset
& GET_SET_IMM_MASK
) << 8) |
3180 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3181 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3187 /* Parse an ICACHE instruction. */
3189 parse_icache (const char *line
, metag_insn
*insn
,
3190 const insn_template
*template)
3192 const char *l
= line
;
3196 l
= parse_imm_constant (l
, insn
, &offset
);
3201 if (!within_signed_range (offset
, IMM15_BITS
))
3206 l
= parse_imm_constant (l
, insn
, &pfcount
);
3211 if (!within_unsigned_range (pfcount
, IMM4_BITS
))
3214 insn
->bits
= (template->meta_opcode
|
3215 ((offset
& IMM15_MASK
) << 9) |
3216 ((pfcount
& IMM4_MASK
) << 1));
3222 /* Parse a LNKGET instruction. */
3224 parse_lnkget (const char *line
, metag_insn
*insn
,
3225 const insn_template
*template)
3227 const char *l
= line
;
3228 const metag_reg
*dest_regs
[2];
3229 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
3233 memset(&addr
, 0, sizeof(addr
));
3234 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3237 l
= parse_pair_gp_regs (l
, dest_regs
);
3239 l
= parse_gp_regs (l
, dest_regs
, 1);
3242 !is_short_unit (dest_regs
[0]->unit
))
3244 as_bad (_("invalid destination register"));
3254 l
= parse_addr (l
, &addr
, size
);
3257 !is_short_unit (addr
.base_reg
->unit
) ||
3261 as_bad (_("invalid memory operand"));
3265 offset
= addr
.exp
.X_add_number
;
3270 offset
= offset
/ size
;
3272 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3274 as_bad (_("offset value out of range"));
3278 insn
->bits
= (template->meta_opcode
|
3279 (dest_regs
[0]->no
<< 19) |
3280 (addr
.base_reg
->no
<< 14) |
3281 ((offset
& GET_SET_IMM_MASK
) << 8) |
3282 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3283 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3289 /* Parse an FPU MOV instruction. */
3291 parse_fmov (const char *line
, metag_insn
*insn
,
3292 const insn_template
*template)
3294 const char *l
= line
;
3295 const metag_reg
*regs
[2];
3297 l
= parse_fpu_regs (l
, regs
, 2);
3302 insn
->bits
= (template->meta_opcode
|
3303 (regs
[0]->no
<< 19) |
3304 (regs
[1]->no
<< 14));
3306 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3307 insn
->bits
|= (1 << 5);
3308 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3309 insn
->bits
|= (1 << 6);
3315 /* Parse an FPU MMOV instruction. */
3317 parse_fmmov (const char *line
, metag_insn
*insn
,
3318 const insn_template
*template)
3320 const char *l
= line
;
3321 bfd_boolean to_fpu
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
3322 bfd_boolean is_mmovl
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
3323 size_t regs_read
= 0;
3324 const metag_reg
*regs
[16];
3325 unsigned int lowest_data_reg
= 0xffffffff;
3326 unsigned int lowest_fpu_reg
= 0xffffffff;
3327 unsigned int rmask
= 0, data_unit
;
3331 if (insn
->fpu_width
!= FPU_WIDTH_SINGLE
)
3334 l
= parse_gp_regs_list (l
, regs
, 16, ®s_read
);
3344 for (i
= 0; i
< regs_read
/ 2; i
++)
3346 if (regs
[i
]->unit
!= UNIT_FX
)
3351 last_reg
= regs
[i
]->no
;
3352 lowest_fpu_reg
= last_reg
;
3358 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3361 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3364 last_reg
= regs
[i
]->no
;
3368 if (regs
[i
]->unit
== UNIT_D0
)
3370 else if (regs
[i
]->unit
== UNIT_D1
)
3375 if (!check_rmask (®s
[i
], regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3381 if (regs
[0]->unit
== UNIT_D0
)
3383 else if (regs
[0]->unit
== UNIT_D1
)
3388 if (!check_rmask (regs
, regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3392 for (i
= regs_read
/ 2; i
< regs_read
; i
++)
3394 if (regs
[i
]->unit
!= UNIT_FX
)
3399 last_reg
= regs
[i
]->no
;
3400 lowest_fpu_reg
= last_reg
;
3406 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3409 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3412 last_reg
= regs
[i
]->no
;
3417 insn
->bits
= (template->meta_opcode
|
3418 ((lowest_data_reg
& REG_MASK
) << 19) |
3419 ((lowest_fpu_reg
& REG_MASK
) << 14) |
3420 ((rmask
& RMASK_MASK
) << 7) |
3427 /* Parse an FPU data unit MOV instruction. */
3429 parse_fmov_data (const char *line
, metag_insn
*insn
,
3430 const insn_template
*template)
3432 const char *l
= line
;
3433 unsigned int to_fpu
= ((template->meta_opcode
>> 7) & 0x1);
3434 const metag_reg
*regs
[2];
3435 unsigned int base_unit
;
3437 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3440 l
= parse_gp_regs (l
, regs
, 2);
3447 if (regs
[0]->unit
!= UNIT_FX
)
3450 if (regs
[1]->unit
== UNIT_D0
)
3452 else if (regs
[1]->unit
== UNIT_D1
)
3459 if (regs
[0]->unit
== UNIT_D0
)
3461 else if (regs
[0]->unit
== UNIT_D1
)
3466 if (regs
[1]->unit
!= UNIT_FX
)
3470 insn
->bits
= (template->meta_opcode
|
3472 (regs
[0]->no
<< 19) |
3473 (regs
[1]->no
<< 9));
3479 /* Parse an FPU immediate MOV instruction. */
3481 parse_fmov_i (const char *line
, metag_insn
*insn
,
3482 const insn_template
*template)
3484 const char *l
= line
;
3485 const metag_reg
*regs
[1];
3488 l
= parse_fpu_regs (l
, regs
, 1);
3496 l
= parse_imm16 (l
, insn
, &value
);
3501 insn
->bits
= (template->meta_opcode
|
3502 (regs
[0]->no
<< 19) |
3503 ((value
& IMM16_MASK
) << 3));
3505 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3506 insn
->bits
|= (1 << 1);
3507 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3508 insn
->bits
|= (1 << 2);
3514 /* Parse an FPU PACK instruction. */
3516 parse_fpack (const char *line
, metag_insn
*insn
,
3517 const insn_template
*template)
3519 const char *l
= line
;
3520 const metag_reg
*regs
[3];
3522 l
= parse_fpu_regs (l
, regs
, 3);
3527 if (regs
[0]->no
% 2)
3529 as_bad (_("destination register should be even numbered"));
3533 insn
->bits
= (template->meta_opcode
|
3534 (regs
[0]->no
<< 19) |
3535 (regs
[1]->no
<< 14) |
3536 (regs
[2]->no
<< 9));
3542 /* Parse an FPU SWAP instruction. */
3544 parse_fswap (const char *line
, metag_insn
*insn
,
3545 const insn_template
*template)
3547 const char *l
= line
;
3548 const metag_reg
*regs
[2];
3550 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3553 l
= parse_fpu_regs (l
, regs
, 2);
3558 if (regs
[0]->no
% 2)
3561 if (regs
[1]->no
% 2)
3564 insn
->bits
= (template->meta_opcode
|
3565 (regs
[0]->no
<< 19) |
3566 (regs
[1]->no
<< 14));
3572 /* Parse an FPU CMP instruction. */
3574 parse_fcmp (const char *line
, metag_insn
*insn
,
3575 const insn_template
*template)
3577 const char *l
= line
, *l2
;
3578 const metag_reg
*regs1
[1];
3579 const metag_reg
*regs2
[1];
3581 l
= parse_fpu_regs (l
, regs1
, 1);
3589 l2
= parse_fpu_regs (l
, regs2
, 1);
3593 insn
->bits
= (regs2
[0]->no
<< 9);
3598 l2
= parse_imm_constant (l
, insn
, &constant
);
3599 if (!l2
|| constant
!= 0)
3601 as_bad (_("comparison must be with register or #0"));
3604 insn
->bits
= (1 << 8);
3607 insn
->bits
|= (template->meta_opcode
|
3608 (regs1
[0]->no
<< 14));
3610 if (insn
->fpu_action_flags
& FPU_ACTION_ABS
)
3611 insn
->bits
|= (1 << 19);
3613 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3614 insn
->bits
|= (1 << 7);
3616 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3617 insn
->bits
|= (1 << 6);
3618 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3619 insn
->bits
|= (1 << 5);
3625 /* Parse an FPU MIN or MAX instruction. */
3627 parse_fminmax (const char *line
, metag_insn
*insn
,
3628 const insn_template
*template)
3630 const char *l
= line
;
3631 const metag_reg
*regs
[3];
3633 l
= parse_fpu_regs (l
, regs
, 3);
3638 insn
->bits
= (template->meta_opcode
|
3639 (regs
[0]->no
<< 19) |
3640 (regs
[1]->no
<< 14) |
3641 (regs
[2]->no
<< 9));
3643 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3644 insn
->bits
|= (1 << 6);
3645 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3646 insn
->bits
|= (1 << 5);
3652 /* Parse an FPU data conversion instruction. */
3654 parse_fconv (const char *line
, metag_insn
*insn
,
3655 const insn_template
*template)
3657 const char *l
= line
;
3658 const metag_reg
*regs
[2];
3660 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3662 if (strncasecmp (template->name
, "FTOH", 4) &&
3663 strncasecmp (template->name
, "HTOF", 4) &&
3664 strncasecmp (template->name
, "FTOI", 4) &&
3665 strncasecmp (template->name
, "ITOF", 4))
3667 as_bad (_("instruction cannot operate on pair values"));
3672 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3674 if (strncasecmp (template->name
, "FTOI", 4) &&
3675 strncasecmp (template->name
, "DTOI", 4) &&
3676 strncasecmp (template->name
, "DTOL", 4))
3678 as_bad (_("zero flag is not valid for this instruction"));
3683 l
= parse_fpu_regs (l
, regs
, 2);
3688 if (!strncasecmp (template->name
, "DTOL", 4) ||
3689 !strncasecmp (template->name
, "LTOD", 4))
3691 if (regs
[0]->no
% 2)
3693 as_bad (_("destination register should be even numbered"));
3697 if (regs
[1]->no
% 2)
3699 as_bad (_("source register should be even numbered"));
3704 insn
->bits
= (template->meta_opcode
|
3705 (regs
[0]->no
<< 19) |
3706 (regs
[1]->no
<< 14));
3708 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3709 insn
->bits
|= (1 << 6);
3711 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3712 insn
->bits
|= (1 << 12);
3718 /* Parse an FPU extended data conversion instruction. */
3720 parse_fconvx (const char *line
, metag_insn
*insn
,
3721 const insn_template
*template)
3723 const char *l
= line
;
3724 const metag_reg
*regs
[2];
3725 int fraction_bits
= 0;
3727 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3729 if (strncasecmp (template->name
, "FTOX", 4) &&
3730 strncasecmp (template->name
, "XTOF", 4))
3732 as_bad (_("instruction cannot operate on pair values"));
3737 l
= parse_fpu_regs (l
, regs
, 2);
3745 l
= parse_imm_constant (l
, insn
, &fraction_bits
);
3750 insn
->bits
= (template->meta_opcode
|
3751 (regs
[0]->no
<< 19) |
3752 (regs
[1]->no
<< 14));
3754 if (strncasecmp (template->name
, "DTOXL", 5) &&
3755 strncasecmp (template->name
, "XLTOD", 5))
3757 if (!within_unsigned_range (fraction_bits
, IMM5_BITS
))
3759 as_bad (_("fraction bits value out of range"));
3762 insn
->bits
|= ((fraction_bits
& IMM5_MASK
) << 9);
3766 if (!within_unsigned_range (fraction_bits
, IMM6_BITS
))
3768 as_bad (_("fraction bits value out of range"));
3771 insn
->bits
|= ((fraction_bits
& IMM6_MASK
) << 8);
3774 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3775 insn
->bits
|= (1 << 6);
3781 /* Parse an FPU basic arithmetic instruction. */
3783 parse_fbarith (const char *line
, metag_insn
*insn
,
3784 const insn_template
*template)
3786 const char *l
= line
;
3787 const metag_reg
*regs
[3];
3789 l
= parse_fpu_regs (l
, regs
, 3);
3794 insn
->bits
= (template->meta_opcode
|
3795 (regs
[0]->no
<< 19) |
3796 (regs
[1]->no
<< 14) |
3797 (regs
[2]->no
<< 9));
3799 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3800 insn
->bits
|= (1 << 6);
3801 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3802 insn
->bits
|= (1 << 5);
3804 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3805 insn
->bits
|= (1 << 7);
3811 /* Parse a floating point accumulator name. */
3813 parse_acf (const char *line
, int *part
)
3815 const char *l
= line
;
3818 for (i
= 0; i
< sizeof(metag_acftab
)/sizeof(metag_acftab
[0]); i
++)
3820 const metag_acf
*acf
= &metag_acftab
[i
];
3821 size_t name_len
= strlen (acf
->name
);
3823 if (strncasecmp (l
, acf
->name
, name_len
) == 0)
3833 /* Parse an FPU extended arithmetic instruction. */
3835 parse_fearith (const char *line
, metag_insn
*insn
,
3836 const insn_template
*template)
3838 const char *l
= line
;
3839 const metag_reg
*regs
[3];
3840 bfd_boolean is_muz
= (MINOR_OPCODE (template->meta_opcode
) == 0x6 &&
3841 ((template->meta_opcode
>> 4) & 0x1));
3842 unsigned int is_o3o
= template->meta_opcode
& 0x1;
3843 unsigned int is_mac
= 0;
3844 unsigned int is_maw
= 0;
3846 if (!strncasecmp (template->name
, "MAW", 3))
3849 if (!strncasecmp (template->name
, "MAC", 3))
3852 l
= parse_acf (l
, &part
);
3854 if (l
== NULL
|| part
!= 0)
3859 l
= parse_fpu_regs (l
, ®s
[1], 2);
3865 if (is_o3o
&& is_maw
)
3866 l
= parse_fpu_regs (l
, regs
, 2);
3868 l
= parse_fpu_regs (l
, regs
, 3);
3874 if (is_o3o
&& is_maw
)
3875 insn
->bits
= (template->meta_opcode
|
3876 (regs
[1]->no
<< 9));
3878 insn
->bits
= (template->meta_opcode
|
3879 (regs
[1]->no
<< 14));
3881 if (!(is_o3o
&& is_maw
))
3882 insn
->bits
|= (regs
[2]->no
<< 9);
3884 if (is_o3o
&& is_maw
)
3885 insn
->bits
|= (regs
[0]->no
<< 14);
3887 insn
->bits
|= (regs
[0]->no
<< 19);
3889 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3890 insn
->bits
|= (1 << 6);
3891 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3892 insn
->bits
|= (1 << 5);
3894 if (!is_mac
&& !is_maw
)
3895 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3896 insn
->bits
|= (1 << 7);
3899 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3900 insn
->bits
|= (1 << 1);
3906 /* Parse an FPU RCP or RSQ instruction. */
3908 parse_frec (const char *line
, metag_insn
*insn
,
3909 const insn_template
*template)
3911 const char *l
= line
;
3912 const metag_reg
*regs
[2];
3914 l
= parse_fpu_regs (l
, regs
, 2);
3919 insn
->bits
= (template->meta_opcode
|
3920 (regs
[0]->no
<< 19) |
3921 (regs
[1]->no
<< 14));
3923 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3924 insn
->bits
|= (1 << 6);
3925 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3926 insn
->bits
|= (1 << 5);
3928 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3929 insn
->bits
|= (1 << 10);
3930 else if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3931 insn
->bits
|= (1 << 9);
3933 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3934 insn
->bits
|= (1 << 7);
3940 /* Parse an FPU vector arithmetic instruction. */
3942 parse_fsimd (const char *line
, metag_insn
*insn
,
3943 const insn_template
*template)
3945 const char *l
= line
;
3946 const metag_reg
*regs
[3];
3948 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3950 as_bad (_("simd instructions operate on pair values (L prefix)"));
3954 l
= parse_fpu_regs (l
, regs
, 3);
3959 if (regs
[0]->no
% 2)
3961 as_bad (_("destination register should be even numbered"));
3965 if ((regs
[1]->no
% 2) ||
3968 as_bad (_("source registers should be even numbered"));
3972 insn
->bits
= (template->meta_opcode
|
3973 (regs
[0]->no
<< 19) |
3974 (regs
[1]->no
<< 14) |
3975 (regs
[2]->no
<< 9));
3977 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3978 insn
->bits
|= (1 << 7);
3984 /* Parse an FPU accumulator GET or SET instruction. */
3986 parse_fget_set_acf (const char *line
, metag_insn
*insn
,
3987 const insn_template
*template)
3989 const char *l
= line
;
3992 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
3994 memset(&addr
, 0, sizeof(addr
));
3995 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3999 l
= parse_acf (l
, &part
);
4006 l
= parse_mget_mset_addr (l
, &addr
);
4010 l
= parse_mget_mset_addr (l
, &addr
);
4017 l
= parse_acf (l
, &part
);
4023 insn
->bits
= (template->meta_opcode
|
4026 if (!is_short_unit (addr
.base_reg
->unit
))
4028 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
4032 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
4033 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
4039 /* Copy the name of the next register in LINE to REG_BUF. */
4041 strip_reg_name(const char *line
, char *reg_buf
)
4043 const char *l
= line
;
4046 while (is_register_char (*l
))
4051 if (!(len
< MAX_REG_LEN
))
4056 reg_buf
[len
] = '\0';
4061 /* Parse a DSP register from LINE into REG using only the registers
4062 from DSP_REGTAB. Return the next character or NULL. */
4064 __parse_dsp_reg (const char *line
, const metag_reg
**reg
, htab_t dsp_regtab
)
4066 const char *l
= line
;
4067 char name
[MAX_REG_LEN
];
4070 const metag_reg
*_reg
;
4072 /* We don't entirely strip the register name because we might
4073 actually want to match whole string in the register table,
4074 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4075 entry limits our comaprison to a reasonable bound anyway. */
4076 while (is_register_char (*l
) || *l
== PLUS
)
4081 if (!(len
< MAX_REG_LEN
))
4091 _reg
= (const metag_reg
*) htab_find (dsp_regtab
, &entry
);
4100 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4101 member is suitable for encoding into a DSP insn register field. */
4103 parse_dsp_insn_reg (const char *line
, const metag_reg
**reg
)
4105 return __parse_dsp_reg (line
, reg
, dsp_reg_htab
);
4108 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4109 member is suitable for encoding into a DSP template definition insn
4112 There is a separate table for whether we're doing a load or a store
4113 definition. "load" specifies which table to look at. */
4115 parse_dsp_template_reg (const char *line
, const metag_reg
**reg
,
4118 return __parse_dsp_reg (line
, reg
, dsp_tmpl_reg_htab
[load
]);
4121 /* Parse a single DSP register from LINE. */
4123 parse_dsp_reg (const char *line
, const metag_reg
**reg
,
4124 bfd_boolean tmpl
, bfd_boolean load
)
4127 return parse_dsp_template_reg (line
, reg
, load
);
4129 return parse_dsp_insn_reg (line
, reg
);
4132 /* Return TRUE if UNIT is an address unit. */
4134 is_addr_unit (enum metag_unit unit
)
4146 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4148 is_same_data_unit (enum metag_unit unit1
, enum metag_unit unit2
)
4156 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
)
4160 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
)
4164 if (unit2
== UNIT_D0
|| unit2
== UNIT_RAM_D0
)
4168 if (unit2
== UNIT_D1
|| unit2
== UNIT_RAM_D1
)
4172 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_D0
)
4176 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_D1
)
4186 /* Return TRUE if the register NUM is a quickrot control register. */
4188 is_quickrot_reg (unsigned int num
)
4200 /* Return TRUE if REG is an accumulator register. */
4202 is_accumulator_reg (const metag_reg
*reg
)
4204 if (reg
->unit
== UNIT_ACC_D0
|| reg
->unit
== UNIT_ACC_D1
)
4210 /* Return TRUE if REG is a DSP RAM register. */
4212 is_dspram_reg (const metag_reg
*reg
)
4214 if (reg
->unit
== UNIT_RAM_D0
|| reg
->unit
== UNIT_RAM_D1
)
4221 __parse_gp_reg (const char *line
, const metag_reg
**reg
, bfd_boolean load
)
4223 const char *l
= line
;
4224 char reg_buf
[MAX_REG_LEN
];
4230 /* Parse [DSPRAM.x]. */
4231 if (*l
== ADDR_BEGIN_CHAR
)
4238 l
= parse_dsp_reg (l
, reg
, TRUE
, load
);
4242 if (*l
== ADDR_END_CHAR
)
4246 as_bad (_("expected ']', not %c in %s"), *l
, l
);
4255 len
= strip_reg_name (l
, reg_buf
);
4260 *reg
= parse_gp_reg (reg_buf
);
4268 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4269 should try to parse the register as a general-purpose register if
4270 we fail to parse it as a DSP one. TMPL indicates whether the
4271 registers are part of a template definition instruction. If this is
4272 a template definition instruction LOAD says whether it's a load
4273 template insn. FIRST_DST indicates whether the first register is
4274 a destination operand. */
4276 parse_dsp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
4277 size_t *regs_read
, bfd_boolean try_gp
, bfd_boolean tmpl
,
4278 bfd_boolean load
, bfd_boolean first_dst
)
4280 const char *l
= line
;
4283 const metag_reg
*reg
;
4285 for (i
= 0; i
< count
; i
++)
4287 const char *next
, *ll
;
4296 *regs_read
= seen_regs
;
4301 ll
= parse_dsp_reg (l
, ®
, tmpl
, load
);
4307 l
= __parse_gp_reg (l
, ®
, !(first_dst
&& i
== 0));
4310 *regs_read
= seen_regs
;
4318 *regs_read
= seen_regs
;
4330 *regs_read
= seen_regs
;
4334 /* Parse the following memory references:
4345 - [DSPRam-DSPRam--] */
4347 parse_dsp_addr (const char *line
, metag_addr
*addr
, unsigned int size
,
4350 const char *l
= line
, *ll
;
4351 const metag_reg
*regs
[1];
4354 /* Skip opening square bracket. */
4357 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4362 if (!is_addr_unit (regs
[0]->unit
) &&
4363 !is_dspram_reg (regs
[0]))
4365 as_bad (_("invalid register for memory access"));
4369 addr
->base_reg
= regs
[0];
4371 if (*l
== ADDR_END_CHAR
)
4373 addr
->exp
.X_op
= O_constant
;
4374 addr
->exp
.X_add_symbol
= NULL
;
4375 addr
->exp
.X_op_symbol
= NULL
;
4377 /* Simple register with no offset (0 immediate). */
4378 addr
->exp
.X_add_number
= 0;
4380 addr
->immediate
= 1;
4386 ll
= parse_addr_post_incr_op (l
, addr
);
4388 if (ll
&& *ll
== ADDR_END_CHAR
)
4390 if (addr
->update
== 1)
4392 /* We have a post increment/decrement. */
4393 addr
->exp
.X_op
= O_constant
;
4394 addr
->exp
.X_add_number
= size
;
4395 addr
->exp
.X_add_symbol
= NULL
;
4396 addr
->exp
.X_op_symbol
= NULL
;
4397 addr
->post_increment
= 1;
4399 addr
->immediate
= 1;
4404 addr
->post_increment
= 0;
4406 l
= parse_addr_op (l
, addr
);
4411 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4416 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
4418 as_bad (_("offset and base must be from the same unit"));
4422 addr
->offset_reg
= regs
[0];
4424 if (*l
== ADDR_END_CHAR
)
4430 l
= parse_addr_post_incr_op (l
, addr
);
4435 if (*l
== ADDR_END_CHAR
)
4444 /* Parse a DSP GET or SET instruction. */
4446 parse_dget_set (const char *line
, metag_insn
*insn
,
4447 const insn_template
*template)
4449 const char *l
= line
;
4453 bfd_boolean is_get
= (template->meta_opcode
& 0x100);
4454 bfd_boolean is_dual
= (template->meta_opcode
& 0x4);
4455 bfd_boolean is_template
= FALSE
;
4456 const metag_reg
*regs
[2];
4458 size_t count
, regs_read
;
4460 memset(&addr
, 0, sizeof(addr
));
4461 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4463 size
= is_dual
? 8 : 4;
4464 count
= is_dual
? 2 : 1;
4468 /* GETL can be used on one template table entry. */
4472 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
,
4473 FALSE
, FALSE
, FALSE
);
4478 as_bad (_("unexpected end of line"));
4482 l
= parse_addr (l
, &addr
, size
);
4486 l
= parse_addr (l
, &addr
, size
);
4493 /* GETL can be used on one template table entry. */
4497 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
, FALSE
,
4504 /* The first register dictates the unit. */
4505 if (regs
[0]->unit
== UNIT_DT
)
4509 if (regs
[0]->unit
== UNIT_D0
|| regs
[0]->unit
== UNIT_RAM_D0
||
4510 regs
[0]->unit
== UNIT_ACC_D0
)
4516 rd_reg
= regs
[0]->no
;
4518 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4519 upper 8-bits of an accumulator. It is _only_ valid for the
4521 if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
)
4523 if (is_template
|| !(rd_reg
>= 16 && rd_reg
< 20))
4525 as_bad (_("'H' modifier only valid for accumulator registers"));
4529 /* Top 8-bits of the accumulator. */
4535 insn
->bits
= (template->meta_opcode
| (1 << 1));
4539 insn
->bits
= (template->meta_opcode
| unit
);
4542 insn
->bits
|= (rd_reg
<< 19);
4546 int offset
= addr
.exp
.X_add_number
;
4551 offset
= offset
/ (int)size
;
4553 if (!within_signed_range (offset
, DGET_SET_IMM_BITS
))
4555 as_bad (_("offset value out of range"));
4559 offset
= offset
& DGET_SET_IMM_MASK
;
4561 insn
->bits
|= (1 << 13);
4562 insn
->bits
|= (offset
<< 9);
4566 int au
= (addr
.base_reg
->unit
== UNIT_A1
);
4568 insn
->bits
|= (au
<< 18);
4569 insn
->bits
|= ((addr
.base_reg
->no
& REG_MASK
) << 14);
4570 insn
->bits
|= ((addr
.offset_reg
->no
& REG_MASK
) << 9);
4574 insn
->bits
|= (1 << 2);
4576 if (!is_addr_unit (addr
.base_reg
->unit
))
4578 as_bad (_("base unit must be either A0 or A1"));
4582 unit
= (addr
.base_reg
->unit
== UNIT_A0
) ? 0 : 1;
4583 insn
->bits
|= ((addr
.base_reg
->no
<< 14) | (unit
<< 18));
4590 /* Parse a DSP template instruction. */
4592 parse_dtemplate (const char *line
, metag_insn
*insn
,
4593 const insn_template
*template)
4595 const char *l
= line
;
4596 const metag_reg
*regs
[TEMPLATE_NUM_REGS
];
4597 bfd_boolean daop_only
= FALSE
;
4599 int regs_which
[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4602 for (i
= 0; i
< TEMPLATE_NUM_REGS
; i
++)
4606 as_bad (_("unexpected end of line"));
4610 /* We may only have 3 register operands. */
4611 if (*l
== END_OF_INSN
&& i
== 3)
4626 l
= parse_imm_constant (l
, insn
, ®s_val
[i
]);
4629 as_bad (_("invalid immediate"));
4636 /* We can't tell from the template instantiation whether
4637 this is a load or store. So we have to try looking up the
4638 register name in both the load and store tables. */
4640 l
= __parse_gp_reg (l
, ®s
[i
], TRUE
);
4643 /* Try the store table too. */
4644 l
= __parse_gp_reg (l2
, ®s
[i
], FALSE
);
4647 /* Then try a DSP register. */
4648 l
= parse_dsp_insn_reg (l2
, ®s
[i
]);
4649 if (l
== NULL
|| regs
[i
]->unit
== UNIT_DT
)
4651 as_bad (_("invalid register"));
4660 insn
->bits
= template->meta_opcode
;
4662 if (regs_which
[0] == 0)
4663 insn
->bits
|= (regs_val
[0] << 19);
4664 else if (regs_which
[0] == 1)
4665 insn
->bits
|= (regs
[0]->no
<< 19);
4667 if (regs_which
[1] == 0)
4668 insn
->bits
|= (regs_val
[1] << 14);
4669 else if (regs_which
[1] == 1)
4670 insn
->bits
|= (regs
[1]->no
<< 14);
4672 if (regs_which
[2] == 0)
4673 insn
->bits
|= (regs_val
[2] << 9);
4674 else if (regs_which
[2] == 1)
4675 insn
->bits
|= (regs
[2]->no
<< 9);
4677 if (regs_which
[3] == 0)
4678 insn
->bits
|= (regs_val
[3] << 4);
4679 else if (regs_which
[3] == 1)
4680 insn
->bits
|= (regs
[3]->no
<< 4);
4684 insn
->bits
|= (0x3 << 24); /* Set the minor opcode. */
4685 else if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
) /* Half Load/Store. */
4686 insn
->bits
|= (0x5 << 24); /* Set the minor opcode. */
4693 /* Parse a DSP Template definiton memory reference, e.g
4694 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4695 template definition is a DSP RAM template definition. */
4697 template_mem_ref(const char *line
, metag_addr
*addr
,
4698 bfd_boolean
*dspram
, int size
, bfd_boolean load
)
4700 const char *l
= line
;
4702 l
= parse_dsp_addr (l
, addr
, size
, load
);
4706 if (is_addr_unit(addr
->base_reg
->unit
))
4715 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4716 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4718 parse_template_regs (const char *line
, bfd_boolean
*load
,
4719 unsigned int *addr_unit
,
4720 const metag_reg
**template_reg
, metag_addr
*addr
,
4721 bfd_boolean
*dspram
, int size
)
4723 const char *l
= line
;
4728 /* DSP Template load definition (Tx, [Ax]) */
4732 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4738 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4740 if (addr
->base_reg
->unit
== UNIT_A1
)
4744 else if (*l
== ADDR_BEGIN_CHAR
) /* DSP Template store ([Ax], Tx) */
4747 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4753 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4757 if (addr
->base_reg
->unit
== UNIT_A1
)
4762 as_bad (_("invalid register operand"));
4769 #define INVALID_SHIFT (-1)
4771 static metag_reg _reg
;
4773 /* Parse a template instruction definition. */
4775 interpret_template_regs(const char *line
, metag_insn
*insn
,
4776 const metag_reg
**regs
,
4777 int *regs_shift
, bfd_boolean
*load
, bfd_boolean
*dspram
,
4778 int size
, int *ls_shift
, int *au_shift
,
4779 unsigned int *au
, int *imm
, int *imm_shift
,
4780 unsigned int *imm_mask
)
4782 const char *l
= line
;
4784 const metag_reg
*template_reg
[1];
4786 memset (&addr
, 0, sizeof(addr
));
4789 regs_shift
[1] = INVALID_SHIFT
;
4791 insn
->bits
|= (1 << 1);
4793 l
= skip_whitespace (l
);
4795 l
= parse_template_regs (l
, load
, au
, template_reg
,
4796 &addr
, dspram
, size
);
4799 as_bad (_("could not parse template definition"));
4803 regs
[2] = template_reg
[0];
4806 /* DSPRAM definition. */
4810 _reg
= *addr
.base_reg
;
4814 /* Set the post-increment bit in the register field. */
4820 /* The bottom bit of the increment register tells us
4821 whether it's increment register 0 or 1. */
4822 if (addr
.offset_reg
->no
& 0x1)
4830 insn
->bits
|= (0x3 << 17); /* This signifies a DSPRAM definition. */
4832 else /* DaOpPaMe definition. */
4834 regs
[0] = addr
.base_reg
;
4837 /* Set the I bit. */
4838 insn
->bits
|= (1 << 18);
4840 if (addr
.update
== 1)
4842 if (addr
.negate
== 1)
4853 /* Setup the offset register. */
4854 regs
[1] = addr
.offset_reg
;
4865 /* Does this combination of units need the O2R bit and can it be encoded? */
4867 units_need_o2r (enum metag_unit unit1
, enum metag_unit unit2
)
4872 if (unit1
== UNIT_D0
|| unit1
== UNIT_ACC_D0
|| unit1
== UNIT_RAM_D0
)
4874 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
|| unit2
== UNIT_D0
)
4889 if (unit1
== UNIT_D1
|| unit1
== UNIT_ACC_D1
|| unit1
== UNIT_RAM_D1
)
4891 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
|| unit2
== UNIT_D1
)
4909 /* Return TRUE if this is a DSP data unit. */
4911 is_dsp_data_unit (const metag_reg
*reg
)
4927 static metag_reg o2r_reg
;
4929 /* Parse a DaOpPaMe load template definition. */
4931 parse_dalu (const char *line
, metag_insn
*insn
,
4932 const insn_template
*template)
4934 const char *l
= line
;
4936 const metag_reg
*regs
[4];
4939 bfd_boolean is_mov
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
;
4940 bfd_boolean is_cmp
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_CMP
) &&
4941 ((template->meta_opcode
& 0xee) == 0));
4942 bfd_boolean is_dual
= (insn
->dsp_width
== DSP_WIDTH_DUAL
);
4943 bfd_boolean is_quickrot64
= ((insn
->dsp_action_flags
& DSP_ACTION_QR64
) != 0);
4944 int l1_shift
= INVALID_SHIFT
;
4945 bfd_boolean load
= FALSE
;
4946 int ls_shift
= INVALID_SHIFT
;
4947 bfd_boolean ar
= FALSE
;
4948 int ar_shift
= INVALID_SHIFT
;
4949 int regs_shift
[3] = { INVALID_SHIFT
, INVALID_SHIFT
, INVALID_SHIFT
};
4951 int imm_shift
= INVALID_SHIFT
;
4952 unsigned int imm_mask
= 0;
4953 unsigned int au
= 0;
4954 int au_shift
= INVALID_SHIFT
;
4955 unsigned int du
= 0;
4956 int du_shift
= INVALID_SHIFT
;
4957 unsigned int sc
= ((insn
->dsp_action_flags
& DSP_ACTION_OV
) != 0);
4958 int sc_shift
= INVALID_SHIFT
;
4959 unsigned int om
= ((insn
->dsp_action_flags
& DSP_ACTION_MOD
) != 0);
4960 int om_shift
= INVALID_SHIFT
;
4961 unsigned int o2r
= 0;
4962 int o2r_shift
= INVALID_SHIFT
;
4963 unsigned int qr
= 0;
4964 int qr_shift
= INVALID_SHIFT
;
4965 int qd_shift
= INVALID_SHIFT
;
4966 unsigned int qn
= 0;
4967 int qn_shift
= INVALID_SHIFT
;
4968 unsigned int a1
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ZERO
)) != 0);
4969 int a1_shift
= INVALID_SHIFT
;
4970 unsigned int a2
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
)) != 0);
4971 int a2_shift
= INVALID_SHIFT
;
4972 unsigned su
= ((insn
->dsp_action_flags
& DSP_ACTION_UMUL
) != 0);
4973 int su_shift
= INVALID_SHIFT
;
4975 int ac_shift
= INVALID_SHIFT
;
4976 unsigned int mx
= (((insn
->dsp_daoppame_flags
& DSP_DAOPPAME_8
) != 0) ||
4977 (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_16
) != 0);
4978 int mx_shift
= INVALID_SHIFT
;
4979 int size
= is_dual
? 8 : 4;
4981 bfd_boolean conditional
= (MINOR_OPCODE (template->meta_opcode
) & 0x4);
4983 /* XFIXME: check the flags are valid with the instruction. */
4984 if (is_quickrot64
&& !(template->arg_type
& DSP_ARGS_QR
))
4986 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
4990 insn
->bits
= template->meta_opcode
;
4992 memset (regs
, 0, sizeof (regs
));
4993 memset (&addr
, 0, sizeof (addr
));
4995 /* There are the following forms of DSP ALU instructions,
4998 19. D[T] Op De.r,Dx.r,De.r
4999 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5000 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5001 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5002 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5003 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5004 8. D Opcc De.r,Dx.r,Rx.r
5005 6. D Op De.r,Dx.r,Rx.r|RD
5006 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5007 7. D Op De.e,Dx.r,#I16
5010 4. D[T] Op Dx.r,De.r
5011 10. D Op Dx.r,Rx.r|RD
5014 12. D[T] Op De.r,Dx.r
5015 14. D Op DSPe.r,Dx.r
5016 15. D Op DSPx.r,#I16
5017 16. D Op De.r,DSPx.r
5018 18. D Op De.r,Dx.r|ACx.r
5021 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5022 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5023 21. D Op De.r,Dx.r|ACx.r,#I5 */
5026 if (template->arg_type
& DSP_ARGS_1
)
5030 /* Could this be a cross-unit accumulator op,
5031 e.g. ACe.e,ACx.r,ACo.e */
5032 if (template->arg_type
& DSP_ARGS_XACC
)
5034 ll
= parse_dsp_regs_list (l
, regs
, 3, ®s_read
, FALSE
, FALSE
,
5036 if (ll
!= NULL
&& regs_read
== 3
5037 && is_accumulator_reg (regs
[0]))
5039 if (regs
[0]->unit
!= regs
[1]->unit
||
5040 regs
[2]->unit
== regs
[1]->unit
)
5042 as_bad (_("invalid operands for cross-unit op"));
5046 du
= (regs
[1]->unit
== UNIT_ACC_D1
);
5050 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5051 insn
->bits
|= (5 << 6);
5053 goto check_for_template
;
5056 /* If we reach here, this instruction is not a
5057 cross-unit accumulator op. */
5060 if (template->arg_type
& DSP_ARGS_SPLIT8
)
5067 /* De.r|ACe.r,Dx.r,De.r */
5068 if (template->arg_type
& DSP_ARGS_DACC
)
5070 /* XFIXME: these need moving? */
5076 ll
= parse_dsp_reg (l
, ®s
[0], FALSE
, FALSE
);
5079 /* Using ACe.r as the dst requires one of the P,N or Z
5080 flags to be used. */
5081 if (!(insn
->dsp_action_flags
&
5082 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5084 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5090 l
= parse_dsp_regs_list (l
, ®s
[1], 2, ®s_read
,
5091 TRUE
, FALSE
, FALSE
, FALSE
);
5092 if (l
== NULL
|| regs_read
!= 2)
5094 as_bad (_("invalid register"));
5098 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5104 goto check_for_template
;
5107 /* If we reach here, this instruction does not use the
5108 accumulator as the destination register. */
5109 if ((insn
->dsp_action_flags
&
5110 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5112 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5120 l
= parse_dsp_regs_list (l
, regs
, 2, ®s_read
, TRUE
, FALSE
, FALSE
, TRUE
);
5121 if (l
== NULL
|| regs_read
!= 2)
5128 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5131 if (is_accumulator_reg(regs
[0]) && !(template->arg_type
& DSP_ARGS_DACC
))
5133 as_bad (_("accumulator not a valid destination"));
5137 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5140 l
= parse_imm16 (l
, insn
, &imm
);
5143 as_bad (_("invalid immediate value"));
5147 if (!within_signed_range (imm
, IMM16_BITS
))
5149 as_bad (_("immediate value out of range"));
5153 if (regs
[0]->unit
!= regs
[1]->unit
|| regs
[0]->no
!= regs
[1]->no
)
5155 as_bad (_("immediate value not allowed when source & dest differ"));
5163 insn
->bits
|= (1 << 25);
5165 insn
->bits
|= (0x3 << 0);
5169 /* Remove any bits that have been set in the immediate
5171 insn
->bits
&= ~(imm_mask
<< imm_shift
);
5179 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5180 ll
= parse_dsp_reg (l
, ®s
[2], FALSE
, FALSE
);
5185 if (!(template->arg_type
& DSP_ARGS_ACC2
))
5187 as_bad (_("invalid register operand: %s"), regs
[2]->name
);
5197 /* De.r,Dx.r,De.r */
5198 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5203 if (template->arg_type
& DSP_ARGS_ACC2
)
5206 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5207 if (template->arg_type
& DSP_ARGS_QR
)
5221 as_bad (_("QUICKRoT extension requires 4 registers"));
5225 l
= __parse_gp_reg (l
, ®s
[3], TRUE
);
5228 as_bad (_("invalid fourth register"));
5232 if (!is_addr_unit (regs
[3]->unit
) ||
5233 !is_quickrot_reg (regs
[3]->no
))
5235 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5239 qn
= (regs
[3]->no
== 3);
5244 /* This is the common exit path. Check for o2r. */
5245 if (regs
[2] != NULL
)
5247 o2r
= units_need_o2r (regs
[1]->unit
, regs
[2]->unit
);
5250 o2r_reg
.no
= lookup_o2r (0, du
, regs
[2]);
5251 o2r_reg
.unit
= regs
[2]->unit
;
5256 /* Check any DSP RAM pointers are valid for this unit. */
5257 if ((du
&& (regs
[0]->unit
== UNIT_RAM_D0
)) ||
5258 (!du
&& (regs
[0]->unit
== UNIT_RAM_D1
)) ||
5259 (du
&& (regs
[1]->unit
== UNIT_RAM_D0
)) ||
5260 (!du
&& (regs
[1]->unit
== UNIT_RAM_D1
)) ||
5261 (du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D0
)) ||
5262 (!du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D1
))) {
5263 as_bad (_("DSP RAM pointer in incorrect unit"));
5267 /* Is this a template definition? */
5268 if (IS_TEMPLATE_DEF (insn
))
5270 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5271 &dspram
, size
, &ls_shift
, &au_shift
,
5272 &au
, &imm
, &imm_shift
, &imm_mask
);
5285 if (template->arg_type
& DSP_ARGS_2
)
5287 bfd_boolean is_xsd
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
) &&
5288 (MINOR_OPCODE (template->meta_opcode
) == 0xa));
5289 bfd_boolean is_fpu_mov
= template->insn_type
== INSN_DSP_FPU
;
5290 bfd_boolean to_fpu
= (template->meta_opcode
>> 7) & 0x1;
5299 /* CMPs and TSTs don't store to their destination operand. */
5300 ll
= __parse_gp_reg (l
, regs
, is_cmp
);
5303 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5304 if (template->arg_type
& DSP_ARGS_DSP_SRC1
)
5306 l
= parse_dsp_reg (l
, regs
, FALSE
, FALSE
);
5309 as_bad (_("invalid register operand #1"));
5313 /* Only MOV instructions have a DSP register as a
5314 destination. Set the MOV DSPe.r opcode. The simple
5315 OR'ing is OK because the usual MOV opcode is 0x00. */
5316 insn
->bits
= (0x91 << 24);
5323 as_bad (_("invalid register operand #2"));
5331 /* Everything but CMP and TST. */
5332 if (MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
5333 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5334 MAJOR_OPCODE (insn
->bits
) == OPC_9
||
5335 MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
||
5336 ((template->meta_opcode
& 0x0000002c) != 0))
5342 if (!is_dsp_data_unit (regs
[0]) && !(regs
[0]->unit
== UNIT_FX
&&
5343 is_fpu_mov
&& to_fpu
))
5346 du
= (regs
[0]->unit
== UNIT_D1
|| regs
[0]->unit
== UNIT_RAM_D1
||
5347 regs
[0]->unit
== UNIT_ACC_D1
);
5353 if (template->arg_type
& DSP_ARGS_IMM
&&
5354 !(is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)))
5356 l
= parse_imm16 (l
, insn
, &imm
);
5359 as_bad (_("invalid immediate value"));
5363 if (!within_signed_range (imm
, IMM16_BITS
))
5372 /* Set the I-bit unless it's a MOV because they're
5374 if (!(is_mov
&& MAJOR_OPCODE (insn
->bits
) == OPC_9
))
5375 insn
->bits
|= (1 << 25);
5377 /* All instructions that takes immediates also have bit 1 set. */
5378 insn
->bits
|= (1 << 1);
5380 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5381 insn
->bits
|= (1 << 0);
5383 insn
->bits
&= ~(1 << 8);
5387 as_bad (_("this instruction does not accept an immediate"));
5393 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5395 insn
->bits
|= (1 << 8);
5399 ll
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5402 if (template->arg_type
& DSP_ARGS_DSP_SRC2
)
5404 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5407 as_bad (_("invalid register operand #3"));
5412 if ((is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)) ||
5413 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
)
5415 if (is_accumulator_reg (regs
[1]))
5419 as_bad (_("this instruction does not accept an accumulator"));
5431 insn
->bits
= (0x92 << 24); /* Set opcode. */
5437 as_bad (_("invalid register operand #4"));
5443 /* Set the o2r bit if required. */
5444 if (!is_fpu_mov
&& units_need_o2r (regs
[0]->unit
, regs
[1]->unit
))
5447 o2r_reg
.no
= lookup_o2r (0, du
, regs
[1]);
5452 else if (!is_dsp_data_unit (regs
[1]) &&
5453 !(is_fpu_mov
&& !to_fpu
&& regs
[1]->unit
== UNIT_FX
))
5456 if (is_fpu_mov
&& to_fpu
)
5457 du
= (regs
[1]->unit
== UNIT_D1
||
5458 regs
[1]->unit
== UNIT_RAM_D1
||
5459 regs
[1]->unit
== UNIT_ACC_D1
);
5463 if (MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5464 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5465 (((template->meta_opcode
& 0x0000002c) == 0) &&
5466 MAJOR_OPCODE (template->meta_opcode
) != OPC_MISC
))
5473 /* If it's an 0x0 MOV or NEG set some lower bits. */
5474 if ((MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5475 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) && !is_fpu_mov
)
5479 insn
->bits
|= (1 << 2);
5482 /* Check for template definitons. */
5483 if (IS_TEMPLATE_DEF (insn
))
5485 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5486 &dspram
, size
, &ls_shift
, &au_shift
,
5487 &au
, &imm
, &imm_shift
, &imm_mask
);
5500 l
= __parse_gp_reg (l
, regs
, FALSE
);
5503 as_bad (_("invalid register operand"));
5511 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5514 as_bad (_("invalid accumulator register"));
5522 l
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5525 as_bad (_("invalid register operand"));
5533 du
= (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_ACC_D1
5534 || regs
[1]->unit
== UNIT_RAM_D1
);
5540 l
= parse_imm_constant (l
, insn
, &imm
);
5543 as_bad (_("invalid immediate value"));
5547 if (!within_unsigned_range (imm
, IMM5_BITS
))
5554 insn
->bits
|= (1 << 25);
5559 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5564 /* Check for post-processing R,G,B flags. Conditional instructions
5565 do not have these bits. */
5566 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP9
)
5568 if ((template->meta_opcode
>> 26) & 0x1)
5570 as_bad (_("conditional instruction cannot use G flag"));
5574 insn
->bits
|= (1 << 3);
5577 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP8
)
5579 if ((template->meta_opcode
>> 26) & 0x1)
5581 as_bad (_("conditional instruction cannot use B flag"));
5585 insn
->bits
|= (0x3 << 2);
5588 if (insn
->dsp_action_flags
& DSP_ACTION_ROUND
)
5590 if ((template->meta_opcode
>> 26) & 0x1)
5592 as_bad (_("conditional instruction cannot use R flag"));
5595 insn
->bits
|= (1 << 2);
5598 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5599 if ((template->meta_opcode
>> 26) & 0x1)
5600 ls_shift
= INVALID_SHIFT
;
5602 /* The Condition Is Always (CA) bit must be set if we're targetting a
5603 Ux.r register as the destination. This means that we can't have
5604 any other condition bits set. */
5605 if (!is_same_data_unit (regs
[1]->unit
, regs
[0]->unit
))
5607 /* Set both the Conditional bit and the Condition is Always bit. */
5608 insn
->bits
|= (1 << 26);
5609 insn
->bits
|= (1 << 5);
5611 /* Fill out the Ud field. */
5612 insn
->bits
|= (regs
[0]->unit
<< 1);
5615 if (IS_TEMPLATE_DEF (insn
))
5617 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5618 &dspram
, size
, &ls_shift
, &au_shift
,
5619 &au
, &imm
, &imm_shift
, &imm_mask
);
5631 /* Set the registers and immediate values. */
5632 if (regs_shift
[0] != INVALID_SHIFT
)
5633 insn
->bits
|= (regs
[0]->no
<< regs_shift
[0]);
5635 if (regs_shift
[1] != INVALID_SHIFT
)
5636 insn
->bits
|= (regs
[1]->no
<< regs_shift
[1]);
5638 if (regs_shift
[2] != INVALID_SHIFT
)
5639 insn
->bits
|= (regs
[2]->no
<< regs_shift
[2]);
5641 /* Does this insn have an 'IMM' bit? The immediate value should
5642 already have been masked. */
5643 if (imm_shift
!= INVALID_SHIFT
)
5644 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5646 /* Does this insn have an 'AU' bit? */
5647 if (au_shift
!= INVALID_SHIFT
)
5648 insn
->bits
|= (au
<< au_shift
);
5650 /* Does this instruction have an 'LS' bit? */
5651 if (ls_shift
!= INVALID_SHIFT
)
5652 insn
->bits
|= (load
<< ls_shift
);
5654 /* Does this instruction have an 'AR' bit? */
5656 insn
->bits
|= (1 << ar_shift
);
5658 if (du_shift
!= INVALID_SHIFT
)
5659 insn
->bits
|= (du
<< du_shift
);
5661 if (sc_shift
!= INVALID_SHIFT
)
5662 insn
->bits
|= (sc
<< sc_shift
);
5664 if (om_shift
!= INVALID_SHIFT
)
5665 insn
->bits
|= (om
<< om_shift
);
5667 if (o2r_shift
!= INVALID_SHIFT
)
5668 insn
->bits
|= (o2r
<< o2r_shift
);
5670 if (qn_shift
!= INVALID_SHIFT
)
5671 insn
->bits
|= (qn
<< qn_shift
);
5673 if (qr_shift
!= INVALID_SHIFT
)
5674 insn
->bits
|= (qr
<< qr_shift
);
5676 if (qd_shift
!= INVALID_SHIFT
)
5677 insn
->bits
|= (is_quickrot64
<< qd_shift
);
5679 if (a1_shift
!= INVALID_SHIFT
)
5680 insn
->bits
|= (a1
<< a1_shift
);
5682 if (a2_shift
!= INVALID_SHIFT
)
5683 insn
->bits
|= (a2
<< a2_shift
);
5685 if (su_shift
!= INVALID_SHIFT
)
5686 insn
->bits
|= (su
<< su_shift
);
5688 if (imm_shift
!= INVALID_SHIFT
)
5689 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5691 if (ac_shift
!= INVALID_SHIFT
)
5692 insn
->bits
|= (ac
<< ac_shift
);
5694 if (mx_shift
!= INVALID_SHIFT
)
5695 insn
->bits
|= (mx
<< mx_shift
);
5699 if (l1_shift
== INVALID_SHIFT
)
5701 as_bad (_("'L' modifier not valid for this instruction"));
5705 insn
->bits
|= (1 << l1_shift
);
5713 typedef const char *(*insn_parser
)(const char *, metag_insn
*,
5714 const insn_template
*);
5717 static const insn_parser insn_parsers
[ENC_MAX
] =
5719 [ENC_NONE
] = parse_none
,
5720 [ENC_MOV_U2U
] = parse_mov_u2u
,
5721 [ENC_MOV_PORT
] = parse_mov_port
,
5722 [ENC_MMOV
] = parse_mmov
,
5723 [ENC_MDRD
] = parse_mdrd
,
5724 [ENC_MOVL_TTREC
] = parse_movl_ttrec
,
5725 [ENC_GET_SET
] = parse_get_set
,
5726 [ENC_GET_SET_EXT
] = parse_get_set_ext
,
5727 [ENC_MGET_MSET
] = parse_mget_mset
,
5728 [ENC_COND_SET
] = parse_cond_set
,
5729 [ENC_XFR
] = parse_xfr
,
5730 [ENC_MOV_CT
] = parse_mov_ct
,
5731 [ENC_SWAP
] = parse_swap
,
5732 [ENC_JUMP
] = parse_jump
,
5733 [ENC_CALLR
] = parse_callr
,
5734 [ENC_ALU
] = parse_alu
,
5735 [ENC_SHIFT
] = parse_shift
,
5736 [ENC_MIN_MAX
] = parse_min_max
,
5737 [ENC_BITOP
] = parse_bitop
,
5738 [ENC_CMP
] = parse_cmp
,
5739 [ENC_BRANCH
] = parse_branch
,
5740 [ENC_KICK
] = parse_kick
,
5741 [ENC_SWITCH
] = parse_switch
,
5742 [ENC_CACHER
] = parse_cacher
,
5743 [ENC_CACHEW
] = parse_cachew
,
5744 [ENC_ICACHE
] = parse_icache
,
5745 [ENC_LNKGET
] = parse_lnkget
,
5746 [ENC_FMOV
] = parse_fmov
,
5747 [ENC_FMMOV
] = parse_fmmov
,
5748 [ENC_FMOV_DATA
] = parse_fmov_data
,
5749 [ENC_FMOV_I
] = parse_fmov_i
,
5750 [ENC_FPACK
] = parse_fpack
,
5751 [ENC_FSWAP
] = parse_fswap
,
5752 [ENC_FCMP
] = parse_fcmp
,
5753 [ENC_FMINMAX
] = parse_fminmax
,
5754 [ENC_FCONV
] = parse_fconv
,
5755 [ENC_FCONVX
] = parse_fconvx
,
5756 [ENC_FBARITH
] = parse_fbarith
,
5757 [ENC_FEARITH
] = parse_fearith
,
5758 [ENC_FREC
] = parse_frec
,
5759 [ENC_FSIMD
] = parse_fsimd
,
5760 [ENC_FGET_SET_ACF
] = parse_fget_set_acf
,
5761 [ENC_DGET_SET
] = parse_dget_set
,
5762 [ENC_DTEMPLATE
] = parse_dtemplate
,
5763 [ENC_DALU
] = parse_dalu
,
5766 struct metag_core_option
5772 /* CPU type options. */
5773 static const struct metag_core_option metag_cpus
[] =
5775 {"all", CoreMeta11
|CoreMeta12
|CoreMeta21
},
5776 {"metac11", CoreMeta11
},
5777 {"metac12", CoreMeta12
},
5778 {"metac21", CoreMeta21
},
5782 /* FPU type options. */
5783 static const struct metag_core_option metag_fpus
[] =
5785 {"metac21", FpuMeta21
},
5789 /* DSP type options. */
5790 static const struct metag_core_option metag_dsps
[] =
5792 {"metac21", DspMeta21
},
5796 /* Parse a CPU command line option. */
5798 metag_parse_cpu (char * str
)
5800 const struct metag_core_option
* opt
;
5803 optlen
= strlen (str
);
5807 as_bad (_("missing cpu name `%s'"), str
);
5811 for (opt
= metag_cpus
; opt
->name
!= NULL
; opt
++)
5812 if (strncmp (opt
->name
, str
, optlen
) == 0)
5814 mcpu_opt
= opt
->value
;
5818 as_bad (_("unknown cpu `%s'"), str
);
5822 /* Parse an FPU command line option. */
5824 metag_parse_fpu (char * str
)
5826 const struct metag_core_option
* opt
;
5829 optlen
= strlen (str
);
5833 as_bad (_("missing fpu name `%s'"), str
);
5837 for (opt
= metag_fpus
; opt
->name
!= NULL
; opt
++)
5838 if (strncmp (opt
->name
, str
, optlen
) == 0)
5840 mfpu_opt
= opt
->value
;
5844 as_bad (_("unknown fpu `%s'"), str
);
5848 /* Parse a DSP command line option. */
5850 metag_parse_dsp (char * str
)
5852 const struct metag_core_option
* opt
;
5855 optlen
= strlen (str
);
5859 as_bad (_("missing DSP name `%s'"), str
);
5863 for (opt
= metag_dsps
; opt
->name
!= NULL
; opt
++)
5864 if (strncmp (opt
->name
, str
, optlen
) == 0)
5866 mdsp_opt
= opt
->value
;
5870 as_bad (_("unknown DSP `%s'"), str
);
5874 struct metag_long_option
5876 char * option
; /* Substring to match. */
5877 char * help
; /* Help information. */
5878 int (* func
) (char * subopt
); /* Function to decode sub-option. */
5879 char * deprecated
; /* If non-null, print this message. */
5882 struct metag_long_option metag_long_opts
[] =
5884 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5885 metag_parse_cpu
, NULL
},
5886 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5887 metag_parse_fpu
, NULL
},
5888 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5889 metag_parse_dsp
, NULL
},
5890 {NULL
, NULL
, 0, NULL
}
5894 md_parse_option (int c
, char * arg
)
5896 struct metag_long_option
*lopt
;
5898 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5900 /* These options are expected to have an argument. */
5901 if (c
== lopt
->option
[0]
5903 && strncmp (arg
, lopt
->option
+ 1,
5904 strlen (lopt
->option
+ 1)) == 0)
5907 /* If the option is deprecated, tell the user. */
5908 if (lopt
->deprecated
!= NULL
)
5909 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
5910 _(lopt
->deprecated
));
5913 /* Call the sup-option parser. */
5914 return lopt
->func (arg
+ strlen (lopt
->option
) - 1);
5922 md_show_usage (FILE * stream
)
5924 struct metag_long_option
*lopt
;
5926 fprintf (stream
, _(" Meta specific command line options:\n"));
5928 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5929 if (lopt
->help
!= NULL
)
5930 fprintf (stream
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
5933 /* The target specific pseudo-ops which we support. */
5934 const pseudo_typeS md_pseudo_table
[] =
5936 { "word", cons
, 2 },
5945 for (c
= 0; c
< 256; c
++)
5949 register_chars
[c
] = c
;
5950 /* LOCK0, LOCK1, LOCK2. */
5951 mnemonic_chars
[c
] = c
;
5953 else if (ISLOWER (c
))
5955 register_chars
[c
] = c
;
5956 mnemonic_chars
[c
] = c
;
5958 else if (ISUPPER (c
))
5960 register_chars
[c
] = c
;
5961 mnemonic_chars
[c
] = c
;
5965 register_chars
[c
] = c
;
5970 /* Parse a split condition code prefix. */
5972 parse_split_condition (const char *line
, metag_insn
*insn
)
5974 const char *l
= line
;
5975 const split_condition
*scond
;
5976 split_condition entry
;
5984 scond
= (const split_condition
*) htab_find (scond_htab
, &entry
);
5989 insn
->scond
= scond
->code
;
5991 return l
+ strlen (scond
->name
);
5994 /* Parse an instruction prefix - F for float, D for DSP - and associated
5995 flags and condition codes. */
5997 parse_prefix (const char *line
, metag_insn
*insn
)
5999 const char *l
= line
;
6001 l
= skip_whitespace (l
);
6003 insn
->type
= INSN_GP
;
6005 if (TOLOWER (*l
) == FPU_PREFIX_CHAR
)
6007 if (strncasecmp (l
, FFB_INSN
, strlen(FFB_INSN
)))
6009 insn
->type
= INSN_FPU
;
6013 if (*l
== END_OF_INSN
)
6015 as_bad (_("premature end of floating point prefix"));
6019 if (TOLOWER (*l
) == FPU_DOUBLE_CHAR
)
6021 insn
->fpu_width
= FPU_WIDTH_DOUBLE
;
6024 else if (TOLOWER (*l
) == FPU_PAIR_CHAR
)
6028 /* Check this isn't a split condition beginning with L. */
6029 l2
= parse_split_condition (l2
, insn
);
6031 if (l2
&& is_whitespace_char (*l2
))
6037 insn
->fpu_width
= FPU_WIDTH_PAIR
;
6043 insn
->fpu_width
= FPU_WIDTH_SINGLE
;
6046 if (TOLOWER (*l
) == FPU_ACTION_ABS_CHAR
)
6048 insn
->fpu_action_flags
|= FPU_ACTION_ABS
;
6051 else if (TOLOWER (*l
) == FPU_ACTION_INV_CHAR
)
6053 insn
->fpu_action_flags
|= FPU_ACTION_INV
;
6057 if (TOLOWER (*l
) == FPU_ACTION_QUIET_CHAR
)
6059 insn
->fpu_action_flags
|= FPU_ACTION_QUIET
;
6063 if (TOLOWER (*l
) == FPU_ACTION_ZERO_CHAR
)
6065 insn
->fpu_action_flags
|= FPU_ACTION_ZERO
;
6069 if (! is_whitespace_char (*l
))
6071 l
= parse_split_condition (l
, insn
);
6075 as_bad (_("unknown floating point prefix character"));
6083 else if (TOLOWER (*l
) == DSP_PREFIX_CHAR
)
6085 if (strncasecmp (l
, DCACHE_INSN
, strlen (DCACHE_INSN
)) &&
6086 strncasecmp (l
, DEFR_INSN
, strlen (DEFR_INSN
)))
6089 insn
->type
= INSN_DSP
;
6093 insn
->dsp_width
= DSP_WIDTH_SINGLE
;
6095 while (!is_whitespace_char (*l
))
6097 /* We have to check for split condition codes first
6098 because they are the longest strings to match,
6099 e.g. if the string contains "LLS" we want it to match
6100 the split condition code "LLS", not the dual unit
6103 l
= parse_split_condition (l
, insn
);
6110 /* Accept an FPU prefix char which may be used when doing
6111 template MOV with FPU registers. */
6112 if (TOLOWER(*l
) == FPU_PREFIX_CHAR
)
6114 insn
->type
= INSN_DSP_FPU
;
6119 if (TOLOWER(*l
) == DSP_DUAL_CHAR
)
6121 insn
->dsp_width
= DSP_WIDTH_DUAL
;
6126 if (TOLOWER(*l
) == DSP_ACTION_QR64_CHAR
)
6128 insn
->dsp_action_flags
|= DSP_ACTION_QR64
;
6133 if (TOLOWER(*l
) == DSP_ACTION_UMUL_CHAR
)
6135 insn
->dsp_action_flags
|= DSP_ACTION_UMUL
;
6140 if (TOLOWER(*l
) == DSP_ACTION_ROUND_CHAR
)
6142 insn
->dsp_action_flags
|= DSP_ACTION_ROUND
;
6147 if (TOLOWER(*l
) == DSP_ACTION_CLAMP9_CHAR
)
6149 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP9
;
6154 if (TOLOWER(*l
) == DSP_ACTION_CLAMP8_CHAR
)
6156 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP8
;
6161 if (TOLOWER(*l
) == DSP_ACTION_MOD_CHAR
)
6163 insn
->dsp_action_flags
|= DSP_ACTION_MOD
;
6168 if (TOLOWER(*l
) == DSP_ACTION_ACC_ZERO_CHAR
)
6170 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ZERO
;
6175 if (TOLOWER(*l
) == DSP_ACTION_ACC_ADD_CHAR
)
6177 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ADD
;
6182 if (TOLOWER(*l
) == DSP_ACTION_ACC_SUB_CHAR
)
6184 insn
->dsp_action_flags
|= DSP_ACTION_ACC_SUB
;
6189 if (TOLOWER(*l
) == DSP_ACTION_OV_CHAR
)
6191 insn
->dsp_action_flags
|= DSP_ACTION_OV
;
6196 if (TOLOWER(*l
) == DSP_DAOPPAME_8_CHAR
)
6198 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_8
;
6203 if (TOLOWER(*l
) == DSP_DAOPPAME_16_CHAR
)
6205 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_16
;
6210 if (TOLOWER(*l
) == DSP_DAOPPAME_TEMP_CHAR
)
6212 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_TEMP
;
6217 if (TOLOWER(*l
) == DSP_DAOPPAME_HIGH_CHAR
)
6219 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_HIGH
;
6224 as_bad (_("unknown DSP prefix character %c %s"), *l
, l
);
6235 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6236 static insn_templates
*
6237 find_insn_templates (const char *mnemonic
)
6239 insn_template
template;
6240 insn_templates entry
;
6241 insn_templates
*slot
;
6243 entry
.template = &template;
6245 memcpy ((void *)&entry
.template->name
, &mnemonic
, sizeof (char *));
6247 slot
= (insn_templates
*) htab_find (mnemonic_htab
, &entry
);
6255 /* Make an uppercase copy of SRC into DST and return DST. */
6257 strupper (char * dst
, const char *src
)
6263 dst
[i
] = TOUPPER (src
[i
]);
6272 /* Calculate a hash value for a template. */
6274 hash_templates (const void *p
)
6276 insn_templates
*tp
= (insn_templates
*)p
;
6277 char buf
[MAX_MNEMONIC_LEN
];
6279 strupper (buf
, tp
->template->name
);
6281 return htab_hash_string (buf
);
6284 /* Check if two templates are equal. */
6286 eq_templates (const void *a
, const void *b
)
6288 insn_templates
*ta
= (insn_templates
*)a
;
6289 insn_templates
*tb
= (insn_templates
*)b
;
6290 return strcasecmp (ta
->template->name
, tb
->template->name
) == 0;
6293 /* Create the hash table required for parsing instructions. */
6295 create_mnemonic_htab (void)
6297 size_t i
, num_templates
= sizeof(metag_optab
)/sizeof(metag_optab
[0]);
6299 mnemonic_htab
= htab_create_alloc (num_templates
, hash_templates
,
6300 eq_templates
, NULL
, xcalloc
, free
);
6302 for (i
= 0; i
< num_templates
; i
++)
6304 const insn_template
*template = &metag_optab
[i
];
6305 insn_templates
**slot
= NULL
;
6306 insn_templates
*new_entry
;
6308 new_entry
= xmalloc (sizeof (insn_templates
));
6310 new_entry
->template = template;
6311 new_entry
->next
= NULL
;
6313 slot
= (insn_templates
**) htab_find_slot (mnemonic_htab
, new_entry
,
6318 insn_templates
*last_entry
= *slot
;
6320 while (last_entry
->next
)
6321 last_entry
= last_entry
->next
;
6323 last_entry
->next
= new_entry
;
6332 /* Calculate a hash value for a register. */
6334 hash_regs (const void *p
)
6336 metag_reg
*rp
= (metag_reg
*)p
;
6337 char buf
[MAX_REG_LEN
];
6339 strupper (buf
, rp
->name
);
6341 return htab_hash_string (buf
);
6344 /* Check if two registers are equal. */
6346 eq_regs (const void *a
, const void *b
)
6348 metag_reg
*ra
= (metag_reg
*)a
;
6349 metag_reg
*rb
= (metag_reg
*)b
;
6350 return strcasecmp (ra
->name
, rb
->name
) == 0;
6353 /* Create the hash table required for parsing registers. */
6355 create_reg_htab (void)
6357 size_t i
, num_regs
= sizeof(metag_regtab
)/sizeof(metag_regtab
[0]);
6359 reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6360 eq_regs
, NULL
, xcalloc
, free
);
6362 for (i
= 0; i
< num_regs
; i
++)
6364 const metag_reg
*reg
= &metag_regtab
[i
];
6365 const metag_reg
**slot
;
6367 slot
= (const metag_reg
**) htab_find_slot (reg_htab
, reg
, INSERT
);
6374 /* Create the hash table required for parsing DSP registers. */
6376 create_dspreg_htabs (void)
6378 size_t i
, num_regs
= sizeof(metag_dsp_regtab
)/sizeof(metag_dsp_regtab
[0]);
6381 dsp_reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6382 eq_regs
, NULL
, xcalloc
, free
);
6384 for (i
= 0; i
< num_regs
; i
++)
6386 const metag_reg
*reg
= &metag_dsp_regtab
[i
];
6387 const metag_reg
**slot
;
6389 slot
= (const metag_reg
**) htab_find_slot (dsp_reg_htab
, reg
, INSERT
);
6391 /* Make sure there are no hash table collisions, which would
6392 require chaining entries. */
6393 BFD_ASSERT (*slot
== NULL
);
6397 num_regs
= sizeof(metag_dsp_tmpl_regtab
[0])/sizeof(metag_dsp_tmpl_regtab
[0][0]);
6399 for (h
= 0; h
< 2; h
++)
6401 dsp_tmpl_reg_htab
[h
] = htab_create_alloc (num_regs
, hash_regs
,
6402 eq_regs
, NULL
, xcalloc
, free
);
6405 for (h
= 0; h
< 2; h
++)
6407 for (i
= 0; i
< num_regs
; i
++)
6409 const metag_reg
*reg
= &metag_dsp_tmpl_regtab
[h
][i
];
6410 const metag_reg
**slot
;
6411 slot
= (const metag_reg
**) htab_find_slot (dsp_tmpl_reg_htab
[h
],
6414 /* Make sure there are no hash table collisions, which would
6415 require chaining entries. */
6416 BFD_ASSERT (*slot
== NULL
);
6422 /* Calculate a hash value for a split condition code. */
6424 hash_scond (const void *p
)
6426 split_condition
*cp
= (split_condition
*)p
;
6429 strupper (buf
, cp
->name
);
6431 return htab_hash_string (buf
);
6434 /* Check if two split condition codes are equal. */
6436 eq_scond (const void *a
, const void *b
)
6438 split_condition
*ra
= (split_condition
*)a
;
6439 split_condition
*rb
= (split_condition
*)b
;
6441 return strcasecmp (ra
->name
, rb
->name
) == 0;
6444 /* Create the hash table required for parsing split condition codes. */
6446 create_scond_htab (void)
6450 nentries
= sizeof (metag_scondtab
) / sizeof (metag_scondtab
[0]);
6452 scond_htab
= htab_create_alloc (nentries
, hash_scond
, eq_scond
,
6453 NULL
, xcalloc
, free
);
6454 for (i
= 0; i
< nentries
; i
++)
6456 const split_condition
*scond
= &metag_scondtab
[i
];
6457 const split_condition
**slot
;
6459 slot
= (const split_condition
**) htab_find_slot (scond_htab
,
6461 /* Make sure there are no hash table collisions, which would
6462 require chaining entries. */
6463 BFD_ASSERT (*slot
== NULL
);
6468 /* Entry point for instruction parsing. */
6470 parse_insn (const char *line
, metag_insn
*insn
)
6472 char mnemonic
[MAX_MNEMONIC_LEN
];
6473 const char *l
= line
;
6474 size_t mnemonic_len
= 0;
6475 insn_templates
*templates
;
6479 while (is_mnemonic_char(*l
))
6485 if (mnemonic_len
>= MAX_MNEMONIC_LEN
)
6487 as_bad (_("instruction mnemonic too long: %s"), line
);
6491 strncpy(mnemonic
, line
, mnemonic_len
);
6493 mnemonic
[mnemonic_len
] = '\0';
6495 templates
= find_insn_templates (mnemonic
);
6499 insn_templates
*current_template
= templates
;
6503 while (current_template
)
6505 const insn_template
*template = current_template
->template;
6506 enum insn_encoding encoding
= template->encoding
;
6507 insn_parser parser
= insn_parsers
[encoding
];
6509 current_template
= current_template
->next
;
6511 if (template->insn_type
== INSN_GP
&&
6512 !(template->core_flags
& mcpu_opt
))
6515 if (template->insn_type
== INSN_FPU
&&
6516 !(template->core_flags
& mfpu_opt
))
6519 if (template->insn_type
== INSN_DSP
&&
6520 !(template->core_flags
& mdsp_opt
))
6523 if (template->insn_type
== INSN_DSP_FPU
&&
6524 !((template->core_flags
& mdsp_opt
) &&
6525 (template->core_flags
& mfpu_opt
)))
6528 /* DSP instructions always require special decoding */
6529 if ((insn
->type
== INSN_DSP
&& (template->insn_type
!= INSN_DSP
)) ||
6530 ((template->insn_type
== INSN_DSP
) && insn
->type
!= INSN_DSP
) ||
6531 (insn
->type
== INSN_DSP_FPU
&& (template->insn_type
!= INSN_DSP_FPU
)) ||
6532 ((template->insn_type
== INSN_DSP_FPU
) && insn
->type
!= INSN_DSP_FPU
))
6537 const char *end
= parser(l
, insn
, template);
6541 if (*end
!= END_OF_INSN
)
6542 as_bad (_("junk at end of line: \"%s\""), line
);
6549 as_bad (_("failed to assemble instruction: \"%s\""), line
);
6553 if (insn
->type
== INSN_FPU
)
6554 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic
);
6556 as_bad (_("unknown mnemonic: \"%s\""), mnemonic
);
6562 output_insn (metag_insn
*insn
)
6566 output
= frag_more (insn
->len
);
6567 dwarf2_emit_insn (insn
->len
);
6569 if (insn
->reloc_type
!= BFD_RELOC_UNUSED
)
6571 fix_new_exp (frag_now
, output
- frag_now
->fr_literal
,
6572 insn
->reloc_size
, &insn
->reloc_exp
,
6573 insn
->reloc_pcrel
, insn
->reloc_type
);
6576 md_number_to_chars (output
, insn
->bits
, insn
->len
);
6580 md_assemble (char *line
)
6582 const char *l
= line
;
6585 memset (&insn
, 0, sizeof(insn
));
6587 insn
.reloc_type
= BFD_RELOC_UNUSED
;
6588 insn
.reloc_pcrel
= 0;
6589 insn
.reloc_size
= 4;
6593 create_mnemonic_htab ();
6595 create_dspreg_htabs ();
6596 create_scond_htab ();
6599 l
= parse_prefix (l
, &insn
);
6604 if (insn
.type
== INSN_DSP
&&
6607 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6611 else if (insn
.type
== INSN_FPU
&&
6614 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6619 if (!parse_insn (l
, &insn
))
6622 output_insn (&insn
);
6626 md_operand (expressionS
* expressionP
)
6628 if (* input_line_pointer
== IMM_CHAR
)
6630 input_line_pointer
++;
6631 expression (expressionP
);
6636 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
6642 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6647 /* Functions concerning relocs. */
6649 /* The location from which a PC relative jump should be calculated,
6650 given a PC relative reloc. */
6653 md_pcrel_from_section (fixS
* fixP
, segT sec
)
6655 if ((fixP
->fx_addsy
!= (symbolS
*) NULL
6656 && (! S_IS_DEFINED (fixP
->fx_addsy
)
6657 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
6658 || metag_force_relocation (fixP
))
6660 /* The symbol is undefined (or is defined but not in this section).
6661 Let the linker figure it out. */
6665 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6668 /* Write a value out to the object file, using the appropriate endianness. */
6671 md_number_to_chars (char * buf
, valueT val
, int n
)
6673 number_to_chars_littleendian (buf
, val
, n
);
6676 /* Turn a string in input_line_pointer into a floating point constant of type
6677 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6678 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6681 /* Equal to MAX_PRECISION in atof-ieee.c */
6682 #define MAX_LITTLENUMS 6
6685 md_atof (int type
, char * litP
, int * sizeP
)
6689 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6708 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6712 return _("Bad call to md_atof()");
6715 t
= atof_ieee (input_line_pointer
, type
, words
);
6717 input_line_pointer
= t
;
6718 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
6720 for (i
= 0; i
< prec
; i
++)
6722 md_number_to_chars (litP
, (valueT
) words
[i
],
6723 sizeof (LITTLENUM_TYPE
));
6724 litP
+= sizeof (LITTLENUM_TYPE
);
6730 /* If this function returns non-zero, it prevents the relocation
6731 against symbol(s) in the FIXP from being replaced with relocations
6732 against section symbols, and guarantees that a relocation will be
6733 emitted even when the value can be resolved locally. */
6736 metag_force_relocation (fixS
* fix
)
6738 switch (fix
->fx_r_type
)
6740 case BFD_RELOC_METAG_RELBRANCH_PLT
:
6741 case BFD_RELOC_METAG_TLS_LE
:
6742 case BFD_RELOC_METAG_TLS_IE
:
6743 case BFD_RELOC_METAG_TLS_LDO
:
6744 case BFD_RELOC_METAG_TLS_LDM
:
6745 case BFD_RELOC_METAG_TLS_GD
:
6751 return generic_force_reloc (fix
);
6755 metag_fix_adjustable (fixS
* fixP
)
6757 if (fixP
->fx_addsy
== NULL
)
6760 /* Prevent all adjustments to global symbols. */
6761 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
6763 if (S_IS_WEAK (fixP
->fx_addsy
))
6766 if (fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTOFF
||
6767 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTOFF
||
6768 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOTOFF
||
6769 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOT
||
6770 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTPC
||
6771 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTPC
||
6772 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_PLT
||
6773 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_PLT
||
6774 fixP
->fx_r_type
== BFD_RELOC_METAG_RELBRANCH_PLT
)
6777 /* We need the symbol name for the VTABLE entries. */
6778 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6779 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6785 /* Return an initial guess of the length by which a fragment must grow to
6786 hold a branch to reach its destination.
6787 Also updates fr_type/fr_subtype as necessary.
6789 Called just before doing relaxation.
6790 Any symbol that is now undefined will not become defined.
6791 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6792 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6793 Although it may not be explicit in the frag, pretend fr_var starts with a
6797 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
6798 segT segment ATTRIBUTE_UNUSED
)
6800 /* No assembler relaxation is defined (or necessary) for this port. */
6804 /* *fragP has been relaxed to its final size, and now needs to have
6805 the bytes inside it modified to conform to the new size.
6807 Called after relaxation is finished.
6808 fragP->fr_type == rs_machine_dependent.
6809 fragP->fr_subtype is the subtype of what the address relaxed to. */
6812 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
,
6813 fragS
* fragP ATTRIBUTE_UNUSED
)
6815 /* No assembler relaxation is defined (or necessary) for this port. */
6819 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6822 metag_handle_align (fragS
* fragP
)
6824 static char const noop
[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6828 if (fragP
->fr_type
!= rs_align_code
)
6831 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
6832 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
6845 memcpy (p
, noop
, 4);
6851 fragP
->fr_fix
+= fix
;
6856 metag_end_of_match (char * cont
, char * what
)
6858 int len
= strlen (what
);
6860 if (strncasecmp (cont
, what
, strlen (what
)) == 0
6861 && ! is_part_of_name (cont
[len
]))
6868 metag_parse_name (char const * name
, expressionS
* exprP
, enum expr_mode mode
,
6871 char *next
= input_line_pointer
;
6877 exprP
->X_op_symbol
= NULL
;
6878 exprP
->X_md
= BFD_RELOC_UNUSED
;
6880 if (strcmp (name
, GOT_NAME
) == 0)
6883 GOT_symbol
= symbol_find_or_make (name
);
6885 exprP
->X_add_symbol
= GOT_symbol
;
6887 /* If we have an absolute symbol or a
6888 reg, then we know its value now. */
6889 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
6890 if (mode
!= expr_defer
&& segment
== absolute_section
)
6892 exprP
->X_op
= O_constant
;
6893 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6894 exprP
->X_add_symbol
= NULL
;
6896 else if (mode
!= expr_defer
&& segment
== reg_section
)
6898 exprP
->X_op
= O_register
;
6899 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6900 exprP
->X_add_symbol
= NULL
;
6904 exprP
->X_op
= O_symbol
;
6905 exprP
->X_add_number
= 0;
6911 exprP
->X_add_symbol
= symbol_find_or_make (name
);
6913 if (*nextcharP
!= '@')
6915 else if ((next_end
= metag_end_of_match (next
+ 1, "GOTOFF")))
6917 reloc_type
= BFD_RELOC_METAG_GOTOFF
;
6918 op_type
= O_PIC_reloc
;
6920 else if ((next_end
= metag_end_of_match (next
+ 1, "GOT")))
6922 reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
6923 op_type
= O_PIC_reloc
;
6925 else if ((next_end
= metag_end_of_match (next
+ 1, "PLT")))
6927 reloc_type
= BFD_RELOC_METAG_PLT
;
6928 op_type
= O_PIC_reloc
;
6930 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSGD")))
6932 reloc_type
= BFD_RELOC_METAG_TLS_GD
;
6933 op_type
= O_PIC_reloc
;
6935 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDM")))
6937 reloc_type
= BFD_RELOC_METAG_TLS_LDM
;
6938 op_type
= O_PIC_reloc
;
6940 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDO")))
6942 reloc_type
= BFD_RELOC_METAG_TLS_LDO
;
6943 op_type
= O_PIC_reloc
;
6945 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIE")))
6947 reloc_type
= BFD_RELOC_METAG_TLS_IE
;
6948 op_type
= O_PIC_reloc
;
6950 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIENONPIC")))
6952 reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC
;
6953 op_type
= O_PIC_reloc
; /* FIXME: is this correct? */
6955 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLE")))
6957 reloc_type
= BFD_RELOC_METAG_TLS_LE
;
6958 op_type
= O_PIC_reloc
;
6963 *input_line_pointer
= *nextcharP
;
6964 input_line_pointer
= next_end
;
6965 *nextcharP
= *input_line_pointer
;
6966 *input_line_pointer
= '\0';
6968 exprP
->X_op
= op_type
;
6969 exprP
->X_add_number
= 0;
6970 exprP
->X_md
= reloc_type
;
6975 /* If while processing a fixup, a reloc really needs to be created
6976 then it is done here. */
6979 tc_gen_reloc (seg
, fixp
)
6980 asection
*seg ATTRIBUTE_UNUSED
;
6985 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
6986 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6987 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6988 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6990 reloc
->addend
= fixp
->fx_offset
;
6991 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
6993 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
6995 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6996 /* xgettext:c-format. */
6997 _("reloc %d not supported by object file format"),
6998 (int) fixp
->fx_r_type
);
7009 md_chars_to_number (char *val
, int n
)
7012 unsigned char * where
= (unsigned char *) val
;
7014 for (retval
= 0; n
--;)
7023 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7025 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7026 int value
= (int)*valP
;
7028 switch (fixP
->fx_r_type
)
7030 case BFD_RELOC_METAG_TLS_GD
:
7031 case BFD_RELOC_METAG_TLS_LE_HI16
:
7032 case BFD_RELOC_METAG_TLS_LE_LO16
:
7033 case BFD_RELOC_METAG_TLS_IE
:
7034 case BFD_RELOC_METAG_TLS_IENONPIC_HI16
:
7035 case BFD_RELOC_METAG_TLS_IENONPIC_LO16
:
7036 case BFD_RELOC_METAG_TLS_LDM
:
7037 case BFD_RELOC_METAG_TLS_LDO_HI16
:
7038 case BFD_RELOC_METAG_TLS_LDO_LO16
:
7039 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7042 case BFD_RELOC_METAG_HIADDR16
:
7043 case BFD_RELOC_METAG_LOADDR16
:
7044 case BFD_RELOC_VTABLE_INHERIT
:
7045 case BFD_RELOC_VTABLE_ENTRY
:
7046 fixP
->fx_done
= FALSE
;
7049 case BFD_RELOC_METAG_REL8
:
7050 if (!within_unsigned_range (value
, IMM8_BITS
))
7052 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7053 "rel8 out of range %d", value
);
7057 unsigned int newval
;
7058 newval
= md_chars_to_number (buf
, 4);
7059 newval
= (newval
& 0xffffc03f) | ((value
& IMM8_MASK
) << 6);
7060 md_number_to_chars (buf
, newval
, 4);
7063 case BFD_RELOC_METAG_REL16
:
7064 if (!within_unsigned_range (value
, IMM16_BITS
))
7066 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7067 "rel16 out of range %d", value
);
7071 unsigned int newval
;
7072 newval
= md_chars_to_number (buf
, 4);
7073 newval
= (newval
& 0xfff80007) | ((value
& IMM16_MASK
) << 3);
7074 md_number_to_chars (buf
, newval
, 4);
7079 md_number_to_chars (buf
, value
, 1);
7082 md_number_to_chars (buf
, value
, 2);
7085 md_number_to_chars (buf
, value
, 4);
7088 md_number_to_chars (buf
, value
, 8);
7090 case BFD_RELOC_METAG_RELBRANCH
:
7096 if (!within_signed_range (value
, IMM19_BITS
))
7098 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7099 "relbranch out of range %d", value
);
7103 unsigned int newval
;
7104 newval
= md_chars_to_number (buf
, 4);
7105 newval
= (newval
& 0xff00001f) | ((value
& IMM19_MASK
) << 5);
7106 md_number_to_chars (buf
, newval
, 4);
7113 if (fixP
->fx_addsy
== NULL
)
7114 fixP
->fx_done
= TRUE
;