1 /* tc-mep.c -- Assembler for the Toshiba Media Processor.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
23 #include "dwarf2dbg.h"
26 #include "opcodes/mep-desc.h"
27 #include "opcodes/mep-opc.h"
29 #include "elf/common.h"
34 /* Structure to hold all of the different components describing
35 an individual instruction. */
38 const CGEN_INSN
* insn
;
39 const CGEN_INSN
* orig_insn
;
42 CGEN_INSN_INT buffer
[1];
43 #define INSN_VALUE(buf) (*(buf))
45 unsigned char buffer
[CGEN_MAX_INSN_SIZE
];
46 #define INSN_VALUE(buf) (buf)
51 fixS
* fixups
[GAS_CGEN_MAX_FIXUPS
];
52 int indices
[MAX_OPERAND_INSTANCES
];
55 static int mode
= CORE
; /* Start in core mode. */
56 static int pluspresent
= 0;
57 static int allow_disabled_registers
= 0;
58 static int library_flag
= 0;
60 /* We're going to need to store all of the instructions along with
61 their fixups so that we can parallelization grouping rules. */
63 static mep_insn saved_insns
[MAX_SAVED_FIXUP_CHAINS
];
64 static int num_insns_saved
= 0;
66 const char comment_chars
[] = "#";
67 const char line_comment_chars
[] = ";#";
68 const char line_separator_chars
[] = ";";
69 const char EXP_CHARS
[] = "eE";
70 const char FLT_CHARS
[] = "dD";
72 static void mep_switch_to_vliw_mode (int);
73 static void mep_switch_to_core_mode (int);
74 static void mep_s_vtext (int);
75 static void mep_noregerr (int);
77 /* The target specific pseudo-ops which we support. */
78 const pseudo_typeS md_pseudo_table
[] =
81 { "file", (void (*) (int)) dwarf2_directive_file
, 0 },
82 { "loc", dwarf2_directive_loc
, 0 },
83 { "vliw", mep_switch_to_vliw_mode
, 0 },
84 { "core", mep_switch_to_core_mode
, 0 },
85 { "vtext", mep_s_vtext
, 0 },
86 { "noregerr", mep_noregerr
, 0 },
90 /* Relocations against symbols are done in two
91 parts, with a HI relocation and a LO relocation. Each relocation
92 has only 16 bits of space to store an addend. This means that in
93 order for the linker to handle carries correctly, it must be able
94 to locate both the HI and the LO relocation. This means that the
95 relocations must appear in order in the relocation table.
97 In order to implement this, we keep track of each unmatched HI
98 relocation. We then sort them so that they immediately precede the
99 corresponding LO relocation. */
103 struct mep_hi_fixup
* next
; /* Next HI fixup. */
104 fixS
* fixp
; /* This fixup. */
105 segT seg
; /* The section this fixup is in. */
108 /* The list of unmatched HI relocs. */
109 static struct mep_hi_fixup
* mep_hi_fixup_list
;
112 #define OPTION_EB (OPTION_MD_BASE + 0)
113 #define OPTION_EL (OPTION_MD_BASE + 1)
114 #define OPTION_CONFIG (OPTION_MD_BASE + 2)
115 #define OPTION_AVERAGE (OPTION_MD_BASE + 3)
116 #define OPTION_NOAVERAGE (OPTION_MD_BASE + 4)
117 #define OPTION_MULT (OPTION_MD_BASE + 5)
118 #define OPTION_NOMULT (OPTION_MD_BASE + 6)
119 #define OPTION_DIV (OPTION_MD_BASE + 7)
120 #define OPTION_NODIV (OPTION_MD_BASE + 8)
121 #define OPTION_BITOPS (OPTION_MD_BASE + 9)
122 #define OPTION_NOBITOPS (OPTION_MD_BASE + 10)
123 #define OPTION_LEADZ (OPTION_MD_BASE + 11)
124 #define OPTION_NOLEADZ (OPTION_MD_BASE + 12)
125 #define OPTION_ABSDIFF (OPTION_MD_BASE + 13)
126 #define OPTION_NOABSDIFF (OPTION_MD_BASE + 14)
127 #define OPTION_MINMAX (OPTION_MD_BASE + 15)
128 #define OPTION_NOMINMAX (OPTION_MD_BASE + 16)
129 #define OPTION_CLIP (OPTION_MD_BASE + 17)
130 #define OPTION_NOCLIP (OPTION_MD_BASE + 18)
131 #define OPTION_SATUR (OPTION_MD_BASE + 19)
132 #define OPTION_NOSATUR (OPTION_MD_BASE + 20)
133 #define OPTION_COP32 (OPTION_MD_BASE + 21)
134 #define OPTION_REPEAT (OPTION_MD_BASE + 25)
135 #define OPTION_NOREPEAT (OPTION_MD_BASE + 26)
136 #define OPTION_DEBUG (OPTION_MD_BASE + 27)
137 #define OPTION_NODEBUG (OPTION_MD_BASE + 28)
138 #define OPTION_LIBRARY (OPTION_MD_BASE + 29)
140 struct option md_longopts
[] = {
141 { "EB", no_argument
, NULL
, OPTION_EB
},
142 { "EL", no_argument
, NULL
, OPTION_EL
},
143 { "mconfig", required_argument
, NULL
, OPTION_CONFIG
},
144 { "maverage", no_argument
, NULL
, OPTION_AVERAGE
},
145 { "mno-average", no_argument
, NULL
, OPTION_NOAVERAGE
},
146 { "mmult", no_argument
, NULL
, OPTION_MULT
},
147 { "mno-mult", no_argument
, NULL
, OPTION_NOMULT
},
148 { "mdiv", no_argument
, NULL
, OPTION_DIV
},
149 { "mno-div", no_argument
, NULL
, OPTION_NODIV
},
150 { "mbitops", no_argument
, NULL
, OPTION_BITOPS
},
151 { "mno-bitops", no_argument
, NULL
, OPTION_NOBITOPS
},
152 { "mleadz", no_argument
, NULL
, OPTION_LEADZ
},
153 { "mno-leadz", no_argument
, NULL
, OPTION_NOLEADZ
},
154 { "mabsdiff", no_argument
, NULL
, OPTION_ABSDIFF
},
155 { "mno-absdiff", no_argument
, NULL
, OPTION_NOABSDIFF
},
156 { "mminmax", no_argument
, NULL
, OPTION_MINMAX
},
157 { "mno-minmax", no_argument
, NULL
, OPTION_NOMINMAX
},
158 { "mclip", no_argument
, NULL
, OPTION_CLIP
},
159 { "mno-clip", no_argument
, NULL
, OPTION_NOCLIP
},
160 { "msatur", no_argument
, NULL
, OPTION_SATUR
},
161 { "mno-satur", no_argument
, NULL
, OPTION_NOSATUR
},
162 { "mcop32", no_argument
, NULL
, OPTION_COP32
},
163 { "mdebug", no_argument
, NULL
, OPTION_DEBUG
},
164 { "mno-debug", no_argument
, NULL
, OPTION_NODEBUG
},
165 { "mlibrary", no_argument
, NULL
, OPTION_LIBRARY
},
166 { NULL
, 0, NULL
, 0 } };
167 size_t md_longopts_size
= sizeof (md_longopts
);
169 const char * md_shortopts
= "";
170 static int optbits
= 0;
171 static int optbitset
= 0;
174 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
180 target_big_endian
= 1;
183 target_big_endian
= 0;
187 for (i
=1; mep_config_map
[i
].name
; i
++)
188 if (strcmp (mep_config_map
[i
].name
, arg
) == 0)
195 fprintf (stderr
, "Error: unknown configuration %s\n", arg
);
198 mep_config_index
= idx
;
199 target_big_endian
= mep_config_map
[idx
].big_endian
;
202 optbits
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
203 optbitset
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
205 case OPTION_NOAVERAGE
:
206 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_AVE_INSN
);
207 optbitset
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
210 optbits
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
211 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
214 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_MUL_INSN
);
215 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
218 optbits
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
219 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
222 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_DIV_INSN
);
223 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
226 optbits
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
227 optbitset
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
229 case OPTION_NOBITOPS
:
230 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_BIT_INSN
);
231 optbitset
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
234 optbits
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
235 optbitset
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
238 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_LDZ_INSN
);
239 optbitset
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
242 optbits
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
243 optbitset
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
245 case OPTION_NOABSDIFF
:
246 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_ABS_INSN
);
247 optbitset
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
250 optbits
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
251 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
253 case OPTION_NOMINMAX
:
254 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
);
255 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
258 optbits
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
259 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
262 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_CLIP_INSN
);
263 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
266 optbits
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
267 optbitset
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
270 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_SAT_INSN
);
271 optbitset
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
274 optbits
|= 1 << CGEN_INSN_OPTIONAL_CP_INSN
;
275 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CP_INSN
;
278 optbits
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
279 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
282 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
);
283 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
286 library_flag
= EF_MEP_LIBRARY
;
289 case OPTION_NOREPEAT
:
298 md_show_usage (FILE *stream
)
300 fprintf (stream
, _("MeP specific command line options:\n\
301 -EB assemble for a big endian system (default)\n\
302 -EL assemble for a little endian system\n\
303 -mconfig=<name> specify a chip configuration to use\n\
304 -maverage -mno-average -mmult -mno-mult -mdiv -mno-div\n\
305 -mbitops -mno-bitops -mleadz -mno-leadz -mabsdiff -mno-absdiff\n\
306 -mminmax -mno-minmax -mclip -mno-clip -msatur -mno-satur -mcop32\n\
307 enable/disable the given opcodes\n\
309 If -mconfig is given, the other -m options modify it. Otherwise,\n\
310 if no -m options are given, all core opcodes are enabled;\n\
311 if any enabling -m options are given, only those are enabled;\n\
312 if only disabling -m options are given, only those are disabled.\n\
314 if (mep_config_map
[1].name
)
317 fprintf (stream
, " -mconfig=STR specify the configuration to use\n");
318 fprintf (stream
, " Configurations:");
319 for (i
=0; mep_config_map
[i
].name
; i
++)
320 fprintf (stream
, " %s", mep_config_map
[i
].name
);
321 fprintf (stream
, "\n");
328 mep_check_for_disabled_registers (mep_insn
*insn
)
330 static int initted
= 0;
331 static int has_mul_div
= 0;
332 static int has_cop
= 0;
333 static int has_debug
= 0;
336 if (allow_disabled_registers
)
340 if (target_big_endian
)
341 b
= insn
->buffer
[0] * 256 + insn
->buffer
[1];
343 b
= insn
->buffer
[1] * 256 + insn
->buffer
[0];
348 if ((b
& 0xfffff00e) == 0x7008 /* stc */
349 || (b
& 0xfffff00e) == 0x700a /* ldc */)
354 if ((MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_MUL_INSN
))
355 || (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_DIV_INSN
)))
357 if (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
))
359 if (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_CP_INSN
))
363 r
= ((b
& 0x00f0) >> 4) | ((b
& 0x0001) << 4);
369 as_bad ("$hi and $lo are disabled when MUL and DIV are off");
376 as_bad ("$mb0, $me0, $mb1, and $me1 are disabled when COP is off");
381 as_bad ("$dbg and $depc are disabled when DEBUG is off");
393 case EF_MEP_CPU_C2
: return bfd_mach_mep
;
394 case EF_MEP_CPU_C3
: return bfd_mach_mep
;
395 case EF_MEP_CPU_C4
: return bfd_mach_mep
;
396 case EF_MEP_CPU_H1
: return bfd_mach_mep_h1
;
402 /* The MeP version of the cgen parse_operand function. The only difference
403 from the standard version is that we want to avoid treating '$foo' and
404 '($foo...)' as references to a symbol called '$foo'. The chances are
405 that '$foo' is really a misspelt register. */
408 mep_parse_operand (CGEN_CPU_DESC cd
, enum cgen_parse_operand_type want
,
409 const char **strP
, int opindex
, int opinfo
,
410 enum cgen_parse_operand_result
*resultP
, bfd_vma
*valueP
)
412 if (want
== CGEN_PARSE_OPERAND_INTEGER
|| want
== CGEN_PARSE_OPERAND_ADDRESS
)
420 return "Not a valid literal";
422 return gas_cgen_parse_operand (cd
, want
, strP
, opindex
, opinfo
,
429 /* Initialize the `cgen' interface. */
431 /* If the user specifies no options, we default to allowing
432 everything. If the user specifies any enabling options, we
433 default to allowing only what is specified. If the user
434 specifies only disabling options, we only disable what is
435 specified. If the user specifies options and a config, the
436 options modify the config. */
437 if (optbits
&& mep_config_index
== 0)
440 MEP_OMASK
= (MEP_OMASK
& ~optbitset
) | optbits
;
442 /* Set the machine number and endian. */
443 gas_cgen_cpu_desc
= mep_cgen_cpu_open (CGEN_CPU_OPEN_MACHS
, 0,
444 CGEN_CPU_OPEN_ENDIAN
,
447 : CGEN_ENDIAN_LITTLE
,
448 CGEN_CPU_OPEN_ISAS
, 0,
450 mep_cgen_init_asm (gas_cgen_cpu_desc
);
452 /* This is a callback from cgen to gas to parse operands. */
453 cgen_set_parse_operand_fn (gas_cgen_cpu_desc
, mep_parse_operand
);
455 /* Identify the architecture. */
456 bfd_default_set_arch_mach (stdoutput
, bfd_arch_mep
, mep_machine ());
458 /* Store the configuration number and core. */
459 bfd_set_private_flags (stdoutput
, MEP_CPU
| MEP_CONFIG
| library_flag
);
461 /* Initialize the array we'll be using to store fixups. */
462 gas_cgen_initialize_saved_fixups_array();
465 /* Variant of mep_cgen_assemble_insn. Assemble insn STR of cpu CD as a
466 coprocessor instruction, if possible, into FIELDS, BUF, and INSN. */
468 static const CGEN_INSN
*
469 mep_cgen_assemble_cop_insn (CGEN_CPU_DESC cd
,
472 CGEN_INSN_BYTES_PTR buf
,
473 const struct cgen_insn
*pinsn
)
476 CGEN_INSN_LIST
*ilist
;
477 const char *errmsg
= NULL
;
479 /* The instructions are stored in hashed lists. */
480 ilist
= CGEN_ASM_LOOKUP_INSN (gas_cgen_cpu_desc
,
481 CGEN_INSN_MNEMONIC (pinsn
));
484 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
486 const CGEN_INSN
*insn
= ilist
->insn
;
487 if (strcmp (CGEN_INSN_MNEMONIC (ilist
->insn
),
488 CGEN_INSN_MNEMONIC (pinsn
)) == 0
489 && MEP_INSN_COP_P (ilist
->insn
)
490 && mep_cgen_insn_supported (cd
, insn
))
494 /* skip this insn if str doesn't look right lexically */
495 if (CGEN_INSN_RX (insn
) != NULL
&&
496 regexec ((regex_t
*) CGEN_INSN_RX (insn
), str
, 0, NULL
, 0) == REG_NOMATCH
)
499 /* Allow parse/insert handlers to obtain length of insn. */
500 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
502 errmsg
= CGEN_PARSE_FN (cd
, insn
) (cd
, insn
, & str
, fields
);
506 errmsg
= CGEN_INSERT_FN (cd
, insn
) (cd
, insn
, fields
, buf
,
518 mep_save_insn (mep_insn insn
)
520 /* Consider change MAX_SAVED_FIXUP_CHAINS to MAX_PARALLEL_INSNS. */
521 if (num_insns_saved
< 0 || num_insns_saved
>= MAX_SAVED_FIXUP_CHAINS
)
523 as_fatal("index into saved_insns[] out of bounds.");
526 saved_insns
[num_insns_saved
] = insn
;
527 gas_cgen_save_fixups(num_insns_saved
);
532 mep_check_parallel32_scheduling (void)
534 int insn0iscopro
, insn1iscopro
, insn0length
, insn1length
;
536 /* More than two instructions means that either someone is referring to
537 an internally parallel core or an internally parallel coprocessor,
538 neither of which are supported at this time. */
539 if ( num_insns_saved
> 2 )
540 as_fatal("Internally paralled cores and coprocessors not supported.");
542 /* If there are no insns saved, that's ok. Just return. This will
543 happen when mep_process_saved_insns is called when the end of the
544 source file is reached and there are no insns left to be processed. */
545 if (num_insns_saved
== 0)
548 /* Check some of the attributes of the first insn. */
549 insn0iscopro
= MEP_INSN_COP_P (saved_insns
[0].insn
);
550 insn0length
= CGEN_FIELDS_BITSIZE (& saved_insns
[0].fields
);
552 if (num_insns_saved
== 2)
554 /* Check some of the attributes of the first insn. */
555 insn1iscopro
= MEP_INSN_COP_P (saved_insns
[1].insn
);
556 insn1length
= CGEN_FIELDS_BITSIZE (& saved_insns
[1].fields
);
558 if ((insn0iscopro
&& !insn1iscopro
)
559 || (insn1iscopro
&& !insn0iscopro
))
561 /* We have one core and one copro insn. If their sizes
562 add up to 32, then the combination is valid. */
563 if (insn0length
+ insn1length
== 32)
566 as_bad ("core and copro insn lengths must total 32 bits.");
569 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
573 /* If we arrive here, we have one saved instruction. There are a
574 number of possible cases:
576 1. The instruction is a 32 bit core or coprocessor insn and
577 can be executed by itself. Valid.
579 2. The instrucion is a core instruction for which a cop nop
580 exists. In this case, insert the cop nop into the saved
581 insn array after the core insn and return. Valid.
583 3. The instruction is a coprocessor insn for which a core nop
584 exists. In this case, move the coprocessor insn to the
585 second element of the array and put the nop in the first
586 element then return. Valid.
588 4. The instruction is a core or coprocessor instruction for
589 which there is no matching coprocessor or core nop to use
590 to form a valid vliw insn combination. In this case, we
593 if (insn0length
> 32)
594 as_fatal ("Cannot use 48- or 64-bit insns with a 32 bit datapath.");
596 if (insn0length
== 32)
599 /* Insn is smaller than datapath. If there are no matching
600 nops for this insn, then terminate assembly. */
601 if (CGEN_INSN_ATTR_VALUE (saved_insns
[0].insn
,
602 CGEN_INSN_VLIW32_NO_MATCHING_NOP
))
603 as_fatal ("No valid nop.");
605 /* At this point we know that we have a single 16-bit insn that has
606 a matching nop. We have to assemble it and put it into the saved
607 insn and fixup chain arrays. */
614 /* Move the insn and it's fixups to the second element of the
615 saved insns arrary and insert a 16 bit core nope into the
617 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "nop",
618 &insn
.fields
, insn
.buffer
,
622 as_bad ("%s", errmsg
);
626 /* Move the insn in element 0 to element 1 and insert the
627 nop into element 0. Move the fixups in element 0 to
628 element 1 and save the current fixups to element 0.
629 Really there aren't any fixups at this point because we're
630 inserting a nop but we might as well be general so that
631 if there's ever a need to insert a general insn, we'll
633 saved_insns
[1] = saved_insns
[0];
634 saved_insns
[0] = insn
;
636 gas_cgen_swap_fixups (0);
637 gas_cgen_save_fixups (1);
643 int insn_num
= saved_insns
[0].insn
->base
->num
;
645 /* Use 32 bit branches and skip the nop. */
646 if (insn_num
== MEP_INSN_BSR12
647 || insn_num
== MEP_INSN_BEQZ
648 || insn_num
== MEP_INSN_BNEZ
)
651 /* Insert a 16-bit coprocessor nop. Note that at the time */
652 /* this was done, no 16-bit coprocessor nop was defined. */
653 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop16",
654 &insn
.fields
, insn
.buffer
,
658 as_bad ("%s", errmsg
);
662 /* Now put the insn and fixups into the arrays. */
663 mep_save_insn (insn
);
669 mep_check_parallel64_scheduling (void)
671 int insn0iscopro
, insn1iscopro
, insn0length
, insn1length
;
673 /* More than two instructions means that someone is referring to an
674 internally parallel core or an internally parallel coprocessor. */
675 /* These are not currently supported. */
676 if (num_insns_saved
> 2)
677 as_fatal ("Internally parallel cores of coprocessors not supported.");
679 /* If there are no insns saved, that's ok. Just return. This will
680 happen when mep_process_saved_insns is called when the end of the
681 source file is reached and there are no insns left to be processed. */
682 if (num_insns_saved
== 0)
685 /* Check some of the attributes of the first insn. */
686 insn0iscopro
= MEP_INSN_COP_P (saved_insns
[0].insn
);
687 insn0length
= CGEN_FIELDS_BITSIZE (& saved_insns
[0].fields
);
689 if (num_insns_saved
== 2)
691 /* Check some of the attributes of the first insn. */
692 insn1iscopro
= MEP_INSN_COP_P (saved_insns
[1].insn
);
693 insn1length
= CGEN_FIELDS_BITSIZE (& saved_insns
[1].fields
);
695 if ((insn0iscopro
&& !insn1iscopro
)
696 || (insn1iscopro
&& !insn0iscopro
))
698 /* We have one core and one copro insn. If their sizes
699 add up to 64, then the combination is valid. */
700 if (insn0length
+ insn1length
== 64)
703 as_bad ("core and copro insn lengths must total 64 bits.");
706 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
710 /* If we arrive here, we have one saved instruction. There are a
711 number of possible cases:
713 1. The instruction is a 64 bit coprocessor insn and can be
714 executed by itself. Valid.
716 2. The instrucion is a core instruction for which a cop nop
717 exists. In this case, insert the cop nop into the saved
718 insn array after the core insn and return. Valid.
720 3. The instruction is a coprocessor insn for which a core nop
721 exists. In this case, move the coprocessor insn to the
722 second element of the array and put the nop in the first
723 element then return. Valid.
725 4. The instruction is a core or coprocessor instruction for
726 which there is no matching coprocessor or core nop to use
727 to form a valid vliw insn combination. In this case, we
730 /* If the insn is 64 bits long, it can run alone. The size check
731 is done indepependantly of whether the insn is core or copro
732 in case 64 bit coprocessor insns are added later. */
733 if (insn0length
== 64)
736 /* Insn is smaller than datapath. If there are no matching
737 nops for this insn, then terminate assembly. */
738 if (CGEN_INSN_ATTR_VALUE (saved_insns
[0].insn
,
739 CGEN_INSN_VLIW64_NO_MATCHING_NOP
))
740 as_fatal ("No valid nop.");
748 /* Initialize the insn buffer. */
749 for (i
= 0; i
< 64; i
++)
750 insn
.buffer
[i
] = '\0';
752 /* We have a coprocessor insn. At this point in time there
753 are is 32-bit core nop. There is only a 16-bit core
754 nop. The idea is to allow for a relatively arbitrary
755 coprocessor to be specified. We aren't looking at
756 trying to cover future changes in the core at this time
757 since it is assumed that the core will remain fairly
758 static. If there ever are 32 or 48 bit core nops added,
759 they will require entries below. */
761 if (insn0length
== 48)
763 /* Move the insn and fixups to the second element of the
764 arrays then assemble and insert a 16 bit core nop. */
765 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "nop",
766 & insn
.fields
, insn
.buffer
,
771 /* If this is reached, then we have a single coprocessor
772 insn that is not 48 bits long, but for which the assembler
773 thinks there is a matching core nop. If a 32-bit core
774 nop has been added, then make the necessary changes and
775 handle its assembly and insertion here. Otherwise,
776 go figure out why either:
778 1. The assembler thinks that there is a 32-bit core nop
779 to match a 32-bit coprocessor insn, or
780 2. The assembler thinks that there is a 48-bit core nop
781 to match a 16-bit coprocessor insn. */
783 as_fatal ("Assembler expects a non-existent core nop.");
788 as_bad ("%s", errmsg
);
792 /* Move the insn in element 0 to element 1 and insert the
793 nop into element 0. Move the fixups in element 0 to
794 element 1 and save the current fixups to element 0.
795 Really there aren't any fixups at this point because we're
796 inserting a nop but we might as well be general so that
797 if there's ever a need to insert a general insn, we'll
800 saved_insns
[1] = saved_insns
[0];
801 saved_insns
[0] = insn
;
803 gas_cgen_swap_fixups(0);
804 gas_cgen_save_fixups(1);
813 /* Initialize the insn buffer */
814 for (i
= 0; i
< 64; i
++)
815 insn
.buffer
[i
] = '\0';
817 /* We have a core insn. We have to handle all possible nop
818 lengths. If a coprocessor doesn't have a nop of a certain
819 length but there exists core insns that when combined with
820 a nop of that length would fill the datapath, those core
821 insns will be flagged with the VLIW_NO_CORRESPONDING_NOP
822 attribute. That will ensure that when used in a way that
823 requires a nop to be inserted, assembly will terminate
824 before reaching this section of code. This guarantees
825 that cases below which would result in the attempted
826 insertion of nop that doesn't exist will never be entered. */
827 if (insn0length
== 16)
829 /* Insert 48 bit coprocessor nop. */
830 /* Assemble it and put it into the arrays. */
831 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop48",
832 &insn
.fields
, insn
.buffer
,
835 else if (insn0length
== 32)
837 /* Insert 32 bit coprocessor nop. */
838 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop32",
839 &insn
.fields
, insn
.buffer
,
842 else if (insn0length
== 48)
844 /* Insert 16 bit coprocessor nop. */
845 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop16",
846 &insn
.fields
, insn
.buffer
,
850 /* Core insn has an invalid length. Something has gone wrong. */
851 as_fatal ("Core insn has invalid length! Something is wrong!");
855 as_bad ("%s", errmsg
);
859 /* Now put the insn and fixups into the arrays. */
860 mep_save_insn (insn
);
865 /* The scheduling functions are just filters for invalid combinations.
866 If there is a violation, they terminate assembly. Otherise they
867 just fall through. Succesful combinations cause no side effects
868 other than valid nop insertion. */
871 mep_check_parallel_scheduling (void)
873 /* This is where we will eventually read the config information
874 and choose which scheduling checking function to call. */
876 mep_check_parallel64_scheduling ();
878 mep_check_parallel32_scheduling ();
882 mep_process_saved_insns (void)
886 gas_cgen_save_fixups (MAX_SAVED_FIXUP_CHAINS
- 1);
888 /* We have to check for valid scheduling here. */
889 mep_check_parallel_scheduling ();
891 /* If the last call didn't cause assembly to terminate, we have
892 a valid vliw insn/insn pair saved. Restore this instructions'
893 fixups and process the insns. */
894 for (i
= 0;i
<num_insns_saved
;i
++)
896 gas_cgen_restore_fixups (i
);
897 gas_cgen_finish_insn (saved_insns
[i
].insn
, saved_insns
[i
].buffer
,
898 CGEN_FIELDS_BITSIZE (& saved_insns
[i
].fields
),
901 gas_cgen_restore_fixups (MAX_SAVED_FIXUP_CHAINS
- 1);
903 /* Clear the fixups and reset the number insn saved to 0. */
904 gas_cgen_initialize_saved_fixups_array ();
906 listing_prev_line ();
910 md_assemble (char * str
)
912 static CGEN_BITSET
* isas
= NULL
;
915 /* Initialize GAS's cgen interface for a new instruction. */
916 gas_cgen_init_parse ();
918 /* There are two possible modes: core and vliw. We have to assemble
919 differently for each.
921 Core Mode: We assemble normally. All instructions are on a
922 single line and are made up of one mnemonic and one
924 VLIW Mode: Vliw combinations are indicated as follows:
929 We want to handle the general case where more than
930 one instruction can be preceeded by a +. This will
931 happen later if we add support for internally parallel
932 coprocessors. We'll make the parsing nice and general
933 so that it can handle an arbitrary number of insns
934 with leading +'s. The actual checking for valid
935 combinations is done elsewhere. */
937 /* Initialize the isa to refer to the core. */
939 isas
= cgen_bitset_copy (& MEP_CORE_ISA
);
942 cgen_bitset_clear (isas
);
943 cgen_bitset_union (isas
, & MEP_CORE_ISA
, isas
);
945 gas_cgen_cpu_desc
->isas
= isas
;
951 int thisInsnIsCopro
= 0;
955 /* Initialize the insn buffer */
957 if (! CGEN_INT_INSN_P
)
958 for (i
=0; i
< CGEN_MAX_INSN_SIZE
; i
++)
961 /* Can't tell core / copro insns apart at parse time! */
962 cgen_bitset_union (isas
, & MEP_COP_ISA
, isas
);
964 /* Assemble the insn so we can examine its attributes. */
965 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, str
,
966 &insn
.fields
, insn
.buffer
,
970 as_bad ("%s", errmsg
);
973 mep_check_for_disabled_registers (&insn
);
975 /* Check to see if it's a coprocessor instruction. */
976 thisInsnIsCopro
= MEP_INSN_COP_P (insn
.insn
);
978 if (!thisInsnIsCopro
)
980 insn
.insn
= mep_cgen_assemble_cop_insn (gas_cgen_cpu_desc
, str
,
981 &insn
.fields
, insn
.buffer
,
983 thisInsnIsCopro
= MEP_INSN_COP_P (insn
.insn
);
984 mep_check_for_disabled_registers (&insn
);
989 /* A plus was present. */
990 /* Check for a + with a core insn and abort if found. */
991 if (!thisInsnIsCopro
)
993 as_fatal("A core insn cannot be preceeded by a +.\n");
997 if (num_insns_saved
> 0)
999 /* There are insns in the queue. Add this one. */
1000 mep_save_insn (insn
);
1004 /* There are no insns in the queue and a plus is present.
1005 This is a syntax error. Let's not tolerate this.
1006 We can relax this later if necessary. */
1007 as_bad (_("Invalid use of parallelization operator."));
1013 /* No plus was present. */
1014 if (num_insns_saved
> 0)
1016 /* There are insns saved and we came across an insn without a
1017 leading +. That's the signal to process the saved insns
1018 before proceeding then treat the current insn as the first
1019 in a new vliw group. */
1020 mep_process_saved_insns ();
1021 num_insns_saved
= 0;
1022 /* mep_save_insn (insn); */
1024 mep_save_insn (insn
);
1029 /* Core Insn. Add it to the beginning of the queue. */
1030 mep_save_insn (insn
);
1031 /* gas_cgen_save_fixups(num_insns_saved); */
1042 /* Only single instructions are assembled in core mode. */
1045 /* If a leading '+' was present, issue an error.
1046 That's not allowed in core mode. */
1049 as_bad (_("Leading plus sign not allowed in core mode"));
1053 insn
.insn
= mep_cgen_assemble_insn
1054 (gas_cgen_cpu_desc
, str
, & insn
.fields
, insn
.buffer
, & errmsg
);
1058 as_bad ("%s", errmsg
);
1061 gas_cgen_finish_insn (insn
.insn
, insn
.buffer
,
1062 CGEN_FIELDS_BITSIZE (& insn
.fields
), 1, NULL
);
1063 mep_check_for_disabled_registers (&insn
);
1068 md_section_align (segT segment
, valueT size
)
1070 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1071 return ((size
+ (1 << align
) - 1) & (-1 << align
));
1076 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1081 /* Interface to relax_segment. */
1084 const relax_typeS md_relax_table
[] =
1087 1) most positive reach of this state,
1088 2) most negative reach of this state,
1089 3) how many bytes this mode will have in the variable part of the frag
1090 4) which index into the table to try if we can't fit into this one. */
1091 /* Note that we use "beq" because "jmp" has a peculiarity - it cannot
1092 jump to addresses with any bits 27..24 set. So, we use beq as a
1093 17-bit pc-relative branch to avoid using jmp, just in case. */
1095 /* 0 */ { 0, 0, 0, 0 }, /* unused */
1096 /* 1 */ { 0, 0, 0, 0 }, /* marker for "don't know yet" */
1098 /* 2 */ { 2047, -2048, 0, 3 }, /* bsr12 */
1099 /* 3 */ { 0, 0, 2, 0 }, /* bsr16 */
1101 /* 4 */ { 2047, -2048, 0, 5 }, /* bra */
1102 /* 5 */ { 65535, -65536, 2, 6 }, /* beq $0,$0 */
1103 /* 6 */ { 0, 0, 2, 0 }, /* jmp24 */
1105 /* 7 */ { 65535, -65536, 0, 8 }, /* beqi */
1106 /* 8 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1108 /* 9 */ { 127, -128, 0, 10 }, /* beqz */
1109 /* 10 */ { 65535, -65536, 2, 11 }, /* beqi */
1110 /* 11 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1112 /* 12 */ { 65535, -65536, 0, 13 }, /* bnei */
1113 /* 13 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1115 /* 14 */ { 127, -128, 0, 15 }, /* bnez */
1116 /* 15 */ { 65535, -65536, 2, 16 }, /* bnei */
1117 /* 16 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1119 /* 17 */ { 65535, -65536, 0, 13 }, /* bgei */
1120 /* 18 */ { 0, 0, 4, 0 },
1121 /* 19 */ { 65535, -65536, 0, 13 }, /* blti */
1122 /* 20 */ { 0, 0, 4, 0 },
1123 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpeq */
1124 /* 20 */ { 0, 0, 4, 0 },
1125 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpne */
1126 /* 20 */ { 0, 0, 4, 0 },
1127 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpat */
1128 /* 20 */ { 0, 0, 4, 0 },
1129 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpaf */
1130 /* 20 */ { 0, 0, 4, 0 }
1133 /* Pseudo-values for 64 bit "insns" which are combinations of two 32
1137 MEP_PSEUDO64_16BITCC
,
1138 MEP_PSEUDO64_32BITCC
,
1139 } MepPseudo64Values
;
1144 int insn_for_extern
;
1145 } subtype_mappings
[] = {
1148 { MEP_INSN_BSR12
, 0, MEP_INSN_BSR24
},
1149 { MEP_INSN_BSR24
, 2, MEP_INSN_BSR24
},
1150 { MEP_INSN_BRA
, 0, MEP_INSN_BRA
},
1151 { MEP_INSN_BEQ
, 2, MEP_INSN_BEQ
},
1152 { MEP_INSN_JMP
, 2, MEP_INSN_JMP
},
1153 { MEP_INSN_BEQI
, 0, MEP_INSN_BEQI
},
1154 { -1, 4, MEP_PSEUDO64_32BITCC
},
1155 { MEP_INSN_BEQZ
, 0, MEP_INSN_BEQZ
},
1156 { MEP_INSN_BEQI
, 2, MEP_INSN_BEQI
},
1157 { -1, 4, MEP_PSEUDO64_16BITCC
},
1158 { MEP_INSN_BNEI
, 0, MEP_INSN_BNEI
},
1159 { -1, 4, MEP_PSEUDO64_32BITCC
},
1160 { MEP_INSN_BNEZ
, 0, MEP_INSN_BNEZ
},
1161 { MEP_INSN_BNEI
, 2, MEP_INSN_BNEI
},
1162 { -1, 4, MEP_PSEUDO64_16BITCC
},
1163 { MEP_INSN_BGEI
, 0, MEP_INSN_BGEI
},
1164 { -1, 4, MEP_PSEUDO64_32BITCC
},
1165 { MEP_INSN_BLTI
, 0, MEP_INSN_BLTI
},
1166 { -1, 4, MEP_PSEUDO64_32BITCC
},
1167 { MEP_INSN_BCPEQ
, 0, MEP_INSN_BCPEQ
},
1168 { -1, 4, MEP_PSEUDO64_32BITCC
},
1169 { MEP_INSN_BCPNE
, 0, MEP_INSN_BCPNE
},
1170 { -1, 4, MEP_PSEUDO64_32BITCC
},
1171 { MEP_INSN_BCPAT
, 0, MEP_INSN_BCPAT
},
1172 { -1, 4, MEP_PSEUDO64_32BITCC
},
1173 { MEP_INSN_BCPAF
, 0, MEP_INSN_BCPAF
},
1174 { -1, 4, MEP_PSEUDO64_32BITCC
}
1176 #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
1179 mep_prepare_relax_scan (fragS
*fragP
, offsetT
*aim
, relax_substateT this_state
)
1181 symbolS
*symbolP
= fragP
->fr_symbol
;
1182 if (symbolP
&& !S_IS_DEFINED (symbolP
))
1184 /* Adjust for MeP pcrel not being relative to the next opcode. */
1185 *aim
+= 2 + md_relax_table
[this_state
].rlx_length
;
1189 insn_to_subtype (int insn
)
1192 for (i
=0; i
<NUM_MAPPINGS
; i
++)
1193 if (insn
== subtype_mappings
[i
].insn
)
1198 /* Return an initial guess of the length by which a fragment must grow
1199 to hold a branch to reach its destination. Also updates fr_type
1200 and fr_subtype as necessary.
1202 Called just before doing relaxation. Any symbol that is now
1203 undefined will not become defined. The guess for fr_var is
1204 ACTUALLY the growth beyond fr_fix. Whatever we do to grow fr_fix
1205 or fr_var contributes to our returned value. Although it may not
1206 be explicit in the frag, pretend fr_var starts with a 0 value. */
1209 md_estimate_size_before_relax (fragS
* fragP
, segT segment
)
1211 if (fragP
->fr_subtype
== 1)
1212 fragP
->fr_subtype
= insn_to_subtype (fragP
->fr_cgen
.insn
->base
->num
);
1214 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
1218 new_insn
= subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
;
1219 fragP
->fr_subtype
= insn_to_subtype (new_insn
);
1222 if (MEP_VLIW
&& ! MEP_VLIW64
1223 && (bfd_get_section_flags (stdoutput
, segment
) & SEC_MEP_VLIW
))
1225 /* Use 32 bit branches for vliw32 so the vliw word is not split. */
1226 switch (fragP
->fr_cgen
.insn
->base
->num
)
1228 case MEP_INSN_BSR12
:
1229 fragP
->fr_subtype
= insn_to_subtype
1230 (subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
);
1233 fragP
->fr_subtype
++;
1236 fragP
->fr_subtype
++;
1241 if (fragP
->fr_cgen
.insn
->base
1242 && fragP
->fr_cgen
.insn
->base
->num
1243 != subtype_mappings
[fragP
->fr_subtype
].insn
)
1245 int new_insn
= subtype_mappings
[fragP
->fr_subtype
].insn
;
1248 fragP
->fr_cgen
.insn
= (fragP
->fr_cgen
.insn
1249 - fragP
->fr_cgen
.insn
->base
->num
1254 return subtype_mappings
[fragP
->fr_subtype
].growth
;
1257 /* *fragP has been relaxed to its final size, and now needs to have
1258 the bytes inside it modified to conform to the new size.
1260 Called after relaxation is finished.
1261 fragP->fr_type == rs_machine_dependent.
1262 fragP->fr_subtype is the subtype of what the address relaxed to. */
1265 target_address_for (fragS
*frag
)
1267 int rv
= frag
->fr_offset
;
1268 symbolS
*sym
= frag
->fr_symbol
;
1271 rv
+= S_GET_VALUE (sym
);
1277 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1278 segT sec ATTRIBUTE_UNUSED
,
1281 int addend
, rn
, bit
= 0;
1283 int where
= fragP
->fr_opcode
- fragP
->fr_literal
;
1284 int e
= target_big_endian
? 0 : 1;
1286 addend
= target_address_for (fragP
) - (fragP
->fr_address
+ where
);
1288 if (subtype_mappings
[fragP
->fr_subtype
].insn
== -1)
1290 fragP
->fr_fix
+= subtype_mappings
[fragP
->fr_subtype
].growth
;
1291 switch (subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
)
1293 case MEP_PSEUDO64_16BITCC
:
1294 fragP
->fr_opcode
[1^e
] = ((fragP
->fr_opcode
[1^e
] & 1) ^ 1) | 0x06;
1295 fragP
->fr_opcode
[2^e
] = 0xd8;
1296 fragP
->fr_opcode
[3^e
] = 0x08;
1297 fragP
->fr_opcode
[4^e
] = 0;
1298 fragP
->fr_opcode
[5^e
] = 0;
1301 case MEP_PSEUDO64_32BITCC
:
1302 if (fragP
->fr_opcode
[0^e
] & 0x10)
1303 fragP
->fr_opcode
[1^e
] ^= 0x01;
1305 fragP
->fr_opcode
[1^e
] ^= 0x04;
1306 fragP
->fr_opcode
[2^e
] = 0;
1307 fragP
->fr_opcode
[3^e
] = 4;
1308 fragP
->fr_opcode
[4^e
] = 0xd8;
1309 fragP
->fr_opcode
[5^e
] = 0x08;
1310 fragP
->fr_opcode
[6^e
] = 0;
1311 fragP
->fr_opcode
[7^e
] = 0;
1317 fragP
->fr_cgen
.insn
= (fragP
->fr_cgen
.insn
1318 - fragP
->fr_cgen
.insn
->base
->num
1320 operand
= MEP_OPERAND_PCABS24A2
;
1323 switch (fragP
->fr_cgen
.insn
->base
->num
)
1325 case MEP_INSN_BSR12
:
1326 fragP
->fr_opcode
[0^e
] = 0xb0 | ((addend
>> 8) & 0x0f);
1327 fragP
->fr_opcode
[1^e
] = 0x01 | (addend
& 0xfe);
1328 operand
= MEP_OPERAND_PCREL12A2
;
1331 case MEP_INSN_BSR24
:
1333 fragP
->fr_opcode
[0^e
] = 0xd8 | ((addend
>> 5) & 0x07);
1334 fragP
->fr_opcode
[1^e
] = 0x09 | ((addend
<< 3) & 0xf0);
1335 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>>16) & 0xff);
1336 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 8) & 0xff);
1337 operand
= MEP_OPERAND_PCREL24A2
;
1341 fragP
->fr_opcode
[0^e
] = 0xb0 | ((addend
>> 8) & 0x0f);
1342 fragP
->fr_opcode
[1^e
] = 0x00 | (addend
& 0xfe);
1343 operand
= MEP_OPERAND_PCREL12A2
;
1347 /* The default relax_frag doesn't change the state if there is no
1348 growth, so we must manually handle converting out-of-range BEQ
1349 instructions to JMP. */
1350 if (addend
<= 65535 && addend
>= -65536)
1353 fragP
->fr_opcode
[0^e
] = 0xe0;
1354 fragP
->fr_opcode
[1^e
] = 0x01;
1355 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>> 9) & 0xff);
1356 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 1) & 0xff);
1357 operand
= MEP_OPERAND_PCREL17A2
;
1360 /* ...FALLTHROUGH... */
1363 addend
= target_address_for (fragP
);
1365 fragP
->fr_opcode
[0^e
] = 0xd8 | ((addend
>> 5) & 0x07);
1366 fragP
->fr_opcode
[1^e
] = 0x08 | ((addend
<< 3) & 0xf0);
1367 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>>16) & 0xff);
1368 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 8) & 0xff);
1369 operand
= MEP_OPERAND_PCABS24A2
;
1375 fragP
->fr_opcode
[1^e
] = bit
| (addend
& 0xfe);
1376 operand
= MEP_OPERAND_PCREL8A2
;
1382 if (subtype_mappings
[fragP
->fr_subtype
].growth
)
1384 fragP
->fr_fix
+= subtype_mappings
[fragP
->fr_subtype
].growth
;
1385 rn
= fragP
->fr_opcode
[0^e
] & 0x0f;
1386 fragP
->fr_opcode
[0^e
] = 0xe0 | rn
;
1387 fragP
->fr_opcode
[1^e
] = bit
;
1389 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>> 9) & 0xff);
1390 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 1) & 0xff);
1391 operand
= MEP_OPERAND_PCREL17A2
;
1396 case MEP_INSN_BCPEQ
:
1397 case MEP_INSN_BCPNE
:
1398 case MEP_INSN_BCPAT
:
1399 case MEP_INSN_BCPAF
:
1400 /* No opcode change needed, just operand. */
1401 fragP
->fr_opcode
[2^e
] = (addend
>> 9) & 0xff;
1402 fragP
->fr_opcode
[3^e
] = (addend
>> 1) & 0xff;
1403 operand
= MEP_OPERAND_PCREL17A2
;
1410 if (S_GET_SEGMENT (fragP
->fr_symbol
) != sec
1411 || operand
== MEP_OPERAND_PCABS24A2
)
1413 assert (fragP
->fr_cgen
.insn
!= 0);
1414 gas_cgen_record_fixup (fragP
,
1416 fragP
->fr_cgen
.insn
,
1417 (fragP
->fr_fix
- where
) * 8,
1418 cgen_operand_lookup_by_num (gas_cgen_cpu_desc
,
1420 fragP
->fr_cgen
.opinfo
,
1421 fragP
->fr_symbol
, fragP
->fr_offset
);
1426 /* Functions concerning relocs. */
1429 mep_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
1431 /* If we already know the fixup value, adjust it in the same
1432 way that the linker would have done. */
1433 if (fixP
->fx_addsy
== 0)
1434 switch (fixP
->fx_cgen
.opinfo
)
1436 case BFD_RELOC_MEP_LOW16
:
1437 *valP
= ((long)(*valP
& 0xffff)) << 16 >> 16;
1439 case BFD_RELOC_MEP_HI16U
:
1442 case BFD_RELOC_MEP_HI16S
:
1443 *valP
= (*valP
+ 0x8000) >> 16;
1447 /* Now call cgen's md_aply_fix. */
1448 gas_cgen_md_apply_fix (fixP
, valP
, seg
);
1452 md_pcrel_from_section (fixS
*fixP
, segT sec
)
1454 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1455 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1456 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1457 /* The symbol is undefined (or is defined but not in this section).
1458 Let the linker figure it out. */
1461 /* Return the address of the opcode - cgen adjusts for opcode size
1462 itself, to be consistent with the disassembler, which must do
1464 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1467 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
1468 Returns BFD_RELOC_NONE if no reloc type can be found.
1469 *FIXP may be modified if desired. */
1471 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
1472 #define MAP(n) case MEP_OPERAND_##n: return BFD_RELOC_MEP_##n;
1474 #define MAP(n) case MEP_OPERAND_/**/n: return BFD_RELOC_MEP_/**/n;
1477 bfd_reloc_code_real_type
1478 md_cgen_lookup_reloc (const CGEN_INSN
*insn ATTRIBUTE_UNUSED
,
1479 const CGEN_OPERAND
*operand
,
1482 enum bfd_reloc_code_real reloc
= fixP
->fx_cgen
.opinfo
;
1483 static char printed
[MEP_OPERAND_MAX
] = { 0 };
1485 /* If there's a reloc here, it's because the parser saw a %foo() and
1486 is giving us the correct reloc to use, or because we converted to
1487 a different size reloc below and want to avoid "converting" more
1489 if (reloc
&& reloc
!= BFD_RELOC_NONE
)
1492 switch (operand
->type
)
1494 MAP (PCREL8A2
); /* beqz */
1495 MAP (PCREL12A2
); /* bsr16 */
1496 MAP (PCREL17A2
); /* beqi */
1497 MAP (PCREL24A2
); /* bsr24 */
1498 MAP (PCABS24A2
); /* jmp */
1499 MAP (UIMM24
); /* mov */
1500 MAP (ADDR24A4
); /* sw/lw */
1502 /* The rest of the relocs should be generated by the parser,
1503 for things such as %tprel(), etc. */
1504 case MEP_OPERAND_SIMM16
:
1505 #ifdef OBJ_COMPLEX_RELC
1506 /* coalescing this into RELOC_MEP_16 is actually a bug,
1507 since it's a signed operand. let the relc code handle it. */
1508 return BFD_RELOC_RELC
;
1511 case MEP_OPERAND_UIMM16
:
1512 case MEP_OPERAND_SDISP16
:
1513 case MEP_OPERAND_CODE16
:
1514 fixP
->fx_where
+= 2;
1515 /* to avoid doing the above add twice */
1516 fixP
->fx_cgen
.opinfo
= BFD_RELOC_MEP_16
;
1517 return BFD_RELOC_MEP_16
;
1520 #ifdef OBJ_COMPLEX_RELC
1521 /* this is not an error, yet.
1522 pass it to the linker. */
1523 return BFD_RELOC_RELC
;
1525 if (printed
[operand
->type
])
1526 return BFD_RELOC_NONE
;
1527 printed
[operand
->type
] = 1;
1529 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1530 _("Don't know how to relocate plain operands of type %s"),
1533 /* Print some helpful hints for the user. */
1534 switch (operand
->type
)
1536 case MEP_OPERAND_UDISP7
:
1537 case MEP_OPERAND_UDISP7A2
:
1538 case MEP_OPERAND_UDISP7A4
:
1539 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1540 _("Perhaps you are missing %%tpoff()?"));
1545 return BFD_RELOC_NONE
;
1549 /* Called while parsing an instruction to create a fixup.
1550 We need to check for HI16 relocs and queue them up for later sorting. */
1553 mep_cgen_record_fixup_exp (fragS
*frag
,
1555 const CGEN_INSN
*insn
,
1557 const CGEN_OPERAND
*operand
,
1561 fixS
* fixP
= gas_cgen_record_fixup_exp (frag
, where
, insn
, length
,
1562 operand
, opinfo
, exp
);
1566 /* Return BFD reloc type from opinfo field in a fixS.
1567 It's tricky using fx_r_type in mep_frob_file because the values
1568 are BFD_RELOC_UNUSED + operand number. */
1569 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
1571 /* Sort any unmatched HI16 relocs so that they immediately precede
1572 the corresponding LO16 reloc. This is called before md_apply_fix and
1578 struct mep_hi_fixup
* l
;
1580 for (l
= mep_hi_fixup_list
; l
!= NULL
; l
= l
->next
)
1582 segment_info_type
* seginfo
;
1585 assert (FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_HI16
1586 || FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_LO16
);
1588 /* Check quickly whether the next fixup happens to be a matching low. */
1589 if (l
->fixp
->fx_next
!= NULL
1590 && FX_OPINFO_R_TYPE (l
->fixp
->fx_next
) == BFD_RELOC_LO16
1591 && l
->fixp
->fx_addsy
== l
->fixp
->fx_next
->fx_addsy
1592 && l
->fixp
->fx_offset
== l
->fixp
->fx_next
->fx_offset
)
1595 /* Look through the fixups for this segment for a matching
1596 `low'. When we find one, move the high just in front of it.
1597 We do this in two passes. In the first pass, we try to find
1598 a unique `low'. In the second pass, we permit multiple
1599 high's relocs for a single `low'. */
1600 seginfo
= seg_info (l
->seg
);
1601 for (pass
= 0; pass
< 2; pass
++)
1607 for (f
= seginfo
->fix_root
; f
!= NULL
; f
= f
->fx_next
)
1609 /* Check whether this is a `low' fixup which matches l->fixp. */
1610 if (FX_OPINFO_R_TYPE (f
) == BFD_RELOC_LO16
1611 && f
->fx_addsy
== l
->fixp
->fx_addsy
1612 && f
->fx_offset
== l
->fixp
->fx_offset
1615 || (FX_OPINFO_R_TYPE (prev
) != BFD_RELOC_HI16
)
1616 || prev
->fx_addsy
!= f
->fx_addsy
1617 || prev
->fx_offset
!= f
->fx_offset
))
1621 /* Move l->fixp before f. */
1622 for (pf
= &seginfo
->fix_root
;
1624 pf
= & (* pf
)->fx_next
)
1625 assert (* pf
!= NULL
);
1627 * pf
= l
->fixp
->fx_next
;
1629 l
->fixp
->fx_next
= f
;
1631 seginfo
->fix_root
= l
->fixp
;
1633 prev
->fx_next
= l
->fixp
;
1645 as_warn_where (l
->fixp
->fx_file
, l
->fixp
->fx_line
,
1646 _("Unmatched high relocation"));
1651 /* See whether we need to force a relocation into the output file. */
1654 mep_force_relocation (fixS
*fixp
)
1656 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
1657 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
1660 /* Allow branches to global symbols to be resolved at assembly time.
1661 This is consistent with way relaxable branches are handled, since
1662 branches to both global and local symbols are relaxed. It also
1663 corresponds to the assumptions made in md_pcrel_from_section. */
1664 return S_FORCE_RELOC (fixp
->fx_addsy
, !fixp
->fx_pcrel
);
1667 /* Write a value out to the object file, using the appropriate endianness. */
1670 md_number_to_chars (char *buf
, valueT val
, int n
)
1672 if (target_big_endian
)
1673 number_to_chars_bigendian (buf
, val
, n
);
1675 number_to_chars_littleendian (buf
, val
, n
);
1678 /* Turn a string in input_line_pointer into a floating point constant
1679 of type type, and store the appropriate bytes in *litP. The number
1680 of LITTLENUMS emitted is stored in *sizeP . An error message is
1681 returned, or NULL on OK. */
1683 /* Equal to MAX_PRECISION in atof-ieee.c */
1684 #define MAX_LITTLENUMS 6
1687 md_atof (int type
, char *litP
, int *sizeP
)
1691 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1710 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1713 return _("Bad call to md_atof()");
1716 t
= atof_ieee (input_line_pointer
, type
, words
);
1718 input_line_pointer
= t
;
1719 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1721 for (i
= 0; i
< prec
; i
++)
1723 md_number_to_chars (litP
, (valueT
) words
[i
],
1724 sizeof (LITTLENUM_TYPE
));
1725 litP
+= sizeof (LITTLENUM_TYPE
);
1733 mep_fix_adjustable (fixS
*fixP
)
1735 bfd_reloc_code_real_type reloc_type
;
1737 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1739 const CGEN_INSN
*insn
= NULL
;
1740 int opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
1741 const CGEN_OPERAND
*operand
1742 = cgen_operand_lookup_by_num(gas_cgen_cpu_desc
, opindex
);
1743 reloc_type
= md_cgen_lookup_reloc (insn
, operand
, fixP
);
1746 reloc_type
= fixP
->fx_r_type
;
1748 if (fixP
->fx_addsy
== NULL
)
1751 /* Prevent all adjustments to global symbols. */
1752 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
1755 if (S_IS_WEAK (fixP
->fx_addsy
))
1758 /* We need the symbol name for the VTABLE entries */
1759 if (reloc_type
== BFD_RELOC_VTABLE_INHERIT
1760 || reloc_type
== BFD_RELOC_VTABLE_ENTRY
)
1767 mep_elf_section_letter (int letter
, char **ptrmsg
)
1770 return SHF_MEP_VLIW
;
1772 *ptrmsg
= _("Bad .section directive: want a,v,w,x,M,S in string");
1777 mep_elf_section_flags (flagword flags
, int attr
, int type ATTRIBUTE_UNUSED
)
1779 if (attr
& SHF_MEP_VLIW
)
1780 flags
|= SEC_MEP_VLIW
;
1784 /* In vliw mode, the default section is .vtext. We have to be able
1785 to switch into .vtext using only the .vtext directive. */
1788 mep_vtext_section (void)
1790 static segT vtext_section
;
1792 if (! vtext_section
)
1794 flagword applicable
= bfd_applicable_section_flags (stdoutput
);
1795 vtext_section
= subseg_new (VTEXT_SECTION_NAME
, 0);
1796 bfd_set_section_flags (stdoutput
, vtext_section
,
1797 applicable
& (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
1798 | SEC_CODE
| SEC_READONLY
1802 return vtext_section
;
1806 mep_s_vtext (int ignore ATTRIBUTE_UNUSED
)
1810 /* Record previous_section and previous_subsection. */
1811 obj_elf_section_change_hook ();
1813 temp
= get_absolute_expression ();
1814 subseg_set (mep_vtext_section (), (subsegT
) temp
);
1815 demand_empty_rest_of_line ();
1819 mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED
)
1821 mep_process_saved_insns ();
1827 mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED
)
1830 as_bad (_(".vliw unavailable when VLIW is disabled."));
1832 /* Switch into .vtext here too. */
1833 /* mep_s_vtext(); */
1836 /* This is an undocumented pseudo-op used to disable gas's
1837 "disabled_registers" check. Used for code which checks for those
1838 registers at runtime. */
1840 mep_noregerr (int i ATTRIBUTE_UNUSED
)
1842 allow_disabled_registers
= 1;
1845 /* mep_unrecognized_line: This is called when a line that can't be parsed
1846 is encountered. We use it to check for a leading '+' sign which indicates
1847 that the current instruction is a coprocessor instruction that is to be
1848 parallelized with a previous core insn. This function accepts the '+' and
1849 rejects all other characters that might indicate garbage at the beginning
1850 of the line. The '+' character gets lost as the calling loop continues,
1851 so we need to indicate that we saw it. */
1854 mep_unrecognized_line (int ch
)
1860 return 1; /* '+' indicates an instruction to be parallelized. */
1862 return 0; /* If it's not a '+', the line can't be parsed. */
1869 /* Take care of any insns left to be parallelized when the file ends.
1870 This is mainly here to handle the case where the file ends with an
1871 insn preceeded by a + or the file ends unexpectedly. */
1873 mep_process_saved_insns ();
1877 mep_flush_pending_output (void)
1881 mep_process_saved_insns ();