]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-mep.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-mep.c
CommitLineData
280d71bf 1/* tc-mep.c -- Assembler for the Toshiba Media Processor.
250d07de 2 Copyright (C) 2001-2021 Free Software Foundation, Inc.
280d71bf
DB
3
4 This file is part of GAS, the GNU Assembler.
5
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
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
280d71bf
DB
9 any later version.
10
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.
15
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. */
20
280d71bf 21#include "as.h"
df7b86aa 22#include <stdio.h>
280d71bf
DB
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"
280d71bf
DB
31#include "xregex.h"
32
33/* Structure to hold all of the different components describing
34 an individual instruction. */
35typedef struct
36{
37 const CGEN_INSN * insn;
38 const CGEN_INSN * orig_insn;
39 CGEN_FIELDS fields;
40#if CGEN_INT_INSN_P
41 CGEN_INSN_INT buffer [1];
42#define INSN_VALUE(buf) (*(buf))
43#else
44 unsigned char buffer [CGEN_MAX_INSN_SIZE];
45#define INSN_VALUE(buf) (buf)
46#endif
47 char * addr;
48 fragS * frag;
49 int num_fixups;
50 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
51 int indices [MAX_OPERAND_INSTANCES];
52} mep_insn;
53
54static int mode = CORE; /* Start in core mode. */
55static int pluspresent = 0;
56static int allow_disabled_registers = 0;
57static int library_flag = 0;
3526b680 58static int mep_cop = EF_MEP_COP_NONE;
280d71bf
DB
59
60/* We're going to need to store all of the instructions along with
61 their fixups so that we can parallelization grouping rules. */
62
63static mep_insn saved_insns[MAX_SAVED_FIXUP_CHAINS];
64static int num_insns_saved = 0;
65
66const char comment_chars[] = "#";
67const char line_comment_chars[] = ";#";
68const char line_separator_chars[] = ";";
69const char EXP_CHARS[] = "eE";
70const char FLT_CHARS[] = "dD";
71
72static void mep_switch_to_vliw_mode (int);
73static void mep_switch_to_core_mode (int);
74static void mep_s_vtext (int);
75static void mep_noregerr (int);
76
77/* The target specific pseudo-ops which we support. */
78const pseudo_typeS md_pseudo_table[] =
79{
80 { "word", cons, 4 },
280d71bf
DB
81 { "vliw", mep_switch_to_vliw_mode, 0 },
82 { "core", mep_switch_to_core_mode, 0 },
83 { "vtext", mep_s_vtext, 0 },
84 { "noregerr", mep_noregerr, 0 },
85 { NULL, NULL, 0 }
86};
87
88/* Relocations against symbols are done in two
89 parts, with a HI relocation and a LO relocation. Each relocation
90 has only 16 bits of space to store an addend. This means that in
91 order for the linker to handle carries correctly, it must be able
92 to locate both the HI and the LO relocation. This means that the
93 relocations must appear in order in the relocation table.
94
95 In order to implement this, we keep track of each unmatched HI
96 relocation. We then sort them so that they immediately precede the
97 corresponding LO relocation. */
98
99struct mep_hi_fixup
100{
101 struct mep_hi_fixup * next; /* Next HI fixup. */
102 fixS * fixp; /* This fixup. */
103 segT seg; /* The section this fixup is in. */
104};
105
106/* The list of unmatched HI relocs. */
107static struct mep_hi_fixup * mep_hi_fixup_list;
108
109\f
110#define OPTION_EB (OPTION_MD_BASE + 0)
111#define OPTION_EL (OPTION_MD_BASE + 1)
112#define OPTION_CONFIG (OPTION_MD_BASE + 2)
113#define OPTION_AVERAGE (OPTION_MD_BASE + 3)
114#define OPTION_NOAVERAGE (OPTION_MD_BASE + 4)
115#define OPTION_MULT (OPTION_MD_BASE + 5)
116#define OPTION_NOMULT (OPTION_MD_BASE + 6)
117#define OPTION_DIV (OPTION_MD_BASE + 7)
118#define OPTION_NODIV (OPTION_MD_BASE + 8)
119#define OPTION_BITOPS (OPTION_MD_BASE + 9)
120#define OPTION_NOBITOPS (OPTION_MD_BASE + 10)
121#define OPTION_LEADZ (OPTION_MD_BASE + 11)
122#define OPTION_NOLEADZ (OPTION_MD_BASE + 12)
123#define OPTION_ABSDIFF (OPTION_MD_BASE + 13)
124#define OPTION_NOABSDIFF (OPTION_MD_BASE + 14)
125#define OPTION_MINMAX (OPTION_MD_BASE + 15)
126#define OPTION_NOMINMAX (OPTION_MD_BASE + 16)
127#define OPTION_CLIP (OPTION_MD_BASE + 17)
128#define OPTION_NOCLIP (OPTION_MD_BASE + 18)
129#define OPTION_SATUR (OPTION_MD_BASE + 19)
130#define OPTION_NOSATUR (OPTION_MD_BASE + 20)
131#define OPTION_COP32 (OPTION_MD_BASE + 21)
132#define OPTION_REPEAT (OPTION_MD_BASE + 25)
133#define OPTION_NOREPEAT (OPTION_MD_BASE + 26)
134#define OPTION_DEBUG (OPTION_MD_BASE + 27)
135#define OPTION_NODEBUG (OPTION_MD_BASE + 28)
4d28413b
DD
136#define OPTION_UCI (OPTION_MD_BASE + 29)
137#define OPTION_NOUCI (OPTION_MD_BASE + 30)
138#define OPTION_DSP (OPTION_MD_BASE + 31)
139#define OPTION_NODSP (OPTION_MD_BASE + 32)
140#define OPTION_LIBRARY (OPTION_MD_BASE + 33)
280d71bf
DB
141
142struct option md_longopts[] = {
143 { "EB", no_argument, NULL, OPTION_EB},
144 { "EL", no_argument, NULL, OPTION_EL},
145 { "mconfig", required_argument, NULL, OPTION_CONFIG},
146 { "maverage", no_argument, NULL, OPTION_AVERAGE},
147 { "mno-average", no_argument, NULL, OPTION_NOAVERAGE},
148 { "mmult", no_argument, NULL, OPTION_MULT},
149 { "mno-mult", no_argument, NULL, OPTION_NOMULT},
150 { "mdiv", no_argument, NULL, OPTION_DIV},
151 { "mno-div", no_argument, NULL, OPTION_NODIV},
152 { "mbitops", no_argument, NULL, OPTION_BITOPS},
153 { "mno-bitops", no_argument, NULL, OPTION_NOBITOPS},
154 { "mleadz", no_argument, NULL, OPTION_LEADZ},
155 { "mno-leadz", no_argument, NULL, OPTION_NOLEADZ},
156 { "mabsdiff", no_argument, NULL, OPTION_ABSDIFF},
157 { "mno-absdiff", no_argument, NULL, OPTION_NOABSDIFF},
158 { "mminmax", no_argument, NULL, OPTION_MINMAX},
159 { "mno-minmax", no_argument, NULL, OPTION_NOMINMAX},
160 { "mclip", no_argument, NULL, OPTION_CLIP},
161 { "mno-clip", no_argument, NULL, OPTION_NOCLIP},
162 { "msatur", no_argument, NULL, OPTION_SATUR},
163 { "mno-satur", no_argument, NULL, OPTION_NOSATUR},
164 { "mcop32", no_argument, NULL, OPTION_COP32},
165 { "mdebug", no_argument, NULL, OPTION_DEBUG},
166 { "mno-debug", no_argument, NULL, OPTION_NODEBUG},
4d28413b
DD
167 { "muci", no_argument, NULL, OPTION_UCI},
168 { "mno-uci", no_argument, NULL, OPTION_NOUCI},
169 { "mdsp", no_argument, NULL, OPTION_DSP},
170 { "mno-dsp", no_argument, NULL, OPTION_NODSP},
280d71bf
DB
171 { "mlibrary", no_argument, NULL, OPTION_LIBRARY},
172 { NULL, 0, NULL, 0 } };
173size_t md_longopts_size = sizeof (md_longopts);
174
7ec721f4
DD
175/* Options which default to on/off together. See the comment where
176 this is used for details. Note that CP and CP64 are not in this
177 list because disabling those overrides the -mivc2 option. */
178#define OPTION_MASK \
179 ( (1 << CGEN_INSN_OPTIONAL_BIT_INSN) \
180 | (1 << CGEN_INSN_OPTIONAL_MUL_INSN) \
181 | (1 << CGEN_INSN_OPTIONAL_DIV_INSN) \
182 | (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN) \
183 | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) \
184 | (1 << CGEN_INSN_OPTIONAL_ABS_INSN) \
185 | (1 << CGEN_INSN_OPTIONAL_AVE_INSN) \
186 | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) \
187 | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) \
188 | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) \
189 | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) \
190 | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) )
191
280d71bf
DB
192const char * md_shortopts = "";
193static int optbits = 0;
194static int optbitset = 0;
195
196int
17b9d67d 197md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
280d71bf
DB
198{
199 int i, idx;
200 switch (c)
201 {
202 case OPTION_EB:
203 target_big_endian = 1;
204 break;
205 case OPTION_EL:
206 target_big_endian = 0;
207 break;
208 case OPTION_CONFIG:
209 idx = 0;
210 for (i=1; mep_config_map[i].name; i++)
211 if (strcmp (mep_config_map[i].name, arg) == 0)
212 {
213 idx = i;
214 break;
215 }
216 if (!idx)
217 {
218 fprintf (stderr, "Error: unknown configuration %s\n", arg);
219 return 0;
220 }
221 mep_config_index = idx;
222 target_big_endian = mep_config_map[idx].big_endian;
223 break;
224 case OPTION_AVERAGE:
225 optbits |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
226 optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
227 break;
228 case OPTION_NOAVERAGE:
229 optbits &= ~(1 << CGEN_INSN_OPTIONAL_AVE_INSN);
230 optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
231 break;
232 case OPTION_MULT:
233 optbits |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
234 optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
235 break;
236 case OPTION_NOMULT:
237 optbits &= ~(1 << CGEN_INSN_OPTIONAL_MUL_INSN);
238 optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
239 break;
240 case OPTION_DIV:
241 optbits |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
242 optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
243 break;
244 case OPTION_NODIV:
245 optbits &= ~(1 << CGEN_INSN_OPTIONAL_DIV_INSN);
246 optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
247 break;
248 case OPTION_BITOPS:
249 optbits |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
250 optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
251 break;
252 case OPTION_NOBITOPS:
253 optbits &= ~(1 << CGEN_INSN_OPTIONAL_BIT_INSN);
254 optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
255 break;
256 case OPTION_LEADZ:
257 optbits |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
258 optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
259 break;
260 case OPTION_NOLEADZ:
261 optbits &= ~(1 << CGEN_INSN_OPTIONAL_LDZ_INSN);
262 optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
263 break;
264 case OPTION_ABSDIFF:
265 optbits |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
266 optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
267 break;
268 case OPTION_NOABSDIFF:
269 optbits &= ~(1 << CGEN_INSN_OPTIONAL_ABS_INSN);
270 optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
271 break;
272 case OPTION_MINMAX:
273 optbits |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
274 optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
275 break;
276 case OPTION_NOMINMAX:
277 optbits &= ~(1 << CGEN_INSN_OPTIONAL_MINMAX_INSN);
278 optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
279 break;
280 case OPTION_CLIP:
281 optbits |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
282 optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
283 break;
284 case OPTION_NOCLIP:
285 optbits &= ~(1 << CGEN_INSN_OPTIONAL_CLIP_INSN);
286 optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
287 break;
288 case OPTION_SATUR:
289 optbits |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
290 optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
291 break;
292 case OPTION_NOSATUR:
293 optbits &= ~(1 << CGEN_INSN_OPTIONAL_SAT_INSN);
294 optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
295 break;
296 case OPTION_COP32:
297 optbits |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
298 optbitset |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
299 break;
300 case OPTION_DEBUG:
301 optbits |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
302 optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
303 break;
304 case OPTION_NODEBUG:
305 optbits &= ~(1 << CGEN_INSN_OPTIONAL_DEBUG_INSN);
306 optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
307 break;
4d28413b
DD
308 case OPTION_UCI:
309 optbits |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
310 optbitset |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
311 break;
312 case OPTION_NOUCI:
313 optbits &= ~(1 << CGEN_INSN_OPTIONAL_UCI_INSN);
314 optbitset |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
315 break;
316 case OPTION_DSP:
317 optbits |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
318 optbitset |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
319 break;
320 case OPTION_NODSP:
321 optbits &= ~(1 << CGEN_INSN_OPTIONAL_DSP_INSN);
322 optbitset |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
323 break;
280d71bf
DB
324 case OPTION_LIBRARY:
325 library_flag = EF_MEP_LIBRARY;
326 break;
327 case OPTION_REPEAT:
328 case OPTION_NOREPEAT:
329 break;
330 default:
331 return 0;
332 }
333 return 1;
334}
335
336void
337md_show_usage (FILE *stream)
338{
339 fprintf (stream, _("MeP specific command line options:\n\
4d28413b
DD
340 -EB assemble for a big endian system\n\
341 -EL assemble for a little endian system (default)\n\
280d71bf
DB
342 -mconfig=<name> specify a chip configuration to use\n\
343 -maverage -mno-average -mmult -mno-mult -mdiv -mno-div\n\
344 -mbitops -mno-bitops -mleadz -mno-leadz -mabsdiff -mno-absdiff\n\
345 -mminmax -mno-minmax -mclip -mno-clip -msatur -mno-satur -mcop32\n\
346 enable/disable the given opcodes\n\
347\n\
348 If -mconfig is given, the other -m options modify it. Otherwise,\n\
349 if no -m options are given, all core opcodes are enabled;\n\
350 if any enabling -m options are given, only those are enabled;\n\
351 if only disabling -m options are given, only those are disabled.\n\
352"));
353 if (mep_config_map[1].name)
354 {
355 int i;
356 fprintf (stream, " -mconfig=STR specify the configuration to use\n");
357 fprintf (stream, " Configurations:");
358 for (i=0; mep_config_map[i].name; i++)
359 fprintf (stream, " %s", mep_config_map[i].name);
360 fprintf (stream, "\n");
361 }
362}
363
364\f
365
366static void
367mep_check_for_disabled_registers (mep_insn *insn)
368{
369 static int initted = 0;
370 static int has_mul_div = 0;
371 static int has_cop = 0;
372 static int has_debug = 0;
373 unsigned int b, r;
374
375 if (allow_disabled_registers)
376 return;
377
378#if !CGEN_INT_INSN_P
379 if (target_big_endian)
380 b = insn->buffer[0] * 256 + insn->buffer[1];
381 else
382 b = insn->buffer[1] * 256 + insn->buffer[0];
383#else
384 b = insn->buffer[0];
385#endif
386
387 if ((b & 0xfffff00e) == 0x7008 /* stc */
388 || (b & 0xfffff00e) == 0x700a /* ldc */)
389 {
390 if (!initted)
391 {
392 initted = 1;
393 if ((MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_MUL_INSN))
394 || (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DIV_INSN)))
395 has_mul_div = 1;
396 if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN))
397 has_debug = 1;
398 if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_CP_INSN))
399 has_cop = 1;
400 }
401
402 r = ((b & 0x00f0) >> 4) | ((b & 0x0001) << 4);
403 switch (r)
404 {
405 case 7: /* $hi */
406 case 8: /* $lo */
407 if (!has_mul_div)
20203fb9 408 as_bad (_("$hi and $lo are disabled when MUL and DIV are off"));
280d71bf
DB
409 break;
410 case 12: /* $mb0 */
411 case 13: /* $me0 */
412 case 14: /* $mb1 */
413 case 15: /* $me1 */
414 if (!has_cop)
20203fb9 415 as_bad (_("$mb0, $me0, $mb1, and $me1 are disabled when COP is off"));
280d71bf
DB
416 break;
417 case 24: /* $dbg */
418 case 25: /* $depc */
419 if (!has_debug)
20203fb9 420 as_bad (_("$dbg and $depc are disabled when DEBUG is off"));
280d71bf
DB
421 break;
422 }
423 }
424}
425
426static int
427mep_machine (void)
428{
b899d332 429 switch (MEP_CPU & EF_MEP_CPU_MASK)
280d71bf
DB
430 {
431 default: break;
432 case EF_MEP_CPU_C2: return bfd_mach_mep;
433 case EF_MEP_CPU_C3: return bfd_mach_mep;
434 case EF_MEP_CPU_C4: return bfd_mach_mep;
4d28413b 435 case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
280d71bf
DB
436 case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
437 }
438
439 return bfd_mach_mep;
440}
441
442/* The MeP version of the cgen parse_operand function. The only difference
443 from the standard version is that we want to avoid treating '$foo' and
444 '($foo...)' as references to a symbol called '$foo'. The chances are
33eaf5de 445 that '$foo' is really a misspelled register. */
280d71bf
DB
446
447static const char *
448mep_parse_operand (CGEN_CPU_DESC cd, enum cgen_parse_operand_type want,
449 const char **strP, int opindex, int opinfo,
450 enum cgen_parse_operand_result *resultP, bfd_vma *valueP)
451{
452 if (want == CGEN_PARSE_OPERAND_INTEGER || want == CGEN_PARSE_OPERAND_ADDRESS)
453 {
454 const char *next;
455
456 next = *strP;
457 while (*next == '(')
458 next++;
459 if (*next == '$')
460 return "Not a valid literal";
461 }
462 return gas_cgen_parse_operand (cd, want, strP, opindex, opinfo,
463 resultP, valueP);
464}
465
466void
e6c7cdec 467md_begin (void)
280d71bf
DB
468{
469 /* Initialize the `cgen' interface. */
470
471 /* If the user specifies no options, we default to allowing
472 everything. If the user specifies any enabling options, we
473 default to allowing only what is specified. If the user
474 specifies only disabling options, we only disable what is
475 specified. If the user specifies options and a config, the
476 options modify the config. */
477 if (optbits && mep_config_index == 0)
7ec721f4
DD
478 {
479 MEP_OMASK &= ~OPTION_MASK;
480 MEP_OMASK |= optbits;
481 }
280d71bf
DB
482 else
483 MEP_OMASK = (MEP_OMASK & ~optbitset) | optbits;
484
3526b680
DD
485 mep_cop = mep_config_map[mep_config_index].cpu_flag & EF_MEP_COP_MASK;
486
280d71bf 487 /* Set the machine number and endian. */
6fd9d738 488 gas_cgen_cpu_desc = mep_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0U,
280d71bf
DB
489 CGEN_CPU_OPEN_ENDIAN,
490 target_big_endian
491 ? CGEN_ENDIAN_BIG
492 : CGEN_ENDIAN_LITTLE,
6fd9d738 493 CGEN_CPU_OPEN_ISAS, (CGEN_BITSET *) 0,
280d71bf
DB
494 CGEN_CPU_OPEN_END);
495 mep_cgen_init_asm (gas_cgen_cpu_desc);
496
497 /* This is a callback from cgen to gas to parse operands. */
498 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, mep_parse_operand);
499
500 /* Identify the architecture. */
501 bfd_default_set_arch_mach (stdoutput, bfd_arch_mep, mep_machine ());
502
503 /* Store the configuration number and core. */
504 bfd_set_private_flags (stdoutput, MEP_CPU | MEP_CONFIG | library_flag);
505
506 /* Initialize the array we'll be using to store fixups. */
507 gas_cgen_initialize_saved_fixups_array();
508}
509
3739860c 510/* Variant of mep_cgen_assemble_insn. Assemble insn STR of cpu CD as a
280d71bf
DB
511 coprocessor instruction, if possible, into FIELDS, BUF, and INSN. */
512
513static const CGEN_INSN *
514mep_cgen_assemble_cop_insn (CGEN_CPU_DESC cd,
515 const char *str,
516 CGEN_FIELDS *fields,
517 CGEN_INSN_BYTES_PTR buf,
518 const struct cgen_insn *pinsn)
519{
520 const char *start;
521 CGEN_INSN_LIST *ilist;
522 const char *errmsg = NULL;
523
524 /* The instructions are stored in hashed lists. */
3739860c 525 ilist = CGEN_ASM_LOOKUP_INSN (gas_cgen_cpu_desc,
280d71bf
DB
526 CGEN_INSN_MNEMONIC (pinsn));
527
528 start = str;
529 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
530 {
531 const CGEN_INSN *insn = ilist->insn;
3739860c 532 if (strcmp (CGEN_INSN_MNEMONIC (ilist->insn),
280d71bf
DB
533 CGEN_INSN_MNEMONIC (pinsn)) == 0
534 && MEP_INSN_COP_P (ilist->insn)
535 && mep_cgen_insn_supported (cd, insn))
536 {
537 str = start;
538
539 /* skip this insn if str doesn't look right lexically */
540 if (CGEN_INSN_RX (insn) != NULL &&
541 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
542 continue;
543
544 /* Allow parse/insert handlers to obtain length of insn. */
545 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
546
547 errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
548 if (errmsg != NULL)
549 continue;
3739860c 550
280d71bf
DB
551 errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
552 (bfd_vma) 0);
553 if (errmsg != NULL)
554 continue;
555
556 return insn;
557 }
558 }
559 return pinsn;
560}
561
562static void
563mep_save_insn (mep_insn insn)
564{
565 /* Consider change MAX_SAVED_FIXUP_CHAINS to MAX_PARALLEL_INSNS. */
566 if (num_insns_saved < 0 || num_insns_saved >= MAX_SAVED_FIXUP_CHAINS)
567 {
568 as_fatal("index into saved_insns[] out of bounds.");
569 return;
570 }
571 saved_insns[num_insns_saved] = insn;
572 gas_cgen_save_fixups(num_insns_saved);
573 num_insns_saved++;
574}
575
576static void
577mep_check_parallel32_scheduling (void)
578{
579 int insn0iscopro, insn1iscopro, insn0length, insn1length;
580
581 /* More than two instructions means that either someone is referring to
582 an internally parallel core or an internally parallel coprocessor,
583 neither of which are supported at this time. */
584 if ( num_insns_saved > 2 )
33eaf5de 585 as_fatal("Internally paralleled cores and coprocessors not supported.");
280d71bf
DB
586
587 /* If there are no insns saved, that's ok. Just return. This will
588 happen when mep_process_saved_insns is called when the end of the
589 source file is reached and there are no insns left to be processed. */
590 if (num_insns_saved == 0)
591 return;
592
593 /* Check some of the attributes of the first insn. */
594 insn0iscopro = MEP_INSN_COP_P (saved_insns[0].insn);
595 insn0length = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
596
597 if (num_insns_saved == 2)
598 {
599 /* Check some of the attributes of the first insn. */
600 insn1iscopro = MEP_INSN_COP_P (saved_insns[1].insn);
601 insn1length = CGEN_FIELDS_BITSIZE (& saved_insns[1].fields);
602
603 if ((insn0iscopro && !insn1iscopro)
604 || (insn1iscopro && !insn0iscopro))
605 {
606 /* We have one core and one copro insn. If their sizes
607 add up to 32, then the combination is valid. */
608 if (insn0length + insn1length == 32)
609 return;
610 else
20203fb9 611 as_bad (_("core and copro insn lengths must total 32 bits."));
280d71bf
DB
612 }
613 else
3739860c 614 as_bad (_("vliw group must consist of 1 core and 1 copro insn."));
280d71bf
DB
615 }
616 else
617 {
618 /* If we arrive here, we have one saved instruction. There are a
619 number of possible cases:
620
621 1. The instruction is a 32 bit core or coprocessor insn and
622 can be executed by itself. Valid.
623
33eaf5de 624 2. The instruction is a core instruction for which a cop nop
280d71bf
DB
625 exists. In this case, insert the cop nop into the saved
626 insn array after the core insn and return. Valid.
627
628 3. The instruction is a coprocessor insn for which a core nop
629 exists. In this case, move the coprocessor insn to the
630 second element of the array and put the nop in the first
631 element then return. Valid.
632
633 4. The instruction is a core or coprocessor instruction for
634 which there is no matching coprocessor or core nop to use
635 to form a valid vliw insn combination. In this case, we
636 we have to abort. */
637
638 if (insn0length > 32)
639 as_fatal ("Cannot use 48- or 64-bit insns with a 32 bit datapath.");
640
641 if (insn0length == 32)
642 return;
643
644 /* Insn is smaller than datapath. If there are no matching
645 nops for this insn, then terminate assembly. */
646 if (CGEN_INSN_ATTR_VALUE (saved_insns[0].insn,
647 CGEN_INSN_VLIW32_NO_MATCHING_NOP))
648 as_fatal ("No valid nop.");
649
3739860c
L
650 /* At this point we know that we have a single 16-bit insn that has
651 a matching nop. We have to assemble it and put it into the saved
280d71bf
DB
652 insn and fixup chain arrays. */
653
654 if (insn0iscopro)
655 {
656 char *errmsg;
657 mep_insn insn;
3739860c 658
280d71bf 659 /* Move the insn and it's fixups to the second element of the
33eaf5de 660 saved insns array and insert a 16 bit core nope into the
280d71bf
DB
661 first element. */
662 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "nop",
663 &insn.fields, insn.buffer,
664 &errmsg);
665 if (!insn.insn)
666 {
667 as_bad ("%s", errmsg);
668 return;
669 }
670
671 /* Move the insn in element 0 to element 1 and insert the
672 nop into element 0. Move the fixups in element 0 to
3739860c 673 element 1 and save the current fixups to element 0.
280d71bf
DB
674 Really there aren't any fixups at this point because we're
675 inserting a nop but we might as well be general so that
676 if there's ever a need to insert a general insn, we'll
677 have an example. */
678 saved_insns[1] = saved_insns[0];
679 saved_insns[0] = insn;
680 num_insns_saved++;
681 gas_cgen_swap_fixups (0);
682 gas_cgen_save_fixups (1);
683 }
684 else
685 {
686 char * errmsg;
687 mep_insn insn;
688 int insn_num = saved_insns[0].insn->base->num;
689
690 /* Use 32 bit branches and skip the nop. */
691 if (insn_num == MEP_INSN_BSR12
692 || insn_num == MEP_INSN_BEQZ
693 || insn_num == MEP_INSN_BNEZ)
694 return;
695
696 /* Insert a 16-bit coprocessor nop. Note that at the time */
697 /* this was done, no 16-bit coprocessor nop was defined. */
698 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop16",
699 &insn.fields, insn.buffer,
700 &errmsg);
701 if (!insn.insn)
702 {
703 as_bad ("%s", errmsg);
704 return;
705 }
706
707 /* Now put the insn and fixups into the arrays. */
708 mep_save_insn (insn);
709 }
710 }
711}
712
713static void
714mep_check_parallel64_scheduling (void)
715{
716 int insn0iscopro, insn1iscopro, insn0length, insn1length;
717
718 /* More than two instructions means that someone is referring to an
719 internally parallel core or an internally parallel coprocessor. */
720 /* These are not currently supported. */
721 if (num_insns_saved > 2)
722 as_fatal ("Internally parallel cores of coprocessors not supported.");
723
724 /* If there are no insns saved, that's ok. Just return. This will
725 happen when mep_process_saved_insns is called when the end of the
726 source file is reached and there are no insns left to be processed. */
727 if (num_insns_saved == 0)
728 return;
729
730 /* Check some of the attributes of the first insn. */
731 insn0iscopro = MEP_INSN_COP_P (saved_insns[0].insn);
732 insn0length = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
733
734 if (num_insns_saved == 2)
735 {
736 /* Check some of the attributes of the first insn. */
737 insn1iscopro = MEP_INSN_COP_P (saved_insns[1].insn);
738 insn1length = CGEN_FIELDS_BITSIZE (& saved_insns[1].fields);
739
740 if ((insn0iscopro && !insn1iscopro)
741 || (insn1iscopro && !insn0iscopro))
742 {
743 /* We have one core and one copro insn. If their sizes
744 add up to 64, then the combination is valid. */
745 if (insn0length + insn1length == 64)
746 return;
747 else
20203fb9 748 as_bad (_("core and copro insn lengths must total 64 bits."));
280d71bf
DB
749 }
750 else
20203fb9 751 as_bad (_("vliw group must consist of 1 core and 1 copro insn."));
280d71bf
DB
752 }
753 else
754 {
755 /* If we arrive here, we have one saved instruction. There are a
756 number of possible cases:
757
758 1. The instruction is a 64 bit coprocessor insn and can be
759 executed by itself. Valid.
760
33eaf5de 761 2. The instruction is a core instruction for which a cop nop
280d71bf
DB
762 exists. In this case, insert the cop nop into the saved
763 insn array after the core insn and return. Valid.
764
765 3. The instruction is a coprocessor insn for which a core nop
766 exists. In this case, move the coprocessor insn to the
767 second element of the array and put the nop in the first
768 element then return. Valid.
769
770 4. The instruction is a core or coprocessor instruction for
771 which there is no matching coprocessor or core nop to use
772 to form a valid vliw insn combination. In this case, we
773 we have to abort. */
774
775 /* If the insn is 64 bits long, it can run alone. The size check
33eaf5de 776 is done independently of whether the insn is core or copro
280d71bf
DB
777 in case 64 bit coprocessor insns are added later. */
778 if (insn0length == 64)
779 return;
780
781 /* Insn is smaller than datapath. If there are no matching
782 nops for this insn, then terminate assembly. */
783 if (CGEN_INSN_ATTR_VALUE (saved_insns[0].insn,
784 CGEN_INSN_VLIW64_NO_MATCHING_NOP))
785 as_fatal ("No valid nop.");
786
787 if (insn0iscopro)
788 {
789 char *errmsg;
790 mep_insn insn;
280d71bf
DB
791
792 /* Initialize the insn buffer. */
3526b680 793 memset (insn.buffer, 0, sizeof(insn.buffer));
280d71bf
DB
794
795 /* We have a coprocessor insn. At this point in time there
796 are is 32-bit core nop. There is only a 16-bit core
797 nop. The idea is to allow for a relatively arbitrary
798 coprocessor to be specified. We aren't looking at
799 trying to cover future changes in the core at this time
800 since it is assumed that the core will remain fairly
801 static. If there ever are 32 or 48 bit core nops added,
802 they will require entries below. */
803
804 if (insn0length == 48)
805 {
806 /* Move the insn and fixups to the second element of the
807 arrays then assemble and insert a 16 bit core nop. */
808 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "nop",
809 & insn.fields, insn.buffer,
810 & errmsg);
811 }
812 else
813 {
814 /* If this is reached, then we have a single coprocessor
815 insn that is not 48 bits long, but for which the assembler
816 thinks there is a matching core nop. If a 32-bit core
817 nop has been added, then make the necessary changes and
818 handle its assembly and insertion here. Otherwise,
819 go figure out why either:
3739860c 820
280d71bf
DB
821 1. The assembler thinks that there is a 32-bit core nop
822 to match a 32-bit coprocessor insn, or
823 2. The assembler thinks that there is a 48-bit core nop
824 to match a 16-bit coprocessor insn. */
825
826 as_fatal ("Assembler expects a non-existent core nop.");
827 }
828
829 if (!insn.insn)
830 {
831 as_bad ("%s", errmsg);
832 return;
833 }
834
835 /* Move the insn in element 0 to element 1 and insert the
836 nop into element 0. Move the fixups in element 0 to
3739860c 837 element 1 and save the current fixups to element 0.
280d71bf
DB
838 Really there aren't any fixups at this point because we're
839 inserting a nop but we might as well be general so that
840 if there's ever a need to insert a general insn, we'll
841 have an example. */
842
843 saved_insns[1] = saved_insns[0];
844 saved_insns[0] = insn;
845 num_insns_saved++;
846 gas_cgen_swap_fixups(0);
847 gas_cgen_save_fixups(1);
848
849 }
850 else
851 {
852 char * errmsg;
853 mep_insn insn;
280d71bf
DB
854
855 /* Initialize the insn buffer */
3526b680 856 memset (insn.buffer, 0, sizeof(insn.buffer));
280d71bf
DB
857
858 /* We have a core insn. We have to handle all possible nop
859 lengths. If a coprocessor doesn't have a nop of a certain
860 length but there exists core insns that when combined with
861 a nop of that length would fill the datapath, those core
862 insns will be flagged with the VLIW_NO_CORRESPONDING_NOP
863 attribute. That will ensure that when used in a way that
864 requires a nop to be inserted, assembly will terminate
865 before reaching this section of code. This guarantees
866 that cases below which would result in the attempted
867 insertion of nop that doesn't exist will never be entered. */
868 if (insn0length == 16)
869 {
870 /* Insert 48 bit coprocessor nop. */
871 /* Assemble it and put it into the arrays. */
872 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop48",
873 &insn.fields, insn.buffer,
874 &errmsg);
875 }
876 else if (insn0length == 32)
877 {
878 /* Insert 32 bit coprocessor nop. */
879 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop32",
880 &insn.fields, insn.buffer,
881 &errmsg);
882 }
883 else if (insn0length == 48)
884 {
885 /* Insert 16 bit coprocessor nop. */
886 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop16",
887 &insn.fields, insn.buffer,
888 &errmsg);
889 }
890 else
891 /* Core insn has an invalid length. Something has gone wrong. */
892 as_fatal ("Core insn has invalid length! Something is wrong!");
893
894 if (!insn.insn)
895 {
896 as_bad ("%s", errmsg);
897 return;
898 }
899
900 /* Now put the insn and fixups into the arrays. */
901 mep_save_insn (insn);
902 }
903 }
904}
905
3526b680
DD
906#ifdef MEP_IVC2_SUPPORTED
907
908/* IVC2 packing is different than other VLIW coprocessors. Many of
909 the COP insns can be placed in any of three different types of
910 slots, and each bundle can hold up to three insns - zero or one
911 core insns and one or two IVC2 insns. The insns in CGEN are tagged
912 with which slots they're allowed in, and we have to decide based on
913 that whether or not the user had given us a possible bundling. */
914
915static int
916slot_ok (int idx, int slot)
917{
918 const CGEN_INSN *insn = saved_insns[idx].insn;
919 return CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot);
920}
921
922static void
923mep_check_ivc2_scheduling (void)
924{
925 /* VLIW modes:
926
927 V1 [-----core-----][--------p0s-------][------------p1------------]
928 V2 [-------------core-------------]xxxx[------------p1------------]
929 V3 1111[--p0--]0111[--------p0--------][------------p1------------]
930 */
931
932 int slots[5]; /* Indexed off the SLOTS_ATTR enum. */
3ef23cd4 933 int corelength, realcorelength;
3526b680
DD
934 int i;
935 bfd_byte temp[4];
936 bfd_byte *f;
937 int e = target_big_endian ? 0 : 1;
938
939 /* If there are no insns saved, that's ok. Just return. This will
940 happen when mep_process_saved_insns is called when the end of the
941 source file is reached and there are no insns left to be processed. */
942 if (num_insns_saved == 0)
943 return;
944
945 for (i=0; i<5; i++)
946 slots[i] = -1;
947
948 if (slot_ok (0, SLOTS_CORE))
949 {
950 slots[SLOTS_CORE] = 0;
3ef23cd4
DD
951 realcorelength = corelength = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
952
953 /* If we encounter one of these, it may get relaxed later into a
954 longer instruction. We can't just push the other opcodes
955 away, the bigger insn has to fit into the existing slot. So,
956 we make room for the relaxed instruction here. */
957
958 if (saved_insns[0].insn->base->num == MEP_INSN_BSR12
959 || saved_insns[0].insn->base->num == MEP_INSN_BRA)
960 corelength = 32;
3526b680
DD
961 }
962 else
3ef23cd4 963 realcorelength = corelength = 0;
3526b680
DD
964
965 if (corelength == 16)
966 {
967 /* V1 mode: we need a P0S slot and a P1 slot. */
968 switch (num_insns_saved)
969 {
970 case 1:
971 /* No other insns, fill with NOPs. */
972 break;
973
974 case 2:
975 if (slot_ok (1, SLOTS_P1))
976 slots[SLOTS_P1] = 1;
977 else if (slot_ok (1, SLOTS_P0S))
978 slots[SLOTS_P0S] = 1;
979 else
20203fb9 980 as_bad (_("cannot pack %s with a 16-bit insn"),
3526b680
DD
981 CGEN_INSN_NAME (saved_insns[1].insn));
982 break;
983
984 case 3:
985 if (slot_ok (1, SLOTS_P0S)
986 && slot_ok (2, SLOTS_P1))
987 {
988 slots[SLOTS_P0S] = 1;
989 slots[SLOTS_P1] = 2;
990 }
991 else if (slot_ok (1, SLOTS_P1)
992 && slot_ok (2, SLOTS_P0S))
993 {
994 slots[SLOTS_P1] = 1;
995 slots[SLOTS_P0S] = 2;
996 }
997 else
20203fb9 998 as_bad (_("cannot pack %s and %s together with a 16-bit insn"),
3526b680
DD
999 CGEN_INSN_NAME (saved_insns[1].insn),
1000 CGEN_INSN_NAME (saved_insns[2].insn));
1001 break;
1002
1003 default:
20203fb9 1004 as_bad (_("too many IVC2 insns to pack with a 16-bit core insn"));
3526b680
DD
1005 break;
1006 }
1007 }
1008 else if (corelength == 32)
1009 {
1010 /* V2 mode: we need a P1 slot. */
1011 switch (num_insns_saved)
1012 {
1013 case 1:
1014 /* No other insns, fill with NOPs. */
1015 break;
1016 case 2:
1017 /* The other insn must allow P1. */
1018 if (!slot_ok (1, SLOTS_P1))
20203fb9 1019 as_bad (_("cannot pack %s into slot P1"),
3526b680
DD
1020 CGEN_INSN_NAME (saved_insns[1].insn));
1021 else
1022 slots[SLOTS_P1] = 1;
1023 break;
1024 default:
20203fb9 1025 as_bad (_("too many IVC2 insns to pack with a 32-bit core insn"));
3526b680
DD
1026 break;
1027 }
1028 }
1029 else if (corelength == 0)
1030 {
1031 /* V3 mode: we need a P0 slot and a P1 slot, or a P0S+P1 with a
1032 core NOP. */
1033 switch (num_insns_saved)
1034 {
1035 case 1:
1036 if (slot_ok (0, SLOTS_P0))
1037 slots[SLOTS_P0] = 0;
1038 else if (slot_ok (0, SLOTS_P1))
1039 slots[SLOTS_P1] = 0;
1040 else if (slot_ok (0, SLOTS_P0S))
1041 slots[SLOTS_P0S] = 0;
1042 else
20203fb9 1043 as_bad (_("unable to pack %s by itself?"),
3526b680
DD
1044 CGEN_INSN_NAME (saved_insns[0].insn));
1045 break;
1046
1047 case 2:
1048 if (slot_ok (0, SLOTS_P0)
1049 && slot_ok (1, SLOTS_P1))
1050 {
1051 slots[SLOTS_P0] = 0;
1052 slots[SLOTS_P1] = 1;
1053 }
1054 else if (slot_ok (0, SLOTS_P1)
1055 && slot_ok (1, SLOTS_P0))
1056 {
1057 slots[SLOTS_P1] = 0;
1058 slots[SLOTS_P0] = 1;
1059 }
1060 else if (slot_ok (0, SLOTS_P0S)
1061 && slot_ok (1, SLOTS_P1))
1062 {
1063 slots[SLOTS_P0S] = 0;
1064 slots[SLOTS_P1] = 1;
1065 }
1066 else if (slot_ok (0, SLOTS_P1)
1067 && slot_ok (1, SLOTS_P0S))
1068 {
1069 slots[SLOTS_P1] = 0;
1070 slots[SLOTS_P0S] = 1;
1071 }
1072 else
20203fb9 1073 as_bad (_("cannot pack %s and %s together"),
3526b680
DD
1074 CGEN_INSN_NAME (saved_insns[0].insn),
1075 CGEN_INSN_NAME (saved_insns[1].insn));
1076 break;
1077
1078 default:
20203fb9 1079 as_bad (_("too many IVC2 insns to pack together"));
3526b680
DD
1080 break;
1081 }
1082 }
1083
1084 /* The core insn needs to be done normally so that fixups,
1085 relaxation, etc are done. Other IVC2 insns need only be resolved
1086 to bit patterns; there are no relocations for them. */
1087 if (slots[SLOTS_CORE] != -1)
1088 {
1089 gas_cgen_restore_fixups (0);
1090 gas_cgen_finish_insn (saved_insns[0].insn, saved_insns[0].buffer,
1091 CGEN_FIELDS_BITSIZE (& saved_insns[0].fields),
1092 1, NULL);
1093 }
1094
1095 /* Allocate whatever bytes remain in our insn word. Adjust the
1096 pointer to point (as if it were) to the beginning of the whole
1097 word, so that we don't have to adjust for it elsewhere. */
3ef23cd4 1098 f = (bfd_byte *) frag_more (8 - realcorelength / 8);
3526b680 1099 /* Unused slots are filled with NOPs, which happen to be all zeros. */
3ef23cd4
DD
1100 memset (f, 0, 8 - realcorelength / 8);
1101 f -= realcorelength / 8;
3526b680
DD
1102
1103 for (i=1; i<5; i++)
1104 {
1105 mep_insn *m;
1106
1107 if (slots[i] == -1)
1108 continue;
1109
1110 m = & saved_insns[slots[i]];
1111
1112#if CGEN_INT_INSN_P
1113 cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) temp, 32,
e9bffec9 1114 m->buffer[0], gas_cgen_cpu_desc->insn_endian);
3526b680
DD
1115#else
1116 memcpy (temp, m->buffer, byte_len);
1117#endif
1118
1119 switch (i)
1120 {
1121 case SLOTS_P0S:
1122 f[2^e] = temp[1^e];
1123 f[3^e] = temp[2^e];
1124 f[4^e] |= temp[3^e] & 0xf0;
1125 break;
1126 case SLOTS_P0:
1127 f[0^e] = 0xf0 | temp[0^e] >> 4;
1128 f[1^e] = temp[0^e] << 4 | 0x07;
1129 f[2^e] = temp[1^e];
1130 f[3^e] = temp[2^e];
1131 f[4^e] |= temp[3^e] & 0xf0;
1132 break;
1133 case SLOTS_P1:
1134 f[4^e] |= temp[0^e] >> 4;
1135 f[5^e] = temp[0^e] << 4 | temp[1^e] >> 4;
1136 f[6^e] = temp[1^e] << 4 | temp[2^e] >> 4;
1137 f[7^e] = temp[2^e] << 4 | temp[3^e] >> 4;
1138 break;
1139 default:
1140 break;
1141 }
1142 }
1143}
1144
1145#endif /* MEP_IVC2_SUPPORTED */
1146
280d71bf 1147/* The scheduling functions are just filters for invalid combinations.
33eaf5de 1148 If there is a violation, they terminate assembly. Otherwise they
2b0f3761 1149 just fall through. Successful combinations cause no side effects
280d71bf
DB
1150 other than valid nop insertion. */
1151
1152static void
1153mep_check_parallel_scheduling (void)
1154{
1155 /* This is where we will eventually read the config information
3739860c 1156 and choose which scheduling checking function to call. */
3526b680
DD
1157#ifdef MEP_IVC2_SUPPORTED
1158 if (mep_cop == EF_MEP_COP_IVC2)
1159 mep_check_ivc2_scheduling ();
1160 else
1161#endif /* MEP_IVC2_SUPPORTED */
1162 if (MEP_VLIW64)
280d71bf
DB
1163 mep_check_parallel64_scheduling ();
1164 else
1165 mep_check_parallel32_scheduling ();
1166}
1167
1168static void
1169mep_process_saved_insns (void)
1170{
1171 int i;
1172
1173 gas_cgen_save_fixups (MAX_SAVED_FIXUP_CHAINS - 1);
1174
1175 /* We have to check for valid scheduling here. */
1176 mep_check_parallel_scheduling ();
1177
3526b680
DD
1178 /* IVC2 has to pack instructions in a funny way, so it does it
1179 itself. */
1180 if (mep_cop != EF_MEP_COP_IVC2)
280d71bf 1181 {
3526b680
DD
1182 /* If the last call didn't cause assembly to terminate, we have
1183 a valid vliw insn/insn pair saved. Restore this instructions'
1184 fixups and process the insns. */
1185 for (i = 0;i<num_insns_saved;i++)
1186 {
1187 gas_cgen_restore_fixups (i);
1188 gas_cgen_finish_insn (saved_insns[i].insn, saved_insns[i].buffer,
1189 CGEN_FIELDS_BITSIZE (& saved_insns[i].fields),
1190 1, NULL);
3526b680 1191 }
280d71bf
DB
1192 }
1193 gas_cgen_restore_fixups (MAX_SAVED_FIXUP_CHAINS - 1);
1194
1195 /* Clear the fixups and reset the number insn saved to 0. */
1196 gas_cgen_initialize_saved_fixups_array ();
1197 num_insns_saved = 0;
1198 listing_prev_line ();
1199}
1200
1201void
1202md_assemble (char * str)
1203{
1204 static CGEN_BITSET* isas = NULL;
1205 char * errmsg;
1206
1207 /* Initialize GAS's cgen interface for a new instruction. */
1208 gas_cgen_init_parse ();
1209
1210 /* There are two possible modes: core and vliw. We have to assemble
1211 differently for each.
1212
1213 Core Mode: We assemble normally. All instructions are on a
1214 single line and are made up of one mnemonic and one
1215 set of operands.
1216 VLIW Mode: Vliw combinations are indicated as follows:
1217
1218 core insn
1219 + copro insn
1220
1221 We want to handle the general case where more than
2b0f3761 1222 one instruction can be preceded by a +. This will
280d71bf
DB
1223 happen later if we add support for internally parallel
1224 coprocessors. We'll make the parsing nice and general
1225 so that it can handle an arbitrary number of insns
1226 with leading +'s. The actual checking for valid
1227 combinations is done elsewhere. */
1228
1229 /* Initialize the isa to refer to the core. */
1230 if (isas == NULL)
1231 isas = cgen_bitset_copy (& MEP_CORE_ISA);
1232 else
1233 {
1234 cgen_bitset_clear (isas);
1235 cgen_bitset_union (isas, & MEP_CORE_ISA, isas);
1236 }
1237 gas_cgen_cpu_desc->isas = isas;
1238
1239 if (mode == VLIW)
1240 {
1241 /* VLIW mode. */
1242
1243 int thisInsnIsCopro = 0;
1244 mep_insn insn;
1245 int i;
3739860c 1246
280d71bf 1247 /* Initialize the insn buffer */
3739860c 1248
280d71bf
DB
1249 if (! CGEN_INT_INSN_P)
1250 for (i=0; i < CGEN_MAX_INSN_SIZE; i++)
1251 insn.buffer[i]='\0';
1252
3526b680
DD
1253
1254 /* IVC2 has two sets of coprocessor opcodes, one for CORE mode
1255 and one for VLIW mode. They have the same names. To specify
1256 which one we want, we use the COP isas - the 32 bit ISA is
1257 for the core instructions (which are always 32 bits), and the
1258 other ISAs are for the VLIW ones (which always pack into 64
1259 bit insns). We use other attributes to determine slotting
1260 later. */
1261 if (mep_cop == EF_MEP_COP_IVC2)
1262 {
1263 cgen_bitset_union (isas, & MEP_COP16_ISA, isas);
1264 cgen_bitset_union (isas, & MEP_COP48_ISA, isas);
1265 cgen_bitset_union (isas, & MEP_COP64_ISA, isas);
1266 }
1267 else
1268 {
1269 /* Can't tell core / copro insns apart at parse time! */
1270 cgen_bitset_union (isas, & MEP_COP_ISA, isas);
1271 }
280d71bf
DB
1272
1273 /* Assemble the insn so we can examine its attributes. */
1274 insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, str,
1275 &insn.fields, insn.buffer,
1276 &errmsg);
1277 if (!insn.insn)
1278 {
1279 as_bad ("%s", errmsg);
1280 return;
1281 }
1282 mep_check_for_disabled_registers (&insn);
1283
1284 /* Check to see if it's a coprocessor instruction. */
1285 thisInsnIsCopro = MEP_INSN_COP_P (insn.insn);
1286
1287 if (!thisInsnIsCopro)
1288 {
1289 insn.insn = mep_cgen_assemble_cop_insn (gas_cgen_cpu_desc, str,
1290 &insn.fields, insn.buffer,
1291 insn.insn);
1292 thisInsnIsCopro = MEP_INSN_COP_P (insn.insn);
1293 mep_check_for_disabled_registers (&insn);
1294 }
1295
1296 if (pluspresent)
1297 {
1298 /* A plus was present. */
1299 /* Check for a + with a core insn and abort if found. */
1300 if (!thisInsnIsCopro)
1301 {
2b0f3761 1302 as_fatal("A core insn cannot be preceded by a +.\n");
280d71bf
DB
1303 return;
1304 }
1305
1306 if (num_insns_saved > 0)
1307 {
1308 /* There are insns in the queue. Add this one. */
1309 mep_save_insn (insn);
1310 }
1311 else
1312 {
1313 /* There are no insns in the queue and a plus is present.
1314 This is a syntax error. Let's not tolerate this.
1315 We can relax this later if necessary. */
1316 as_bad (_("Invalid use of parallelization operator."));
1317 return;
1318 }
1319 }
1320 else
1321 {
1322 /* No plus was present. */
1323 if (num_insns_saved > 0)
1324 {
1325 /* There are insns saved and we came across an insn without a
1326 leading +. That's the signal to process the saved insns
1327 before proceeding then treat the current insn as the first
1328 in a new vliw group. */
1329 mep_process_saved_insns ();
1330 num_insns_saved = 0;
1331 /* mep_save_insn (insn); */
1332 }
1333 mep_save_insn (insn);
1334#if 0
1335 else
1336 {
1337
1338 /* Core Insn. Add it to the beginning of the queue. */
1339 mep_save_insn (insn);
1340 /* gas_cgen_save_fixups(num_insns_saved); */
1341 }
1342#endif
1343 }
1344
1345 pluspresent = 0;
1346 }
1347 else
1348 {
1349 /* Core mode. */
1350
1351 /* Only single instructions are assembled in core mode. */
1352 mep_insn insn;
1353
3526b680
DD
1354 /* See comment in the VLIW clause above about this. */
1355 if (mep_cop & EF_MEP_COP_IVC2)
1356 cgen_bitset_union (isas, & MEP_COP32_ISA, isas);
1357
280d71bf
DB
1358 /* If a leading '+' was present, issue an error.
1359 That's not allowed in core mode. */
1360 if (pluspresent)
1361 {
1362 as_bad (_("Leading plus sign not allowed in core mode"));
1363 return;
1364 }
1365
1366 insn.insn = mep_cgen_assemble_insn
1367 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
1368
1369 if (!insn.insn)
1370 {
1371 as_bad ("%s", errmsg);
1372 return;
1373 }
1374 gas_cgen_finish_insn (insn.insn, insn.buffer,
1375 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
1376 mep_check_for_disabled_registers (&insn);
1377 }
1378}
1379
1380valueT
1381md_section_align (segT segment, valueT size)
1382{
fd361982 1383 int align = bfd_section_alignment (segment);
8d3842cd 1384 return ((size + (1 << align) - 1) & -(1 << align));
280d71bf
DB
1385}
1386
1387
1388symbolS *
1389md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1390{
1391 return 0;
1392}
1393\f
1394/* Interface to relax_segment. */
1395
1396
1397const relax_typeS md_relax_table[] =
1398{
1399 /* The fields are:
1400 1) most positive reach of this state,
1401 2) most negative reach of this state,
1402 3) how many bytes this mode will have in the variable part of the frag
1403 4) which index into the table to try if we can't fit into this one. */
1404 /* Note that we use "beq" because "jmp" has a peculiarity - it cannot
1405 jump to addresses with any bits 27..24 set. So, we use beq as a
1406 17-bit pc-relative branch to avoid using jmp, just in case. */
1407
1408 /* 0 */ { 0, 0, 0, 0 }, /* unused */
1409 /* 1 */ { 0, 0, 0, 0 }, /* marker for "don't know yet" */
1410
1411 /* 2 */ { 2047, -2048, 0, 3 }, /* bsr12 */
1412 /* 3 */ { 0, 0, 2, 0 }, /* bsr16 */
1413
1414 /* 4 */ { 2047, -2048, 0, 5 }, /* bra */
1415 /* 5 */ { 65535, -65536, 2, 6 }, /* beq $0,$0 */
1416 /* 6 */ { 0, 0, 2, 0 }, /* jmp24 */
1417
1418 /* 7 */ { 65535, -65536, 0, 8 }, /* beqi */
1419 /* 8 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1420
1421 /* 9 */ { 127, -128, 0, 10 }, /* beqz */
1422 /* 10 */ { 65535, -65536, 2, 11 }, /* beqi */
1423 /* 11 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1424
1425 /* 12 */ { 65535, -65536, 0, 13 }, /* bnei */
1426 /* 13 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1427
1428 /* 14 */ { 127, -128, 0, 15 }, /* bnez */
1429 /* 15 */ { 65535, -65536, 2, 16 }, /* bnei */
1430 /* 16 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1431
1432 /* 17 */ { 65535, -65536, 0, 13 }, /* bgei */
1433 /* 18 */ { 0, 0, 4, 0 },
1434 /* 19 */ { 65535, -65536, 0, 13 }, /* blti */
1435 /* 20 */ { 0, 0, 4, 0 },
1436 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpeq */
1437 /* 20 */ { 0, 0, 4, 0 },
1438 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpne */
1439 /* 20 */ { 0, 0, 4, 0 },
1440 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpat */
1441 /* 20 */ { 0, 0, 4, 0 },
1442 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpaf */
1443 /* 20 */ { 0, 0, 4, 0 }
1444};
1445
1446/* Pseudo-values for 64 bit "insns" which are combinations of two 32
1447 bit insns. */
1448typedef enum {
1449 MEP_PSEUDO64_NONE,
1450 MEP_PSEUDO64_16BITCC,
1451 MEP_PSEUDO64_32BITCC,
1452} MepPseudo64Values;
1453
1454static struct {
1455 int insn;
1456 int growth;
1457 int insn_for_extern;
1458} subtype_mappings[] = {
1459 { 0, 0, 0 },
1460 { 0, 0, 0 },
1461 { MEP_INSN_BSR12, 0, MEP_INSN_BSR24 },
1462 { MEP_INSN_BSR24, 2, MEP_INSN_BSR24 },
1463 { MEP_INSN_BRA, 0, MEP_INSN_BRA },
1464 { MEP_INSN_BEQ, 2, MEP_INSN_BEQ },
1465 { MEP_INSN_JMP, 2, MEP_INSN_JMP },
1466 { MEP_INSN_BEQI, 0, MEP_INSN_BEQI },
1467 { -1, 4, MEP_PSEUDO64_32BITCC },
1468 { MEP_INSN_BEQZ, 0, MEP_INSN_BEQZ },
1469 { MEP_INSN_BEQI, 2, MEP_INSN_BEQI },
1470 { -1, 4, MEP_PSEUDO64_16BITCC },
1471 { MEP_INSN_BNEI, 0, MEP_INSN_BNEI },
1472 { -1, 4, MEP_PSEUDO64_32BITCC },
1473 { MEP_INSN_BNEZ, 0, MEP_INSN_BNEZ },
1474 { MEP_INSN_BNEI, 2, MEP_INSN_BNEI },
1475 { -1, 4, MEP_PSEUDO64_16BITCC },
1476 { MEP_INSN_BGEI, 0, MEP_INSN_BGEI },
1477 { -1, 4, MEP_PSEUDO64_32BITCC },
1478 { MEP_INSN_BLTI, 0, MEP_INSN_BLTI },
1479 { -1, 4, MEP_PSEUDO64_32BITCC },
1480 { MEP_INSN_BCPEQ, 0, MEP_INSN_BCPEQ },
1481 { -1, 4, MEP_PSEUDO64_32BITCC },
1482 { MEP_INSN_BCPNE, 0, MEP_INSN_BCPNE },
1483 { -1, 4, MEP_PSEUDO64_32BITCC },
1484 { MEP_INSN_BCPAT, 0, MEP_INSN_BCPAT },
1485 { -1, 4, MEP_PSEUDO64_32BITCC },
1486 { MEP_INSN_BCPAF, 0, MEP_INSN_BCPAF },
1487 { -1, 4, MEP_PSEUDO64_32BITCC }
1488};
1489#define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
1490
1491void
1492mep_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
1493{
1494 symbolS *symbolP = fragP->fr_symbol;
1495 if (symbolP && !S_IS_DEFINED (symbolP))
1496 *aim = 0;
1497 /* Adjust for MeP pcrel not being relative to the next opcode. */
1498 *aim += 2 + md_relax_table[this_state].rlx_length;
1499}
1500
1501static int
1502insn_to_subtype (int insn)
1503{
1504 unsigned int i;
1505 for (i=0; i<NUM_MAPPINGS; i++)
1506 if (insn == subtype_mappings[i].insn)
1507 return i;
1508 abort ();
1509}
1510
1511/* Return an initial guess of the length by which a fragment must grow
1512 to hold a branch to reach its destination. Also updates fr_type
1513 and fr_subtype as necessary.
1514
1515 Called just before doing relaxation. Any symbol that is now
1516 undefined will not become defined. The guess for fr_var is
1517 ACTUALLY the growth beyond fr_fix. Whatever we do to grow fr_fix
1518 or fr_var contributes to our returned value. Although it may not
1519 be explicit in the frag, pretend fr_var starts with a 0 value. */
1520
1521int
1522md_estimate_size_before_relax (fragS * fragP, segT segment)
1523{
1524 if (fragP->fr_subtype == 1)
1525 fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num);
1526
3ef23cd4 1527 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
85143216 1528 || S_IS_WEAK (fragP->fr_symbol)
3ef23cd4
DD
1529#ifdef MEP_IVC2_SUPPORTED
1530 || (mep_cop == EF_MEP_COP_IVC2
fd361982 1531 && bfd_section_flags (segment) & SEC_MEP_VLIW)
3ef23cd4
DD
1532#endif /* MEP_IVC2_SUPPORTED */
1533 )
280d71bf
DB
1534 {
1535 int new_insn;
1536
1537 new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
1538 fragP->fr_subtype = insn_to_subtype (new_insn);
1539 }
1540
1541 if (MEP_VLIW && ! MEP_VLIW64
fd361982 1542 && (bfd_section_flags (segment) & SEC_MEP_VLIW))
280d71bf
DB
1543 {
1544 /* Use 32 bit branches for vliw32 so the vliw word is not split. */
1545 switch (fragP->fr_cgen.insn->base->num)
1546 {
1547 case MEP_INSN_BSR12:
3739860c 1548 fragP->fr_subtype = insn_to_subtype
280d71bf
DB
1549 (subtype_mappings[fragP->fr_subtype].insn_for_extern);
1550 break;
1551 case MEP_INSN_BEQZ:
1552 fragP->fr_subtype ++;
1553 break;
1554 case MEP_INSN_BNEZ:
1555 fragP->fr_subtype ++;
1556 break;
1557 }
1558 }
1559
1560 if (fragP->fr_cgen.insn->base
1561 && fragP->fr_cgen.insn->base->num
1562 != subtype_mappings[fragP->fr_subtype].insn)
1563 {
1564 int new_insn= subtype_mappings[fragP->fr_subtype].insn;
1565 if (new_insn != -1)
1566 {
1567 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
1568 - fragP->fr_cgen.insn->base->num
1569 + new_insn);
1570 }
1571 }
1572
3ef23cd4
DD
1573#ifdef MEP_IVC2_SUPPORTED
1574 if (mep_cop == EF_MEP_COP_IVC2
fd361982 1575 && bfd_section_flags (segment) & SEC_MEP_VLIW)
3ef23cd4
DD
1576 return 0;
1577#endif /* MEP_IVC2_SUPPORTED */
1578
280d71bf
DB
1579 return subtype_mappings[fragP->fr_subtype].growth;
1580}
1581
3ef23cd4
DD
1582/* VLIW does relaxing, but not growth. */
1583
1584long
1585mep_relax_frag (segT segment, fragS *fragP, long stretch)
1586{
1587 long rv = relax_frag (segment, fragP, stretch);
1588#ifdef MEP_IVC2_SUPPORTED
1589 if (mep_cop == EF_MEP_COP_IVC2
fd361982 1590 && bfd_section_flags (segment) & SEC_MEP_VLIW)
3ef23cd4
DD
1591 return 0;
1592#endif
1593 return rv;
1594}
1595
280d71bf
DB
1596/* *fragP has been relaxed to its final size, and now needs to have
1597 the bytes inside it modified to conform to the new size.
1598
1599 Called after relaxation is finished.
1600 fragP->fr_type == rs_machine_dependent.
1601 fragP->fr_subtype is the subtype of what the address relaxed to. */
1602
1603static int
1604target_address_for (fragS *frag)
1605{
1606 int rv = frag->fr_offset;
1607 symbolS *sym = frag->fr_symbol;
1608
1609 if (sym)
1610 rv += S_GET_VALUE (sym);
1611
1612 return rv;
1613}
1614
1615void
3739860c 1616md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3ef23cd4 1617 segT seg ATTRIBUTE_UNUSED,
280d71bf
DB
1618 fragS *fragP)
1619{
7a5dd76f 1620 uint32_t addend, rn, bit = 0;
280d71bf
DB
1621 int operand;
1622 int where = fragP->fr_opcode - fragP->fr_literal;
1623 int e = target_big_endian ? 0 : 1;
3ef23cd4
DD
1624 int core_mode;
1625
1626#ifdef MEP_IVC2_SUPPORTED
fd361982 1627 if (bfd_section_flags (seg) & SEC_MEP_VLIW
3ef23cd4
DD
1628 && mep_cop == EF_MEP_COP_IVC2)
1629 core_mode = 0;
1630 else
1631#endif /* MEP_IVC2_SUPPORTED */
1632 core_mode = 1;
280d71bf
DB
1633
1634 addend = target_address_for (fragP) - (fragP->fr_address + where);
1635
1636 if (subtype_mappings[fragP->fr_subtype].insn == -1)
1637 {
3ef23cd4
DD
1638 if (core_mode)
1639 fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
280d71bf
DB
1640 switch (subtype_mappings[fragP->fr_subtype].insn_for_extern)
1641 {
1642 case MEP_PSEUDO64_16BITCC:
1643 fragP->fr_opcode[1^e] = ((fragP->fr_opcode[1^e] & 1) ^ 1) | 0x06;
1644 fragP->fr_opcode[2^e] = 0xd8;
1645 fragP->fr_opcode[3^e] = 0x08;
1646 fragP->fr_opcode[4^e] = 0;
1647 fragP->fr_opcode[5^e] = 0;
1648 where += 2;
1649 break;
1650 case MEP_PSEUDO64_32BITCC:
1651 if (fragP->fr_opcode[0^e] & 0x10)
1652 fragP->fr_opcode[1^e] ^= 0x01;
1653 else
1654 fragP->fr_opcode[1^e] ^= 0x04;
1655 fragP->fr_opcode[2^e] = 0;
1656 fragP->fr_opcode[3^e] = 4;
1657 fragP->fr_opcode[4^e] = 0xd8;
1658 fragP->fr_opcode[5^e] = 0x08;
1659 fragP->fr_opcode[6^e] = 0;
1660 fragP->fr_opcode[7^e] = 0;
1661 where += 4;
1662 break;
1663 default:
1664 abort ();
1665 }
1666 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
1667 - fragP->fr_cgen.insn->base->num
1668 + MEP_INSN_JMP);
1669 operand = MEP_OPERAND_PCABS24A2;
1670 }
1671 else
1672 switch (fragP->fr_cgen.insn->base->num)
1673 {
1674 case MEP_INSN_BSR12:
1675 fragP->fr_opcode[0^e] = 0xb0 | ((addend >> 8) & 0x0f);
1676 fragP->fr_opcode[1^e] = 0x01 | (addend & 0xfe);
1677 operand = MEP_OPERAND_PCREL12A2;
1678 break;
1679
1680 case MEP_INSN_BSR24:
3ef23cd4
DD
1681 if (core_mode)
1682 fragP->fr_fix += 2;
280d71bf
DB
1683 fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
1684 fragP->fr_opcode[1^e] = 0x09 | ((addend << 3) & 0xf0);
1685 fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
1686 fragP->fr_opcode[3^e] = 0x00 | ((addend >> 8) & 0xff);
1687 operand = MEP_OPERAND_PCREL24A2;
1688 break;
1689
1690 case MEP_INSN_BRA:
1691 fragP->fr_opcode[0^e] = 0xb0 | ((addend >> 8) & 0x0f);
1692 fragP->fr_opcode[1^e] = 0x00 | (addend & 0xfe);
1693 operand = MEP_OPERAND_PCREL12A2;
1694 break;
1695
1696 case MEP_INSN_BEQ:
1697 /* The default relax_frag doesn't change the state if there is no
1698 growth, so we must manually handle converting out-of-range BEQ
1699 instructions to JMP. */
7a5dd76f 1700 if (addend + 65536 < 131071)
280d71bf 1701 {
3ef23cd4
DD
1702 if (core_mode)
1703 fragP->fr_fix += 2;
280d71bf
DB
1704 fragP->fr_opcode[0^e] = 0xe0;
1705 fragP->fr_opcode[1^e] = 0x01;
1706 fragP->fr_opcode[2^e] = 0x00 | ((addend >> 9) & 0xff);
1707 fragP->fr_opcode[3^e] = 0x00 | ((addend >> 1) & 0xff);
1708 operand = MEP_OPERAND_PCREL17A2;
1709 break;
1710 }
1a0670f3 1711 /* Fall through. */
280d71bf
DB
1712
1713 case MEP_INSN_JMP:
1714 addend = target_address_for (fragP);
3ef23cd4
DD
1715 if (core_mode)
1716 fragP->fr_fix += 2;
280d71bf
DB
1717 fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
1718 fragP->fr_opcode[1^e] = 0x08 | ((addend << 3) & 0xf0);
1719 fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
1720 fragP->fr_opcode[3^e] = 0x00 | ((addend >> 8) & 0xff);
1721 operand = MEP_OPERAND_PCABS24A2;
1722 break;
1723
1724 case MEP_INSN_BNEZ:
1725 bit = 1;
1a0670f3 1726 /* Fall through. */
280d71bf
DB
1727 case MEP_INSN_BEQZ:
1728 fragP->fr_opcode[1^e] = bit | (addend & 0xfe);
1729 operand = MEP_OPERAND_PCREL8A2;
1730 break;
1731
1732 case MEP_INSN_BNEI:
1733 bit = 4;
1a0670f3 1734 /* Fall through. */
280d71bf
DB
1735 case MEP_INSN_BEQI:
1736 if (subtype_mappings[fragP->fr_subtype].growth)
1737 {
3ef23cd4
DD
1738 if (core_mode)
1739 fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
280d71bf
DB
1740 rn = fragP->fr_opcode[0^e] & 0x0f;
1741 fragP->fr_opcode[0^e] = 0xe0 | rn;
1742 fragP->fr_opcode[1^e] = bit;
1743 }
1744 fragP->fr_opcode[2^e] = 0x00 | ((addend >> 9) & 0xff);
1745 fragP->fr_opcode[3^e] = 0x00 | ((addend >> 1) & 0xff);
1746 operand = MEP_OPERAND_PCREL17A2;
1747 break;
1748
1749 case MEP_INSN_BLTI:
1750 case MEP_INSN_BGEI:
1751 case MEP_INSN_BCPEQ:
1752 case MEP_INSN_BCPNE:
1753 case MEP_INSN_BCPAT:
1754 case MEP_INSN_BCPAF:
1755 /* No opcode change needed, just operand. */
1756 fragP->fr_opcode[2^e] = (addend >> 9) & 0xff;
1757 fragP->fr_opcode[3^e] = (addend >> 1) & 0xff;
1758 operand = MEP_OPERAND_PCREL17A2;
1759 break;
1760
1761 default:
1762 abort ();
1763 }
1764
3ef23cd4 1765 if (S_GET_SEGMENT (fragP->fr_symbol) != seg
85143216 1766 || S_IS_WEAK (fragP->fr_symbol)
280d71bf
DB
1767 || operand == MEP_OPERAND_PCABS24A2)
1768 {
9c2799c2 1769 gas_assert (fragP->fr_cgen.insn != 0);
280d71bf
DB
1770 gas_cgen_record_fixup (fragP,
1771 where,
1772 fragP->fr_cgen.insn,
1773 (fragP->fr_fix - where) * 8,
1774 cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
1775 operand),
1776 fragP->fr_cgen.opinfo,
1777 fragP->fr_symbol, fragP->fr_offset);
1778 }
1779}
1780
1781\f
1782/* Functions concerning relocs. */
1783
1784void
1785mep_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1786{
1787 /* If we already know the fixup value, adjust it in the same
1788 way that the linker would have done. */
1789 if (fixP->fx_addsy == 0)
1790 switch (fixP->fx_cgen.opinfo)
1791 {
1792 case BFD_RELOC_MEP_LOW16:
4f7cc141 1793 *valP = ((*valP & 0xffff) ^ 0x8000) - 0x8000;
280d71bf
DB
1794 break;
1795 case BFD_RELOC_MEP_HI16U:
1796 *valP >>= 16;
1797 break;
1798 case BFD_RELOC_MEP_HI16S:
1799 *valP = (*valP + 0x8000) >> 16;
1800 break;
1801 }
1802
33eaf5de 1803 /* Now call cgen's md_apply_fix. */
280d71bf
DB
1804 gas_cgen_md_apply_fix (fixP, valP, seg);
1805}
1806
1807long
1808md_pcrel_from_section (fixS *fixP, segT sec)
1809{
1810 if (fixP->fx_addsy != (symbolS *) NULL
1811 && (! S_IS_DEFINED (fixP->fx_addsy)
85143216 1812 || S_IS_WEAK (fixP->fx_addsy)
280d71bf
DB
1813 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1814 /* The symbol is undefined (or is defined but not in this section).
1815 Let the linker figure it out. */
1816 return 0;
1817
4e7defc1
DD
1818 /* If we've got other reasons for emitting this relocation, let the
1819 linker handle pc-rel also. */
1820 if (mep_force_relocation (fixP))
1821 return 0;
1822
280d71bf
DB
1823 /* Return the address of the opcode - cgen adjusts for opcode size
1824 itself, to be consistent with the disassembler, which must do
1825 so. */
1826 return fixP->fx_where + fixP->fx_frag->fr_address;
1827}
1828
1829/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
1830 Returns BFD_RELOC_NONE if no reloc type can be found.
1831 *FIXP may be modified if desired. */
1832
1833#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
1834#define MAP(n) case MEP_OPERAND_##n: return BFD_RELOC_MEP_##n;
1835#else
1836#define MAP(n) case MEP_OPERAND_/**/n: return BFD_RELOC_MEP_/**/n;
1837#endif
1838
1839bfd_reloc_code_real_type
1840md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
1841 const CGEN_OPERAND *operand,
1842 fixS *fixP)
1843{
1844 enum bfd_reloc_code_real reloc = fixP->fx_cgen.opinfo;
1845 static char printed[MEP_OPERAND_MAX] = { 0 };
1846
1847 /* If there's a reloc here, it's because the parser saw a %foo() and
1848 is giving us the correct reloc to use, or because we converted to
1849 a different size reloc below and want to avoid "converting" more
1850 than once. */
1851 if (reloc && reloc != BFD_RELOC_NONE)
1852 return reloc;
1853
1854 switch (operand->type)
1855 {
1856 MAP (PCREL8A2); /* beqz */
1857 MAP (PCREL12A2); /* bsr16 */
1858 MAP (PCREL17A2); /* beqi */
1859 MAP (PCREL24A2); /* bsr24 */
1860 MAP (PCABS24A2); /* jmp */
1861 MAP (UIMM24); /* mov */
1862 MAP (ADDR24A4); /* sw/lw */
1863
1864 /* The rest of the relocs should be generated by the parser,
1865 for things such as %tprel(), etc. */
1866 case MEP_OPERAND_SIMM16:
1867#ifdef OBJ_COMPLEX_RELC
1868 /* coalescing this into RELOC_MEP_16 is actually a bug,
1869 since it's a signed operand. let the relc code handle it. */
3739860c 1870 return BFD_RELOC_RELC;
280d71bf
DB
1871#endif
1872
1873 case MEP_OPERAND_UIMM16:
1874 case MEP_OPERAND_SDISP16:
1875 case MEP_OPERAND_CODE16:
1876 fixP->fx_where += 2;
1877 /* to avoid doing the above add twice */
1878 fixP->fx_cgen.opinfo = BFD_RELOC_MEP_16;
1879 return BFD_RELOC_MEP_16;
1880
1881 default:
1882#ifdef OBJ_COMPLEX_RELC
3739860c 1883 /* this is not an error, yet.
280d71bf
DB
1884 pass it to the linker. */
1885 return BFD_RELOC_RELC;
1886#endif
1887 if (printed[operand->type])
1888 return BFD_RELOC_NONE;
1889 printed[operand->type] = 1;
1890
1891 as_bad_where (fixP->fx_file, fixP->fx_line,
1892 _("Don't know how to relocate plain operands of type %s"),
1893 operand->name);
1894
1895 /* Print some helpful hints for the user. */
1896 switch (operand->type)
1897 {
1898 case MEP_OPERAND_UDISP7:
1899 case MEP_OPERAND_UDISP7A2:
1900 case MEP_OPERAND_UDISP7A4:
1901 as_bad_where (fixP->fx_file, fixP->fx_line,
1902 _("Perhaps you are missing %%tpoff()?"));
1903 break;
1904 default:
1905 break;
1906 }
1907 return BFD_RELOC_NONE;
1908 }
1909}
1910
1911/* Called while parsing an instruction to create a fixup.
1912 We need to check for HI16 relocs and queue them up for later sorting. */
1913
1914fixS *
1915mep_cgen_record_fixup_exp (fragS *frag,
1916 int where,
1917 const CGEN_INSN *insn,
1918 int length,
1919 const CGEN_OPERAND *operand,
1920 int opinfo,
1921 expressionS *exp)
1922{
1923 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
1924 operand, opinfo, exp);
1925 return fixP;
1926}
1927
1928/* Return BFD reloc type from opinfo field in a fixS.
1929 It's tricky using fx_r_type in mep_frob_file because the values
1930 are BFD_RELOC_UNUSED + operand number. */
1931#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
1932
1933/* Sort any unmatched HI16 relocs so that they immediately precede
1934 the corresponding LO16 reloc. This is called before md_apply_fix and
1935 tc_gen_reloc. */
1936
1937void
e6c7cdec 1938mep_frob_file (void)
280d71bf
DB
1939{
1940 struct mep_hi_fixup * l;
1941
1942 for (l = mep_hi_fixup_list; l != NULL; l = l->next)
1943 {
1944 segment_info_type * seginfo;
1945 int pass;
1946
9c2799c2 1947 gas_assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16
280d71bf
DB
1948 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16);
1949
1950 /* Check quickly whether the next fixup happens to be a matching low. */
1951 if (l->fixp->fx_next != NULL
1952 && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_LO16
1953 && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
1954 && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
1955 continue;
1956
1957 /* Look through the fixups for this segment for a matching
1958 `low'. When we find one, move the high just in front of it.
1959 We do this in two passes. In the first pass, we try to find
1960 a unique `low'. In the second pass, we permit multiple
1961 high's relocs for a single `low'. */
1962 seginfo = seg_info (l->seg);
1963 for (pass = 0; pass < 2; pass++)
1964 {
1965 fixS * f;
1966 fixS * prev;
1967
1968 prev = NULL;
1969 for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
1970 {
1971 /* Check whether this is a `low' fixup which matches l->fixp. */
1972 if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_LO16
1973 && f->fx_addsy == l->fixp->fx_addsy
1974 && f->fx_offset == l->fixp->fx_offset
1975 && (pass == 1
1976 || prev == NULL
1977 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
1978 || prev->fx_addsy != f->fx_addsy
1979 || prev->fx_offset != f->fx_offset))
1980 {
1981 fixS ** pf;
1982
1983 /* Move l->fixp before f. */
1984 for (pf = &seginfo->fix_root;
1985 * pf != l->fixp;
1986 pf = & (* pf)->fx_next)
9c2799c2 1987 gas_assert (* pf != NULL);
280d71bf
DB
1988
1989 * pf = l->fixp->fx_next;
1990
1991 l->fixp->fx_next = f;
1992 if (prev == NULL)
1993 seginfo->fix_root = l->fixp;
1994 else
1995 prev->fx_next = l->fixp;
1996
1997 break;
1998 }
1999
2000 prev = f;
2001 }
2002
2003 if (f != NULL)
2004 break;
2005
2006 if (pass == 1)
2007 as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
2008 _("Unmatched high relocation"));
2009 }
2010 }
2011}
2012
2013/* See whether we need to force a relocation into the output file. */
2014
2015int
2016mep_force_relocation (fixS *fixp)
2017{
2018 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2019 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2020 return 1;
2021
85143216
DD
2022 if (generic_force_reloc (fixp))
2023 return 1;
2024
280d71bf
DB
2025 /* Allow branches to global symbols to be resolved at assembly time.
2026 This is consistent with way relaxable branches are handled, since
2027 branches to both global and local symbols are relaxed. It also
2028 corresponds to the assumptions made in md_pcrel_from_section. */
2029 return S_FORCE_RELOC (fixp->fx_addsy, !fixp->fx_pcrel);
2030}
2031\f
2032/* Write a value out to the object file, using the appropriate endianness. */
2033
2034void
2035md_number_to_chars (char *buf, valueT val, int n)
2036{
2037 if (target_big_endian)
2038 number_to_chars_bigendian (buf, val, n);
2039 else
2040 number_to_chars_littleendian (buf, val, n);
2041}
2042
6d4af3c2 2043const char *
280d71bf
DB
2044md_atof (int type, char *litP, int *sizeP)
2045{
499ac353 2046 return ieee_md_atof (type, litP, sizeP, TRUE);
280d71bf
DB
2047}
2048
280d71bf
DB
2049bfd_boolean
2050mep_fix_adjustable (fixS *fixP)
2051{
2052 bfd_reloc_code_real_type reloc_type;
2053
2054 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
2055 {
2056 const CGEN_INSN *insn = NULL;
2057 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
2058 const CGEN_OPERAND *operand
2059 = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
2060 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
2061 }
2062 else
2063 reloc_type = fixP->fx_r_type;
2064
2065 if (fixP->fx_addsy == NULL)
2066 return 1;
2067
2068 /* Prevent all adjustments to global symbols. */
2069 if (S_IS_EXTERNAL (fixP->fx_addsy))
2070 return 0;
2071
2072 if (S_IS_WEAK (fixP->fx_addsy))
2073 return 0;
2074
2075 /* We need the symbol name for the VTABLE entries */
2076 if (reloc_type == BFD_RELOC_VTABLE_INHERIT
2077 || reloc_type == BFD_RELOC_VTABLE_ENTRY)
2078 return 0;
2079
2080 return 1;
2081}
2082
01e1a5bc 2083bfd_vma
6d4af3c2 2084mep_elf_section_letter (int letter, const char **ptrmsg)
280d71bf
DB
2085{
2086 if (letter == 'v')
2087 return SHF_MEP_VLIW;
2088
8f3bae45
AM
2089 *ptrmsg = _("bad .section directive: want a,v,w,x,M,S in string");
2090 return -1;
280d71bf
DB
2091}
2092
2093flagword
01e1a5bc 2094mep_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
280d71bf
DB
2095{
2096 if (attr & SHF_MEP_VLIW)
2097 flags |= SEC_MEP_VLIW;
2098 return flags;
2099}
2100
2101/* In vliw mode, the default section is .vtext. We have to be able
2102 to switch into .vtext using only the .vtext directive. */
2103
2104static segT
2105mep_vtext_section (void)
2106{
2107 static segT vtext_section;
2108
2109 if (! vtext_section)
2110 {
2111 flagword applicable = bfd_applicable_section_flags (stdoutput);
2112 vtext_section = subseg_new (VTEXT_SECTION_NAME, 0);
fd361982 2113 bfd_set_section_flags (vtext_section,
280d71bf
DB
2114 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
2115 | SEC_CODE | SEC_READONLY
2116 | SEC_MEP_VLIW));
2117 }
2118
2119 return vtext_section;
2120}
2121
2122static void
2123mep_s_vtext (int ignore ATTRIBUTE_UNUSED)
2124{
2125 int temp;
2126
2127 /* Record previous_section and previous_subsection. */
2128 obj_elf_section_change_hook ();
2129
2130 temp = get_absolute_expression ();
2131 subseg_set (mep_vtext_section (), (subsegT) temp);
2132 demand_empty_rest_of_line ();
2133}
2134
2135static void
2136mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED)
2137{
2138 mep_process_saved_insns ();
2139 pluspresent = 0;
2140 mode = CORE;
2141}
2142
2143static void
2144mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED)
2145{
2146 if (! MEP_VLIW)
2147 as_bad (_(".vliw unavailable when VLIW is disabled."));
2148 mode = VLIW;
2149 /* Switch into .vtext here too. */
2150 /* mep_s_vtext(); */
2151}
2152
2153/* This is an undocumented pseudo-op used to disable gas's
2154 "disabled_registers" check. Used for code which checks for those
2155 registers at runtime. */
2156static void
2157mep_noregerr (int i ATTRIBUTE_UNUSED)
2158{
2159 allow_disabled_registers = 1;
2160}
2161
2162/* mep_unrecognized_line: This is called when a line that can't be parsed
2163 is encountered. We use it to check for a leading '+' sign which indicates
2164 that the current instruction is a coprocessor instruction that is to be
2165 parallelized with a previous core insn. This function accepts the '+' and
2166 rejects all other characters that might indicate garbage at the beginning
2167 of the line. The '+' character gets lost as the calling loop continues,
2168 so we need to indicate that we saw it. */
2169
2170int
2171mep_unrecognized_line (int ch)
2172{
2173 switch (ch)
2174 {
2175 case '+':
2176 pluspresent = 1;
2177 return 1; /* '+' indicates an instruction to be parallelized. */
2178 default:
2179 return 0; /* If it's not a '+', the line can't be parsed. */
2180 }
2181}
2182
2183void
2184mep_cleanup (void)
2185{
2186 /* Take care of any insns left to be parallelized when the file ends.
2187 This is mainly here to handle the case where the file ends with an
2b0f3761 2188 insn preceded by a + or the file ends unexpectedly. */
280d71bf
DB
2189 if (mode == VLIW)
2190 mep_process_saved_insns ();
2191}
2192
2193int
2194mep_flush_pending_output (void)
2195{
2196 if (mode == VLIW)
2197 {
2198 mep_process_saved_insns ();
2199 pluspresent = 0;
2200 }
2201
3739860c 2202 return 1;
280d71bf 2203}