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