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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 18 khays
/* Instruction building/extraction support for fr30. -*- 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 "fr30-desc.h"
35
#include "fr30-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 * fr30_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
fr30_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 FR30_OPERAND_CRI :
570
      errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
571
      break;
572
    case FR30_OPERAND_CRJ :
573
      errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
574
      break;
575
    case FR30_OPERAND_R13 :
576
      break;
577
    case FR30_OPERAND_R14 :
578
      break;
579
    case FR30_OPERAND_R15 :
580
      break;
581
    case FR30_OPERAND_RI :
582
      errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
583
      break;
584
    case FR30_OPERAND_RIC :
585
      errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
586
      break;
587
    case FR30_OPERAND_RJ :
588
      errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
589
      break;
590
    case FR30_OPERAND_RJC :
591
      errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
592
      break;
593
    case FR30_OPERAND_RS1 :
594
      errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
595
      break;
596
    case FR30_OPERAND_RS2 :
597
      errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
598
      break;
599
    case FR30_OPERAND_CC :
600
      errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
601
      break;
602
    case FR30_OPERAND_CCC :
603
      errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
604
      break;
605
    case FR30_OPERAND_DIR10 :
606
      {
607
        long value = fields->f_dir10;
608
        value = ((USI) (value) >> (2));
609
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
610
      }
611
      break;
612
    case FR30_OPERAND_DIR8 :
613
      errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
614
      break;
615
    case FR30_OPERAND_DIR9 :
616
      {
617
        long value = fields->f_dir9;
618
        value = ((USI) (value) >> (1));
619
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
620
      }
621
      break;
622
    case FR30_OPERAND_DISP10 :
623
      {
624
        long value = fields->f_disp10;
625
        value = ((SI) (value) >> (2));
626
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
627
      }
628
      break;
629
    case FR30_OPERAND_DISP8 :
630
      errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
631
      break;
632
    case FR30_OPERAND_DISP9 :
633
      {
634
        long value = fields->f_disp9;
635
        value = ((SI) (value) >> (1));
636
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
637
      }
638
      break;
639
    case FR30_OPERAND_I20 :
640
      {
641
{
642
  FLD (f_i20_4) = ((UINT) (FLD (f_i20)) >> (16));
643
  FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
644
}
645
        errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
646
        if (errmsg)
647
          break;
648
        errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
649
        if (errmsg)
650
          break;
651
      }
652
      break;
653
    case FR30_OPERAND_I32 :
654
      errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
655
      break;
656
    case FR30_OPERAND_I8 :
657
      errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
658
      break;
659
    case FR30_OPERAND_LABEL12 :
660
      {
661
        long value = fields->f_rel12;
662
        value = ((SI) (((value) - (((pc) + (2))))) >> (1));
663
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
664
      }
665
      break;
666
    case FR30_OPERAND_LABEL9 :
667
      {
668
        long value = fields->f_rel9;
669
        value = ((SI) (((value) - (((pc) + (2))))) >> (1));
670
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
671
      }
672
      break;
673
    case FR30_OPERAND_M4 :
674
      {
675
        long value = fields->f_m4;
676
        value = ((value) & (15));
677
        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
678
      }
679
      break;
680
    case FR30_OPERAND_PS :
681
      break;
682
    case FR30_OPERAND_REGLIST_HI_LD :
683
      errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
684
      break;
685
    case FR30_OPERAND_REGLIST_HI_ST :
686
      errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
687
      break;
688
    case FR30_OPERAND_REGLIST_LOW_LD :
689
      errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
690
      break;
691
    case FR30_OPERAND_REGLIST_LOW_ST :
692
      errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
693
      break;
694
    case FR30_OPERAND_S10 :
695
      {
696
        long value = fields->f_s10;
697
        value = ((SI) (value) >> (2));
698
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
699
      }
700
      break;
701
    case FR30_OPERAND_U10 :
702
      {
703
        long value = fields->f_u10;
704
        value = ((USI) (value) >> (2));
705
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
706
      }
707
      break;
708
    case FR30_OPERAND_U4 :
709
      errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
710
      break;
711
    case FR30_OPERAND_U4C :
712
      errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
713
      break;
714
    case FR30_OPERAND_U8 :
715
      errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
716
      break;
717
    case FR30_OPERAND_UDISP6 :
718
      {
719
        long value = fields->f_udisp6;
720
        value = ((USI) (value) >> (2));
721
        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
722
      }
723
      break;
724
 
725
    default :
726
      /* xgettext:c-format */
727
      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
728
               opindex);
729
      abort ();
730
  }
731
 
732
  return errmsg;
733
}
734
 
735
int fr30_cgen_extract_operand
736
  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
737
 
738
/* Main entry point for operand extraction.
739
   The result is <= 0 for error, >0 for success.
740
   ??? Actual values aren't well defined right now.
741
 
742
   This function is basically just a big switch statement.  Earlier versions
743
   used tables to look up the function to use, but
744
   - if the table contains both assembler and disassembler functions then
745
     the disassembler contains much of the assembler and vice-versa,
746
   - there's a lot of inlining possibilities as things grow,
747
   - using a switch statement avoids the function call overhead.
748
 
749
   This function could be moved into `print_insn_normal', but keeping it
750
   separate makes clear the interface between `print_insn_normal' and each of
751
   the handlers.  */
752
 
753
int
754
fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
755
                             int opindex,
756
                             CGEN_EXTRACT_INFO *ex_info,
757
                             CGEN_INSN_INT insn_value,
758
                             CGEN_FIELDS * fields,
759
                             bfd_vma pc)
760
{
761
  /* Assume success (for those operands that are nops).  */
762
  int length = 1;
763
  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
764
 
765
  switch (opindex)
766
    {
767
    case FR30_OPERAND_CRI :
768
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
769
      break;
770
    case FR30_OPERAND_CRJ :
771
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
772
      break;
773
    case FR30_OPERAND_R13 :
774
      break;
775
    case FR30_OPERAND_R14 :
776
      break;
777
    case FR30_OPERAND_R15 :
778
      break;
779
    case FR30_OPERAND_RI :
780
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
781
      break;
782
    case FR30_OPERAND_RIC :
783
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
784
      break;
785
    case FR30_OPERAND_RJ :
786
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
787
      break;
788
    case FR30_OPERAND_RJC :
789
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
790
      break;
791
    case FR30_OPERAND_RS1 :
792
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
793
      break;
794
    case FR30_OPERAND_RS2 :
795
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
796
      break;
797
    case FR30_OPERAND_CC :
798
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
799
      break;
800
    case FR30_OPERAND_CCC :
801
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
802
      break;
803
    case FR30_OPERAND_DIR10 :
804
      {
805
        long value;
806
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
807
        value = ((value) << (2));
808
        fields->f_dir10 = value;
809
      }
810
      break;
811
    case FR30_OPERAND_DIR8 :
812
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
813
      break;
814
    case FR30_OPERAND_DIR9 :
815
      {
816
        long value;
817
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
818
        value = ((value) << (1));
819
        fields->f_dir9 = value;
820
      }
821
      break;
822
    case FR30_OPERAND_DISP10 :
823
      {
824
        long value;
825
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
826
        value = ((value) << (2));
827
        fields->f_disp10 = value;
828
      }
829
      break;
830
    case FR30_OPERAND_DISP8 :
831
      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
832
      break;
833
    case FR30_OPERAND_DISP9 :
834
      {
835
        long value;
836
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
837
        value = ((value) << (1));
838
        fields->f_disp9 = value;
839
      }
840
      break;
841
    case FR30_OPERAND_I20 :
842
      {
843
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
844
        if (length <= 0) break;
845
        length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
846
        if (length <= 0) break;
847
{
848
  FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
849
}
850
      }
851
      break;
852
    case FR30_OPERAND_I32 :
853
      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
854
      break;
855
    case FR30_OPERAND_I8 :
856
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
857
      break;
858
    case FR30_OPERAND_LABEL12 :
859
      {
860
        long value;
861
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
862
        value = ((((value) << (1))) + (((pc) + (2))));
863
        fields->f_rel12 = value;
864
      }
865
      break;
866
    case FR30_OPERAND_LABEL9 :
867
      {
868
        long value;
869
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
870
        value = ((((value) << (1))) + (((pc) + (2))));
871
        fields->f_rel9 = value;
872
      }
873
      break;
874
    case FR30_OPERAND_M4 :
875
      {
876
        long value;
877
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
878
        value = ((value) | (((-1) << (4))));
879
        fields->f_m4 = value;
880
      }
881
      break;
882
    case FR30_OPERAND_PS :
883
      break;
884
    case FR30_OPERAND_REGLIST_HI_LD :
885
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
886
      break;
887
    case FR30_OPERAND_REGLIST_HI_ST :
888
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
889
      break;
890
    case FR30_OPERAND_REGLIST_LOW_LD :
891
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
892
      break;
893
    case FR30_OPERAND_REGLIST_LOW_ST :
894
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
895
      break;
896
    case FR30_OPERAND_S10 :
897
      {
898
        long value;
899
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
900
        value = ((value) << (2));
901
        fields->f_s10 = value;
902
      }
903
      break;
904
    case FR30_OPERAND_U10 :
905
      {
906
        long value;
907
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
908
        value = ((value) << (2));
909
        fields->f_u10 = value;
910
      }
911
      break;
912
    case FR30_OPERAND_U4 :
913
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
914
      break;
915
    case FR30_OPERAND_U4C :
916
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
917
      break;
918
    case FR30_OPERAND_U8 :
919
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
920
      break;
921
    case FR30_OPERAND_UDISP6 :
922
      {
923
        long value;
924
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
925
        value = ((value) << (2));
926
        fields->f_udisp6 = value;
927
      }
928
      break;
929
 
930
    default :
931
      /* xgettext:c-format */
932
      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
933
               opindex);
934
      abort ();
935
    }
936
 
937
  return length;
938
}
939
 
940
cgen_insert_fn * const fr30_cgen_insert_handlers[] =
941
{
942
  insert_insn_normal,
943
};
944
 
945
cgen_extract_fn * const fr30_cgen_extract_handlers[] =
946
{
947
  extract_insn_normal,
948
};
949
 
950
int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
951
bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
952
 
953
/* Getting values from cgen_fields is handled by a collection of functions.
954
   They are distinguished by the type of the VALUE argument they return.
955
   TODO: floating point, inlining support, remove cases where result type
956
   not appropriate.  */
957
 
958
int
959
fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
960
                             int opindex,
961
                             const CGEN_FIELDS * fields)
962
{
963
  int value;
964
 
965
  switch (opindex)
966
    {
967
    case FR30_OPERAND_CRI :
968
      value = fields->f_CRi;
969
      break;
970
    case FR30_OPERAND_CRJ :
971
      value = fields->f_CRj;
972
      break;
973
    case FR30_OPERAND_R13 :
974
      value = 0;
975
      break;
976
    case FR30_OPERAND_R14 :
977
      value = 0;
978
      break;
979
    case FR30_OPERAND_R15 :
980
      value = 0;
981
      break;
982
    case FR30_OPERAND_RI :
983
      value = fields->f_Ri;
984
      break;
985
    case FR30_OPERAND_RIC :
986
      value = fields->f_Ric;
987
      break;
988
    case FR30_OPERAND_RJ :
989
      value = fields->f_Rj;
990
      break;
991
    case FR30_OPERAND_RJC :
992
      value = fields->f_Rjc;
993
      break;
994
    case FR30_OPERAND_RS1 :
995
      value = fields->f_Rs1;
996
      break;
997
    case FR30_OPERAND_RS2 :
998
      value = fields->f_Rs2;
999
      break;
1000
    case FR30_OPERAND_CC :
1001
      value = fields->f_cc;
1002
      break;
1003
    case FR30_OPERAND_CCC :
1004
      value = fields->f_ccc;
1005
      break;
1006
    case FR30_OPERAND_DIR10 :
1007
      value = fields->f_dir10;
1008
      break;
1009
    case FR30_OPERAND_DIR8 :
1010
      value = fields->f_dir8;
1011
      break;
1012
    case FR30_OPERAND_DIR9 :
1013
      value = fields->f_dir9;
1014
      break;
1015
    case FR30_OPERAND_DISP10 :
1016
      value = fields->f_disp10;
1017
      break;
1018
    case FR30_OPERAND_DISP8 :
1019
      value = fields->f_disp8;
1020
      break;
1021
    case FR30_OPERAND_DISP9 :
1022
      value = fields->f_disp9;
1023
      break;
1024
    case FR30_OPERAND_I20 :
1025
      value = fields->f_i20;
1026
      break;
1027
    case FR30_OPERAND_I32 :
1028
      value = fields->f_i32;
1029
      break;
1030
    case FR30_OPERAND_I8 :
1031
      value = fields->f_i8;
1032
      break;
1033
    case FR30_OPERAND_LABEL12 :
1034
      value = fields->f_rel12;
1035
      break;
1036
    case FR30_OPERAND_LABEL9 :
1037
      value = fields->f_rel9;
1038
      break;
1039
    case FR30_OPERAND_M4 :
1040
      value = fields->f_m4;
1041
      break;
1042
    case FR30_OPERAND_PS :
1043
      value = 0;
1044
      break;
1045
    case FR30_OPERAND_REGLIST_HI_LD :
1046
      value = fields->f_reglist_hi_ld;
1047
      break;
1048
    case FR30_OPERAND_REGLIST_HI_ST :
1049
      value = fields->f_reglist_hi_st;
1050
      break;
1051
    case FR30_OPERAND_REGLIST_LOW_LD :
1052
      value = fields->f_reglist_low_ld;
1053
      break;
1054
    case FR30_OPERAND_REGLIST_LOW_ST :
1055
      value = fields->f_reglist_low_st;
1056
      break;
1057
    case FR30_OPERAND_S10 :
1058
      value = fields->f_s10;
1059
      break;
1060
    case FR30_OPERAND_U10 :
1061
      value = fields->f_u10;
1062
      break;
1063
    case FR30_OPERAND_U4 :
1064
      value = fields->f_u4;
1065
      break;
1066
    case FR30_OPERAND_U4C :
1067
      value = fields->f_u4c;
1068
      break;
1069
    case FR30_OPERAND_U8 :
1070
      value = fields->f_u8;
1071
      break;
1072
    case FR30_OPERAND_UDISP6 :
1073
      value = fields->f_udisp6;
1074
      break;
1075
 
1076
    default :
1077
      /* xgettext:c-format */
1078
      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1079
                       opindex);
1080
      abort ();
1081
  }
1082
 
1083
  return value;
1084
}
1085
 
1086
bfd_vma
1087
fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1088
                             int opindex,
1089
                             const CGEN_FIELDS * fields)
1090
{
1091
  bfd_vma value;
1092
 
1093
  switch (opindex)
1094
    {
1095
    case FR30_OPERAND_CRI :
1096
      value = fields->f_CRi;
1097
      break;
1098
    case FR30_OPERAND_CRJ :
1099
      value = fields->f_CRj;
1100
      break;
1101
    case FR30_OPERAND_R13 :
1102
      value = 0;
1103
      break;
1104
    case FR30_OPERAND_R14 :
1105
      value = 0;
1106
      break;
1107
    case FR30_OPERAND_R15 :
1108
      value = 0;
1109
      break;
1110
    case FR30_OPERAND_RI :
1111
      value = fields->f_Ri;
1112
      break;
1113
    case FR30_OPERAND_RIC :
1114
      value = fields->f_Ric;
1115
      break;
1116
    case FR30_OPERAND_RJ :
1117
      value = fields->f_Rj;
1118
      break;
1119
    case FR30_OPERAND_RJC :
1120
      value = fields->f_Rjc;
1121
      break;
1122
    case FR30_OPERAND_RS1 :
1123
      value = fields->f_Rs1;
1124
      break;
1125
    case FR30_OPERAND_RS2 :
1126
      value = fields->f_Rs2;
1127
      break;
1128
    case FR30_OPERAND_CC :
1129
      value = fields->f_cc;
1130
      break;
1131
    case FR30_OPERAND_CCC :
1132
      value = fields->f_ccc;
1133
      break;
1134
    case FR30_OPERAND_DIR10 :
1135
      value = fields->f_dir10;
1136
      break;
1137
    case FR30_OPERAND_DIR8 :
1138
      value = fields->f_dir8;
1139
      break;
1140
    case FR30_OPERAND_DIR9 :
1141
      value = fields->f_dir9;
1142
      break;
1143
    case FR30_OPERAND_DISP10 :
1144
      value = fields->f_disp10;
1145
      break;
1146
    case FR30_OPERAND_DISP8 :
1147
      value = fields->f_disp8;
1148
      break;
1149
    case FR30_OPERAND_DISP9 :
1150
      value = fields->f_disp9;
1151
      break;
1152
    case FR30_OPERAND_I20 :
1153
      value = fields->f_i20;
1154
      break;
1155
    case FR30_OPERAND_I32 :
1156
      value = fields->f_i32;
1157
      break;
1158
    case FR30_OPERAND_I8 :
1159
      value = fields->f_i8;
1160
      break;
1161
    case FR30_OPERAND_LABEL12 :
1162
      value = fields->f_rel12;
1163
      break;
1164
    case FR30_OPERAND_LABEL9 :
1165
      value = fields->f_rel9;
1166
      break;
1167
    case FR30_OPERAND_M4 :
1168
      value = fields->f_m4;
1169
      break;
1170
    case FR30_OPERAND_PS :
1171
      value = 0;
1172
      break;
1173
    case FR30_OPERAND_REGLIST_HI_LD :
1174
      value = fields->f_reglist_hi_ld;
1175
      break;
1176
    case FR30_OPERAND_REGLIST_HI_ST :
1177
      value = fields->f_reglist_hi_st;
1178
      break;
1179
    case FR30_OPERAND_REGLIST_LOW_LD :
1180
      value = fields->f_reglist_low_ld;
1181
      break;
1182
    case FR30_OPERAND_REGLIST_LOW_ST :
1183
      value = fields->f_reglist_low_st;
1184
      break;
1185
    case FR30_OPERAND_S10 :
1186
      value = fields->f_s10;
1187
      break;
1188
    case FR30_OPERAND_U10 :
1189
      value = fields->f_u10;
1190
      break;
1191
    case FR30_OPERAND_U4 :
1192
      value = fields->f_u4;
1193
      break;
1194
    case FR30_OPERAND_U4C :
1195
      value = fields->f_u4c;
1196
      break;
1197
    case FR30_OPERAND_U8 :
1198
      value = fields->f_u8;
1199
      break;
1200
    case FR30_OPERAND_UDISP6 :
1201
      value = fields->f_udisp6;
1202
      break;
1203
 
1204
    default :
1205
      /* xgettext:c-format */
1206
      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1207
                       opindex);
1208
      abort ();
1209
  }
1210
 
1211
  return value;
1212
}
1213
 
1214
void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1215
void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1216
 
1217
/* Stuffing values in cgen_fields is handled by a collection of functions.
1218
   They are distinguished by the type of the VALUE argument they accept.
1219
   TODO: floating point, inlining support, remove cases where argument type
1220
   not appropriate.  */
1221
 
1222
void
1223
fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1224
                             int opindex,
1225
                             CGEN_FIELDS * fields,
1226
                             int value)
1227
{
1228
  switch (opindex)
1229
    {
1230
    case FR30_OPERAND_CRI :
1231
      fields->f_CRi = value;
1232
      break;
1233
    case FR30_OPERAND_CRJ :
1234
      fields->f_CRj = value;
1235
      break;
1236
    case FR30_OPERAND_R13 :
1237
      break;
1238
    case FR30_OPERAND_R14 :
1239
      break;
1240
    case FR30_OPERAND_R15 :
1241
      break;
1242
    case FR30_OPERAND_RI :
1243
      fields->f_Ri = value;
1244
      break;
1245
    case FR30_OPERAND_RIC :
1246
      fields->f_Ric = value;
1247
      break;
1248
    case FR30_OPERAND_RJ :
1249
      fields->f_Rj = value;
1250
      break;
1251
    case FR30_OPERAND_RJC :
1252
      fields->f_Rjc = value;
1253
      break;
1254
    case FR30_OPERAND_RS1 :
1255
      fields->f_Rs1 = value;
1256
      break;
1257
    case FR30_OPERAND_RS2 :
1258
      fields->f_Rs2 = value;
1259
      break;
1260
    case FR30_OPERAND_CC :
1261
      fields->f_cc = value;
1262
      break;
1263
    case FR30_OPERAND_CCC :
1264
      fields->f_ccc = value;
1265
      break;
1266
    case FR30_OPERAND_DIR10 :
1267
      fields->f_dir10 = value;
1268
      break;
1269
    case FR30_OPERAND_DIR8 :
1270
      fields->f_dir8 = value;
1271
      break;
1272
    case FR30_OPERAND_DIR9 :
1273
      fields->f_dir9 = value;
1274
      break;
1275
    case FR30_OPERAND_DISP10 :
1276
      fields->f_disp10 = value;
1277
      break;
1278
    case FR30_OPERAND_DISP8 :
1279
      fields->f_disp8 = value;
1280
      break;
1281
    case FR30_OPERAND_DISP9 :
1282
      fields->f_disp9 = value;
1283
      break;
1284
    case FR30_OPERAND_I20 :
1285
      fields->f_i20 = value;
1286
      break;
1287
    case FR30_OPERAND_I32 :
1288
      fields->f_i32 = value;
1289
      break;
1290
    case FR30_OPERAND_I8 :
1291
      fields->f_i8 = value;
1292
      break;
1293
    case FR30_OPERAND_LABEL12 :
1294
      fields->f_rel12 = value;
1295
      break;
1296
    case FR30_OPERAND_LABEL9 :
1297
      fields->f_rel9 = value;
1298
      break;
1299
    case FR30_OPERAND_M4 :
1300
      fields->f_m4 = value;
1301
      break;
1302
    case FR30_OPERAND_PS :
1303
      break;
1304
    case FR30_OPERAND_REGLIST_HI_LD :
1305
      fields->f_reglist_hi_ld = value;
1306
      break;
1307
    case FR30_OPERAND_REGLIST_HI_ST :
1308
      fields->f_reglist_hi_st = value;
1309
      break;
1310
    case FR30_OPERAND_REGLIST_LOW_LD :
1311
      fields->f_reglist_low_ld = value;
1312
      break;
1313
    case FR30_OPERAND_REGLIST_LOW_ST :
1314
      fields->f_reglist_low_st = value;
1315
      break;
1316
    case FR30_OPERAND_S10 :
1317
      fields->f_s10 = value;
1318
      break;
1319
    case FR30_OPERAND_U10 :
1320
      fields->f_u10 = value;
1321
      break;
1322
    case FR30_OPERAND_U4 :
1323
      fields->f_u4 = value;
1324
      break;
1325
    case FR30_OPERAND_U4C :
1326
      fields->f_u4c = value;
1327
      break;
1328
    case FR30_OPERAND_U8 :
1329
      fields->f_u8 = value;
1330
      break;
1331
    case FR30_OPERAND_UDISP6 :
1332
      fields->f_udisp6 = value;
1333
      break;
1334
 
1335
    default :
1336
      /* xgettext:c-format */
1337
      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1338
                       opindex);
1339
      abort ();
1340
  }
1341
}
1342
 
1343
void
1344
fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1345
                             int opindex,
1346
                             CGEN_FIELDS * fields,
1347
                             bfd_vma value)
1348
{
1349
  switch (opindex)
1350
    {
1351
    case FR30_OPERAND_CRI :
1352
      fields->f_CRi = value;
1353
      break;
1354
    case FR30_OPERAND_CRJ :
1355
      fields->f_CRj = value;
1356
      break;
1357
    case FR30_OPERAND_R13 :
1358
      break;
1359
    case FR30_OPERAND_R14 :
1360
      break;
1361
    case FR30_OPERAND_R15 :
1362
      break;
1363
    case FR30_OPERAND_RI :
1364
      fields->f_Ri = value;
1365
      break;
1366
    case FR30_OPERAND_RIC :
1367
      fields->f_Ric = value;
1368
      break;
1369
    case FR30_OPERAND_RJ :
1370
      fields->f_Rj = value;
1371
      break;
1372
    case FR30_OPERAND_RJC :
1373
      fields->f_Rjc = value;
1374
      break;
1375
    case FR30_OPERAND_RS1 :
1376
      fields->f_Rs1 = value;
1377
      break;
1378
    case FR30_OPERAND_RS2 :
1379
      fields->f_Rs2 = value;
1380
      break;
1381
    case FR30_OPERAND_CC :
1382
      fields->f_cc = value;
1383
      break;
1384
    case FR30_OPERAND_CCC :
1385
      fields->f_ccc = value;
1386
      break;
1387
    case FR30_OPERAND_DIR10 :
1388
      fields->f_dir10 = value;
1389
      break;
1390
    case FR30_OPERAND_DIR8 :
1391
      fields->f_dir8 = value;
1392
      break;
1393
    case FR30_OPERAND_DIR9 :
1394
      fields->f_dir9 = value;
1395
      break;
1396
    case FR30_OPERAND_DISP10 :
1397
      fields->f_disp10 = value;
1398
      break;
1399
    case FR30_OPERAND_DISP8 :
1400
      fields->f_disp8 = value;
1401
      break;
1402
    case FR30_OPERAND_DISP9 :
1403
      fields->f_disp9 = value;
1404
      break;
1405
    case FR30_OPERAND_I20 :
1406
      fields->f_i20 = value;
1407
      break;
1408
    case FR30_OPERAND_I32 :
1409
      fields->f_i32 = value;
1410
      break;
1411
    case FR30_OPERAND_I8 :
1412
      fields->f_i8 = value;
1413
      break;
1414
    case FR30_OPERAND_LABEL12 :
1415
      fields->f_rel12 = value;
1416
      break;
1417
    case FR30_OPERAND_LABEL9 :
1418
      fields->f_rel9 = value;
1419
      break;
1420
    case FR30_OPERAND_M4 :
1421
      fields->f_m4 = value;
1422
      break;
1423
    case FR30_OPERAND_PS :
1424
      break;
1425
    case FR30_OPERAND_REGLIST_HI_LD :
1426
      fields->f_reglist_hi_ld = value;
1427
      break;
1428
    case FR30_OPERAND_REGLIST_HI_ST :
1429
      fields->f_reglist_hi_st = value;
1430
      break;
1431
    case FR30_OPERAND_REGLIST_LOW_LD :
1432
      fields->f_reglist_low_ld = value;
1433
      break;
1434
    case FR30_OPERAND_REGLIST_LOW_ST :
1435
      fields->f_reglist_low_st = value;
1436
      break;
1437
    case FR30_OPERAND_S10 :
1438
      fields->f_s10 = value;
1439
      break;
1440
    case FR30_OPERAND_U10 :
1441
      fields->f_u10 = value;
1442
      break;
1443
    case FR30_OPERAND_U4 :
1444
      fields->f_u4 = value;
1445
      break;
1446
    case FR30_OPERAND_U4C :
1447
      fields->f_u4c = value;
1448
      break;
1449
    case FR30_OPERAND_U8 :
1450
      fields->f_u8 = value;
1451
      break;
1452
    case FR30_OPERAND_UDISP6 :
1453
      fields->f_udisp6 = value;
1454
      break;
1455
 
1456
    default :
1457
      /* xgettext:c-format */
1458
      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1459
                       opindex);
1460
      abort ();
1461
  }
1462
}
1463
 
1464
/* Function to call before using the instruction builder tables.  */
1465
 
1466
void
1467
fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1468
{
1469
  cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1470
  cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1471
 
1472
  cd->insert_operand = fr30_cgen_insert_operand;
1473
  cd->extract_operand = fr30_cgen_extract_operand;
1474
 
1475
  cd->get_int_operand = fr30_cgen_get_int_operand;
1476
  cd->set_int_operand = fr30_cgen_set_int_operand;
1477
  cd->get_vma_operand = fr30_cgen_get_vma_operand;
1478
  cd->set_vma_operand = fr30_cgen_set_vma_operand;
1479
}

powered by: WebSVN 2.1.0

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