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"
30 #include "opcode/metag.h"
32 const char comment_chars
[] = "!";
33 const char line_comment_chars
[] = "!#";
34 const char line_separator_chars
[] = ";";
35 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
36 const char EXP_CHARS
[] = "eE";
37 const char metag_symbol_chars
[] = "[";
39 static char register_chars
[256];
40 static char mnemonic_chars
[256];
42 #define is_register_char(x) (register_chars[(unsigned char) x])
43 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
44 #define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
45 #define is_space_char(x) ((x) == ' ')
47 #define FPU_PREFIX_CHAR 'f'
48 #define DSP_PREFIX_CHAR 'd'
50 /* Instruction mnemonics that need disambiguating with respect to prefixes. */
51 #define FFB_INSN "ffb"
52 #define DCACHE_INSN "dcache"
53 #define DEFR_INSN "defr"
55 #define FPU_DOUBLE_CHAR 'd'
56 #define FPU_PAIR_CHAR 'l'
58 #define DSP_DUAL_CHAR 'l'
60 #define END_OF_INSN '\0'
62 /* Maximum length of a mnemonic including all suffixes. */
63 #define MAX_MNEMONIC_LEN 16
64 /* Maximum length of a register name. */
65 #define MAX_REG_LEN 17
67 /* Addressing modes must be enclosed with square brackets. */
68 #define ADDR_BEGIN_CHAR '['
69 #define ADDR_END_CHAR ']'
70 /* Immediates must be prefixed with a hash. */
77 /* Short units are those that can be encoded with 2 bits. */
78 #define SHORT_UNITS "D0, D1, A0 or A1"
80 static unsigned int mcpu_opt
= CoreMeta12
;
81 static unsigned int mfpu_opt
= 0;
82 static unsigned int mdsp_opt
= 0;
84 const char * md_shortopts
= "m:";
86 struct option md_longopts
[] =
88 {NULL
, no_argument
, NULL
, 0}
90 size_t md_longopts_size
= sizeof (md_longopts
);
92 /* Parser hash tables. */
93 static htab_t mnemonic_htab
;
94 static htab_t reg_htab
;
95 static htab_t dsp_reg_htab
;
96 static htab_t dsp_tmpl_reg_htab
[2];
97 static htab_t scond_htab
;
99 #define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
100 symbolS
* GOT_symbol
;
102 enum fpu_insn_width
{
108 #define FPU_ACTION_ABS_CHAR 'a'
109 #define FPU_ACTION_INV_CHAR 'i'
110 #define FPU_ACTION_QUIET_CHAR 'q'
111 #define FPU_ACTION_ZERO_CHAR 'z'
113 #define FPU_ACTION_ABS 0x1
114 #define FPU_ACTION_INV 0x2
115 #define FPU_ACTION_QUIET 0x4
116 #define FPU_ACTION_ZERO 0x8
118 enum dsp_insn_width
{
123 #define DSP_ACTION_QR64_CHAR 'q'
124 #define DSP_ACTION_UMUL_CHAR 'u'
125 #define DSP_ACTION_ROUND_CHAR 'r'
126 #define DSP_ACTION_CLAMP9_CHAR 'g'
127 #define DSP_ACTION_CLAMP8_CHAR 'b'
128 #define DSP_ACTION_MOD_CHAR 'm'
129 #define DSP_ACTION_ACC_ZERO_CHAR 'z'
130 #define DSP_ACTION_ACC_ADD_CHAR 'p'
131 #define DSP_ACTION_ACC_SUB_CHAR 'n'
132 #define DSP_ACTION_OV_CHAR 'o'
134 #define DSP_ACTION_QR64 0x001
135 #define DSP_ACTION_UMUL 0x002
136 #define DSP_ACTION_ROUND 0x004
137 #define DSP_ACTION_CLAMP9 0x008
138 #define DSP_ACTION_CLAMP8 0x010
139 #define DSP_ACTION_MOD 0x020
140 #define DSP_ACTION_ACC_ZERO 0x040
141 #define DSP_ACTION_ACC_ADD 0x080
142 #define DSP_ACTION_ACC_SUB 0x100
143 #define DSP_ACTION_OV 0x200
145 #define DSP_DAOPPAME_8_CHAR 'b'
146 #define DSP_DAOPPAME_16_CHAR 'w'
147 #define DSP_DAOPPAME_TEMP_CHAR 't'
148 #define DSP_DAOPPAME_HIGH_CHAR 'h'
150 #define DSP_DAOPPAME_8 0x1
151 #define DSP_DAOPPAME_16 0x2
152 #define DSP_DAOPPAME_TEMP 0x4
153 #define DSP_DAOPPAME_HIGH 0x8
155 /* Structure holding information about a parsed instruction. */
157 /* Instruction type. */
159 /* Split condition code. */
160 enum scond_code scond
;
162 /* Instruction bits. */
164 /* Size of the instruction in bytes. */
167 /* FPU instruction encoding. */
168 enum fpu_insn_width fpu_width
;
169 unsigned int fpu_action_flags
;
171 /* DSP instruction encoding. */
172 enum dsp_insn_width dsp_width
;
173 unsigned int dsp_action_flags
;
174 unsigned int dsp_daoppame_flags
;
176 /* Reloc encoding information, maximum of one reloc per insn. */
177 enum bfd_reloc_code_real reloc_type
;
179 expressionS reloc_exp
;
180 unsigned int reloc_size
;
183 /* Structure holding information about a parsed addressing mode. */
185 const metag_reg
*base_reg
;
186 const metag_reg
*offset_reg
;
190 enum bfd_reloc_code_real reloc_type
;
192 /* Whether we have an immediate or not. */
193 unsigned short immediate
:1;
194 /* Whether or not the base register is updated. */
195 unsigned short update
:1;
196 /* Whether the operation uses the address pre or post increment. */
197 unsigned short post_increment
:1;
198 /* Whether the immediate should be negated. */
199 unsigned short negate
:1;
202 /* Linked list of possible parsers for this instruction. */
203 typedef struct _insn_templates
{
204 const insn_template
*template;
205 struct _insn_templates
*next
;
208 /* Parse an instruction that takes no operands. */
210 parse_none (const char *line
, metag_insn
*insn
,
211 const insn_template
*template)
213 insn
->bits
= template->meta_opcode
;
218 /* Return the next non-whitespace character in LINE or NULL. */
220 skip_whitespace (const char *line
)
222 const char *l
= line
;
224 if (is_whitespace_char (*l
))
232 /* Return the next non-space character in LINE or NULL. */
234 skip_space (const char *line
)
236 const char *l
= line
;
238 if (is_space_char (*l
))
246 /* Return the character after the current one in LINE if the current
247 character is a comma, otherwise NULL. */
249 skip_comma (const char *line
)
251 const char *l
= line
;
253 if (l
== NULL
|| *l
!= COMMA
)
261 /* Return the metag_reg struct corresponding to NAME or NULL if no such
263 static const metag_reg
*
264 parse_gp_reg (const char *name
)
266 const metag_reg
*reg
;
271 reg
= (const metag_reg
*) htab_find (reg_htab
, &entry
);
276 /* Parse a list of up to COUNT GP registers from LINE, returning the
277 registers parsed in REGS and the number parsed in REGS_READ. Return
278 a pointer to the next character or NULL. */
280 parse_gp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
283 const char *l
= line
;
284 char reg_buf
[MAX_REG_LEN
];
288 for (i
= 0; i
< count
; i
++)
300 *regs_read
= seen_regs
;
305 while (is_register_char (*l
))
310 if (!(len
< MAX_REG_LEN
))
318 const metag_reg
*reg
= parse_gp_reg (reg_buf
);
322 *regs_read
= seen_regs
;
333 *regs_read
= seen_regs
;
338 *regs_read
= seen_regs
;
342 /* Parse a list of exactly COUNT GP registers from LINE, returning the
343 registers parsed in REGS. Return a pointer to the next character or NULL. */
345 parse_gp_regs (const char *line
, const metag_reg
**regs
, size_t count
)
347 const char *l
= line
;
348 size_t regs_read
= 0;
350 l
= parse_gp_regs_list (l
, regs
, count
, ®s_read
);
352 if (regs_read
!= count
)
358 /* Parse a list of exactly COUNT FPU registers from LINE, returning the
359 registers parsed in REGS. Return a pointer to the next character or NULL. */
361 parse_fpu_regs (const char *line
, const metag_reg
**regs
, size_t count
)
363 const char *l
= line
;
364 size_t regs_read
= 0;
366 l
= parse_gp_regs_list (l
, regs
, count
, ®s_read
);
368 if (regs_read
!= count
)
373 for (i
= 0; i
< count
; i
++)
375 if (regs
[i
]->unit
!= UNIT_FX
)
382 /* Return TRUE if REG1 and REG2 are in paired units. */
384 is_unit_pair (const metag_reg
*reg1
, const metag_reg
*reg2
)
386 if ((reg1
->unit
== UNIT_A0
&&
387 (reg2
->unit
== UNIT_A1
)) ||
388 (reg1
->unit
== UNIT_A1
&&
389 (reg2
->unit
== UNIT_A0
)) ||
390 (reg1
->unit
== UNIT_D0
&&
391 (reg2
->unit
== UNIT_D1
)) ||
392 (reg1
->unit
== UNIT_D1
&&
393 (reg2
->unit
== UNIT_D0
)))
399 /* Return TRUE if REG1 and REG2 form a register pair. */
401 is_reg_pair (const metag_reg
*reg1
, const metag_reg
*reg2
)
403 if (reg1
->unit
== UNIT_FX
&&
404 reg2
->unit
== UNIT_FX
&&
405 reg2
->no
== reg1
->no
+ 1)
408 if (reg1
->no
!= reg2
->no
)
411 return is_unit_pair (reg1
, reg2
);
414 /* Parse a pair of GP registers from LINE, returning the registers parsed
415 in REGS. Return a pointer to the next character or NULL. */
417 parse_pair_gp_regs (const char *line
, const metag_reg
**regs
)
419 const char *l
= line
;
421 l
= parse_gp_regs (line
, regs
, 2);
425 l
= parse_gp_regs (line
, regs
, 1);
430 if (regs
[0]->unit
== UNIT_RD
)
436 if (is_reg_pair (regs
[0], regs
[1]))
442 /* Parse a unit-to-unit MOV instruction. */
444 parse_mov_u2u (const char *line
, metag_insn
*insn
,
445 const insn_template
*template)
447 const metag_reg
*regs
[2];
449 line
= parse_gp_regs (line
, regs
, 2);
454 if (!mfpu_opt
&& (regs
[0]->unit
== UNIT_FX
|| regs
[1]->unit
== UNIT_FX
))
456 as_bad (_("no floating point unit specified"));
460 insn
->bits
= (template->meta_opcode
|
461 (regs
[1]->no
<< 19) |
462 (regs
[0]->no
<< 14) |
463 (regs
[1]->unit
<< 10) |
464 (regs
[0]->unit
<< 5));
469 /* Parse a MOV to port instruction. */
471 parse_mov_port (const char *line
, metag_insn
*insn
,
472 const insn_template
*template)
474 const char *l
= line
;
475 unsigned int is_movl
= MINOR_OPCODE (template->meta_opcode
) == MOVL_MINOR
;
476 const metag_reg
*dest_regs
[2];
477 const metag_reg
*port_regs
[1];
480 l
= parse_gp_regs (l
, dest_regs
, 2);
482 l
= parse_gp_regs (l
, dest_regs
, 1);
487 if (template->insn_type
== INSN_FPU
&& dest_regs
[0]->unit
!= UNIT_FX
)
496 l
= parse_gp_regs (l
, port_regs
, 1);
501 if (port_regs
[0]->unit
!= UNIT_RD
||
502 port_regs
[0]->no
!= 0)
507 if (!is_unit_pair (dest_regs
[0], dest_regs
[1]))
510 insn
->bits
= (template->meta_opcode
|
511 (dest_regs
[0]->no
<< 14) |
512 (dest_regs
[1]->no
<< 9) |
513 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 5));
516 insn
->bits
= (template->meta_opcode
|
517 (dest_regs
[0]->no
<< 14) |
518 (dest_regs
[0]->unit
<< 5));
524 /* Parse a MOVL to TTREC instruction. */
526 parse_movl_ttrec (const char *line
, metag_insn
*insn
,
527 const insn_template
*template)
529 const char *l
= line
;
530 const metag_reg
*src_regs
[2];
531 const metag_reg
*dest_regs
[1];
533 l
= parse_gp_regs (l
, dest_regs
, 1);
538 if (dest_regs
[0]->unit
!= UNIT_TT
||
539 dest_regs
[0]->no
!= 3)
548 l
= parse_gp_regs (l
, src_regs
, 2);
553 if (!is_unit_pair (src_regs
[0], src_regs
[1]))
556 insn
->bits
= (template->meta_opcode
|
557 (src_regs
[0]->no
<< 19) |
558 (src_regs
[1]->no
<< 14) |
559 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 7));
565 /* Parse an incrementing or decrementing addressing mode. */
567 parse_addr_incr_op (const char *line
, metag_addr
*addr
)
569 const char *l
= line
;
581 else if (*l
== MINUS
&&
592 /* Parse an pre-incrementing or pre-decrementing addressing mode. */
594 parse_addr_pre_incr_op (const char *line
, metag_addr
*addr
)
596 return parse_addr_incr_op (line
, addr
);
599 /* Parse an post-incrementing or post-decrementing addressing mode. */
601 parse_addr_post_incr_op (const char *line
, metag_addr
*addr
)
605 l
= parse_addr_incr_op (line
, addr
);
610 addr
->post_increment
= 1;
615 /* Parse an infix addressing mode. */
617 parse_addr_op (const char *line
, metag_addr
*addr
)
619 const char *l
= line
;
638 /* Parse the immediate portion of an addrssing mode. */
640 parse_imm_addr (const char *line
, metag_addr
*addr
)
642 const char *l
= line
;
643 char *save_input_line_pointer
;
644 expressionS
*exp
= &addr
->exp
;
652 save_input_line_pointer
= input_line_pointer
;
653 input_line_pointer
= (char *) l
;
657 l
= input_line_pointer
;
658 input_line_pointer
= save_input_line_pointer
;
660 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
664 else if (exp
->X_op
== O_constant
)
670 if (exp
->X_op
== O_PIC_reloc
&&
671 exp
->X_md
== BFD_RELOC_METAG_GETSET_GOT
)
673 exp
->X_op
= O_symbol
;
674 addr
->reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
676 else if (exp
->X_op
== O_PIC_reloc
&&
677 exp
->X_md
== BFD_RELOC_METAG_TLS_IE
)
679 exp
->X_op
= O_symbol
;
680 addr
->reloc_type
= BFD_RELOC_METAG_TLS_IE
;
682 else if (exp
->X_op
== O_PIC_reloc
&&
683 exp
->X_md
== BFD_RELOC_METAG_GOTOFF
)
685 exp
->X_op
= O_symbol
;
686 addr
->reloc_type
= BFD_RELOC_METAG_GETSET_GOTOFF
;
689 addr
->reloc_type
= BFD_RELOC_METAG_GETSETOFF
;
694 /* Parse the offset portion of an addressing mode (register or immediate). */
696 parse_addr_offset (const char *line
, metag_addr
*addr
, int size
)
698 const char *l
= line
;
699 const metag_reg
*regs
[1];
703 /* ++ is a valid operator in our addressing but not in an expr. Make
704 sure that the expression parser never sees it. */
705 char *ppp
= strstr(l
, "++");
711 l
= parse_imm_addr (l
, addr
);
719 if (addr
->exp
.X_add_number
% size
)
721 as_bad (_("offset must be a multiple of %d"), size
);
730 l
= parse_gp_regs (l
, regs
, 1);
735 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
737 as_bad (_("offset and base must be from the same unit"));
741 addr
->offset_reg
= regs
[0];
746 /* Parse an addressing mode. */
748 parse_addr (const char *line
, metag_addr
*addr
, unsigned int size
)
750 const char *l
= line
;
752 const metag_reg
*regs
[1];
754 /* Skip opening square bracket. */
757 ll
= parse_addr_pre_incr_op (l
, addr
);
762 l
= parse_gp_regs (l
, regs
, 1);
767 addr
->base_reg
= regs
[0];
769 if (*l
== ADDR_END_CHAR
)
771 addr
->exp
.X_op
= O_constant
;
772 addr
->exp
.X_add_symbol
= NULL
;
773 addr
->exp
.X_op_symbol
= NULL
;
774 if (addr
->update
== 1)
776 /* We have a pre increment/decrement. */
777 addr
->exp
.X_add_number
= size
;
781 /* Simple register with no offset (0 immediate). */
782 addr
->exp
.X_add_number
= 0;
789 /* We already had a pre increment/decrement. */
790 if (addr
->update
== 1)
793 ll
= parse_addr_post_incr_op (l
, addr
);
795 if (ll
&& *ll
== ADDR_END_CHAR
)
797 if (addr
->update
== 1)
799 /* We have a post increment/decrement. */
800 addr
->exp
.X_op
= O_constant
;
801 addr
->exp
.X_add_number
= size
;
802 addr
->exp
.X_add_symbol
= NULL
;
803 addr
->exp
.X_op_symbol
= NULL
;
804 addr
->post_increment
= 1;
811 addr
->post_increment
= 0;
813 l
= parse_addr_op (l
, addr
);
818 l
= parse_addr_offset (l
, addr
, size
);
823 if (*l
== ADDR_END_CHAR
)
829 /* We already had a pre increment/decrement. */
830 if (addr
->update
== 1)
833 l
= parse_addr_post_incr_op (l
, addr
);
838 if (*l
== ADDR_END_CHAR
)
847 /* Parse a GET or pipeline MOV instruction. */
849 parse_get (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
850 unsigned int size
, bfd_boolean is_mov
)
852 const char *l
= line
;
856 l
= parse_pair_gp_regs (l
, regs
);
863 l
= parse_gp_regs (l
, regs
, 1);
868 as_bad (_("invalid destination register"));
879 l
= parse_addr (l
, addr
, size
);
884 as_bad (_("invalid memory operand"));
891 /* Parse a SET instruction. */
893 parse_set (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
896 const char *l
= line
;
898 l
= parse_addr (l
, addr
, size
);
902 as_bad (_("invalid memory operand"));
916 ll
= parse_pair_gp_regs (l
, regs
);
920 /* Maybe this is an RD register, which is 64 bits wide so needs no
922 l
= parse_gp_regs (l
, regs
, 1);
925 regs
[0]->unit
!= UNIT_RD
)
935 l
= parse_gp_regs (l
, regs
, 1);
939 as_bad (_("invalid source register"));
947 /* Check a signed integer value can be represented in the given number
950 within_signed_range (int value
, unsigned int bits
)
952 int min_val
= -(1 << (bits
- 1));
953 int max_val
= (1 << (bits
- 1)) - 1;
954 return (value
<= max_val
) && (value
>= min_val
);
957 /* Check an unsigned integer value can be represented in the given number
960 within_unsigned_range (unsigned int value
, unsigned int bits
)
962 return value
< (unsigned int)(1 << bits
);
965 /* Return TRUE if UNIT can be expressed using a short code. */
967 is_short_unit (enum metag_unit unit
)
981 /* Copy reloc data from ADDR to INSN. */
983 copy_addr_reloc (metag_insn
*insn
, metag_addr
*addr
)
985 memcpy (&insn
->reloc_exp
, &addr
->exp
, sizeof(insn
->reloc_exp
));
986 insn
->reloc_type
= addr
->reloc_type
;
989 /* Parse a GET, SET or pipeline MOV instruction. */
991 parse_get_set (const char *line
, metag_insn
*insn
,
992 const insn_template
*template)
994 const char *l
= line
;
995 const metag_reg
*regs
[2];
997 unsigned int size
= metag_get_set_size_bytes (template->meta_opcode
);
998 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
1001 memset(&addr
, 0, sizeof(addr
));
1002 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1006 bfd_boolean is_mov
= strncmp (template->name
, "MOV", 3) == 0;
1008 l
= parse_get (l
, regs
, &addr
, size
, is_mov
);
1013 if (!(regs
[0]->unit
== UNIT_D0
||
1014 regs
[0]->unit
== UNIT_D1
||
1015 regs
[0]->unit
== UNIT_A0
||
1016 regs
[0]->unit
== UNIT_A1
||
1017 (regs
[0]->unit
== UNIT_RD
&& is_mov
) ||
1018 (regs
[0]->unit
== UNIT_CT
&& size
== 4) ||
1019 (regs
[0]->unit
== UNIT_PC
&& size
== 4) ||
1020 (regs
[0]->unit
== UNIT_TR
&& size
== 4) ||
1021 (regs
[0]->unit
== UNIT_TT
&& (size
== 4 || size
== 8)) ||
1022 regs
[0]->unit
== UNIT_FX
))
1024 as_bad (_("invalid destination unit"));
1028 if (regs
[0]->unit
== UNIT_RD
)
1030 if (regs
[0]->no
== 0)
1032 as_bad (_("mov cannot use RD port as destination"));
1037 reg_no
= regs
[0]->no
;
1041 l
= parse_set (l
, regs
, &addr
, size
);
1046 if (!(regs
[0]->unit
== UNIT_D0
||
1047 regs
[0]->unit
== UNIT_D1
||
1048 regs
[0]->unit
== UNIT_A0
||
1049 regs
[0]->unit
== UNIT_A1
||
1050 regs
[0]->unit
== UNIT_RD
||
1051 (regs
[0]->unit
== UNIT_CT
&& size
== 4) ||
1052 (regs
[0]->unit
== UNIT_PC
&& size
== 4) ||
1053 (regs
[0]->unit
== UNIT_TR
&& size
== 4) ||
1054 (regs
[0]->unit
== UNIT_TT
&& (size
== 4 || size
== 8)) ||
1055 regs
[0]->unit
== UNIT_FX
))
1057 as_bad (_("invalid source unit"));
1061 if (addr
.immediate
== 0 &&
1062 (regs
[0]->unit
== addr
.base_reg
->unit
||
1063 (size
== 8 && is_unit_pair (regs
[0], addr
.base_reg
))))
1065 as_bad (_("source and address units must not be shared for this addressing mode"));
1069 if (regs
[0]->unit
== UNIT_RD
)
1071 if (regs
[0]->no
!= 0)
1073 as_bad (_("set can only use RD port as source"));
1079 reg_no
= regs
[0]->no
;
1082 insn
->bits
= (template->meta_opcode
|
1084 (regs
[0]->unit
<< 1));
1086 if (!is_short_unit (addr
.base_reg
->unit
))
1088 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1092 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1093 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1097 int offset
= addr
.exp
.X_add_number
;
1099 copy_addr_reloc (insn
, &addr
);
1104 offset
= offset
/ (int)size
;
1106 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
1108 /* We already tried to encode as an extended GET/SET. */
1109 as_bad (_("offset value out of range"));
1113 offset
= offset
& GET_SET_IMM_MASK
;
1115 insn
->bits
|= (0x1 << 25);
1116 insn
->bits
|= (offset
<< 8);
1120 insn
->bits
|= (addr
.offset_reg
->no
<< 9);
1124 insn
->bits
|= (0x1 << 7);
1126 if (addr
.post_increment
)
1133 /* Parse an extended GET or SET instruction. */
1135 parse_get_set_ext (const char *line
, metag_insn
*insn
,
1136 const insn_template
*template)
1138 const char *l
= line
;
1139 const metag_reg
*regs
[2];
1141 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
1142 bfd_boolean is_get
= MINOR_OPCODE (template->meta_opcode
) == GET_EXT_MINOR
;
1143 bfd_boolean is_mov
= MINOR_OPCODE (template->meta_opcode
) == MOV_EXT_MINOR
;
1144 unsigned int reg_unit
;
1146 memset(&addr
, 0, sizeof(addr
));
1147 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1149 if (is_get
|| is_mov
)
1151 l
= parse_get (l
, regs
, &addr
, size
, is_mov
);
1155 l
= parse_set (l
, regs
, &addr
, size
);
1161 /* Extended GET/SET does not support incrementing addressing. */
1167 if (regs
[0]->unit
!= UNIT_RD
)
1169 as_bad (_("destination unit must be RD"));
1176 if (!is_short_unit (regs
[0]->unit
))
1180 reg_unit
= regs
[0]->unit
;
1183 insn
->bits
= (template->meta_opcode
|
1184 (regs
[0]->no
<< 19) |
1185 ((reg_unit
& SHORT_UNIT_MASK
) << 3));
1187 if (!is_short_unit (addr
.base_reg
->unit
))
1189 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1193 if (addr
.base_reg
->no
> 1)
1198 insn
->bits
|= ((addr
.base_reg
->no
& EXT_BASE_REG_MASK
) |
1199 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1203 int offset
= addr
.exp
.X_add_number
;
1205 copy_addr_reloc (insn
, &addr
);
1210 offset
= offset
/ (int)size
;
1212 if (!within_signed_range (offset
, GET_SET_EXT_IMM_BITS
))
1214 /* Parsing as a standard GET/SET provides a smaller offset. */
1215 as_bad (_("offset value out of range"));
1219 offset
= offset
& GET_SET_EXT_IMM_MASK
;
1221 insn
->bits
|= (offset
<< 7);
1232 /* Parse an MGET or MSET instruction addressing mode. */
1234 parse_mget_mset_addr (const char *line
, metag_addr
*addr
)
1236 const char *l
= line
;
1238 const metag_reg
*regs
[1];
1240 /* Skip opening square bracket. */
1243 l
= parse_gp_regs (l
, regs
, 1);
1248 addr
->base_reg
= regs
[0];
1250 ll
= parse_addr_post_incr_op (l
, addr
);
1255 if (addr
->negate
== 1)
1258 if (*l
== ADDR_END_CHAR
)
1267 /* Parse an MGET instruction. */
1269 parse_mget (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
1272 const char *l
= line
;
1274 l
= parse_gp_regs_list (l
, regs
, MGET_MSET_MAX_REGS
, regs_read
);
1279 as_bad (_("invalid destination register list"));
1289 l
= parse_mget_mset_addr (l
, addr
);
1293 as_bad (_("invalid memory operand"));
1300 /* Parse an MSET instruction. */
1302 parse_mset (const char *line
, const metag_reg
**regs
, metag_addr
*addr
,
1305 const char *l
= line
;
1307 l
= parse_mget_mset_addr (l
, addr
);
1311 as_bad (_("invalid memory operand"));
1321 l
= parse_gp_regs_list (l
, regs
, MGET_MSET_MAX_REGS
, regs_read
);
1326 as_bad (_("invalid source register list"));
1333 /* Take a register list REGS of size REGS_READ and convert it into an
1334 rmask value if possible. Return the rmask value in RMASK and the
1335 lowest numbered register in LOWEST_REG. Return TRUE if the conversion
1338 check_rmask (const metag_reg
**regs
, size_t regs_read
, bfd_boolean is_fpu
,
1339 bfd_boolean is_64bit
, unsigned int *lowest_reg
,
1340 unsigned int *rmask
)
1342 unsigned int reg_unit
= regs
[0]->unit
;
1345 for (i
= 0; i
< regs_read
; i
++)
1349 if (is_64bit
&& regs
[i
]->no
% 2)
1351 as_bad (_("register list must be even numbered"));
1355 else if (regs
[i
]->unit
!= reg_unit
)
1357 as_bad (_("register list must be from the same unit"));
1361 if (regs
[i
]->no
< *lowest_reg
)
1362 *lowest_reg
= regs
[i
]->no
;
1365 for (i
= 0; i
< regs_read
; i
++)
1367 unsigned int next_bit
, next_reg
;
1368 if (regs
[i
]->no
== *lowest_reg
)
1371 if (is_fpu
&& is_64bit
)
1372 next_reg
= ((regs
[i
]->no
/ 2) - ((*lowest_reg
/ 2) + 1));
1374 next_reg
= (regs
[i
]->no
- (*lowest_reg
+ 1));
1376 next_bit
= (1 << next_reg
);
1378 if (*rmask
& next_bit
)
1380 as_bad (_("register list must not contain duplicates"));
1390 /* Parse an MGET or MSET instruction. */
1392 parse_mget_mset (const char *line
, metag_insn
*insn
,
1393 const insn_template
*template)
1395 const char *l
= line
;
1396 const metag_reg
*regs
[MGET_MSET_MAX_REGS
];
1398 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
1399 bfd_boolean is_fpu
= (MINOR_OPCODE (template->meta_opcode
) & 0x6) == 0x6;
1400 bfd_boolean is_64bit
= (MINOR_OPCODE (template->meta_opcode
) & 0x1) == 0x1;
1401 size_t regs_read
= 0;
1402 unsigned int rmask
= 0, reg_unit
= 0, lowest_reg
= 0xffffffff;
1404 memset(&addr
, 0, sizeof(addr
));
1405 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1409 l
= parse_mget (l
, regs
, &addr
, ®s_read
);
1413 l
= parse_mset (l
, regs
, &addr
, ®s_read
);
1419 if (!check_rmask (regs
, regs_read
, is_fpu
, is_64bit
, &lowest_reg
, &rmask
))
1422 reg_unit
= regs
[0]->unit
;
1426 if (reg_unit
!= UNIT_FX
)
1431 else if (reg_unit
== UNIT_FX
)
1434 insn
->bits
= (template->meta_opcode
|
1435 (lowest_reg
<< 19) |
1436 ((reg_unit
& SHORT_UNIT_MASK
) << 3));
1438 if (!is_short_unit (addr
.base_reg
->unit
))
1440 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1444 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1445 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1447 insn
->bits
|= (rmask
& RMASK_MASK
) << 7;
1453 /* Parse a list of registers for MMOV pipeline prime. */
1455 parse_mmov_prime_list (const char *line
, const metag_reg
**regs
,
1456 unsigned int *rmask
)
1458 const char *l
= line
;
1459 const metag_reg
*ra_regs
[MMOV_MAX_REGS
];
1460 size_t regs_read
= 0, i
;
1461 unsigned int mask
= 0;
1463 l
= parse_gp_regs_list (l
, regs
, 1, ®s_read
);
1465 /* First register must be a port. */
1466 if (l
== NULL
|| regs
[0]->unit
!= UNIT_RD
)
1474 l
= parse_gp_regs_list (l
, ra_regs
, MMOV_MAX_REGS
, ®s_read
);
1479 /* Check remaining registers match the first.
1481 Note that we also accept RA (0x10) as input for the remaining registers.
1482 Whilst this doesn't represent the instruction in any way we're stuck
1483 with it because the embedded assembler accepts it. */
1484 for (i
= 0; i
< regs_read
; i
++)
1486 if (ra_regs
[i
]->unit
!= UNIT_RD
||
1487 (ra_regs
[i
]->no
!= 0x10 && ra_regs
[i
]->no
!= regs
[0]->no
))
1490 mask
= (mask
<< 1) | 0x1;
1498 /* Parse a MMOV instruction. */
1500 parse_mmov (const char *line
, metag_insn
*insn
,
1501 const insn_template
*template)
1503 const char *l
= line
;
1504 unsigned int is_fpu
= template->insn_type
== INSN_FPU
;
1505 unsigned int is_prime
= ((MINOR_OPCODE (template->meta_opcode
) & 0x2) &&
1507 unsigned int is_64bit
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
1508 unsigned int rmask
= 0;
1512 const metag_reg
*reg
;
1515 memset (&addr
, 0, sizeof(addr
));
1517 l
= parse_mmov_prime_list (l
, ®
, &rmask
);
1527 l
= parse_mget_mset_addr (l
, &addr
);
1531 as_bad (_("invalid memory operand"));
1535 insn
->bits
= (template->meta_opcode
|
1537 (addr
.base_reg
->no
<< 14) |
1538 ((rmask
& RMASK_MASK
) << 7) |
1539 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1543 const metag_reg
*regs
[MMOV_MAX_REGS
+ 1];
1544 unsigned int lowest_reg
= 0xffffffff;
1545 size_t regs_read
= 0;
1547 l
= parse_gp_regs_list (l
, regs
, MMOV_MAX_REGS
+ 1, ®s_read
);
1549 if (l
== NULL
|| regs_read
== 0)
1552 if (!is_short_unit (regs
[0]->unit
) &&
1553 !(is_fpu
&& regs
[0]->unit
== UNIT_FX
))
1558 if (!(regs
[regs_read
-1]->unit
== UNIT_RD
&&
1559 regs
[regs_read
-1]->no
== 0))
1564 if (!check_rmask (regs
, regs_read
- 1, is_fpu
, is_64bit
, &lowest_reg
,
1570 insn
->bits
= (template->meta_opcode
|
1571 (regs
[0]->no
<< 14) |
1572 ((rmask
& RMASK_MASK
) << 7));
1576 insn
->bits
= (template->meta_opcode
|
1577 (regs
[0]->no
<< 19) |
1578 ((rmask
& RMASK_MASK
) << 7) |
1579 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
1587 /* Parse an immediate constant. */
1589 parse_imm_constant (const char *line
, metag_insn
*insn
, int *value
)
1591 const char *l
= line
;
1592 char *save_input_line_pointer
;
1593 expressionS
*exp
= &insn
->reloc_exp
;
1601 save_input_line_pointer
= input_line_pointer
;
1602 input_line_pointer
= (char *) l
;
1606 l
= input_line_pointer
;
1607 input_line_pointer
= save_input_line_pointer
;
1609 if (exp
->X_op
== O_constant
)
1611 *value
= exp
->X_add_number
;
1621 /* Parse an MDRD instruction. */
1623 parse_mdrd (const char *line
, metag_insn
*insn
,
1624 const insn_template
*template)
1626 const char *l
= line
;
1627 unsigned int rmask
= 0;
1630 l
= parse_imm_constant (l
, insn
, &value
);
1635 if (value
< 1 || value
> 8)
1637 as_bad (_("MDRD value must be between 1 and 8"));
1641 for (i
= 1; i
< value
; i
++)
1647 insn
->bits
= (template->meta_opcode
|
1654 /* Parse a conditional SET instruction. */
1656 parse_cond_set (const char *line
, metag_insn
*insn
,
1657 const insn_template
*template)
1659 const char *l
= line
;
1660 const metag_reg
*regs
[2];
1662 unsigned int size
= metag_cond_set_size_bytes (template->meta_opcode
);
1663 unsigned int reg_no
;
1665 memset(&addr
, 0, sizeof(addr
));
1666 addr
.reloc_type
= BFD_RELOC_UNUSED
;
1668 l
= parse_set (l
, regs
, &addr
, size
);
1673 if (regs
[0]->unit
== UNIT_RD
)
1675 if (regs
[0]->no
!= 0)
1677 as_bad (_("set can only use RD port as source"));
1683 reg_no
= regs
[0]->no
;
1688 if (!(addr
.immediate
&&
1689 addr
.exp
.X_add_number
== 0))
1692 insn
->bits
= (template->meta_opcode
|
1694 (regs
[0]->unit
<< 10));
1696 if (!is_short_unit (addr
.base_reg
->unit
))
1698 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
1702 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
1703 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
1709 /* Parse an XFR instruction. */
1711 parse_xfr (const char *line
, metag_insn
*insn
,
1712 const insn_template
*template)
1714 const char *l
= line
;
1715 metag_addr dest_addr
, src_addr
;
1716 unsigned int size
= 4;
1718 memset(&dest_addr
, 0, sizeof(dest_addr
));
1719 memset(&src_addr
, 0, sizeof(src_addr
));
1720 dest_addr
.reloc_type
= BFD_RELOC_UNUSED
;
1721 src_addr
.reloc_type
= BFD_RELOC_UNUSED
;
1723 l
= parse_addr (l
, &dest_addr
, size
);
1726 dest_addr
.immediate
== 1)
1728 as_bad (_("invalid destination memory operand"));
1738 l
= parse_addr (l
, &src_addr
, size
);
1741 src_addr
.immediate
== 1)
1743 as_bad (_("invalid source memory operand"));
1747 if (!is_short_unit (dest_addr
.base_reg
->unit
) ||
1748 !is_short_unit (src_addr
.base_reg
->unit
))
1750 as_bad (_("address units must be one of %s"), SHORT_UNITS
);
1754 if ((dest_addr
.base_reg
->unit
!= dest_addr
.offset_reg
->unit
) ||
1755 (src_addr
.base_reg
->unit
!= src_addr
.offset_reg
->unit
))
1757 as_bad (_("base and offset must be from the same unit"));
1761 if (dest_addr
.update
== 1 &&
1762 src_addr
.update
== 1 &&
1763 dest_addr
.post_increment
!= src_addr
.post_increment
)
1765 as_bad (_("source and destination increment mode must agree"));
1769 insn
->bits
= (template->meta_opcode
|
1770 (src_addr
.base_reg
->no
<< 19) |
1771 (src_addr
.offset_reg
->no
<< 14) |
1772 ((src_addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 2));
1774 insn
->bits
|= ((dest_addr
.base_reg
->no
<< 9) |
1775 (dest_addr
.offset_reg
->no
<< 4) |
1776 ((dest_addr
.base_reg
->unit
& SHORT_UNIT_MASK
)));
1778 if (dest_addr
.update
== 1)
1779 insn
->bits
|= (1 << 26);
1781 if (src_addr
.update
== 1)
1782 insn
->bits
|= (1 << 27);
1784 if (dest_addr
.post_increment
== 1 ||
1785 src_addr
.post_increment
== 1)
1786 insn
->bits
|= (1 << 24);
1792 /* Parse an 8bit immediate value. */
1794 parse_imm8 (const char *line
, metag_insn
*insn
, int *value
)
1796 const char *l
= line
;
1797 char *save_input_line_pointer
;
1798 expressionS
*exp
= &insn
->reloc_exp
;
1806 save_input_line_pointer
= input_line_pointer
;
1807 input_line_pointer
= (char *) l
;
1811 l
= input_line_pointer
;
1812 input_line_pointer
= save_input_line_pointer
;
1814 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1818 else if (exp
->X_op
== O_constant
)
1820 *value
= exp
->X_add_number
;
1824 insn
->reloc_type
= BFD_RELOC_METAG_REL8
;
1825 insn
->reloc_pcrel
= 0;
1831 /* Parse a 16bit immediate value. */
1833 parse_imm16 (const char *line
, metag_insn
*insn
, int *value
)
1835 const char *l
= line
;
1836 char *save_input_line_pointer
;
1837 expressionS
*exp
= &insn
->reloc_exp
;
1838 bfd_boolean is_hi
= FALSE
;
1839 bfd_boolean is_lo
= FALSE
;
1847 if (strncasecmp (l
, "HI", 2) == 0)
1852 else if (strncasecmp (l
, "LO", 2) == 0)
1858 save_input_line_pointer
= input_line_pointer
;
1859 input_line_pointer
= (char *) l
;
1863 l
= input_line_pointer
;
1864 input_line_pointer
= save_input_line_pointer
;
1866 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
1870 else if (exp
->X_op
== O_constant
)
1873 *value
= (exp
->X_add_number
>> 16) & IMM16_MASK
;
1875 *value
= exp
->X_add_number
& IMM16_MASK
;
1877 *value
= exp
->X_add_number
;
1881 if (exp
->X_op
== O_PIC_reloc
)
1883 exp
->X_op
= O_symbol
;
1885 if (exp
->X_md
== BFD_RELOC_METAG_GOTOFF
)
1888 insn
->reloc_type
= BFD_RELOC_METAG_HI16_GOTOFF
;
1890 insn
->reloc_type
= BFD_RELOC_METAG_LO16_GOTOFF
;
1894 else if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
1897 insn
->reloc_type
= BFD_RELOC_METAG_HI16_PLT
;
1899 insn
->reloc_type
= BFD_RELOC_METAG_LO16_PLT
;
1903 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_LDO
)
1906 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LDO_HI16
;
1908 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LDO_LO16
;
1912 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_IENONPIC
)
1915 insn
->reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC_HI16
;
1917 insn
->reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC_LO16
;
1921 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_LE
)
1924 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LE_HI16
;
1926 insn
->reloc_type
= BFD_RELOC_METAG_TLS_LE_LO16
;
1930 else if (exp
->X_md
== BFD_RELOC_METAG_TLS_GD
||
1931 exp
->X_md
== BFD_RELOC_METAG_TLS_LDM
)
1932 insn
->reloc_type
= exp
->X_md
;
1936 if (exp
->X_op
== O_symbol
&& exp
->X_add_symbol
== GOT_symbol
)
1939 insn
->reloc_type
= BFD_RELOC_METAG_HI16_GOTPC
;
1941 insn
->reloc_type
= BFD_RELOC_METAG_LO16_GOTPC
;
1948 insn
->reloc_type
= BFD_RELOC_METAG_HIADDR16
;
1950 insn
->reloc_type
= BFD_RELOC_METAG_LOADDR16
;
1952 insn
->reloc_type
= BFD_RELOC_METAG_REL16
;
1956 insn
->reloc_pcrel
= 0;
1962 /* Parse a MOV to control unit instruction. */
1964 parse_mov_ct (const char *line
, metag_insn
*insn
,
1965 const insn_template
*template)
1967 const char *l
= line
;
1968 const metag_reg
*regs
[1];
1969 unsigned int top
= template->meta_opcode
& 0x1;
1970 unsigned int is_trace
= (template->meta_opcode
>> 2) & 0x1;
1971 unsigned int sign_extend
= 0;
1974 l
= parse_gp_regs (l
, regs
, 1);
1981 if (regs
[0]->unit
!= UNIT_TT
)
1986 if (regs
[0]->unit
!= UNIT_CT
)
1996 l
= parse_imm16 (l
, insn
, &value
);
2004 insn
->bits
= (template->meta_opcode
|
2005 (regs
[0]->no
<< 19) |
2006 ((value
& IMM16_MASK
) << 3));
2008 if (sign_extend
== 1 && top
== 0)
2009 insn
->bits
|= (1 << 1);
2015 /* Parse a SWAP instruction. */
2017 parse_swap (const char *line
, metag_insn
*insn
,
2018 const insn_template
*template)
2020 const char *l
= line
;
2021 const metag_reg
*regs
[2];
2023 l
= parse_gp_regs (l
, regs
, 2);
2028 /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit. */
2029 switch (regs
[0]->unit
)
2035 if (regs
[1]->unit
== UNIT_PC
2036 || regs
[1]->unit
== UNIT_CT
2037 || regs
[1]->unit
== UNIT_TR
2038 || regs
[1]->unit
== UNIT_TT
)
2040 as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
2045 /* Registers must be in different units. */
2046 if (regs
[0]->unit
== regs
[1]->unit
)
2048 as_bad (_("source and destination register must be in different units"));
2054 insn
->bits
= (template->meta_opcode
2055 | (regs
[1]->no
<< 19)
2056 | (regs
[0]->no
<< 14)
2057 | (regs
[1]->unit
<< 10)
2058 | (regs
[0]->unit
<< 5));
2064 /* Parse a JUMP instruction. */
2066 parse_jump (const char *line
, metag_insn
*insn
,
2067 const insn_template
*template)
2069 const char *l
= line
;
2070 const metag_reg
*regs
[1];
2073 l
= parse_gp_regs (l
, regs
, 1);
2078 if (!is_short_unit (regs
[0]->unit
))
2080 as_bad (_("register unit must be one of %s"), SHORT_UNITS
);
2090 l
= parse_imm16 (l
, insn
, &value
);
2095 insn
->bits
= (template->meta_opcode
|
2096 (regs
[0]->no
<< 19) |
2097 (regs
[0]->unit
& SHORT_UNIT_MASK
) |
2098 ((value
& IMM16_MASK
) << 3));
2104 /* Parse a 19bit immediate value. */
2106 parse_imm19 (const char *line
, metag_insn
*insn
, int *value
)
2108 const char *l
= line
;
2109 char *save_input_line_pointer
;
2110 expressionS
*exp
= &insn
->reloc_exp
;
2116 save_input_line_pointer
= input_line_pointer
;
2117 input_line_pointer
= (char *) l
;
2121 l
= input_line_pointer
;
2122 input_line_pointer
= save_input_line_pointer
;
2124 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
2128 else if (exp
->X_op
== O_constant
)
2130 *value
= exp
->X_add_number
;
2134 if (exp
->X_op
== O_PIC_reloc
)
2136 exp
->X_op
= O_symbol
;
2138 if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
2139 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH_PLT
;
2144 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH
;
2145 insn
->reloc_pcrel
= 1;
2151 /* Parse a CALLR instruction. */
2153 parse_callr (const char *line
, metag_insn
*insn
,
2154 const insn_template
*template)
2156 const char *l
= line
;
2157 const metag_reg
*regs
[1];
2160 l
= parse_gp_regs (l
, regs
, 1);
2165 if (!is_short_unit (regs
[0]->unit
))
2167 as_bad (_("link register unit must be one of %s"), SHORT_UNITS
);
2171 if (regs
[0]->no
& ~CALLR_REG_MASK
)
2173 as_bad (_("link register must be in a low numbered register"));
2183 l
= parse_imm19 (l
, insn
, &value
);
2188 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2190 as_bad (_("target out of range"));
2194 insn
->bits
= (template->meta_opcode
|
2195 (regs
[0]->no
& CALLR_REG_MASK
) |
2196 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3) |
2197 ((value
& IMM19_MASK
) << 5));
2203 /* Return the value for the register field if we apply the O2R modifier
2204 to operand 2 REG, combined with UNIT_BIT derived from the destination
2205 register or source1. Uses address unit O2R if IS_ADDR is set. */
2207 lookup_o2r (unsigned int is_addr
, unsigned int unit_bit
, const metag_reg
*reg
)
2209 if (reg
->no
& ~O2R_REG_MASK
)
2221 return (1 << 3) | reg
->no
;
2223 return (2 << 3) | reg
->no
;
2225 return (3 << 3) | reg
->no
;
2237 return (1 << 3) | reg
->no
;
2239 return (2 << 3) | reg
->no
;
2241 return (3 << 3) | reg
->no
;
2256 return (1 << 3) | reg
->no
;
2258 return (2 << 3) | reg
->no
;
2260 return (3 << 3) | reg
->no
;
2272 return (1 << 3) | reg
->no
;
2274 return (2 << 3) | reg
->no
;
2276 return (3 << 3) | reg
->no
;
2284 /* Parse GP ALU instruction. */
2286 parse_alu (const char *line
, metag_insn
*insn
,
2287 const insn_template
*template)
2289 const char *l
= line
;
2290 const metag_reg
*dest_regs
[1];
2291 const metag_reg
*src_regs
[2];
2293 unsigned int o1z
= 0;
2294 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2295 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2296 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2297 unsigned int top
= template->meta_opcode
& 0x1;
2298 unsigned int sign_extend
= 0;
2299 unsigned int is_addr_op
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
;
2300 unsigned int is_mul
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MUL
;
2301 unsigned int unit_bit
= 0;
2302 bfd_boolean is_quickrot
= template->arg_type
& GP_ARGS_QR
;
2304 l
= parse_gp_regs (l
, dest_regs
, 1);
2317 if (dest_regs
[0]->unit
== UNIT_A0
)
2319 else if (dest_regs
[0]->unit
== UNIT_A1
)
2324 if (dest_regs
[0]->unit
== UNIT_D0
)
2326 else if (dest_regs
[0]->unit
== UNIT_D1
)
2330 if ((MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
||
2331 MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
2332 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) &&
2333 ((template->meta_opcode
>> 2) & 0x1))
2342 if (dest_regs
[0]->unit
== UNIT_A0
)
2344 else if (dest_regs
[0]->unit
== UNIT_A1
)
2351 if (dest_regs
[0]->unit
== UNIT_D0
)
2353 else if (dest_regs
[0]->unit
== UNIT_D1
)
2362 l
= parse_gp_regs (l
, src_regs
, 1);
2375 if (src_regs
[0]->unit
== UNIT_A0
)
2377 else if (src_regs
[0]->unit
== UNIT_A1
)
2384 if (src_regs
[0]->unit
== UNIT_D0
)
2386 else if (src_regs
[0]->unit
== UNIT_D1
)
2392 if (src_regs
[0]->unit
!= dest_regs
[0]->unit
&& !ca
)
2395 l
= parse_imm8 (l
, insn
, &value
);
2400 if (!within_unsigned_range (value
, IMM8_BITS
))
2403 insn
->bits
= (template->meta_opcode
|
2404 (dest_regs
[0]->no
<< 19) |
2405 (src_regs
[0]->no
<< 14) |
2406 ((value
& IMM8_MASK
) << 6));
2412 if (src_regs
[0]->unit
== UNIT_A0
)
2414 else if (src_regs
[0]->unit
== UNIT_A1
)
2421 if (src_regs
[0]->unit
== UNIT_D0
)
2423 else if (src_regs
[0]->unit
== UNIT_D1
)
2429 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2434 l
= parse_imm16 (l
, insn
, &value
);
2441 if (!within_signed_range (value
, IMM16_BITS
))
2443 as_bad (_("immediate out of range"));
2450 if (!within_unsigned_range (value
, IMM16_BITS
))
2452 as_bad (_("immediate out of range"));
2457 insn
->bits
= (template->meta_opcode
|
2458 (dest_regs
[0]->no
<< 19) |
2459 ((value
& IMM16_MASK
) << 3));
2463 l
= parse_gp_regs (l
, src_regs
, 1);
2468 if (!(src_regs
[0]->unit
== dest_regs
[0]->unit
))
2471 /* CPC is valid for address ops. */
2472 if (src_regs
[0]->no
!= dest_regs
[0]->no
&&
2473 !(is_addr_op
&& src_regs
[0]->no
== 0x10))
2482 l
= parse_imm16 (l
, insn
, &value
);
2489 if (!within_signed_range (value
, IMM16_BITS
))
2491 as_bad (_("immediate out of range"));
2498 if (!within_unsigned_range (value
, IMM16_BITS
))
2500 as_bad (_("immediate out of range"));
2505 insn
->bits
= (template->meta_opcode
|
2506 (dest_regs
[0]->no
<< 19) |
2507 (src_regs
[0]->no
<< 19) |
2508 ((value
& IMM16_MASK
) << 3));
2513 unsigned int o2r
= 0;
2517 l
= parse_gp_regs (l
, src_regs
, 2);
2519 l
= parse_gp_regs (l
, src_regs
, 1);
2528 if (src_regs
[0]->unit
== UNIT_A0
)
2530 else if (src_regs
[0]->unit
== UNIT_A1
)
2537 if (src_regs
[0]->unit
== UNIT_D0
)
2539 else if (src_regs
[0]->unit
== UNIT_D1
)
2549 if (dest_regs
[0]->unit
== UNIT_A0
)
2551 else if (dest_regs
[0]->unit
== UNIT_A1
)
2558 if (dest_regs
[0]->unit
== UNIT_D0
)
2560 else if (dest_regs
[0]->unit
== UNIT_D1
)
2569 if (src_regs
[0]->unit
!= src_regs
[1]->unit
)
2571 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2580 rs2
= src_regs
[1]->no
;
2583 insn
->bits
= (template->meta_opcode
|
2584 (dest_regs
[0]->no
<< 19) |
2585 (src_regs
[0]->no
<< 14) |
2590 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
&& is_mul
)
2594 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2601 insn
->bits
|= dest_regs
[0]->unit
<< 5;
2605 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2607 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[0]);
2616 rs2
= src_regs
[0]->no
;
2619 insn
->bits
= (template->meta_opcode
|
2620 (dest_regs
[0]->no
<< 19) |
2625 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2628 if (dest_regs
[0]->unit
!= src_regs
[1]->unit
)
2630 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2639 rs2
= src_regs
[1]->no
;
2642 insn
->bits
= (template->meta_opcode
|
2643 (dest_regs
[0]->no
<< 19) |
2644 (src_regs
[0]->no
<< 14) |
2654 const metag_reg
*qr_regs
[1];
2655 bfd_boolean limit_regs
= imm
&& cond
;
2663 l
= parse_gp_regs (l
, qr_regs
, 1);
2668 if (!((unit_bit
== 0 && qr_regs
[0]->unit
!= UNIT_A0
) ||
2669 !(unit_bit
== 1 && qr_regs
[0]->unit
!= UNIT_A1
)))
2671 as_bad (_("invalid quickrot unit specified"));
2675 switch (qr_regs
[0]->no
)
2682 insn
->bits
|= (1 << 7);
2686 as_bad (_("invalid quickrot register specified"));
2691 if (sign_extend
== 1 && top
== 0)
2692 insn
->bits
|= (1 << 1);
2694 insn
->bits
|= unit_bit
<< 24;
2699 /* Parse a B instruction. */
2701 parse_branch (const char *line
, metag_insn
*insn
,
2702 const insn_template
*template)
2704 const char *l
= line
;
2707 l
= parse_imm19 (l
, insn
, &value
);
2712 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2714 as_bad (_("target out of range"));
2718 insn
->bits
= (template->meta_opcode
|
2719 ((value
& IMM19_MASK
) << 5));
2725 /* Parse a KICK instruction. */
2727 parse_kick (const char *line
, metag_insn
*insn
,
2728 const insn_template
*template)
2730 const char *l
= line
;
2731 const metag_reg
*regs
[2];
2733 l
= parse_gp_regs (l
, regs
, 2);
2738 if (regs
[1]->unit
!= UNIT_TR
)
2740 as_bad (_("source register must be in the trigger unit"));
2744 insn
->bits
= (template->meta_opcode
|
2745 (regs
[1]->no
<< 19) |
2746 (regs
[0]->no
<< 14) |
2747 (regs
[0]->unit
<< 5));
2753 /* Parse a SWITCH instruction. */
2755 parse_switch (const char *line
, metag_insn
*insn
,
2756 const insn_template
*template)
2758 const char *l
= line
;
2761 l
= parse_imm_constant (l
, insn
, &value
);
2766 if (!within_unsigned_range (value
, IMM24_BITS
))
2768 as_bad (_("target out of range"));
2772 insn
->bits
= (template->meta_opcode
|
2773 (value
& IMM24_MASK
));
2779 /* Parse a shift instruction. */
2781 parse_shift (const char *line
, metag_insn
*insn
,
2782 const insn_template
*template)
2784 const char *l
= line
;
2785 const metag_reg
*regs
[2];
2786 const metag_reg
*src2_regs
[1];
2788 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2789 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2790 unsigned int unit_bit
= 0;
2792 l
= parse_gp_regs (l
, regs
, 2);
2803 if (regs
[1]->unit
== UNIT_D0
)
2805 else if (regs
[1]->unit
== UNIT_D1
)
2810 if (regs
[0]->unit
!= regs
[1]->unit
&& !(cond
&& ca
))
2815 l
= parse_imm_constant (l
, insn
, &value
);
2820 if (!within_unsigned_range (value
, IMM5_BITS
))
2823 insn
->bits
= (template->meta_opcode
|
2825 (regs
[0]->no
<< 19) |
2826 (regs
[1]->no
<< 14) |
2827 ((value
& IMM5_MASK
) << 9));
2831 l
= parse_gp_regs (l
, src2_regs
, 1);
2836 insn
->bits
= (template->meta_opcode
|
2837 (regs
[0]->no
<< 19) |
2838 (regs
[1]->no
<< 14) |
2839 (src2_regs
[0]->no
<< 9));
2841 if (src2_regs
[0]->unit
!= regs
[1]->unit
)
2843 as_bad(_("Source registers must be in the same unit"));
2848 if (regs
[0]->unit
!= regs
[1]->unit
)
2852 if (regs
[1]->unit
== UNIT_D0
)
2854 else if (regs
[1]->unit
== UNIT_D1
)
2859 insn
->bits
|= ((1 << 5) |
2860 (regs
[0]->unit
<< 1));
2866 insn
->bits
|= unit_bit
<< 24;
2871 /* Parse a MIN or MAX instruction. */
2873 parse_min_max (const char *line
, metag_insn
*insn
,
2874 const insn_template
*template)
2876 const char *l
= line
;
2877 const metag_reg
*regs
[3];
2879 l
= parse_gp_regs (l
, regs
, 3);
2884 if (!(regs
[0]->unit
== UNIT_D0
||
2885 regs
[0]->unit
== UNIT_D1
))
2888 if (!(regs
[0]->unit
== regs
[1]->unit
&&
2889 regs
[1]->unit
== regs
[2]->unit
))
2892 insn
->bits
= (template->meta_opcode
|
2893 (regs
[0]->no
<< 19) |
2894 (regs
[1]->no
<< 14) |
2895 (regs
[2]->no
<< 9));
2897 if (regs
[0]->unit
== UNIT_D1
)
2898 insn
->bits
|= (1 << 24);
2904 /* Parse a bit operation instruction. */
2906 parse_bitop (const char *line
, metag_insn
*insn
,
2907 const insn_template
*template)
2909 const char *l
= line
;
2910 const metag_reg
*regs
[2];
2911 unsigned int swap_inst
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
;
2912 unsigned int is_bexl
= 0;
2915 ((template->meta_opcode
>> 1) & 0xb) == 0xa)
2918 l
= parse_gp_regs (l
, regs
, 2);
2923 if (!(regs
[0]->unit
== UNIT_D0
||
2924 regs
[0]->unit
== UNIT_D1
))
2929 if (regs
[0]->unit
== UNIT_D0
&&
2930 regs
[1]->unit
!= UNIT_D1
)
2932 else if (regs
[0]->unit
== UNIT_D1
&&
2933 regs
[1]->unit
!= UNIT_D0
)
2936 else if (!(regs
[0]->unit
== regs
[1]->unit
))
2939 insn
->bits
= (template->meta_opcode
|
2940 (regs
[0]->no
<< 19) |
2941 (regs
[1]->no
<< 14));
2945 if (regs
[1]->unit
== UNIT_D1
)
2950 if (regs
[1]->unit
== UNIT_D1
)
2951 insn
->bits
|= (1 << 24);
2958 /* Parse a CMP or TST instruction. */
2960 parse_cmp (const char *line
, metag_insn
*insn
,
2961 const insn_template
*template)
2963 const char *l
= line
;
2964 const metag_reg
*dest_regs
[1];
2965 const metag_reg
*src_regs
[1];
2967 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2968 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2969 unsigned int top
= template->meta_opcode
& 0x1;
2970 unsigned int sign_extend
= 0;
2971 unsigned int unit_bit
= 0;
2973 l
= parse_gp_regs (l
, dest_regs
, 1);
2984 if (dest_regs
[0]->unit
== UNIT_D0
)
2986 else if (dest_regs
[0]->unit
== UNIT_D1
)
2995 l
= parse_imm_constant (l
, insn
, &value
);
3000 if (!within_unsigned_range (value
, IMM8_BITS
))
3003 insn
->bits
= (template->meta_opcode
|
3004 (dest_regs
[0]->no
<< 14) |
3005 ((value
& IMM8_MASK
) << 6));
3010 l
= parse_imm16 (l
, insn
, &value
);
3017 if (!within_signed_range (value
, IMM16_BITS
))
3019 as_bad (_("immediate out of range"));
3026 if (!within_unsigned_range (value
, IMM16_BITS
))
3028 as_bad (_("immediate out of range"));
3033 insn
->bits
= (template->meta_opcode
|
3034 (dest_regs
[0]->no
<< 19) |
3035 ((value
& IMM16_MASK
) << 3));
3040 unsigned int o2r
= 0;
3043 l
= parse_gp_regs (l
, src_regs
, 1);
3048 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
3050 rs2
= lookup_o2r (0, unit_bit
, src_regs
[0]);
3059 rs2
= src_regs
[0]->no
;
3062 insn
->bits
= (template->meta_opcode
|
3063 (dest_regs
[0]->no
<< 14) |
3070 if (sign_extend
== 1 && top
== 0)
3071 insn
->bits
|= (1 << 1);
3073 insn
->bits
|= unit_bit
<< 24;
3078 /* Parse a CACHEW instruction. */
3080 parse_cachew (const char *line
, metag_insn
*insn
,
3081 const insn_template
*template)
3083 const char *l
= line
;
3084 const metag_reg
*src_regs
[2];
3085 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3089 memset(&addr
, 0, sizeof(addr
));
3090 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3092 l
= parse_addr (l
, &addr
, size
);
3095 !is_short_unit (addr
.base_reg
->unit
) ||
3099 as_bad (_("invalid memory operand"));
3110 l
= parse_gp_regs (l
, src_regs
, 1);
3112 l
= parse_pair_gp_regs (l
, src_regs
);
3115 !is_short_unit (src_regs
[0]->unit
))
3117 as_bad (_("invalid source register"));
3121 offset
= addr
.exp
.X_add_number
;
3126 offset
= offset
/ 64;
3128 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3130 as_bad (_("offset value out of range"));
3134 insn
->bits
= (template->meta_opcode
|
3135 (src_regs
[0]->no
<< 19) |
3136 (addr
.base_reg
->no
<< 14) |
3137 ((offset
& GET_SET_IMM_MASK
) << 8) |
3138 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3139 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3145 /* Parse a CACHEW instruction. */
3147 parse_cacher (const char *line
, metag_insn
*insn
,
3148 const insn_template
*template)
3150 const char *l
= line
;
3151 const metag_reg
*dest_regs
[2];
3152 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3156 memset(&addr
, 0, sizeof(addr
));
3157 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3160 l
= parse_gp_regs (l
, dest_regs
, 1);
3162 l
= parse_pair_gp_regs (l
, dest_regs
);
3165 !is_short_unit (dest_regs
[0]->unit
))
3167 as_bad (_("invalid destination register"));
3177 l
= parse_addr (l
, &addr
, size
);
3180 !is_short_unit (addr
.base_reg
->unit
) ||
3184 as_bad (_("invalid memory operand"));
3188 offset
= addr
.exp
.X_add_number
;
3193 offset
= offset
/ (int)size
;
3195 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3197 as_bad (_("offset value out of range"));
3201 insn
->bits
= (template->meta_opcode
|
3202 (dest_regs
[0]->no
<< 19) |
3203 (addr
.base_reg
->no
<< 14) |
3204 ((offset
& GET_SET_IMM_MASK
) << 8) |
3205 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3206 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3212 /* Parse an ICACHE instruction. */
3214 parse_icache (const char *line
, metag_insn
*insn
,
3215 const insn_template
*template)
3217 const char *l
= line
;
3221 l
= parse_imm_constant (l
, insn
, &offset
);
3226 if (!within_signed_range (offset
, IMM15_BITS
))
3231 l
= parse_imm_constant (l
, insn
, &pfcount
);
3236 if (!within_unsigned_range (pfcount
, IMM4_BITS
))
3239 insn
->bits
= (template->meta_opcode
|
3240 ((offset
& IMM15_MASK
) << 9) |
3241 ((pfcount
& IMM4_MASK
) << 1));
3247 /* Parse a LNKGET instruction. */
3249 parse_lnkget (const char *line
, metag_insn
*insn
,
3250 const insn_template
*template)
3252 const char *l
= line
;
3253 const metag_reg
*dest_regs
[2];
3254 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
3258 memset(&addr
, 0, sizeof(addr
));
3259 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3262 l
= parse_pair_gp_regs (l
, dest_regs
);
3264 l
= parse_gp_regs (l
, dest_regs
, 1);
3267 !is_short_unit (dest_regs
[0]->unit
))
3269 as_bad (_("invalid destination register"));
3279 l
= parse_addr (l
, &addr
, size
);
3282 !is_short_unit (addr
.base_reg
->unit
) ||
3286 as_bad (_("invalid memory operand"));
3290 offset
= addr
.exp
.X_add_number
;
3295 offset
= offset
/ size
;
3297 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3299 as_bad (_("offset value out of range"));
3303 insn
->bits
= (template->meta_opcode
|
3304 (dest_regs
[0]->no
<< 19) |
3305 (addr
.base_reg
->no
<< 14) |
3306 ((offset
& GET_SET_IMM_MASK
) << 8) |
3307 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3308 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3314 /* Parse an FPU MOV instruction. */
3316 parse_fmov (const char *line
, metag_insn
*insn
,
3317 const insn_template
*template)
3319 const char *l
= line
;
3320 const metag_reg
*regs
[2];
3322 l
= parse_fpu_regs (l
, regs
, 2);
3327 insn
->bits
= (template->meta_opcode
|
3328 (regs
[0]->no
<< 19) |
3329 (regs
[1]->no
<< 14));
3331 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3332 insn
->bits
|= (1 << 5);
3333 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3334 insn
->bits
|= (1 << 6);
3340 /* Parse an FPU MMOV instruction. */
3342 parse_fmmov (const char *line
, metag_insn
*insn
,
3343 const insn_template
*template)
3345 const char *l
= line
;
3346 bfd_boolean to_fpu
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
3347 bfd_boolean is_mmovl
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
3348 size_t regs_read
= 0;
3349 const metag_reg
*regs
[16];
3350 unsigned int lowest_data_reg
= 0xffffffff;
3351 unsigned int lowest_fpu_reg
= 0xffffffff;
3352 unsigned int rmask
= 0, data_unit
;
3356 if (insn
->fpu_width
!= FPU_WIDTH_SINGLE
)
3359 l
= parse_gp_regs_list (l
, regs
, 16, ®s_read
);
3369 for (i
= 0; i
< regs_read
/ 2; i
++)
3371 if (regs
[i
]->unit
!= UNIT_FX
)
3376 last_reg
= regs
[i
]->no
;
3377 lowest_fpu_reg
= last_reg
;
3383 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3386 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3389 last_reg
= regs
[i
]->no
;
3393 if (regs
[i
]->unit
== UNIT_D0
)
3395 else if (regs
[i
]->unit
== UNIT_D1
)
3400 if (!check_rmask (®s
[i
], regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3406 if (regs
[0]->unit
== UNIT_D0
)
3408 else if (regs
[0]->unit
== UNIT_D1
)
3413 if (!check_rmask (regs
, regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3417 for (i
= regs_read
/ 2; i
< regs_read
; i
++)
3419 if (regs
[i
]->unit
!= UNIT_FX
)
3424 last_reg
= regs
[i
]->no
;
3425 lowest_fpu_reg
= last_reg
;
3431 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3434 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3437 last_reg
= regs
[i
]->no
;
3442 insn
->bits
= (template->meta_opcode
|
3443 ((lowest_data_reg
& REG_MASK
) << 19) |
3444 ((lowest_fpu_reg
& REG_MASK
) << 14) |
3445 ((rmask
& RMASK_MASK
) << 7) |
3452 /* Parse an FPU data unit MOV instruction. */
3454 parse_fmov_data (const char *line
, metag_insn
*insn
,
3455 const insn_template
*template)
3457 const char *l
= line
;
3458 unsigned int to_fpu
= ((template->meta_opcode
>> 7) & 0x1);
3459 const metag_reg
*regs
[2];
3460 unsigned int base_unit
;
3462 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3465 l
= parse_gp_regs (l
, regs
, 2);
3472 if (regs
[0]->unit
!= UNIT_FX
)
3475 if (regs
[1]->unit
== UNIT_D0
)
3477 else if (regs
[1]->unit
== UNIT_D1
)
3484 if (regs
[0]->unit
== UNIT_D0
)
3486 else if (regs
[0]->unit
== UNIT_D1
)
3491 if (regs
[1]->unit
!= UNIT_FX
)
3495 insn
->bits
= (template->meta_opcode
|
3497 (regs
[0]->no
<< 19) |
3498 (regs
[1]->no
<< 9));
3504 /* Parse an FPU immediate MOV instruction. */
3506 parse_fmov_i (const char *line
, metag_insn
*insn
,
3507 const insn_template
*template)
3509 const char *l
= line
;
3510 const metag_reg
*regs
[1];
3513 l
= parse_fpu_regs (l
, regs
, 1);
3521 l
= parse_imm16 (l
, insn
, &value
);
3526 insn
->bits
= (template->meta_opcode
|
3527 (regs
[0]->no
<< 19) |
3528 ((value
& IMM16_MASK
) << 3));
3530 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3531 insn
->bits
|= (1 << 1);
3532 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3533 insn
->bits
|= (1 << 2);
3539 /* Parse an FPU PACK instruction. */
3541 parse_fpack (const char *line
, metag_insn
*insn
,
3542 const insn_template
*template)
3544 const char *l
= line
;
3545 const metag_reg
*regs
[3];
3547 l
= parse_fpu_regs (l
, regs
, 3);
3552 if (regs
[0]->no
% 2)
3554 as_bad (_("destination register should be even numbered"));
3558 insn
->bits
= (template->meta_opcode
|
3559 (regs
[0]->no
<< 19) |
3560 (regs
[1]->no
<< 14) |
3561 (regs
[2]->no
<< 9));
3567 /* Parse an FPU SWAP instruction. */
3569 parse_fswap (const char *line
, metag_insn
*insn
,
3570 const insn_template
*template)
3572 const char *l
= line
;
3573 const metag_reg
*regs
[2];
3575 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3578 l
= parse_fpu_regs (l
, regs
, 2);
3583 if (regs
[0]->no
% 2)
3586 if (regs
[1]->no
% 2)
3589 insn
->bits
= (template->meta_opcode
|
3590 (regs
[0]->no
<< 19) |
3591 (regs
[1]->no
<< 14));
3597 /* Parse an FPU CMP instruction. */
3599 parse_fcmp (const char *line
, metag_insn
*insn
,
3600 const insn_template
*template)
3602 const char *l
= line
, *l2
;
3603 const metag_reg
*regs1
[1];
3604 const metag_reg
*regs2
[1];
3606 l
= parse_fpu_regs (l
, regs1
, 1);
3614 l2
= parse_fpu_regs (l
, regs2
, 1);
3618 insn
->bits
= (regs2
[0]->no
<< 9);
3623 l2
= parse_imm_constant (l
, insn
, &constant
);
3624 if (!l2
|| constant
!= 0)
3626 as_bad (_("comparison must be with register or #0"));
3629 insn
->bits
= (1 << 8);
3632 insn
->bits
|= (template->meta_opcode
|
3633 (regs1
[0]->no
<< 14));
3635 if (insn
->fpu_action_flags
& FPU_ACTION_ABS
)
3636 insn
->bits
|= (1 << 19);
3638 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3639 insn
->bits
|= (1 << 7);
3641 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3642 insn
->bits
|= (1 << 6);
3643 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3644 insn
->bits
|= (1 << 5);
3650 /* Parse an FPU MIN or MAX instruction. */
3652 parse_fminmax (const char *line
, metag_insn
*insn
,
3653 const insn_template
*template)
3655 const char *l
= line
;
3656 const metag_reg
*regs
[3];
3658 l
= parse_fpu_regs (l
, regs
, 3);
3663 insn
->bits
= (template->meta_opcode
|
3664 (regs
[0]->no
<< 19) |
3665 (regs
[1]->no
<< 14) |
3666 (regs
[2]->no
<< 9));
3668 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3669 insn
->bits
|= (1 << 6);
3670 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3671 insn
->bits
|= (1 << 5);
3677 /* Parse an FPU data conversion instruction. */
3679 parse_fconv (const char *line
, metag_insn
*insn
,
3680 const insn_template
*template)
3682 const char *l
= line
;
3683 const metag_reg
*regs
[2];
3685 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3687 if (strncasecmp (template->name
, "FTOH", 4) &&
3688 strncasecmp (template->name
, "HTOF", 4) &&
3689 strncasecmp (template->name
, "FTOI", 4) &&
3690 strncasecmp (template->name
, "ITOF", 4))
3692 as_bad (_("instruction cannot operate on pair values"));
3697 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3699 if (strncasecmp (template->name
, "FTOI", 4) &&
3700 strncasecmp (template->name
, "DTOI", 4) &&
3701 strncasecmp (template->name
, "DTOL", 4))
3703 as_bad (_("zero flag is not valid for this instruction"));
3708 l
= parse_fpu_regs (l
, regs
, 2);
3713 if (!strncasecmp (template->name
, "DTOL", 4) ||
3714 !strncasecmp (template->name
, "LTOD", 4))
3716 if (regs
[0]->no
% 2)
3718 as_bad (_("destination register should be even numbered"));
3722 if (regs
[1]->no
% 2)
3724 as_bad (_("source register should be even numbered"));
3729 insn
->bits
= (template->meta_opcode
|
3730 (regs
[0]->no
<< 19) |
3731 (regs
[1]->no
<< 14));
3733 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3734 insn
->bits
|= (1 << 6);
3736 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3737 insn
->bits
|= (1 << 12);
3743 /* Parse an FPU extended data conversion instruction. */
3745 parse_fconvx (const char *line
, metag_insn
*insn
,
3746 const insn_template
*template)
3748 const char *l
= line
;
3749 const metag_reg
*regs
[2];
3750 int fraction_bits
= 0;
3752 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3754 if (strncasecmp (template->name
, "FTOX", 4) &&
3755 strncasecmp (template->name
, "XTOF", 4))
3757 as_bad (_("instruction cannot operate on pair values"));
3762 l
= parse_fpu_regs (l
, regs
, 2);
3770 l
= parse_imm_constant (l
, insn
, &fraction_bits
);
3775 insn
->bits
= (template->meta_opcode
|
3776 (regs
[0]->no
<< 19) |
3777 (regs
[1]->no
<< 14));
3779 if (strncasecmp (template->name
, "DTOXL", 5) &&
3780 strncasecmp (template->name
, "XLTOD", 5))
3782 if (!within_unsigned_range (fraction_bits
, IMM5_BITS
))
3784 as_bad (_("fraction bits value out of range"));
3787 insn
->bits
|= ((fraction_bits
& IMM5_MASK
) << 9);
3791 if (!within_unsigned_range (fraction_bits
, IMM6_BITS
))
3793 as_bad (_("fraction bits value out of range"));
3796 insn
->bits
|= ((fraction_bits
& IMM6_MASK
) << 8);
3799 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3800 insn
->bits
|= (1 << 6);
3806 /* Parse an FPU basic arithmetic instruction. */
3808 parse_fbarith (const char *line
, metag_insn
*insn
,
3809 const insn_template
*template)
3811 const char *l
= line
;
3812 const metag_reg
*regs
[3];
3814 l
= parse_fpu_regs (l
, regs
, 3);
3819 insn
->bits
= (template->meta_opcode
|
3820 (regs
[0]->no
<< 19) |
3821 (regs
[1]->no
<< 14) |
3822 (regs
[2]->no
<< 9));
3824 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3825 insn
->bits
|= (1 << 6);
3826 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3827 insn
->bits
|= (1 << 5);
3829 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3830 insn
->bits
|= (1 << 7);
3836 /* Parse a floating point accumulator name. */
3838 parse_acf (const char *line
, int *part
)
3840 const char *l
= line
;
3843 for (i
= 0; i
< sizeof(metag_acftab
)/sizeof(metag_acftab
[0]); i
++)
3845 const metag_acf
*acf
= &metag_acftab
[i
];
3846 size_t name_len
= strlen (acf
->name
);
3848 if (strncasecmp (l
, acf
->name
, name_len
) == 0)
3858 /* Parse an FPU extended arithmetic instruction. */
3860 parse_fearith (const char *line
, metag_insn
*insn
,
3861 const insn_template
*template)
3863 const char *l
= line
;
3864 const metag_reg
*regs
[3];
3865 bfd_boolean is_muz
= (MINOR_OPCODE (template->meta_opcode
) == 0x6 &&
3866 ((template->meta_opcode
>> 4) & 0x1));
3867 unsigned int is_o3o
= template->meta_opcode
& 0x1;
3868 unsigned int is_mac
= 0;
3869 unsigned int is_maw
= 0;
3871 if (!strncasecmp (template->name
, "MAW", 3))
3874 if (!strncasecmp (template->name
, "MAC", 3))
3877 l
= parse_acf (l
, &part
);
3879 if (l
== NULL
|| part
!= 0)
3884 l
= parse_fpu_regs (l
, ®s
[1], 2);
3890 if (is_o3o
&& is_maw
)
3891 l
= parse_fpu_regs (l
, regs
, 2);
3893 l
= parse_fpu_regs (l
, regs
, 3);
3899 if (is_o3o
&& is_maw
)
3900 insn
->bits
= (template->meta_opcode
|
3901 (regs
[1]->no
<< 9));
3903 insn
->bits
= (template->meta_opcode
|
3904 (regs
[1]->no
<< 14));
3906 if (!(is_o3o
&& is_maw
))
3907 insn
->bits
|= (regs
[2]->no
<< 9);
3909 if (is_o3o
&& is_maw
)
3910 insn
->bits
|= (regs
[0]->no
<< 14);
3912 insn
->bits
|= (regs
[0]->no
<< 19);
3914 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3915 insn
->bits
|= (1 << 6);
3916 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3917 insn
->bits
|= (1 << 5);
3919 if (!is_mac
&& !is_maw
)
3920 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3921 insn
->bits
|= (1 << 7);
3924 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3925 insn
->bits
|= (1 << 1);
3931 /* Parse an FPU RCP or RSQ instruction. */
3933 parse_frec (const char *line
, metag_insn
*insn
,
3934 const insn_template
*template)
3936 const char *l
= line
;
3937 const metag_reg
*regs
[2];
3939 l
= parse_fpu_regs (l
, regs
, 2);
3944 insn
->bits
= (template->meta_opcode
|
3945 (regs
[0]->no
<< 19) |
3946 (regs
[1]->no
<< 14));
3948 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3949 insn
->bits
|= (1 << 6);
3950 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3951 insn
->bits
|= (1 << 5);
3953 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3954 insn
->bits
|= (1 << 10);
3955 else if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3956 insn
->bits
|= (1 << 9);
3958 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3959 insn
->bits
|= (1 << 7);
3965 /* Parse an FPU vector arithmetic instruction. */
3967 parse_fsimd (const char *line
, metag_insn
*insn
,
3968 const insn_template
*template)
3970 const char *l
= line
;
3971 const metag_reg
*regs
[3];
3973 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3975 as_bad (_("simd instructions operate on pair values (L prefix)"));
3979 l
= parse_fpu_regs (l
, regs
, 3);
3984 if (regs
[0]->no
% 2)
3986 as_bad (_("destination register should be even numbered"));
3990 if ((regs
[1]->no
% 2) ||
3993 as_bad (_("source registers should be even numbered"));
3997 insn
->bits
= (template->meta_opcode
|
3998 (regs
[0]->no
<< 19) |
3999 (regs
[1]->no
<< 14) |
4000 (regs
[2]->no
<< 9));
4002 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
4003 insn
->bits
|= (1 << 7);
4009 /* Parse an FPU accumulator GET or SET instruction. */
4011 parse_fget_set_acf (const char *line
, metag_insn
*insn
,
4012 const insn_template
*template)
4014 const char *l
= line
;
4017 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
4019 memset(&addr
, 0, sizeof(addr
));
4020 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4024 l
= parse_acf (l
, &part
);
4031 l
= parse_mget_mset_addr (l
, &addr
);
4035 l
= parse_mget_mset_addr (l
, &addr
);
4042 l
= parse_acf (l
, &part
);
4048 insn
->bits
= (template->meta_opcode
|
4051 if (!is_short_unit (addr
.base_reg
->unit
))
4053 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
4057 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
4058 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
4064 /* Copy the name of the next register in LINE to REG_BUF. */
4066 strip_reg_name(const char *line
, char *reg_buf
)
4068 const char *l
= line
;
4071 while (is_register_char (*l
))
4076 if (!(len
< MAX_REG_LEN
))
4081 reg_buf
[len
] = '\0';
4086 /* Parse a DSP register from LINE into REG using only the registers
4087 from DSP_REGTAB. Return the next character or NULL. */
4089 __parse_dsp_reg (const char *line
, const metag_reg
**reg
, htab_t dsp_regtab
)
4091 const char *l
= line
;
4092 char name
[MAX_REG_LEN
];
4095 const metag_reg
*_reg
;
4097 /* We don't entirely strip the register name because we might
4098 actually want to match whole string in the register table,
4099 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4100 entry limits our comaprison to a reasonable bound anyway. */
4101 while (is_register_char (*l
) || *l
== PLUS
)
4106 if (!(len
< MAX_REG_LEN
))
4116 _reg
= (const metag_reg
*) htab_find (dsp_regtab
, &entry
);
4125 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4126 member is suitable for encoding into a DSP insn register field. */
4128 parse_dsp_insn_reg (const char *line
, const metag_reg
**reg
)
4130 return __parse_dsp_reg (line
, reg
, dsp_reg_htab
);
4133 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4134 member is suitable for encoding into a DSP template definition insn
4137 There is a separate table for whether we're doing a load or a store
4138 definition. "load" specifies which table to look at. */
4140 parse_dsp_template_reg (const char *line
, const metag_reg
**reg
,
4143 return __parse_dsp_reg (line
, reg
, dsp_tmpl_reg_htab
[load
]);
4146 /* Parse a single DSP register from LINE. */
4148 parse_dsp_reg (const char *line
, const metag_reg
**reg
,
4149 bfd_boolean tmpl
, bfd_boolean load
)
4152 return parse_dsp_template_reg (line
, reg
, load
);
4154 return parse_dsp_insn_reg (line
, reg
);
4157 /* Return TRUE if UNIT is an address unit. */
4159 is_addr_unit (enum metag_unit unit
)
4171 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4173 is_same_data_unit (enum metag_unit unit1
, enum metag_unit unit2
)
4181 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
)
4185 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
)
4189 if (unit2
== UNIT_D0
|| unit2
== UNIT_RAM_D0
)
4193 if (unit2
== UNIT_D1
|| unit2
== UNIT_RAM_D1
)
4197 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_D0
)
4201 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_D1
)
4211 /* Return TRUE if the register NUM is a quickrot control register. */
4213 is_quickrot_reg (unsigned int num
)
4225 /* Return TRUE if REG is an accumulator register. */
4227 is_accumulator_reg (const metag_reg
*reg
)
4229 if (reg
->unit
== UNIT_ACC_D0
|| reg
->unit
== UNIT_ACC_D1
)
4235 /* Return TRUE if REG is a DSP RAM register. */
4237 is_dspram_reg (const metag_reg
*reg
)
4239 if (reg
->unit
== UNIT_RAM_D0
|| reg
->unit
== UNIT_RAM_D1
)
4246 __parse_gp_reg (const char *line
, const metag_reg
**reg
, bfd_boolean load
)
4248 const char *l
= line
;
4249 char reg_buf
[MAX_REG_LEN
];
4255 /* Parse [DSPRAM.x]. */
4256 if (*l
== ADDR_BEGIN_CHAR
)
4263 l
= parse_dsp_reg (l
, reg
, TRUE
, load
);
4267 if (*l
== ADDR_END_CHAR
)
4271 as_bad (_("expected ']', not %c in %s"), *l
, l
);
4280 len
= strip_reg_name (l
, reg_buf
);
4285 *reg
= parse_gp_reg (reg_buf
);
4293 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4294 should try to parse the register as a general-purpose register if
4295 we fail to parse it as a DSP one. TMPL indicates whether the
4296 registers are part of a template definition instruction. If this is
4297 a template definition instruction LOAD says whether it's a load
4298 template insn. FIRST_DST indicates whether the first register is
4299 a destination operand. */
4301 parse_dsp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
4302 size_t *regs_read
, bfd_boolean try_gp
, bfd_boolean tmpl
,
4303 bfd_boolean load
, bfd_boolean first_dst
)
4305 const char *l
= line
;
4308 const metag_reg
*reg
;
4310 for (i
= 0; i
< count
; i
++)
4312 const char *next
, *ll
;
4321 *regs_read
= seen_regs
;
4326 ll
= parse_dsp_reg (l
, ®
, tmpl
, load
);
4332 l
= __parse_gp_reg (l
, ®
, !(first_dst
&& i
== 0));
4335 *regs_read
= seen_regs
;
4343 *regs_read
= seen_regs
;
4355 *regs_read
= seen_regs
;
4359 /* Parse the following memory references:
4370 - [DSPRam-DSPRam--] */
4372 parse_dsp_addr (const char *line
, metag_addr
*addr
, unsigned int size
,
4375 const char *l
= line
, *ll
;
4376 const metag_reg
*regs
[1];
4379 /* Skip opening square bracket. */
4382 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4387 if (!is_addr_unit (regs
[0]->unit
) &&
4388 !is_dspram_reg (regs
[0]))
4390 as_bad (_("invalid register for memory access"));
4394 addr
->base_reg
= regs
[0];
4396 if (*l
== ADDR_END_CHAR
)
4398 addr
->exp
.X_op
= O_constant
;
4399 addr
->exp
.X_add_symbol
= NULL
;
4400 addr
->exp
.X_op_symbol
= NULL
;
4402 /* Simple register with no offset (0 immediate). */
4403 addr
->exp
.X_add_number
= 0;
4405 addr
->immediate
= 1;
4411 ll
= parse_addr_post_incr_op (l
, addr
);
4413 if (ll
&& *ll
== ADDR_END_CHAR
)
4415 if (addr
->update
== 1)
4417 /* We have a post increment/decrement. */
4418 addr
->exp
.X_op
= O_constant
;
4419 addr
->exp
.X_add_number
= size
;
4420 addr
->exp
.X_add_symbol
= NULL
;
4421 addr
->exp
.X_op_symbol
= NULL
;
4422 addr
->post_increment
= 1;
4424 addr
->immediate
= 1;
4429 addr
->post_increment
= 0;
4431 l
= parse_addr_op (l
, addr
);
4436 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4441 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
4443 as_bad (_("offset and base must be from the same unit"));
4447 addr
->offset_reg
= regs
[0];
4449 if (*l
== ADDR_END_CHAR
)
4455 l
= parse_addr_post_incr_op (l
, addr
);
4460 if (*l
== ADDR_END_CHAR
)
4469 /* Parse a DSP GET or SET instruction. */
4471 parse_dget_set (const char *line
, metag_insn
*insn
,
4472 const insn_template
*template)
4474 const char *l
= line
;
4478 bfd_boolean is_get
= (template->meta_opcode
& 0x100);
4479 bfd_boolean is_dual
= (template->meta_opcode
& 0x4);
4480 bfd_boolean is_template
= FALSE
;
4481 const metag_reg
*regs
[2];
4483 size_t count
, regs_read
;
4485 memset(&addr
, 0, sizeof(addr
));
4486 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4488 size
= is_dual
? 8 : 4;
4489 count
= is_dual
? 2 : 1;
4493 /* GETL can be used on one template table entry. */
4497 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
,
4498 FALSE
, FALSE
, FALSE
);
4503 as_bad (_("unexpected end of line"));
4507 l
= parse_addr (l
, &addr
, size
);
4511 l
= parse_addr (l
, &addr
, size
);
4518 /* GETL can be used on one template table entry. */
4522 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
, FALSE
,
4529 /* The first register dictates the unit. */
4530 if (regs
[0]->unit
== UNIT_DT
)
4534 if (regs
[0]->unit
== UNIT_D0
|| regs
[0]->unit
== UNIT_RAM_D0
||
4535 regs
[0]->unit
== UNIT_ACC_D0
)
4541 rd_reg
= regs
[0]->no
;
4543 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4544 upper 8-bits of an accumulator. It is _only_ valid for the
4546 if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
)
4548 if (is_template
|| !(rd_reg
>= 16 && rd_reg
< 20))
4550 as_bad (_("'H' modifier only valid for accumulator registers"));
4554 /* Top 8-bits of the accumulator. */
4560 insn
->bits
= (template->meta_opcode
| (1 << 1));
4564 insn
->bits
= (template->meta_opcode
| unit
);
4567 insn
->bits
|= (rd_reg
<< 19);
4571 int offset
= addr
.exp
.X_add_number
;
4576 offset
= offset
/ (int)size
;
4578 if (!within_signed_range (offset
, DGET_SET_IMM_BITS
))
4580 as_bad (_("offset value out of range"));
4584 offset
= offset
& DGET_SET_IMM_MASK
;
4586 insn
->bits
|= (1 << 13);
4587 insn
->bits
|= (offset
<< 9);
4591 int au
= (addr
.base_reg
->unit
== UNIT_A1
);
4593 insn
->bits
|= (au
<< 18);
4594 insn
->bits
|= ((addr
.base_reg
->no
& REG_MASK
) << 14);
4595 insn
->bits
|= ((addr
.offset_reg
->no
& REG_MASK
) << 9);
4599 insn
->bits
|= (1 << 2);
4601 if (!is_addr_unit (addr
.base_reg
->unit
))
4603 as_bad (_("base unit must be either A0 or A1"));
4607 unit
= (addr
.base_reg
->unit
== UNIT_A0
) ? 0 : 1;
4608 insn
->bits
|= ((addr
.base_reg
->no
<< 14) | (unit
<< 18));
4615 /* Parse a DSP template instruction. */
4617 parse_dtemplate (const char *line
, metag_insn
*insn
,
4618 const insn_template
*template)
4620 const char *l
= line
;
4621 const metag_reg
*regs
[TEMPLATE_NUM_REGS
];
4622 bfd_boolean daop_only
= FALSE
;
4624 int regs_which
[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4627 for (i
= 0; i
< TEMPLATE_NUM_REGS
; i
++)
4631 as_bad (_("unexpected end of line"));
4635 /* We may only have 3 register operands. */
4636 if (*l
== END_OF_INSN
&& i
== 3)
4651 l
= parse_imm_constant (l
, insn
, ®s_val
[i
]);
4654 as_bad (_("invalid immediate"));
4661 /* We can't tell from the template instantiation whether
4662 this is a load or store. So we have to try looking up the
4663 register name in both the load and store tables. */
4665 l
= __parse_gp_reg (l
, ®s
[i
], TRUE
);
4668 /* Try the store table too. */
4669 l
= __parse_gp_reg (l2
, ®s
[i
], FALSE
);
4672 /* Then try a DSP register. */
4673 l
= parse_dsp_insn_reg (l2
, ®s
[i
]);
4674 if (l
== NULL
|| regs
[i
]->unit
== UNIT_DT
)
4676 as_bad (_("invalid register"));
4685 insn
->bits
= template->meta_opcode
;
4687 if (regs_which
[0] == 0)
4688 insn
->bits
|= (regs_val
[0] << 19);
4689 else if (regs_which
[0] == 1)
4690 insn
->bits
|= (regs
[0]->no
<< 19);
4692 if (regs_which
[1] == 0)
4693 insn
->bits
|= (regs_val
[1] << 14);
4694 else if (regs_which
[1] == 1)
4695 insn
->bits
|= (regs
[1]->no
<< 14);
4697 if (regs_which
[2] == 0)
4698 insn
->bits
|= (regs_val
[2] << 9);
4699 else if (regs_which
[2] == 1)
4700 insn
->bits
|= (regs
[2]->no
<< 9);
4702 if (regs_which
[3] == 0)
4703 insn
->bits
|= (regs_val
[3] << 4);
4704 else if (regs_which
[3] == 1)
4705 insn
->bits
|= (regs
[3]->no
<< 4);
4709 insn
->bits
|= (0x3 << 24); /* Set the minor opcode. */
4710 else if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
) /* Half Load/Store. */
4711 insn
->bits
|= (0x5 << 24); /* Set the minor opcode. */
4718 /* Parse a DSP Template definiton memory reference, e.g
4719 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4720 template definition is a DSP RAM template definition. */
4722 template_mem_ref(const char *line
, metag_addr
*addr
,
4723 bfd_boolean
*dspram
, int size
, bfd_boolean load
)
4725 const char *l
= line
;
4727 l
= parse_dsp_addr (l
, addr
, size
, load
);
4731 if (is_addr_unit(addr
->base_reg
->unit
))
4740 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4741 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4743 parse_template_regs (const char *line
, bfd_boolean
*load
,
4744 unsigned int *addr_unit
,
4745 const metag_reg
**template_reg
, metag_addr
*addr
,
4746 bfd_boolean
*dspram
, int size
)
4748 const char *l
= line
;
4753 /* DSP Template load definition (Tx, [Ax]) */
4757 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4763 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4765 if (addr
->base_reg
->unit
== UNIT_A1
)
4769 else if (*l
== ADDR_BEGIN_CHAR
) /* DSP Template store ([Ax], Tx) */
4772 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4778 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4782 if (addr
->base_reg
->unit
== UNIT_A1
)
4787 as_bad (_("invalid register operand"));
4794 #define INVALID_SHIFT (-1)
4796 static metag_reg _reg
;
4798 /* Parse a template instruction definition. */
4800 interpret_template_regs(const char *line
, metag_insn
*insn
,
4801 const metag_reg
**regs
,
4802 int *regs_shift
, bfd_boolean
*load
, bfd_boolean
*dspram
,
4803 int size
, int *ls_shift
, int *au_shift
,
4804 unsigned int *au
, int *imm
, int *imm_shift
,
4805 unsigned int *imm_mask
)
4807 const char *l
= line
;
4809 const metag_reg
*template_reg
[1];
4811 memset (&addr
, 0, sizeof(addr
));
4814 regs_shift
[1] = INVALID_SHIFT
;
4816 insn
->bits
|= (1 << 1);
4818 l
= skip_whitespace (l
);
4820 l
= parse_template_regs (l
, load
, au
, template_reg
,
4821 &addr
, dspram
, size
);
4824 as_bad (_("could not parse template definition"));
4828 regs
[2] = template_reg
[0];
4831 /* DSPRAM definition. */
4835 _reg
= *addr
.base_reg
;
4839 /* Set the post-increment bit in the register field. */
4845 /* The bottom bit of the increment register tells us
4846 whether it's increment register 0 or 1. */
4847 if (addr
.offset_reg
->no
& 0x1)
4855 insn
->bits
|= (0x3 << 17); /* This signifies a DSPRAM definition. */
4857 else /* DaOpPaMe definition. */
4859 regs
[0] = addr
.base_reg
;
4862 /* Set the I bit. */
4863 insn
->bits
|= (1 << 18);
4865 if (addr
.update
== 1)
4867 if (addr
.negate
== 1)
4878 /* Setup the offset register. */
4879 regs
[1] = addr
.offset_reg
;
4890 /* Does this combination of units need the O2R bit and can it be encoded? */
4892 units_need_o2r (enum metag_unit unit1
, enum metag_unit unit2
)
4897 if (unit1
== UNIT_D0
|| unit1
== UNIT_ACC_D0
|| unit1
== UNIT_RAM_D0
)
4899 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
|| unit2
== UNIT_D0
)
4914 if (unit1
== UNIT_D1
|| unit1
== UNIT_ACC_D1
|| unit1
== UNIT_RAM_D1
)
4916 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
|| unit2
== UNIT_D1
)
4934 /* Return TRUE if this is a DSP data unit. */
4936 is_dsp_data_unit (const metag_reg
*reg
)
4952 static metag_reg o2r_reg
;
4954 /* Parse a DaOpPaMe load template definition. */
4956 parse_dalu (const char *line
, metag_insn
*insn
,
4957 const insn_template
*template)
4959 const char *l
= line
;
4961 const metag_reg
*regs
[4];
4964 bfd_boolean is_mov
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
;
4965 bfd_boolean is_cmp
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_CMP
) &&
4966 ((template->meta_opcode
& 0xee) == 0));
4967 bfd_boolean is_dual
= (insn
->dsp_width
== DSP_WIDTH_DUAL
);
4968 bfd_boolean is_quickrot64
= ((insn
->dsp_action_flags
& DSP_ACTION_QR64
) != 0);
4969 int l1_shift
= INVALID_SHIFT
;
4970 bfd_boolean load
= FALSE
;
4971 int ls_shift
= INVALID_SHIFT
;
4972 bfd_boolean ar
= FALSE
;
4973 int ar_shift
= INVALID_SHIFT
;
4974 int regs_shift
[3] = { INVALID_SHIFT
, INVALID_SHIFT
, INVALID_SHIFT
};
4976 int imm_shift
= INVALID_SHIFT
;
4977 unsigned int imm_mask
= 0;
4978 unsigned int au
= 0;
4979 int au_shift
= INVALID_SHIFT
;
4980 unsigned int du
= 0;
4981 int du_shift
= INVALID_SHIFT
;
4982 unsigned int sc
= ((insn
->dsp_action_flags
& DSP_ACTION_OV
) != 0);
4983 int sc_shift
= INVALID_SHIFT
;
4984 unsigned int om
= ((insn
->dsp_action_flags
& DSP_ACTION_MOD
) != 0);
4985 int om_shift
= INVALID_SHIFT
;
4986 unsigned int o2r
= 0;
4987 int o2r_shift
= INVALID_SHIFT
;
4988 unsigned int qr
= 0;
4989 int qr_shift
= INVALID_SHIFT
;
4990 int qd_shift
= INVALID_SHIFT
;
4991 unsigned int qn
= 0;
4992 int qn_shift
= INVALID_SHIFT
;
4993 unsigned int a1
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ZERO
)) != 0);
4994 int a1_shift
= INVALID_SHIFT
;
4995 unsigned int a2
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
)) != 0);
4996 int a2_shift
= INVALID_SHIFT
;
4997 unsigned su
= ((insn
->dsp_action_flags
& DSP_ACTION_UMUL
) != 0);
4998 int su_shift
= INVALID_SHIFT
;
5000 int ac_shift
= INVALID_SHIFT
;
5001 unsigned int mx
= (((insn
->dsp_daoppame_flags
& DSP_DAOPPAME_8
) != 0) ||
5002 (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_16
) != 0);
5003 int mx_shift
= INVALID_SHIFT
;
5004 int size
= is_dual
? 8 : 4;
5006 bfd_boolean conditional
= (MINOR_OPCODE (template->meta_opcode
) & 0x4);
5008 /* XFIXME: check the flags are valid with the instruction. */
5009 if (is_quickrot64
&& !(template->arg_type
& DSP_ARGS_QR
))
5011 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5015 insn
->bits
= template->meta_opcode
;
5017 memset (regs
, 0, sizeof (regs
));
5018 memset (&addr
, 0, sizeof (addr
));
5020 /* There are the following forms of DSP ALU instructions,
5023 19. D[T] Op De.r,Dx.r,De.r
5024 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5025 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5026 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5027 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5028 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5029 8. D Opcc De.r,Dx.r,Rx.r
5030 6. D Op De.r,Dx.r,Rx.r|RD
5031 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5032 7. D Op De.e,Dx.r,#I16
5035 4. D[T] Op Dx.r,De.r
5036 10. D Op Dx.r,Rx.r|RD
5039 12. D[T] Op De.r,Dx.r
5040 14. D Op DSPe.r,Dx.r
5041 15. D Op DSPx.r,#I16
5042 16. D Op De.r,DSPx.r
5043 18. D Op De.r,Dx.r|ACx.r
5046 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5047 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5048 21. D Op De.r,Dx.r|ACx.r,#I5 */
5051 if (template->arg_type
& DSP_ARGS_1
)
5055 /* Could this be a cross-unit accumulator op,
5056 e.g. ACe.e,ACx.r,ACo.e */
5057 if (template->arg_type
& DSP_ARGS_XACC
)
5059 ll
= parse_dsp_regs_list (l
, regs
, 3, ®s_read
, FALSE
, FALSE
,
5061 if (ll
!= NULL
&& regs_read
== 3
5062 && is_accumulator_reg (regs
[0]))
5064 if (regs
[0]->unit
!= regs
[1]->unit
||
5065 regs
[2]->unit
== regs
[1]->unit
)
5067 as_bad (_("invalid operands for cross-unit op"));
5071 du
= (regs
[1]->unit
== UNIT_ACC_D1
);
5075 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5076 insn
->bits
|= (5 << 6);
5078 goto check_for_template
;
5081 /* If we reach here, this instruction is not a
5082 cross-unit accumulator op. */
5085 if (template->arg_type
& DSP_ARGS_SPLIT8
)
5092 /* De.r|ACe.r,Dx.r,De.r */
5093 if (template->arg_type
& DSP_ARGS_DACC
)
5095 /* XFIXME: these need moving? */
5101 ll
= parse_dsp_reg (l
, ®s
[0], FALSE
, FALSE
);
5104 /* Using ACe.r as the dst requires one of the P,N or Z
5105 flags to be used. */
5106 if (!(insn
->dsp_action_flags
&
5107 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5109 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5115 l
= parse_dsp_regs_list (l
, ®s
[1], 2, ®s_read
,
5116 TRUE
, FALSE
, FALSE
, FALSE
);
5117 if (l
== NULL
|| regs_read
!= 2)
5119 as_bad (_("invalid register"));
5123 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5129 goto check_for_template
;
5132 /* If we reach here, this instruction does not use the
5133 accumulator as the destination register. */
5134 if ((insn
->dsp_action_flags
&
5135 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5137 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5145 l
= parse_dsp_regs_list (l
, regs
, 2, ®s_read
, TRUE
, FALSE
, FALSE
, TRUE
);
5146 if (l
== NULL
|| regs_read
!= 2)
5153 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5156 if (is_accumulator_reg(regs
[0]) && !(template->arg_type
& DSP_ARGS_DACC
))
5158 as_bad (_("accumulator not a valid destination"));
5162 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5165 l
= parse_imm16 (l
, insn
, &imm
);
5168 as_bad (_("invalid immediate value"));
5172 if (!within_signed_range (imm
, IMM16_BITS
))
5174 as_bad (_("immediate value out of range"));
5178 if (regs
[0]->unit
!= regs
[1]->unit
|| regs
[0]->no
!= regs
[1]->no
)
5180 as_bad (_("immediate value not allowed when source & dest differ"));
5188 insn
->bits
|= (1 << 25);
5190 insn
->bits
|= (0x3 << 0);
5194 /* Remove any bits that have been set in the immediate
5196 insn
->bits
&= ~(imm_mask
<< imm_shift
);
5204 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5205 ll
= parse_dsp_reg (l
, ®s
[2], FALSE
, FALSE
);
5210 if (!(template->arg_type
& DSP_ARGS_ACC2
))
5212 as_bad (_("invalid register operand: %s"), regs
[2]->name
);
5222 /* De.r,Dx.r,De.r */
5223 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5228 if (template->arg_type
& DSP_ARGS_ACC2
)
5231 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5232 if (template->arg_type
& DSP_ARGS_QR
)
5246 as_bad (_("QUICKRoT extension requires 4 registers"));
5250 l
= __parse_gp_reg (l
, ®s
[3], TRUE
);
5253 as_bad (_("invalid fourth register"));
5257 if (!is_addr_unit (regs
[3]->unit
) ||
5258 !is_quickrot_reg (regs
[3]->no
))
5260 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5264 qn
= (regs
[3]->no
== 3);
5269 /* This is the common exit path. Check for o2r. */
5270 if (regs
[2] != NULL
)
5272 o2r
= units_need_o2r (regs
[1]->unit
, regs
[2]->unit
);
5275 o2r_reg
.no
= lookup_o2r (0, du
, regs
[2]);
5276 o2r_reg
.unit
= regs
[2]->unit
;
5281 /* Check any DSP RAM pointers are valid for this unit. */
5282 if ((du
&& (regs
[0]->unit
== UNIT_RAM_D0
)) ||
5283 (!du
&& (regs
[0]->unit
== UNIT_RAM_D1
)) ||
5284 (du
&& (regs
[1]->unit
== UNIT_RAM_D0
)) ||
5285 (!du
&& (regs
[1]->unit
== UNIT_RAM_D1
)) ||
5286 (du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D0
)) ||
5287 (!du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D1
))) {
5288 as_bad (_("DSP RAM pointer in incorrect unit"));
5292 /* Is this a template definition? */
5293 if (IS_TEMPLATE_DEF (insn
))
5295 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5296 &dspram
, size
, &ls_shift
, &au_shift
,
5297 &au
, &imm
, &imm_shift
, &imm_mask
);
5310 if (template->arg_type
& DSP_ARGS_2
)
5312 bfd_boolean is_xsd
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
) &&
5313 (MINOR_OPCODE (template->meta_opcode
) == 0xa));
5314 bfd_boolean is_fpu_mov
= template->insn_type
== INSN_DSP_FPU
;
5315 bfd_boolean to_fpu
= (template->meta_opcode
>> 7) & 0x1;
5324 /* CMPs and TSTs don't store to their destination operand. */
5325 ll
= __parse_gp_reg (l
, regs
, is_cmp
);
5328 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5329 if (template->arg_type
& DSP_ARGS_DSP_SRC1
)
5331 l
= parse_dsp_reg (l
, regs
, FALSE
, FALSE
);
5334 as_bad (_("invalid register operand #1"));
5338 /* Only MOV instructions have a DSP register as a
5339 destination. Set the MOV DSPe.r opcode. The simple
5340 OR'ing is OK because the usual MOV opcode is 0x00. */
5341 insn
->bits
= (0x91 << 24);
5348 as_bad (_("invalid register operand #2"));
5356 /* Everything but CMP and TST. */
5357 if (MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
5358 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5359 MAJOR_OPCODE (insn
->bits
) == OPC_9
||
5360 MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
||
5361 ((template->meta_opcode
& 0x0000002c) != 0))
5367 if (!is_dsp_data_unit (regs
[0]) && !(regs
[0]->unit
== UNIT_FX
&&
5368 is_fpu_mov
&& to_fpu
))
5371 du
= (regs
[0]->unit
== UNIT_D1
|| regs
[0]->unit
== UNIT_RAM_D1
||
5372 regs
[0]->unit
== UNIT_ACC_D1
);
5378 if (template->arg_type
& DSP_ARGS_IMM
&&
5379 !(is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)))
5381 l
= parse_imm16 (l
, insn
, &imm
);
5384 as_bad (_("invalid immediate value"));
5388 if (!within_signed_range (imm
, IMM16_BITS
))
5397 /* Set the I-bit unless it's a MOV because they're
5399 if (!(is_mov
&& MAJOR_OPCODE (insn
->bits
) == OPC_9
))
5400 insn
->bits
|= (1 << 25);
5402 /* All instructions that takes immediates also have bit 1 set. */
5403 insn
->bits
|= (1 << 1);
5405 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5406 insn
->bits
|= (1 << 0);
5408 insn
->bits
&= ~(1 << 8);
5412 as_bad (_("this instruction does not accept an immediate"));
5418 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5420 insn
->bits
|= (1 << 8);
5424 ll
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5427 if (template->arg_type
& DSP_ARGS_DSP_SRC2
)
5429 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5432 as_bad (_("invalid register operand #3"));
5437 if ((is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)) ||
5438 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
)
5440 if (is_accumulator_reg (regs
[1]))
5444 as_bad (_("this instruction does not accept an accumulator"));
5456 insn
->bits
= (0x92 << 24); /* Set opcode. */
5462 as_bad (_("invalid register operand #4"));
5468 /* Set the o2r bit if required. */
5469 if (!is_fpu_mov
&& units_need_o2r (regs
[0]->unit
, regs
[1]->unit
))
5472 o2r_reg
.no
= lookup_o2r (0, du
, regs
[1]);
5477 else if (!is_dsp_data_unit (regs
[1]) &&
5478 !(is_fpu_mov
&& !to_fpu
&& regs
[1]->unit
== UNIT_FX
))
5481 if (is_fpu_mov
&& to_fpu
)
5482 du
= (regs
[1]->unit
== UNIT_D1
||
5483 regs
[1]->unit
== UNIT_RAM_D1
||
5484 regs
[1]->unit
== UNIT_ACC_D1
);
5488 if (MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5489 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5490 (((template->meta_opcode
& 0x0000002c) == 0) &&
5491 MAJOR_OPCODE (template->meta_opcode
) != OPC_MISC
))
5498 /* If it's an 0x0 MOV or NEG set some lower bits. */
5499 if ((MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5500 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) && !is_fpu_mov
)
5504 insn
->bits
|= (1 << 2);
5507 /* Check for template definitons. */
5508 if (IS_TEMPLATE_DEF (insn
))
5510 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5511 &dspram
, size
, &ls_shift
, &au_shift
,
5512 &au
, &imm
, &imm_shift
, &imm_mask
);
5525 l
= __parse_gp_reg (l
, regs
, FALSE
);
5528 as_bad (_("invalid register operand"));
5536 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5539 as_bad (_("invalid accumulator register"));
5547 l
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5550 as_bad (_("invalid register operand"));
5558 du
= (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_ACC_D1
5559 || regs
[1]->unit
== UNIT_RAM_D1
);
5565 l
= parse_imm_constant (l
, insn
, &imm
);
5568 as_bad (_("invalid immediate value"));
5572 if (!within_unsigned_range (imm
, IMM5_BITS
))
5579 insn
->bits
|= (1 << 25);
5584 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5589 /* Check for post-processing R,G,B flags. Conditional instructions
5590 do not have these bits. */
5591 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP9
)
5593 if ((template->meta_opcode
>> 26) & 0x1)
5595 as_bad (_("conditional instruction cannot use G flag"));
5599 insn
->bits
|= (1 << 3);
5602 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP8
)
5604 if ((template->meta_opcode
>> 26) & 0x1)
5606 as_bad (_("conditional instruction cannot use B flag"));
5610 insn
->bits
|= (0x3 << 2);
5613 if (insn
->dsp_action_flags
& DSP_ACTION_ROUND
)
5615 if ((template->meta_opcode
>> 26) & 0x1)
5617 as_bad (_("conditional instruction cannot use R flag"));
5620 insn
->bits
|= (1 << 2);
5623 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5624 if ((template->meta_opcode
>> 26) & 0x1)
5625 ls_shift
= INVALID_SHIFT
;
5627 /* The Condition Is Always (CA) bit must be set if we're targetting a
5628 Ux.r register as the destination. This means that we can't have
5629 any other condition bits set. */
5630 if (!is_same_data_unit (regs
[1]->unit
, regs
[0]->unit
))
5632 /* Set both the Conditional bit and the Condition is Always bit. */
5633 insn
->bits
|= (1 << 26);
5634 insn
->bits
|= (1 << 5);
5636 /* Fill out the Ud field. */
5637 insn
->bits
|= (regs
[0]->unit
<< 1);
5640 if (IS_TEMPLATE_DEF (insn
))
5642 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5643 &dspram
, size
, &ls_shift
, &au_shift
,
5644 &au
, &imm
, &imm_shift
, &imm_mask
);
5656 /* Set the registers and immediate values. */
5657 if (regs_shift
[0] != INVALID_SHIFT
)
5658 insn
->bits
|= (regs
[0]->no
<< regs_shift
[0]);
5660 if (regs_shift
[1] != INVALID_SHIFT
)
5661 insn
->bits
|= (regs
[1]->no
<< regs_shift
[1]);
5663 if (regs_shift
[2] != INVALID_SHIFT
)
5664 insn
->bits
|= (regs
[2]->no
<< regs_shift
[2]);
5666 /* Does this insn have an 'IMM' bit? The immediate value should
5667 already have been masked. */
5668 if (imm_shift
!= INVALID_SHIFT
)
5669 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5671 /* Does this insn have an 'AU' bit? */
5672 if (au_shift
!= INVALID_SHIFT
)
5673 insn
->bits
|= (au
<< au_shift
);
5675 /* Does this instruction have an 'LS' bit? */
5676 if (ls_shift
!= INVALID_SHIFT
)
5677 insn
->bits
|= (load
<< ls_shift
);
5679 /* Does this instruction have an 'AR' bit? */
5681 insn
->bits
|= (1 << ar_shift
);
5683 if (du_shift
!= INVALID_SHIFT
)
5684 insn
->bits
|= (du
<< du_shift
);
5686 if (sc_shift
!= INVALID_SHIFT
)
5687 insn
->bits
|= (sc
<< sc_shift
);
5689 if (om_shift
!= INVALID_SHIFT
)
5690 insn
->bits
|= (om
<< om_shift
);
5692 if (o2r_shift
!= INVALID_SHIFT
)
5693 insn
->bits
|= (o2r
<< o2r_shift
);
5695 if (qn_shift
!= INVALID_SHIFT
)
5696 insn
->bits
|= (qn
<< qn_shift
);
5698 if (qr_shift
!= INVALID_SHIFT
)
5699 insn
->bits
|= (qr
<< qr_shift
);
5701 if (qd_shift
!= INVALID_SHIFT
)
5702 insn
->bits
|= (is_quickrot64
<< qd_shift
);
5704 if (a1_shift
!= INVALID_SHIFT
)
5705 insn
->bits
|= (a1
<< a1_shift
);
5707 if (a2_shift
!= INVALID_SHIFT
)
5708 insn
->bits
|= (a2
<< a2_shift
);
5710 if (su_shift
!= INVALID_SHIFT
)
5711 insn
->bits
|= (su
<< su_shift
);
5713 if (imm_shift
!= INVALID_SHIFT
)
5714 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5716 if (ac_shift
!= INVALID_SHIFT
)
5717 insn
->bits
|= (ac
<< ac_shift
);
5719 if (mx_shift
!= INVALID_SHIFT
)
5720 insn
->bits
|= (mx
<< mx_shift
);
5724 if (l1_shift
== INVALID_SHIFT
)
5726 as_bad (_("'L' modifier not valid for this instruction"));
5730 insn
->bits
|= (1 << l1_shift
);
5738 typedef const char *(*insn_parser
)(const char *, metag_insn
*,
5739 const insn_template
*);
5742 static const insn_parser insn_parsers
[ENC_MAX
] =
5744 [ENC_NONE
] = parse_none
,
5745 [ENC_MOV_U2U
] = parse_mov_u2u
,
5746 [ENC_MOV_PORT
] = parse_mov_port
,
5747 [ENC_MMOV
] = parse_mmov
,
5748 [ENC_MDRD
] = parse_mdrd
,
5749 [ENC_MOVL_TTREC
] = parse_movl_ttrec
,
5750 [ENC_GET_SET
] = parse_get_set
,
5751 [ENC_GET_SET_EXT
] = parse_get_set_ext
,
5752 [ENC_MGET_MSET
] = parse_mget_mset
,
5753 [ENC_COND_SET
] = parse_cond_set
,
5754 [ENC_XFR
] = parse_xfr
,
5755 [ENC_MOV_CT
] = parse_mov_ct
,
5756 [ENC_SWAP
] = parse_swap
,
5757 [ENC_JUMP
] = parse_jump
,
5758 [ENC_CALLR
] = parse_callr
,
5759 [ENC_ALU
] = parse_alu
,
5760 [ENC_SHIFT
] = parse_shift
,
5761 [ENC_MIN_MAX
] = parse_min_max
,
5762 [ENC_BITOP
] = parse_bitop
,
5763 [ENC_CMP
] = parse_cmp
,
5764 [ENC_BRANCH
] = parse_branch
,
5765 [ENC_KICK
] = parse_kick
,
5766 [ENC_SWITCH
] = parse_switch
,
5767 [ENC_CACHER
] = parse_cacher
,
5768 [ENC_CACHEW
] = parse_cachew
,
5769 [ENC_ICACHE
] = parse_icache
,
5770 [ENC_LNKGET
] = parse_lnkget
,
5771 [ENC_FMOV
] = parse_fmov
,
5772 [ENC_FMMOV
] = parse_fmmov
,
5773 [ENC_FMOV_DATA
] = parse_fmov_data
,
5774 [ENC_FMOV_I
] = parse_fmov_i
,
5775 [ENC_FPACK
] = parse_fpack
,
5776 [ENC_FSWAP
] = parse_fswap
,
5777 [ENC_FCMP
] = parse_fcmp
,
5778 [ENC_FMINMAX
] = parse_fminmax
,
5779 [ENC_FCONV
] = parse_fconv
,
5780 [ENC_FCONVX
] = parse_fconvx
,
5781 [ENC_FBARITH
] = parse_fbarith
,
5782 [ENC_FEARITH
] = parse_fearith
,
5783 [ENC_FREC
] = parse_frec
,
5784 [ENC_FSIMD
] = parse_fsimd
,
5785 [ENC_FGET_SET_ACF
] = parse_fget_set_acf
,
5786 [ENC_DGET_SET
] = parse_dget_set
,
5787 [ENC_DTEMPLATE
] = parse_dtemplate
,
5788 [ENC_DALU
] = parse_dalu
,
5791 struct metag_core_option
5797 /* CPU type options. */
5798 static const struct metag_core_option metag_cpus
[] =
5800 {"all", CoreMeta11
|CoreMeta12
|CoreMeta21
},
5801 {"metac11", CoreMeta11
},
5802 {"metac12", CoreMeta12
},
5803 {"metac21", CoreMeta21
},
5807 /* FPU type options. */
5808 static const struct metag_core_option metag_fpus
[] =
5810 {"metac21", FpuMeta21
},
5814 /* DSP type options. */
5815 static const struct metag_core_option metag_dsps
[] =
5817 {"metac21", DspMeta21
},
5821 /* Parse a CPU command line option. */
5823 metag_parse_cpu (const char * str
)
5825 const struct metag_core_option
* opt
;
5828 optlen
= strlen (str
);
5832 as_bad (_("missing cpu name `%s'"), str
);
5836 for (opt
= metag_cpus
; opt
->name
!= NULL
; opt
++)
5837 if (strncmp (opt
->name
, str
, optlen
) == 0)
5839 mcpu_opt
= opt
->value
;
5843 as_bad (_("unknown cpu `%s'"), str
);
5847 /* Parse an FPU command line option. */
5849 metag_parse_fpu (const char * str
)
5851 const struct metag_core_option
* opt
;
5854 optlen
= strlen (str
);
5858 as_bad (_("missing fpu name `%s'"), str
);
5862 for (opt
= metag_fpus
; opt
->name
!= NULL
; opt
++)
5863 if (strncmp (opt
->name
, str
, optlen
) == 0)
5865 mfpu_opt
= opt
->value
;
5869 as_bad (_("unknown fpu `%s'"), str
);
5873 /* Parse a DSP command line option. */
5875 metag_parse_dsp (const char * str
)
5877 const struct metag_core_option
* opt
;
5880 optlen
= strlen (str
);
5884 as_bad (_("missing DSP name `%s'"), str
);
5888 for (opt
= metag_dsps
; opt
->name
!= NULL
; opt
++)
5889 if (strncmp (opt
->name
, str
, optlen
) == 0)
5891 mdsp_opt
= opt
->value
;
5895 as_bad (_("unknown DSP `%s'"), str
);
5899 struct metag_long_option
5901 const char * option
; /* Substring to match. */
5902 const char * help
; /* Help information. */
5903 int (* func
) (const char * subopt
); /* Function to decode sub-option. */
5904 const char * deprecated
; /* If non-null, print this message. */
5907 struct metag_long_option metag_long_opts
[] =
5909 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5910 metag_parse_cpu
, NULL
},
5911 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5912 metag_parse_fpu
, NULL
},
5913 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5914 metag_parse_dsp
, NULL
},
5915 {NULL
, NULL
, 0, NULL
}
5919 md_parse_option (int c
, const char * arg
)
5921 struct metag_long_option
*lopt
;
5923 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5925 /* These options are expected to have an argument. */
5926 if (c
== lopt
->option
[0]
5928 && strncmp (arg
, lopt
->option
+ 1,
5929 strlen (lopt
->option
+ 1)) == 0)
5932 /* If the option is deprecated, tell the user. */
5933 if (lopt
->deprecated
!= NULL
)
5934 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
5935 _(lopt
->deprecated
));
5938 /* Call the sup-option parser. */
5939 return lopt
->func (arg
+ strlen (lopt
->option
) - 1);
5947 md_show_usage (FILE * stream
)
5949 struct metag_long_option
*lopt
;
5951 fprintf (stream
, _(" Meta specific command line options:\n"));
5953 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5954 if (lopt
->help
!= NULL
)
5955 fprintf (stream
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
5958 /* The target specific pseudo-ops which we support. */
5959 const pseudo_typeS md_pseudo_table
[] =
5961 { "word", cons
, 2 },
5970 for (c
= 0; c
< 256; c
++)
5974 register_chars
[c
] = c
;
5975 /* LOCK0, LOCK1, LOCK2. */
5976 mnemonic_chars
[c
] = c
;
5978 else if (ISLOWER (c
))
5980 register_chars
[c
] = c
;
5981 mnemonic_chars
[c
] = c
;
5983 else if (ISUPPER (c
))
5985 register_chars
[c
] = c
;
5986 mnemonic_chars
[c
] = c
;
5990 register_chars
[c
] = c
;
5995 /* Parse a split condition code prefix. */
5997 parse_split_condition (const char *line
, metag_insn
*insn
)
5999 const char *l
= line
;
6000 const split_condition
*scond
;
6001 split_condition entry
;
6009 scond
= (const split_condition
*) htab_find (scond_htab
, &entry
);
6014 insn
->scond
= scond
->code
;
6016 return l
+ strlen (scond
->name
);
6019 /* Parse an instruction prefix - F for float, D for DSP - and associated
6020 flags and condition codes. */
6022 parse_prefix (const char *line
, metag_insn
*insn
)
6024 const char *l
= line
;
6026 l
= skip_whitespace (l
);
6028 insn
->type
= INSN_GP
;
6030 if (TOLOWER (*l
) == FPU_PREFIX_CHAR
)
6032 if (strncasecmp (l
, FFB_INSN
, strlen(FFB_INSN
)))
6034 insn
->type
= INSN_FPU
;
6038 if (*l
== END_OF_INSN
)
6040 as_bad (_("premature end of floating point prefix"));
6044 if (TOLOWER (*l
) == FPU_DOUBLE_CHAR
)
6046 insn
->fpu_width
= FPU_WIDTH_DOUBLE
;
6049 else if (TOLOWER (*l
) == FPU_PAIR_CHAR
)
6053 /* Check this isn't a split condition beginning with L. */
6054 l2
= parse_split_condition (l2
, insn
);
6056 if (l2
&& is_whitespace_char (*l2
))
6062 insn
->fpu_width
= FPU_WIDTH_PAIR
;
6068 insn
->fpu_width
= FPU_WIDTH_SINGLE
;
6071 if (TOLOWER (*l
) == FPU_ACTION_ABS_CHAR
)
6073 insn
->fpu_action_flags
|= FPU_ACTION_ABS
;
6076 else if (TOLOWER (*l
) == FPU_ACTION_INV_CHAR
)
6078 insn
->fpu_action_flags
|= FPU_ACTION_INV
;
6082 if (TOLOWER (*l
) == FPU_ACTION_QUIET_CHAR
)
6084 insn
->fpu_action_flags
|= FPU_ACTION_QUIET
;
6088 if (TOLOWER (*l
) == FPU_ACTION_ZERO_CHAR
)
6090 insn
->fpu_action_flags
|= FPU_ACTION_ZERO
;
6094 if (! is_whitespace_char (*l
))
6096 l
= parse_split_condition (l
, insn
);
6100 as_bad (_("unknown floating point prefix character"));
6108 else if (TOLOWER (*l
) == DSP_PREFIX_CHAR
)
6110 if (strncasecmp (l
, DCACHE_INSN
, strlen (DCACHE_INSN
)) &&
6111 strncasecmp (l
, DEFR_INSN
, strlen (DEFR_INSN
)))
6114 insn
->type
= INSN_DSP
;
6118 insn
->dsp_width
= DSP_WIDTH_SINGLE
;
6120 while (!is_whitespace_char (*l
))
6122 /* We have to check for split condition codes first
6123 because they are the longest strings to match,
6124 e.g. if the string contains "LLS" we want it to match
6125 the split condition code "LLS", not the dual unit
6128 l
= parse_split_condition (l
, insn
);
6135 /* Accept an FPU prefix char which may be used when doing
6136 template MOV with FPU registers. */
6137 if (TOLOWER(*l
) == FPU_PREFIX_CHAR
)
6139 insn
->type
= INSN_DSP_FPU
;
6144 if (TOLOWER(*l
) == DSP_DUAL_CHAR
)
6146 insn
->dsp_width
= DSP_WIDTH_DUAL
;
6151 if (TOLOWER(*l
) == DSP_ACTION_QR64_CHAR
)
6153 insn
->dsp_action_flags
|= DSP_ACTION_QR64
;
6158 if (TOLOWER(*l
) == DSP_ACTION_UMUL_CHAR
)
6160 insn
->dsp_action_flags
|= DSP_ACTION_UMUL
;
6165 if (TOLOWER(*l
) == DSP_ACTION_ROUND_CHAR
)
6167 insn
->dsp_action_flags
|= DSP_ACTION_ROUND
;
6172 if (TOLOWER(*l
) == DSP_ACTION_CLAMP9_CHAR
)
6174 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP9
;
6179 if (TOLOWER(*l
) == DSP_ACTION_CLAMP8_CHAR
)
6181 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP8
;
6186 if (TOLOWER(*l
) == DSP_ACTION_MOD_CHAR
)
6188 insn
->dsp_action_flags
|= DSP_ACTION_MOD
;
6193 if (TOLOWER(*l
) == DSP_ACTION_ACC_ZERO_CHAR
)
6195 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ZERO
;
6200 if (TOLOWER(*l
) == DSP_ACTION_ACC_ADD_CHAR
)
6202 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ADD
;
6207 if (TOLOWER(*l
) == DSP_ACTION_ACC_SUB_CHAR
)
6209 insn
->dsp_action_flags
|= DSP_ACTION_ACC_SUB
;
6214 if (TOLOWER(*l
) == DSP_ACTION_OV_CHAR
)
6216 insn
->dsp_action_flags
|= DSP_ACTION_OV
;
6221 if (TOLOWER(*l
) == DSP_DAOPPAME_8_CHAR
)
6223 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_8
;
6228 if (TOLOWER(*l
) == DSP_DAOPPAME_16_CHAR
)
6230 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_16
;
6235 if (TOLOWER(*l
) == DSP_DAOPPAME_TEMP_CHAR
)
6237 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_TEMP
;
6242 if (TOLOWER(*l
) == DSP_DAOPPAME_HIGH_CHAR
)
6244 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_HIGH
;
6249 as_bad (_("unknown DSP prefix character %c %s"), *l
, l
);
6260 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6261 static insn_templates
*
6262 find_insn_templates (const char *mnemonic
)
6264 insn_template
template;
6265 insn_templates entry
;
6266 insn_templates
*slot
;
6268 entry
.template = &template;
6270 memcpy ((void *)&entry
.template->name
, &mnemonic
, sizeof (char *));
6272 slot
= (insn_templates
*) htab_find (mnemonic_htab
, &entry
);
6280 /* Make an uppercase copy of SRC into DST and return DST. */
6282 strupper (char * dst
, const char *src
)
6288 dst
[i
] = TOUPPER (src
[i
]);
6297 /* Calculate a hash value for a template. */
6299 hash_templates (const void *p
)
6301 insn_templates
*tp
= (insn_templates
*)p
;
6302 char buf
[MAX_MNEMONIC_LEN
];
6304 strupper (buf
, tp
->template->name
);
6306 return htab_hash_string (buf
);
6309 /* Check if two templates are equal. */
6311 eq_templates (const void *a
, const void *b
)
6313 insn_templates
*ta
= (insn_templates
*)a
;
6314 insn_templates
*tb
= (insn_templates
*)b
;
6315 return strcasecmp (ta
->template->name
, tb
->template->name
) == 0;
6318 /* Create the hash table required for parsing instructions. */
6320 create_mnemonic_htab (void)
6322 size_t i
, num_templates
= sizeof(metag_optab
)/sizeof(metag_optab
[0]);
6324 mnemonic_htab
= htab_create_alloc (num_templates
, hash_templates
,
6325 eq_templates
, NULL
, xcalloc
, free
);
6327 for (i
= 0; i
< num_templates
; i
++)
6329 const insn_template
*template = &metag_optab
[i
];
6330 insn_templates
**slot
= NULL
;
6331 insn_templates
*new_entry
;
6333 new_entry
= XNEW (insn_templates
);
6335 new_entry
->template = template;
6336 new_entry
->next
= NULL
;
6338 slot
= (insn_templates
**) htab_find_slot (mnemonic_htab
, new_entry
,
6343 insn_templates
*last_entry
= *slot
;
6345 while (last_entry
->next
)
6346 last_entry
= last_entry
->next
;
6348 last_entry
->next
= new_entry
;
6357 /* Calculate a hash value for a register. */
6359 hash_regs (const void *p
)
6361 metag_reg
*rp
= (metag_reg
*)p
;
6362 char buf
[MAX_REG_LEN
];
6364 strupper (buf
, rp
->name
);
6366 return htab_hash_string (buf
);
6369 /* Check if two registers are equal. */
6371 eq_regs (const void *a
, const void *b
)
6373 metag_reg
*ra
= (metag_reg
*)a
;
6374 metag_reg
*rb
= (metag_reg
*)b
;
6375 return strcasecmp (ra
->name
, rb
->name
) == 0;
6378 /* Create the hash table required for parsing registers. */
6380 create_reg_htab (void)
6382 size_t i
, num_regs
= sizeof(metag_regtab
)/sizeof(metag_regtab
[0]);
6384 reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6385 eq_regs
, NULL
, xcalloc
, free
);
6387 for (i
= 0; i
< num_regs
; i
++)
6389 const metag_reg
*reg
= &metag_regtab
[i
];
6390 const metag_reg
**slot
;
6392 slot
= (const metag_reg
**) htab_find_slot (reg_htab
, reg
, INSERT
);
6399 /* Create the hash table required for parsing DSP registers. */
6401 create_dspreg_htabs (void)
6403 size_t i
, num_regs
= sizeof(metag_dsp_regtab
)/sizeof(metag_dsp_regtab
[0]);
6406 dsp_reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6407 eq_regs
, NULL
, xcalloc
, free
);
6409 for (i
= 0; i
< num_regs
; i
++)
6411 const metag_reg
*reg
= &metag_dsp_regtab
[i
];
6412 const metag_reg
**slot
;
6414 slot
= (const metag_reg
**) htab_find_slot (dsp_reg_htab
, reg
, INSERT
);
6416 /* Make sure there are no hash table collisions, which would
6417 require chaining entries. */
6418 gas_assert (*slot
== NULL
);
6422 num_regs
= sizeof(metag_dsp_tmpl_regtab
[0])/sizeof(metag_dsp_tmpl_regtab
[0][0]);
6424 for (h
= 0; h
< 2; h
++)
6426 dsp_tmpl_reg_htab
[h
] = htab_create_alloc (num_regs
, hash_regs
,
6427 eq_regs
, NULL
, xcalloc
, free
);
6430 for (h
= 0; h
< 2; h
++)
6432 for (i
= 0; i
< num_regs
; i
++)
6434 const metag_reg
*reg
= &metag_dsp_tmpl_regtab
[h
][i
];
6435 const metag_reg
**slot
;
6436 slot
= (const metag_reg
**) htab_find_slot (dsp_tmpl_reg_htab
[h
],
6439 /* Make sure there are no hash table collisions, which would
6440 require chaining entries. */
6441 gas_assert (*slot
== NULL
);
6447 /* Calculate a hash value for a split condition code. */
6449 hash_scond (const void *p
)
6451 split_condition
*cp
= (split_condition
*)p
;
6454 strupper (buf
, cp
->name
);
6456 return htab_hash_string (buf
);
6459 /* Check if two split condition codes are equal. */
6461 eq_scond (const void *a
, const void *b
)
6463 split_condition
*ra
= (split_condition
*)a
;
6464 split_condition
*rb
= (split_condition
*)b
;
6466 return strcasecmp (ra
->name
, rb
->name
) == 0;
6469 /* Create the hash table required for parsing split condition codes. */
6471 create_scond_htab (void)
6475 nentries
= sizeof (metag_scondtab
) / sizeof (metag_scondtab
[0]);
6477 scond_htab
= htab_create_alloc (nentries
, hash_scond
, eq_scond
,
6478 NULL
, xcalloc
, free
);
6479 for (i
= 0; i
< nentries
; i
++)
6481 const split_condition
*scond
= &metag_scondtab
[i
];
6482 const split_condition
**slot
;
6484 slot
= (const split_condition
**) htab_find_slot (scond_htab
,
6486 /* Make sure there are no hash table collisions, which would
6487 require chaining entries. */
6488 gas_assert (*slot
== NULL
);
6493 /* Entry point for instruction parsing. */
6495 parse_insn (const char *line
, metag_insn
*insn
)
6497 char mnemonic
[MAX_MNEMONIC_LEN
];
6498 const char *l
= line
;
6499 size_t mnemonic_len
= 0;
6500 insn_templates
*templates
;
6504 while (is_mnemonic_char(*l
))
6510 if (mnemonic_len
>= MAX_MNEMONIC_LEN
)
6512 as_bad (_("instruction mnemonic too long: %s"), line
);
6516 strncpy(mnemonic
, line
, mnemonic_len
);
6518 mnemonic
[mnemonic_len
] = '\0';
6520 templates
= find_insn_templates (mnemonic
);
6524 insn_templates
*current_template
= templates
;
6528 while (current_template
)
6530 const insn_template
*template = current_template
->template;
6531 enum insn_encoding encoding
= template->encoding
;
6532 insn_parser parser
= insn_parsers
[encoding
];
6534 current_template
= current_template
->next
;
6536 if (template->insn_type
== INSN_GP
&&
6537 !(template->core_flags
& mcpu_opt
))
6540 if (template->insn_type
== INSN_FPU
&&
6541 !(template->core_flags
& mfpu_opt
))
6544 if (template->insn_type
== INSN_DSP
&&
6545 !(template->core_flags
& mdsp_opt
))
6548 if (template->insn_type
== INSN_DSP_FPU
&&
6549 !((template->core_flags
& mdsp_opt
) &&
6550 (template->core_flags
& mfpu_opt
)))
6553 /* DSP instructions always require special decoding */
6554 if ((insn
->type
== INSN_DSP
&& (template->insn_type
!= INSN_DSP
)) ||
6555 ((template->insn_type
== INSN_DSP
) && insn
->type
!= INSN_DSP
) ||
6556 (insn
->type
== INSN_DSP_FPU
&& (template->insn_type
!= INSN_DSP_FPU
)) ||
6557 ((template->insn_type
== INSN_DSP_FPU
) && insn
->type
!= INSN_DSP_FPU
))
6562 const char *end
= parser(l
, insn
, template);
6566 if (*end
!= END_OF_INSN
)
6567 as_bad (_("junk at end of line: \"%s\""), line
);
6574 as_bad (_("failed to assemble instruction: \"%s\""), line
);
6578 if (insn
->type
== INSN_FPU
)
6579 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic
);
6581 as_bad (_("unknown mnemonic: \"%s\""), mnemonic
);
6587 output_insn (metag_insn
*insn
)
6591 output
= frag_more (insn
->len
);
6592 dwarf2_emit_insn (insn
->len
);
6594 if (insn
->reloc_type
!= BFD_RELOC_UNUSED
)
6596 fix_new_exp (frag_now
, output
- frag_now
->fr_literal
,
6597 insn
->reloc_size
, &insn
->reloc_exp
,
6598 insn
->reloc_pcrel
, insn
->reloc_type
);
6601 md_number_to_chars (output
, insn
->bits
, insn
->len
);
6605 md_assemble (char *line
)
6607 const char *l
= line
;
6610 memset (&insn
, 0, sizeof(insn
));
6612 insn
.reloc_type
= BFD_RELOC_UNUSED
;
6613 insn
.reloc_pcrel
= 0;
6614 insn
.reloc_size
= 4;
6618 create_mnemonic_htab ();
6620 create_dspreg_htabs ();
6621 create_scond_htab ();
6624 l
= parse_prefix (l
, &insn
);
6629 if (insn
.type
== INSN_DSP
&&
6632 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6636 else if (insn
.type
== INSN_FPU
&&
6639 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6644 if (!parse_insn (l
, &insn
))
6647 output_insn (&insn
);
6651 md_operand (expressionS
* expressionP
)
6653 if (* input_line_pointer
== IMM_CHAR
)
6655 input_line_pointer
++;
6656 expression (expressionP
);
6661 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
6667 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6672 /* Functions concerning relocs. */
6674 /* The location from which a PC relative jump should be calculated,
6675 given a PC relative reloc. */
6678 md_pcrel_from_section (fixS
* fixP
, segT sec
)
6680 if ((fixP
->fx_addsy
!= (symbolS
*) NULL
6681 && (! S_IS_DEFINED (fixP
->fx_addsy
)
6682 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
6683 || metag_force_relocation (fixP
))
6685 /* The symbol is undefined (or is defined but not in this section).
6686 Let the linker figure it out. */
6690 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6693 /* Write a value out to the object file, using the appropriate endianness. */
6696 md_number_to_chars (char * buf
, valueT val
, int n
)
6698 number_to_chars_littleendian (buf
, val
, n
);
6701 /* Turn a string in input_line_pointer into a floating point constant of type
6702 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6703 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6706 /* Equal to MAX_PRECISION in atof-ieee.c */
6707 #define MAX_LITTLENUMS 6
6710 md_atof (int type
, char * litP
, int * sizeP
)
6714 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6733 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6737 return _("Bad call to md_atof()");
6740 t
= atof_ieee (input_line_pointer
, type
, words
);
6742 input_line_pointer
= t
;
6743 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
6745 for (i
= 0; i
< prec
; i
++)
6747 md_number_to_chars (litP
, (valueT
) words
[i
],
6748 sizeof (LITTLENUM_TYPE
));
6749 litP
+= sizeof (LITTLENUM_TYPE
);
6755 /* If this function returns non-zero, it prevents the relocation
6756 against symbol(s) in the FIXP from being replaced with relocations
6757 against section symbols, and guarantees that a relocation will be
6758 emitted even when the value can be resolved locally. */
6761 metag_force_relocation (fixS
* fix
)
6763 switch (fix
->fx_r_type
)
6765 case BFD_RELOC_METAG_RELBRANCH_PLT
:
6766 case BFD_RELOC_METAG_TLS_LE
:
6767 case BFD_RELOC_METAG_TLS_IE
:
6768 case BFD_RELOC_METAG_TLS_LDO
:
6769 case BFD_RELOC_METAG_TLS_LDM
:
6770 case BFD_RELOC_METAG_TLS_GD
:
6776 return generic_force_reloc (fix
);
6780 metag_fix_adjustable (fixS
* fixP
)
6782 if (fixP
->fx_addsy
== NULL
)
6785 /* Prevent all adjustments to global symbols. */
6786 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
6788 if (S_IS_WEAK (fixP
->fx_addsy
))
6791 if (fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTOFF
||
6792 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTOFF
||
6793 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOTOFF
||
6794 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOT
||
6795 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTPC
||
6796 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTPC
||
6797 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_PLT
||
6798 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_PLT
||
6799 fixP
->fx_r_type
== BFD_RELOC_METAG_RELBRANCH_PLT
)
6802 /* We need the symbol name for the VTABLE entries. */
6803 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6804 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6810 /* Return an initial guess of the length by which a fragment must grow to
6811 hold a branch to reach its destination.
6812 Also updates fr_type/fr_subtype as necessary.
6814 Called just before doing relaxation.
6815 Any symbol that is now undefined will not become defined.
6816 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6817 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6818 Although it may not be explicit in the frag, pretend fr_var starts with a
6822 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
6823 segT segment ATTRIBUTE_UNUSED
)
6825 /* No assembler relaxation is defined (or necessary) for this port. */
6829 /* *fragP has been relaxed to its final size, and now needs to have
6830 the bytes inside it modified to conform to the new size.
6832 Called after relaxation is finished.
6833 fragP->fr_type == rs_machine_dependent.
6834 fragP->fr_subtype is the subtype of what the address relaxed to. */
6837 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
,
6838 fragS
* fragP ATTRIBUTE_UNUSED
)
6840 /* No assembler relaxation is defined (or necessary) for this port. */
6844 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6847 metag_handle_align (fragS
* fragP
)
6849 static unsigned char const noop
[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6853 if (fragP
->fr_type
!= rs_align_code
)
6856 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
6857 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
6870 memcpy (p
, noop
, 4);
6876 fragP
->fr_fix
+= fix
;
6881 metag_end_of_match (char * cont
, const char * what
)
6883 int len
= strlen (what
);
6885 if (strncasecmp (cont
, what
, strlen (what
)) == 0
6886 && ! is_part_of_name (cont
[len
]))
6893 metag_parse_name (char const * name
, expressionS
* exprP
, enum expr_mode mode
,
6896 char *next
= input_line_pointer
;
6902 exprP
->X_op_symbol
= NULL
;
6903 exprP
->X_md
= BFD_RELOC_UNUSED
;
6905 if (strcmp (name
, GOT_NAME
) == 0)
6908 GOT_symbol
= symbol_find_or_make (name
);
6910 exprP
->X_add_symbol
= GOT_symbol
;
6912 /* If we have an absolute symbol or a
6913 reg, then we know its value now. */
6914 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
6915 if (mode
!= expr_defer
&& segment
== absolute_section
)
6917 exprP
->X_op
= O_constant
;
6918 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6919 exprP
->X_add_symbol
= NULL
;
6921 else if (mode
!= expr_defer
&& segment
== reg_section
)
6923 exprP
->X_op
= O_register
;
6924 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6925 exprP
->X_add_symbol
= NULL
;
6929 exprP
->X_op
= O_symbol
;
6930 exprP
->X_add_number
= 0;
6936 exprP
->X_add_symbol
= symbol_find_or_make (name
);
6938 if (*nextcharP
!= '@')
6940 else if ((next_end
= metag_end_of_match (next
+ 1, "GOTOFF")))
6942 reloc_type
= BFD_RELOC_METAG_GOTOFF
;
6943 op_type
= O_PIC_reloc
;
6945 else if ((next_end
= metag_end_of_match (next
+ 1, "GOT")))
6947 reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
6948 op_type
= O_PIC_reloc
;
6950 else if ((next_end
= metag_end_of_match (next
+ 1, "PLT")))
6952 reloc_type
= BFD_RELOC_METAG_PLT
;
6953 op_type
= O_PIC_reloc
;
6955 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSGD")))
6957 reloc_type
= BFD_RELOC_METAG_TLS_GD
;
6958 op_type
= O_PIC_reloc
;
6960 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDM")))
6962 reloc_type
= BFD_RELOC_METAG_TLS_LDM
;
6963 op_type
= O_PIC_reloc
;
6965 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDO")))
6967 reloc_type
= BFD_RELOC_METAG_TLS_LDO
;
6968 op_type
= O_PIC_reloc
;
6970 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIE")))
6972 reloc_type
= BFD_RELOC_METAG_TLS_IE
;
6973 op_type
= O_PIC_reloc
;
6975 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIENONPIC")))
6977 reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC
;
6978 op_type
= O_PIC_reloc
; /* FIXME: is this correct? */
6980 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLE")))
6982 reloc_type
= BFD_RELOC_METAG_TLS_LE
;
6983 op_type
= O_PIC_reloc
;
6988 *input_line_pointer
= *nextcharP
;
6989 input_line_pointer
= next_end
;
6990 *nextcharP
= *input_line_pointer
;
6991 *input_line_pointer
= '\0';
6993 exprP
->X_op
= op_type
;
6994 exprP
->X_add_number
= 0;
6995 exprP
->X_md
= reloc_type
;
7000 /* If while processing a fixup, a reloc really needs to be created
7001 then it is done here. */
7004 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
7008 reloc
= XNEW (arelent
);
7009 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7010 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7011 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7013 reloc
->addend
= fixp
->fx_offset
;
7014 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
7016 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
7018 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7019 /* xgettext:c-format. */
7020 _("reloc %d not supported by object file format"),
7021 (int) fixp
->fx_r_type
);
7032 md_chars_to_number (char *val
, int n
)
7035 unsigned char * where
= (unsigned char *) val
;
7037 for (retval
= 0; n
--;)
7046 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7048 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7049 int value
= (int)*valP
;
7051 switch (fixP
->fx_r_type
)
7053 case BFD_RELOC_METAG_TLS_GD
:
7054 case BFD_RELOC_METAG_TLS_LE_HI16
:
7055 case BFD_RELOC_METAG_TLS_LE_LO16
:
7056 case BFD_RELOC_METAG_TLS_IE
:
7057 case BFD_RELOC_METAG_TLS_IENONPIC_HI16
:
7058 case BFD_RELOC_METAG_TLS_IENONPIC_LO16
:
7059 case BFD_RELOC_METAG_TLS_LDM
:
7060 case BFD_RELOC_METAG_TLS_LDO_HI16
:
7061 case BFD_RELOC_METAG_TLS_LDO_LO16
:
7062 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7065 case BFD_RELOC_METAG_HIADDR16
:
7066 case BFD_RELOC_METAG_LOADDR16
:
7067 case BFD_RELOC_VTABLE_INHERIT
:
7068 case BFD_RELOC_VTABLE_ENTRY
:
7069 fixP
->fx_done
= FALSE
;
7072 case BFD_RELOC_METAG_REL8
:
7073 if (!within_unsigned_range (value
, IMM8_BITS
))
7075 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7076 "rel8 out of range %d", value
);
7080 unsigned int newval
;
7081 newval
= md_chars_to_number (buf
, 4);
7082 newval
= (newval
& 0xffffc03f) | ((value
& IMM8_MASK
) << 6);
7083 md_number_to_chars (buf
, newval
, 4);
7086 case BFD_RELOC_METAG_REL16
:
7087 if (!within_unsigned_range (value
, IMM16_BITS
))
7089 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7090 "rel16 out of range %d", value
);
7094 unsigned int newval
;
7095 newval
= md_chars_to_number (buf
, 4);
7096 newval
= (newval
& 0xfff80007) | ((value
& IMM16_MASK
) << 3);
7097 md_number_to_chars (buf
, newval
, 4);
7102 md_number_to_chars (buf
, value
, 1);
7105 md_number_to_chars (buf
, value
, 2);
7108 md_number_to_chars (buf
, value
, 4);
7111 md_number_to_chars (buf
, value
, 8);
7113 case BFD_RELOC_METAG_RELBRANCH
:
7119 if (!within_signed_range (value
, IMM19_BITS
))
7121 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7122 "relbranch out of range %d", value
);
7126 unsigned int newval
;
7127 newval
= md_chars_to_number (buf
, 4);
7128 newval
= (newval
& 0xff00001f) | ((value
& IMM19_MASK
) << 5);
7129 md_number_to_chars (buf
, newval
, 4);
7136 if (fixP
->fx_addsy
== NULL
)
7137 fixP
->fx_done
= TRUE
;