daily update
[external/binutils.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 char *
1680 md_atof (int type, char *litP, int *sizeP)
1681 {
1682   return ieee_md_atof (type, litP, sizeP, TRUE);
1683 }
1684
1685 bfd_boolean
1686 mep_fix_adjustable (fixS *fixP)
1687 {
1688   bfd_reloc_code_real_type reloc_type;
1689
1690   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1691     {
1692       const CGEN_INSN *insn = NULL;
1693       int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1694       const CGEN_OPERAND *operand
1695         = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
1696       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
1697     }
1698   else
1699     reloc_type = fixP->fx_r_type;
1700
1701   if (fixP->fx_addsy == NULL)
1702     return 1;
1703
1704   /* Prevent all adjustments to global symbols. */
1705   if (S_IS_EXTERNAL (fixP->fx_addsy))
1706     return 0;
1707
1708   if (S_IS_WEAK (fixP->fx_addsy))
1709     return 0;
1710
1711   /* We need the symbol name for the VTABLE entries */
1712   if (reloc_type == BFD_RELOC_VTABLE_INHERIT
1713       || reloc_type == BFD_RELOC_VTABLE_ENTRY)
1714     return 0;
1715
1716   return 1;
1717 }
1718
1719 int
1720 mep_elf_section_letter (int letter, char **ptrmsg)
1721 {
1722   if (letter == 'v')
1723     return SHF_MEP_VLIW;
1724
1725   *ptrmsg = _("Bad .section directive: want a,v,w,x,M,S in string");
1726   return 0;
1727 }
1728
1729 flagword
1730 mep_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
1731 {
1732   if (attr & SHF_MEP_VLIW)
1733     flags |= SEC_MEP_VLIW;
1734   return flags;
1735 }
1736
1737 /* In vliw mode, the default section is .vtext.  We have to be able
1738    to switch into .vtext using only the .vtext directive.  */
1739
1740 static segT
1741 mep_vtext_section (void)
1742 {
1743   static segT vtext_section;
1744
1745   if (! vtext_section)
1746     {
1747       flagword applicable = bfd_applicable_section_flags (stdoutput);
1748       vtext_section = subseg_new (VTEXT_SECTION_NAME, 0);
1749       bfd_set_section_flags (stdoutput, vtext_section,
1750                              applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
1751                                            | SEC_CODE | SEC_READONLY
1752                                            | SEC_MEP_VLIW));
1753     }
1754
1755   return vtext_section;
1756 }
1757
1758 static void
1759 mep_s_vtext (int ignore ATTRIBUTE_UNUSED)
1760 {
1761   int temp;
1762
1763   /* Record previous_section and previous_subsection.  */
1764   obj_elf_section_change_hook ();
1765
1766   temp = get_absolute_expression ();
1767   subseg_set (mep_vtext_section (), (subsegT) temp);
1768   demand_empty_rest_of_line ();
1769 }
1770
1771 static void
1772 mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED)
1773 {
1774   mep_process_saved_insns ();
1775   pluspresent = 0;
1776   mode = CORE;
1777 }
1778
1779 static void
1780 mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED)
1781 {
1782   if (! MEP_VLIW)
1783     as_bad (_(".vliw unavailable when VLIW is disabled."));
1784   mode = VLIW;
1785   /* Switch into .vtext here too. */
1786   /* mep_s_vtext(); */
1787 }
1788
1789 /* This is an undocumented pseudo-op used to disable gas's
1790    "disabled_registers" check.  Used for code which checks for those
1791    registers at runtime.  */
1792 static void
1793 mep_noregerr (int i ATTRIBUTE_UNUSED)
1794 {
1795   allow_disabled_registers = 1;
1796 }
1797
1798 /* mep_unrecognized_line: This is called when a line that can't be parsed
1799    is encountered.  We use it to check for a leading '+' sign which indicates
1800    that the current instruction is a coprocessor instruction that is to be
1801    parallelized with a previous core insn.  This function accepts the '+' and
1802    rejects all other characters that might indicate garbage at the beginning
1803    of the line.  The '+' character gets lost as the calling loop continues,
1804    so we need to indicate that we saw it.  */
1805
1806 int
1807 mep_unrecognized_line (int ch)
1808 {
1809   switch (ch)
1810     {
1811     case '+':
1812       pluspresent = 1;
1813       return 1; /* '+' indicates an instruction to be parallelized. */
1814     default:
1815       return 0; /* If it's not a '+', the line can't be parsed. */
1816     }
1817 }
1818
1819 void
1820 mep_cleanup (void)
1821 {
1822   /* Take care of any insns left to be parallelized when the file ends.
1823      This is mainly here to handle the case where the file ends with an
1824      insn preceeded by a + or the file ends unexpectedly.  */
1825   if (mode == VLIW)
1826     mep_process_saved_insns ();
1827 }
1828
1829 int
1830 mep_flush_pending_output (void)
1831 {
1832   if (mode == VLIW)
1833     {
1834       mep_process_saved_insns ();
1835       pluspresent = 0;
1836     }
1837
1838   return 1; 
1839 }