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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-mep.c] - Blame information for rev 237

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

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

powered by: WebSVN 2.1.0

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