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