Support for Toshiba MeP and for complex relocations.
[binutils.git] / gas / config / tc-mep.c
blobb3b17d3c7a1502d7fa623f6e889e19f484a3e2be
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)
9 any later version.
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. */
21 #include <stdio.h>
22 #include "as.h"
23 #include "dwarf2dbg.h"
24 #include "subsegs.h"
25 #include "symcat.h"
26 #include "opcodes/mep-desc.h"
27 #include "opcodes/mep-opc.h"
28 #include "cgen.h"
29 #include "elf/common.h"
30 #include "elf/mep.h"
31 #include "libbfd.h"
32 #include "xregex.h"
34 /* Structure to hold all of the different components describing
35 an individual instruction. */
36 typedef struct
38 const CGEN_INSN * insn;
39 const CGEN_INSN * orig_insn;
40 CGEN_FIELDS fields;
41 #if CGEN_INT_INSN_P
42 CGEN_INSN_INT buffer [1];
43 #define INSN_VALUE(buf) (*(buf))
44 #else
45 unsigned char buffer [CGEN_MAX_INSN_SIZE];
46 #define INSN_VALUE(buf) (buf)
47 #endif
48 char * addr;
49 fragS * frag;
50 int num_fixups;
51 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
52 int indices [MAX_OPERAND_INSTANCES];
53 } mep_insn;
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[] =
80 { "word", cons, 4 },
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 },
87 { NULL, NULL, 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. */
101 struct mep_hi_fixup
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)
176 int i, idx;
177 switch (c)
179 case OPTION_EB:
180 target_big_endian = 1;
181 break;
182 case OPTION_EL:
183 target_big_endian = 0;
184 break;
185 case OPTION_CONFIG:
186 idx = 0;
187 for (i=1; mep_config_map[i].name; i++)
188 if (strcmp (mep_config_map[i].name, arg) == 0)
190 idx = i;
191 break;
193 if (!idx)
195 fprintf (stderr, "Error: unknown configuration %s\n", arg);
196 return 0;
198 mep_config_index = idx;
199 target_big_endian = mep_config_map[idx].big_endian;
200 break;
201 case OPTION_AVERAGE:
202 optbits |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
203 optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
204 break;
205 case OPTION_NOAVERAGE:
206 optbits &= ~(1 << CGEN_INSN_OPTIONAL_AVE_INSN);
207 optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
208 break;
209 case OPTION_MULT:
210 optbits |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
211 optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
212 break;
213 case OPTION_NOMULT:
214 optbits &= ~(1 << CGEN_INSN_OPTIONAL_MUL_INSN);
215 optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
216 break;
217 case OPTION_DIV:
218 optbits |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
219 optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
220 break;
221 case OPTION_NODIV:
222 optbits &= ~(1 << CGEN_INSN_OPTIONAL_DIV_INSN);
223 optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
224 break;
225 case OPTION_BITOPS:
226 optbits |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
227 optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
228 break;
229 case OPTION_NOBITOPS:
230 optbits &= ~(1 << CGEN_INSN_OPTIONAL_BIT_INSN);
231 optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
232 break;
233 case OPTION_LEADZ:
234 optbits |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
235 optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
236 break;
237 case OPTION_NOLEADZ:
238 optbits &= ~(1 << CGEN_INSN_OPTIONAL_LDZ_INSN);
239 optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
240 break;
241 case OPTION_ABSDIFF:
242 optbits |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
243 optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
244 break;
245 case OPTION_NOABSDIFF:
246 optbits &= ~(1 << CGEN_INSN_OPTIONAL_ABS_INSN);
247 optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
248 break;
249 case OPTION_MINMAX:
250 optbits |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
251 optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
252 break;
253 case OPTION_NOMINMAX:
254 optbits &= ~(1 << CGEN_INSN_OPTIONAL_MINMAX_INSN);
255 optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
256 break;
257 case OPTION_CLIP:
258 optbits |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
259 optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
260 break;
261 case OPTION_NOCLIP:
262 optbits &= ~(1 << CGEN_INSN_OPTIONAL_CLIP_INSN);
263 optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
264 break;
265 case OPTION_SATUR:
266 optbits |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
267 optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
268 break;
269 case OPTION_NOSATUR:
270 optbits &= ~(1 << CGEN_INSN_OPTIONAL_SAT_INSN);
271 optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
272 break;
273 case OPTION_COP32:
274 optbits |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
275 optbitset |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
276 break;
277 case OPTION_DEBUG:
278 optbits |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
279 optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
280 break;
281 case OPTION_NODEBUG:
282 optbits &= ~(1 << CGEN_INSN_OPTIONAL_DEBUG_INSN);
283 optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
284 break;
285 case OPTION_LIBRARY:
286 library_flag = EF_MEP_LIBRARY;
287 break;
288 case OPTION_REPEAT:
289 case OPTION_NOREPEAT:
290 break;
291 default:
292 return 0;
294 return 1;
297 void
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\
313 "));
314 if (mep_config_map[1].name)
316 int i;
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");
327 static void
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;
334 unsigned int b, r;
336 if (allow_disabled_registers)
337 return;
339 #if !CGEN_INT_INSN_P
340 if (target_big_endian)
341 b = insn->buffer[0] * 256 + insn->buffer[1];
342 else
343 b = insn->buffer[1] * 256 + insn->buffer[0];
344 #else
345 b = insn->buffer[0];
346 #endif
348 if ((b & 0xfffff00e) == 0x7008 /* stc */
349 || (b & 0xfffff00e) == 0x700a /* ldc */)
351 if (!initted)
353 initted = 1;
354 if ((MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_MUL_INSN))
355 || (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DIV_INSN)))
356 has_mul_div = 1;
357 if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN))
358 has_debug = 1;
359 if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_CP_INSN))
360 has_cop = 1;
363 r = ((b & 0x00f0) >> 4) | ((b & 0x0001) << 4);
364 switch (r)
366 case 7: /* $hi */
367 case 8: /* $lo */
368 if (!has_mul_div)
369 as_bad ("$hi and $lo are disabled when MUL and DIV are off");
370 break;
371 case 12: /* $mb0 */
372 case 13: /* $me0 */
373 case 14: /* $mb1 */
374 case 15: /* $me1 */
375 if (!has_cop)
376 as_bad ("$mb0, $me0, $mb1, and $me1 are disabled when COP is off");
377 break;
378 case 24: /* $dbg */
379 case 25: /* $depc */
380 if (!has_debug)
381 as_bad ("$dbg and $depc are disabled when DEBUG is off");
382 break;
387 static int
388 mep_machine (void)
390 switch (MEP_CPU)
392 default: break;
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;
399 return bfd_mach_mep;
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. */
407 static const char *
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)
414 const char *next;
416 next = *strP;
417 while (*next == '(')
418 next++;
419 if (*next == '$')
420 return "Not a valid literal";
422 return gas_cgen_parse_operand (cd, want, strP, opindex, opinfo,
423 resultP, valueP);
426 void
427 md_begin ()
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)
438 MEP_OMASK = optbits;
439 else
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,
445 target_big_endian
446 ? CGEN_ENDIAN_BIG
447 : CGEN_ENDIAN_LITTLE,
448 CGEN_CPU_OPEN_ISAS, 0,
449 CGEN_CPU_OPEN_END);
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,
470 const char *str,
471 CGEN_FIELDS *fields,
472 CGEN_INSN_BYTES_PTR buf,
473 const struct cgen_insn *pinsn)
475 const char *start;
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));
483 start = str;
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))
492 str = start;
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)
497 continue;
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);
503 if (errmsg != NULL)
504 continue;
506 errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
507 (bfd_vma) 0);
508 if (errmsg != NULL)
509 continue;
511 return insn;
514 return pinsn;
517 static void
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.");
524 return;
526 saved_insns[num_insns_saved] = insn;
527 gas_cgen_save_fixups(num_insns_saved);
528 num_insns_saved++;
531 static void
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)
546 return;
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)
564 return;
565 else
566 as_bad ("core and copro insn lengths must total 32 bits.");
568 else
569 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
571 else
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
591 we have to abort. */
593 if (insn0length > 32)
594 as_fatal ("Cannot use 48- or 64-bit insns with a 32 bit datapath.");
596 if (insn0length == 32)
597 return;
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. */
609 if (insn0iscopro)
611 char *errmsg;
612 mep_insn insn;
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
616 first element. */
617 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "nop",
618 &insn.fields, insn.buffer,
619 &errmsg);
620 if (!insn.insn)
622 as_bad ("%s", errmsg);
623 return;
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
632 have an example. */
633 saved_insns[1] = saved_insns[0];
634 saved_insns[0] = insn;
635 num_insns_saved++;
636 gas_cgen_swap_fixups (0);
637 gas_cgen_save_fixups (1);
639 else
641 char * errmsg;
642 mep_insn insn;
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)
649 return;
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,
655 &errmsg);
656 if (!insn.insn)
658 as_bad ("%s", errmsg);
659 return;
662 /* Now put the insn and fixups into the arrays. */
663 mep_save_insn (insn);
668 static void
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)
683 return;
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)
701 return;
702 else
703 as_bad ("core and copro insn lengths must total 64 bits.");
705 else
706 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
708 else
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
728 we have to abort. */
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)
734 return;
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.");
742 if (insn0iscopro)
744 char *errmsg;
745 mep_insn insn;
746 int i;
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,
767 & errmsg);
769 else
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.");
786 if (!insn.insn)
788 as_bad ("%s", errmsg);
789 return;
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
798 have an example. */
800 saved_insns[1] = saved_insns[0];
801 saved_insns[0] = insn;
802 num_insns_saved++;
803 gas_cgen_swap_fixups(0);
804 gas_cgen_save_fixups(1);
807 else
809 char * errmsg;
810 mep_insn insn;
811 int i;
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,
833 &errmsg);
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,
840 &errmsg);
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,
847 &errmsg);
849 else
850 /* Core insn has an invalid length. Something has gone wrong. */
851 as_fatal ("Core insn has invalid length! Something is wrong!");
853 if (!insn.insn)
855 as_bad ("%s", errmsg);
856 return;
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. */
870 static void
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. */
875 if (MEP_VLIW64)
876 mep_check_parallel64_scheduling ();
877 else
878 mep_check_parallel32_scheduling ();
881 static void
882 mep_process_saved_insns (void)
884 int i;
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),
899 1, NULL);
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 ();
905 num_insns_saved = 0;
906 listing_prev_line ();
909 void
910 md_assemble (char * str)
912 static CGEN_BITSET* isas = NULL;
913 char * errmsg;
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
923 set of operands.
924 VLIW Mode: Vliw combinations are indicated as follows:
926 core insn
927 + copro insn
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. */
938 if (isas == NULL)
939 isas = cgen_bitset_copy (& MEP_CORE_ISA);
940 else
942 cgen_bitset_clear (isas);
943 cgen_bitset_union (isas, & MEP_CORE_ISA, isas);
945 gas_cgen_cpu_desc->isas = isas;
947 if (mode == VLIW)
949 /* VLIW mode. */
951 int thisInsnIsCopro = 0;
952 mep_insn insn;
953 int i;
955 /* Initialize the insn buffer */
957 if (! CGEN_INT_INSN_P)
958 for (i=0; i < CGEN_MAX_INSN_SIZE; i++)
959 insn.buffer[i]='\0';
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,
967 &errmsg);
968 if (!insn.insn)
970 as_bad ("%s", errmsg);
971 return;
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,
982 insn.insn);
983 thisInsnIsCopro = MEP_INSN_COP_P (insn.insn);
984 mep_check_for_disabled_registers (&insn);
987 if (pluspresent)
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");
994 return;
997 if (num_insns_saved > 0)
999 /* There are insns in the queue. Add this one. */
1000 mep_save_insn (insn);
1002 else
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."));
1008 return;
1011 else
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);
1025 #if 0
1026 else
1029 /* Core Insn. Add it to the beginning of the queue. */
1030 mep_save_insn (insn);
1031 /* gas_cgen_save_fixups(num_insns_saved); */
1033 #endif
1036 pluspresent = 0;
1038 else
1040 /* Core mode. */
1042 /* Only single instructions are assembled in core mode. */
1043 mep_insn insn;
1045 /* If a leading '+' was present, issue an error.
1046 That's not allowed in core mode. */
1047 if (pluspresent)
1049 as_bad (_("Leading plus sign not allowed in core mode"));
1050 return;
1053 insn.insn = mep_cgen_assemble_insn
1054 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
1056 if (!insn.insn)
1058 as_bad ("%s", errmsg);
1059 return;
1061 gas_cgen_finish_insn (insn.insn, insn.buffer,
1062 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
1063 mep_check_for_disabled_registers (&insn);
1067 valueT
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));
1075 symbolS *
1076 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1078 return 0;
1081 /* Interface to relax_segment. */
1084 const relax_typeS md_relax_table[] =
1086 /* The fields are:
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
1134 bit insns. */
1135 typedef enum {
1136 MEP_PSEUDO64_NONE,
1137 MEP_PSEUDO64_16BITCC,
1138 MEP_PSEUDO64_32BITCC,
1139 } MepPseudo64Values;
1141 static struct {
1142 int insn;
1143 int growth;
1144 int insn_for_extern;
1145 } subtype_mappings[] = {
1146 { 0, 0, 0 },
1147 { 0, 0, 0 },
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]))
1178 void
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))
1183 *aim = 0;
1184 /* Adjust for MeP pcrel not being relative to the next opcode. */
1185 *aim += 2 + md_relax_table[this_state].rlx_length;
1188 static int
1189 insn_to_subtype (int insn)
1191 unsigned int i;
1192 for (i=0; i<NUM_MAPPINGS; i++)
1193 if (insn == subtype_mappings[i].insn)
1194 return i;
1195 abort ();
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)
1216 int new_insn;
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);
1231 break;
1232 case MEP_INSN_BEQZ:
1233 fragP->fr_subtype ++;
1234 break;
1235 case MEP_INSN_BNEZ:
1236 fragP->fr_subtype ++;
1237 break;
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;
1246 if (new_insn != -1)
1248 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
1249 - fragP->fr_cgen.insn->base->num
1250 + new_insn);
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. */
1264 static int
1265 target_address_for (fragS *frag)
1267 int rv = frag->fr_offset;
1268 symbolS *sym = frag->fr_symbol;
1270 if (sym)
1271 rv += S_GET_VALUE (sym);
1273 return rv;
1276 void
1277 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1278 segT sec ATTRIBUTE_UNUSED,
1279 fragS *fragP)
1281 int addend, rn, bit = 0;
1282 int operand;
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;
1299 where += 2;
1300 break;
1301 case MEP_PSEUDO64_32BITCC:
1302 if (fragP->fr_opcode[0^e] & 0x10)
1303 fragP->fr_opcode[1^e] ^= 0x01;
1304 else
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;
1312 where += 4;
1313 break;
1314 default:
1315 abort ();
1317 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
1318 - fragP->fr_cgen.insn->base->num
1319 + MEP_INSN_JMP);
1320 operand = MEP_OPERAND_PCABS24A2;
1322 else
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;
1329 break;
1331 case MEP_INSN_BSR24:
1332 fragP->fr_fix += 2;
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;
1338 break;
1340 case MEP_INSN_BRA:
1341 fragP->fr_opcode[0^e] = 0xb0 | ((addend >> 8) & 0x0f);
1342 fragP->fr_opcode[1^e] = 0x00 | (addend & 0xfe);
1343 operand = MEP_OPERAND_PCREL12A2;
1344 break;
1346 case MEP_INSN_BEQ:
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)
1352 fragP->fr_fix += 2;
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;
1358 break;
1360 /* ...FALLTHROUGH... */
1362 case MEP_INSN_JMP:
1363 addend = target_address_for (fragP);
1364 fragP->fr_fix += 2;
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;
1370 break;
1372 case MEP_INSN_BNEZ:
1373 bit = 1;
1374 case MEP_INSN_BEQZ:
1375 fragP->fr_opcode[1^e] = bit | (addend & 0xfe);
1376 operand = MEP_OPERAND_PCREL8A2;
1377 break;
1379 case MEP_INSN_BNEI:
1380 bit = 4;
1381 case MEP_INSN_BEQI:
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;
1392 break;
1394 case MEP_INSN_BLTI:
1395 case MEP_INSN_BGEI:
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;
1404 break;
1406 default:
1407 abort ();
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,
1415 where,
1416 fragP->fr_cgen.insn,
1417 (fragP->fr_fix - where) * 8,
1418 cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
1419 operand),
1420 fragP->fr_cgen.opinfo,
1421 fragP->fr_symbol, fragP->fr_offset);
1426 /* Functions concerning relocs. */
1428 void
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;
1438 break;
1439 case BFD_RELOC_MEP_HI16U:
1440 *valP >>= 16;
1441 break;
1442 case BFD_RELOC_MEP_HI16S:
1443 *valP = (*valP + 0x8000) >> 16;
1444 break;
1447 /* Now call cgen's md_aply_fix. */
1448 gas_cgen_md_apply_fix (fixP, valP, seg);
1451 long
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. */
1459 return 0;
1461 /* Return the address of the opcode - cgen adjusts for opcode size
1462 itself, to be consistent with the disassembler, which must do
1463 so. */
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;
1473 #else
1474 #define MAP(n) case MEP_OPERAND_/**/n: return BFD_RELOC_MEP_/**/n;
1475 #endif
1477 bfd_reloc_code_real_type
1478 md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
1479 const CGEN_OPERAND *operand,
1480 fixS *fixP)
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
1488 than once. */
1489 if (reloc && reloc != BFD_RELOC_NONE)
1490 return reloc;
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;
1509 #endif
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;
1519 default:
1520 #ifdef OBJ_COMPLEX_RELC
1521 /* this is not an error, yet.
1522 pass it to the linker. */
1523 return BFD_RELOC_RELC;
1524 #endif
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"),
1531 operand->name);
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()?"));
1541 break;
1542 default:
1543 break;
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. */
1552 fixS *
1553 mep_cgen_record_fixup_exp (fragS *frag,
1554 int where,
1555 const CGEN_INSN *insn,
1556 int length,
1557 const CGEN_OPERAND *operand,
1558 int opinfo,
1559 expressionS *exp)
1561 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
1562 operand, opinfo, exp);
1563 return fixP;
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
1573 tc_gen_reloc. */
1575 void
1576 mep_frob_file ()
1578 struct mep_hi_fixup * l;
1580 for (l = mep_hi_fixup_list; l != NULL; l = l->next)
1582 segment_info_type * seginfo;
1583 int pass;
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)
1593 continue;
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++)
1603 fixS * f;
1604 fixS * prev;
1606 prev = NULL;
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
1613 && (pass == 1
1614 || prev == NULL
1615 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
1616 || prev->fx_addsy != f->fx_addsy
1617 || prev->fx_offset != f->fx_offset))
1619 fixS ** pf;
1621 /* Move l->fixp before f. */
1622 for (pf = &seginfo->fix_root;
1623 * pf != l->fixp;
1624 pf = & (* pf)->fx_next)
1625 assert (* pf != NULL);
1627 * pf = l->fixp->fx_next;
1629 l->fixp->fx_next = f;
1630 if (prev == NULL)
1631 seginfo->fix_root = l->fixp;
1632 else
1633 prev->fx_next = l->fixp;
1635 break;
1638 prev = f;
1641 if (f != NULL)
1642 break;
1644 if (pass == 1)
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)
1658 return 1;
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. */
1669 void
1670 md_number_to_chars (char *buf, valueT val, int n)
1672 if (target_big_endian)
1673 number_to_chars_bigendian (buf, val, n);
1674 else
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
1686 char *
1687 md_atof (int type, char *litP, int *sizeP)
1689 int i;
1690 int prec;
1691 LITTLENUM_TYPE words [MAX_LITTLENUMS];
1692 char * t;
1694 switch (type)
1696 case 'f':
1697 case 'F':
1698 case 's':
1699 case 'S':
1700 prec = 2;
1701 break;
1703 case 'd':
1704 case 'D':
1705 case 'r':
1706 case 'R':
1707 prec = 4;
1708 break;
1710 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1711 default:
1712 *sizeP = 0;
1713 return _("Bad call to md_atof()");
1716 t = atof_ieee (input_line_pointer, type, words);
1717 if (t)
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);
1728 return 0;
1732 bfd_boolean
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);
1745 else
1746 reloc_type = fixP->fx_r_type;
1748 if (fixP->fx_addsy == NULL)
1749 return 1;
1751 /* Prevent all adjustments to global symbols. */
1752 if (S_IS_EXTERNAL (fixP->fx_addsy))
1753 return 0;
1755 if (S_IS_WEAK (fixP->fx_addsy))
1756 return 0;
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)
1761 return 0;
1763 return 1;
1767 mep_elf_section_letter (int letter, char **ptrmsg)
1769 if (letter == 'v')
1770 return SHF_MEP_VLIW;
1772 *ptrmsg = _("Bad .section directive: want a,v,w,x,M,S in string");
1773 return 0;
1776 flagword
1777 mep_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
1779 if (attr & SHF_MEP_VLIW)
1780 flags |= SEC_MEP_VLIW;
1781 return flags;
1784 /* In vliw mode, the default section is .vtext. We have to be able
1785 to switch into .vtext using only the .vtext directive. */
1787 static segT
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
1799 | SEC_MEP_VLIW));
1802 return vtext_section;
1805 static void
1806 mep_s_vtext (int ignore ATTRIBUTE_UNUSED)
1808 int temp;
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 ();
1818 static void
1819 mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED)
1821 mep_process_saved_insns ();
1822 pluspresent = 0;
1823 mode = CORE;
1826 static void
1827 mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED)
1829 if (! MEP_VLIW)
1830 as_bad (_(".vliw unavailable when VLIW is disabled."));
1831 mode = VLIW;
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. */
1839 static void
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)
1856 switch (ch)
1858 case '+':
1859 pluspresent = 1;
1860 return 1; /* '+' indicates an instruction to be parallelized. */
1861 default:
1862 return 0; /* If it's not a '+', the line can't be parsed. */
1866 void
1867 mep_cleanup (void)
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. */
1872 if (mode == VLIW)
1873 mep_process_saved_insns ();
1877 mep_flush_pending_output (void)
1879 if (mode == VLIW)
1881 mep_process_saved_insns ();
1882 pluspresent = 0;
1885 return 1;