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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [epiphany-ibld.c] - Blame information for rev 299

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

Line No. Rev Author Line
1 163 khays
/* Instruction building/extraction support for epiphany. -*- C -*-
2
 
3
   THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4
   - the resultant file is machine generated, cgen-ibld.in isn't
5
 
6
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007,
7
   2008, 2010  Free Software Foundation, Inc.
8
 
9
   This file is part of libopcodes.
10
 
11
   This library is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 3, or (at your option)
14
   any later version.
15
 
16
   It is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19
   License for more details.
20
 
21
   You should have received a copy of the GNU General Public License
22
   along with this program; if not, write to the Free Software Foundation, Inc.,
23
   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
24
 
25
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
26
   Keep that in mind.  */
27
 
28
#include "sysdep.h"
29
#include <stdio.h>
30
#include "ansidecl.h"
31
#include "dis-asm.h"
32
#include "bfd.h"
33
#include "symcat.h"
34
#include "epiphany-desc.h"
35
#include "epiphany-opc.h"
36
#include "cgen/basic-modes.h"
37
#include "opintl.h"
38
#include "safe-ctype.h"
39
 
40
#undef  min
41
#define min(a,b) ((a) < (b) ? (a) : (b))
42
#undef  max
43
#define max(a,b) ((a) > (b) ? (a) : (b))
44
 
45
/* Used by the ifield rtx function.  */
46
#define FLD(f) (fields->f)
47
 
48
static const char * insert_normal
49
  (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
50
   unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
51
static const char * insert_insn_normal
52
  (CGEN_CPU_DESC, const CGEN_INSN *,
53
   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54
static int extract_normal
55
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
56
   unsigned int, unsigned int, unsigned int, unsigned int,
57
   unsigned int, unsigned int, bfd_vma, long *);
58
static int extract_insn_normal
59
  (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
60
   CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
61
#if CGEN_INT_INSN_P
62
static void put_insn_int_value
63
  (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
64
#endif
65
#if ! CGEN_INT_INSN_P
66
static CGEN_INLINE void insert_1
67
  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68
static CGEN_INLINE int fill_cache
69
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
70
static CGEN_INLINE long extract_1
71
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72
#endif
73
 
74
/* Operand insertion.  */
75
 
76
#if ! CGEN_INT_INSN_P
77
 
78
/* Subroutine of insert_normal.  */
79
 
80
static CGEN_INLINE void
81
insert_1 (CGEN_CPU_DESC cd,
82
          unsigned long value,
83
          int start,
84
          int length,
85
          int word_length,
86
          unsigned char *bufp)
87
{
88
  unsigned long x,mask;
89
  int shift;
90
 
91
  x = cgen_get_insn_value (cd, bufp, word_length);
92
 
93
  /* Written this way to avoid undefined behaviour.  */
94
  mask = (((1L << (length - 1)) - 1) << 1) | 1;
95
  if (CGEN_INSN_LSB0_P)
96
    shift = (start + 1) - length;
97
  else
98
    shift = (word_length - (start + length));
99
  x = (x & ~(mask << shift)) | ((value & mask) << shift);
100
 
101
  cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
102
}
103
 
104
#endif /* ! CGEN_INT_INSN_P */
105
 
106
/* Default insertion routine.
107
 
108
   ATTRS is a mask of the boolean attributes.
109
   WORD_OFFSET is the offset in bits from the start of the insn of the value.
110
   WORD_LENGTH is the length of the word in bits in which the value resides.
111
   START is the starting bit number in the word, architecture origin.
112
   LENGTH is the length of VALUE in bits.
113
   TOTAL_LENGTH is the total length of the insn in bits.
114
 
115
   The result is an error message or NULL if success.  */
116
 
117
/* ??? This duplicates functionality with bfd's howto table and
118
   bfd_install_relocation.  */
119
/* ??? This doesn't handle bfd_vma's.  Create another function when
120
   necessary.  */
121
 
122
static const char *
123
insert_normal (CGEN_CPU_DESC cd,
124
               long value,
125
               unsigned int attrs,
126
               unsigned int word_offset,
127
               unsigned int start,
128
               unsigned int length,
129
               unsigned int word_length,
130
               unsigned int total_length,
131
               CGEN_INSN_BYTES_PTR buffer)
132
{
133
  static char errbuf[100];
134
  /* Written this way to avoid undefined behaviour.  */
135
  unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
136
 
137
  /* If LENGTH is zero, this operand doesn't contribute to the value.  */
138
  if (length == 0)
139
    return NULL;
140
 
141
  if (word_length > 8 * sizeof (CGEN_INSN_INT))
142
    abort ();
143
 
144
  /* For architectures with insns smaller than the base-insn-bitsize,
145
     word_length may be too big.  */
146
  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
147
    {
148
      if (word_offset == 0
149
          && word_length > total_length)
150
        word_length = total_length;
151
    }
152
 
153
  /* Ensure VALUE will fit.  */
154
  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
155
    {
156
      long minval = - (1L << (length - 1));
157
      unsigned long maxval = mask;
158
 
159
      if ((value > 0 && (unsigned long) value > maxval)
160
          || value < minval)
161
        {
162
          /* xgettext:c-format */
163
          sprintf (errbuf,
164
                   _("operand out of range (%ld not between %ld and %lu)"),
165
                   value, minval, maxval);
166
          return errbuf;
167
        }
168
    }
169
  else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
170
    {
171
      unsigned long maxval = mask;
172
      unsigned long val = (unsigned long) value;
173
 
174
      /* For hosts with a word size > 32 check to see if value has been sign
175
         extended beyond 32 bits.  If so then ignore these higher sign bits
176
         as the user is attempting to store a 32-bit signed value into an
177
         unsigned 32-bit field which is allowed.  */
178
      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
179
        val &= 0xFFFFFFFF;
180
 
181
      if (val > maxval)
182
        {
183
          /* xgettext:c-format */
184
          sprintf (errbuf,
185
                   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
186
                   val, maxval);
187
          return errbuf;
188
        }
189
    }
190
  else
191
    {
192
      if (! cgen_signed_overflow_ok_p (cd))
193
        {
194
          long minval = - (1L << (length - 1));
195
          long maxval =   (1L << (length - 1)) - 1;
196
 
197
          if (value < minval || value > maxval)
198
            {
199
              sprintf
200
                /* xgettext:c-format */
201
                (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
202
                 value, minval, maxval);
203
              return errbuf;
204
            }
205
        }
206
    }
207
 
208
#if CGEN_INT_INSN_P
209
 
210
  {
211
    int shift;
212
 
213
    if (CGEN_INSN_LSB0_P)
214
      shift = (word_offset + start + 1) - length;
215
    else
216
      shift = total_length - (word_offset + start + length);
217
    *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
218
  }
219
 
220
#else /* ! CGEN_INT_INSN_P */
221
 
222
  {
223
    unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
224
 
225
    insert_1 (cd, value, start, length, word_length, bufp);
226
  }
227
 
228
#endif /* ! CGEN_INT_INSN_P */
229
 
230
  return NULL;
231
}
232
 
233
/* Default insn builder (insert handler).
234
   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
235
   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
236
   recorded in host byte order, otherwise BUFFER is an array of bytes
237
   and the value is recorded in target byte order).
238
   The result is an error message or NULL if success.  */
239
 
240
static const char *
241
insert_insn_normal (CGEN_CPU_DESC cd,
242
                    const CGEN_INSN * insn,
243
                    CGEN_FIELDS * fields,
244
                    CGEN_INSN_BYTES_PTR buffer,
245
                    bfd_vma pc)
246
{
247
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
248
  unsigned long value;
249
  const CGEN_SYNTAX_CHAR_TYPE * syn;
250
 
251
  CGEN_INIT_INSERT (cd);
252
  value = CGEN_INSN_BASE_VALUE (insn);
253
 
254
  /* If we're recording insns as numbers (rather than a string of bytes),
255
     target byte order handling is deferred until later.  */
256
 
257
#if CGEN_INT_INSN_P
258
 
259
  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
260
                      CGEN_FIELDS_BITSIZE (fields), value);
261
 
262
#else
263
 
264
  cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
265
                                        (unsigned) CGEN_FIELDS_BITSIZE (fields)),
266
                       value);
267
 
268
#endif /* ! CGEN_INT_INSN_P */
269
 
270
  /* ??? It would be better to scan the format's fields.
271
     Still need to be able to insert a value based on the operand though;
272
     e.g. storing a branch displacement that got resolved later.
273
     Needs more thought first.  */
274
 
275
  for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
276
    {
277
      const char *errmsg;
278
 
279
      if (CGEN_SYNTAX_CHAR_P (* syn))
280
        continue;
281
 
282
      errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
283
                                       fields, buffer, pc);
284
      if (errmsg)
285
        return errmsg;
286
    }
287
 
288
  return NULL;
289
}
290
 
291
#if CGEN_INT_INSN_P
292
/* Cover function to store an insn value into an integral insn.  Must go here
293
   because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
294
 
295
static void
296
put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
297
                    CGEN_INSN_BYTES_PTR buf,
298
                    int length,
299
                    int insn_length,
300
                    CGEN_INSN_INT value)
301
{
302
  /* For architectures with insns smaller than the base-insn-bitsize,
303
     length may be too big.  */
304
  if (length > insn_length)
305
    *buf = value;
306
  else
307
    {
308
      int shift = insn_length - length;
309
      /* Written this way to avoid undefined behaviour.  */
310
      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
311
 
312
      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
313
    }
314
}
315
#endif
316
 
317
/* Operand extraction.  */
318
 
319
#if ! CGEN_INT_INSN_P
320
 
321
/* Subroutine of extract_normal.
322
   Ensure sufficient bytes are cached in EX_INFO.
323
   OFFSET is the offset in bytes from the start of the insn of the value.
324
   BYTES is the length of the needed value.
325
   Returns 1 for success, 0 for failure.  */
326
 
327
static CGEN_INLINE int
328
fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
329
            CGEN_EXTRACT_INFO *ex_info,
330
            int offset,
331
            int bytes,
332
            bfd_vma pc)
333
{
334
  /* It's doubtful that the middle part has already been fetched so
335
     we don't optimize that case.  kiss.  */
336
  unsigned int mask;
337
  disassemble_info *info = (disassemble_info *) ex_info->dis_info;
338
 
339
  /* First do a quick check.  */
340
  mask = (1 << bytes) - 1;
341
  if (((ex_info->valid >> offset) & mask) == mask)
342
    return 1;
343
 
344
  /* Search for the first byte we need to read.  */
345
  for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
346
    if (! (mask & ex_info->valid))
347
      break;
348
 
349
  if (bytes)
350
    {
351
      int status;
352
 
353
      pc += offset;
354
      status = (*info->read_memory_func)
355
        (pc, ex_info->insn_bytes + offset, bytes, info);
356
 
357
      if (status != 0)
358
        {
359
          (*info->memory_error_func) (status, pc, info);
360
          return 0;
361
        }
362
 
363
      ex_info->valid |= ((1 << bytes) - 1) << offset;
364
    }
365
 
366
  return 1;
367
}
368
 
369
/* Subroutine of extract_normal.  */
370
 
371
static CGEN_INLINE long
372
extract_1 (CGEN_CPU_DESC cd,
373
           CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
374
           int start,
375
           int length,
376
           int word_length,
377
           unsigned char *bufp,
378
           bfd_vma pc ATTRIBUTE_UNUSED)
379
{
380
  unsigned long x;
381
  int shift;
382
 
383
  x = cgen_get_insn_value (cd, bufp, word_length);
384
 
385
  if (CGEN_INSN_LSB0_P)
386
    shift = (start + 1) - length;
387
  else
388
    shift = (word_length - (start + length));
389
  return x >> shift;
390
}
391
 
392
#endif /* ! CGEN_INT_INSN_P */
393
 
394
/* Default extraction routine.
395
 
396
   INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
397
   or sometimes less for cases like the m32r where the base insn size is 32
398
   but some insns are 16 bits.
399
   ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
400
   but for generality we take a bitmask of all of them.
401
   WORD_OFFSET is the offset in bits from the start of the insn of the value.
402
   WORD_LENGTH is the length of the word in bits in which the value resides.
403
   START is the starting bit number in the word, architecture origin.
404
   LENGTH is the length of VALUE in bits.
405
   TOTAL_LENGTH is the total length of the insn in bits.
406
 
407
   Returns 1 for success, 0 for failure.  */
408
 
409
/* ??? The return code isn't properly used.  wip.  */
410
 
411
/* ??? This doesn't handle bfd_vma's.  Create another function when
412
   necessary.  */
413
 
414
static int
415
extract_normal (CGEN_CPU_DESC cd,
416
#if ! CGEN_INT_INSN_P
417
                CGEN_EXTRACT_INFO *ex_info,
418
#else
419
                CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
420
#endif
421
                CGEN_INSN_INT insn_value,
422
                unsigned int attrs,
423
                unsigned int word_offset,
424
                unsigned int start,
425
                unsigned int length,
426
                unsigned int word_length,
427
                unsigned int total_length,
428
#if ! CGEN_INT_INSN_P
429
                bfd_vma pc,
430
#else
431
                bfd_vma pc ATTRIBUTE_UNUSED,
432
#endif
433
                long *valuep)
434
{
435
  long value, mask;
436
 
437
  /* If LENGTH is zero, this operand doesn't contribute to the value
438
     so give it a standard value of zero.  */
439
  if (length == 0)
440
    {
441
      *valuep = 0;
442
      return 1;
443
    }
444
 
445
  if (word_length > 8 * sizeof (CGEN_INSN_INT))
446
    abort ();
447
 
448
  /* For architectures with insns smaller than the insn-base-bitsize,
449
     word_length may be too big.  */
450
  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
451
    {
452
      if (word_offset + word_length > total_length)
453
        word_length = total_length - word_offset;
454
    }
455
 
456
  /* Does the value reside in INSN_VALUE, and at the right alignment?  */
457
 
458
  if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
459
    {
460
      if (CGEN_INSN_LSB0_P)
461
        value = insn_value >> ((word_offset + start + 1) - length);
462
      else
463
        value = insn_value >> (total_length - ( word_offset + start + length));
464
    }
465
 
466
#if ! CGEN_INT_INSN_P
467
 
468
  else
469
    {
470
      unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
471
 
472
      if (word_length > 8 * sizeof (CGEN_INSN_INT))
473
        abort ();
474
 
475
      if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
476
        return 0;
477
 
478
      value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
479
    }
480
 
481
#endif /* ! CGEN_INT_INSN_P */
482
 
483
  /* Written this way to avoid undefined behaviour.  */
484
  mask = (((1L << (length - 1)) - 1) << 1) | 1;
485
 
486
  value &= mask;
487
  /* sign extend? */
488
  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489
      && (value & (1L << (length - 1))))
490
    value |= ~mask;
491
 
492
  *valuep = value;
493
 
494
  return 1;
495
}
496
 
497
/* Default insn extractor.
498
 
499
   INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
500
   The extracted fields are stored in FIELDS.
501
   EX_INFO is used to handle reading variable length insns.
502
   Return the length of the insn in bits, or 0 if no match,
503
   or -1 if an error occurs fetching data (memory_error_func will have
504
   been called).  */
505
 
506
static int
507
extract_insn_normal (CGEN_CPU_DESC cd,
508
                     const CGEN_INSN *insn,
509
                     CGEN_EXTRACT_INFO *ex_info,
510
                     CGEN_INSN_INT insn_value,
511
                     CGEN_FIELDS *fields,
512
                     bfd_vma pc)
513
{
514
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
515
  const CGEN_SYNTAX_CHAR_TYPE *syn;
516
 
517
  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
518
 
519
  CGEN_INIT_EXTRACT (cd);
520
 
521
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
522
    {
523
      int length;
524
 
525
      if (CGEN_SYNTAX_CHAR_P (*syn))
526
        continue;
527
 
528
      length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
529
                                        ex_info, insn_value, fields, pc);
530
      if (length <= 0)
531
        return length;
532
    }
533
 
534
  /* We recognized and successfully extracted this insn.  */
535
  return CGEN_INSN_BITSIZE (insn);
536
}
537
 
538
/* Machine generated code added here.  */
539
 
540
const char * epiphany_cgen_insert_operand
541
  (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
542
 
543
/* Main entry point for operand insertion.
544
 
545
   This function is basically just a big switch statement.  Earlier versions
546
   used tables to look up the function to use, but
547
   - if the table contains both assembler and disassembler functions then
548
     the disassembler contains much of the assembler and vice-versa,
549
   - there's a lot of inlining possibilities as things grow,
550
   - using a switch statement avoids the function call overhead.
551
 
552
   This function could be moved into `parse_insn_normal', but keeping it
553
   separate makes clear the interface between `parse_insn_normal' and each of
554
   the handlers.  It's also needed by GAS to insert operands that couldn't be
555
   resolved during parsing.  */
556
 
557
const char *
558
epiphany_cgen_insert_operand (CGEN_CPU_DESC cd,
559
                             int opindex,
560
                             CGEN_FIELDS * fields,
561
                             CGEN_INSN_BYTES_PTR buffer,
562
                             bfd_vma pc ATTRIBUTE_UNUSED)
563
{
564
  const char * errmsg = NULL;
565
  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
566
 
567
  switch (opindex)
568
    {
569
    case EPIPHANY_OPERAND_DIRECTION :
570
      errmsg = insert_normal (cd, fields->f_addsubx, 0, 0, 20, 1, 32, total_length, buffer);
571
      break;
572
    case EPIPHANY_OPERAND_DISP11 :
573
      {
574
{
575
  FLD (f_disp8) = ((((UINT) (FLD (f_disp11)) >> (3))) & (255));
576
  FLD (f_disp3) = ((FLD (f_disp11)) & (7));
577
}
578
        errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
579
        if (errmsg)
580
          break;
581
        errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
582
        if (errmsg)
583
          break;
584
      }
585
      break;
586
    case EPIPHANY_OPERAND_DISP3 :
587
      errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
588
      break;
589
    case EPIPHANY_OPERAND_DPMI :
590
      errmsg = insert_normal (cd, fields->f_subd, 0, 0, 24, 1, 32, total_length, buffer);
591
      break;
592
    case EPIPHANY_OPERAND_FRD :
593
      errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
594
      break;
595
    case EPIPHANY_OPERAND_FRD6 :
596
      {
597
{
598
  FLD (f_rd) = ((FLD (f_rd6)) & (7));
599
  FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
600
}
601
        errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
602
        if (errmsg)
603
          break;
604
        errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
605
        if (errmsg)
606
          break;
607
      }
608
      break;
609
    case EPIPHANY_OPERAND_FRM :
610
      errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
611
      break;
612
    case EPIPHANY_OPERAND_FRM6 :
613
      {
614
{
615
  FLD (f_rm) = ((FLD (f_rm6)) & (7));
616
  FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
617
}
618
        errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
619
        if (errmsg)
620
          break;
621
        errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
622
        if (errmsg)
623
          break;
624
      }
625
      break;
626
    case EPIPHANY_OPERAND_FRN :
627
      errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
628
      break;
629
    case EPIPHANY_OPERAND_FRN6 :
630
      {
631
{
632
  FLD (f_rn) = ((FLD (f_rn6)) & (7));
633
  FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
634
}
635
        errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
636
        if (errmsg)
637
          break;
638
        errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
639
        if (errmsg)
640
          break;
641
      }
642
      break;
643
    case EPIPHANY_OPERAND_IMM16 :
644
      {
645
{
646
  FLD (f_imm8) = ((FLD (f_imm16)) & (255));
647
  FLD (f_imm_27_8) = ((UINT) (FLD (f_imm16)) >> (8));
648
}
649
        errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
650
        if (errmsg)
651
          break;
652
        errmsg = insert_normal (cd, fields->f_imm_27_8, 0, 0, 27, 8, 32, total_length, buffer);
653
        if (errmsg)
654
          break;
655
      }
656
      break;
657
    case EPIPHANY_OPERAND_IMM8 :
658
      errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
659
      break;
660
    case EPIPHANY_OPERAND_RD :
661
      errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
662
      break;
663
    case EPIPHANY_OPERAND_RD6 :
664
      {
665
{
666
  FLD (f_rd) = ((FLD (f_rd6)) & (7));
667
  FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
668
}
669
        errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
670
        if (errmsg)
671
          break;
672
        errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
673
        if (errmsg)
674
          break;
675
      }
676
      break;
677
    case EPIPHANY_OPERAND_RM :
678
      errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
679
      break;
680
    case EPIPHANY_OPERAND_RM6 :
681
      {
682
{
683
  FLD (f_rm) = ((FLD (f_rm6)) & (7));
684
  FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
685
}
686
        errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
687
        if (errmsg)
688
          break;
689
        errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
690
        if (errmsg)
691
          break;
692
      }
693
      break;
694
    case EPIPHANY_OPERAND_RN :
695
      errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
696
      break;
697
    case EPIPHANY_OPERAND_RN6 :
698
      {
699
{
700
  FLD (f_rn) = ((FLD (f_rn6)) & (7));
701
  FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
702
}
703
        errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
704
        if (errmsg)
705
          break;
706
        errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
707
        if (errmsg)
708
          break;
709
      }
710
      break;
711
    case EPIPHANY_OPERAND_SD :
712
      errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
713
      break;
714
    case EPIPHANY_OPERAND_SD6 :
715
      {
716
{
717
  FLD (f_sd) = ((FLD (f_sd6)) & (7));
718
  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
719
}
720
        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
721
        if (errmsg)
722
          break;
723
        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
724
        if (errmsg)
725
          break;
726
      }
727
      break;
728
    case EPIPHANY_OPERAND_SDDMA :
729
      {
730
{
731
  FLD (f_sd) = ((FLD (f_sd6)) & (7));
732
  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
733
}
734
        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
735
        if (errmsg)
736
          break;
737
        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
738
        if (errmsg)
739
          break;
740
      }
741
      break;
742
    case EPIPHANY_OPERAND_SDMEM :
743
      {
744
{
745
  FLD (f_sd) = ((FLD (f_sd6)) & (7));
746
  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
747
}
748
        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
749
        if (errmsg)
750
          break;
751
        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
752
        if (errmsg)
753
          break;
754
      }
755
      break;
756
    case EPIPHANY_OPERAND_SDMESH :
757
      {
758
{
759
  FLD (f_sd) = ((FLD (f_sd6)) & (7));
760
  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
761
}
762
        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
763
        if (errmsg)
764
          break;
765
        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
766
        if (errmsg)
767
          break;
768
      }
769
      break;
770
    case EPIPHANY_OPERAND_SHIFT :
771
      errmsg = insert_normal (cd, fields->f_shift, 0, 0, 9, 5, 32, total_length, buffer);
772
      break;
773
    case EPIPHANY_OPERAND_SIMM11 :
774
      {
775
{
776
  FLD (f_disp8) = ((255) & (((USI) (FLD (f_sdisp11)) >> (3))));
777
  FLD (f_disp3) = ((FLD (f_sdisp11)) & (7));
778
}
779
        errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
780
        if (errmsg)
781
          break;
782
        errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
783
        if (errmsg)
784
          break;
785
      }
786
      break;
787
    case EPIPHANY_OPERAND_SIMM24 :
788
      {
789
        long value = fields->f_simm24;
790
        value = ((SI) (((value) - (pc))) >> (1));
791
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, buffer);
792
      }
793
      break;
794
    case EPIPHANY_OPERAND_SIMM3 :
795
      errmsg = insert_normal (cd, fields->f_sdisp3, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, buffer);
796
      break;
797
    case EPIPHANY_OPERAND_SIMM8 :
798
      {
799
        long value = fields->f_simm8;
800
        value = ((SI) (((value) - (pc))) >> (1));
801
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, buffer);
802
      }
803
      break;
804
    case EPIPHANY_OPERAND_SN :
805
      errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
806
      break;
807
    case EPIPHANY_OPERAND_SN6 :
808
      {
809
{
810
  FLD (f_sn) = ((FLD (f_sn6)) & (7));
811
  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
812
}
813
        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
814
        if (errmsg)
815
          break;
816
        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
817
        if (errmsg)
818
          break;
819
      }
820
      break;
821
    case EPIPHANY_OPERAND_SNDMA :
822
      {
823
{
824
  FLD (f_sn) = ((FLD (f_sn6)) & (7));
825
  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
826
}
827
        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
828
        if (errmsg)
829
          break;
830
        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
831
        if (errmsg)
832
          break;
833
      }
834
      break;
835
    case EPIPHANY_OPERAND_SNMEM :
836
      {
837
{
838
  FLD (f_sn) = ((FLD (f_sn6)) & (7));
839
  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
840
}
841
        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
842
        if (errmsg)
843
          break;
844
        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
845
        if (errmsg)
846
          break;
847
      }
848
      break;
849
    case EPIPHANY_OPERAND_SNMESH :
850
      {
851
{
852
  FLD (f_sn) = ((FLD (f_sn6)) & (7));
853
  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
854
}
855
        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
856
        if (errmsg)
857
          break;
858
        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
859
        if (errmsg)
860
          break;
861
      }
862
      break;
863
    case EPIPHANY_OPERAND_SWI_NUM :
864
      errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
865
      break;
866
    case EPIPHANY_OPERAND_TRAPNUM6 :
867
      errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
868
      break;
869
 
870
    default :
871
      /* xgettext:c-format */
872
      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
873
               opindex);
874
      abort ();
875
  }
876
 
877
  return errmsg;
878
}
879
 
880
int epiphany_cgen_extract_operand
881
  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
882
 
883
/* Main entry point for operand extraction.
884
   The result is <= 0 for error, >0 for success.
885
   ??? Actual values aren't well defined right now.
886
 
887
   This function is basically just a big switch statement.  Earlier versions
888
   used tables to look up the function to use, but
889
   - if the table contains both assembler and disassembler functions then
890
     the disassembler contains much of the assembler and vice-versa,
891
   - there's a lot of inlining possibilities as things grow,
892
   - using a switch statement avoids the function call overhead.
893
 
894
   This function could be moved into `print_insn_normal', but keeping it
895
   separate makes clear the interface between `print_insn_normal' and each of
896
   the handlers.  */
897
 
898
int
899
epiphany_cgen_extract_operand (CGEN_CPU_DESC cd,
900
                             int opindex,
901
                             CGEN_EXTRACT_INFO *ex_info,
902
                             CGEN_INSN_INT insn_value,
903
                             CGEN_FIELDS * fields,
904
                             bfd_vma pc)
905
{
906
  /* Assume success (for those operands that are nops).  */
907
  int length = 1;
908
  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
909
 
910
  switch (opindex)
911
    {
912
    case EPIPHANY_OPERAND_DIRECTION :
913
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 1, 32, total_length, pc, & fields->f_addsubx);
914
      break;
915
    case EPIPHANY_OPERAND_DISP11 :
916
      {
917
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
918
        if (length <= 0) break;
919
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
920
        if (length <= 0) break;
921
{
922
  FLD (f_disp11) = ((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)));
923
}
924
      }
925
      break;
926
    case EPIPHANY_OPERAND_DISP3 :
927
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
928
      break;
929
    case EPIPHANY_OPERAND_DPMI :
930
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_subd);
931
      break;
932
    case EPIPHANY_OPERAND_FRD :
933
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
934
      break;
935
    case EPIPHANY_OPERAND_FRD6 :
936
      {
937
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
938
        if (length <= 0) break;
939
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
940
        if (length <= 0) break;
941
{
942
  FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
943
}
944
      }
945
      break;
946
    case EPIPHANY_OPERAND_FRM :
947
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
948
      break;
949
    case EPIPHANY_OPERAND_FRM6 :
950
      {
951
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
952
        if (length <= 0) break;
953
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
954
        if (length <= 0) break;
955
{
956
  FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
957
}
958
      }
959
      break;
960
    case EPIPHANY_OPERAND_FRN :
961
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
962
      break;
963
    case EPIPHANY_OPERAND_FRN6 :
964
      {
965
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
966
        if (length <= 0) break;
967
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
968
        if (length <= 0) break;
969
{
970
  FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
971
}
972
      }
973
      break;
974
    case EPIPHANY_OPERAND_IMM16 :
975
      {
976
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
977
        if (length <= 0) break;
978
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 8, 32, total_length, pc, & fields->f_imm_27_8);
979
        if (length <= 0) break;
980
{
981
  FLD (f_imm16) = ((((FLD (f_imm_27_8)) << (8))) | (FLD (f_imm8)));
982
}
983
      }
984
      break;
985
    case EPIPHANY_OPERAND_IMM8 :
986
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
987
      break;
988
    case EPIPHANY_OPERAND_RD :
989
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
990
      break;
991
    case EPIPHANY_OPERAND_RD6 :
992
      {
993
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
994
        if (length <= 0) break;
995
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
996
        if (length <= 0) break;
997
{
998
  FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
999
}
1000
      }
1001
      break;
1002
    case EPIPHANY_OPERAND_RM :
1003
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1004
      break;
1005
    case EPIPHANY_OPERAND_RM6 :
1006
      {
1007
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
1008
        if (length <= 0) break;
1009
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1010
        if (length <= 0) break;
1011
{
1012
  FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
1013
}
1014
      }
1015
      break;
1016
    case EPIPHANY_OPERAND_RN :
1017
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1018
      break;
1019
    case EPIPHANY_OPERAND_RN6 :
1020
      {
1021
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
1022
        if (length <= 0) break;
1023
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1024
        if (length <= 0) break;
1025
{
1026
  FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
1027
}
1028
      }
1029
      break;
1030
    case EPIPHANY_OPERAND_SD :
1031
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1032
      break;
1033
    case EPIPHANY_OPERAND_SD6 :
1034
      {
1035
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1036
        if (length <= 0) break;
1037
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1038
        if (length <= 0) break;
1039
{
1040
  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1041
}
1042
      }
1043
      break;
1044
    case EPIPHANY_OPERAND_SDDMA :
1045
      {
1046
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1047
        if (length <= 0) break;
1048
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1049
        if (length <= 0) break;
1050
{
1051
  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1052
}
1053
      }
1054
      break;
1055
    case EPIPHANY_OPERAND_SDMEM :
1056
      {
1057
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1058
        if (length <= 0) break;
1059
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1060
        if (length <= 0) break;
1061
{
1062
  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1063
}
1064
      }
1065
      break;
1066
    case EPIPHANY_OPERAND_SDMESH :
1067
      {
1068
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1069
        if (length <= 0) break;
1070
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1071
        if (length <= 0) break;
1072
{
1073
  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1074
}
1075
      }
1076
      break;
1077
    case EPIPHANY_OPERAND_SHIFT :
1078
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & fields->f_shift);
1079
      break;
1080
    case EPIPHANY_OPERAND_SIMM11 :
1081
      {
1082
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
1083
        if (length <= 0) break;
1084
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
1085
        if (length <= 0) break;
1086
{
1087
  FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21));
1088
}
1089
      }
1090
      break;
1091
    case EPIPHANY_OPERAND_SIMM24 :
1092
      {
1093
        long value;
1094
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, pc, & value);
1095
        value = ((((value) << (1))) + (pc));
1096
        fields->f_simm24 = value;
1097
      }
1098
      break;
1099
    case EPIPHANY_OPERAND_SIMM3 :
1100
      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, pc, & fields->f_sdisp3);
1101
      break;
1102
    case EPIPHANY_OPERAND_SIMM8 :
1103
      {
1104
        long value;
1105
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, pc, & value);
1106
        value = ((((value) << (1))) + (pc));
1107
        fields->f_simm8 = value;
1108
      }
1109
      break;
1110
    case EPIPHANY_OPERAND_SN :
1111
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1112
      break;
1113
    case EPIPHANY_OPERAND_SN6 :
1114
      {
1115
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1116
        if (length <= 0) break;
1117
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1118
        if (length <= 0) break;
1119
{
1120
  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1121
}
1122
      }
1123
      break;
1124
    case EPIPHANY_OPERAND_SNDMA :
1125
      {
1126
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1127
        if (length <= 0) break;
1128
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1129
        if (length <= 0) break;
1130
{
1131
  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1132
}
1133
      }
1134
      break;
1135
    case EPIPHANY_OPERAND_SNMEM :
1136
      {
1137
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1138
        if (length <= 0) break;
1139
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1140
        if (length <= 0) break;
1141
{
1142
  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1143
}
1144
      }
1145
      break;
1146
    case EPIPHANY_OPERAND_SNMESH :
1147
      {
1148
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1149
        if (length <= 0) break;
1150
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1151
        if (length <= 0) break;
1152
{
1153
  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1154
}
1155
      }
1156
      break;
1157
    case EPIPHANY_OPERAND_SWI_NUM :
1158
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1159
      break;
1160
    case EPIPHANY_OPERAND_TRAPNUM6 :
1161
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1162
      break;
1163
 
1164
    default :
1165
      /* xgettext:c-format */
1166
      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
1167
               opindex);
1168
      abort ();
1169
    }
1170
 
1171
  return length;
1172
}
1173
 
1174
cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
1175
{
1176
  insert_insn_normal,
1177
};
1178
 
1179
cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
1180
{
1181
  extract_insn_normal,
1182
};
1183
 
1184
int epiphany_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1185
bfd_vma epiphany_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1186
 
1187
/* Getting values from cgen_fields is handled by a collection of functions.
1188
   They are distinguished by the type of the VALUE argument they return.
1189
   TODO: floating point, inlining support, remove cases where result type
1190
   not appropriate.  */
1191
 
1192
int
1193
epiphany_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1194
                             int opindex,
1195
                             const CGEN_FIELDS * fields)
1196
{
1197
  int value;
1198
 
1199
  switch (opindex)
1200
    {
1201
    case EPIPHANY_OPERAND_DIRECTION :
1202
      value = fields->f_addsubx;
1203
      break;
1204
    case EPIPHANY_OPERAND_DISP11 :
1205
      value = fields->f_disp11;
1206
      break;
1207
    case EPIPHANY_OPERAND_DISP3 :
1208
      value = fields->f_disp3;
1209
      break;
1210
    case EPIPHANY_OPERAND_DPMI :
1211
      value = fields->f_subd;
1212
      break;
1213
    case EPIPHANY_OPERAND_FRD :
1214
      value = fields->f_rd;
1215
      break;
1216
    case EPIPHANY_OPERAND_FRD6 :
1217
      value = fields->f_rd6;
1218
      break;
1219
    case EPIPHANY_OPERAND_FRM :
1220
      value = fields->f_rm;
1221
      break;
1222
    case EPIPHANY_OPERAND_FRM6 :
1223
      value = fields->f_rm6;
1224
      break;
1225
    case EPIPHANY_OPERAND_FRN :
1226
      value = fields->f_rn;
1227
      break;
1228
    case EPIPHANY_OPERAND_FRN6 :
1229
      value = fields->f_rn6;
1230
      break;
1231
    case EPIPHANY_OPERAND_IMM16 :
1232
      value = fields->f_imm16;
1233
      break;
1234
    case EPIPHANY_OPERAND_IMM8 :
1235
      value = fields->f_imm8;
1236
      break;
1237
    case EPIPHANY_OPERAND_RD :
1238
      value = fields->f_rd;
1239
      break;
1240
    case EPIPHANY_OPERAND_RD6 :
1241
      value = fields->f_rd6;
1242
      break;
1243
    case EPIPHANY_OPERAND_RM :
1244
      value = fields->f_rm;
1245
      break;
1246
    case EPIPHANY_OPERAND_RM6 :
1247
      value = fields->f_rm6;
1248
      break;
1249
    case EPIPHANY_OPERAND_RN :
1250
      value = fields->f_rn;
1251
      break;
1252
    case EPIPHANY_OPERAND_RN6 :
1253
      value = fields->f_rn6;
1254
      break;
1255
    case EPIPHANY_OPERAND_SD :
1256
      value = fields->f_sd;
1257
      break;
1258
    case EPIPHANY_OPERAND_SD6 :
1259
      value = fields->f_sd6;
1260
      break;
1261
    case EPIPHANY_OPERAND_SDDMA :
1262
      value = fields->f_sd6;
1263
      break;
1264
    case EPIPHANY_OPERAND_SDMEM :
1265
      value = fields->f_sd6;
1266
      break;
1267
    case EPIPHANY_OPERAND_SDMESH :
1268
      value = fields->f_sd6;
1269
      break;
1270
    case EPIPHANY_OPERAND_SHIFT :
1271
      value = fields->f_shift;
1272
      break;
1273
    case EPIPHANY_OPERAND_SIMM11 :
1274
      value = fields->f_sdisp11;
1275
      break;
1276
    case EPIPHANY_OPERAND_SIMM24 :
1277
      value = fields->f_simm24;
1278
      break;
1279
    case EPIPHANY_OPERAND_SIMM3 :
1280
      value = fields->f_sdisp3;
1281
      break;
1282
    case EPIPHANY_OPERAND_SIMM8 :
1283
      value = fields->f_simm8;
1284
      break;
1285
    case EPIPHANY_OPERAND_SN :
1286
      value = fields->f_sn;
1287
      break;
1288
    case EPIPHANY_OPERAND_SN6 :
1289
      value = fields->f_sn6;
1290
      break;
1291
    case EPIPHANY_OPERAND_SNDMA :
1292
      value = fields->f_sn6;
1293
      break;
1294
    case EPIPHANY_OPERAND_SNMEM :
1295
      value = fields->f_sn6;
1296
      break;
1297
    case EPIPHANY_OPERAND_SNMESH :
1298
      value = fields->f_sn6;
1299
      break;
1300
    case EPIPHANY_OPERAND_SWI_NUM :
1301
      value = fields->f_trap_num;
1302
      break;
1303
    case EPIPHANY_OPERAND_TRAPNUM6 :
1304
      value = fields->f_trap_num;
1305
      break;
1306
 
1307
    default :
1308
      /* xgettext:c-format */
1309
      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1310
                       opindex);
1311
      abort ();
1312
  }
1313
 
1314
  return value;
1315
}
1316
 
1317
bfd_vma
1318
epiphany_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1319
                             int opindex,
1320
                             const CGEN_FIELDS * fields)
1321
{
1322
  bfd_vma value;
1323
 
1324
  switch (opindex)
1325
    {
1326
    case EPIPHANY_OPERAND_DIRECTION :
1327
      value = fields->f_addsubx;
1328
      break;
1329
    case EPIPHANY_OPERAND_DISP11 :
1330
      value = fields->f_disp11;
1331
      break;
1332
    case EPIPHANY_OPERAND_DISP3 :
1333
      value = fields->f_disp3;
1334
      break;
1335
    case EPIPHANY_OPERAND_DPMI :
1336
      value = fields->f_subd;
1337
      break;
1338
    case EPIPHANY_OPERAND_FRD :
1339
      value = fields->f_rd;
1340
      break;
1341
    case EPIPHANY_OPERAND_FRD6 :
1342
      value = fields->f_rd6;
1343
      break;
1344
    case EPIPHANY_OPERAND_FRM :
1345
      value = fields->f_rm;
1346
      break;
1347
    case EPIPHANY_OPERAND_FRM6 :
1348
      value = fields->f_rm6;
1349
      break;
1350
    case EPIPHANY_OPERAND_FRN :
1351
      value = fields->f_rn;
1352
      break;
1353
    case EPIPHANY_OPERAND_FRN6 :
1354
      value = fields->f_rn6;
1355
      break;
1356
    case EPIPHANY_OPERAND_IMM16 :
1357
      value = fields->f_imm16;
1358
      break;
1359
    case EPIPHANY_OPERAND_IMM8 :
1360
      value = fields->f_imm8;
1361
      break;
1362
    case EPIPHANY_OPERAND_RD :
1363
      value = fields->f_rd;
1364
      break;
1365
    case EPIPHANY_OPERAND_RD6 :
1366
      value = fields->f_rd6;
1367
      break;
1368
    case EPIPHANY_OPERAND_RM :
1369
      value = fields->f_rm;
1370
      break;
1371
    case EPIPHANY_OPERAND_RM6 :
1372
      value = fields->f_rm6;
1373
      break;
1374
    case EPIPHANY_OPERAND_RN :
1375
      value = fields->f_rn;
1376
      break;
1377
    case EPIPHANY_OPERAND_RN6 :
1378
      value = fields->f_rn6;
1379
      break;
1380
    case EPIPHANY_OPERAND_SD :
1381
      value = fields->f_sd;
1382
      break;
1383
    case EPIPHANY_OPERAND_SD6 :
1384
      value = fields->f_sd6;
1385
      break;
1386
    case EPIPHANY_OPERAND_SDDMA :
1387
      value = fields->f_sd6;
1388
      break;
1389
    case EPIPHANY_OPERAND_SDMEM :
1390
      value = fields->f_sd6;
1391
      break;
1392
    case EPIPHANY_OPERAND_SDMESH :
1393
      value = fields->f_sd6;
1394
      break;
1395
    case EPIPHANY_OPERAND_SHIFT :
1396
      value = fields->f_shift;
1397
      break;
1398
    case EPIPHANY_OPERAND_SIMM11 :
1399
      value = fields->f_sdisp11;
1400
      break;
1401
    case EPIPHANY_OPERAND_SIMM24 :
1402
      value = fields->f_simm24;
1403
      break;
1404
    case EPIPHANY_OPERAND_SIMM3 :
1405
      value = fields->f_sdisp3;
1406
      break;
1407
    case EPIPHANY_OPERAND_SIMM8 :
1408
      value = fields->f_simm8;
1409
      break;
1410
    case EPIPHANY_OPERAND_SN :
1411
      value = fields->f_sn;
1412
      break;
1413
    case EPIPHANY_OPERAND_SN6 :
1414
      value = fields->f_sn6;
1415
      break;
1416
    case EPIPHANY_OPERAND_SNDMA :
1417
      value = fields->f_sn6;
1418
      break;
1419
    case EPIPHANY_OPERAND_SNMEM :
1420
      value = fields->f_sn6;
1421
      break;
1422
    case EPIPHANY_OPERAND_SNMESH :
1423
      value = fields->f_sn6;
1424
      break;
1425
    case EPIPHANY_OPERAND_SWI_NUM :
1426
      value = fields->f_trap_num;
1427
      break;
1428
    case EPIPHANY_OPERAND_TRAPNUM6 :
1429
      value = fields->f_trap_num;
1430
      break;
1431
 
1432
    default :
1433
      /* xgettext:c-format */
1434
      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1435
                       opindex);
1436
      abort ();
1437
  }
1438
 
1439
  return value;
1440
}
1441
 
1442
void epiphany_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1443
void epiphany_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1444
 
1445
/* Stuffing values in cgen_fields is handled by a collection of functions.
1446
   They are distinguished by the type of the VALUE argument they accept.
1447
   TODO: floating point, inlining support, remove cases where argument type
1448
   not appropriate.  */
1449
 
1450
void
1451
epiphany_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1452
                             int opindex,
1453
                             CGEN_FIELDS * fields,
1454
                             int value)
1455
{
1456
  switch (opindex)
1457
    {
1458
    case EPIPHANY_OPERAND_DIRECTION :
1459
      fields->f_addsubx = value;
1460
      break;
1461
    case EPIPHANY_OPERAND_DISP11 :
1462
      fields->f_disp11 = value;
1463
      break;
1464
    case EPIPHANY_OPERAND_DISP3 :
1465
      fields->f_disp3 = value;
1466
      break;
1467
    case EPIPHANY_OPERAND_DPMI :
1468
      fields->f_subd = value;
1469
      break;
1470
    case EPIPHANY_OPERAND_FRD :
1471
      fields->f_rd = value;
1472
      break;
1473
    case EPIPHANY_OPERAND_FRD6 :
1474
      fields->f_rd6 = value;
1475
      break;
1476
    case EPIPHANY_OPERAND_FRM :
1477
      fields->f_rm = value;
1478
      break;
1479
    case EPIPHANY_OPERAND_FRM6 :
1480
      fields->f_rm6 = value;
1481
      break;
1482
    case EPIPHANY_OPERAND_FRN :
1483
      fields->f_rn = value;
1484
      break;
1485
    case EPIPHANY_OPERAND_FRN6 :
1486
      fields->f_rn6 = value;
1487
      break;
1488
    case EPIPHANY_OPERAND_IMM16 :
1489
      fields->f_imm16 = value;
1490
      break;
1491
    case EPIPHANY_OPERAND_IMM8 :
1492
      fields->f_imm8 = value;
1493
      break;
1494
    case EPIPHANY_OPERAND_RD :
1495
      fields->f_rd = value;
1496
      break;
1497
    case EPIPHANY_OPERAND_RD6 :
1498
      fields->f_rd6 = value;
1499
      break;
1500
    case EPIPHANY_OPERAND_RM :
1501
      fields->f_rm = value;
1502
      break;
1503
    case EPIPHANY_OPERAND_RM6 :
1504
      fields->f_rm6 = value;
1505
      break;
1506
    case EPIPHANY_OPERAND_RN :
1507
      fields->f_rn = value;
1508
      break;
1509
    case EPIPHANY_OPERAND_RN6 :
1510
      fields->f_rn6 = value;
1511
      break;
1512
    case EPIPHANY_OPERAND_SD :
1513
      fields->f_sd = value;
1514
      break;
1515
    case EPIPHANY_OPERAND_SD6 :
1516
      fields->f_sd6 = value;
1517
      break;
1518
    case EPIPHANY_OPERAND_SDDMA :
1519
      fields->f_sd6 = value;
1520
      break;
1521
    case EPIPHANY_OPERAND_SDMEM :
1522
      fields->f_sd6 = value;
1523
      break;
1524
    case EPIPHANY_OPERAND_SDMESH :
1525
      fields->f_sd6 = value;
1526
      break;
1527
    case EPIPHANY_OPERAND_SHIFT :
1528
      fields->f_shift = value;
1529
      break;
1530
    case EPIPHANY_OPERAND_SIMM11 :
1531
      fields->f_sdisp11 = value;
1532
      break;
1533
    case EPIPHANY_OPERAND_SIMM24 :
1534
      fields->f_simm24 = value;
1535
      break;
1536
    case EPIPHANY_OPERAND_SIMM3 :
1537
      fields->f_sdisp3 = value;
1538
      break;
1539
    case EPIPHANY_OPERAND_SIMM8 :
1540
      fields->f_simm8 = value;
1541
      break;
1542
    case EPIPHANY_OPERAND_SN :
1543
      fields->f_sn = value;
1544
      break;
1545
    case EPIPHANY_OPERAND_SN6 :
1546
      fields->f_sn6 = value;
1547
      break;
1548
    case EPIPHANY_OPERAND_SNDMA :
1549
      fields->f_sn6 = value;
1550
      break;
1551
    case EPIPHANY_OPERAND_SNMEM :
1552
      fields->f_sn6 = value;
1553
      break;
1554
    case EPIPHANY_OPERAND_SNMESH :
1555
      fields->f_sn6 = value;
1556
      break;
1557
    case EPIPHANY_OPERAND_SWI_NUM :
1558
      fields->f_trap_num = value;
1559
      break;
1560
    case EPIPHANY_OPERAND_TRAPNUM6 :
1561
      fields->f_trap_num = value;
1562
      break;
1563
 
1564
    default :
1565
      /* xgettext:c-format */
1566
      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1567
                       opindex);
1568
      abort ();
1569
  }
1570
}
1571
 
1572
void
1573
epiphany_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1574
                             int opindex,
1575
                             CGEN_FIELDS * fields,
1576
                             bfd_vma value)
1577
{
1578
  switch (opindex)
1579
    {
1580
    case EPIPHANY_OPERAND_DIRECTION :
1581
      fields->f_addsubx = value;
1582
      break;
1583
    case EPIPHANY_OPERAND_DISP11 :
1584
      fields->f_disp11 = value;
1585
      break;
1586
    case EPIPHANY_OPERAND_DISP3 :
1587
      fields->f_disp3 = value;
1588
      break;
1589
    case EPIPHANY_OPERAND_DPMI :
1590
      fields->f_subd = value;
1591
      break;
1592
    case EPIPHANY_OPERAND_FRD :
1593
      fields->f_rd = value;
1594
      break;
1595
    case EPIPHANY_OPERAND_FRD6 :
1596
      fields->f_rd6 = value;
1597
      break;
1598
    case EPIPHANY_OPERAND_FRM :
1599
      fields->f_rm = value;
1600
      break;
1601
    case EPIPHANY_OPERAND_FRM6 :
1602
      fields->f_rm6 = value;
1603
      break;
1604
    case EPIPHANY_OPERAND_FRN :
1605
      fields->f_rn = value;
1606
      break;
1607
    case EPIPHANY_OPERAND_FRN6 :
1608
      fields->f_rn6 = value;
1609
      break;
1610
    case EPIPHANY_OPERAND_IMM16 :
1611
      fields->f_imm16 = value;
1612
      break;
1613
    case EPIPHANY_OPERAND_IMM8 :
1614
      fields->f_imm8 = value;
1615
      break;
1616
    case EPIPHANY_OPERAND_RD :
1617
      fields->f_rd = value;
1618
      break;
1619
    case EPIPHANY_OPERAND_RD6 :
1620
      fields->f_rd6 = value;
1621
      break;
1622
    case EPIPHANY_OPERAND_RM :
1623
      fields->f_rm = value;
1624
      break;
1625
    case EPIPHANY_OPERAND_RM6 :
1626
      fields->f_rm6 = value;
1627
      break;
1628
    case EPIPHANY_OPERAND_RN :
1629
      fields->f_rn = value;
1630
      break;
1631
    case EPIPHANY_OPERAND_RN6 :
1632
      fields->f_rn6 = value;
1633
      break;
1634
    case EPIPHANY_OPERAND_SD :
1635
      fields->f_sd = value;
1636
      break;
1637
    case EPIPHANY_OPERAND_SD6 :
1638
      fields->f_sd6 = value;
1639
      break;
1640
    case EPIPHANY_OPERAND_SDDMA :
1641
      fields->f_sd6 = value;
1642
      break;
1643
    case EPIPHANY_OPERAND_SDMEM :
1644
      fields->f_sd6 = value;
1645
      break;
1646
    case EPIPHANY_OPERAND_SDMESH :
1647
      fields->f_sd6 = value;
1648
      break;
1649
    case EPIPHANY_OPERAND_SHIFT :
1650
      fields->f_shift = value;
1651
      break;
1652
    case EPIPHANY_OPERAND_SIMM11 :
1653
      fields->f_sdisp11 = value;
1654
      break;
1655
    case EPIPHANY_OPERAND_SIMM24 :
1656
      fields->f_simm24 = value;
1657
      break;
1658
    case EPIPHANY_OPERAND_SIMM3 :
1659
      fields->f_sdisp3 = value;
1660
      break;
1661
    case EPIPHANY_OPERAND_SIMM8 :
1662
      fields->f_simm8 = value;
1663
      break;
1664
    case EPIPHANY_OPERAND_SN :
1665
      fields->f_sn = value;
1666
      break;
1667
    case EPIPHANY_OPERAND_SN6 :
1668
      fields->f_sn6 = value;
1669
      break;
1670
    case EPIPHANY_OPERAND_SNDMA :
1671
      fields->f_sn6 = value;
1672
      break;
1673
    case EPIPHANY_OPERAND_SNMEM :
1674
      fields->f_sn6 = value;
1675
      break;
1676
    case EPIPHANY_OPERAND_SNMESH :
1677
      fields->f_sn6 = value;
1678
      break;
1679
    case EPIPHANY_OPERAND_SWI_NUM :
1680
      fields->f_trap_num = value;
1681
      break;
1682
    case EPIPHANY_OPERAND_TRAPNUM6 :
1683
      fields->f_trap_num = value;
1684
      break;
1685
 
1686
    default :
1687
      /* xgettext:c-format */
1688
      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1689
                       opindex);
1690
      abort ();
1691
  }
1692
}
1693
 
1694
/* Function to call before using the instruction builder tables.  */
1695
 
1696
void
1697
epiphany_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1698
{
1699
  cd->insert_handlers = & epiphany_cgen_insert_handlers[0];
1700
  cd->extract_handlers = & epiphany_cgen_extract_handlers[0];
1701
 
1702
  cd->insert_operand = epiphany_cgen_insert_operand;
1703
  cd->extract_operand = epiphany_cgen_extract_operand;
1704
 
1705
  cd->get_int_operand = epiphany_cgen_get_int_operand;
1706
  cd->set_int_operand = epiphany_cgen_set_int_operand;
1707
  cd->get_vma_operand = epiphany_cgen_get_vma_operand;
1708
  cd->set_vma_operand = epiphany_cgen_set_vma_operand;
1709
}

powered by: WebSVN 2.1.0

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