1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2 Copyright (C) 2013-2016 Free Software Foundation, Inc.
3 Contributed by Imagination Technologies Ltd.
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 /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit. */
2030 switch (regs
[0]->unit
)
2036 if (regs
[1]->unit
== UNIT_PC
2037 || regs
[1]->unit
== UNIT_CT
2038 || regs
[1]->unit
== UNIT_TR
2039 || regs
[1]->unit
== UNIT_TT
)
2041 as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
2046 /* Registers must be in different units. */
2047 if (regs
[0]->unit
== regs
[1]->unit
)
2049 as_bad (_("source and destination register must be in different units"));
2055 insn
->bits
= (template->meta_opcode
2056 | (regs
[1]->no
<< 19)
2057 | (regs
[0]->no
<< 14)
2058 | (regs
[1]->unit
<< 10)
2059 | (regs
[0]->unit
<< 5));
2065 /* Parse a JUMP instruction. */
2067 parse_jump (const char *line
, metag_insn
*insn
,
2068 const insn_template
*template)
2070 const char *l
= line
;
2071 const metag_reg
*regs
[1];
2074 l
= parse_gp_regs (l
, regs
, 1);
2079 if (!is_short_unit (regs
[0]->unit
))
2081 as_bad (_("register unit must be one of %s"), SHORT_UNITS
);
2091 l
= parse_imm16 (l
, insn
, &value
);
2096 insn
->bits
= (template->meta_opcode
|
2097 (regs
[0]->no
<< 19) |
2098 (regs
[0]->unit
& SHORT_UNIT_MASK
) |
2099 ((value
& IMM16_MASK
) << 3));
2105 /* Parse a 19bit immediate value. */
2107 parse_imm19 (const char *line
, metag_insn
*insn
, int *value
)
2109 const char *l
= line
;
2110 char *save_input_line_pointer
;
2111 expressionS
*exp
= &insn
->reloc_exp
;
2117 save_input_line_pointer
= input_line_pointer
;
2118 input_line_pointer
= (char *) l
;
2122 l
= input_line_pointer
;
2123 input_line_pointer
= save_input_line_pointer
;
2125 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
2129 else if (exp
->X_op
== O_constant
)
2131 *value
= exp
->X_add_number
;
2135 if (exp
->X_op
== O_PIC_reloc
)
2137 exp
->X_op
= O_symbol
;
2139 if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
2140 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH_PLT
;
2145 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH
;
2146 insn
->reloc_pcrel
= 1;
2152 /* Parse a CALLR instruction. */
2154 parse_callr (const char *line
, metag_insn
*insn
,
2155 const insn_template
*template)
2157 const char *l
= line
;
2158 const metag_reg
*regs
[1];
2161 l
= parse_gp_regs (l
, regs
, 1);
2166 if (!is_short_unit (regs
[0]->unit
))
2168 as_bad (_("link register unit must be one of %s"), SHORT_UNITS
);
2172 if (regs
[0]->no
& ~CALLR_REG_MASK
)
2174 as_bad (_("link register must be in a low numbered register"));
2184 l
= parse_imm19 (l
, insn
, &value
);
2189 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2191 as_bad (_("target out of range"));
2195 insn
->bits
= (template->meta_opcode
|
2196 (regs
[0]->no
& CALLR_REG_MASK
) |
2197 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3) |
2198 ((value
& IMM19_MASK
) << 5));
2204 /* Return the value for the register field if we apply the O2R modifier
2205 to operand 2 REG, combined with UNIT_BIT derived from the destination
2206 register or source1. Uses address unit O2R if IS_ADDR is set. */
2208 lookup_o2r (unsigned int is_addr
, unsigned int unit_bit
, const metag_reg
*reg
)
2210 if (reg
->no
& ~O2R_REG_MASK
)
2222 return (1 << 3) | reg
->no
;
2224 return (2 << 3) | reg
->no
;
2226 return (3 << 3) | reg
->no
;
2238 return (1 << 3) | reg
->no
;
2240 return (2 << 3) | reg
->no
;
2242 return (3 << 3) | reg
->no
;
2257 return (1 << 3) | reg
->no
;
2259 return (2 << 3) | reg
->no
;
2261 return (3 << 3) | reg
->no
;
2273 return (1 << 3) | reg
->no
;
2275 return (2 << 3) | reg
->no
;
2277 return (3 << 3) | reg
->no
;
2285 /* Parse GP ALU instruction. */
2287 parse_alu (const char *line
, metag_insn
*insn
,
2288 const insn_template
*template)
2290 const char *l
= line
;
2291 const metag_reg
*dest_regs
[1];
2292 const metag_reg
*src_regs
[2];
2294 unsigned int o1z
= 0;
2295 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2296 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2297 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2298 unsigned int top
= template->meta_opcode
& 0x1;
2299 unsigned int sign_extend
= 0;
2300 unsigned int is_addr_op
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
;
2301 unsigned int is_mul
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MUL
;
2302 unsigned int unit_bit
= 0;
2303 bfd_boolean is_quickrot
= template->arg_type
& GP_ARGS_QR
;
2305 l
= parse_gp_regs (l
, dest_regs
, 1);
2318 if (dest_regs
[0]->unit
== UNIT_A0
)
2320 else if (dest_regs
[0]->unit
== UNIT_A1
)
2325 if (dest_regs
[0]->unit
== UNIT_D0
)
2327 else if (dest_regs
[0]->unit
== UNIT_D1
)
2331 if ((MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
||
2332 MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
2333 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) &&
2334 ((template->meta_opcode
>> 2) & 0x1))
2343 if (dest_regs
[0]->unit
== UNIT_A0
)
2345 else if (dest_regs
[0]->unit
== UNIT_A1
)
2352 if (dest_regs
[0]->unit
== UNIT_D0
)
2354 else if (dest_regs
[0]->unit
== UNIT_D1
)
2363 l
= parse_gp_regs (l
, src_regs
, 1);
2376 if (src_regs
[0]->unit
== UNIT_A0
)
2378 else if (src_regs
[0]->unit
== UNIT_A1
)
2385 if (src_regs
[0]->unit
== UNIT_D0
)
2387 else if (src_regs
[0]->unit
== UNIT_D1
)
2393 if (src_regs
[0]->unit
!= dest_regs
[0]->unit
&& !ca
)
2396 l
= parse_imm8 (l
, insn
, &value
);
2401 if (!within_unsigned_range (value
, IMM8_BITS
))
2404 insn
->bits
= (template->meta_opcode
|
2405 (dest_regs
[0]->no
<< 19) |
2406 (src_regs
[0]->no
<< 14) |
2407 ((value
& IMM8_MASK
) << 6));
2413 if (src_regs
[0]->unit
== UNIT_A0
)
2415 else if (src_regs
[0]->unit
== UNIT_A1
)
2422 if (src_regs
[0]->unit
== UNIT_D0
)
2424 else if (src_regs
[0]->unit
== UNIT_D1
)
2430 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2435 l
= parse_imm16 (l
, insn
, &value
);
2442 if (!within_signed_range (value
, IMM16_BITS
))
2444 as_bad (_("immediate out of range"));
2451 if (!within_unsigned_range (value
, IMM16_BITS
))
2453 as_bad (_("immediate out of range"));
2458 insn
->bits
= (template->meta_opcode
|
2459 (dest_regs
[0]->no
<< 19) |
2460 ((value
& IMM16_MASK
) << 3));
2464 l
= parse_gp_regs (l
, src_regs
, 1);
2469 if (!(src_regs
[0]->unit
== dest_regs
[0]->unit
))
2472 /* CPC is valid for address ops. */
2473 if (src_regs
[0]->no
!= dest_regs
[0]->no
&&
2474 !(is_addr_op
&& src_regs
[0]->no
== 0x10))
2483 l
= parse_imm16 (l
, insn
, &value
);
2490 if (!within_signed_range (value
, IMM16_BITS
))
2492 as_bad (_("immediate out of range"));
2499 if (!within_unsigned_range (value
, IMM16_BITS
))
2501 as_bad (_("immediate out of range"));
2506 insn
->bits
= (template->meta_opcode
|
2507 (dest_regs
[0]->no
<< 19) |
2508 (src_regs
[0]->no
<< 19) |
2509 ((value
& IMM16_MASK
) << 3));
2514 unsigned int o2r
= 0;
2518 l
= parse_gp_regs (l
, src_regs
, 2);
2520 l
= parse_gp_regs (l
, src_regs
, 1);
2529 if (src_regs
[0]->unit
== UNIT_A0
)
2531 else if (src_regs
[0]->unit
== UNIT_A1
)
2538 if (src_regs
[0]->unit
== UNIT_D0
)
2540 else if (src_regs
[0]->unit
== UNIT_D1
)
2550 if (dest_regs
[0]->unit
== UNIT_A0
)
2552 else if (dest_regs
[0]->unit
== UNIT_A1
)
2559 if (dest_regs
[0]->unit
== UNIT_D0
)
2561 else if (dest_regs
[0]->unit
== UNIT_D1
)
2570 if (src_regs
[0]->unit
!= src_regs
[1]->unit
)
2572 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2581 rs2
= src_regs
[1]->no
;
2584 insn
->bits
= (template->meta_opcode
|
2585 (dest_regs
[0]->no
<< 19) |
2586 (src_regs
[0]->no
<< 14) |
2591 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
&& is_mul
)
2595 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2602 insn
->bits
|= dest_regs
[0]->unit
<< 5;
2606 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2608 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[0]);
2617 rs2
= src_regs
[0]->no
;
2620 insn
->bits
= (template->meta_opcode
|
2621 (dest_regs
[0]->no
<< 19) |
2626 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2629 if (dest_regs
[0]->unit
!= src_regs
[1]->unit
)
2631 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2640 rs2
= src_regs
[1]->no
;
2643 insn
->bits
= (template->meta_opcode
|
2644 (dest_regs
[0]->no
<< 19) |
2645 (src_regs
[0]->no
<< 14) |
2655 const metag_reg
*qr_regs
[1];
2656 bfd_boolean limit_regs
= imm
&& cond
;
2664 l
= parse_gp_regs (l
, qr_regs
, 1);
2669 if (!((unit_bit
== 0 && qr_regs
[0]->unit
!= UNIT_A0
) ||
2670 !(unit_bit
== 1 && qr_regs
[0]->unit
!= UNIT_A1
)))
2672 as_bad (_("invalid quickrot unit specified"));
2676 switch (qr_regs
[0]->no
)
2683 insn
->bits
|= (1 << 7);
2687 as_bad (_("invalid quickrot register specified"));
2692 if (sign_extend
== 1 && top
== 0)
2693 insn
->bits
|= (1 << 1);
2695 insn
->bits
|= unit_bit
<< 24;
2700 /* Parse a B instruction. */
2702 parse_branch (const char *line
, metag_insn
*insn
,
2703 const insn_template
*template)
2705 const char *l
= line
;
2708 l
= parse_imm19 (l
, insn
, &value
);
2713 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2715 as_bad (_("target out of range"));
2719 insn
->bits
= (template->meta_opcode
|
2720 ((value
& IMM19_MASK
) << 5));
2726 /* Parse a KICK instruction. */
2728 parse_kick (const char *line
, metag_insn
*insn
,
2729 const insn_template
*template)
2731 const char *l
= line
;
2732 const metag_reg
*regs
[2];
2734 l
= parse_gp_regs (l
, regs
, 2);
2739 if (regs
[1]->unit
!= UNIT_TR
)
2741 as_bad (_("source register must be in the trigger unit"));
2745 insn
->bits
= (template->meta_opcode
|
2746 (regs
[1]->no
<< 19) |
2747 (regs
[0]->no
<< 14) |
2748 (regs
[0]->unit
<< 5));
2754 /* Parse a SWITCH instruction. */
2756 parse_switch (const char *line
, metag_insn
*insn
,
2757 const insn_template
*template)
2759 const char *l
= line
;
2762 l
= parse_imm_constant (l
, insn
, &value
);
2767 if (!within_unsigned_range (value
, IMM24_BITS
))
2769 as_bad (_("target out of range"));
2773 insn
->bits
= (template->meta_opcode
|
2774 (value
& IMM24_MASK
));
2780 /* Parse a shift instruction. */
2782 parse_shift (const char *line
, metag_insn
*insn
,
2783 const insn_template
*template)
2785 const char *l
= line
;
2786 const metag_reg
*regs
[2];
2787 const metag_reg
*src2_regs
[1];
2789 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2790 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2791 unsigned int unit_bit
= 0;
2793 l
= parse_gp_regs (l
, regs
, 2);
2804 if (regs
[1]->unit
== UNIT_D0
)
2806 else if (regs
[1]->unit
== UNIT_D1
)
2811 if (regs
[0]->unit
!= regs
[1]->unit
&& !(cond
&& ca
))
2816 l
= parse_imm_constant (l
, insn
, &value
);
2821 if (!within_unsigned_range (value
, IMM5_BITS
))
2824 insn
->bits
= (template->meta_opcode
|
2826 (regs
[0]->no
<< 19) |
2827 (regs
[1]->no
<< 14) |
2828 ((value
& IMM5_MASK
) << 9));
2832 l
= parse_gp_regs (l
, src2_regs
, 1);
2837 insn
->bits
= (template->meta_opcode
|
2838 (regs
[0]->no
<< 19) |
2839 (regs
[1]->no
<< 14) |
2840 (src2_regs
[0]->no
<< 9));
2842 if (src2_regs
[0]->unit
!= regs
[1]->unit
)
2844 as_bad(_("Source registers must be in the same unit"));
2849 if (regs
[0]->unit
!= regs
[1]->unit
)
2853 if (regs
[1]->unit
== UNIT_D0
)
2855 else if (regs
[1]->unit
== UNIT_D1
)
2860 insn
->bits
|= ((1 << 5) |
2861 (regs
[0]->unit
<< 1));
2867 insn
->bits
|= unit_bit
<< 24;
2872 /* Parse a MIN or MAX instruction. */
2874 parse_min_max (const char *line
, metag_insn
*insn
,
2875 const insn_template
*template)
2877 const char *l
= line
;
2878 const metag_reg
*regs
[3];
2880 l
= parse_gp_regs (l
, regs
, 3);
2885 if (!(regs
[0]->unit
== UNIT_D0
||
2886 regs
[0]->unit
== UNIT_D1
))
2889 if (!(regs
[0]->unit
== regs
[1]->unit
&&
2890 regs
[1]->unit
== regs
[2]->unit
))
2893 insn
->bits
= (template->meta_opcode
|
2894 (regs
[0]->no
<< 19) |
2895 (regs
[1]->no
<< 14) |
2896 (regs
[2]->no
<< 9));
2898 if (regs
[0]->unit
== UNIT_D1
)
2899 insn
->bits
|= (1 << 24);
2905 /* Parse a bit operation instruction. */
2907 parse_bitop (const char *line
, metag_insn
*insn
,
2908 const insn_template
*template)
2910 const char *l
= line
;
2911 const metag_reg
*regs
[2];
2912 unsigned int swap_inst
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
;
2913 unsigned int is_bexl
= 0;
2916 ((template->meta_opcode
>> 1) & 0xb) == 0xa)
2919 l
= parse_gp_regs (l
, regs
, 2);
2924 if (!(regs
[0]->unit
== UNIT_D0
||
2925 regs
[0]->unit
== UNIT_D1
))
2930 if (regs
[0]->unit
== UNIT_D0
&&
2931 regs
[1]->unit
!= UNIT_D1
)
2933 else if (regs
[0]->unit
== UNIT_D1
&&
2934 regs
[1]->unit
!= UNIT_D0
)
2937 else if (!(regs
[0]->unit
== regs
[1]->unit
))
2940 insn
->bits
= (template->meta_opcode
|
2941 (regs
[0]->no
<< 19) |
2942 (regs
[1]->no
<< 14));
2946 if (regs
[1]->unit
== UNIT_D1
)
2951 if (regs
[1]->unit
== UNIT_D1
)
2952 insn
->bits
|= (1 << 24);
2959 /* Parse a CMP or TST instruction. */
2961 parse_cmp (const char *line
, metag_insn
*insn
,
2962 const insn_template
*template)
2964 const char *l
= line
;
2965 const metag_reg
*dest_regs
[1];
2966 const metag_reg
*src_regs
[1];
2968 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2969 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2970 unsigned int top
= template->meta_opcode
& 0x1;
2971 unsigned int sign_extend
= 0;
2972 unsigned int unit_bit
= 0;
2974 l
= parse_gp_regs (l
, dest_regs
, 1);
2985 if (dest_regs
[0]->unit
== UNIT_D0
)
2987 else if (dest_regs
[0]->unit
== UNIT_D1
)
2996 l
= parse_imm_constant (l
, insn
, &value
);
3001 if (!within_unsigned_range (value
, IMM8_BITS
))
3004 insn
->bits
= (template->meta_opcode
|
3005 (dest_regs
[0]->no
<< 14) |
3006 ((value
& IMM8_MASK
) << 6));
3011 l
= parse_imm16 (l
, insn
, &value
);
3018 if (!within_signed_range (value
, IMM16_BITS
))
3020 as_bad (_("immediate out of range"));
3027 if (!within_unsigned_range (value
, IMM16_BITS
))
3029 as_bad (_("immediate out of range"));
3034 insn
->bits
= (template->meta_opcode
|
3035 (dest_regs
[0]->no
<< 19) |
3036 ((value
& IMM16_MASK
) << 3));
3041 unsigned int o2r
= 0;
3044 l
= parse_gp_regs (l
, src_regs
, 1);
3049 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
3051 rs2
= lookup_o2r (0, unit_bit
, src_regs
[0]);
3060 rs2
= src_regs
[0]->no
;
3063 insn
->bits
= (template->meta_opcode
|
3064 (dest_regs
[0]->no
<< 14) |
3071 if (sign_extend
== 1 && top
== 0)
3072 insn
->bits
|= (1 << 1);
3074 insn
->bits
|= unit_bit
<< 24;
3079 /* Parse a CACHEW instruction. */
3081 parse_cachew (const char *line
, metag_insn
*insn
,
3082 const insn_template
*template)
3084 const char *l
= line
;
3085 const metag_reg
*src_regs
[2];
3086 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3090 memset(&addr
, 0, sizeof(addr
));
3091 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3093 l
= parse_addr (l
, &addr
, size
);
3096 !is_short_unit (addr
.base_reg
->unit
) ||
3100 as_bad (_("invalid memory operand"));
3111 l
= parse_gp_regs (l
, src_regs
, 1);
3113 l
= parse_pair_gp_regs (l
, src_regs
);
3116 !is_short_unit (src_regs
[0]->unit
))
3118 as_bad (_("invalid source register"));
3122 offset
= addr
.exp
.X_add_number
;
3127 offset
= offset
/ 64;
3129 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3131 as_bad (_("offset value out of range"));
3135 insn
->bits
= (template->meta_opcode
|
3136 (src_regs
[0]->no
<< 19) |
3137 (addr
.base_reg
->no
<< 14) |
3138 ((offset
& GET_SET_IMM_MASK
) << 8) |
3139 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3140 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3146 /* Parse a CACHEW instruction. */
3148 parse_cacher (const char *line
, metag_insn
*insn
,
3149 const insn_template
*template)
3151 const char *l
= line
;
3152 const metag_reg
*dest_regs
[2];
3153 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3157 memset(&addr
, 0, sizeof(addr
));
3158 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3161 l
= parse_gp_regs (l
, dest_regs
, 1);
3163 l
= parse_pair_gp_regs (l
, dest_regs
);
3166 !is_short_unit (dest_regs
[0]->unit
))
3168 as_bad (_("invalid destination register"));
3178 l
= parse_addr (l
, &addr
, size
);
3181 !is_short_unit (addr
.base_reg
->unit
) ||
3185 as_bad (_("invalid memory operand"));
3189 offset
= addr
.exp
.X_add_number
;
3194 offset
= offset
/ (int)size
;
3196 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3198 as_bad (_("offset value out of range"));
3202 insn
->bits
= (template->meta_opcode
|
3203 (dest_regs
[0]->no
<< 19) |
3204 (addr
.base_reg
->no
<< 14) |
3205 ((offset
& GET_SET_IMM_MASK
) << 8) |
3206 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3207 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3213 /* Parse an ICACHE instruction. */
3215 parse_icache (const char *line
, metag_insn
*insn
,
3216 const insn_template
*template)
3218 const char *l
= line
;
3222 l
= parse_imm_constant (l
, insn
, &offset
);
3227 if (!within_signed_range (offset
, IMM15_BITS
))
3232 l
= parse_imm_constant (l
, insn
, &pfcount
);
3237 if (!within_unsigned_range (pfcount
, IMM4_BITS
))
3240 insn
->bits
= (template->meta_opcode
|
3241 ((offset
& IMM15_MASK
) << 9) |
3242 ((pfcount
& IMM4_MASK
) << 1));
3248 /* Parse a LNKGET instruction. */
3250 parse_lnkget (const char *line
, metag_insn
*insn
,
3251 const insn_template
*template)
3253 const char *l
= line
;
3254 const metag_reg
*dest_regs
[2];
3255 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
3259 memset(&addr
, 0, sizeof(addr
));
3260 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3263 l
= parse_pair_gp_regs (l
, dest_regs
);
3265 l
= parse_gp_regs (l
, dest_regs
, 1);
3268 !is_short_unit (dest_regs
[0]->unit
))
3270 as_bad (_("invalid destination register"));
3280 l
= parse_addr (l
, &addr
, size
);
3283 !is_short_unit (addr
.base_reg
->unit
) ||
3287 as_bad (_("invalid memory operand"));
3291 offset
= addr
.exp
.X_add_number
;
3296 offset
= offset
/ size
;
3298 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3300 as_bad (_("offset value out of range"));
3304 insn
->bits
= (template->meta_opcode
|
3305 (dest_regs
[0]->no
<< 19) |
3306 (addr
.base_reg
->no
<< 14) |
3307 ((offset
& GET_SET_IMM_MASK
) << 8) |
3308 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3309 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3315 /* Parse an FPU MOV instruction. */
3317 parse_fmov (const char *line
, metag_insn
*insn
,
3318 const insn_template
*template)
3320 const char *l
= line
;
3321 const metag_reg
*regs
[2];
3323 l
= parse_fpu_regs (l
, regs
, 2);
3328 insn
->bits
= (template->meta_opcode
|
3329 (regs
[0]->no
<< 19) |
3330 (regs
[1]->no
<< 14));
3332 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3333 insn
->bits
|= (1 << 5);
3334 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3335 insn
->bits
|= (1 << 6);
3341 /* Parse an FPU MMOV instruction. */
3343 parse_fmmov (const char *line
, metag_insn
*insn
,
3344 const insn_template
*template)
3346 const char *l
= line
;
3347 bfd_boolean to_fpu
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
3348 bfd_boolean is_mmovl
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
3349 size_t regs_read
= 0;
3350 const metag_reg
*regs
[16];
3351 unsigned int lowest_data_reg
= 0xffffffff;
3352 unsigned int lowest_fpu_reg
= 0xffffffff;
3353 unsigned int rmask
= 0, data_unit
;
3357 if (insn
->fpu_width
!= FPU_WIDTH_SINGLE
)
3360 l
= parse_gp_regs_list (l
, regs
, 16, ®s_read
);
3370 for (i
= 0; i
< regs_read
/ 2; i
++)
3372 if (regs
[i
]->unit
!= UNIT_FX
)
3377 last_reg
= regs
[i
]->no
;
3378 lowest_fpu_reg
= last_reg
;
3384 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3387 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3390 last_reg
= regs
[i
]->no
;
3394 if (regs
[i
]->unit
== UNIT_D0
)
3396 else if (regs
[i
]->unit
== UNIT_D1
)
3401 if (!check_rmask (®s
[i
], regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3407 if (regs
[0]->unit
== UNIT_D0
)
3409 else if (regs
[0]->unit
== UNIT_D1
)
3414 if (!check_rmask (regs
, regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3418 for (i
= regs_read
/ 2; i
< regs_read
; i
++)
3420 if (regs
[i
]->unit
!= UNIT_FX
)
3425 last_reg
= regs
[i
]->no
;
3426 lowest_fpu_reg
= last_reg
;
3432 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3435 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3438 last_reg
= regs
[i
]->no
;
3443 insn
->bits
= (template->meta_opcode
|
3444 ((lowest_data_reg
& REG_MASK
) << 19) |
3445 ((lowest_fpu_reg
& REG_MASK
) << 14) |
3446 ((rmask
& RMASK_MASK
) << 7) |
3453 /* Parse an FPU data unit MOV instruction. */
3455 parse_fmov_data (const char *line
, metag_insn
*insn
,
3456 const insn_template
*template)
3458 const char *l
= line
;
3459 unsigned int to_fpu
= ((template->meta_opcode
>> 7) & 0x1);
3460 const metag_reg
*regs
[2];
3461 unsigned int base_unit
;
3463 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3466 l
= parse_gp_regs (l
, regs
, 2);
3473 if (regs
[0]->unit
!= UNIT_FX
)
3476 if (regs
[1]->unit
== UNIT_D0
)
3478 else if (regs
[1]->unit
== UNIT_D1
)
3485 if (regs
[0]->unit
== UNIT_D0
)
3487 else if (regs
[0]->unit
== UNIT_D1
)
3492 if (regs
[1]->unit
!= UNIT_FX
)
3496 insn
->bits
= (template->meta_opcode
|
3498 (regs
[0]->no
<< 19) |
3499 (regs
[1]->no
<< 9));
3505 /* Parse an FPU immediate MOV instruction. */
3507 parse_fmov_i (const char *line
, metag_insn
*insn
,
3508 const insn_template
*template)
3510 const char *l
= line
;
3511 const metag_reg
*regs
[1];
3514 l
= parse_fpu_regs (l
, regs
, 1);
3522 l
= parse_imm16 (l
, insn
, &value
);
3527 insn
->bits
= (template->meta_opcode
|
3528 (regs
[0]->no
<< 19) |
3529 ((value
& IMM16_MASK
) << 3));
3531 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3532 insn
->bits
|= (1 << 1);
3533 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3534 insn
->bits
|= (1 << 2);
3540 /* Parse an FPU PACK instruction. */
3542 parse_fpack (const char *line
, metag_insn
*insn
,
3543 const insn_template
*template)
3545 const char *l
= line
;
3546 const metag_reg
*regs
[3];
3548 l
= parse_fpu_regs (l
, regs
, 3);
3553 if (regs
[0]->no
% 2)
3555 as_bad (_("destination register should be even numbered"));
3559 insn
->bits
= (template->meta_opcode
|
3560 (regs
[0]->no
<< 19) |
3561 (regs
[1]->no
<< 14) |
3562 (regs
[2]->no
<< 9));
3568 /* Parse an FPU SWAP instruction. */
3570 parse_fswap (const char *line
, metag_insn
*insn
,
3571 const insn_template
*template)
3573 const char *l
= line
;
3574 const metag_reg
*regs
[2];
3576 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3579 l
= parse_fpu_regs (l
, regs
, 2);
3584 if (regs
[0]->no
% 2)
3587 if (regs
[1]->no
% 2)
3590 insn
->bits
= (template->meta_opcode
|
3591 (regs
[0]->no
<< 19) |
3592 (regs
[1]->no
<< 14));
3598 /* Parse an FPU CMP instruction. */
3600 parse_fcmp (const char *line
, metag_insn
*insn
,
3601 const insn_template
*template)
3603 const char *l
= line
, *l2
;
3604 const metag_reg
*regs1
[1];
3605 const metag_reg
*regs2
[1];
3607 l
= parse_fpu_regs (l
, regs1
, 1);
3615 l2
= parse_fpu_regs (l
, regs2
, 1);
3619 insn
->bits
= (regs2
[0]->no
<< 9);
3624 l2
= parse_imm_constant (l
, insn
, &constant
);
3625 if (!l2
|| constant
!= 0)
3627 as_bad (_("comparison must be with register or #0"));
3630 insn
->bits
= (1 << 8);
3633 insn
->bits
|= (template->meta_opcode
|
3634 (regs1
[0]->no
<< 14));
3636 if (insn
->fpu_action_flags
& FPU_ACTION_ABS
)
3637 insn
->bits
|= (1 << 19);
3639 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3640 insn
->bits
|= (1 << 7);
3642 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3643 insn
->bits
|= (1 << 6);
3644 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3645 insn
->bits
|= (1 << 5);
3651 /* Parse an FPU MIN or MAX instruction. */
3653 parse_fminmax (const char *line
, metag_insn
*insn
,
3654 const insn_template
*template)
3656 const char *l
= line
;
3657 const metag_reg
*regs
[3];
3659 l
= parse_fpu_regs (l
, regs
, 3);
3664 insn
->bits
= (template->meta_opcode
|
3665 (regs
[0]->no
<< 19) |
3666 (regs
[1]->no
<< 14) |
3667 (regs
[2]->no
<< 9));
3669 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3670 insn
->bits
|= (1 << 6);
3671 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3672 insn
->bits
|= (1 << 5);
3678 /* Parse an FPU data conversion instruction. */
3680 parse_fconv (const char *line
, metag_insn
*insn
,
3681 const insn_template
*template)
3683 const char *l
= line
;
3684 const metag_reg
*regs
[2];
3686 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3688 if (strncasecmp (template->name
, "FTOH", 4) &&
3689 strncasecmp (template->name
, "HTOF", 4) &&
3690 strncasecmp (template->name
, "FTOI", 4) &&
3691 strncasecmp (template->name
, "ITOF", 4))
3693 as_bad (_("instruction cannot operate on pair values"));
3698 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3700 if (strncasecmp (template->name
, "FTOI", 4) &&
3701 strncasecmp (template->name
, "DTOI", 4) &&
3702 strncasecmp (template->name
, "DTOL", 4))
3704 as_bad (_("zero flag is not valid for this instruction"));
3709 l
= parse_fpu_regs (l
, regs
, 2);
3714 if (!strncasecmp (template->name
, "DTOL", 4) ||
3715 !strncasecmp (template->name
, "LTOD", 4))
3717 if (regs
[0]->no
% 2)
3719 as_bad (_("destination register should be even numbered"));
3723 if (regs
[1]->no
% 2)
3725 as_bad (_("source register should be even numbered"));
3730 insn
->bits
= (template->meta_opcode
|
3731 (regs
[0]->no
<< 19) |
3732 (regs
[1]->no
<< 14));
3734 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3735 insn
->bits
|= (1 << 6);
3737 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3738 insn
->bits
|= (1 << 12);
3744 /* Parse an FPU extended data conversion instruction. */
3746 parse_fconvx (const char *line
, metag_insn
*insn
,
3747 const insn_template
*template)
3749 const char *l
= line
;
3750 const metag_reg
*regs
[2];
3751 int fraction_bits
= 0;
3753 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3755 if (strncasecmp (template->name
, "FTOX", 4) &&
3756 strncasecmp (template->name
, "XTOF", 4))
3758 as_bad (_("instruction cannot operate on pair values"));
3763 l
= parse_fpu_regs (l
, regs
, 2);
3771 l
= parse_imm_constant (l
, insn
, &fraction_bits
);
3776 insn
->bits
= (template->meta_opcode
|
3777 (regs
[0]->no
<< 19) |
3778 (regs
[1]->no
<< 14));
3780 if (strncasecmp (template->name
, "DTOXL", 5) &&
3781 strncasecmp (template->name
, "XLTOD", 5))
3783 if (!within_unsigned_range (fraction_bits
, IMM5_BITS
))
3785 as_bad (_("fraction bits value out of range"));
3788 insn
->bits
|= ((fraction_bits
& IMM5_MASK
) << 9);
3792 if (!within_unsigned_range (fraction_bits
, IMM6_BITS
))
3794 as_bad (_("fraction bits value out of range"));
3797 insn
->bits
|= ((fraction_bits
& IMM6_MASK
) << 8);
3800 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3801 insn
->bits
|= (1 << 6);
3807 /* Parse an FPU basic arithmetic instruction. */
3809 parse_fbarith (const char *line
, metag_insn
*insn
,
3810 const insn_template
*template)
3812 const char *l
= line
;
3813 const metag_reg
*regs
[3];
3815 l
= parse_fpu_regs (l
, regs
, 3);
3820 insn
->bits
= (template->meta_opcode
|
3821 (regs
[0]->no
<< 19) |
3822 (regs
[1]->no
<< 14) |
3823 (regs
[2]->no
<< 9));
3825 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3826 insn
->bits
|= (1 << 6);
3827 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3828 insn
->bits
|= (1 << 5);
3830 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3831 insn
->bits
|= (1 << 7);
3837 /* Parse a floating point accumulator name. */
3839 parse_acf (const char *line
, int *part
)
3841 const char *l
= line
;
3844 for (i
= 0; i
< sizeof(metag_acftab
)/sizeof(metag_acftab
[0]); i
++)
3846 const metag_acf
*acf
= &metag_acftab
[i
];
3847 size_t name_len
= strlen (acf
->name
);
3849 if (strncasecmp (l
, acf
->name
, name_len
) == 0)
3859 /* Parse an FPU extended arithmetic instruction. */
3861 parse_fearith (const char *line
, metag_insn
*insn
,
3862 const insn_template
*template)
3864 const char *l
= line
;
3865 const metag_reg
*regs
[3];
3866 bfd_boolean is_muz
= (MINOR_OPCODE (template->meta_opcode
) == 0x6 &&
3867 ((template->meta_opcode
>> 4) & 0x1));
3868 unsigned int is_o3o
= template->meta_opcode
& 0x1;
3869 unsigned int is_mac
= 0;
3870 unsigned int is_maw
= 0;
3872 if (!strncasecmp (template->name
, "MAW", 3))
3875 if (!strncasecmp (template->name
, "MAC", 3))
3878 l
= parse_acf (l
, &part
);
3880 if (l
== NULL
|| part
!= 0)
3885 l
= parse_fpu_regs (l
, ®s
[1], 2);
3891 if (is_o3o
&& is_maw
)
3892 l
= parse_fpu_regs (l
, regs
, 2);
3894 l
= parse_fpu_regs (l
, regs
, 3);
3900 if (is_o3o
&& is_maw
)
3901 insn
->bits
= (template->meta_opcode
|
3902 (regs
[1]->no
<< 9));
3904 insn
->bits
= (template->meta_opcode
|
3905 (regs
[1]->no
<< 14));
3907 if (!(is_o3o
&& is_maw
))
3908 insn
->bits
|= (regs
[2]->no
<< 9);
3910 if (is_o3o
&& is_maw
)
3911 insn
->bits
|= (regs
[0]->no
<< 14);
3913 insn
->bits
|= (regs
[0]->no
<< 19);
3915 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3916 insn
->bits
|= (1 << 6);
3917 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3918 insn
->bits
|= (1 << 5);
3920 if (!is_mac
&& !is_maw
)
3921 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3922 insn
->bits
|= (1 << 7);
3925 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3926 insn
->bits
|= (1 << 1);
3932 /* Parse an FPU RCP or RSQ instruction. */
3934 parse_frec (const char *line
, metag_insn
*insn
,
3935 const insn_template
*template)
3937 const char *l
= line
;
3938 const metag_reg
*regs
[2];
3940 l
= parse_fpu_regs (l
, regs
, 2);
3945 insn
->bits
= (template->meta_opcode
|
3946 (regs
[0]->no
<< 19) |
3947 (regs
[1]->no
<< 14));
3949 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3950 insn
->bits
|= (1 << 6);
3951 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3952 insn
->bits
|= (1 << 5);
3954 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3955 insn
->bits
|= (1 << 10);
3956 else if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3957 insn
->bits
|= (1 << 9);
3959 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3960 insn
->bits
|= (1 << 7);
3966 /* Parse an FPU vector arithmetic instruction. */
3968 parse_fsimd (const char *line
, metag_insn
*insn
,
3969 const insn_template
*template)
3971 const char *l
= line
;
3972 const metag_reg
*regs
[3];
3974 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3976 as_bad (_("simd instructions operate on pair values (L prefix)"));
3980 l
= parse_fpu_regs (l
, regs
, 3);
3985 if (regs
[0]->no
% 2)
3987 as_bad (_("destination register should be even numbered"));
3991 if ((regs
[1]->no
% 2) ||
3994 as_bad (_("source registers should be even numbered"));
3998 insn
->bits
= (template->meta_opcode
|
3999 (regs
[0]->no
<< 19) |
4000 (regs
[1]->no
<< 14) |
4001 (regs
[2]->no
<< 9));
4003 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
4004 insn
->bits
|= (1 << 7);
4010 /* Parse an FPU accumulator GET or SET instruction. */
4012 parse_fget_set_acf (const char *line
, metag_insn
*insn
,
4013 const insn_template
*template)
4015 const char *l
= line
;
4018 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
4020 memset(&addr
, 0, sizeof(addr
));
4021 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4025 l
= parse_acf (l
, &part
);
4032 l
= parse_mget_mset_addr (l
, &addr
);
4036 l
= parse_mget_mset_addr (l
, &addr
);
4043 l
= parse_acf (l
, &part
);
4049 insn
->bits
= (template->meta_opcode
|
4052 if (!is_short_unit (addr
.base_reg
->unit
))
4054 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
4058 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
4059 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
4065 /* Copy the name of the next register in LINE to REG_BUF. */
4067 strip_reg_name(const char *line
, char *reg_buf
)
4069 const char *l
= line
;
4072 while (is_register_char (*l
))
4077 if (!(len
< MAX_REG_LEN
))
4082 reg_buf
[len
] = '\0';
4087 /* Parse a DSP register from LINE into REG using only the registers
4088 from DSP_REGTAB. Return the next character or NULL. */
4090 __parse_dsp_reg (const char *line
, const metag_reg
**reg
, htab_t dsp_regtab
)
4092 const char *l
= line
;
4093 char name
[MAX_REG_LEN
];
4096 const metag_reg
*_reg
;
4098 /* We don't entirely strip the register name because we might
4099 actually want to match whole string in the register table,
4100 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4101 entry limits our comaprison to a reasonable bound anyway. */
4102 while (is_register_char (*l
) || *l
== PLUS
)
4107 if (!(len
< MAX_REG_LEN
))
4117 _reg
= (const metag_reg
*) htab_find (dsp_regtab
, &entry
);
4126 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4127 member is suitable for encoding into a DSP insn register field. */
4129 parse_dsp_insn_reg (const char *line
, const metag_reg
**reg
)
4131 return __parse_dsp_reg (line
, reg
, dsp_reg_htab
);
4134 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4135 member is suitable for encoding into a DSP template definition insn
4138 There is a separate table for whether we're doing a load or a store
4139 definition. "load" specifies which table to look at. */
4141 parse_dsp_template_reg (const char *line
, const metag_reg
**reg
,
4144 return __parse_dsp_reg (line
, reg
, dsp_tmpl_reg_htab
[load
]);
4147 /* Parse a single DSP register from LINE. */
4149 parse_dsp_reg (const char *line
, const metag_reg
**reg
,
4150 bfd_boolean tmpl
, bfd_boolean load
)
4153 return parse_dsp_template_reg (line
, reg
, load
);
4155 return parse_dsp_insn_reg (line
, reg
);
4158 /* Return TRUE if UNIT is an address unit. */
4160 is_addr_unit (enum metag_unit unit
)
4172 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4174 is_same_data_unit (enum metag_unit unit1
, enum metag_unit unit2
)
4182 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
)
4186 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
)
4190 if (unit2
== UNIT_D0
|| unit2
== UNIT_RAM_D0
)
4194 if (unit2
== UNIT_D1
|| unit2
== UNIT_RAM_D1
)
4198 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_D0
)
4202 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_D1
)
4212 /* Return TRUE if the register NUM is a quickrot control register. */
4214 is_quickrot_reg (unsigned int num
)
4226 /* Return TRUE if REG is an accumulator register. */
4228 is_accumulator_reg (const metag_reg
*reg
)
4230 if (reg
->unit
== UNIT_ACC_D0
|| reg
->unit
== UNIT_ACC_D1
)
4236 /* Return TRUE if REG is a DSP RAM register. */
4238 is_dspram_reg (const metag_reg
*reg
)
4240 if (reg
->unit
== UNIT_RAM_D0
|| reg
->unit
== UNIT_RAM_D1
)
4247 __parse_gp_reg (const char *line
, const metag_reg
**reg
, bfd_boolean load
)
4249 const char *l
= line
;
4250 char reg_buf
[MAX_REG_LEN
];
4256 /* Parse [DSPRAM.x]. */
4257 if (*l
== ADDR_BEGIN_CHAR
)
4264 l
= parse_dsp_reg (l
, reg
, TRUE
, load
);
4268 if (*l
== ADDR_END_CHAR
)
4272 as_bad (_("expected ']', not %c in %s"), *l
, l
);
4281 len
= strip_reg_name (l
, reg_buf
);
4286 *reg
= parse_gp_reg (reg_buf
);
4294 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4295 should try to parse the register as a general-purpose register if
4296 we fail to parse it as a DSP one. TMPL indicates whether the
4297 registers are part of a template definition instruction. If this is
4298 a template definition instruction LOAD says whether it's a load
4299 template insn. FIRST_DST indicates whether the first register is
4300 a destination operand. */
4302 parse_dsp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
4303 size_t *regs_read
, bfd_boolean try_gp
, bfd_boolean tmpl
,
4304 bfd_boolean load
, bfd_boolean first_dst
)
4306 const char *l
= line
;
4309 const metag_reg
*reg
;
4311 for (i
= 0; i
< count
; i
++)
4313 const char *next
, *ll
;
4322 *regs_read
= seen_regs
;
4327 ll
= parse_dsp_reg (l
, ®
, tmpl
, load
);
4333 l
= __parse_gp_reg (l
, ®
, !(first_dst
&& i
== 0));
4336 *regs_read
= seen_regs
;
4344 *regs_read
= seen_regs
;
4356 *regs_read
= seen_regs
;
4360 /* Parse the following memory references:
4371 - [DSPRam-DSPRam--] */
4373 parse_dsp_addr (const char *line
, metag_addr
*addr
, unsigned int size
,
4376 const char *l
= line
, *ll
;
4377 const metag_reg
*regs
[1];
4380 /* Skip opening square bracket. */
4383 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4388 if (!is_addr_unit (regs
[0]->unit
) &&
4389 !is_dspram_reg (regs
[0]))
4391 as_bad (_("invalid register for memory access"));
4395 addr
->base_reg
= regs
[0];
4397 if (*l
== ADDR_END_CHAR
)
4399 addr
->exp
.X_op
= O_constant
;
4400 addr
->exp
.X_add_symbol
= NULL
;
4401 addr
->exp
.X_op_symbol
= NULL
;
4403 /* Simple register with no offset (0 immediate). */
4404 addr
->exp
.X_add_number
= 0;
4406 addr
->immediate
= 1;
4412 ll
= parse_addr_post_incr_op (l
, addr
);
4414 if (ll
&& *ll
== ADDR_END_CHAR
)
4416 if (addr
->update
== 1)
4418 /* We have a post increment/decrement. */
4419 addr
->exp
.X_op
= O_constant
;
4420 addr
->exp
.X_add_number
= size
;
4421 addr
->exp
.X_add_symbol
= NULL
;
4422 addr
->exp
.X_op_symbol
= NULL
;
4423 addr
->post_increment
= 1;
4425 addr
->immediate
= 1;
4430 addr
->post_increment
= 0;
4432 l
= parse_addr_op (l
, addr
);
4437 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4442 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
4444 as_bad (_("offset and base must be from the same unit"));
4448 addr
->offset_reg
= regs
[0];
4450 if (*l
== ADDR_END_CHAR
)
4456 l
= parse_addr_post_incr_op (l
, addr
);
4461 if (*l
== ADDR_END_CHAR
)
4470 /* Parse a DSP GET or SET instruction. */
4472 parse_dget_set (const char *line
, metag_insn
*insn
,
4473 const insn_template
*template)
4475 const char *l
= line
;
4479 bfd_boolean is_get
= (template->meta_opcode
& 0x100);
4480 bfd_boolean is_dual
= (template->meta_opcode
& 0x4);
4481 bfd_boolean is_template
= FALSE
;
4482 const metag_reg
*regs
[2];
4484 size_t count
, regs_read
;
4486 memset(&addr
, 0, sizeof(addr
));
4487 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4489 size
= is_dual
? 8 : 4;
4490 count
= is_dual
? 2 : 1;
4494 /* GETL can be used on one template table entry. */
4498 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
,
4499 FALSE
, FALSE
, FALSE
);
4504 as_bad (_("unexpected end of line"));
4508 l
= parse_addr (l
, &addr
, size
);
4512 l
= parse_addr (l
, &addr
, size
);
4519 /* GETL can be used on one template table entry. */
4523 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
, FALSE
,
4530 /* The first register dictates the unit. */
4531 if (regs
[0]->unit
== UNIT_DT
)
4535 if (regs
[0]->unit
== UNIT_D0
|| regs
[0]->unit
== UNIT_RAM_D0
||
4536 regs
[0]->unit
== UNIT_ACC_D0
)
4542 rd_reg
= regs
[0]->no
;
4544 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4545 upper 8-bits of an accumulator. It is _only_ valid for the
4547 if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
)
4549 if (is_template
|| !(rd_reg
>= 16 && rd_reg
< 20))
4551 as_bad (_("'H' modifier only valid for accumulator registers"));
4555 /* Top 8-bits of the accumulator. */
4561 insn
->bits
= (template->meta_opcode
| (1 << 1));
4565 insn
->bits
= (template->meta_opcode
| unit
);
4568 insn
->bits
|= (rd_reg
<< 19);
4572 int offset
= addr
.exp
.X_add_number
;
4577 offset
= offset
/ (int)size
;
4579 if (!within_signed_range (offset
, DGET_SET_IMM_BITS
))
4581 as_bad (_("offset value out of range"));
4585 offset
= offset
& DGET_SET_IMM_MASK
;
4587 insn
->bits
|= (1 << 13);
4588 insn
->bits
|= (offset
<< 9);
4592 int au
= (addr
.base_reg
->unit
== UNIT_A1
);
4594 insn
->bits
|= (au
<< 18);
4595 insn
->bits
|= ((addr
.base_reg
->no
& REG_MASK
) << 14);
4596 insn
->bits
|= ((addr
.offset_reg
->no
& REG_MASK
) << 9);
4600 insn
->bits
|= (1 << 2);
4602 if (!is_addr_unit (addr
.base_reg
->unit
))
4604 as_bad (_("base unit must be either A0 or A1"));
4608 unit
= (addr
.base_reg
->unit
== UNIT_A0
) ? 0 : 1;
4609 insn
->bits
|= ((addr
.base_reg
->no
<< 14) | (unit
<< 18));
4616 /* Parse a DSP template instruction. */
4618 parse_dtemplate (const char *line
, metag_insn
*insn
,
4619 const insn_template
*template)
4621 const char *l
= line
;
4622 const metag_reg
*regs
[TEMPLATE_NUM_REGS
];
4623 bfd_boolean daop_only
= FALSE
;
4625 int regs_which
[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4628 for (i
= 0; i
< TEMPLATE_NUM_REGS
; i
++)
4632 as_bad (_("unexpected end of line"));
4636 /* We may only have 3 register operands. */
4637 if (*l
== END_OF_INSN
&& i
== 3)
4652 l
= parse_imm_constant (l
, insn
, ®s_val
[i
]);
4655 as_bad (_("invalid immediate"));
4662 /* We can't tell from the template instantiation whether
4663 this is a load or store. So we have to try looking up the
4664 register name in both the load and store tables. */
4666 l
= __parse_gp_reg (l
, ®s
[i
], TRUE
);
4669 /* Try the store table too. */
4670 l
= __parse_gp_reg (l2
, ®s
[i
], FALSE
);
4673 /* Then try a DSP register. */
4674 l
= parse_dsp_insn_reg (l2
, ®s
[i
]);
4675 if (l
== NULL
|| regs
[i
]->unit
== UNIT_DT
)
4677 as_bad (_("invalid register"));
4686 insn
->bits
= template->meta_opcode
;
4688 if (regs_which
[0] == 0)
4689 insn
->bits
|= (regs_val
[0] << 19);
4690 else if (regs_which
[0] == 1)
4691 insn
->bits
|= (regs
[0]->no
<< 19);
4693 if (regs_which
[1] == 0)
4694 insn
->bits
|= (regs_val
[1] << 14);
4695 else if (regs_which
[1] == 1)
4696 insn
->bits
|= (regs
[1]->no
<< 14);
4698 if (regs_which
[2] == 0)
4699 insn
->bits
|= (regs_val
[2] << 9);
4700 else if (regs_which
[2] == 1)
4701 insn
->bits
|= (regs
[2]->no
<< 9);
4703 if (regs_which
[3] == 0)
4704 insn
->bits
|= (regs_val
[3] << 4);
4705 else if (regs_which
[3] == 1)
4706 insn
->bits
|= (regs
[3]->no
<< 4);
4710 insn
->bits
|= (0x3 << 24); /* Set the minor opcode. */
4711 else if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
) /* Half Load/Store. */
4712 insn
->bits
|= (0x5 << 24); /* Set the minor opcode. */
4719 /* Parse a DSP Template definiton memory reference, e.g
4720 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4721 template definition is a DSP RAM template definition. */
4723 template_mem_ref(const char *line
, metag_addr
*addr
,
4724 bfd_boolean
*dspram
, int size
, bfd_boolean load
)
4726 const char *l
= line
;
4728 l
= parse_dsp_addr (l
, addr
, size
, load
);
4732 if (is_addr_unit(addr
->base_reg
->unit
))
4741 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4742 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4744 parse_template_regs (const char *line
, bfd_boolean
*load
,
4745 unsigned int *addr_unit
,
4746 const metag_reg
**template_reg
, metag_addr
*addr
,
4747 bfd_boolean
*dspram
, int size
)
4749 const char *l
= line
;
4754 /* DSP Template load definition (Tx, [Ax]) */
4758 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4764 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4766 if (addr
->base_reg
->unit
== UNIT_A1
)
4770 else if (*l
== ADDR_BEGIN_CHAR
) /* DSP Template store ([Ax], Tx) */
4773 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4779 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4783 if (addr
->base_reg
->unit
== UNIT_A1
)
4788 as_bad (_("invalid register operand"));
4795 #define INVALID_SHIFT (-1)
4797 static metag_reg _reg
;
4799 /* Parse a template instruction definition. */
4801 interpret_template_regs(const char *line
, metag_insn
*insn
,
4802 const metag_reg
**regs
,
4803 int *regs_shift
, bfd_boolean
*load
, bfd_boolean
*dspram
,
4804 int size
, int *ls_shift
, int *au_shift
,
4805 unsigned int *au
, int *imm
, int *imm_shift
,
4806 unsigned int *imm_mask
)
4808 const char *l
= line
;
4810 const metag_reg
*template_reg
[1];
4812 memset (&addr
, 0, sizeof(addr
));
4815 regs_shift
[1] = INVALID_SHIFT
;
4817 insn
->bits
|= (1 << 1);
4819 l
= skip_whitespace (l
);
4821 l
= parse_template_regs (l
, load
, au
, template_reg
,
4822 &addr
, dspram
, size
);
4825 as_bad (_("could not parse template definition"));
4829 regs
[2] = template_reg
[0];
4832 /* DSPRAM definition. */
4836 _reg
= *addr
.base_reg
;
4840 /* Set the post-increment bit in the register field. */
4846 /* The bottom bit of the increment register tells us
4847 whether it's increment register 0 or 1. */
4848 if (addr
.offset_reg
->no
& 0x1)
4856 insn
->bits
|= (0x3 << 17); /* This signifies a DSPRAM definition. */
4858 else /* DaOpPaMe definition. */
4860 regs
[0] = addr
.base_reg
;
4863 /* Set the I bit. */
4864 insn
->bits
|= (1 << 18);
4866 if (addr
.update
== 1)
4868 if (addr
.negate
== 1)
4879 /* Setup the offset register. */
4880 regs
[1] = addr
.offset_reg
;
4891 /* Does this combination of units need the O2R bit and can it be encoded? */
4893 units_need_o2r (enum metag_unit unit1
, enum metag_unit unit2
)
4898 if (unit1
== UNIT_D0
|| unit1
== UNIT_ACC_D0
|| unit1
== UNIT_RAM_D0
)
4900 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
|| unit2
== UNIT_D0
)
4915 if (unit1
== UNIT_D1
|| unit1
== UNIT_ACC_D1
|| unit1
== UNIT_RAM_D1
)
4917 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
|| unit2
== UNIT_D1
)
4935 /* Return TRUE if this is a DSP data unit. */
4937 is_dsp_data_unit (const metag_reg
*reg
)
4953 static metag_reg o2r_reg
;
4955 /* Parse a DaOpPaMe load template definition. */
4957 parse_dalu (const char *line
, metag_insn
*insn
,
4958 const insn_template
*template)
4960 const char *l
= line
;
4962 const metag_reg
*regs
[4];
4965 bfd_boolean is_mov
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
;
4966 bfd_boolean is_cmp
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_CMP
) &&
4967 ((template->meta_opcode
& 0xee) == 0));
4968 bfd_boolean is_dual
= (insn
->dsp_width
== DSP_WIDTH_DUAL
);
4969 bfd_boolean is_quickrot64
= ((insn
->dsp_action_flags
& DSP_ACTION_QR64
) != 0);
4970 int l1_shift
= INVALID_SHIFT
;
4971 bfd_boolean load
= FALSE
;
4972 int ls_shift
= INVALID_SHIFT
;
4973 bfd_boolean ar
= FALSE
;
4974 int ar_shift
= INVALID_SHIFT
;
4975 int regs_shift
[3] = { INVALID_SHIFT
, INVALID_SHIFT
, INVALID_SHIFT
};
4977 int imm_shift
= INVALID_SHIFT
;
4978 unsigned int imm_mask
= 0;
4979 unsigned int au
= 0;
4980 int au_shift
= INVALID_SHIFT
;
4981 unsigned int du
= 0;
4982 int du_shift
= INVALID_SHIFT
;
4983 unsigned int sc
= ((insn
->dsp_action_flags
& DSP_ACTION_OV
) != 0);
4984 int sc_shift
= INVALID_SHIFT
;
4985 unsigned int om
= ((insn
->dsp_action_flags
& DSP_ACTION_MOD
) != 0);
4986 int om_shift
= INVALID_SHIFT
;
4987 unsigned int o2r
= 0;
4988 int o2r_shift
= INVALID_SHIFT
;
4989 unsigned int qr
= 0;
4990 int qr_shift
= INVALID_SHIFT
;
4991 int qd_shift
= INVALID_SHIFT
;
4992 unsigned int qn
= 0;
4993 int qn_shift
= INVALID_SHIFT
;
4994 unsigned int a1
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ZERO
)) != 0);
4995 int a1_shift
= INVALID_SHIFT
;
4996 unsigned int a2
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
)) != 0);
4997 int a2_shift
= INVALID_SHIFT
;
4998 unsigned su
= ((insn
->dsp_action_flags
& DSP_ACTION_UMUL
) != 0);
4999 int su_shift
= INVALID_SHIFT
;
5001 int ac_shift
= INVALID_SHIFT
;
5002 unsigned int mx
= (((insn
->dsp_daoppame_flags
& DSP_DAOPPAME_8
) != 0) ||
5003 (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_16
) != 0);
5004 int mx_shift
= INVALID_SHIFT
;
5005 int size
= is_dual
? 8 : 4;
5007 bfd_boolean conditional
= (MINOR_OPCODE (template->meta_opcode
) & 0x4);
5009 /* XFIXME: check the flags are valid with the instruction. */
5010 if (is_quickrot64
&& !(template->arg_type
& DSP_ARGS_QR
))
5012 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5016 insn
->bits
= template->meta_opcode
;
5018 memset (regs
, 0, sizeof (regs
));
5019 memset (&addr
, 0, sizeof (addr
));
5021 /* There are the following forms of DSP ALU instructions,
5024 19. D[T] Op De.r,Dx.r,De.r
5025 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5026 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5027 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5028 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5029 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5030 8. D Opcc De.r,Dx.r,Rx.r
5031 6. D Op De.r,Dx.r,Rx.r|RD
5032 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5033 7. D Op De.e,Dx.r,#I16
5036 4. D[T] Op Dx.r,De.r
5037 10. D Op Dx.r,Rx.r|RD
5040 12. D[T] Op De.r,Dx.r
5041 14. D Op DSPe.r,Dx.r
5042 15. D Op DSPx.r,#I16
5043 16. D Op De.r,DSPx.r
5044 18. D Op De.r,Dx.r|ACx.r
5047 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5048 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5049 21. D Op De.r,Dx.r|ACx.r,#I5 */
5052 if (template->arg_type
& DSP_ARGS_1
)
5056 /* Could this be a cross-unit accumulator op,
5057 e.g. ACe.e,ACx.r,ACo.e */
5058 if (template->arg_type
& DSP_ARGS_XACC
)
5060 ll
= parse_dsp_regs_list (l
, regs
, 3, ®s_read
, FALSE
, FALSE
,
5062 if (ll
!= NULL
&& regs_read
== 3
5063 && is_accumulator_reg (regs
[0]))
5065 if (regs
[0]->unit
!= regs
[1]->unit
||
5066 regs
[2]->unit
== regs
[1]->unit
)
5068 as_bad (_("invalid operands for cross-unit op"));
5072 du
= (regs
[1]->unit
== UNIT_ACC_D1
);
5076 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5077 insn
->bits
|= (5 << 6);
5079 goto check_for_template
;
5082 /* If we reach here, this instruction is not a
5083 cross-unit accumulator op. */
5086 if (template->arg_type
& DSP_ARGS_SPLIT8
)
5093 /* De.r|ACe.r,Dx.r,De.r */
5094 if (template->arg_type
& DSP_ARGS_DACC
)
5096 /* XFIXME: these need moving? */
5102 ll
= parse_dsp_reg (l
, ®s
[0], FALSE
, FALSE
);
5105 /* Using ACe.r as the dst requires one of the P,N or Z
5106 flags to be used. */
5107 if (!(insn
->dsp_action_flags
&
5108 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5110 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5116 l
= parse_dsp_regs_list (l
, ®s
[1], 2, ®s_read
,
5117 TRUE
, FALSE
, FALSE
, FALSE
);
5118 if (l
== NULL
|| regs_read
!= 2)
5120 as_bad (_("invalid register"));
5124 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5130 goto check_for_template
;
5133 /* If we reach here, this instruction does not use the
5134 accumulator as the destination register. */
5135 if ((insn
->dsp_action_flags
&
5136 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5138 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5146 l
= parse_dsp_regs_list (l
, regs
, 2, ®s_read
, TRUE
, FALSE
, FALSE
, TRUE
);
5147 if (l
== NULL
|| regs_read
!= 2)
5154 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5157 if (is_accumulator_reg(regs
[0]) && !(template->arg_type
& DSP_ARGS_DACC
))
5159 as_bad (_("accumulator not a valid destination"));
5163 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5166 l
= parse_imm16 (l
, insn
, &imm
);
5169 as_bad (_("invalid immediate value"));
5173 if (!within_signed_range (imm
, IMM16_BITS
))
5175 as_bad (_("immediate value out of range"));
5179 if (regs
[0]->unit
!= regs
[1]->unit
|| regs
[0]->no
!= regs
[1]->no
)
5181 as_bad (_("immediate value not allowed when source & dest differ"));
5189 insn
->bits
|= (1 << 25);
5191 insn
->bits
|= (0x3 << 0);
5195 /* Remove any bits that have been set in the immediate
5197 insn
->bits
&= ~(imm_mask
<< imm_shift
);
5205 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5206 ll
= parse_dsp_reg (l
, ®s
[2], FALSE
, FALSE
);
5211 if (!(template->arg_type
& DSP_ARGS_ACC2
))
5213 as_bad (_("invalid register operand: %s"), regs
[2]->name
);
5223 /* De.r,Dx.r,De.r */
5224 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5229 if (template->arg_type
& DSP_ARGS_ACC2
)
5232 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5233 if (template->arg_type
& DSP_ARGS_QR
)
5247 as_bad (_("QUICKRoT extension requires 4 registers"));
5251 l
= __parse_gp_reg (l
, ®s
[3], TRUE
);
5254 as_bad (_("invalid fourth register"));
5258 if (!is_addr_unit (regs
[3]->unit
) ||
5259 !is_quickrot_reg (regs
[3]->no
))
5261 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5265 qn
= (regs
[3]->no
== 3);
5270 /* This is the common exit path. Check for o2r. */
5271 if (regs
[2] != NULL
)
5273 o2r
= units_need_o2r (regs
[1]->unit
, regs
[2]->unit
);
5276 o2r_reg
.no
= lookup_o2r (0, du
, regs
[2]);
5277 o2r_reg
.unit
= regs
[2]->unit
;
5282 /* Check any DSP RAM pointers are valid for this unit. */
5283 if ((du
&& (regs
[0]->unit
== UNIT_RAM_D0
)) ||
5284 (!du
&& (regs
[0]->unit
== UNIT_RAM_D1
)) ||
5285 (du
&& (regs
[1]->unit
== UNIT_RAM_D0
)) ||
5286 (!du
&& (regs
[1]->unit
== UNIT_RAM_D1
)) ||
5287 (du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D0
)) ||
5288 (!du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D1
))) {
5289 as_bad (_("DSP RAM pointer in incorrect unit"));
5293 /* Is this a template definition? */
5294 if (IS_TEMPLATE_DEF (insn
))
5296 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5297 &dspram
, size
, &ls_shift
, &au_shift
,
5298 &au
, &imm
, &imm_shift
, &imm_mask
);
5311 if (template->arg_type
& DSP_ARGS_2
)
5313 bfd_boolean is_xsd
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
) &&
5314 (MINOR_OPCODE (template->meta_opcode
) == 0xa));
5315 bfd_boolean is_fpu_mov
= template->insn_type
== INSN_DSP_FPU
;
5316 bfd_boolean to_fpu
= (template->meta_opcode
>> 7) & 0x1;
5325 /* CMPs and TSTs don't store to their destination operand. */
5326 ll
= __parse_gp_reg (l
, regs
, is_cmp
);
5329 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5330 if (template->arg_type
& DSP_ARGS_DSP_SRC1
)
5332 l
= parse_dsp_reg (l
, regs
, FALSE
, FALSE
);
5335 as_bad (_("invalid register operand #1"));
5339 /* Only MOV instructions have a DSP register as a
5340 destination. Set the MOV DSPe.r opcode. The simple
5341 OR'ing is OK because the usual MOV opcode is 0x00. */
5342 insn
->bits
= (0x91 << 24);
5349 as_bad (_("invalid register operand #2"));
5357 /* Everything but CMP and TST. */
5358 if (MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
5359 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5360 MAJOR_OPCODE (insn
->bits
) == OPC_9
||
5361 MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
||
5362 ((template->meta_opcode
& 0x0000002c) != 0))
5368 if (!is_dsp_data_unit (regs
[0]) && !(regs
[0]->unit
== UNIT_FX
&&
5369 is_fpu_mov
&& to_fpu
))
5372 du
= (regs
[0]->unit
== UNIT_D1
|| regs
[0]->unit
== UNIT_RAM_D1
||
5373 regs
[0]->unit
== UNIT_ACC_D1
);
5379 if (template->arg_type
& DSP_ARGS_IMM
&&
5380 !(is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)))
5382 l
= parse_imm16 (l
, insn
, &imm
);
5385 as_bad (_("invalid immediate value"));
5389 if (!within_signed_range (imm
, IMM16_BITS
))
5398 /* Set the I-bit unless it's a MOV because they're
5400 if (!(is_mov
&& MAJOR_OPCODE (insn
->bits
) == OPC_9
))
5401 insn
->bits
|= (1 << 25);
5403 /* All instructions that takes immediates also have bit 1 set. */
5404 insn
->bits
|= (1 << 1);
5406 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5407 insn
->bits
|= (1 << 0);
5409 insn
->bits
&= ~(1 << 8);
5413 as_bad (_("this instruction does not accept an immediate"));
5419 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5421 insn
->bits
|= (1 << 8);
5425 ll
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5428 if (template->arg_type
& DSP_ARGS_DSP_SRC2
)
5430 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5433 as_bad (_("invalid register operand #3"));
5438 if ((is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)) ||
5439 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
)
5441 if (is_accumulator_reg (regs
[1]))
5445 as_bad (_("this instruction does not accept an accumulator"));
5457 insn
->bits
= (0x92 << 24); /* Set opcode. */
5463 as_bad (_("invalid register operand #4"));
5469 /* Set the o2r bit if required. */
5470 if (!is_fpu_mov
&& units_need_o2r (regs
[0]->unit
, regs
[1]->unit
))
5473 o2r_reg
.no
= lookup_o2r (0, du
, regs
[1]);
5478 else if (!is_dsp_data_unit (regs
[1]) &&
5479 !(is_fpu_mov
&& !to_fpu
&& regs
[1]->unit
== UNIT_FX
))
5482 if (is_fpu_mov
&& to_fpu
)
5483 du
= (regs
[1]->unit
== UNIT_D1
||
5484 regs
[1]->unit
== UNIT_RAM_D1
||
5485 regs
[1]->unit
== UNIT_ACC_D1
);
5489 if (MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5490 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5491 (((template->meta_opcode
& 0x0000002c) == 0) &&
5492 MAJOR_OPCODE (template->meta_opcode
) != OPC_MISC
))
5499 /* If it's an 0x0 MOV or NEG set some lower bits. */
5500 if ((MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5501 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) && !is_fpu_mov
)
5505 insn
->bits
|= (1 << 2);
5508 /* Check for template definitons. */
5509 if (IS_TEMPLATE_DEF (insn
))
5511 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5512 &dspram
, size
, &ls_shift
, &au_shift
,
5513 &au
, &imm
, &imm_shift
, &imm_mask
);
5526 l
= __parse_gp_reg (l
, regs
, FALSE
);
5529 as_bad (_("invalid register operand"));
5537 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5540 as_bad (_("invalid accumulator register"));
5548 l
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5551 as_bad (_("invalid register operand"));
5559 du
= (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_ACC_D1
5560 || regs
[1]->unit
== UNIT_RAM_D1
);
5566 l
= parse_imm_constant (l
, insn
, &imm
);
5569 as_bad (_("invalid immediate value"));
5573 if (!within_unsigned_range (imm
, IMM5_BITS
))
5580 insn
->bits
|= (1 << 25);
5585 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5590 /* Check for post-processing R,G,B flags. Conditional instructions
5591 do not have these bits. */
5592 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP9
)
5594 if ((template->meta_opcode
>> 26) & 0x1)
5596 as_bad (_("conditional instruction cannot use G flag"));
5600 insn
->bits
|= (1 << 3);
5603 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP8
)
5605 if ((template->meta_opcode
>> 26) & 0x1)
5607 as_bad (_("conditional instruction cannot use B flag"));
5611 insn
->bits
|= (0x3 << 2);
5614 if (insn
->dsp_action_flags
& DSP_ACTION_ROUND
)
5616 if ((template->meta_opcode
>> 26) & 0x1)
5618 as_bad (_("conditional instruction cannot use R flag"));
5621 insn
->bits
|= (1 << 2);
5624 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5625 if ((template->meta_opcode
>> 26) & 0x1)
5626 ls_shift
= INVALID_SHIFT
;
5628 /* The Condition Is Always (CA) bit must be set if we're targetting a
5629 Ux.r register as the destination. This means that we can't have
5630 any other condition bits set. */
5631 if (!is_same_data_unit (regs
[1]->unit
, regs
[0]->unit
))
5633 /* Set both the Conditional bit and the Condition is Always bit. */
5634 insn
->bits
|= (1 << 26);
5635 insn
->bits
|= (1 << 5);
5637 /* Fill out the Ud field. */
5638 insn
->bits
|= (regs
[0]->unit
<< 1);
5641 if (IS_TEMPLATE_DEF (insn
))
5643 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5644 &dspram
, size
, &ls_shift
, &au_shift
,
5645 &au
, &imm
, &imm_shift
, &imm_mask
);
5657 /* Set the registers and immediate values. */
5658 if (regs_shift
[0] != INVALID_SHIFT
)
5659 insn
->bits
|= (regs
[0]->no
<< regs_shift
[0]);
5661 if (regs_shift
[1] != INVALID_SHIFT
)
5662 insn
->bits
|= (regs
[1]->no
<< regs_shift
[1]);
5664 if (regs_shift
[2] != INVALID_SHIFT
)
5665 insn
->bits
|= (regs
[2]->no
<< regs_shift
[2]);
5667 /* Does this insn have an 'IMM' bit? The immediate value should
5668 already have been masked. */
5669 if (imm_shift
!= INVALID_SHIFT
)
5670 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5672 /* Does this insn have an 'AU' bit? */
5673 if (au_shift
!= INVALID_SHIFT
)
5674 insn
->bits
|= (au
<< au_shift
);
5676 /* Does this instruction have an 'LS' bit? */
5677 if (ls_shift
!= INVALID_SHIFT
)
5678 insn
->bits
|= (load
<< ls_shift
);
5680 /* Does this instruction have an 'AR' bit? */
5682 insn
->bits
|= (1 << ar_shift
);
5684 if (du_shift
!= INVALID_SHIFT
)
5685 insn
->bits
|= (du
<< du_shift
);
5687 if (sc_shift
!= INVALID_SHIFT
)
5688 insn
->bits
|= (sc
<< sc_shift
);
5690 if (om_shift
!= INVALID_SHIFT
)
5691 insn
->bits
|= (om
<< om_shift
);
5693 if (o2r_shift
!= INVALID_SHIFT
)
5694 insn
->bits
|= (o2r
<< o2r_shift
);
5696 if (qn_shift
!= INVALID_SHIFT
)
5697 insn
->bits
|= (qn
<< qn_shift
);
5699 if (qr_shift
!= INVALID_SHIFT
)
5700 insn
->bits
|= (qr
<< qr_shift
);
5702 if (qd_shift
!= INVALID_SHIFT
)
5703 insn
->bits
|= (is_quickrot64
<< qd_shift
);
5705 if (a1_shift
!= INVALID_SHIFT
)
5706 insn
->bits
|= (a1
<< a1_shift
);
5708 if (a2_shift
!= INVALID_SHIFT
)
5709 insn
->bits
|= (a2
<< a2_shift
);
5711 if (su_shift
!= INVALID_SHIFT
)
5712 insn
->bits
|= (su
<< su_shift
);
5714 if (imm_shift
!= INVALID_SHIFT
)
5715 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5717 if (ac_shift
!= INVALID_SHIFT
)
5718 insn
->bits
|= (ac
<< ac_shift
);
5720 if (mx_shift
!= INVALID_SHIFT
)
5721 insn
->bits
|= (mx
<< mx_shift
);
5725 if (l1_shift
== INVALID_SHIFT
)
5727 as_bad (_("'L' modifier not valid for this instruction"));
5731 insn
->bits
|= (1 << l1_shift
);
5739 typedef const char *(*insn_parser
)(const char *, metag_insn
*,
5740 const insn_template
*);
5743 static const insn_parser insn_parsers
[ENC_MAX
] =
5745 [ENC_NONE
] = parse_none
,
5746 [ENC_MOV_U2U
] = parse_mov_u2u
,
5747 [ENC_MOV_PORT
] = parse_mov_port
,
5748 [ENC_MMOV
] = parse_mmov
,
5749 [ENC_MDRD
] = parse_mdrd
,
5750 [ENC_MOVL_TTREC
] = parse_movl_ttrec
,
5751 [ENC_GET_SET
] = parse_get_set
,
5752 [ENC_GET_SET_EXT
] = parse_get_set_ext
,
5753 [ENC_MGET_MSET
] = parse_mget_mset
,
5754 [ENC_COND_SET
] = parse_cond_set
,
5755 [ENC_XFR
] = parse_xfr
,
5756 [ENC_MOV_CT
] = parse_mov_ct
,
5757 [ENC_SWAP
] = parse_swap
,
5758 [ENC_JUMP
] = parse_jump
,
5759 [ENC_CALLR
] = parse_callr
,
5760 [ENC_ALU
] = parse_alu
,
5761 [ENC_SHIFT
] = parse_shift
,
5762 [ENC_MIN_MAX
] = parse_min_max
,
5763 [ENC_BITOP
] = parse_bitop
,
5764 [ENC_CMP
] = parse_cmp
,
5765 [ENC_BRANCH
] = parse_branch
,
5766 [ENC_KICK
] = parse_kick
,
5767 [ENC_SWITCH
] = parse_switch
,
5768 [ENC_CACHER
] = parse_cacher
,
5769 [ENC_CACHEW
] = parse_cachew
,
5770 [ENC_ICACHE
] = parse_icache
,
5771 [ENC_LNKGET
] = parse_lnkget
,
5772 [ENC_FMOV
] = parse_fmov
,
5773 [ENC_FMMOV
] = parse_fmmov
,
5774 [ENC_FMOV_DATA
] = parse_fmov_data
,
5775 [ENC_FMOV_I
] = parse_fmov_i
,
5776 [ENC_FPACK
] = parse_fpack
,
5777 [ENC_FSWAP
] = parse_fswap
,
5778 [ENC_FCMP
] = parse_fcmp
,
5779 [ENC_FMINMAX
] = parse_fminmax
,
5780 [ENC_FCONV
] = parse_fconv
,
5781 [ENC_FCONVX
] = parse_fconvx
,
5782 [ENC_FBARITH
] = parse_fbarith
,
5783 [ENC_FEARITH
] = parse_fearith
,
5784 [ENC_FREC
] = parse_frec
,
5785 [ENC_FSIMD
] = parse_fsimd
,
5786 [ENC_FGET_SET_ACF
] = parse_fget_set_acf
,
5787 [ENC_DGET_SET
] = parse_dget_set
,
5788 [ENC_DTEMPLATE
] = parse_dtemplate
,
5789 [ENC_DALU
] = parse_dalu
,
5792 struct metag_core_option
5798 /* CPU type options. */
5799 static const struct metag_core_option metag_cpus
[] =
5801 {"all", CoreMeta11
|CoreMeta12
|CoreMeta21
},
5802 {"metac11", CoreMeta11
},
5803 {"metac12", CoreMeta12
},
5804 {"metac21", CoreMeta21
},
5808 /* FPU type options. */
5809 static const struct metag_core_option metag_fpus
[] =
5811 {"metac21", FpuMeta21
},
5815 /* DSP type options. */
5816 static const struct metag_core_option metag_dsps
[] =
5818 {"metac21", DspMeta21
},
5822 /* Parse a CPU command line option. */
5824 metag_parse_cpu (char * str
)
5826 const struct metag_core_option
* opt
;
5829 optlen
= strlen (str
);
5833 as_bad (_("missing cpu name `%s'"), str
);
5837 for (opt
= metag_cpus
; opt
->name
!= NULL
; opt
++)
5838 if (strncmp (opt
->name
, str
, optlen
) == 0)
5840 mcpu_opt
= opt
->value
;
5844 as_bad (_("unknown cpu `%s'"), str
);
5848 /* Parse an FPU command line option. */
5850 metag_parse_fpu (char * str
)
5852 const struct metag_core_option
* opt
;
5855 optlen
= strlen (str
);
5859 as_bad (_("missing fpu name `%s'"), str
);
5863 for (opt
= metag_fpus
; opt
->name
!= NULL
; opt
++)
5864 if (strncmp (opt
->name
, str
, optlen
) == 0)
5866 mfpu_opt
= opt
->value
;
5870 as_bad (_("unknown fpu `%s'"), str
);
5874 /* Parse a DSP command line option. */
5876 metag_parse_dsp (char * str
)
5878 const struct metag_core_option
* opt
;
5881 optlen
= strlen (str
);
5885 as_bad (_("missing DSP name `%s'"), str
);
5889 for (opt
= metag_dsps
; opt
->name
!= NULL
; opt
++)
5890 if (strncmp (opt
->name
, str
, optlen
) == 0)
5892 mdsp_opt
= opt
->value
;
5896 as_bad (_("unknown DSP `%s'"), str
);
5900 struct metag_long_option
5902 char * option
; /* Substring to match. */
5903 char * help
; /* Help information. */
5904 int (* func
) (char * subopt
); /* Function to decode sub-option. */
5905 char * deprecated
; /* If non-null, print this message. */
5908 struct metag_long_option metag_long_opts
[] =
5910 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5911 metag_parse_cpu
, NULL
},
5912 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5913 metag_parse_fpu
, NULL
},
5914 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5915 metag_parse_dsp
, NULL
},
5916 {NULL
, NULL
, 0, NULL
}
5920 md_parse_option (int c
, char * arg
)
5922 struct metag_long_option
*lopt
;
5924 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5926 /* These options are expected to have an argument. */
5927 if (c
== lopt
->option
[0]
5929 && strncmp (arg
, lopt
->option
+ 1,
5930 strlen (lopt
->option
+ 1)) == 0)
5933 /* If the option is deprecated, tell the user. */
5934 if (lopt
->deprecated
!= NULL
)
5935 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
5936 _(lopt
->deprecated
));
5939 /* Call the sup-option parser. */
5940 return lopt
->func (arg
+ strlen (lopt
->option
) - 1);
5948 md_show_usage (FILE * stream
)
5950 struct metag_long_option
*lopt
;
5952 fprintf (stream
, _(" Meta specific command line options:\n"));
5954 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5955 if (lopt
->help
!= NULL
)
5956 fprintf (stream
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
5959 /* The target specific pseudo-ops which we support. */
5960 const pseudo_typeS md_pseudo_table
[] =
5962 { "word", cons
, 2 },
5971 for (c
= 0; c
< 256; c
++)
5975 register_chars
[c
] = c
;
5976 /* LOCK0, LOCK1, LOCK2. */
5977 mnemonic_chars
[c
] = c
;
5979 else if (ISLOWER (c
))
5981 register_chars
[c
] = c
;
5982 mnemonic_chars
[c
] = c
;
5984 else if (ISUPPER (c
))
5986 register_chars
[c
] = c
;
5987 mnemonic_chars
[c
] = c
;
5991 register_chars
[c
] = c
;
5996 /* Parse a split condition code prefix. */
5998 parse_split_condition (const char *line
, metag_insn
*insn
)
6000 const char *l
= line
;
6001 const split_condition
*scond
;
6002 split_condition entry
;
6010 scond
= (const split_condition
*) htab_find (scond_htab
, &entry
);
6015 insn
->scond
= scond
->code
;
6017 return l
+ strlen (scond
->name
);
6020 /* Parse an instruction prefix - F for float, D for DSP - and associated
6021 flags and condition codes. */
6023 parse_prefix (const char *line
, metag_insn
*insn
)
6025 const char *l
= line
;
6027 l
= skip_whitespace (l
);
6029 insn
->type
= INSN_GP
;
6031 if (TOLOWER (*l
) == FPU_PREFIX_CHAR
)
6033 if (strncasecmp (l
, FFB_INSN
, strlen(FFB_INSN
)))
6035 insn
->type
= INSN_FPU
;
6039 if (*l
== END_OF_INSN
)
6041 as_bad (_("premature end of floating point prefix"));
6045 if (TOLOWER (*l
) == FPU_DOUBLE_CHAR
)
6047 insn
->fpu_width
= FPU_WIDTH_DOUBLE
;
6050 else if (TOLOWER (*l
) == FPU_PAIR_CHAR
)
6054 /* Check this isn't a split condition beginning with L. */
6055 l2
= parse_split_condition (l2
, insn
);
6057 if (l2
&& is_whitespace_char (*l2
))
6063 insn
->fpu_width
= FPU_WIDTH_PAIR
;
6069 insn
->fpu_width
= FPU_WIDTH_SINGLE
;
6072 if (TOLOWER (*l
) == FPU_ACTION_ABS_CHAR
)
6074 insn
->fpu_action_flags
|= FPU_ACTION_ABS
;
6077 else if (TOLOWER (*l
) == FPU_ACTION_INV_CHAR
)
6079 insn
->fpu_action_flags
|= FPU_ACTION_INV
;
6083 if (TOLOWER (*l
) == FPU_ACTION_QUIET_CHAR
)
6085 insn
->fpu_action_flags
|= FPU_ACTION_QUIET
;
6089 if (TOLOWER (*l
) == FPU_ACTION_ZERO_CHAR
)
6091 insn
->fpu_action_flags
|= FPU_ACTION_ZERO
;
6095 if (! is_whitespace_char (*l
))
6097 l
= parse_split_condition (l
, insn
);
6101 as_bad (_("unknown floating point prefix character"));
6109 else if (TOLOWER (*l
) == DSP_PREFIX_CHAR
)
6111 if (strncasecmp (l
, DCACHE_INSN
, strlen (DCACHE_INSN
)) &&
6112 strncasecmp (l
, DEFR_INSN
, strlen (DEFR_INSN
)))
6115 insn
->type
= INSN_DSP
;
6119 insn
->dsp_width
= DSP_WIDTH_SINGLE
;
6121 while (!is_whitespace_char (*l
))
6123 /* We have to check for split condition codes first
6124 because they are the longest strings to match,
6125 e.g. if the string contains "LLS" we want it to match
6126 the split condition code "LLS", not the dual unit
6129 l
= parse_split_condition (l
, insn
);
6136 /* Accept an FPU prefix char which may be used when doing
6137 template MOV with FPU registers. */
6138 if (TOLOWER(*l
) == FPU_PREFIX_CHAR
)
6140 insn
->type
= INSN_DSP_FPU
;
6145 if (TOLOWER(*l
) == DSP_DUAL_CHAR
)
6147 insn
->dsp_width
= DSP_WIDTH_DUAL
;
6152 if (TOLOWER(*l
) == DSP_ACTION_QR64_CHAR
)
6154 insn
->dsp_action_flags
|= DSP_ACTION_QR64
;
6159 if (TOLOWER(*l
) == DSP_ACTION_UMUL_CHAR
)
6161 insn
->dsp_action_flags
|= DSP_ACTION_UMUL
;
6166 if (TOLOWER(*l
) == DSP_ACTION_ROUND_CHAR
)
6168 insn
->dsp_action_flags
|= DSP_ACTION_ROUND
;
6173 if (TOLOWER(*l
) == DSP_ACTION_CLAMP9_CHAR
)
6175 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP9
;
6180 if (TOLOWER(*l
) == DSP_ACTION_CLAMP8_CHAR
)
6182 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP8
;
6187 if (TOLOWER(*l
) == DSP_ACTION_MOD_CHAR
)
6189 insn
->dsp_action_flags
|= DSP_ACTION_MOD
;
6194 if (TOLOWER(*l
) == DSP_ACTION_ACC_ZERO_CHAR
)
6196 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ZERO
;
6201 if (TOLOWER(*l
) == DSP_ACTION_ACC_ADD_CHAR
)
6203 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ADD
;
6208 if (TOLOWER(*l
) == DSP_ACTION_ACC_SUB_CHAR
)
6210 insn
->dsp_action_flags
|= DSP_ACTION_ACC_SUB
;
6215 if (TOLOWER(*l
) == DSP_ACTION_OV_CHAR
)
6217 insn
->dsp_action_flags
|= DSP_ACTION_OV
;
6222 if (TOLOWER(*l
) == DSP_DAOPPAME_8_CHAR
)
6224 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_8
;
6229 if (TOLOWER(*l
) == DSP_DAOPPAME_16_CHAR
)
6231 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_16
;
6236 if (TOLOWER(*l
) == DSP_DAOPPAME_TEMP_CHAR
)
6238 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_TEMP
;
6243 if (TOLOWER(*l
) == DSP_DAOPPAME_HIGH_CHAR
)
6245 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_HIGH
;
6250 as_bad (_("unknown DSP prefix character %c %s"), *l
, l
);
6261 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6262 static insn_templates
*
6263 find_insn_templates (const char *mnemonic
)
6265 insn_template
template;
6266 insn_templates entry
;
6267 insn_templates
*slot
;
6269 entry
.template = &template;
6271 memcpy ((void *)&entry
.template->name
, &mnemonic
, sizeof (char *));
6273 slot
= (insn_templates
*) htab_find (mnemonic_htab
, &entry
);
6281 /* Make an uppercase copy of SRC into DST and return DST. */
6283 strupper (char * dst
, const char *src
)
6289 dst
[i
] = TOUPPER (src
[i
]);
6298 /* Calculate a hash value for a template. */
6300 hash_templates (const void *p
)
6302 insn_templates
*tp
= (insn_templates
*)p
;
6303 char buf
[MAX_MNEMONIC_LEN
];
6305 strupper (buf
, tp
->template->name
);
6307 return htab_hash_string (buf
);
6310 /* Check if two templates are equal. */
6312 eq_templates (const void *a
, const void *b
)
6314 insn_templates
*ta
= (insn_templates
*)a
;
6315 insn_templates
*tb
= (insn_templates
*)b
;
6316 return strcasecmp (ta
->template->name
, tb
->template->name
) == 0;
6319 /* Create the hash table required for parsing instructions. */
6321 create_mnemonic_htab (void)
6323 size_t i
, num_templates
= sizeof(metag_optab
)/sizeof(metag_optab
[0]);
6325 mnemonic_htab
= htab_create_alloc (num_templates
, hash_templates
,
6326 eq_templates
, NULL
, xcalloc
, free
);
6328 for (i
= 0; i
< num_templates
; i
++)
6330 const insn_template
*template = &metag_optab
[i
];
6331 insn_templates
**slot
= NULL
;
6332 insn_templates
*new_entry
;
6334 new_entry
= xmalloc (sizeof (insn_templates
));
6336 new_entry
->template = template;
6337 new_entry
->next
= NULL
;
6339 slot
= (insn_templates
**) htab_find_slot (mnemonic_htab
, new_entry
,
6344 insn_templates
*last_entry
= *slot
;
6346 while (last_entry
->next
)
6347 last_entry
= last_entry
->next
;
6349 last_entry
->next
= new_entry
;
6358 /* Calculate a hash value for a register. */
6360 hash_regs (const void *p
)
6362 metag_reg
*rp
= (metag_reg
*)p
;
6363 char buf
[MAX_REG_LEN
];
6365 strupper (buf
, rp
->name
);
6367 return htab_hash_string (buf
);
6370 /* Check if two registers are equal. */
6372 eq_regs (const void *a
, const void *b
)
6374 metag_reg
*ra
= (metag_reg
*)a
;
6375 metag_reg
*rb
= (metag_reg
*)b
;
6376 return strcasecmp (ra
->name
, rb
->name
) == 0;
6379 /* Create the hash table required for parsing registers. */
6381 create_reg_htab (void)
6383 size_t i
, num_regs
= sizeof(metag_regtab
)/sizeof(metag_regtab
[0]);
6385 reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6386 eq_regs
, NULL
, xcalloc
, free
);
6388 for (i
= 0; i
< num_regs
; i
++)
6390 const metag_reg
*reg
= &metag_regtab
[i
];
6391 const metag_reg
**slot
;
6393 slot
= (const metag_reg
**) htab_find_slot (reg_htab
, reg
, INSERT
);
6400 /* Create the hash table required for parsing DSP registers. */
6402 create_dspreg_htabs (void)
6404 size_t i
, num_regs
= sizeof(metag_dsp_regtab
)/sizeof(metag_dsp_regtab
[0]);
6407 dsp_reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6408 eq_regs
, NULL
, xcalloc
, free
);
6410 for (i
= 0; i
< num_regs
; i
++)
6412 const metag_reg
*reg
= &metag_dsp_regtab
[i
];
6413 const metag_reg
**slot
;
6415 slot
= (const metag_reg
**) htab_find_slot (dsp_reg_htab
, reg
, INSERT
);
6417 /* Make sure there are no hash table collisions, which would
6418 require chaining entries. */
6419 BFD_ASSERT (*slot
== NULL
);
6423 num_regs
= sizeof(metag_dsp_tmpl_regtab
[0])/sizeof(metag_dsp_tmpl_regtab
[0][0]);
6425 for (h
= 0; h
< 2; h
++)
6427 dsp_tmpl_reg_htab
[h
] = htab_create_alloc (num_regs
, hash_regs
,
6428 eq_regs
, NULL
, xcalloc
, free
);
6431 for (h
= 0; h
< 2; h
++)
6433 for (i
= 0; i
< num_regs
; i
++)
6435 const metag_reg
*reg
= &metag_dsp_tmpl_regtab
[h
][i
];
6436 const metag_reg
**slot
;
6437 slot
= (const metag_reg
**) htab_find_slot (dsp_tmpl_reg_htab
[h
],
6440 /* Make sure there are no hash table collisions, which would
6441 require chaining entries. */
6442 BFD_ASSERT (*slot
== NULL
);
6448 /* Calculate a hash value for a split condition code. */
6450 hash_scond (const void *p
)
6452 split_condition
*cp
= (split_condition
*)p
;
6455 strupper (buf
, cp
->name
);
6457 return htab_hash_string (buf
);
6460 /* Check if two split condition codes are equal. */
6462 eq_scond (const void *a
, const void *b
)
6464 split_condition
*ra
= (split_condition
*)a
;
6465 split_condition
*rb
= (split_condition
*)b
;
6467 return strcasecmp (ra
->name
, rb
->name
) == 0;
6470 /* Create the hash table required for parsing split condition codes. */
6472 create_scond_htab (void)
6476 nentries
= sizeof (metag_scondtab
) / sizeof (metag_scondtab
[0]);
6478 scond_htab
= htab_create_alloc (nentries
, hash_scond
, eq_scond
,
6479 NULL
, xcalloc
, free
);
6480 for (i
= 0; i
< nentries
; i
++)
6482 const split_condition
*scond
= &metag_scondtab
[i
];
6483 const split_condition
**slot
;
6485 slot
= (const split_condition
**) htab_find_slot (scond_htab
,
6487 /* Make sure there are no hash table collisions, which would
6488 require chaining entries. */
6489 BFD_ASSERT (*slot
== NULL
);
6494 /* Entry point for instruction parsing. */
6496 parse_insn (const char *line
, metag_insn
*insn
)
6498 char mnemonic
[MAX_MNEMONIC_LEN
];
6499 const char *l
= line
;
6500 size_t mnemonic_len
= 0;
6501 insn_templates
*templates
;
6505 while (is_mnemonic_char(*l
))
6511 if (mnemonic_len
>= MAX_MNEMONIC_LEN
)
6513 as_bad (_("instruction mnemonic too long: %s"), line
);
6517 strncpy(mnemonic
, line
, mnemonic_len
);
6519 mnemonic
[mnemonic_len
] = '\0';
6521 templates
= find_insn_templates (mnemonic
);
6525 insn_templates
*current_template
= templates
;
6529 while (current_template
)
6531 const insn_template
*template = current_template
->template;
6532 enum insn_encoding encoding
= template->encoding
;
6533 insn_parser parser
= insn_parsers
[encoding
];
6535 current_template
= current_template
->next
;
6537 if (template->insn_type
== INSN_GP
&&
6538 !(template->core_flags
& mcpu_opt
))
6541 if (template->insn_type
== INSN_FPU
&&
6542 !(template->core_flags
& mfpu_opt
))
6545 if (template->insn_type
== INSN_DSP
&&
6546 !(template->core_flags
& mdsp_opt
))
6549 if (template->insn_type
== INSN_DSP_FPU
&&
6550 !((template->core_flags
& mdsp_opt
) &&
6551 (template->core_flags
& mfpu_opt
)))
6554 /* DSP instructions always require special decoding */
6555 if ((insn
->type
== INSN_DSP
&& (template->insn_type
!= INSN_DSP
)) ||
6556 ((template->insn_type
== INSN_DSP
) && insn
->type
!= INSN_DSP
) ||
6557 (insn
->type
== INSN_DSP_FPU
&& (template->insn_type
!= INSN_DSP_FPU
)) ||
6558 ((template->insn_type
== INSN_DSP_FPU
) && insn
->type
!= INSN_DSP_FPU
))
6563 const char *end
= parser(l
, insn
, template);
6567 if (*end
!= END_OF_INSN
)
6568 as_bad (_("junk at end of line: \"%s\""), line
);
6575 as_bad (_("failed to assemble instruction: \"%s\""), line
);
6579 if (insn
->type
== INSN_FPU
)
6580 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic
);
6582 as_bad (_("unknown mnemonic: \"%s\""), mnemonic
);
6588 output_insn (metag_insn
*insn
)
6592 output
= frag_more (insn
->len
);
6593 dwarf2_emit_insn (insn
->len
);
6595 if (insn
->reloc_type
!= BFD_RELOC_UNUSED
)
6597 fix_new_exp (frag_now
, output
- frag_now
->fr_literal
,
6598 insn
->reloc_size
, &insn
->reloc_exp
,
6599 insn
->reloc_pcrel
, insn
->reloc_type
);
6602 md_number_to_chars (output
, insn
->bits
, insn
->len
);
6606 md_assemble (char *line
)
6608 const char *l
= line
;
6611 memset (&insn
, 0, sizeof(insn
));
6613 insn
.reloc_type
= BFD_RELOC_UNUSED
;
6614 insn
.reloc_pcrel
= 0;
6615 insn
.reloc_size
= 4;
6619 create_mnemonic_htab ();
6621 create_dspreg_htabs ();
6622 create_scond_htab ();
6625 l
= parse_prefix (l
, &insn
);
6630 if (insn
.type
== INSN_DSP
&&
6633 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6637 else if (insn
.type
== INSN_FPU
&&
6640 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6645 if (!parse_insn (l
, &insn
))
6648 output_insn (&insn
);
6652 md_operand (expressionS
* expressionP
)
6654 if (* input_line_pointer
== IMM_CHAR
)
6656 input_line_pointer
++;
6657 expression (expressionP
);
6662 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
6668 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6673 /* Functions concerning relocs. */
6675 /* The location from which a PC relative jump should be calculated,
6676 given a PC relative reloc. */
6679 md_pcrel_from_section (fixS
* fixP
, segT sec
)
6681 if ((fixP
->fx_addsy
!= (symbolS
*) NULL
6682 && (! S_IS_DEFINED (fixP
->fx_addsy
)
6683 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
6684 || metag_force_relocation (fixP
))
6686 /* The symbol is undefined (or is defined but not in this section).
6687 Let the linker figure it out. */
6691 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6694 /* Write a value out to the object file, using the appropriate endianness. */
6697 md_number_to_chars (char * buf
, valueT val
, int n
)
6699 number_to_chars_littleendian (buf
, val
, n
);
6702 /* Turn a string in input_line_pointer into a floating point constant of type
6703 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6704 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6707 /* Equal to MAX_PRECISION in atof-ieee.c */
6708 #define MAX_LITTLENUMS 6
6711 md_atof (int type
, char * litP
, int * sizeP
)
6715 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6734 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6738 return _("Bad call to md_atof()");
6741 t
= atof_ieee (input_line_pointer
, type
, words
);
6743 input_line_pointer
= t
;
6744 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
6746 for (i
= 0; i
< prec
; i
++)
6748 md_number_to_chars (litP
, (valueT
) words
[i
],
6749 sizeof (LITTLENUM_TYPE
));
6750 litP
+= sizeof (LITTLENUM_TYPE
);
6756 /* If this function returns non-zero, it prevents the relocation
6757 against symbol(s) in the FIXP from being replaced with relocations
6758 against section symbols, and guarantees that a relocation will be
6759 emitted even when the value can be resolved locally. */
6762 metag_force_relocation (fixS
* fix
)
6764 switch (fix
->fx_r_type
)
6766 case BFD_RELOC_METAG_RELBRANCH_PLT
:
6767 case BFD_RELOC_METAG_TLS_LE
:
6768 case BFD_RELOC_METAG_TLS_IE
:
6769 case BFD_RELOC_METAG_TLS_LDO
:
6770 case BFD_RELOC_METAG_TLS_LDM
:
6771 case BFD_RELOC_METAG_TLS_GD
:
6777 return generic_force_reloc (fix
);
6781 metag_fix_adjustable (fixS
* fixP
)
6783 if (fixP
->fx_addsy
== NULL
)
6786 /* Prevent all adjustments to global symbols. */
6787 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
6789 if (S_IS_WEAK (fixP
->fx_addsy
))
6792 if (fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTOFF
||
6793 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTOFF
||
6794 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOTOFF
||
6795 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOT
||
6796 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTPC
||
6797 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTPC
||
6798 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_PLT
||
6799 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_PLT
||
6800 fixP
->fx_r_type
== BFD_RELOC_METAG_RELBRANCH_PLT
)
6803 /* We need the symbol name for the VTABLE entries. */
6804 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6805 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6811 /* Return an initial guess of the length by which a fragment must grow to
6812 hold a branch to reach its destination.
6813 Also updates fr_type/fr_subtype as necessary.
6815 Called just before doing relaxation.
6816 Any symbol that is now undefined will not become defined.
6817 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6818 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6819 Although it may not be explicit in the frag, pretend fr_var starts with a
6823 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
6824 segT segment ATTRIBUTE_UNUSED
)
6826 /* No assembler relaxation is defined (or necessary) for this port. */
6830 /* *fragP has been relaxed to its final size, and now needs to have
6831 the bytes inside it modified to conform to the new size.
6833 Called after relaxation is finished.
6834 fragP->fr_type == rs_machine_dependent.
6835 fragP->fr_subtype is the subtype of what the address relaxed to. */
6838 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
,
6839 fragS
* fragP ATTRIBUTE_UNUSED
)
6841 /* No assembler relaxation is defined (or necessary) for this port. */
6845 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6848 metag_handle_align (fragS
* fragP
)
6850 static char const noop
[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6854 if (fragP
->fr_type
!= rs_align_code
)
6857 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
6858 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
6871 memcpy (p
, noop
, 4);
6877 fragP
->fr_fix
+= fix
;
6882 metag_end_of_match (char * cont
, char * what
)
6884 int len
= strlen (what
);
6886 if (strncasecmp (cont
, what
, strlen (what
)) == 0
6887 && ! is_part_of_name (cont
[len
]))
6894 metag_parse_name (char const * name
, expressionS
* exprP
, enum expr_mode mode
,
6897 char *next
= input_line_pointer
;
6903 exprP
->X_op_symbol
= NULL
;
6904 exprP
->X_md
= BFD_RELOC_UNUSED
;
6906 if (strcmp (name
, GOT_NAME
) == 0)
6909 GOT_symbol
= symbol_find_or_make (name
);
6911 exprP
->X_add_symbol
= GOT_symbol
;
6913 /* If we have an absolute symbol or a
6914 reg, then we know its value now. */
6915 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
6916 if (mode
!= expr_defer
&& segment
== absolute_section
)
6918 exprP
->X_op
= O_constant
;
6919 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6920 exprP
->X_add_symbol
= NULL
;
6922 else if (mode
!= expr_defer
&& segment
== reg_section
)
6924 exprP
->X_op
= O_register
;
6925 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6926 exprP
->X_add_symbol
= NULL
;
6930 exprP
->X_op
= O_symbol
;
6931 exprP
->X_add_number
= 0;
6937 exprP
->X_add_symbol
= symbol_find_or_make (name
);
6939 if (*nextcharP
!= '@')
6941 else if ((next_end
= metag_end_of_match (next
+ 1, "GOTOFF")))
6943 reloc_type
= BFD_RELOC_METAG_GOTOFF
;
6944 op_type
= O_PIC_reloc
;
6946 else if ((next_end
= metag_end_of_match (next
+ 1, "GOT")))
6948 reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
6949 op_type
= O_PIC_reloc
;
6951 else if ((next_end
= metag_end_of_match (next
+ 1, "PLT")))
6953 reloc_type
= BFD_RELOC_METAG_PLT
;
6954 op_type
= O_PIC_reloc
;
6956 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSGD")))
6958 reloc_type
= BFD_RELOC_METAG_TLS_GD
;
6959 op_type
= O_PIC_reloc
;
6961 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDM")))
6963 reloc_type
= BFD_RELOC_METAG_TLS_LDM
;
6964 op_type
= O_PIC_reloc
;
6966 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDO")))
6968 reloc_type
= BFD_RELOC_METAG_TLS_LDO
;
6969 op_type
= O_PIC_reloc
;
6971 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIE")))
6973 reloc_type
= BFD_RELOC_METAG_TLS_IE
;
6974 op_type
= O_PIC_reloc
;
6976 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIENONPIC")))
6978 reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC
;
6979 op_type
= O_PIC_reloc
; /* FIXME: is this correct? */
6981 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLE")))
6983 reloc_type
= BFD_RELOC_METAG_TLS_LE
;
6984 op_type
= O_PIC_reloc
;
6989 *input_line_pointer
= *nextcharP
;
6990 input_line_pointer
= next_end
;
6991 *nextcharP
= *input_line_pointer
;
6992 *input_line_pointer
= '\0';
6994 exprP
->X_op
= op_type
;
6995 exprP
->X_add_number
= 0;
6996 exprP
->X_md
= reloc_type
;
7001 /* If while processing a fixup, a reloc really needs to be created
7002 then it is done here. */
7005 tc_gen_reloc (seg
, fixp
)
7006 asection
*seg ATTRIBUTE_UNUSED
;
7011 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
7012 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
7013 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7014 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7016 reloc
->addend
= fixp
->fx_offset
;
7017 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
7019 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
7021 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7022 /* xgettext:c-format. */
7023 _("reloc %d not supported by object file format"),
7024 (int) fixp
->fx_r_type
);
7035 md_chars_to_number (char *val
, int n
)
7038 unsigned char * where
= (unsigned char *) val
;
7040 for (retval
= 0; n
--;)
7049 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7051 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7052 int value
= (int)*valP
;
7054 switch (fixP
->fx_r_type
)
7056 case BFD_RELOC_METAG_TLS_GD
:
7057 case BFD_RELOC_METAG_TLS_LE_HI16
:
7058 case BFD_RELOC_METAG_TLS_LE_LO16
:
7059 case BFD_RELOC_METAG_TLS_IE
:
7060 case BFD_RELOC_METAG_TLS_IENONPIC_HI16
:
7061 case BFD_RELOC_METAG_TLS_IENONPIC_LO16
:
7062 case BFD_RELOC_METAG_TLS_LDM
:
7063 case BFD_RELOC_METAG_TLS_LDO_HI16
:
7064 case BFD_RELOC_METAG_TLS_LDO_LO16
:
7065 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7068 case BFD_RELOC_METAG_HIADDR16
:
7069 case BFD_RELOC_METAG_LOADDR16
:
7070 case BFD_RELOC_VTABLE_INHERIT
:
7071 case BFD_RELOC_VTABLE_ENTRY
:
7072 fixP
->fx_done
= FALSE
;
7075 case BFD_RELOC_METAG_REL8
:
7076 if (!within_unsigned_range (value
, IMM8_BITS
))
7078 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7079 "rel8 out of range %d", value
);
7083 unsigned int newval
;
7084 newval
= md_chars_to_number (buf
, 4);
7085 newval
= (newval
& 0xffffc03f) | ((value
& IMM8_MASK
) << 6);
7086 md_number_to_chars (buf
, newval
, 4);
7089 case BFD_RELOC_METAG_REL16
:
7090 if (!within_unsigned_range (value
, IMM16_BITS
))
7092 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7093 "rel16 out of range %d", value
);
7097 unsigned int newval
;
7098 newval
= md_chars_to_number (buf
, 4);
7099 newval
= (newval
& 0xfff80007) | ((value
& IMM16_MASK
) << 3);
7100 md_number_to_chars (buf
, newval
, 4);
7105 md_number_to_chars (buf
, value
, 1);
7108 md_number_to_chars (buf
, value
, 2);
7111 md_number_to_chars (buf
, value
, 4);
7114 md_number_to_chars (buf
, value
, 8);
7116 case BFD_RELOC_METAG_RELBRANCH
:
7122 if (!within_signed_range (value
, IMM19_BITS
))
7124 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7125 "relbranch out of range %d", value
);
7129 unsigned int newval
;
7130 newval
= md_chars_to_number (buf
, 4);
7131 newval
= (newval
& 0xff00001f) | ((value
& IMM19_MASK
) << 5);
7132 md_number_to_chars (buf
, newval
, 4);
7139 if (fixP
->fx_addsy
== NULL
)
7140 fixP
->fx_done
= TRUE
;