OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-mep.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.