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