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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [cpu/] [mep.opc] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
/* MeP opcode support.  -*- C -*-
2
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
3
   This file is part of CGEN.
4
   This file is copyrighted with the GNU General Public License.
5
   See file COPYING for details.  */
6
 
7
/* -- opc.h */
8
 
9
#undef  CGEN_DIS_HASH_SIZE
10
#define CGEN_DIS_HASH_SIZE 1
11
 
12
#undef  CGEN_DIS_HASH
13
#define CGEN_DIS_HASH(buffer, insn) 0
14
 
15
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
16
 
17
typedef struct
18
{
19
  char * name;
20
  int    config_enum;
21
  unsigned cpu_flag;
22
  int    big_endian;
23
  int    vliw_bits;
24
  CGEN_ATTR_VALUE_BITSET_TYPE cop16_isa;
25
  CGEN_ATTR_VALUE_BITSET_TYPE cop32_isa;
26
  CGEN_ATTR_VALUE_BITSET_TYPE cop48_isa;
27
  CGEN_ATTR_VALUE_BITSET_TYPE cop64_isa;
28
  CGEN_ATTR_VALUE_BITSET_TYPE cop_isa;
29
  CGEN_ATTR_VALUE_BITSET_TYPE core_isa;
30
  unsigned int option_mask;
31
} mep_config_map_struct;
32
 
33
extern mep_config_map_struct mep_config_map[];
34
extern int mep_config_index;
35
 
36
extern void init_mep_all_core_isas_mask (void);
37
extern void init_mep_all_cop_isas_mask  (void);
38
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_cop_isa  (void);
39
 
40
#define MEP_CONFIG     (mep_config_map[mep_config_index].config_enum)
41
#define MEP_CPU        (mep_config_map[mep_config_index].cpu_flag)
42
#define MEP_OMASK      (mep_config_map[mep_config_index].option_mask)
43
#define MEP_VLIW       (mep_config_map[mep_config_index].vliw_bits > 0)
44
#define MEP_VLIW32     (mep_config_map[mep_config_index].vliw_bits == 32)
45
#define MEP_VLIW64     (mep_config_map[mep_config_index].vliw_bits == 64)
46
#define MEP_COP16_ISA  (mep_config_map[mep_config_index].cop16_isa)
47
#define MEP_COP32_ISA  (mep_config_map[mep_config_index].cop32_isa)
48
#define MEP_COP48_ISA  (mep_config_map[mep_config_index].cop48_isa)
49
#define MEP_COP64_ISA  (mep_config_map[mep_config_index].cop64_isa)
50
#define MEP_COP_ISA    (mep_config_map[mep_config_index].cop_isa)
51
#define MEP_CORE_ISA   (mep_config_map[mep_config_index].core_isa)
52
 
53
/* begin-cop-ip-supported-defines */
54
#define MEP_IVC2_SUPPORTED 1
55
/* end-cop-ip-supported-defines */
56
 
57
extern int mep_insn_supported_by_isa (const CGEN_INSN *, CGEN_ATTR_VALUE_BITSET_TYPE *);
58
 
59
/* A mask for all ISAs executed by the core.  */
60
#define MEP_ALL_CORE_ISAS_MASK mep_all_core_isas_mask
61
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask;
62
 
63
#define MEP_INSN_CORE_P(insn) ( \
64
  init_mep_all_core_isas_mask (), \
65
  mep_insn_supported_by_isa (insn, & MEP_ALL_CORE_ISAS_MASK) \
66
)
67
 
68
/* A mask for all ISAs executed by a VLIW coprocessor.  */
69
#define MEP_ALL_COP_ISAS_MASK mep_all_cop_isas_mask
70
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask;
71
 
72
#define MEP_INSN_COP_P(insn) ( \
73
  init_mep_all_cop_isas_mask (), \
74
  mep_insn_supported_by_isa (insn, & MEP_ALL_COP_ISAS_MASK) \
75
)
76
 
77
extern int mep_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
78
extern int mep_cgen_insn_supported_asm (CGEN_CPU_DESC, const CGEN_INSN *);
79
 
80
/* -- asm.c */
81
 
82
#include "elf/mep.h"
83
 
84
#define CGEN_VALIDATE_INSN_SUPPORTED
85
#define mep_cgen_insn_supported mep_cgen_insn_supported_asm
86
 
87
       const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
88
       const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
89
       const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
90
       const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
91
       const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
92
static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
93
static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *);
94
static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
95
static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *);
96
static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
97
static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
98
static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
99
 
100
const char *
101
parse_csrn (CGEN_CPU_DESC cd, const char **strp,
102
            CGEN_KEYWORD *keyword_table, long *field)
103
{
104
  const char *err;
105
  unsigned long value;
106
 
107
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
108
  if (!err)
109
    return NULL;
110
 
111
  err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
112
  if (err)
113
    return err;
114
  *field = value;
115
  return NULL;
116
}
117
 
118
/* begin-cop-ip-parse-handlers */
119
static const char *
120
parse_ivc2_cr (CGEN_CPU_DESC,
121
        const char **,
122
        CGEN_KEYWORD *,
123
        long *) ATTRIBUTE_UNUSED;
124
static const char *
125
parse_ivc2_cr (CGEN_CPU_DESC cd,
126
        const char **strp,
127
        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
128
        long *field)
129
{
130
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
131
}
132
static const char *
133
parse_ivc2_ccr (CGEN_CPU_DESC,
134
        const char **,
135
        CGEN_KEYWORD *,
136
        long *) ATTRIBUTE_UNUSED;
137
static const char *
138
parse_ivc2_ccr (CGEN_CPU_DESC cd,
139
        const char **strp,
140
        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
141
        long *field)
142
{
143
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
144
}
145
/* end-cop-ip-parse-handlers */
146
 
147
const char *
148
parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
149
             CGEN_KEYWORD *keyword_table, long *field)
150
{
151
  const char *err;
152
 
153
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
154
  if (err)
155
    return err;
156
  if (*field != 13)
157
    return _("Only $tp or $13 allowed for this opcode");
158
  return NULL;
159
}
160
 
161
const char *
162
parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
163
             CGEN_KEYWORD *keyword_table, long *field)
164
{
165
  const char *err;
166
 
167
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
168
  if (err)
169
    return err;
170
  if (*field != 15)
171
    return _("Only $sp or $15 allowed for this opcode");
172
  return NULL;
173
}
174
 
175
const char *
176
parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
177
                 enum cgen_operand_type type, long *field)
178
{
179
  long lsbs = 0;
180
  const char *err;
181
 
182
  switch (type)
183
    {
184
    case MEP_OPERAND_PCREL8A2:
185
    case MEP_OPERAND_PCREL12A2:
186
    case MEP_OPERAND_PCREL17A2:
187
    case MEP_OPERAND_PCREL24A2:
188
      err = cgen_parse_signed_integer   (cd, strp, type, field);
189
      break;
190
    case MEP_OPERAND_PCABS24A2:
191
    case MEP_OPERAND_UDISP7:
192
    case MEP_OPERAND_UDISP7A2:
193
    case MEP_OPERAND_UDISP7A4:
194
    case MEP_OPERAND_UIMM7A4:
195
    case MEP_OPERAND_ADDR24A4:
196
      err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
197
      break;
198
    default:
199
      abort();
200
    }
201
  if (err)
202
    return err;
203
  switch (type)
204
    {
205
    case MEP_OPERAND_UDISP7:
206
      lsbs = 0;
207
      break;
208
    case MEP_OPERAND_PCREL8A2:
209
    case MEP_OPERAND_PCREL12A2:
210
    case MEP_OPERAND_PCREL17A2:
211
    case MEP_OPERAND_PCREL24A2:
212
    case MEP_OPERAND_PCABS24A2:
213
    case MEP_OPERAND_UDISP7A2:
214
      lsbs = *field & 1;
215
      break;
216
    case MEP_OPERAND_UDISP7A4:
217
    case MEP_OPERAND_UIMM7A4:
218
    case MEP_OPERAND_ADDR24A4:
219
      lsbs = *field & 3;
220
      break;
221
      lsbs = *field & 7;
222
      break;
223
    default:
224
      /* Safe assumption?  */
225
      abort ();
226
    }
227
  if (lsbs)
228
    return "Value is not aligned enough";
229
  return NULL;
230
}
231
 
232
const char *
233
parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
234
                 enum cgen_operand_type type, unsigned long *field)
235
{
236
  return parse_mep_align (cd, strp, type, (long *) field);
237
}
238
 
239
 
240
/* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
241
   constants in a signed context.  */
242
 
243
static const char *
244
parse_signed16 (CGEN_CPU_DESC cd,
245
                const char **strp,
246
                int opindex,
247
                long *valuep)
248
{
249
  return parse_lo16 (cd, strp, opindex, valuep, 1);
250
}
251
 
252
static const char *
253
parse_lo16 (CGEN_CPU_DESC cd,
254
            const char **strp,
255
            int opindex,
256
            long *valuep,
257
            long signedp)
258
{
259
  const char *errmsg;
260
  enum cgen_parse_operand_result result_type;
261
  bfd_vma value;
262
 
263
  if (strncasecmp (*strp, "%lo(", 4) == 0)
264
    {
265
      *strp += 4;
266
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
267
                                   & result_type, & value);
268
      if (**strp != ')')
269
        return _("missing `)'");
270
      ++*strp;
271
      if (errmsg == NULL
272
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
273
        value &= 0xffff;
274
      if (signedp)
275
        *valuep = (long)(short) value;
276
      else
277
        *valuep = value;
278
      return errmsg;
279
    }
280
 
281
  if (strncasecmp (*strp, "%hi(", 4) == 0)
282
    {
283
      *strp += 4;
284
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
285
                                   & result_type, & value);
286
      if (**strp != ')')
287
        return _("missing `)'");
288
      ++*strp;
289
      if (errmsg == NULL
290
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
291
        value = (value + 0x8000) >> 16;
292
      *valuep = value;
293
      return errmsg;
294
    }
295
 
296
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
297
    {
298
      *strp += 5;
299
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
300
                                   & result_type, & value);
301
      if (**strp != ')')
302
        return _("missing `)'");
303
      ++*strp;
304
      if (errmsg == NULL
305
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
306
        value = value >> 16;
307
      *valuep = value;
308
      return errmsg;
309
    }
310
 
311
  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
312
    {
313
      *strp += 8;
314
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
315
                                   NULL, & value);
316
      if (**strp != ')')
317
        return _("missing `)'");
318
      ++*strp;
319
      *valuep = value;
320
      return errmsg;
321
    }
322
 
323
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
324
    {
325
      *strp += 7;
326
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
327
                                   NULL, & value);
328
      if (**strp != ')')
329
        return _("missing `)'");
330
      ++*strp;
331
      *valuep = value;
332
      return errmsg;
333
    }
334
 
335
  if (**strp == '%')
336
    return _("invalid %function() here");
337
 
338
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
339
}
340
 
341
static const char *
342
parse_unsigned16 (CGEN_CPU_DESC cd,
343
                  const char **strp,
344
                  int opindex,
345
                  unsigned long *valuep)
346
{
347
  return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
348
}
349
 
350
static const char *
351
parse_signed16_range (CGEN_CPU_DESC cd,
352
                      const char **strp,
353
                      int opindex,
354
                      signed long *valuep)
355
{
356
  const char *errmsg = 0;
357
  signed long value;
358
 
359
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
360
  if (errmsg)
361
    return errmsg;
362
 
363
  if (value < -32768 || value > 32767)
364
    return _("Immediate is out of range -32768 to 32767");
365
 
366
  *valuep = value;
367
  return 0;
368
}
369
 
370
static const char *
371
parse_unsigned16_range (CGEN_CPU_DESC cd,
372
                        const char **strp,
373
                        int opindex,
374
                        unsigned long *valuep)
375
{
376
  const char *errmsg = 0;
377
  unsigned long value;
378
 
379
  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
380
  if (errmsg)
381
    return errmsg;
382
 
383
  if (value > 65535)
384
    return _("Immediate is out of range 0 to 65535");
385
 
386
  *valuep = value;
387
  return 0;
388
}
389
 
390
/* A special case of parse_signed16 which accepts only the value zero.  */
391
 
392
static const char *
393
parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
394
{
395
  const char *errmsg;
396
  enum cgen_parse_operand_result result_type;
397
  bfd_vma value;
398
 
399
  /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
400
 
401
  /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
402
     It will fail and cause ry to be listed as an undefined symbol in the
403
     listing.  */
404
  if (strncmp (*strp, "($", 2) == 0)
405
    return "not zero"; /* any string will do -- will never be seen.  */
406
 
407
  if (strncasecmp (*strp, "%lo(", 4) == 0)
408
    {
409
      *strp += 4;
410
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
411
                                   &result_type, &value);
412
      if (**strp != ')')
413
        return "missing `)'";
414
      ++*strp;
415
      if (errmsg == NULL
416
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
417
        return "not zero"; /* any string will do -- will never be seen.  */
418
      *valuep = value;
419
      return errmsg;
420
    }
421
 
422
  if (strncasecmp (*strp, "%hi(", 4) == 0)
423
    {
424
      *strp += 4;
425
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
426
                                   &result_type, &value);
427
      if (**strp != ')')
428
        return "missing `)'";
429
      ++*strp;
430
      if (errmsg == NULL
431
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
432
        return "not zero"; /* any string will do -- will never be seen.  */
433
      *valuep = value;
434
      return errmsg;
435
    }
436
 
437
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
438
    {
439
      *strp += 5;
440
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
441
                                   &result_type, &value);
442
      if (**strp != ')')
443
        return "missing `)'";
444
      ++*strp;
445
      if (errmsg == NULL
446
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
447
        return "not zero"; /* any string will do -- will never be seen.  */
448
      *valuep = value;
449
      return errmsg;
450
    }
451
 
452
  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
453
    {
454
      *strp += 8;
455
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
456
                                   &result_type, &value);
457
      if (**strp != ')')
458
        return "missing `)'";
459
      ++*strp;
460
      if (errmsg == NULL
461
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
462
        return "not zero"; /* any string will do -- will never be seen.  */
463
      *valuep = value;
464
      return errmsg;
465
    }
466
 
467
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
468
    {
469
      *strp += 7;
470
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
471
                                   &result_type, &value);
472
      if (**strp != ')')
473
        return "missing `)'";
474
      ++*strp;
475
      if (errmsg == NULL
476
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
477
        return "not zero"; /* any string will do -- will never be seen.  */
478
      *valuep = value;
479
      return errmsg;
480
    }
481
 
482
  if (**strp == '%')
483
    return "invalid %function() here";
484
 
485
  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
486
                               &result_type, &value);
487
  if (errmsg == NULL
488
      && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
489
    return "not zero"; /* any string will do -- will never be seen.  */
490
 
491
  return errmsg;
492
}
493
 
494
static const char *
495
parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
496
                 enum cgen_operand_type opindex, unsigned long *valuep)
497
{
498
  const char *errmsg;
499
  bfd_vma value;
500
 
501
  /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
502
 
503
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
504
    {
505
      int reloc;
506
      *strp += 7;
507
      switch (opindex)
508
        {
509
        case MEP_OPERAND_UDISP7:
510
          reloc = BFD_RELOC_MEP_TPREL7;
511
          break;
512
        case MEP_OPERAND_UDISP7A2:
513
          reloc = BFD_RELOC_MEP_TPREL7A2;
514
          break;
515
        case MEP_OPERAND_UDISP7A4:
516
          reloc = BFD_RELOC_MEP_TPREL7A4;
517
          break;
518
        default:
519
          /* Safe assumption?  */
520
          abort ();
521
        }
522
      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
523
                                   NULL, &value);
524
      if (**strp != ')')
525
        return "missing `)'";
526
      ++*strp;
527
      *valuep = value;
528
      return errmsg;
529
    }
530
 
531
  if (**strp == '%')
532
    return _("invalid %function() here");
533
 
534
  return parse_mep_alignu (cd, strp, opindex, valuep);
535
}
536
 
537
static ATTRIBUTE_UNUSED const char *
538
parse_cdisp10 (CGEN_CPU_DESC cd,
539
               const char **strp,
540
               int opindex,
541
               long *valuep)
542
{
543
  const char *errmsg = 0;
544
  signed long value;
545
  long have_zero = 0;
546
  int wide = 0;
547
  int alignment;
548
 
549
  switch (opindex)
550
    {
551
    case MEP_OPERAND_CDISP10A4:
552
      alignment = 2;
553
      break;
554
    case MEP_OPERAND_CDISP10A2:
555
      alignment = 1;
556
      break;
557
    case MEP_OPERAND_CDISP10:
558
    default:
559
      alignment = 0;
560
      break;
561
    }
562
 
563
  if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
564
    wide = 1;
565
 
566
  if (strncmp (*strp, "0x0", 3) == 0
567
      || (**strp == '0' && *(*strp + 1) != 'x'))
568
    have_zero = 1;
569
 
570
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
571
  if (errmsg)
572
    return errmsg;
573
 
574
  if (wide)
575
    {
576
      if (value < -512 || value > 511)
577
        return _("Immediate is out of range -512 to 511");
578
    }
579
  else
580
    {
581
      if (value < -128 || value > 127)
582
        return _("Immediate is out of range -128 to 127");
583
    }
584
 
585
  if (value & ((1<
586
    return _("Value is not aligned enough");
587
 
588
  /* If this field may require a relocation then use larger dsp16.  */
589
  if (! have_zero && value == 0)
590
    return (wide ? _("Immediate is out of range -512 to 511")
591
            : _("Immediate is out of range -128 to 127"));
592
 
593
  *valuep = value;
594
  return 0;
595
}
596
 
597
/* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
598
 
599
#define MAXARGS 9
600
 
601
typedef struct
602
{
603
  char *name;
604
  char *expansion;
605
}  macro;
606
 
607
typedef struct
608
{
609
  const char *start;
610
  int len;
611
} arg;
612
 
613
macro macros[] =
614
{
615
  { "sizeof", "(`1.end + (- `1))"},
616
  { "startof", "(`1 | 0)" },
617
  { "align4", "(`1&(~3))"},
618
/*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
619
/*{ "lo", "(`1 & 0xffff)" },  */
620
/*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
621
/*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
622
  { 0,0 }
623
};
624
 
625
static char  * expand_string    (const char *, int);
626
 
627
static const char *
628
mep_cgen_expand_macros_and_parse_operand
629
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
630
 
631
static char *
632
str_append (char *dest, const char *input, int len)
633
{
634
  char *new_dest;
635
  int oldlen;
636
 
637
  if (len == 0)
638
    return dest;
639
  /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
640
  oldlen = (dest ? strlen(dest) : 0);
641
  new_dest = realloc (dest, oldlen + len + 1);
642
  memset (new_dest + oldlen, 0, len + 1);
643
  return strncat (new_dest, input, len);
644
}
645
 
646
static macro *
647
lookup_macro (const char *name)
648
{
649
  macro *m;
650
 
651
  for (m = macros; m->name; ++m)
652
    if (strncmp (m->name, name, strlen(m->name)) == 0)
653
      return m;
654
 
655
  return 0;
656
}
657
 
658
static char *
659
expand_macro (arg *args, int narg, macro *mac)
660
{
661
  char *result = 0, *rescanned_result = 0;
662
  char *e = mac->expansion;
663
  char *mark = e;
664
  int arg = 0;
665
 
666
  /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
667
  while (*e)
668
    {
669
      if (*e == '`' &&
670
          (*e+1) &&
671
          ((*(e + 1) - '1') <= MAXARGS) &&
672
          ((*(e + 1) - '1') <= narg))
673
        {
674
          result = str_append (result, mark, e - mark);
675
          arg = (*(e + 1) - '1');
676
          /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */
677
          result = str_append (result, args[arg].start, args[arg].len);
678
          ++e;
679
          mark = e+1;
680
        }
681
      ++e;
682
    }
683
 
684
  if (mark != e)
685
    result = str_append (result, mark, e - mark);
686
 
687
  if (result)
688
    {
689
      rescanned_result = expand_string (result, 0);
690
      free (result);
691
      return rescanned_result;
692
    }
693
  else
694
    return result;
695
}
696
 
697
#define IN_TEXT 0
698
#define IN_ARGS 1
699
 
700
static char *
701
expand_string (const char *in, int first_only)
702
{
703
  int num_expansions = 0;
704
  int depth = 0;
705
  int narg = -1;
706
  arg args[MAXARGS];
707
  int state = IN_TEXT;
708
  const char *mark = in;
709
  macro *macro = 0;
710
 
711
  char *expansion = 0;
712
  char *result = 0;
713
 
714
  while (*in)
715
    {
716
      switch (state)
717
        {
718
        case IN_TEXT:
719
          if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
720
            {
721
              macro = lookup_macro (in + 1);
722
              if (macro)
723
                {
724
                  /* printf("entering state %d at '%s'...\n", state, in); */
725
                  result = str_append (result, mark, in - mark);
726
                  mark = in;
727
                  in += 1 + strlen (macro->name);
728
                  while (*in == ' ') ++in;
729
                  if (*in != '(')
730
                    {
731
                      state = IN_TEXT;
732
                      macro = 0;
733
                    }
734
                  else
735
                    {
736
                      state = IN_ARGS;
737
                      narg = 0;
738
                      args[narg].start = in + 1;
739
                      args[narg].len = 0;
740
                      mark = in + 1;
741
                    }
742
                }
743
            }
744
          break;
745
        case IN_ARGS:
746
          if (depth == 0)
747
            {
748
              switch (*in)
749
                {
750
                case ',':
751
                  narg++;
752
                  args[narg].start = (in + 1);
753
                  args[narg].len = 0;
754
                  break;
755
                case ')':
756
                  state = IN_TEXT;
757
                  /* printf("entering state %d at '%s'...\n", state, in); */
758
                  if (macro)
759
                    {
760
                      expansion = 0;
761
                      expansion = expand_macro (args, narg, macro);
762
                      num_expansions++;
763
                      if (expansion)
764
                        {
765
                          result = str_append (result, expansion, strlen (expansion));
766
                          free (expansion);
767
                        }
768
                    }
769
                  else
770
                    {
771
                      result = str_append (result, mark, in - mark);
772
                    }
773
                  macro = 0;
774
                  mark = in + 1;
775
                  break;
776
                case '(':
777
                  depth++;
778
                default:
779
                  args[narg].len++;
780
                  break;
781
                }
782
            }
783
          else
784
            {
785
              if (*in == ')')
786
                depth--;
787
              if (narg > -1)
788
                args[narg].len++;
789
            }
790
 
791
        }
792
      ++in;
793
    }
794
 
795
  if (mark != in)
796
    result = str_append (result, mark, in - mark);
797
 
798
  return result;
799
}
800
 
801
#undef IN_ARGS
802
#undef IN_TEXT
803
#undef MAXARGS
804
 
805
 
806
/* END LIGHTWEIGHT MACRO PROCESSOR.  */
807
 
808
const char * mep_cgen_parse_operand
809
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
810
 
811
const char *
812
mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
813
                                          const char ** strp_in, CGEN_FIELDS * fields)
814
{
815
  const char * errmsg = NULL;
816
  char *str = 0, *hold = 0;
817
  const char **strp = 0;
818
 
819
  /* Set up a new pointer to macro-expanded string.  */
820
  str = expand_string (*strp_in, 1);
821
  /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
822
 
823
  hold = str;
824
  strp = (const char **)(&str);
825
 
826
  errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
827
 
828
  /* Now work out the advance.  */
829
  if (strlen (str) == 0)
830
    *strp_in += strlen (*strp_in);
831
 
832
  else
833
    {
834
      if (strstr (*strp_in, str))
835
        /* A macro-expansion was pulled off the front.  */
836
        *strp_in = strstr (*strp_in, str);
837
      else
838
        /* A non-macro-expansion was pulled off the front.  */
839
        *strp_in += (str - hold);
840
    }
841
 
842
  if (hold)
843
    free (hold);
844
 
845
  return errmsg;
846
}
847
 
848
#define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
849
 
850
/* -- dis.c */
851
 
852
#include "elf/mep.h"
853
#include "elf-bfd.h"
854
 
855
#define CGEN_VALIDATE_INSN_SUPPORTED
856
 
857
static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
858
static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
859
 
860
static void
861
print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
862
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
863
             unsigned int flags ATTRIBUTE_UNUSED)
864
{
865
  disassemble_info *info = (disassemble_info *) dis_info;
866
 
867
  (*info->fprintf_func) (info->stream, "$tp");
868
}
869
 
870
static void
871
print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
872
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
873
             unsigned int flags ATTRIBUTE_UNUSED)
874
{
875
  disassemble_info *info = (disassemble_info *) dis_info;
876
 
877
  (*info->fprintf_func) (info->stream, "$sp");
878
}
879
 
880
/* begin-cop-ip-print-handlers */
881
static void
882
print_ivc2_cr (CGEN_CPU_DESC,
883
        void *,
884
        CGEN_KEYWORD *,
885
        long,
886
        unsigned int) ATTRIBUTE_UNUSED;
887
static void
888
print_ivc2_cr (CGEN_CPU_DESC cd,
889
        void *dis_info,
890
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
891
        long value,
892
        unsigned int attrs)
893
{
894
  print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
895
}
896
static void
897
print_ivc2_ccr (CGEN_CPU_DESC,
898
        void *,
899
        CGEN_KEYWORD *,
900
        long,
901
        unsigned int) ATTRIBUTE_UNUSED;
902
static void
903
print_ivc2_ccr (CGEN_CPU_DESC cd,
904
        void *dis_info,
905
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
906
        long value,
907
        unsigned int attrs)
908
{
909
  print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
910
}
911
/* end-cop-ip-print-handlers */
912
 
913
/************************************************************\
914
*********************** Experimental *************************
915
\************************************************************/
916
 
917
#undef  CGEN_PRINT_INSN
918
#define CGEN_PRINT_INSN mep_print_insn
919
 
920
static int
921
mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
922
                      bfd_byte *buf, int corelength, int copro1length,
923
                      int copro2length ATTRIBUTE_UNUSED)
924
{
925
  int i;
926
  int status = 0;
927
  /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
928
  bfd_byte insnbuf[64];
929
 
930
  /* If corelength > 0 then there is a core insn present. It
931
     will be at the beginning of the buffer.  After printing
932
     the core insn, we need to print the + on the next line.  */
933
  if (corelength > 0)
934
    {
935
      int my_status = 0;
936
 
937
      for (i = 0; i < corelength; i++ )
938
        insnbuf[i] = buf[i];
939
      cd->isas = & MEP_CORE_ISA;
940
 
941
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
942
      if (my_status != corelength)
943
        {
944
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
945
          my_status = corelength;
946
        }
947
      status += my_status;
948
 
949
      /* Print the + to indicate that the following copro insn is   */
950
      /* part of a vliw group.                                      */
951
      if (copro1length > 0)
952
        (*info->fprintf_func) (info->stream, " + ");
953
    }
954
 
955
  /* Now all that is left to be processed is the coprocessor insns
956
     In vliw mode, there will always be one.  Its positioning will
957
     be from byte corelength to byte corelength+copro1length -1.
958
     No need to check for existence.   Also, the first vliw insn,
959
     will, as spec'd, always be at least as long as the core insn
960
     so we don't need to flush the buffer.  */
961
  if (copro1length > 0)
962
    {
963
      int my_status = 0;
964
 
965
      for (i = corelength; i < corelength + copro1length; i++ )
966
        insnbuf[i - corelength] = buf[i];
967
 
968
      switch (copro1length)
969
        {
970
        case 0:
971
          break;
972
        case 2:
973
          cd->isas = & MEP_COP16_ISA;
974
          break;
975
        case 4:
976
          cd->isas = & MEP_COP32_ISA;
977
          break;
978
        case 6:
979
          cd->isas = & MEP_COP48_ISA;
980
          break;
981
        case 8:
982
          cd->isas = & MEP_COP64_ISA;
983
          break;
984
        default:
985
          /* Shouldn't be anything but 16,32,48,64.  */
986
          break;
987
        }
988
 
989
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
990
 
991
      if (my_status != copro1length)
992
        {
993
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
994
          my_status = copro1length;
995
        }
996
      status += my_status;
997
    }
998
 
999
#if 0
1000
  /* Now we need to process the second copro insn if it exists. We
1001
     have no guarantee that the second copro insn will be longer
1002
     than the first, so we have to flush the buffer if we are have
1003
     a second copro insn to process.  If present, this insn will
1004
     be in the position from byte corelength+copro1length to byte
1005
     corelength+copro1length+copro2length-1 (which better equal 8
1006
     or else we're in big trouble.  */
1007
  if (copro2length > 0)
1008
    {
1009
      int my_status = 0;
1010
 
1011
      for (i = 0; i < 64 ; i++)
1012
        insnbuf[i] = 0;
1013
 
1014
      for (i = corelength + copro1length; i < 64; i++)
1015
        insnbuf[i - (corelength + copro1length)] = buf[i];
1016
 
1017
      switch (copro2length)
1018
        {
1019
        case 2:
1020
          cd->isas = 1 << ISA_EXT_COP1_16;
1021
          break;
1022
        case 4:
1023
          cd->isas = 1 << ISA_EXT_COP1_32;
1024
          break;
1025
        case 6:
1026
          cd->isas = 1 << ISA_EXT_COP1_48;
1027
          break;
1028
        case 8:
1029
          cd->isas = 1 << ISA_EXT_COP1_64;
1030
          break;
1031
        default:
1032
          /* Shouldn't be anything but 16,32,48,64.  */
1033
          break;
1034
        }
1035
 
1036
      my_status = print_insn (cd, pc, info, insnbuf, copro2length);
1037
 
1038
      if (my_status != copro2length)
1039
        {
1040
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1041
          my_status = copro2length;
1042
        }
1043
 
1044
      status += my_status;
1045
    }
1046
#endif
1047
 
1048
  /* Status should now be the number of bytes that were printed
1049
     which should be 4 for VLIW32 mode and 64 for VLIW64 mode.  */
1050
 
1051
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
1052
    return -1;
1053
  else
1054
    return status;
1055
}
1056
 
1057
/* The two functions mep_examine_vliw[32,64]_insns are used find out
1058
   which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
1059
   with 32 bit copro, etc.) is present.  Later on, when internally
1060
   parallel coprocessors are handled, only these functions should
1061
   need to be changed.
1062
 
1063
   At this time only the following combinations are supported:
1064
 
1065
   VLIW32 Mode:
1066
   16 bit core insn (core) and 16 bit coprocessor insn (cop1)
1067
   32 bit core insn (core)
1068
   32 bit coprocessor insn (cop1)
1069
   Note: As of this time, I do not believe we have enough information
1070
         to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
1071
         no 16 bit coprocessor insns have been specified.
1072
 
1073
   VLIW64 Mode:
1074
   16 bit core insn (core) and 48 bit coprocessor insn (cop1)
1075
   32 bit core insn (core) and 32 bit coprocessor insn (cop1)
1076
   64 bit coprocessor insn (cop1)
1077
 
1078
   The framework for an internally parallel coprocessor is also
1079
   present (2nd coprocessor insn is cop2), but at this time it
1080
   is not used.  This only appears to be valid in VLIW64 mode.  */
1081
 
1082
static int
1083
mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1084
{
1085
  int status;
1086
  int buflength;
1087
  int corebuflength;
1088
  int cop1buflength;
1089
  int cop2buflength;
1090
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1091
  char indicator16[1];
1092
  char indicatorcop32[2];
1093
 
1094
  /* At this time we're not supporting internally parallel coprocessors,
1095
     so cop2buflength will always be 0.  */
1096
  cop2buflength = 0;
1097
 
1098
  /* Read in 32 bits.  */
1099
  buflength = 4; /* VLIW insn spans 4 bytes.  */
1100
  status = (*info->read_memory_func) (pc, buf, buflength, info);
1101
 
1102
  if (status != 0)
1103
    {
1104
      (*info->memory_error_func) (status, pc, info);
1105
      return -1;
1106
    }
1107
 
1108
  /* Put the big endian representation of the bytes to be examined
1109
     in the temporary buffers for examination.  */
1110
 
1111
  if (info->endian == BFD_ENDIAN_BIG)
1112
    {
1113
      indicator16[0] = buf[0];
1114
      indicatorcop32[0] = buf[0];
1115
      indicatorcop32[1] = buf[1];
1116
    }
1117
  else
1118
    {
1119
      indicator16[0] = buf[1];
1120
      indicatorcop32[0] = buf[1];
1121
      indicatorcop32[1] = buf[0];
1122
    }
1123
 
1124
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
1125
     core insn and a 48 bit copro insn.  */
1126
 
1127
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
1128
    {
1129
      if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
1130
        {
1131
          /* We have a 32 bit copro insn.  */
1132
          corebuflength = 0;
1133
          /* All 4 4ytes are one copro insn. */
1134
          cop1buflength = 4;
1135
        }
1136
      else
1137
        {
1138
          /* We have a 32 bit core.  */
1139
          corebuflength = 4;
1140
          cop1buflength = 0;
1141
        }
1142
    }
1143
  else
1144
    {
1145
      /* We have a 16 bit core insn and a 16 bit copro insn.  */
1146
      corebuflength = 2;
1147
      cop1buflength = 2;
1148
    }
1149
 
1150
  /* Now we have the distrubution set.  Print them out.  */
1151
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
1152
                                 cop1buflength, cop2buflength);
1153
 
1154
  return status;
1155
}
1156
 
1157
static int
1158
mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1159
{
1160
  int status;
1161
  int buflength;
1162
  int corebuflength;
1163
  int cop1buflength;
1164
  int cop2buflength;
1165
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1166
  char indicator16[1];
1167
  char indicator64[4];
1168
 
1169
  /* At this time we're not supporting internally parallel
1170
     coprocessors, so cop2buflength will always be 0.  */
1171
  cop2buflength = 0;
1172
 
1173
  /* Read in 64 bits.  */
1174
  buflength = 8; /* VLIW insn spans 8 bytes.  */
1175
  status = (*info->read_memory_func) (pc, buf, buflength, info);
1176
 
1177
  if (status != 0)
1178
    {
1179
      (*info->memory_error_func) (status, pc, info);
1180
      return -1;
1181
    }
1182
 
1183
  /* We have all 64 bits in the buffer now.  We have to figure out
1184
     what combination of instruction sizes are present.  The two
1185
     high order bits will indicate whether or not we have a 16 bit
1186
     core insn or not.  If not, then we have to look at the 7,8th
1187
     bytes to tell whether we have 64 bit copro insn or a 32 bit
1188
     core insn with a 32 bit copro insn.  Endianness will make a
1189
     difference here.  */
1190
 
1191
  /* Put the big endian representation of the bytes to be examined
1192
     in the temporary buffers for examination.  */
1193
 
1194
  /* indicator16[0] = buf[0];  */
1195
  if (info->endian == BFD_ENDIAN_BIG)
1196
    {
1197
      indicator16[0] = buf[0];
1198
      indicator64[0] = buf[0];
1199
      indicator64[1] = buf[1];
1200
      indicator64[2] = buf[2];
1201
      indicator64[3] = buf[3];
1202
    }
1203
  else
1204
    {
1205
      indicator16[0] = buf[1];
1206
      indicator64[0] = buf[1];
1207
      indicator64[1] = buf[0];
1208
      indicator64[2] = buf[3];
1209
      indicator64[3] = buf[2];
1210
    }
1211
 
1212
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
1213
     core insn and a 48 bit copro insn.  */
1214
 
1215
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
1216
    {
1217
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
1218
          && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
1219
        {
1220
          /* We have a 64 bit copro insn.  */
1221
          corebuflength = 0;
1222
          /* All 8 bytes are one copro insn.  */
1223
          cop1buflength = 8;
1224
        }
1225
      else
1226
        {
1227
          /* We have a 32 bit core insn and a 32 bit copro insn.  */
1228
          corebuflength = 4;
1229
          cop1buflength = 4;
1230
        }
1231
    }
1232
  else
1233
    {
1234
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
1235
      corebuflength = 2;
1236
      cop1buflength = 6;
1237
    }
1238
 
1239
  /* Now we have the distrubution set.  Print them out. */
1240
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
1241
                                 cop1buflength, cop2buflength);
1242
 
1243
  return status;
1244
}
1245
 
1246
#ifdef MEP_IVC2_SUPPORTED
1247
 
1248
static int
1249
print_slot_insn (CGEN_CPU_DESC cd,
1250
                 bfd_vma pc,
1251
                 disassemble_info *info,
1252
                 SLOTS_ATTR slot,
1253
                 bfd_byte *buf)
1254
{
1255
  const CGEN_INSN_LIST *insn_list;
1256
  CGEN_INSN_INT insn_value;
1257
  CGEN_EXTRACT_INFO ex_info;
1258
 
1259
  insn_value = cgen_get_insn_value (cd, buf, 32);
1260
 
1261
  /* Fill in ex_info fields like read_insn would.  Don't actually call
1262
     read_insn, since the incoming buffer is already read (and possibly
1263
     modified a la m32r).  */
1264
  ex_info.valid = (1 << 8) - 1;
1265
  ex_info.dis_info = info;
1266
  ex_info.insn_bytes = buf;
1267
 
1268
  /* The instructions are stored in hash lists.
1269
     Pick the first one and keep trying until we find the right one.  */
1270
 
1271
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1272
  while (insn_list != NULL)
1273
    {
1274
      const CGEN_INSN *insn = insn_list->insn;
1275
      CGEN_FIELDS fields;
1276
      int length;
1277
 
1278
      if ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG)
1279
           && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG) != MEP_CONFIG)
1280
          || ! (CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot)))
1281
        {
1282
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1283
          continue;
1284
        }
1285
 
1286
      if ((insn_value & CGEN_INSN_BASE_MASK (insn))
1287
          == CGEN_INSN_BASE_VALUE (insn))
1288
        {
1289
          /* Printing is handled in two passes.  The first pass parses the
1290
             machine insn and extracts the fields.  The second pass prints
1291
             them.  */
1292
 
1293
          length = CGEN_EXTRACT_FN (cd, insn)
1294
            (cd, insn, &ex_info, insn_value, &fields, pc);
1295
 
1296
          /* Length < 0 -> error.  */
1297
          if (length < 0)
1298
            return length;
1299
          if (length > 0)
1300
            {
1301
              CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1302
              /* Length is in bits, result is in bytes.  */
1303
              return length / 8;
1304
            }
1305
        }
1306
 
1307
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1308
    }
1309
 
1310
  if (slot == SLOTS_P0S)
1311
    (*info->fprintf_func) (info->stream, "*unknown-p0s*");
1312
  else if (slot == SLOTS_P0)
1313
    (*info->fprintf_func) (info->stream, "*unknown-p0*");
1314
  else if (slot == SLOTS_P1)
1315
    (*info->fprintf_func) (info->stream, "*unknown-p1*");
1316
  else if (slot == SLOTS_C3)
1317
    (*info->fprintf_func) (info->stream, "*unknown-c3*");
1318
  return 0;
1319
}
1320
 
1321
static int
1322
mep_examine_ivc2_insns (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info ATTRIBUTE_UNUSED)
1323
{
1324
  int status;
1325
  int buflength;
1326
  int cop2buflength;
1327
  bfd_byte buf[8];
1328
  bfd_byte insn[8];
1329
  int e;
1330
 
1331
  /* At this time we're not supporting internally parallel
1332
     coprocessors, so cop2buflength will always be 0.  */
1333
  cop2buflength = 0;
1334
 
1335
  /* Read in 64 bits.  */
1336
  buflength = 8; /* VLIW insn spans 8 bytes.  */
1337
  status = (*info->read_memory_func) (pc, buf, buflength, info);
1338
 
1339
  if (status != 0)
1340
    {
1341
      (*info->memory_error_func) (status, pc, info);
1342
      return -1;
1343
    }
1344
 
1345
  if (info->endian == BFD_ENDIAN_LITTLE)
1346
    e = 1;
1347
  else
1348
    e = 0;
1349
 
1350
  if (((unsigned char)buf[0^e] & 0xf0) < 0xc0)
1351
    {
1352
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1353
      /* V1   [-----core-----][--------p0s-------][------------p1------------] */
1354
 
1355
      print_insn (cd, pc, info, buf, 2);
1356
 
1357
      insn[0^e] = 0;
1358
      insn[1^e] = buf[2^e];
1359
      insn[2^e] = buf[3^e];
1360
      insn[3^e] = buf[4^e] & 0xf0;
1361
      (*info->fprintf_func) (info->stream, " + ");
1362
      print_slot_insn (cd, pc, info, SLOTS_P0S, insn);
1363
 
1364
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1365
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1366
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1367
      insn[3^e] = buf[7^e] << 4;
1368
      (*info->fprintf_func) (info->stream, " + ");
1369
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1370
    }
1371
  else if ((buf[0^e] & 0xf0) == 0xf0 && (buf[1^e] & 0x0f) == 0x07)
1372
    {
1373
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1374
      /* V3   1111[--p0--]0111[--------p0--------][------------p1------------] */
1375
      /*                                          00000000111111112222222233333333 */
1376
 
1377
      insn[0^e] = buf[0^e] << 4 | buf[1^e] >> 4;
1378
      insn[1^e] = buf[2^e];
1379
      insn[2^e] = buf[3^e];
1380
      insn[3^e] = buf[4^e] & 0xf0;
1381
      print_slot_insn (cd, pc, info, SLOTS_P0, insn);
1382
 
1383
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1384
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1385
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1386
      insn[3^e] = buf[7^e] << 4;
1387
      (*info->fprintf_func) (info->stream, " + ");
1388
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1389
    }
1390
  else
1391
    {
1392
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1393
      /* V2   [-------------core-------------]xxxx[------------p1------------] */
1394
      print_insn (cd, pc, info, buf, 4);
1395
 
1396
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1397
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1398
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1399
      insn[3^e] = buf[7^e] << 4;
1400
      (*info->fprintf_func) (info->stream, " + ");
1401
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1402
    }
1403
 
1404
  return 8;
1405
}
1406
 
1407
#endif /* MEP_IVC2_SUPPORTED */
1408
 
1409
/* This is a hack.  SID calls this to update the disassembler as the
1410
   CPU changes modes.  */
1411
static int mep_ivc2_disassemble_p = 0;
1412
static int mep_ivc2_vliw_disassemble_p = 0;
1413
 
1414
void
1415
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx);
1416
void
1417
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx)
1418
{
1419
  mep_ivc2_disassemble_p = ivc2_p;
1420
  mep_ivc2_vliw_disassemble_p = vliw_p;
1421
  mep_config_index = cfg_idx;
1422
}
1423
 
1424
static int
1425
mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1426
{
1427
  int status;
1428
  int cop_type;
1429
  int ivc2 = 0;
1430
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
1431
 
1432
  if (ivc2_core_isa == NULL)
1433
    {
1434
      /* IVC2 has some core-only coprocessor instructions.  We
1435
         use COP32 to flag those, and COP64 for the VLIW ones,
1436
         since they have the same names.  */
1437
      ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
1438
    }
1439
 
1440
  /* Extract and adapt to configuration number, if available. */
1441
  if (info->section && info->section->owner)
1442
    {
1443
      bfd *abfd = info->section->owner;
1444
      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
1445
      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
1446
 
1447
      cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
1448
      if (cop_type == EF_MEP_COP_IVC2)
1449
        ivc2 = 1;
1450
    }
1451
 
1452
  /* Picking the right ISA bitmask for the current context is tricky.  */
1453
  if (info->section)
1454
    {
1455
      if (info->section->flags & SEC_MEP_VLIW)
1456
        {
1457
#ifdef MEP_IVC2_SUPPORTED
1458
          if (ivc2)
1459
            {
1460
              /* ivc2 has its own way of selecting its functions.  */
1461
              cd->isas = & MEP_CORE_ISA;
1462
              status = mep_examine_ivc2_insns (cd, pc, info);
1463
            }
1464
          else
1465
#endif
1466
            /* Are we in 32 or 64 bit vliw mode?  */
1467
            if (MEP_VLIW64)
1468
              status = mep_examine_vliw64_insns (cd, pc, info);
1469
            else
1470
              status = mep_examine_vliw32_insns (cd, pc, info);
1471
          /* Both the above branches set their own isa bitmasks.  */
1472
        }
1473
      else
1474
        {
1475
          if (ivc2)
1476
            {
1477
              cgen_bitset_clear (ivc2_core_isa);
1478
              cgen_bitset_union (ivc2_core_isa, &MEP_CORE_ISA, ivc2_core_isa);
1479
              cgen_bitset_union (ivc2_core_isa, &MEP_COP32_ISA, ivc2_core_isa);
1480
              cd->isas = ivc2_core_isa;
1481
            }
1482
          else
1483
            cd->isas = & MEP_CORE_ISA;
1484
          status = default_print_insn (cd, pc, info);
1485
        }
1486
    }
1487
  else /* sid or gdb */
1488
    {
1489
#ifdef MEP_IVC2_SUPPORTED
1490
      if (mep_ivc2_disassemble_p)
1491
        {
1492
          if (mep_ivc2_vliw_disassemble_p)
1493
            {
1494
              cd->isas = & MEP_CORE_ISA;
1495
              status = mep_examine_ivc2_insns (cd, pc, info);
1496
              return status;
1497
            }
1498
          else
1499
            {
1500
              if (ivc2)
1501
                cd->isas = ivc2_core_isa;
1502
            }
1503
        }
1504
#endif
1505
 
1506
      status = default_print_insn (cd, pc, info);
1507
    }
1508
 
1509
  return status;
1510
}
1511
 
1512
 
1513
/* -- opc.c */
1514
#include "elf/mep.h"
1515
 
1516
/* A mask for all ISAs executed by the core. */
1517
CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask = {0, 0};
1518
 
1519
void
1520
init_mep_all_core_isas_mask (void)
1521
{
1522
  if (mep_all_core_isas_mask.length != 0)
1523
    return;
1524
  cgen_bitset_init (& mep_all_core_isas_mask, ISA_MAX);
1525
  cgen_bitset_set (& mep_all_core_isas_mask, ISA_MEP);
1526
  /* begin-all-core-isas */
1527
  cgen_bitset_add (& mep_all_core_isas_mask, ISA_EXT_CORE1);
1528
  /* end-all-core-isas */
1529
}
1530
 
1531
CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask = {0, 0};
1532
 
1533
void
1534
init_mep_all_cop_isas_mask (void)
1535
{
1536
  if (mep_all_cop_isas_mask.length != 0)
1537
    return;
1538
  cgen_bitset_init (& mep_all_cop_isas_mask, ISA_MAX);
1539
  /* begin-all-cop-isas */
1540
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_16);
1541
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_32);
1542
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_48);
1543
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_64);
1544
  /* end-all-cop-isas */
1545
}
1546
 
1547
int
1548
mep_insn_supported_by_isa (const CGEN_INSN *insn, CGEN_ATTR_VALUE_BITSET_TYPE *isa_mask)
1549
{
1550
  CGEN_BITSET insn_isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
1551
  return cgen_bitset_intersect_p (& insn_isas, isa_mask);
1552
}
1553
 
1554
#define OPTION_MASK \
1555
        ( (1 << CGEN_INSN_OPTIONAL_BIT_INSN) \
1556
        | (1 << CGEN_INSN_OPTIONAL_MUL_INSN) \
1557
        | (1 << CGEN_INSN_OPTIONAL_DIV_INSN) \
1558
        | (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN) \
1559
        | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) \
1560
        | (1 << CGEN_INSN_OPTIONAL_ABS_INSN) \
1561
        | (1 << CGEN_INSN_OPTIONAL_AVE_INSN) \
1562
        | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) \
1563
        | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) \
1564
        | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) \
1565
        | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) \
1566
        | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) \
1567
        | (1 << CGEN_INSN_OPTIONAL_CP_INSN) \
1568
        | (1 << CGEN_INSN_OPTIONAL_CP64_INSN) )
1569
 
1570
 
1571
mep_config_map_struct mep_config_map[] =
1572
{
1573
  /* config-map-start */
1574
  /* Default entry: first module, with all options enabled. */
1575
  { "", 0,  EF_MEP_COP_IVC2 | EF_MEP_CPU_C5,0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" }, OPTION_MASK | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) },
1576
  { "default", CONFIG_DEFAULT, EF_MEP_COP_IVC2 | EF_MEP_CPU_C5, 0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" },
1577
 
1578
        | (1 << CGEN_INSN_OPTIONAL_CP_INSN)
1579
        | (1 << CGEN_INSN_OPTIONAL_CP64_INSN)
1580
        | (1 << CGEN_INSN_OPTIONAL_MUL_INSN)
1581
        | (1 << CGEN_INSN_OPTIONAL_DIV_INSN)
1582
        | (1 << CGEN_INSN_OPTIONAL_BIT_INSN)
1583
        | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN)
1584
        | (1 << CGEN_INSN_OPTIONAL_ABS_INSN)
1585
        | (1 << CGEN_INSN_OPTIONAL_AVE_INSN)
1586
        | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN)
1587
        | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN)
1588
        | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) },
1589
  /* config-map-end */
1590
  { 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0 }
1591
};
1592
 
1593
int mep_config_index = 0;
1594
 
1595
static int
1596
check_configured_mach (int machs)
1597
{
1598
  /* All base insns are supported.  */
1599
  int mach = 1 << MACH_BASE;
1600
  switch (MEP_CPU & EF_MEP_CPU_MASK)
1601
    {
1602
    case EF_MEP_CPU_C2:
1603
    case EF_MEP_CPU_C3:
1604
      mach |= (1 << MACH_MEP);
1605
      break;
1606
    case EF_MEP_CPU_H1:
1607
      mach |= (1 << MACH_H1);
1608
      break;
1609
    case EF_MEP_CPU_C5:
1610
      mach |= (1 << MACH_MEP);
1611
      mach |= (1 << MACH_C5);
1612
      break;
1613
    default:
1614
      break;
1615
    }
1616
  return machs & mach;
1617
}
1618
 
1619
int
1620
mep_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
1621
{
1622
  int iconfig = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG);
1623
  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
1624
  CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
1625
  int ok1;
1626
  int ok2;
1627
  int ok3;
1628
 
1629
  /* If the insn has an option bit set that we don't want,
1630
     reject it.  */
1631
  if (CGEN_INSN_ATTRS (insn)->bool & OPTION_MASK & ~MEP_OMASK)
1632
    return 0;
1633
 
1634
  /* If attributes are absent, assume no restriction. */
1635
  if (machs == 0)
1636
    machs = ~0;
1637
 
1638
  ok1 = ((machs & cd->machs) && cgen_bitset_intersect_p (& isas, cd->isas));
1639
  /* If the insn is config-specific, make sure it matches.  */
1640
  ok2 =  (iconfig == 0 || iconfig == MEP_CONFIG);
1641
  /* Make sure the insn is supported by the configured mach  */
1642
  ok3 = check_configured_mach (machs);
1643
 
1644
  return (ok1 && ok2 && ok3);
1645
}
1646
 
1647
int
1648
mep_cgen_insn_supported_asm (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
1649
{
1650
  /* If we're assembling VLIW packets, ignore the 12-bit BSR as we
1651
     can't relax that.  The 24-bit BSR is matched instead.  */
1652
  if (insn->base->num == MEP_INSN_BSR12
1653
      && cgen_bitset_contains (cd->isas, ISA_EXT_COP1_64))
1654
    return 0;
1655
 
1656
  return mep_cgen_insn_supported (cd, insn);
1657
}

powered by: WebSVN 2.1.0

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