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