1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2 Copyright (C) 2013-2020 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 addressing 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"));
2046 /* Registers must be in different units. */
2047 if (regs
[0]->unit
== regs
[1]->unit
)
2049 as_bad (_("source and destination register must be in different units"));
2055 insn
->bits
= (template->meta_opcode
2056 | (regs
[1]->no
<< 19)
2057 | (regs
[0]->no
<< 14)
2058 | (regs
[1]->unit
<< 10)
2059 | (regs
[0]->unit
<< 5));
2065 /* Parse a JUMP instruction. */
2067 parse_jump (const char *line
, metag_insn
*insn
,
2068 const insn_template
*template)
2070 const char *l
= line
;
2071 const metag_reg
*regs
[1];
2074 l
= parse_gp_regs (l
, regs
, 1);
2079 if (!is_short_unit (regs
[0]->unit
))
2081 as_bad (_("register unit must be one of %s"), SHORT_UNITS
);
2091 l
= parse_imm16 (l
, insn
, &value
);
2096 insn
->bits
= (template->meta_opcode
|
2097 (regs
[0]->no
<< 19) |
2098 (regs
[0]->unit
& SHORT_UNIT_MASK
) |
2099 ((value
& IMM16_MASK
) << 3));
2105 /* Parse a 19bit immediate value. */
2107 parse_imm19 (const char *line
, metag_insn
*insn
, int *value
)
2109 const char *l
= line
;
2110 char *save_input_line_pointer
;
2111 expressionS
*exp
= &insn
->reloc_exp
;
2117 save_input_line_pointer
= input_line_pointer
;
2118 input_line_pointer
= (char *) l
;
2122 l
= input_line_pointer
;
2123 input_line_pointer
= save_input_line_pointer
;
2125 if (exp
->X_op
== O_absent
|| exp
->X_op
== O_big
)
2129 else if (exp
->X_op
== O_constant
)
2131 *value
= exp
->X_add_number
;
2135 if (exp
->X_op
== O_PIC_reloc
)
2137 exp
->X_op
= O_symbol
;
2139 if (exp
->X_md
== BFD_RELOC_METAG_PLT
)
2140 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH_PLT
;
2145 insn
->reloc_type
= BFD_RELOC_METAG_RELBRANCH
;
2146 insn
->reloc_pcrel
= 1;
2152 /* Parse a CALLR instruction. */
2154 parse_callr (const char *line
, metag_insn
*insn
,
2155 const insn_template
*template)
2157 const char *l
= line
;
2158 const metag_reg
*regs
[1];
2161 l
= parse_gp_regs (l
, regs
, 1);
2166 if (!is_short_unit (regs
[0]->unit
))
2168 as_bad (_("link register unit must be one of %s"), SHORT_UNITS
);
2172 if (regs
[0]->no
& ~CALLR_REG_MASK
)
2174 as_bad (_("link register must be in a low numbered register"));
2184 l
= parse_imm19 (l
, insn
, &value
);
2189 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2191 as_bad (_("target out of range"));
2195 insn
->bits
= (template->meta_opcode
|
2196 (regs
[0]->no
& CALLR_REG_MASK
) |
2197 ((regs
[0]->unit
& SHORT_UNIT_MASK
) << 3) |
2198 ((value
& IMM19_MASK
) << 5));
2204 /* Return the value for the register field if we apply the O2R modifier
2205 to operand 2 REG, combined with UNIT_BIT derived from the destination
2206 register or source1. Uses address unit O2R if IS_ADDR is set. */
2208 lookup_o2r (unsigned int is_addr
, unsigned int unit_bit
, const metag_reg
*reg
)
2210 if (reg
->no
& ~O2R_REG_MASK
)
2222 return (1 << 3) | reg
->no
;
2224 return (2 << 3) | reg
->no
;
2226 return (3 << 3) | reg
->no
;
2238 return (1 << 3) | reg
->no
;
2240 return (2 << 3) | reg
->no
;
2242 return (3 << 3) | reg
->no
;
2257 return (1 << 3) | reg
->no
;
2259 return (2 << 3) | reg
->no
;
2261 return (3 << 3) | reg
->no
;
2273 return (1 << 3) | reg
->no
;
2275 return (2 << 3) | reg
->no
;
2277 return (3 << 3) | reg
->no
;
2285 /* Parse GP ALU instruction. */
2287 parse_alu (const char *line
, metag_insn
*insn
,
2288 const insn_template
*template)
2290 const char *l
= line
;
2291 const metag_reg
*dest_regs
[1];
2292 const metag_reg
*src_regs
[2];
2294 unsigned int o1z
= 0;
2295 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2296 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2297 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2298 unsigned int top
= template->meta_opcode
& 0x1;
2299 unsigned int sign_extend
= 0;
2300 unsigned int is_addr_op
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
;
2301 unsigned int is_mul
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MUL
;
2302 unsigned int unit_bit
= 0;
2303 bfd_boolean is_quickrot
= template->arg_type
& GP_ARGS_QR
;
2305 l
= parse_gp_regs (l
, dest_regs
, 1);
2318 if (dest_regs
[0]->unit
== UNIT_A0
)
2320 else if (dest_regs
[0]->unit
== UNIT_A1
)
2325 if (dest_regs
[0]->unit
== UNIT_D0
)
2327 else if (dest_regs
[0]->unit
== UNIT_D1
)
2331 if ((MAJOR_OPCODE (template->meta_opcode
) == OPC_ADDR
||
2332 MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
2333 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) &&
2334 ((template->meta_opcode
>> 2) & 0x1))
2343 if (dest_regs
[0]->unit
== UNIT_A0
)
2345 else if (dest_regs
[0]->unit
== UNIT_A1
)
2352 if (dest_regs
[0]->unit
== UNIT_D0
)
2354 else if (dest_regs
[0]->unit
== UNIT_D1
)
2363 l
= parse_gp_regs (l
, src_regs
, 1);
2376 if (src_regs
[0]->unit
== UNIT_A0
)
2378 else if (src_regs
[0]->unit
== UNIT_A1
)
2385 if (src_regs
[0]->unit
== UNIT_D0
)
2387 else if (src_regs
[0]->unit
== UNIT_D1
)
2393 if (src_regs
[0]->unit
!= dest_regs
[0]->unit
&& !ca
)
2396 l
= parse_imm8 (l
, insn
, &value
);
2401 if (!within_unsigned_range (value
, IMM8_BITS
))
2404 insn
->bits
= (template->meta_opcode
|
2405 (dest_regs
[0]->no
<< 19) |
2406 (src_regs
[0]->no
<< 14) |
2407 ((value
& IMM8_MASK
) << 6));
2413 if (src_regs
[0]->unit
== UNIT_A0
)
2415 else if (src_regs
[0]->unit
== UNIT_A1
)
2422 if (src_regs
[0]->unit
== UNIT_D0
)
2424 else if (src_regs
[0]->unit
== UNIT_D1
)
2430 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2435 l
= parse_imm16 (l
, insn
, &value
);
2442 if (!within_signed_range (value
, IMM16_BITS
))
2444 as_bad (_("immediate out of range"));
2451 if (!within_unsigned_range (value
, IMM16_BITS
))
2453 as_bad (_("immediate out of range"));
2458 insn
->bits
= (template->meta_opcode
|
2459 (dest_regs
[0]->no
<< 19) |
2460 ((value
& IMM16_MASK
) << 3));
2464 l
= parse_gp_regs (l
, src_regs
, 1);
2469 if (!(src_regs
[0]->unit
== dest_regs
[0]->unit
))
2472 /* CPC is valid for address ops. */
2473 if (src_regs
[0]->no
!= dest_regs
[0]->no
&&
2474 !(is_addr_op
&& src_regs
[0]->no
== 0x10))
2483 l
= parse_imm16 (l
, insn
, &value
);
2490 if (!within_signed_range (value
, IMM16_BITS
))
2492 as_bad (_("immediate out of range"));
2499 if (!within_unsigned_range (value
, IMM16_BITS
))
2501 as_bad (_("immediate out of range"));
2506 insn
->bits
= (template->meta_opcode
|
2507 (dest_regs
[0]->no
<< 19) |
2508 (src_regs
[0]->no
<< 19) |
2509 ((value
& IMM16_MASK
) << 3));
2514 unsigned int o2r
= 0;
2518 l
= parse_gp_regs (l
, src_regs
, 2);
2520 l
= parse_gp_regs (l
, src_regs
, 1);
2529 if (src_regs
[0]->unit
== UNIT_A0
)
2531 else if (src_regs
[0]->unit
== UNIT_A1
)
2538 if (src_regs
[0]->unit
== UNIT_D0
)
2540 else if (src_regs
[0]->unit
== UNIT_D1
)
2550 if (dest_regs
[0]->unit
== UNIT_A0
)
2552 else if (dest_regs
[0]->unit
== UNIT_A1
)
2559 if (dest_regs
[0]->unit
== UNIT_D0
)
2561 else if (dest_regs
[0]->unit
== UNIT_D1
)
2570 if (src_regs
[0]->unit
!= src_regs
[1]->unit
)
2572 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2581 rs2
= src_regs
[1]->no
;
2584 insn
->bits
= (template->meta_opcode
|
2585 (dest_regs
[0]->no
<< 19) |
2586 (src_regs
[0]->no
<< 14) |
2591 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
&& is_mul
)
2595 insn
->bits
|= dest_regs
[0]->unit
<< 1;
2602 insn
->bits
|= dest_regs
[0]->unit
<< 5;
2606 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2608 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[0]);
2617 rs2
= src_regs
[0]->no
;
2620 insn
->bits
= (template->meta_opcode
|
2621 (dest_regs
[0]->no
<< 19) |
2626 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
2629 if (dest_regs
[0]->unit
!= src_regs
[1]->unit
)
2631 rs2
= lookup_o2r (is_addr_op
, unit_bit
, src_regs
[1]);
2640 rs2
= src_regs
[1]->no
;
2643 insn
->bits
= (template->meta_opcode
|
2644 (dest_regs
[0]->no
<< 19) |
2645 (src_regs
[0]->no
<< 14) |
2655 const metag_reg
*qr_regs
[1];
2656 bfd_boolean limit_regs
= imm
&& cond
;
2664 l
= parse_gp_regs (l
, qr_regs
, 1);
2669 if (!((unit_bit
== 0 && qr_regs
[0]->unit
!= UNIT_A0
) ||
2670 !(unit_bit
== 1 && qr_regs
[0]->unit
!= UNIT_A1
)))
2672 as_bad (_("invalid quickrot unit specified"));
2676 switch (qr_regs
[0]->no
)
2683 insn
->bits
|= (1 << 7);
2688 as_bad (_("invalid quickrot register specified"));
2693 if (sign_extend
== 1 && top
== 0)
2694 insn
->bits
|= (1 << 1);
2696 insn
->bits
|= unit_bit
<< 24;
2701 /* Parse a B instruction. */
2703 parse_branch (const char *line
, metag_insn
*insn
,
2704 const insn_template
*template)
2706 const char *l
= line
;
2709 l
= parse_imm19 (l
, insn
, &value
);
2714 if (!within_signed_range (value
/ 4, IMM19_BITS
))
2716 as_bad (_("target out of range"));
2720 insn
->bits
= (template->meta_opcode
|
2721 ((value
& IMM19_MASK
) << 5));
2727 /* Parse a KICK instruction. */
2729 parse_kick (const char *line
, metag_insn
*insn
,
2730 const insn_template
*template)
2732 const char *l
= line
;
2733 const metag_reg
*regs
[2];
2735 l
= parse_gp_regs (l
, regs
, 2);
2740 if (regs
[1]->unit
!= UNIT_TR
)
2742 as_bad (_("source register must be in the trigger unit"));
2746 insn
->bits
= (template->meta_opcode
|
2747 (regs
[1]->no
<< 19) |
2748 (regs
[0]->no
<< 14) |
2749 (regs
[0]->unit
<< 5));
2755 /* Parse a SWITCH instruction. */
2757 parse_switch (const char *line
, metag_insn
*insn
,
2758 const insn_template
*template)
2760 const char *l
= line
;
2763 l
= parse_imm_constant (l
, insn
, &value
);
2768 if (!within_unsigned_range (value
, IMM24_BITS
))
2770 as_bad (_("target out of range"));
2774 insn
->bits
= (template->meta_opcode
|
2775 (value
& IMM24_MASK
));
2781 /* Parse a shift instruction. */
2783 parse_shift (const char *line
, metag_insn
*insn
,
2784 const insn_template
*template)
2786 const char *l
= line
;
2787 const metag_reg
*regs
[2];
2788 const metag_reg
*src2_regs
[1];
2790 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2791 unsigned int ca
= (template->meta_opcode
>> 5) & 0x1;
2792 unsigned int unit_bit
= 0;
2794 l
= parse_gp_regs (l
, regs
, 2);
2805 if (regs
[1]->unit
== UNIT_D0
)
2807 else if (regs
[1]->unit
== UNIT_D1
)
2812 if (regs
[0]->unit
!= regs
[1]->unit
&& !(cond
&& ca
))
2817 l
= parse_imm_constant (l
, insn
, &value
);
2822 if (!within_unsigned_range (value
, IMM5_BITS
))
2825 insn
->bits
= (template->meta_opcode
|
2827 (regs
[0]->no
<< 19) |
2828 (regs
[1]->no
<< 14) |
2829 ((value
& IMM5_MASK
) << 9));
2833 l
= parse_gp_regs (l
, src2_regs
, 1);
2838 insn
->bits
= (template->meta_opcode
|
2839 (regs
[0]->no
<< 19) |
2840 (regs
[1]->no
<< 14) |
2841 (src2_regs
[0]->no
<< 9));
2843 if (src2_regs
[0]->unit
!= regs
[1]->unit
)
2845 as_bad(_("Source registers must be in the same unit"));
2850 if (regs
[0]->unit
!= regs
[1]->unit
)
2854 if (regs
[1]->unit
== UNIT_D0
)
2856 else if (regs
[1]->unit
== UNIT_D1
)
2861 insn
->bits
|= ((1 << 5) |
2862 (regs
[0]->unit
<< 1));
2868 insn
->bits
|= unit_bit
<< 24;
2873 /* Parse a MIN or MAX instruction. */
2875 parse_min_max (const char *line
, metag_insn
*insn
,
2876 const insn_template
*template)
2878 const char *l
= line
;
2879 const metag_reg
*regs
[3];
2881 l
= parse_gp_regs (l
, regs
, 3);
2886 if (!(regs
[0]->unit
== UNIT_D0
||
2887 regs
[0]->unit
== UNIT_D1
))
2890 if (!(regs
[0]->unit
== regs
[1]->unit
&&
2891 regs
[1]->unit
== regs
[2]->unit
))
2894 insn
->bits
= (template->meta_opcode
|
2895 (regs
[0]->no
<< 19) |
2896 (regs
[1]->no
<< 14) |
2897 (regs
[2]->no
<< 9));
2899 if (regs
[0]->unit
== UNIT_D1
)
2900 insn
->bits
|= (1 << 24);
2906 /* Parse a bit operation instruction. */
2908 parse_bitop (const char *line
, metag_insn
*insn
,
2909 const insn_template
*template)
2911 const char *l
= line
;
2912 const metag_reg
*regs
[2];
2913 unsigned int swap_inst
= MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
;
2914 unsigned int is_bexl
= 0;
2917 ((template->meta_opcode
>> 1) & 0xb) == 0xa)
2920 l
= parse_gp_regs (l
, regs
, 2);
2925 if (!(regs
[0]->unit
== UNIT_D0
||
2926 regs
[0]->unit
== UNIT_D1
))
2931 if (regs
[0]->unit
== UNIT_D0
&&
2932 regs
[1]->unit
!= UNIT_D1
)
2934 else if (regs
[0]->unit
== UNIT_D1
&&
2935 regs
[1]->unit
!= UNIT_D0
)
2938 else if (!(regs
[0]->unit
== regs
[1]->unit
))
2941 insn
->bits
= (template->meta_opcode
|
2942 (regs
[0]->no
<< 19) |
2943 (regs
[1]->no
<< 14));
2947 if (regs
[1]->unit
== UNIT_D1
)
2952 if (regs
[1]->unit
== UNIT_D1
)
2953 insn
->bits
|= (1 << 24);
2960 /* Parse a CMP or TST instruction. */
2962 parse_cmp (const char *line
, metag_insn
*insn
,
2963 const insn_template
*template)
2965 const char *l
= line
;
2966 const metag_reg
*dest_regs
[1];
2967 const metag_reg
*src_regs
[1];
2969 unsigned int imm
= (template->meta_opcode
>> 25) & 0x1;
2970 unsigned int cond
= (template->meta_opcode
>> 26) & 0x1;
2971 unsigned int top
= template->meta_opcode
& 0x1;
2972 unsigned int sign_extend
= 0;
2973 unsigned int unit_bit
= 0;
2975 l
= parse_gp_regs (l
, dest_regs
, 1);
2986 if (dest_regs
[0]->unit
== UNIT_D0
)
2988 else if (dest_regs
[0]->unit
== UNIT_D1
)
2997 l
= parse_imm_constant (l
, insn
, &value
);
3002 if (!within_unsigned_range (value
, IMM8_BITS
))
3005 insn
->bits
= (template->meta_opcode
|
3006 (dest_regs
[0]->no
<< 14) |
3007 ((value
& IMM8_MASK
) << 6));
3012 l
= parse_imm16 (l
, insn
, &value
);
3019 if (!within_signed_range (value
, IMM16_BITS
))
3021 as_bad (_("immediate out of range"));
3028 if (!within_unsigned_range (value
, IMM16_BITS
))
3030 as_bad (_("immediate out of range"));
3035 insn
->bits
= (template->meta_opcode
|
3036 (dest_regs
[0]->no
<< 19) |
3037 ((value
& IMM16_MASK
) << 3));
3042 unsigned int o2r
= 0;
3045 l
= parse_gp_regs (l
, src_regs
, 1);
3050 if (dest_regs
[0]->unit
!= src_regs
[0]->unit
)
3052 rs2
= lookup_o2r (0, unit_bit
, src_regs
[0]);
3061 rs2
= src_regs
[0]->no
;
3064 insn
->bits
= (template->meta_opcode
|
3065 (dest_regs
[0]->no
<< 14) |
3072 if (sign_extend
== 1 && top
== 0)
3073 insn
->bits
|= (1 << 1);
3075 insn
->bits
|= unit_bit
<< 24;
3080 /* Parse a CACHEW instruction. */
3082 parse_cachew (const char *line
, metag_insn
*insn
,
3083 const insn_template
*template)
3085 const char *l
= line
;
3086 const metag_reg
*src_regs
[2];
3087 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3091 memset(&addr
, 0, sizeof(addr
));
3092 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3094 l
= parse_addr (l
, &addr
, size
);
3097 !is_short_unit (addr
.base_reg
->unit
) ||
3101 as_bad (_("invalid memory operand"));
3112 l
= parse_gp_regs (l
, src_regs
, 1);
3114 l
= parse_pair_gp_regs (l
, src_regs
);
3117 !is_short_unit (src_regs
[0]->unit
))
3119 as_bad (_("invalid source register"));
3123 offset
= addr
.exp
.X_add_number
;
3128 offset
= offset
/ 64;
3130 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3132 as_bad (_("offset value out of range"));
3136 insn
->bits
= (template->meta_opcode
|
3137 (src_regs
[0]->no
<< 19) |
3138 (addr
.base_reg
->no
<< 14) |
3139 ((offset
& GET_SET_IMM_MASK
) << 8) |
3140 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3141 ((src_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3147 /* Parse a CACHEW instruction. */
3149 parse_cacher (const char *line
, metag_insn
*insn
,
3150 const insn_template
*template)
3152 const char *l
= line
;
3153 const metag_reg
*dest_regs
[2];
3154 unsigned int size
= ((template->meta_opcode
>> 1) & 0x1) ? 8 : 4;
3158 memset(&addr
, 0, sizeof(addr
));
3159 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3162 l
= parse_gp_regs (l
, dest_regs
, 1);
3164 l
= parse_pair_gp_regs (l
, dest_regs
);
3167 !is_short_unit (dest_regs
[0]->unit
))
3169 as_bad (_("invalid destination register"));
3179 l
= parse_addr (l
, &addr
, size
);
3182 !is_short_unit (addr
.base_reg
->unit
) ||
3186 as_bad (_("invalid memory operand"));
3190 offset
= addr
.exp
.X_add_number
;
3195 offset
= offset
/ (int)size
;
3197 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3199 as_bad (_("offset value out of range"));
3203 insn
->bits
= (template->meta_opcode
|
3204 (dest_regs
[0]->no
<< 19) |
3205 (addr
.base_reg
->no
<< 14) |
3206 ((offset
& GET_SET_IMM_MASK
) << 8) |
3207 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3208 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3214 /* Parse an ICACHE instruction. */
3216 parse_icache (const char *line
, metag_insn
*insn
,
3217 const insn_template
*template)
3219 const char *l
= line
;
3223 l
= parse_imm_constant (l
, insn
, &offset
);
3228 if (!within_signed_range (offset
, IMM15_BITS
))
3233 l
= parse_imm_constant (l
, insn
, &pfcount
);
3238 if (!within_unsigned_range (pfcount
, IMM4_BITS
))
3241 insn
->bits
= (template->meta_opcode
|
3242 ((offset
& IMM15_MASK
) << 9) |
3243 ((pfcount
& IMM4_MASK
) << 1));
3249 /* Parse a LNKGET instruction. */
3251 parse_lnkget (const char *line
, metag_insn
*insn
,
3252 const insn_template
*template)
3254 const char *l
= line
;
3255 const metag_reg
*dest_regs
[2];
3256 unsigned int size
= metag_get_set_ext_size_bytes (template->meta_opcode
);
3260 memset(&addr
, 0, sizeof(addr
));
3261 addr
.reloc_type
= BFD_RELOC_UNUSED
;
3264 l
= parse_pair_gp_regs (l
, dest_regs
);
3266 l
= parse_gp_regs (l
, dest_regs
, 1);
3269 !is_short_unit (dest_regs
[0]->unit
))
3271 as_bad (_("invalid destination register"));
3281 l
= parse_addr (l
, &addr
, size
);
3284 !is_short_unit (addr
.base_reg
->unit
) ||
3288 as_bad (_("invalid memory operand"));
3292 offset
= addr
.exp
.X_add_number
;
3297 offset
= offset
/ size
;
3299 if (!within_signed_range (offset
, GET_SET_IMM_BITS
))
3301 as_bad (_("offset value out of range"));
3305 insn
->bits
= (template->meta_opcode
|
3306 (dest_regs
[0]->no
<< 19) |
3307 (addr
.base_reg
->no
<< 14) |
3308 ((offset
& GET_SET_IMM_MASK
) << 8) |
3309 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5) |
3310 ((dest_regs
[0]->unit
& SHORT_UNIT_MASK
) << 3));
3316 /* Parse an FPU MOV instruction. */
3318 parse_fmov (const char *line
, metag_insn
*insn
,
3319 const insn_template
*template)
3321 const char *l
= line
;
3322 const metag_reg
*regs
[2];
3324 l
= parse_fpu_regs (l
, regs
, 2);
3329 insn
->bits
= (template->meta_opcode
|
3330 (regs
[0]->no
<< 19) |
3331 (regs
[1]->no
<< 14));
3333 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3334 insn
->bits
|= (1 << 5);
3335 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3336 insn
->bits
|= (1 << 6);
3342 /* Parse an FPU MMOV instruction. */
3344 parse_fmmov (const char *line
, metag_insn
*insn
,
3345 const insn_template
*template)
3347 const char *l
= line
;
3348 bfd_boolean to_fpu
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
3349 bfd_boolean is_mmovl
= MINOR_OPCODE (template->meta_opcode
) & 0x1;
3350 size_t regs_read
= 0;
3351 const metag_reg
*regs
[16];
3352 unsigned int lowest_data_reg
= 0xffffffff;
3353 unsigned int lowest_fpu_reg
= 0xffffffff;
3354 unsigned int rmask
= 0, data_unit
;
3358 if (insn
->fpu_width
!= FPU_WIDTH_SINGLE
)
3361 l
= parse_gp_regs_list (l
, regs
, 16, ®s_read
);
3371 for (i
= 0; i
< regs_read
/ 2; i
++)
3373 if (regs
[i
]->unit
!= UNIT_FX
)
3378 last_reg
= regs
[i
]->no
;
3379 lowest_fpu_reg
= last_reg
;
3385 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3388 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3391 last_reg
= regs
[i
]->no
;
3395 if (regs
[i
]->unit
== UNIT_D0
)
3397 else if (regs
[i
]->unit
== UNIT_D1
)
3402 if (!check_rmask (®s
[i
], regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3408 if (regs
[0]->unit
== UNIT_D0
)
3410 else if (regs
[0]->unit
== UNIT_D1
)
3415 if (!check_rmask (regs
, regs_read
/ 2, TRUE
, FALSE
, &lowest_data_reg
,
3419 for (i
= regs_read
/ 2; i
< regs_read
; i
++)
3421 if (regs
[i
]->unit
!= UNIT_FX
)
3426 last_reg
= regs
[i
]->no
;
3427 lowest_fpu_reg
= last_reg
;
3433 if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 2))
3436 else if (regs
[i
]->no
!= (unsigned int)(last_reg
+ 1))
3439 last_reg
= regs
[i
]->no
;
3444 insn
->bits
= (template->meta_opcode
|
3445 ((lowest_data_reg
& REG_MASK
) << 19) |
3446 ((lowest_fpu_reg
& REG_MASK
) << 14) |
3447 ((rmask
& RMASK_MASK
) << 7) |
3454 /* Parse an FPU data unit MOV instruction. */
3456 parse_fmov_data (const char *line
, metag_insn
*insn
,
3457 const insn_template
*template)
3459 const char *l
= line
;
3460 unsigned int to_fpu
= ((template->meta_opcode
>> 7) & 0x1);
3461 const metag_reg
*regs
[2];
3462 unsigned int base_unit
;
3464 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3467 l
= parse_gp_regs (l
, regs
, 2);
3474 if (regs
[0]->unit
!= UNIT_FX
)
3477 if (regs
[1]->unit
== UNIT_D0
)
3479 else if (regs
[1]->unit
== UNIT_D1
)
3486 if (regs
[0]->unit
== UNIT_D0
)
3488 else if (regs
[0]->unit
== UNIT_D1
)
3493 if (regs
[1]->unit
!= UNIT_FX
)
3497 insn
->bits
= (template->meta_opcode
|
3499 (regs
[0]->no
<< 19) |
3500 (regs
[1]->no
<< 9));
3506 /* Parse an FPU immediate MOV instruction. */
3508 parse_fmov_i (const char *line
, metag_insn
*insn
,
3509 const insn_template
*template)
3511 const char *l
= line
;
3512 const metag_reg
*regs
[1];
3515 l
= parse_fpu_regs (l
, regs
, 1);
3523 l
= parse_imm16 (l
, insn
, &value
);
3528 insn
->bits
= (template->meta_opcode
|
3529 (regs
[0]->no
<< 19) |
3530 ((value
& IMM16_MASK
) << 3));
3532 if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3533 insn
->bits
|= (1 << 1);
3534 else if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3535 insn
->bits
|= (1 << 2);
3541 /* Parse an FPU PACK instruction. */
3543 parse_fpack (const char *line
, metag_insn
*insn
,
3544 const insn_template
*template)
3546 const char *l
= line
;
3547 const metag_reg
*regs
[3];
3549 l
= parse_fpu_regs (l
, regs
, 3);
3554 if (regs
[0]->no
% 2)
3556 as_bad (_("destination register should be even numbered"));
3560 insn
->bits
= (template->meta_opcode
|
3561 (regs
[0]->no
<< 19) |
3562 (regs
[1]->no
<< 14) |
3563 (regs
[2]->no
<< 9));
3569 /* Parse an FPU SWAP instruction. */
3571 parse_fswap (const char *line
, metag_insn
*insn
,
3572 const insn_template
*template)
3574 const char *l
= line
;
3575 const metag_reg
*regs
[2];
3577 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3580 l
= parse_fpu_regs (l
, regs
, 2);
3585 if (regs
[0]->no
% 2)
3588 if (regs
[1]->no
% 2)
3591 insn
->bits
= (template->meta_opcode
|
3592 (regs
[0]->no
<< 19) |
3593 (regs
[1]->no
<< 14));
3599 /* Parse an FPU CMP instruction. */
3601 parse_fcmp (const char *line
, metag_insn
*insn
,
3602 const insn_template
*template)
3604 const char *l
= line
, *l2
;
3605 const metag_reg
*regs1
[1];
3606 const metag_reg
*regs2
[1];
3608 l
= parse_fpu_regs (l
, regs1
, 1);
3616 l2
= parse_fpu_regs (l
, regs2
, 1);
3620 insn
->bits
= (regs2
[0]->no
<< 9);
3625 l2
= parse_imm_constant (l
, insn
, &constant
);
3626 if (!l2
|| constant
!= 0)
3628 as_bad (_("comparison must be with register or #0"));
3631 insn
->bits
= (1 << 8);
3634 insn
->bits
|= (template->meta_opcode
|
3635 (regs1
[0]->no
<< 14));
3637 if (insn
->fpu_action_flags
& FPU_ACTION_ABS
)
3638 insn
->bits
|= (1 << 19);
3640 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3641 insn
->bits
|= (1 << 7);
3643 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3644 insn
->bits
|= (1 << 6);
3645 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3646 insn
->bits
|= (1 << 5);
3652 /* Parse an FPU MIN or MAX instruction. */
3654 parse_fminmax (const char *line
, metag_insn
*insn
,
3655 const insn_template
*template)
3657 const char *l
= line
;
3658 const metag_reg
*regs
[3];
3660 l
= parse_fpu_regs (l
, regs
, 3);
3665 insn
->bits
= (template->meta_opcode
|
3666 (regs
[0]->no
<< 19) |
3667 (regs
[1]->no
<< 14) |
3668 (regs
[2]->no
<< 9));
3670 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3671 insn
->bits
|= (1 << 6);
3672 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3673 insn
->bits
|= (1 << 5);
3679 /* Parse an FPU data conversion instruction. */
3681 parse_fconv (const char *line
, metag_insn
*insn
,
3682 const insn_template
*template)
3684 const char *l
= line
;
3685 const metag_reg
*regs
[2];
3687 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3689 if (strncasecmp (template->name
, "FTOH", 4) &&
3690 strncasecmp (template->name
, "HTOF", 4) &&
3691 strncasecmp (template->name
, "FTOI", 4) &&
3692 strncasecmp (template->name
, "ITOF", 4))
3694 as_bad (_("instruction cannot operate on pair values"));
3699 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3701 if (strncasecmp (template->name
, "FTOI", 4) &&
3702 strncasecmp (template->name
, "DTOI", 4) &&
3703 strncasecmp (template->name
, "DTOL", 4))
3705 as_bad (_("zero flag is not valid for this instruction"));
3710 l
= parse_fpu_regs (l
, regs
, 2);
3715 if (!strncasecmp (template->name
, "DTOL", 4) ||
3716 !strncasecmp (template->name
, "LTOD", 4))
3718 if (regs
[0]->no
% 2)
3720 as_bad (_("destination register should be even numbered"));
3724 if (regs
[1]->no
% 2)
3726 as_bad (_("source register should be even numbered"));
3731 insn
->bits
= (template->meta_opcode
|
3732 (regs
[0]->no
<< 19) |
3733 (regs
[1]->no
<< 14));
3735 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3736 insn
->bits
|= (1 << 6);
3738 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3739 insn
->bits
|= (1 << 12);
3745 /* Parse an FPU extended data conversion instruction. */
3747 parse_fconvx (const char *line
, metag_insn
*insn
,
3748 const insn_template
*template)
3750 const char *l
= line
;
3751 const metag_reg
*regs
[2];
3752 int fraction_bits
= 0;
3754 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3756 if (strncasecmp (template->name
, "FTOX", 4) &&
3757 strncasecmp (template->name
, "XTOF", 4))
3759 as_bad (_("instruction cannot operate on pair values"));
3764 l
= parse_fpu_regs (l
, regs
, 2);
3772 l
= parse_imm_constant (l
, insn
, &fraction_bits
);
3777 insn
->bits
= (template->meta_opcode
|
3778 (regs
[0]->no
<< 19) |
3779 (regs
[1]->no
<< 14));
3781 if (strncasecmp (template->name
, "DTOXL", 5) &&
3782 strncasecmp (template->name
, "XLTOD", 5))
3784 if (!within_unsigned_range (fraction_bits
, IMM5_BITS
))
3786 as_bad (_("fraction bits value out of range"));
3789 insn
->bits
|= ((fraction_bits
& IMM5_MASK
) << 9);
3793 if (!within_unsigned_range (fraction_bits
, IMM6_BITS
))
3795 as_bad (_("fraction bits value out of range"));
3798 insn
->bits
|= ((fraction_bits
& IMM6_MASK
) << 8);
3801 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3802 insn
->bits
|= (1 << 6);
3808 /* Parse an FPU basic arithmetic instruction. */
3810 parse_fbarith (const char *line
, metag_insn
*insn
,
3811 const insn_template
*template)
3813 const char *l
= line
;
3814 const metag_reg
*regs
[3];
3816 l
= parse_fpu_regs (l
, regs
, 3);
3821 insn
->bits
= (template->meta_opcode
|
3822 (regs
[0]->no
<< 19) |
3823 (regs
[1]->no
<< 14) |
3824 (regs
[2]->no
<< 9));
3826 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3827 insn
->bits
|= (1 << 6);
3828 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3829 insn
->bits
|= (1 << 5);
3831 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3832 insn
->bits
|= (1 << 7);
3838 /* Parse a floating point accumulator name. */
3840 parse_acf (const char *line
, int *part
)
3842 const char *l
= line
;
3845 for (i
= 0; i
< sizeof(metag_acftab
)/sizeof(metag_acftab
[0]); i
++)
3847 const metag_acf
*acf
= &metag_acftab
[i
];
3848 size_t name_len
= strlen (acf
->name
);
3850 if (strncasecmp (l
, acf
->name
, name_len
) == 0)
3860 /* Parse an FPU extended arithmetic instruction. */
3862 parse_fearith (const char *line
, metag_insn
*insn
,
3863 const insn_template
*template)
3865 const char *l
= line
;
3866 const metag_reg
*regs
[3];
3867 bfd_boolean is_muz
= (MINOR_OPCODE (template->meta_opcode
) == 0x6 &&
3868 ((template->meta_opcode
>> 4) & 0x1));
3869 unsigned int is_o3o
= template->meta_opcode
& 0x1;
3870 unsigned int is_mac
= 0;
3871 unsigned int is_maw
= 0;
3873 if (!strncasecmp (template->name
, "MAW", 3))
3876 if (!strncasecmp (template->name
, "MAC", 3))
3879 l
= parse_acf (l
, &part
);
3881 if (l
== NULL
|| part
!= 0)
3886 l
= parse_fpu_regs (l
, ®s
[1], 2);
3892 if (is_o3o
&& is_maw
)
3893 l
= parse_fpu_regs (l
, regs
, 2);
3895 l
= parse_fpu_regs (l
, regs
, 3);
3901 if (is_o3o
&& is_maw
)
3902 insn
->bits
= (template->meta_opcode
|
3903 (regs
[1]->no
<< 9));
3905 insn
->bits
= (template->meta_opcode
|
3906 (regs
[1]->no
<< 14));
3908 if (!(is_o3o
&& is_maw
))
3909 insn
->bits
|= (regs
[2]->no
<< 9);
3911 if (is_o3o
&& is_maw
)
3912 insn
->bits
|= (regs
[0]->no
<< 14);
3914 insn
->bits
|= (regs
[0]->no
<< 19);
3916 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3917 insn
->bits
|= (1 << 6);
3918 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3919 insn
->bits
|= (1 << 5);
3921 if (!is_mac
&& !is_maw
)
3922 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3923 insn
->bits
|= (1 << 7);
3926 if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3927 insn
->bits
|= (1 << 1);
3933 /* Parse an FPU RCP or RSQ instruction. */
3935 parse_frec (const char *line
, metag_insn
*insn
,
3936 const insn_template
*template)
3938 const char *l
= line
;
3939 const metag_reg
*regs
[2];
3941 l
= parse_fpu_regs (l
, regs
, 2);
3946 insn
->bits
= (template->meta_opcode
|
3947 (regs
[0]->no
<< 19) |
3948 (regs
[1]->no
<< 14));
3950 if (insn
->fpu_width
== FPU_WIDTH_PAIR
)
3951 insn
->bits
|= (1 << 6);
3952 else if (insn
->fpu_width
== FPU_WIDTH_DOUBLE
)
3953 insn
->bits
|= (1 << 5);
3955 if (insn
->fpu_action_flags
& FPU_ACTION_ZERO
)
3956 insn
->bits
|= (1 << 10);
3957 else if (insn
->fpu_action_flags
& FPU_ACTION_QUIET
)
3958 insn
->bits
|= (1 << 9);
3960 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
3961 insn
->bits
|= (1 << 7);
3967 /* Parse an FPU vector arithmetic instruction. */
3969 parse_fsimd (const char *line
, metag_insn
*insn
,
3970 const insn_template
*template)
3972 const char *l
= line
;
3973 const metag_reg
*regs
[3];
3975 if (insn
->fpu_width
!= FPU_WIDTH_PAIR
)
3977 as_bad (_("simd instructions operate on pair values (L prefix)"));
3981 l
= parse_fpu_regs (l
, regs
, 3);
3986 if (regs
[0]->no
% 2)
3988 as_bad (_("destination register should be even numbered"));
3992 if ((regs
[1]->no
% 2) ||
3995 as_bad (_("source registers should be even numbered"));
3999 insn
->bits
= (template->meta_opcode
|
4000 (regs
[0]->no
<< 19) |
4001 (regs
[1]->no
<< 14) |
4002 (regs
[2]->no
<< 9));
4004 if (insn
->fpu_action_flags
& FPU_ACTION_INV
)
4005 insn
->bits
|= (1 << 7);
4011 /* Parse an FPU accumulator GET or SET instruction. */
4013 parse_fget_set_acf (const char *line
, metag_insn
*insn
,
4014 const insn_template
*template)
4016 const char *l
= line
;
4019 bfd_boolean is_get
= MAJOR_OPCODE (template->meta_opcode
) == OPC_GET
;
4021 memset(&addr
, 0, sizeof(addr
));
4022 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4026 l
= parse_acf (l
, &part
);
4033 l
= parse_mget_mset_addr (l
, &addr
);
4037 l
= parse_mget_mset_addr (l
, &addr
);
4044 l
= parse_acf (l
, &part
);
4050 insn
->bits
= (template->meta_opcode
|
4053 if (!is_short_unit (addr
.base_reg
->unit
))
4055 as_bad (_("base unit must be one of %s"), SHORT_UNITS
);
4059 insn
->bits
|= ((addr
.base_reg
->no
<< 14) |
4060 ((addr
.base_reg
->unit
& SHORT_UNIT_MASK
) << 5));
4066 /* Copy the name of the next register in LINE to REG_BUF. */
4068 strip_reg_name(const char *line
, char *reg_buf
)
4070 const char *l
= line
;
4073 while (is_register_char (*l
))
4078 if (!(len
< MAX_REG_LEN
))
4083 reg_buf
[len
] = '\0';
4088 /* Parse a DSP register from LINE into REG using only the registers
4089 from DSP_REGTAB. Return the next character or NULL. */
4091 __parse_dsp_reg (const char *line
, const metag_reg
**reg
, htab_t dsp_regtab
)
4093 const char *l
= line
;
4094 char name
[MAX_REG_LEN
];
4097 const metag_reg
*_reg
;
4099 /* We don't entirely strip the register name because we might
4100 actually want to match whole string in the register table,
4101 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4102 entry limits our comparison to a reasonable bound anyway. */
4103 while (is_register_char (*l
) || *l
== PLUS
)
4108 if (!(len
< MAX_REG_LEN
))
4118 _reg
= (const metag_reg
*) htab_find (dsp_regtab
, &entry
);
4127 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4128 member is suitable for encoding into a DSP insn register field. */
4130 parse_dsp_insn_reg (const char *line
, const metag_reg
**reg
)
4132 return __parse_dsp_reg (line
, reg
, dsp_reg_htab
);
4135 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4136 member is suitable for encoding into a DSP template definition insn
4139 There is a separate table for whether we're doing a load or a store
4140 definition. "load" specifies which table to look at. */
4142 parse_dsp_template_reg (const char *line
, const metag_reg
**reg
,
4145 return __parse_dsp_reg (line
, reg
, dsp_tmpl_reg_htab
[load
]);
4148 /* Parse a single DSP register from LINE. */
4150 parse_dsp_reg (const char *line
, const metag_reg
**reg
,
4151 bfd_boolean tmpl
, bfd_boolean load
)
4154 return parse_dsp_template_reg (line
, reg
, load
);
4156 return parse_dsp_insn_reg (line
, reg
);
4159 /* Return TRUE if UNIT is an address unit. */
4161 is_addr_unit (enum metag_unit unit
)
4173 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4175 is_same_data_unit (enum metag_unit unit1
, enum metag_unit unit2
)
4183 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
)
4187 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
)
4191 if (unit2
== UNIT_D0
|| unit2
== UNIT_RAM_D0
)
4195 if (unit2
== UNIT_D1
|| unit2
== UNIT_RAM_D1
)
4199 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_D0
)
4203 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_D1
)
4213 /* Return TRUE if the register NUM is a quickrot control register. */
4215 is_quickrot_reg (unsigned int num
)
4227 /* Return TRUE if REG is an accumulator register. */
4229 is_accumulator_reg (const metag_reg
*reg
)
4231 if (reg
->unit
== UNIT_ACC_D0
|| reg
->unit
== UNIT_ACC_D1
)
4237 /* Return TRUE if REG is a DSP RAM register. */
4239 is_dspram_reg (const metag_reg
*reg
)
4241 if (reg
->unit
== UNIT_RAM_D0
|| reg
->unit
== UNIT_RAM_D1
)
4248 __parse_gp_reg (const char *line
, const metag_reg
**reg
, bfd_boolean load
)
4250 const char *l
= line
;
4251 char reg_buf
[MAX_REG_LEN
];
4257 /* Parse [DSPRAM.x]. */
4258 if (*l
== ADDR_BEGIN_CHAR
)
4265 l
= parse_dsp_reg (l
, reg
, TRUE
, load
);
4269 if (*l
== ADDR_END_CHAR
)
4273 as_bad (_("expected ']', not %c in %s"), *l
, l
);
4282 len
= strip_reg_name (l
, reg_buf
);
4287 *reg
= parse_gp_reg (reg_buf
);
4295 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4296 should try to parse the register as a general-purpose register if
4297 we fail to parse it as a DSP one. TMPL indicates whether the
4298 registers are part of a template definition instruction. If this is
4299 a template definition instruction LOAD says whether it's a load
4300 template insn. FIRST_DST indicates whether the first register is
4301 a destination operand. */
4303 parse_dsp_regs_list (const char *line
, const metag_reg
**regs
, size_t count
,
4304 size_t *regs_read
, bfd_boolean try_gp
, bfd_boolean tmpl
,
4305 bfd_boolean load
, bfd_boolean first_dst
)
4307 const char *l
= line
;
4310 const metag_reg
*reg
;
4312 for (i
= 0; i
< count
; i
++)
4314 const char *next
, *ll
;
4323 *regs_read
= seen_regs
;
4328 ll
= parse_dsp_reg (l
, ®
, tmpl
, load
);
4334 l
= __parse_gp_reg (l
, ®
, !(first_dst
&& i
== 0));
4337 *regs_read
= seen_regs
;
4345 *regs_read
= seen_regs
;
4357 *regs_read
= seen_regs
;
4361 /* Parse the following memory references:
4372 - [DSPRam-DSPRam--] */
4374 parse_dsp_addr (const char *line
, metag_addr
*addr
, unsigned int size
,
4377 const char *l
= line
, *ll
;
4378 const metag_reg
*regs
[1];
4381 /* Skip opening square bracket. */
4384 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4389 if (!is_addr_unit (regs
[0]->unit
) &&
4390 !is_dspram_reg (regs
[0]))
4392 as_bad (_("invalid register for memory access"));
4396 addr
->base_reg
= regs
[0];
4398 if (*l
== ADDR_END_CHAR
)
4400 addr
->exp
.X_op
= O_constant
;
4401 addr
->exp
.X_add_symbol
= NULL
;
4402 addr
->exp
.X_op_symbol
= NULL
;
4404 /* Simple register with no offset (0 immediate). */
4405 addr
->exp
.X_add_number
= 0;
4407 addr
->immediate
= 1;
4413 ll
= parse_addr_post_incr_op (l
, addr
);
4415 if (ll
&& *ll
== ADDR_END_CHAR
)
4417 if (addr
->update
== 1)
4419 /* We have a post increment/decrement. */
4420 addr
->exp
.X_op
= O_constant
;
4421 addr
->exp
.X_add_number
= size
;
4422 addr
->exp
.X_add_symbol
= NULL
;
4423 addr
->exp
.X_op_symbol
= NULL
;
4424 addr
->post_increment
= 1;
4426 addr
->immediate
= 1;
4431 addr
->post_increment
= 0;
4433 l
= parse_addr_op (l
, addr
);
4438 l
= parse_dsp_regs_list (l
, regs
, 1, ®s_read
, TRUE
, TRUE
, load
, FALSE
);
4443 if (regs
[0]->unit
!= addr
->base_reg
->unit
)
4445 as_bad (_("offset and base must be from the same unit"));
4449 addr
->offset_reg
= regs
[0];
4451 if (*l
== ADDR_END_CHAR
)
4457 l
= parse_addr_post_incr_op (l
, addr
);
4462 if (*l
== ADDR_END_CHAR
)
4471 /* Parse a DSP GET or SET instruction. */
4473 parse_dget_set (const char *line
, metag_insn
*insn
,
4474 const insn_template
*template)
4476 const char *l
= line
;
4480 bfd_boolean is_get
= (template->meta_opcode
& 0x100);
4481 bfd_boolean is_dual
= (template->meta_opcode
& 0x4);
4482 bfd_boolean is_template
= FALSE
;
4483 const metag_reg
*regs
[2];
4485 size_t count
, regs_read
;
4487 memset(&addr
, 0, sizeof(addr
));
4488 addr
.reloc_type
= BFD_RELOC_UNUSED
;
4490 size
= is_dual
? 8 : 4;
4491 count
= is_dual
? 2 : 1;
4495 /* GETL can be used on one template table entry. */
4499 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
,
4500 FALSE
, FALSE
, FALSE
);
4505 as_bad (_("unexpected end of line"));
4509 l
= parse_addr (l
, &addr
, size
);
4513 l
= parse_addr (l
, &addr
, size
);
4520 /* GETL can be used on one template table entry. */
4524 l
= parse_dsp_regs_list (l
, regs
, count
, ®s_read
, FALSE
, FALSE
,
4531 /* The first register dictates the unit. */
4532 if (regs
[0]->unit
== UNIT_DT
)
4536 if (regs
[0]->unit
== UNIT_D0
|| regs
[0]->unit
== UNIT_RAM_D0
||
4537 regs
[0]->unit
== UNIT_ACC_D0
)
4543 rd_reg
= regs
[0]->no
;
4545 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4546 upper 8-bits of an accumulator. It is _only_ valid for the
4548 if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
)
4550 if (is_template
|| !(rd_reg
>= 16 && rd_reg
< 20))
4552 as_bad (_("'H' modifier only valid for accumulator registers"));
4556 /* Top 8-bits of the accumulator. */
4562 insn
->bits
= (template->meta_opcode
| (1 << 1));
4566 insn
->bits
= (template->meta_opcode
| unit
);
4569 insn
->bits
|= (rd_reg
<< 19);
4573 int offset
= addr
.exp
.X_add_number
;
4578 offset
= offset
/ (int)size
;
4580 if (!within_signed_range (offset
, DGET_SET_IMM_BITS
))
4582 as_bad (_("offset value out of range"));
4586 offset
= offset
& DGET_SET_IMM_MASK
;
4588 insn
->bits
|= (1 << 13);
4589 insn
->bits
|= (offset
<< 9);
4593 int au
= (addr
.base_reg
->unit
== UNIT_A1
);
4595 insn
->bits
|= (au
<< 18);
4596 insn
->bits
|= ((addr
.base_reg
->no
& REG_MASK
) << 14);
4597 insn
->bits
|= ((addr
.offset_reg
->no
& REG_MASK
) << 9);
4601 insn
->bits
|= (1 << 2);
4603 if (!is_addr_unit (addr
.base_reg
->unit
))
4605 as_bad (_("base unit must be either A0 or A1"));
4609 unit
= (addr
.base_reg
->unit
== UNIT_A0
) ? 0 : 1;
4610 insn
->bits
|= ((addr
.base_reg
->no
<< 14) | (unit
<< 18));
4617 /* Parse a DSP template instruction. */
4619 parse_dtemplate (const char *line
, metag_insn
*insn
,
4620 const insn_template
*template)
4622 const char *l
= line
;
4623 const metag_reg
*regs
[TEMPLATE_NUM_REGS
];
4624 bfd_boolean daop_only
= FALSE
;
4626 int regs_which
[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4629 for (i
= 0; i
< TEMPLATE_NUM_REGS
; i
++)
4633 as_bad (_("unexpected end of line"));
4637 /* We may only have 3 register operands. */
4638 if (*l
== END_OF_INSN
&& i
== 3)
4653 l
= parse_imm_constant (l
, insn
, ®s_val
[i
]);
4656 as_bad (_("invalid immediate"));
4663 /* We can't tell from the template instantiation whether
4664 this is a load or store. So we have to try looking up the
4665 register name in both the load and store tables. */
4667 l
= __parse_gp_reg (l
, ®s
[i
], TRUE
);
4670 /* Try the store table too. */
4671 l
= __parse_gp_reg (l2
, ®s
[i
], FALSE
);
4674 /* Then try a DSP register. */
4675 l
= parse_dsp_insn_reg (l2
, ®s
[i
]);
4676 if (l
== NULL
|| regs
[i
]->unit
== UNIT_DT
)
4678 as_bad (_("invalid register"));
4687 insn
->bits
= template->meta_opcode
;
4689 if (regs_which
[0] == 0)
4690 insn
->bits
|= (regs_val
[0] << 19);
4691 else if (regs_which
[0] == 1)
4692 insn
->bits
|= (regs
[0]->no
<< 19);
4694 if (regs_which
[1] == 0)
4695 insn
->bits
|= (regs_val
[1] << 14);
4696 else if (regs_which
[1] == 1)
4697 insn
->bits
|= (regs
[1]->no
<< 14);
4699 if (regs_which
[2] == 0)
4700 insn
->bits
|= (regs_val
[2] << 9);
4701 else if (regs_which
[2] == 1)
4702 insn
->bits
|= (regs
[2]->no
<< 9);
4704 if (regs_which
[3] == 0)
4705 insn
->bits
|= (regs_val
[3] << 4);
4706 else if (regs_which
[3] == 1)
4707 insn
->bits
|= (regs
[3]->no
<< 4);
4711 insn
->bits
|= (0x3 << 24); /* Set the minor opcode. */
4712 else if (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_HIGH
) /* Half Load/Store. */
4713 insn
->bits
|= (0x5 << 24); /* Set the minor opcode. */
4720 /* Parse a DSP Template definition memory reference, e.g
4721 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4722 template definition is a DSP RAM template definition. */
4724 template_mem_ref(const char *line
, metag_addr
*addr
,
4725 bfd_boolean
*dspram
, int size
, bfd_boolean load
)
4727 const char *l
= line
;
4729 l
= parse_dsp_addr (l
, addr
, size
, load
);
4733 if (is_addr_unit(addr
->base_reg
->unit
))
4742 /* Sets LOAD to TRUE if this is a Template load definition (otherwise
4743 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4745 parse_template_regs (const char *line
, bfd_boolean
*load
,
4746 unsigned int *addr_unit
,
4747 const metag_reg
**template_reg
, metag_addr
*addr
,
4748 bfd_boolean
*dspram
, int size
)
4750 const char *l
= line
;
4755 /* DSP Template load definition (Tx, [Ax]) */
4759 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4765 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4767 if (addr
->base_reg
->unit
== UNIT_A1
)
4771 else if (*l
== ADDR_BEGIN_CHAR
) /* DSP Template store ([Ax], Tx) */
4774 l
= template_mem_ref (l
, addr
, dspram
, size
, *load
);
4780 l
= parse_dsp_reg (l
, &template_reg
[0], FALSE
, FALSE
);
4784 if (addr
->base_reg
->unit
== UNIT_A1
)
4789 as_bad (_("invalid register operand"));
4796 #define INVALID_SHIFT (-1)
4798 static metag_reg _reg
;
4800 /* Parse a template instruction definition. */
4802 interpret_template_regs(const char *line
, metag_insn
*insn
,
4803 const metag_reg
**regs
,
4804 int *regs_shift
, bfd_boolean
*load
, bfd_boolean
*dspram
,
4805 int size
, int *ls_shift
, int *au_shift
,
4806 unsigned int *au
, int *imm
, int *imm_shift
,
4807 unsigned int *imm_mask
)
4809 const char *l
= line
;
4811 const metag_reg
*template_reg
[1];
4813 memset (&addr
, 0, sizeof(addr
));
4816 regs_shift
[1] = INVALID_SHIFT
;
4818 insn
->bits
|= (1 << 1);
4820 l
= skip_whitespace (l
);
4822 l
= parse_template_regs (l
, load
, au
, template_reg
,
4823 &addr
, dspram
, size
);
4826 as_bad (_("could not parse template definition"));
4830 regs
[2] = template_reg
[0];
4833 /* DSPRAM definition. */
4837 _reg
= *addr
.base_reg
;
4841 /* Set the post-increment bit in the register field. */
4847 /* The bottom bit of the increment register tells us
4848 whether it's increment register 0 or 1. */
4849 if (addr
.offset_reg
->no
& 0x1)
4857 insn
->bits
|= (0x3 << 17); /* This signifies a DSPRAM definition. */
4859 else /* DaOpPaMe definition. */
4861 regs
[0] = addr
.base_reg
;
4864 /* Set the I bit. */
4865 insn
->bits
|= (1 << 18);
4867 if (addr
.update
== 1)
4869 if (addr
.negate
== 1)
4880 /* Setup the offset register. */
4881 regs
[1] = addr
.offset_reg
;
4892 /* Does this combination of units need the O2R bit and can it be encoded? */
4894 units_need_o2r (enum metag_unit unit1
, enum metag_unit unit2
)
4899 if (unit1
== UNIT_D0
|| unit1
== UNIT_ACC_D0
|| unit1
== UNIT_RAM_D0
)
4901 if (unit2
== UNIT_ACC_D0
|| unit2
== UNIT_RAM_D0
|| unit2
== UNIT_D0
)
4916 if (unit1
== UNIT_D1
|| unit1
== UNIT_ACC_D1
|| unit1
== UNIT_RAM_D1
)
4918 if (unit2
== UNIT_ACC_D1
|| unit2
== UNIT_RAM_D1
|| unit2
== UNIT_D1
)
4936 /* Return TRUE if this is a DSP data unit. */
4938 is_dsp_data_unit (const metag_reg
*reg
)
4954 static metag_reg o2r_reg
;
4956 /* Parse a DaOpPaMe load template definition. */
4958 parse_dalu (const char *line
, metag_insn
*insn
,
4959 const insn_template
*template)
4961 const char *l
= line
;
4963 const metag_reg
*regs
[4];
4966 bfd_boolean is_mov
= MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
;
4967 bfd_boolean is_cmp
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_CMP
) &&
4968 ((template->meta_opcode
& 0xee) == 0));
4969 bfd_boolean is_dual
= (insn
->dsp_width
== DSP_WIDTH_DUAL
);
4970 bfd_boolean is_quickrot64
= ((insn
->dsp_action_flags
& DSP_ACTION_QR64
) != 0);
4971 int l1_shift
= INVALID_SHIFT
;
4972 bfd_boolean load
= FALSE
;
4973 int ls_shift
= INVALID_SHIFT
;
4974 bfd_boolean ar
= FALSE
;
4975 int ar_shift
= INVALID_SHIFT
;
4976 int regs_shift
[3] = { INVALID_SHIFT
, INVALID_SHIFT
, INVALID_SHIFT
};
4978 int imm_shift
= INVALID_SHIFT
;
4979 unsigned int imm_mask
= 0;
4980 unsigned int au
= 0;
4981 int au_shift
= INVALID_SHIFT
;
4982 unsigned int du
= 0;
4983 int du_shift
= INVALID_SHIFT
;
4984 unsigned int sc
= ((insn
->dsp_action_flags
& DSP_ACTION_OV
) != 0);
4985 int sc_shift
= INVALID_SHIFT
;
4986 unsigned int om
= ((insn
->dsp_action_flags
& DSP_ACTION_MOD
) != 0);
4987 int om_shift
= INVALID_SHIFT
;
4988 unsigned int o2r
= 0;
4989 int o2r_shift
= INVALID_SHIFT
;
4990 unsigned int qr
= 0;
4991 int qr_shift
= INVALID_SHIFT
;
4992 int qd_shift
= INVALID_SHIFT
;
4993 unsigned int qn
= 0;
4994 int qn_shift
= INVALID_SHIFT
;
4995 unsigned int a1
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ZERO
)) != 0);
4996 int a1_shift
= INVALID_SHIFT
;
4997 unsigned int a2
= ((insn
->dsp_action_flags
& (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
)) != 0);
4998 int a2_shift
= INVALID_SHIFT
;
4999 unsigned su
= ((insn
->dsp_action_flags
& DSP_ACTION_UMUL
) != 0);
5000 int su_shift
= INVALID_SHIFT
;
5002 int ac_shift
= INVALID_SHIFT
;
5003 unsigned int mx
= (((insn
->dsp_daoppame_flags
& DSP_DAOPPAME_8
) != 0) ||
5004 (insn
->dsp_daoppame_flags
& DSP_DAOPPAME_16
) != 0);
5005 int mx_shift
= INVALID_SHIFT
;
5006 int size
= is_dual
? 8 : 4;
5008 bfd_boolean conditional
= (MINOR_OPCODE (template->meta_opcode
) & 0x4);
5010 /* XFIXME: check the flags are valid with the instruction. */
5011 if (is_quickrot64
&& !(template->arg_type
& DSP_ARGS_QR
))
5013 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5017 insn
->bits
= template->meta_opcode
;
5019 memset (regs
, 0, sizeof (regs
));
5020 memset (&addr
, 0, sizeof (addr
));
5022 /* There are the following forms of DSP ALU instructions,
5025 19. D[T] Op De.r,Dx.r,De.r
5026 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5027 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5028 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5029 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5030 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5031 8. D Opcc De.r,Dx.r,Rx.r
5032 6. D Op De.r,Dx.r,Rx.r|RD
5033 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5034 7. D Op De.e,Dx.r,#I16
5037 4. D[T] Op Dx.r,De.r
5038 10. D Op Dx.r,Rx.r|RD
5041 12. D[T] Op De.r,Dx.r
5042 14. D Op DSPe.r,Dx.r
5043 15. D Op DSPx.r,#I16
5044 16. D Op De.r,DSPx.r
5045 18. D Op De.r,Dx.r|ACx.r
5048 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5049 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5050 21. D Op De.r,Dx.r|ACx.r,#I5 */
5053 if (template->arg_type
& DSP_ARGS_1
)
5057 /* Could this be a cross-unit accumulator op,
5058 e.g. ACe.e,ACx.r,ACo.e */
5059 if (template->arg_type
& DSP_ARGS_XACC
)
5061 ll
= parse_dsp_regs_list (l
, regs
, 3, ®s_read
, FALSE
, FALSE
,
5063 if (ll
!= NULL
&& regs_read
== 3
5064 && is_accumulator_reg (regs
[0]))
5066 if (regs
[0]->unit
!= regs
[1]->unit
||
5067 regs
[2]->unit
== regs
[1]->unit
)
5069 as_bad (_("invalid operands for cross-unit op"));
5073 du
= (regs
[1]->unit
== UNIT_ACC_D1
);
5077 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5078 insn
->bits
|= (5 << 6);
5080 goto check_for_template
;
5083 /* If we reach here, this instruction is not a
5084 cross-unit accumulator op. */
5087 if (template->arg_type
& DSP_ARGS_SPLIT8
)
5094 /* De.r|ACe.r,Dx.r,De.r */
5095 if (template->arg_type
& DSP_ARGS_DACC
)
5097 /* XFIXME: these need moving? */
5103 ll
= parse_dsp_reg (l
, ®s
[0], FALSE
, FALSE
);
5106 /* Using ACe.r as the dst requires one of the P,N or Z
5107 flags to be used. */
5108 if (!(insn
->dsp_action_flags
&
5109 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5111 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5117 l
= parse_dsp_regs_list (l
, ®s
[1], 2, ®s_read
,
5118 TRUE
, FALSE
, FALSE
, FALSE
);
5119 if (l
== NULL
|| regs_read
!= 2)
5121 as_bad (_("invalid register"));
5125 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5131 goto check_for_template
;
5134 /* If we reach here, this instruction does not use the
5135 accumulator as the destination register. */
5136 if ((insn
->dsp_action_flags
&
5137 (DSP_ACTION_ACC_SUB
|DSP_ACTION_ACC_ADD
|DSP_ACTION_ACC_ZERO
)))
5139 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5147 l
= parse_dsp_regs_list (l
, regs
, 2, ®s_read
, TRUE
, FALSE
, FALSE
, TRUE
);
5148 if (l
== NULL
|| regs_read
!= 2)
5155 if (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_RAM_D1
)
5158 if (is_accumulator_reg(regs
[0]) && !(template->arg_type
& DSP_ARGS_DACC
))
5160 as_bad (_("accumulator not a valid destination"));
5164 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5167 l
= parse_imm16 (l
, insn
, &imm
);
5170 as_bad (_("invalid immediate value"));
5174 if (!within_signed_range (imm
, IMM16_BITS
))
5176 as_bad (_("immediate value out of range"));
5180 if (regs
[0]->unit
!= regs
[1]->unit
|| regs
[0]->no
!= regs
[1]->no
)
5182 as_bad (_("immediate value not allowed when source & dest differ"));
5190 insn
->bits
|= (1 << 25);
5192 insn
->bits
|= (0x3 << 0);
5196 /* Remove any bits that have been set in the immediate
5198 insn
->bits
&= ~(imm_mask
<< imm_shift
);
5206 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5207 ll
= parse_dsp_reg (l
, ®s
[2], FALSE
, FALSE
);
5212 if (!(template->arg_type
& DSP_ARGS_ACC2
))
5214 as_bad (_("invalid register operand: %s"), regs
[2]->name
);
5224 /* De.r,Dx.r,De.r */
5225 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5230 if (template->arg_type
& DSP_ARGS_ACC2
)
5233 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5234 if (template->arg_type
& DSP_ARGS_QR
)
5248 as_bad (_("QUICKRoT extension requires 4 registers"));
5252 l
= __parse_gp_reg (l
, ®s
[3], TRUE
);
5255 as_bad (_("invalid fourth register"));
5259 if (!is_addr_unit (regs
[3]->unit
) ||
5260 !is_quickrot_reg (regs
[3]->no
))
5262 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5266 qn
= (regs
[3]->no
== 3);
5271 /* This is the common exit path. Check for o2r. */
5272 if (regs
[2] != NULL
)
5274 o2r
= units_need_o2r (regs
[1]->unit
, regs
[2]->unit
);
5277 o2r_reg
.no
= lookup_o2r (0, du
, regs
[2]);
5278 o2r_reg
.unit
= regs
[2]->unit
;
5283 /* Check any DSP RAM pointers are valid for this unit. */
5284 if ((du
&& (regs
[0]->unit
== UNIT_RAM_D0
)) ||
5285 (!du
&& (regs
[0]->unit
== UNIT_RAM_D1
)) ||
5286 (du
&& (regs
[1]->unit
== UNIT_RAM_D0
)) ||
5287 (!du
&& (regs
[1]->unit
== UNIT_RAM_D1
)) ||
5288 (du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D0
)) ||
5289 (!du
&& regs
[2] && (regs
[2]->unit
== UNIT_RAM_D1
))) {
5290 as_bad (_("DSP RAM pointer in incorrect unit"));
5294 /* Is this a template definition? */
5295 if (IS_TEMPLATE_DEF (insn
))
5297 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5298 &dspram
, size
, &ls_shift
, &au_shift
,
5299 &au
, &imm
, &imm_shift
, &imm_mask
);
5312 if (template->arg_type
& DSP_ARGS_2
)
5314 bfd_boolean is_xsd
= ((MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
) &&
5315 (MINOR_OPCODE (template->meta_opcode
) == 0xa));
5316 bfd_boolean is_fpu_mov
= template->insn_type
== INSN_DSP_FPU
;
5317 bfd_boolean to_fpu
= (template->meta_opcode
>> 7) & 0x1;
5326 /* CMPs and TSTs don't store to their destination operand. */
5327 ll
= __parse_gp_reg (l
, regs
, is_cmp
);
5330 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5331 if (template->arg_type
& DSP_ARGS_DSP_SRC1
)
5333 l
= parse_dsp_reg (l
, regs
, FALSE
, FALSE
);
5336 as_bad (_("invalid register operand #1"));
5340 /* Only MOV instructions have a DSP register as a
5341 destination. Set the MOV DSPe.r opcode. The simple
5342 OR'ing is OK because the usual MOV opcode is 0x00. */
5343 insn
->bits
= 0x91u
<< 24;
5350 as_bad (_("invalid register operand #2"));
5358 /* Everything but CMP and TST. */
5359 if (MAJOR_OPCODE (template->meta_opcode
) == OPC_ADD
||
5360 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5361 MAJOR_OPCODE (insn
->bits
) == OPC_9
||
5362 MAJOR_OPCODE (template->meta_opcode
) == OPC_MISC
||
5363 ((template->meta_opcode
& 0x0000002c) != 0))
5369 if (!is_dsp_data_unit (regs
[0]) && !(regs
[0]->unit
== UNIT_FX
&&
5370 is_fpu_mov
&& to_fpu
))
5373 du
= (regs
[0]->unit
== UNIT_D1
|| regs
[0]->unit
== UNIT_RAM_D1
||
5374 regs
[0]->unit
== UNIT_ACC_D1
);
5380 if (template->arg_type
& DSP_ARGS_IMM
&&
5381 !(is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)))
5383 l
= parse_imm16 (l
, insn
, &imm
);
5386 as_bad (_("invalid immediate value"));
5390 if (!within_signed_range (imm
, IMM16_BITS
))
5399 /* Set the I-bit unless it's a MOV because they're
5401 if (!(is_mov
&& MAJOR_OPCODE (insn
->bits
) == OPC_9
))
5402 insn
->bits
|= (1 << 25);
5404 /* All instructions that takes immediates also have bit 1 set. */
5405 insn
->bits
|= (1 << 1);
5407 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5408 insn
->bits
|= (1 << 0);
5410 insn
->bits
&= ~(1 << 8);
5414 as_bad (_("this instruction does not accept an immediate"));
5420 if (MAJOR_OPCODE (insn
->bits
) != OPC_9
)
5422 insn
->bits
|= (1 << 8);
5426 ll
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5429 if (template->arg_type
& DSP_ARGS_DSP_SRC2
)
5431 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5434 as_bad (_("invalid register operand #3"));
5439 if ((is_mov
&& (MAJOR_OPCODE (insn
->bits
) != OPC_9
)) ||
5440 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
)
5442 if (is_accumulator_reg (regs
[1]))
5446 as_bad (_("this instruction does not accept an accumulator"));
5458 insn
->bits
= 0x92u
<< 24; /* Set opcode. */
5464 as_bad (_("invalid register operand #4"));
5470 /* Set the o2r bit if required. */
5471 if (!is_fpu_mov
&& units_need_o2r (regs
[0]->unit
, regs
[1]->unit
))
5474 o2r_reg
.no
= lookup_o2r (0, du
, regs
[1]);
5479 else if (!is_dsp_data_unit (regs
[1]) &&
5480 !(is_fpu_mov
&& !to_fpu
&& regs
[1]->unit
== UNIT_FX
))
5483 if (is_fpu_mov
&& to_fpu
)
5484 du
= (regs
[1]->unit
== UNIT_D1
||
5485 regs
[1]->unit
== UNIT_RAM_D1
||
5486 regs
[1]->unit
== UNIT_ACC_D1
);
5490 if (MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5491 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
||
5492 (((template->meta_opcode
& 0x0000002c) == 0) &&
5493 MAJOR_OPCODE (template->meta_opcode
) != OPC_MISC
))
5500 /* If it's an 0x0 MOV or NEG set some lower bits. */
5501 if ((MAJOR_OPCODE (insn
->bits
) == OPC_ADD
||
5502 MAJOR_OPCODE (template->meta_opcode
) == OPC_SUB
) && !is_fpu_mov
)
5506 insn
->bits
|= (1 << 2);
5509 /* Check for template definitions. */
5510 if (IS_TEMPLATE_DEF (insn
))
5512 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5513 &dspram
, size
, &ls_shift
, &au_shift
,
5514 &au
, &imm
, &imm_shift
, &imm_mask
);
5527 l
= __parse_gp_reg (l
, regs
, FALSE
);
5530 as_bad (_("invalid register operand"));
5538 l
= parse_dsp_reg (l
, ®s
[1], FALSE
, FALSE
);
5541 as_bad (_("invalid accumulator register"));
5549 l
= __parse_gp_reg (l
, ®s
[1], TRUE
);
5552 as_bad (_("invalid register operand"));
5560 du
= (regs
[1]->unit
== UNIT_D1
|| regs
[1]->unit
== UNIT_ACC_D1
5561 || regs
[1]->unit
== UNIT_RAM_D1
);
5567 l
= parse_imm_constant (l
, insn
, &imm
);
5570 as_bad (_("invalid immediate value"));
5574 if (!within_unsigned_range (imm
, IMM5_BITS
))
5581 insn
->bits
|= (1 << 25);
5586 l
= __parse_gp_reg (l
, ®s
[2], TRUE
);
5591 /* Check for post-processing R,G,B flags. Conditional instructions
5592 do not have these bits. */
5593 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP9
)
5595 if ((template->meta_opcode
>> 26) & 0x1)
5597 as_bad (_("conditional instruction cannot use G flag"));
5601 insn
->bits
|= (1 << 3);
5604 if (insn
->dsp_action_flags
& DSP_ACTION_CLAMP8
)
5606 if ((template->meta_opcode
>> 26) & 0x1)
5608 as_bad (_("conditional instruction cannot use B flag"));
5612 insn
->bits
|= (0x3 << 2);
5615 if (insn
->dsp_action_flags
& DSP_ACTION_ROUND
)
5617 if ((template->meta_opcode
>> 26) & 0x1)
5619 as_bad (_("conditional instruction cannot use R flag"));
5622 insn
->bits
|= (1 << 2);
5625 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5626 if ((template->meta_opcode
>> 26) & 0x1)
5627 ls_shift
= INVALID_SHIFT
;
5629 /* The Condition Is Always (CA) bit must be set if we're targeting a
5630 Ux.r register as the destination. This means that we can't have
5631 any other condition bits set. */
5632 if (!is_same_data_unit (regs
[1]->unit
, regs
[0]->unit
))
5634 /* Set both the Conditional bit and the Condition is Always bit. */
5635 insn
->bits
|= (1 << 26);
5636 insn
->bits
|= (1 << 5);
5638 /* Fill out the Ud field. */
5639 insn
->bits
|= (regs
[0]->unit
<< 1);
5642 if (IS_TEMPLATE_DEF (insn
))
5644 l
= interpret_template_regs(l
, insn
, regs
, regs_shift
, &load
,
5645 &dspram
, size
, &ls_shift
, &au_shift
,
5646 &au
, &imm
, &imm_shift
, &imm_mask
);
5658 /* Set the registers and immediate values. */
5659 if (regs_shift
[0] != INVALID_SHIFT
)
5660 insn
->bits
|= (regs
[0]->no
<< regs_shift
[0]);
5662 if (regs_shift
[1] != INVALID_SHIFT
)
5663 insn
->bits
|= (regs
[1]->no
<< regs_shift
[1]);
5665 if (regs_shift
[2] != INVALID_SHIFT
)
5666 insn
->bits
|= (regs
[2]->no
<< regs_shift
[2]);
5668 /* Does this insn have an 'IMM' bit? The immediate value should
5669 already have been masked. */
5670 if (imm_shift
!= INVALID_SHIFT
)
5671 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5673 /* Does this insn have an 'AU' bit? */
5674 if (au_shift
!= INVALID_SHIFT
)
5675 insn
->bits
|= (au
<< au_shift
);
5677 /* Does this instruction have an 'LS' bit? */
5678 if (ls_shift
!= INVALID_SHIFT
)
5679 insn
->bits
|= (load
<< ls_shift
);
5681 /* Does this instruction have an 'AR' bit? */
5683 insn
->bits
|= (1 << ar_shift
);
5685 if (du_shift
!= INVALID_SHIFT
)
5686 insn
->bits
|= (du
<< du_shift
);
5688 if (sc_shift
!= INVALID_SHIFT
)
5689 insn
->bits
|= (sc
<< sc_shift
);
5691 if (om_shift
!= INVALID_SHIFT
)
5692 insn
->bits
|= (om
<< om_shift
);
5694 if (o2r_shift
!= INVALID_SHIFT
)
5695 insn
->bits
|= (o2r
<< o2r_shift
);
5697 if (qn_shift
!= INVALID_SHIFT
)
5698 insn
->bits
|= (qn
<< qn_shift
);
5700 if (qr_shift
!= INVALID_SHIFT
)
5701 insn
->bits
|= (qr
<< qr_shift
);
5703 if (qd_shift
!= INVALID_SHIFT
)
5704 insn
->bits
|= (is_quickrot64
<< qd_shift
);
5706 if (a1_shift
!= INVALID_SHIFT
)
5707 insn
->bits
|= (a1
<< a1_shift
);
5709 if (a2_shift
!= INVALID_SHIFT
)
5710 insn
->bits
|= (a2
<< a2_shift
);
5712 if (su_shift
!= INVALID_SHIFT
)
5713 insn
->bits
|= (su
<< su_shift
);
5715 if (imm_shift
!= INVALID_SHIFT
)
5716 insn
->bits
|= ((imm
& imm_mask
) << imm_shift
);
5718 if (ac_shift
!= INVALID_SHIFT
)
5719 insn
->bits
|= (ac
<< ac_shift
);
5721 if (mx_shift
!= INVALID_SHIFT
)
5722 insn
->bits
|= (mx
<< mx_shift
);
5726 if (l1_shift
== INVALID_SHIFT
)
5728 as_bad (_("'L' modifier not valid for this instruction"));
5732 insn
->bits
|= (1 << l1_shift
);
5740 typedef const char *(*insn_parser
)(const char *, metag_insn
*,
5741 const insn_template
*);
5744 static const insn_parser insn_parsers
[ENC_MAX
] =
5746 [ENC_NONE
] = parse_none
,
5747 [ENC_MOV_U2U
] = parse_mov_u2u
,
5748 [ENC_MOV_PORT
] = parse_mov_port
,
5749 [ENC_MMOV
] = parse_mmov
,
5750 [ENC_MDRD
] = parse_mdrd
,
5751 [ENC_MOVL_TTREC
] = parse_movl_ttrec
,
5752 [ENC_GET_SET
] = parse_get_set
,
5753 [ENC_GET_SET_EXT
] = parse_get_set_ext
,
5754 [ENC_MGET_MSET
] = parse_mget_mset
,
5755 [ENC_COND_SET
] = parse_cond_set
,
5756 [ENC_XFR
] = parse_xfr
,
5757 [ENC_MOV_CT
] = parse_mov_ct
,
5758 [ENC_SWAP
] = parse_swap
,
5759 [ENC_JUMP
] = parse_jump
,
5760 [ENC_CALLR
] = parse_callr
,
5761 [ENC_ALU
] = parse_alu
,
5762 [ENC_SHIFT
] = parse_shift
,
5763 [ENC_MIN_MAX
] = parse_min_max
,
5764 [ENC_BITOP
] = parse_bitop
,
5765 [ENC_CMP
] = parse_cmp
,
5766 [ENC_BRANCH
] = parse_branch
,
5767 [ENC_KICK
] = parse_kick
,
5768 [ENC_SWITCH
] = parse_switch
,
5769 [ENC_CACHER
] = parse_cacher
,
5770 [ENC_CACHEW
] = parse_cachew
,
5771 [ENC_ICACHE
] = parse_icache
,
5772 [ENC_LNKGET
] = parse_lnkget
,
5773 [ENC_FMOV
] = parse_fmov
,
5774 [ENC_FMMOV
] = parse_fmmov
,
5775 [ENC_FMOV_DATA
] = parse_fmov_data
,
5776 [ENC_FMOV_I
] = parse_fmov_i
,
5777 [ENC_FPACK
] = parse_fpack
,
5778 [ENC_FSWAP
] = parse_fswap
,
5779 [ENC_FCMP
] = parse_fcmp
,
5780 [ENC_FMINMAX
] = parse_fminmax
,
5781 [ENC_FCONV
] = parse_fconv
,
5782 [ENC_FCONVX
] = parse_fconvx
,
5783 [ENC_FBARITH
] = parse_fbarith
,
5784 [ENC_FEARITH
] = parse_fearith
,
5785 [ENC_FREC
] = parse_frec
,
5786 [ENC_FSIMD
] = parse_fsimd
,
5787 [ENC_FGET_SET_ACF
] = parse_fget_set_acf
,
5788 [ENC_DGET_SET
] = parse_dget_set
,
5789 [ENC_DTEMPLATE
] = parse_dtemplate
,
5790 [ENC_DALU
] = parse_dalu
,
5793 struct metag_core_option
5799 /* CPU type options. */
5800 static const struct metag_core_option metag_cpus
[] =
5802 {"all", CoreMeta11
|CoreMeta12
|CoreMeta21
},
5803 {"metac11", CoreMeta11
},
5804 {"metac12", CoreMeta12
},
5805 {"metac21", CoreMeta21
},
5809 /* FPU type options. */
5810 static const struct metag_core_option metag_fpus
[] =
5812 {"metac21", FpuMeta21
},
5816 /* DSP type options. */
5817 static const struct metag_core_option metag_dsps
[] =
5819 {"metac21", DspMeta21
},
5823 /* Parse a CPU command line option. */
5825 metag_parse_cpu (const char * str
)
5827 const struct metag_core_option
* opt
;
5830 optlen
= strlen (str
);
5834 as_bad (_("missing cpu name `%s'"), str
);
5838 for (opt
= metag_cpus
; opt
->name
!= NULL
; opt
++)
5839 if (strncmp (opt
->name
, str
, optlen
) == 0)
5841 mcpu_opt
= opt
->value
;
5845 as_bad (_("unknown cpu `%s'"), str
);
5849 /* Parse an FPU command line option. */
5851 metag_parse_fpu (const char * str
)
5853 const struct metag_core_option
* opt
;
5856 optlen
= strlen (str
);
5860 as_bad (_("missing fpu name `%s'"), str
);
5864 for (opt
= metag_fpus
; opt
->name
!= NULL
; opt
++)
5865 if (strncmp (opt
->name
, str
, optlen
) == 0)
5867 mfpu_opt
= opt
->value
;
5871 as_bad (_("unknown fpu `%s'"), str
);
5875 /* Parse a DSP command line option. */
5877 metag_parse_dsp (const char * str
)
5879 const struct metag_core_option
* opt
;
5882 optlen
= strlen (str
);
5886 as_bad (_("missing DSP name `%s'"), str
);
5890 for (opt
= metag_dsps
; opt
->name
!= NULL
; opt
++)
5891 if (strncmp (opt
->name
, str
, optlen
) == 0)
5893 mdsp_opt
= opt
->value
;
5897 as_bad (_("unknown DSP `%s'"), str
);
5901 struct metag_long_option
5903 const char * option
; /* Substring to match. */
5904 const char * help
; /* Help information. */
5905 int (* func
) (const char * subopt
); /* Function to decode sub-option. */
5906 const char * deprecated
; /* If non-null, print this message. */
5909 struct metag_long_option metag_long_opts
[] =
5911 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5912 metag_parse_cpu
, NULL
},
5913 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5914 metag_parse_fpu
, NULL
},
5915 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5916 metag_parse_dsp
, NULL
},
5917 {NULL
, NULL
, 0, NULL
}
5921 md_parse_option (int c
, const char * arg
)
5923 struct metag_long_option
*lopt
;
5925 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5927 /* These options are expected to have an argument. */
5928 if (c
== lopt
->option
[0]
5930 && strncmp (arg
, lopt
->option
+ 1,
5931 strlen (lopt
->option
+ 1)) == 0)
5934 /* If the option is deprecated, tell the user. */
5935 if (lopt
->deprecated
!= NULL
)
5936 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
5937 _(lopt
->deprecated
));
5940 /* Call the sup-option parser. */
5941 return lopt
->func (arg
+ strlen (lopt
->option
) - 1);
5949 md_show_usage (FILE * stream
)
5951 struct metag_long_option
*lopt
;
5953 fprintf (stream
, _(" Meta specific command line options:\n"));
5955 for (lopt
= metag_long_opts
; lopt
->option
!= NULL
; lopt
++)
5956 if (lopt
->help
!= NULL
)
5957 fprintf (stream
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
5960 /* The target specific pseudo-ops which we support. */
5961 const pseudo_typeS md_pseudo_table
[] =
5963 { "word", cons
, 2 },
5972 for (c
= 0; c
< 256; c
++)
5976 register_chars
[c
] = c
;
5977 /* LOCK0, LOCK1, LOCK2. */
5978 mnemonic_chars
[c
] = c
;
5980 else if (ISLOWER (c
))
5982 register_chars
[c
] = c
;
5983 mnemonic_chars
[c
] = c
;
5985 else if (ISUPPER (c
))
5987 register_chars
[c
] = c
;
5988 mnemonic_chars
[c
] = c
;
5992 register_chars
[c
] = c
;
5997 /* Parse a split condition code prefix. */
5999 parse_split_condition (const char *line
, metag_insn
*insn
)
6001 const char *l
= line
;
6002 const split_condition
*scond
;
6003 split_condition entry
;
6011 scond
= (const split_condition
*) htab_find (scond_htab
, &entry
);
6016 insn
->scond
= scond
->code
;
6018 return l
+ strlen (scond
->name
);
6021 /* Parse an instruction prefix - F for float, D for DSP - and associated
6022 flags and condition codes. */
6024 parse_prefix (const char *line
, metag_insn
*insn
)
6026 const char *l
= line
;
6028 l
= skip_whitespace (l
);
6030 insn
->type
= INSN_GP
;
6032 if (TOLOWER (*l
) == FPU_PREFIX_CHAR
)
6034 if (strncasecmp (l
, FFB_INSN
, strlen(FFB_INSN
)))
6036 insn
->type
= INSN_FPU
;
6040 if (*l
== END_OF_INSN
)
6042 as_bad (_("premature end of floating point prefix"));
6046 if (TOLOWER (*l
) == FPU_DOUBLE_CHAR
)
6048 insn
->fpu_width
= FPU_WIDTH_DOUBLE
;
6051 else if (TOLOWER (*l
) == FPU_PAIR_CHAR
)
6055 /* Check this isn't a split condition beginning with L. */
6056 l2
= parse_split_condition (l2
, insn
);
6058 if (l2
&& is_whitespace_char (*l2
))
6064 insn
->fpu_width
= FPU_WIDTH_PAIR
;
6070 insn
->fpu_width
= FPU_WIDTH_SINGLE
;
6073 if (TOLOWER (*l
) == FPU_ACTION_ABS_CHAR
)
6075 insn
->fpu_action_flags
|= FPU_ACTION_ABS
;
6078 else if (TOLOWER (*l
) == FPU_ACTION_INV_CHAR
)
6080 insn
->fpu_action_flags
|= FPU_ACTION_INV
;
6084 if (TOLOWER (*l
) == FPU_ACTION_QUIET_CHAR
)
6086 insn
->fpu_action_flags
|= FPU_ACTION_QUIET
;
6090 if (TOLOWER (*l
) == FPU_ACTION_ZERO_CHAR
)
6092 insn
->fpu_action_flags
|= FPU_ACTION_ZERO
;
6096 if (! is_whitespace_char (*l
))
6098 l
= parse_split_condition (l
, insn
);
6102 as_bad (_("unknown floating point prefix character"));
6110 else if (TOLOWER (*l
) == DSP_PREFIX_CHAR
)
6112 if (strncasecmp (l
, DCACHE_INSN
, strlen (DCACHE_INSN
)) &&
6113 strncasecmp (l
, DEFR_INSN
, strlen (DEFR_INSN
)))
6116 insn
->type
= INSN_DSP
;
6120 insn
->dsp_width
= DSP_WIDTH_SINGLE
;
6122 while (!is_whitespace_char (*l
))
6124 /* We have to check for split condition codes first
6125 because they are the longest strings to match,
6126 e.g. if the string contains "LLS" we want it to match
6127 the split condition code "LLS", not the dual unit
6130 l
= parse_split_condition (l
, insn
);
6137 /* Accept an FPU prefix char which may be used when doing
6138 template MOV with FPU registers. */
6139 if (TOLOWER(*l
) == FPU_PREFIX_CHAR
)
6141 insn
->type
= INSN_DSP_FPU
;
6146 if (TOLOWER(*l
) == DSP_DUAL_CHAR
)
6148 insn
->dsp_width
= DSP_WIDTH_DUAL
;
6153 if (TOLOWER(*l
) == DSP_ACTION_QR64_CHAR
)
6155 insn
->dsp_action_flags
|= DSP_ACTION_QR64
;
6160 if (TOLOWER(*l
) == DSP_ACTION_UMUL_CHAR
)
6162 insn
->dsp_action_flags
|= DSP_ACTION_UMUL
;
6167 if (TOLOWER(*l
) == DSP_ACTION_ROUND_CHAR
)
6169 insn
->dsp_action_flags
|= DSP_ACTION_ROUND
;
6174 if (TOLOWER(*l
) == DSP_ACTION_CLAMP9_CHAR
)
6176 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP9
;
6181 if (TOLOWER(*l
) == DSP_ACTION_CLAMP8_CHAR
)
6183 insn
->dsp_action_flags
|= DSP_ACTION_CLAMP8
;
6188 if (TOLOWER(*l
) == DSP_ACTION_MOD_CHAR
)
6190 insn
->dsp_action_flags
|= DSP_ACTION_MOD
;
6195 if (TOLOWER(*l
) == DSP_ACTION_ACC_ZERO_CHAR
)
6197 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ZERO
;
6202 if (TOLOWER(*l
) == DSP_ACTION_ACC_ADD_CHAR
)
6204 insn
->dsp_action_flags
|= DSP_ACTION_ACC_ADD
;
6209 if (TOLOWER(*l
) == DSP_ACTION_ACC_SUB_CHAR
)
6211 insn
->dsp_action_flags
|= DSP_ACTION_ACC_SUB
;
6216 if (TOLOWER(*l
) == DSP_ACTION_OV_CHAR
)
6218 insn
->dsp_action_flags
|= DSP_ACTION_OV
;
6223 if (TOLOWER(*l
) == DSP_DAOPPAME_8_CHAR
)
6225 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_8
;
6230 if (TOLOWER(*l
) == DSP_DAOPPAME_16_CHAR
)
6232 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_16
;
6237 if (TOLOWER(*l
) == DSP_DAOPPAME_TEMP_CHAR
)
6239 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_TEMP
;
6244 if (TOLOWER(*l
) == DSP_DAOPPAME_HIGH_CHAR
)
6246 insn
->dsp_daoppame_flags
|= DSP_DAOPPAME_HIGH
;
6251 as_bad (_("unknown DSP prefix character %c %s"), *l
, l
);
6262 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6263 static insn_templates
*
6264 find_insn_templates (const char *mnemonic
)
6266 insn_template
template;
6267 insn_templates entry
;
6268 insn_templates
*slot
;
6270 entry
.template = &template;
6272 memcpy ((void *)&entry
.template->name
, &mnemonic
, sizeof (char *));
6274 slot
= (insn_templates
*) htab_find (mnemonic_htab
, &entry
);
6282 /* Make an uppercase copy of SRC into DST and return DST. */
6284 strupper (char * dst
, const char *src
)
6290 dst
[i
] = TOUPPER (src
[i
]);
6299 /* Calculate a hash value for a template. */
6301 hash_templates (const void *p
)
6303 insn_templates
*tp
= (insn_templates
*)p
;
6304 char buf
[MAX_MNEMONIC_LEN
];
6306 strupper (buf
, tp
->template->name
);
6308 return htab_hash_string (buf
);
6311 /* Check if two templates are equal. */
6313 eq_templates (const void *a
, const void *b
)
6315 insn_templates
*ta
= (insn_templates
*)a
;
6316 insn_templates
*tb
= (insn_templates
*)b
;
6317 return strcasecmp (ta
->template->name
, tb
->template->name
) == 0;
6320 /* Create the hash table required for parsing instructions. */
6322 create_mnemonic_htab (void)
6324 size_t i
, num_templates
= sizeof(metag_optab
)/sizeof(metag_optab
[0]);
6326 mnemonic_htab
= htab_create_alloc (num_templates
, hash_templates
,
6327 eq_templates
, NULL
, xcalloc
, free
);
6329 for (i
= 0; i
< num_templates
; i
++)
6331 const insn_template
*template = &metag_optab
[i
];
6332 insn_templates
**slot
= NULL
;
6333 insn_templates
*new_entry
;
6335 new_entry
= XNEW (insn_templates
);
6337 new_entry
->template = template;
6338 new_entry
->next
= NULL
;
6340 slot
= (insn_templates
**) htab_find_slot (mnemonic_htab
, new_entry
,
6345 insn_templates
*last_entry
= *slot
;
6347 while (last_entry
->next
)
6348 last_entry
= last_entry
->next
;
6350 last_entry
->next
= new_entry
;
6359 /* Calculate a hash value for a register. */
6361 hash_regs (const void *p
)
6363 metag_reg
*rp
= (metag_reg
*)p
;
6364 char buf
[MAX_REG_LEN
];
6366 strupper (buf
, rp
->name
);
6368 return htab_hash_string (buf
);
6371 /* Check if two registers are equal. */
6373 eq_regs (const void *a
, const void *b
)
6375 metag_reg
*ra
= (metag_reg
*)a
;
6376 metag_reg
*rb
= (metag_reg
*)b
;
6377 return strcasecmp (ra
->name
, rb
->name
) == 0;
6380 /* Create the hash table required for parsing registers. */
6382 create_reg_htab (void)
6384 size_t i
, num_regs
= sizeof(metag_regtab
)/sizeof(metag_regtab
[0]);
6386 reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6387 eq_regs
, NULL
, xcalloc
, free
);
6389 for (i
= 0; i
< num_regs
; i
++)
6391 const metag_reg
*reg
= &metag_regtab
[i
];
6392 const metag_reg
**slot
;
6394 slot
= (const metag_reg
**) htab_find_slot (reg_htab
, reg
, INSERT
);
6401 /* Create the hash table required for parsing DSP registers. */
6403 create_dspreg_htabs (void)
6405 size_t i
, num_regs
= sizeof(metag_dsp_regtab
)/sizeof(metag_dsp_regtab
[0]);
6408 dsp_reg_htab
= htab_create_alloc (num_regs
, hash_regs
,
6409 eq_regs
, NULL
, xcalloc
, free
);
6411 for (i
= 0; i
< num_regs
; i
++)
6413 const metag_reg
*reg
= &metag_dsp_regtab
[i
];
6414 const metag_reg
**slot
;
6416 slot
= (const metag_reg
**) htab_find_slot (dsp_reg_htab
, reg
, INSERT
);
6418 /* Make sure there are no hash table collisions, which would
6419 require chaining entries. */
6420 gas_assert (*slot
== NULL
);
6424 num_regs
= sizeof(metag_dsp_tmpl_regtab
[0])/sizeof(metag_dsp_tmpl_regtab
[0][0]);
6426 for (h
= 0; h
< 2; h
++)
6428 dsp_tmpl_reg_htab
[h
] = htab_create_alloc (num_regs
, hash_regs
,
6429 eq_regs
, NULL
, xcalloc
, free
);
6432 for (h
= 0; h
< 2; h
++)
6434 for (i
= 0; i
< num_regs
; i
++)
6436 const metag_reg
*reg
= &metag_dsp_tmpl_regtab
[h
][i
];
6437 const metag_reg
**slot
;
6438 slot
= (const metag_reg
**) htab_find_slot (dsp_tmpl_reg_htab
[h
],
6441 /* Make sure there are no hash table collisions, which would
6442 require chaining entries. */
6443 gas_assert (*slot
== NULL
);
6449 /* Calculate a hash value for a split condition code. */
6451 hash_scond (const void *p
)
6453 split_condition
*cp
= (split_condition
*)p
;
6456 strupper (buf
, cp
->name
);
6458 return htab_hash_string (buf
);
6461 /* Check if two split condition codes are equal. */
6463 eq_scond (const void *a
, const void *b
)
6465 split_condition
*ra
= (split_condition
*)a
;
6466 split_condition
*rb
= (split_condition
*)b
;
6468 return strcasecmp (ra
->name
, rb
->name
) == 0;
6471 /* Create the hash table required for parsing split condition codes. */
6473 create_scond_htab (void)
6477 nentries
= sizeof (metag_scondtab
) / sizeof (metag_scondtab
[0]);
6479 scond_htab
= htab_create_alloc (nentries
, hash_scond
, eq_scond
,
6480 NULL
, xcalloc
, free
);
6481 for (i
= 0; i
< nentries
; i
++)
6483 const split_condition
*scond
= &metag_scondtab
[i
];
6484 const split_condition
**slot
;
6486 slot
= (const split_condition
**) htab_find_slot (scond_htab
,
6488 /* Make sure there are no hash table collisions, which would
6489 require chaining entries. */
6490 gas_assert (*slot
== NULL
);
6495 /* Entry point for instruction parsing. */
6497 parse_insn (const char *line
, metag_insn
*insn
)
6499 char mnemonic
[MAX_MNEMONIC_LEN
];
6500 const char *l
= line
;
6501 size_t mnemonic_len
= 0;
6502 insn_templates
*templates
;
6506 while (is_mnemonic_char(*l
))
6512 if (mnemonic_len
>= MAX_MNEMONIC_LEN
)
6514 as_bad (_("instruction mnemonic too long: %s"), line
);
6518 strncpy(mnemonic
, line
, mnemonic_len
);
6520 mnemonic
[mnemonic_len
] = '\0';
6522 templates
= find_insn_templates (mnemonic
);
6526 insn_templates
*current_template
= templates
;
6530 while (current_template
)
6532 const insn_template
*template = current_template
->template;
6533 enum insn_encoding encoding
= template->encoding
;
6534 insn_parser parser
= insn_parsers
[encoding
];
6536 current_template
= current_template
->next
;
6538 if (template->insn_type
== INSN_GP
&&
6539 !(template->core_flags
& mcpu_opt
))
6542 if (template->insn_type
== INSN_FPU
&&
6543 !(template->core_flags
& mfpu_opt
))
6546 if (template->insn_type
== INSN_DSP
&&
6547 !(template->core_flags
& mdsp_opt
))
6550 if (template->insn_type
== INSN_DSP_FPU
&&
6551 !((template->core_flags
& mdsp_opt
) &&
6552 (template->core_flags
& mfpu_opt
)))
6555 /* DSP instructions always require special decoding */
6556 if ((insn
->type
== INSN_DSP
&& (template->insn_type
!= INSN_DSP
)) ||
6557 ((template->insn_type
== INSN_DSP
) && insn
->type
!= INSN_DSP
) ||
6558 (insn
->type
== INSN_DSP_FPU
&& (template->insn_type
!= INSN_DSP_FPU
)) ||
6559 ((template->insn_type
== INSN_DSP_FPU
) && insn
->type
!= INSN_DSP_FPU
))
6564 const char *end
= parser(l
, insn
, template);
6568 if (*end
!= END_OF_INSN
)
6569 as_bad (_("junk at end of line: \"%s\""), line
);
6576 as_bad (_("failed to assemble instruction: \"%s\""), line
);
6580 if (insn
->type
== INSN_FPU
)
6581 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic
);
6583 as_bad (_("unknown mnemonic: \"%s\""), mnemonic
);
6589 output_insn (metag_insn
*insn
)
6593 output
= frag_more (insn
->len
);
6594 dwarf2_emit_insn (insn
->len
);
6596 if (insn
->reloc_type
!= BFD_RELOC_UNUSED
)
6598 fix_new_exp (frag_now
, output
- frag_now
->fr_literal
,
6599 insn
->reloc_size
, &insn
->reloc_exp
,
6600 insn
->reloc_pcrel
, insn
->reloc_type
);
6603 md_number_to_chars (output
, insn
->bits
, insn
->len
);
6607 md_assemble (char *line
)
6609 const char *l
= line
;
6612 memset (&insn
, 0, sizeof(insn
));
6614 insn
.reloc_type
= BFD_RELOC_UNUSED
;
6615 insn
.reloc_pcrel
= 0;
6616 insn
.reloc_size
= 4;
6620 create_mnemonic_htab ();
6622 create_dspreg_htabs ();
6623 create_scond_htab ();
6626 l
= parse_prefix (l
, &insn
);
6631 if (insn
.type
== INSN_DSP
&&
6634 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6638 else if (insn
.type
== INSN_FPU
&&
6641 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6646 if (!parse_insn (l
, &insn
))
6649 output_insn (&insn
);
6653 md_operand (expressionS
* expressionP
)
6655 if (* input_line_pointer
== IMM_CHAR
)
6657 input_line_pointer
++;
6658 expression (expressionP
);
6663 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
6669 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6674 /* Functions concerning relocs. */
6676 /* The location from which a PC relative jump should be calculated,
6677 given a PC relative reloc. */
6680 md_pcrel_from_section (fixS
* fixP
, segT sec
)
6682 if ((fixP
->fx_addsy
!= (symbolS
*) NULL
6683 && (! S_IS_DEFINED (fixP
->fx_addsy
)
6684 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
6685 || metag_force_relocation (fixP
))
6687 /* The symbol is undefined (or is defined but not in this section).
6688 Let the linker figure it out. */
6692 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6695 /* Write a value out to the object file, using the appropriate endianness. */
6698 md_number_to_chars (char * buf
, valueT val
, int n
)
6700 number_to_chars_littleendian (buf
, val
, n
);
6703 /* Turn a string in input_line_pointer into a floating point constant of type
6704 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6705 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6709 md_atof (int type
, char * litP
, int * sizeP
)
6713 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6732 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6736 return _("Bad call to md_atof()");
6739 t
= atof_ieee (input_line_pointer
, type
, words
);
6741 input_line_pointer
= t
;
6742 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
6744 for (i
= 0; i
< prec
; i
++)
6746 md_number_to_chars (litP
, (valueT
) words
[i
],
6747 sizeof (LITTLENUM_TYPE
));
6748 litP
+= sizeof (LITTLENUM_TYPE
);
6754 /* If this function returns non-zero, it prevents the relocation
6755 against symbol(s) in the FIXP from being replaced with relocations
6756 against section symbols, and guarantees that a relocation will be
6757 emitted even when the value can be resolved locally. */
6760 metag_force_relocation (fixS
* fix
)
6762 switch (fix
->fx_r_type
)
6764 case BFD_RELOC_METAG_RELBRANCH_PLT
:
6765 case BFD_RELOC_METAG_TLS_LE
:
6766 case BFD_RELOC_METAG_TLS_IE
:
6767 case BFD_RELOC_METAG_TLS_LDO
:
6768 case BFD_RELOC_METAG_TLS_LDM
:
6769 case BFD_RELOC_METAG_TLS_GD
:
6775 return generic_force_reloc (fix
);
6779 metag_fix_adjustable (fixS
* fixP
)
6781 if (fixP
->fx_addsy
== NULL
)
6784 /* Prevent all adjustments to global symbols. */
6785 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
6787 if (S_IS_WEAK (fixP
->fx_addsy
))
6790 if (fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTOFF
||
6791 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTOFF
||
6792 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOTOFF
||
6793 fixP
->fx_r_type
== BFD_RELOC_METAG_GETSET_GOT
||
6794 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_GOTPC
||
6795 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_GOTPC
||
6796 fixP
->fx_r_type
== BFD_RELOC_METAG_HI16_PLT
||
6797 fixP
->fx_r_type
== BFD_RELOC_METAG_LO16_PLT
||
6798 fixP
->fx_r_type
== BFD_RELOC_METAG_RELBRANCH_PLT
)
6801 /* We need the symbol name for the VTABLE entries. */
6802 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6803 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6809 /* Return an initial guess of the length by which a fragment must grow to
6810 hold a branch to reach its destination.
6811 Also updates fr_type/fr_subtype as necessary.
6813 Called just before doing relaxation.
6814 Any symbol that is now undefined will not become defined.
6815 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6816 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6817 Although it may not be explicit in the frag, pretend fr_var starts with a
6821 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
6822 segT segment ATTRIBUTE_UNUSED
)
6824 /* No assembler relaxation is defined (or necessary) for this port. */
6828 /* *fragP has been relaxed to its final size, and now needs to have
6829 the bytes inside it modified to conform to the new size.
6831 Called after relaxation is finished.
6832 fragP->fr_type == rs_machine_dependent.
6833 fragP->fr_subtype is the subtype of what the address relaxed to. */
6836 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
,
6837 fragS
* fragP ATTRIBUTE_UNUSED
)
6839 /* No assembler relaxation is defined (or necessary) for this port. */
6843 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6846 metag_handle_align (fragS
* fragP
)
6848 static unsigned char const noop
[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6852 if (fragP
->fr_type
!= rs_align_code
)
6855 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
6856 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
6869 memcpy (p
, noop
, 4);
6875 fragP
->fr_fix
+= fix
;
6880 metag_end_of_match (char * cont
, const char * what
)
6882 int len
= strlen (what
);
6884 if (strncasecmp (cont
, what
, strlen (what
)) == 0
6885 && ! is_part_of_name (cont
[len
]))
6892 metag_parse_name (char const * name
, expressionS
* exprP
, enum expr_mode mode
,
6895 char *next
= input_line_pointer
;
6901 exprP
->X_op_symbol
= NULL
;
6902 exprP
->X_md
= BFD_RELOC_UNUSED
;
6904 if (strcmp (name
, GOT_NAME
) == 0)
6907 GOT_symbol
= symbol_find_or_make (name
);
6909 exprP
->X_add_symbol
= GOT_symbol
;
6911 /* If we have an absolute symbol or a
6912 reg, then we know its value now. */
6913 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
6914 if (mode
!= expr_defer
&& segment
== absolute_section
)
6916 exprP
->X_op
= O_constant
;
6917 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6918 exprP
->X_add_symbol
= NULL
;
6920 else if (mode
!= expr_defer
&& segment
== reg_section
)
6922 exprP
->X_op
= O_register
;
6923 exprP
->X_add_number
= S_GET_VALUE (exprP
->X_add_symbol
);
6924 exprP
->X_add_symbol
= NULL
;
6928 exprP
->X_op
= O_symbol
;
6929 exprP
->X_add_number
= 0;
6935 exprP
->X_add_symbol
= symbol_find_or_make (name
);
6937 if (*nextcharP
!= '@')
6939 else if ((next_end
= metag_end_of_match (next
+ 1, "GOTOFF")))
6941 reloc_type
= BFD_RELOC_METAG_GOTOFF
;
6942 op_type
= O_PIC_reloc
;
6944 else if ((next_end
= metag_end_of_match (next
+ 1, "GOT")))
6946 reloc_type
= BFD_RELOC_METAG_GETSET_GOT
;
6947 op_type
= O_PIC_reloc
;
6949 else if ((next_end
= metag_end_of_match (next
+ 1, "PLT")))
6951 reloc_type
= BFD_RELOC_METAG_PLT
;
6952 op_type
= O_PIC_reloc
;
6954 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSGD")))
6956 reloc_type
= BFD_RELOC_METAG_TLS_GD
;
6957 op_type
= O_PIC_reloc
;
6959 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDM")))
6961 reloc_type
= BFD_RELOC_METAG_TLS_LDM
;
6962 op_type
= O_PIC_reloc
;
6964 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLDO")))
6966 reloc_type
= BFD_RELOC_METAG_TLS_LDO
;
6967 op_type
= O_PIC_reloc
;
6969 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIE")))
6971 reloc_type
= BFD_RELOC_METAG_TLS_IE
;
6972 op_type
= O_PIC_reloc
;
6974 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSIENONPIC")))
6976 reloc_type
= BFD_RELOC_METAG_TLS_IENONPIC
;
6977 op_type
= O_PIC_reloc
; /* FIXME: is this correct? */
6979 else if ((next_end
= metag_end_of_match (next
+ 1, "TLSLE")))
6981 reloc_type
= BFD_RELOC_METAG_TLS_LE
;
6982 op_type
= O_PIC_reloc
;
6987 *input_line_pointer
= *nextcharP
;
6988 input_line_pointer
= next_end
;
6989 *nextcharP
= *input_line_pointer
;
6990 *input_line_pointer
= '\0';
6992 exprP
->X_op
= op_type
;
6993 exprP
->X_add_number
= 0;
6994 exprP
->X_md
= reloc_type
;
6999 /* If while processing a fixup, a reloc really needs to be created
7000 then it is done here. */
7003 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
7007 reloc
= XNEW (arelent
);
7008 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7009 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7010 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7012 reloc
->addend
= fixp
->fx_offset
;
7013 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
7015 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
7017 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7018 /* xgettext:c-format. */
7019 _("reloc %d not supported by object file format"),
7020 (int) fixp
->fx_r_type
);
7031 md_chars_to_number (char *val
, int n
)
7034 unsigned char * where
= (unsigned char *) val
;
7036 for (retval
= 0; n
--;)
7045 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7047 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7048 int value
= (int)*valP
;
7050 switch (fixP
->fx_r_type
)
7052 case BFD_RELOC_METAG_TLS_GD
:
7053 case BFD_RELOC_METAG_TLS_LE_HI16
:
7054 case BFD_RELOC_METAG_TLS_LE_LO16
:
7055 case BFD_RELOC_METAG_TLS_IE
:
7056 case BFD_RELOC_METAG_TLS_IENONPIC_HI16
:
7057 case BFD_RELOC_METAG_TLS_IENONPIC_LO16
:
7058 case BFD_RELOC_METAG_TLS_LDM
:
7059 case BFD_RELOC_METAG_TLS_LDO_HI16
:
7060 case BFD_RELOC_METAG_TLS_LDO_LO16
:
7061 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7064 case BFD_RELOC_METAG_HIADDR16
:
7065 case BFD_RELOC_METAG_LOADDR16
:
7066 case BFD_RELOC_VTABLE_INHERIT
:
7067 case BFD_RELOC_VTABLE_ENTRY
:
7068 fixP
->fx_done
= FALSE
;
7071 case BFD_RELOC_METAG_REL8
:
7072 if (!within_unsigned_range (value
, IMM8_BITS
))
7074 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7075 "rel8 out of range %d", value
);
7079 unsigned int newval
;
7080 newval
= md_chars_to_number (buf
, 4);
7081 newval
= (newval
& 0xffffc03f) | ((value
& IMM8_MASK
) << 6);
7082 md_number_to_chars (buf
, newval
, 4);
7085 case BFD_RELOC_METAG_REL16
:
7086 if (!within_unsigned_range (value
, IMM16_BITS
))
7088 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7089 "rel16 out of range %d", value
);
7093 unsigned int newval
;
7094 newval
= md_chars_to_number (buf
, 4);
7095 newval
= (newval
& 0xfff80007) | ((value
& IMM16_MASK
) << 3);
7096 md_number_to_chars (buf
, newval
, 4);
7101 md_number_to_chars (buf
, value
, 1);
7104 md_number_to_chars (buf
, value
, 2);
7107 md_number_to_chars (buf
, value
, 4);
7110 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
;