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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [opcodes/] [fr30-ibld.c] - Blame information for rev 407

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

Line No. Rev Author Line
1 205 julius
/* 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  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 "opintl.h"
37
#include "safe-ctype.h"
38
 
39
#undef  min
40
#define min(a,b) ((a) < (b) ? (a) : (b))
41
#undef  max
42
#define max(a,b) ((a) > (b) ? (a) : (b))
43
 
44
/* Used by the ifield rtx function.  */
45
#define FLD(f) (fields->f)
46
 
47
static const char * insert_normal
48
  (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49
   unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50
static const char * insert_insn_normal
51
  (CGEN_CPU_DESC, const CGEN_INSN *,
52
   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53
static int extract_normal
54
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55
   unsigned int, unsigned int, unsigned int, unsigned int,
56
   unsigned int, unsigned int, bfd_vma, long *);
57
static int extract_insn_normal
58
  (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59
   CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
60
#if CGEN_INT_INSN_P
61
static void put_insn_int_value
62
  (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
63
#endif
64
#if ! CGEN_INT_INSN_P
65
static CGEN_INLINE void insert_1
66
  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67
static CGEN_INLINE int fill_cache
68
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
69
static CGEN_INLINE long extract_1
70
  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71
#endif
72
 
73
/* Operand insertion.  */
74
 
75
#if ! CGEN_INT_INSN_P
76
 
77
/* Subroutine of insert_normal.  */
78
 
79
static CGEN_INLINE void
80
insert_1 (CGEN_CPU_DESC cd,
81
          unsigned long value,
82
          int start,
83
          int length,
84
          int word_length,
85
          unsigned char *bufp)
86
{
87
  unsigned long x,mask;
88
  int shift;
89
 
90
  x = cgen_get_insn_value (cd, bufp, word_length);
91
 
92
  /* Written this way to avoid undefined behaviour.  */
93
  mask = (((1L << (length - 1)) - 1) << 1) | 1;
94
  if (CGEN_INSN_LSB0_P)
95
    shift = (start + 1) - length;
96
  else
97
    shift = (word_length - (start + length));
98
  x = (x & ~(mask << shift)) | ((value & mask) << shift);
99
 
100
  cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
101
}
102
 
103
#endif /* ! CGEN_INT_INSN_P */
104
 
105
/* Default insertion routine.
106
 
107
   ATTRS is a mask of the boolean attributes.
108
   WORD_OFFSET is the offset in bits from the start of the insn of the value.
109
   WORD_LENGTH is the length of the word in bits in which the value resides.
110
   START is the starting bit number in the word, architecture origin.
111
   LENGTH is the length of VALUE in bits.
112
   TOTAL_LENGTH is the total length of the insn in bits.
113
 
114
   The result is an error message or NULL if success.  */
115
 
116
/* ??? This duplicates functionality with bfd's howto table and
117
   bfd_install_relocation.  */
118
/* ??? This doesn't handle bfd_vma's.  Create another function when
119
   necessary.  */
120
 
121
static const char *
122
insert_normal (CGEN_CPU_DESC cd,
123
               long value,
124
               unsigned int attrs,
125
               unsigned int word_offset,
126
               unsigned int start,
127
               unsigned int length,
128
               unsigned int word_length,
129
               unsigned int total_length,
130
               CGEN_INSN_BYTES_PTR buffer)
131
{
132
  static char errbuf[100];
133
  /* Written this way to avoid undefined behaviour.  */
134
  unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
135
 
136
  /* If LENGTH is zero, this operand doesn't contribute to the value.  */
137
  if (length == 0)
138
    return NULL;
139
 
140
  if (word_length > 32)
141
    abort ();
142
 
143
  /* For architectures with insns smaller than the base-insn-bitsize,
144
     word_length may be too big.  */
145
  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
146
    {
147
      if (word_offset == 0
148
          && word_length > total_length)
149
        word_length = total_length;
150
    }
151
 
152
  /* Ensure VALUE will fit.  */
153
  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
154
    {
155
      long minval = - (1L << (length - 1));
156
      unsigned long maxval = mask;
157
 
158
      if ((value > 0 && (unsigned long) value > maxval)
159
          || value < minval)
160
        {
161
          /* xgettext:c-format */
162
          sprintf (errbuf,
163
                   _("operand out of range (%ld not between %ld and %lu)"),
164
                   value, minval, maxval);
165
          return errbuf;
166
        }
167
    }
168
  else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
169
    {
170
      unsigned long maxval = mask;
171
      unsigned long val = (unsigned long) value;
172
 
173
      /* For hosts with a word size > 32 check to see if value has been sign
174
         extended beyond 32 bits.  If so then ignore these higher sign bits
175
         as the user is attempting to store a 32-bit signed value into an
176
         unsigned 32-bit field which is allowed.  */
177
      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
178
        val &= 0xFFFFFFFF;
179
 
180
      if (val > maxval)
181
        {
182
          /* xgettext:c-format */
183
          sprintf (errbuf,
184
                   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
185
                   val, maxval);
186
          return errbuf;
187
        }
188
    }
189
  else
190
    {
191
      if (! cgen_signed_overflow_ok_p (cd))
192
        {
193
          long minval = - (1L << (length - 1));
194
          long maxval =   (1L << (length - 1)) - 1;
195
 
196
          if (value < minval || value > maxval)
197
            {
198
              sprintf
199
                /* xgettext:c-format */
200
                (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
201
                 value, minval, maxval);
202
              return errbuf;
203
            }
204
        }
205
    }
206
 
207
#if CGEN_INT_INSN_P
208
 
209
  {
210
    int shift;
211
 
212
    if (CGEN_INSN_LSB0_P)
213
      shift = (word_offset + start + 1) - length;
214
    else
215
      shift = total_length - (word_offset + start + length);
216
    *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
217
  }
218
 
219
#else /* ! CGEN_INT_INSN_P */
220
 
221
  {
222
    unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
223
 
224
    insert_1 (cd, value, start, length, word_length, bufp);
225
  }
226
 
227
#endif /* ! CGEN_INT_INSN_P */
228
 
229
  return NULL;
230
}
231
 
232
/* Default insn builder (insert handler).
233
   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
234
   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
235
   recorded in host byte order, otherwise BUFFER is an array of bytes
236
   and the value is recorded in target byte order).
237
   The result is an error message or NULL if success.  */
238
 
239
static const char *
240
insert_insn_normal (CGEN_CPU_DESC cd,
241
                    const CGEN_INSN * insn,
242
                    CGEN_FIELDS * fields,
243
                    CGEN_INSN_BYTES_PTR buffer,
244
                    bfd_vma pc)
245
{
246
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
247
  unsigned long value;
248
  const CGEN_SYNTAX_CHAR_TYPE * syn;
249
 
250
  CGEN_INIT_INSERT (cd);
251
  value = CGEN_INSN_BASE_VALUE (insn);
252
 
253
  /* If we're recording insns as numbers (rather than a string of bytes),
254
     target byte order handling is deferred until later.  */
255
 
256
#if CGEN_INT_INSN_P
257
 
258
  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
259
                      CGEN_FIELDS_BITSIZE (fields), value);
260
 
261
#else
262
 
263
  cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
264
                                        (unsigned) CGEN_FIELDS_BITSIZE (fields)),
265
                       value);
266
 
267
#endif /* ! CGEN_INT_INSN_P */
268
 
269
  /* ??? It would be better to scan the format's fields.
270
     Still need to be able to insert a value based on the operand though;
271
     e.g. storing a branch displacement that got resolved later.
272
     Needs more thought first.  */
273
 
274
  for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
275
    {
276
      const char *errmsg;
277
 
278
      if (CGEN_SYNTAX_CHAR_P (* syn))
279
        continue;
280
 
281
      errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
282
                                       fields, buffer, pc);
283
      if (errmsg)
284
        return errmsg;
285
    }
286
 
287
  return NULL;
288
}
289
 
290
#if CGEN_INT_INSN_P
291
/* Cover function to store an insn value into an integral insn.  Must go here
292
   because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
293
 
294
static void
295
put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
296
                    CGEN_INSN_BYTES_PTR buf,
297
                    int length,
298
                    int insn_length,
299
                    CGEN_INSN_INT value)
300
{
301
  /* For architectures with insns smaller than the base-insn-bitsize,
302
     length may be too big.  */
303
  if (length > insn_length)
304
    *buf = value;
305
  else
306
    {
307
      int shift = insn_length - length;
308
      /* Written this way to avoid undefined behaviour.  */
309
      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
310
 
311
      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
312
    }
313
}
314
#endif
315
 
316
/* Operand extraction.  */
317
 
318
#if ! CGEN_INT_INSN_P
319
 
320
/* Subroutine of extract_normal.
321
   Ensure sufficient bytes are cached in EX_INFO.
322
   OFFSET is the offset in bytes from the start of the insn of the value.
323
   BYTES is the length of the needed value.
324
   Returns 1 for success, 0 for failure.  */
325
 
326
static CGEN_INLINE int
327
fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
328
            CGEN_EXTRACT_INFO *ex_info,
329
            int offset,
330
            int bytes,
331
            bfd_vma pc)
332
{
333
  /* It's doubtful that the middle part has already been fetched so
334
     we don't optimize that case.  kiss.  */
335
  unsigned int mask;
336
  disassemble_info *info = (disassemble_info *) ex_info->dis_info;
337
 
338
  /* First do a quick check.  */
339
  mask = (1 << bytes) - 1;
340
  if (((ex_info->valid >> offset) & mask) == mask)
341
    return 1;
342
 
343
  /* Search for the first byte we need to read.  */
344
  for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
345
    if (! (mask & ex_info->valid))
346
      break;
347
 
348
  if (bytes)
349
    {
350
      int status;
351
 
352
      pc += offset;
353
      status = (*info->read_memory_func)
354
        (pc, ex_info->insn_bytes + offset, bytes, info);
355
 
356
      if (status != 0)
357
        {
358
          (*info->memory_error_func) (status, pc, info);
359
          return 0;
360
        }
361
 
362
      ex_info->valid |= ((1 << bytes) - 1) << offset;
363
    }
364
 
365
  return 1;
366
}
367
 
368
/* Subroutine of extract_normal.  */
369
 
370
static CGEN_INLINE long
371
extract_1 (CGEN_CPU_DESC cd,
372
           CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
373
           int start,
374
           int length,
375
           int word_length,
376
           unsigned char *bufp,
377
           bfd_vma pc ATTRIBUTE_UNUSED)
378
{
379
  unsigned long x;
380
  int shift;
381
 
382
  x = cgen_get_insn_value (cd, bufp, word_length);
383
 
384
  if (CGEN_INSN_LSB0_P)
385
    shift = (start + 1) - length;
386
  else
387
    shift = (word_length - (start + length));
388
  return x >> shift;
389
}
390
 
391
#endif /* ! CGEN_INT_INSN_P */
392
 
393
/* Default extraction routine.
394
 
395
   INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
396
   or sometimes less for cases like the m32r where the base insn size is 32
397
   but some insns are 16 bits.
398
   ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
399
   but for generality we take a bitmask of all of them.
400
   WORD_OFFSET is the offset in bits from the start of the insn of the value.
401
   WORD_LENGTH is the length of the word in bits in which the value resides.
402
   START is the starting bit number in the word, architecture origin.
403
   LENGTH is the length of VALUE in bits.
404
   TOTAL_LENGTH is the total length of the insn in bits.
405
 
406
   Returns 1 for success, 0 for failure.  */
407
 
408
/* ??? The return code isn't properly used.  wip.  */
409
 
410
/* ??? This doesn't handle bfd_vma's.  Create another function when
411
   necessary.  */
412
 
413
static int
414
extract_normal (CGEN_CPU_DESC cd,
415
#if ! CGEN_INT_INSN_P
416
                CGEN_EXTRACT_INFO *ex_info,
417
#else
418
                CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
419
#endif
420
                CGEN_INSN_INT insn_value,
421
                unsigned int attrs,
422
                unsigned int word_offset,
423
                unsigned int start,
424
                unsigned int length,
425
                unsigned int word_length,
426
                unsigned int total_length,
427
#if ! CGEN_INT_INSN_P
428
                bfd_vma pc,
429
#else
430
                bfd_vma pc ATTRIBUTE_UNUSED,
431
#endif
432
                long *valuep)
433
{
434
  long value, mask;
435
 
436
  /* If LENGTH is zero, this operand doesn't contribute to the value
437
     so give it a standard value of zero.  */
438
  if (length == 0)
439
    {
440
      *valuep = 0;
441
      return 1;
442
    }
443
 
444
  if (word_length > 32)
445
    abort ();
446
 
447
  /* For architectures with insns smaller than the insn-base-bitsize,
448
     word_length may be too big.  */
449
  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
450
    {
451
      if (word_offset + word_length > total_length)
452
        word_length = total_length - word_offset;
453
    }
454
 
455
  /* Does the value reside in INSN_VALUE, and at the right alignment?  */
456
 
457
  if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
458
    {
459
      if (CGEN_INSN_LSB0_P)
460
        value = insn_value >> ((word_offset + start + 1) - length);
461
      else
462
        value = insn_value >> (total_length - ( word_offset + start + length));
463
    }
464
 
465
#if ! CGEN_INT_INSN_P
466
 
467
  else
468
    {
469
      unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
470
 
471
      if (word_length > 32)
472
        abort ();
473
 
474
      if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
475
        return 0;
476
 
477
      value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
478
    }
479
 
480
#endif /* ! CGEN_INT_INSN_P */
481
 
482
  /* Written this way to avoid undefined behaviour.  */
483
  mask = (((1L << (length - 1)) - 1) << 1) | 1;
484
 
485
  value &= mask;
486
  /* sign extend? */
487
  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
488
      && (value & (1L << (length - 1))))
489
    value |= ~mask;
490
 
491
  *valuep = value;
492
 
493
  return 1;
494
}
495
 
496
/* Default insn extractor.
497
 
498
   INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
499
   The extracted fields are stored in FIELDS.
500
   EX_INFO is used to handle reading variable length insns.
501
   Return the length of the insn in bits, or 0 if no match,
502
   or -1 if an error occurs fetching data (memory_error_func will have
503
   been called).  */
504
 
505
static int
506
extract_insn_normal (CGEN_CPU_DESC cd,
507
                     const CGEN_INSN *insn,
508
                     CGEN_EXTRACT_INFO *ex_info,
509
                     CGEN_INSN_INT insn_value,
510
                     CGEN_FIELDS *fields,
511
                     bfd_vma pc)
512
{
513
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
514
  const CGEN_SYNTAX_CHAR_TYPE *syn;
515
 
516
  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
517
 
518
  CGEN_INIT_EXTRACT (cd);
519
 
520
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
521
    {
522
      int length;
523
 
524
      if (CGEN_SYNTAX_CHAR_P (*syn))
525
        continue;
526
 
527
      length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
528
                                        ex_info, insn_value, fields, pc);
529
      if (length <= 0)
530
        return length;
531
    }
532
 
533
  /* We recognized and successfully extracted this insn.  */
534
  return CGEN_INSN_BITSIZE (insn);
535
}
536
 
537
/* Machine generated code added here.  */
538
 
539
const char * fr30_cgen_insert_operand
540
  (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
541
 
542
/* Main entry point for operand insertion.
543
 
544
   This function is basically just a big switch statement.  Earlier versions
545
   used tables to look up the function to use, but
546
   - if the table contains both assembler and disassembler functions then
547
     the disassembler contains much of the assembler and vice-versa,
548
   - there's a lot of inlining possibilities as things grow,
549
   - using a switch statement avoids the function call overhead.
550
 
551
   This function could be moved into `parse_insn_normal', but keeping it
552
   separate makes clear the interface between `parse_insn_normal' and each of
553
   the handlers.  It's also needed by GAS to insert operands that couldn't be
554
   resolved during parsing.  */
555
 
556
const char *
557
fr30_cgen_insert_operand (CGEN_CPU_DESC cd,
558
                             int opindex,
559
                             CGEN_FIELDS * fields,
560
                             CGEN_INSN_BYTES_PTR buffer,
561
                             bfd_vma pc ATTRIBUTE_UNUSED)
562
{
563
  const char * errmsg = NULL;
564
  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
565
 
566
  switch (opindex)
567
    {
568
    case FR30_OPERAND_CRI :
569
      errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
570
      break;
571
    case FR30_OPERAND_CRJ :
572
      errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
573
      break;
574
    case FR30_OPERAND_R13 :
575
      break;
576
    case FR30_OPERAND_R14 :
577
      break;
578
    case FR30_OPERAND_R15 :
579
      break;
580
    case FR30_OPERAND_RI :
581
      errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
582
      break;
583
    case FR30_OPERAND_RIC :
584
      errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
585
      break;
586
    case FR30_OPERAND_RJ :
587
      errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
588
      break;
589
    case FR30_OPERAND_RJC :
590
      errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
591
      break;
592
    case FR30_OPERAND_RS1 :
593
      errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
594
      break;
595
    case FR30_OPERAND_RS2 :
596
      errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
597
      break;
598
    case FR30_OPERAND_CC :
599
      errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
600
      break;
601
    case FR30_OPERAND_CCC :
602
      errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
603
      break;
604
    case FR30_OPERAND_DIR10 :
605
      {
606
        long value = fields->f_dir10;
607
        value = ((unsigned int) (value) >> (2));
608
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
609
      }
610
      break;
611
    case FR30_OPERAND_DIR8 :
612
      errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
613
      break;
614
    case FR30_OPERAND_DIR9 :
615
      {
616
        long value = fields->f_dir9;
617
        value = ((unsigned int) (value) >> (1));
618
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
619
      }
620
      break;
621
    case FR30_OPERAND_DISP10 :
622
      {
623
        long value = fields->f_disp10;
624
        value = ((int) (value) >> (2));
625
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
626
      }
627
      break;
628
    case FR30_OPERAND_DISP8 :
629
      errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
630
      break;
631
    case FR30_OPERAND_DISP9 :
632
      {
633
        long value = fields->f_disp9;
634
        value = ((int) (value) >> (1));
635
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
636
      }
637
      break;
638
    case FR30_OPERAND_I20 :
639
      {
640
{
641
  FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
642
  FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
643
}
644
        errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
645
        if (errmsg)
646
          break;
647
        errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
648
        if (errmsg)
649
          break;
650
      }
651
      break;
652
    case FR30_OPERAND_I32 :
653
      errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
654
      break;
655
    case FR30_OPERAND_I8 :
656
      errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
657
      break;
658
    case FR30_OPERAND_LABEL12 :
659
      {
660
        long value = fields->f_rel12;
661
        value = ((int) (((value) - (((pc) + (2))))) >> (1));
662
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
663
      }
664
      break;
665
    case FR30_OPERAND_LABEL9 :
666
      {
667
        long value = fields->f_rel9;
668
        value = ((int) (((value) - (((pc) + (2))))) >> (1));
669
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
670
      }
671
      break;
672
    case FR30_OPERAND_M4 :
673
      {
674
        long value = fields->f_m4;
675
        value = ((value) & (15));
676
        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
677
      }
678
      break;
679
    case FR30_OPERAND_PS :
680
      break;
681
    case FR30_OPERAND_REGLIST_HI_LD :
682
      errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
683
      break;
684
    case FR30_OPERAND_REGLIST_HI_ST :
685
      errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
686
      break;
687
    case FR30_OPERAND_REGLIST_LOW_LD :
688
      errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
689
      break;
690
    case FR30_OPERAND_REGLIST_LOW_ST :
691
      errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
692
      break;
693
    case FR30_OPERAND_S10 :
694
      {
695
        long value = fields->f_s10;
696
        value = ((int) (value) >> (2));
697
        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
698
      }
699
      break;
700
    case FR30_OPERAND_U10 :
701
      {
702
        long value = fields->f_u10;
703
        value = ((unsigned int) (value) >> (2));
704
        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
705
      }
706
      break;
707
    case FR30_OPERAND_U4 :
708
      errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
709
      break;
710
    case FR30_OPERAND_U4C :
711
      errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
712
      break;
713
    case FR30_OPERAND_U8 :
714
      errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
715
      break;
716
    case FR30_OPERAND_UDISP6 :
717
      {
718
        long value = fields->f_udisp6;
719
        value = ((unsigned int) (value) >> (2));
720
        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
721
      }
722
      break;
723
 
724
    default :
725
      /* xgettext:c-format */
726
      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
727
               opindex);
728
      abort ();
729
  }
730
 
731
  return errmsg;
732
}
733
 
734
int fr30_cgen_extract_operand
735
  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
736
 
737
/* Main entry point for operand extraction.
738
   The result is <= 0 for error, >0 for success.
739
   ??? Actual values aren't well defined right now.
740
 
741
   This function is basically just a big switch statement.  Earlier versions
742
   used tables to look up the function to use, but
743
   - if the table contains both assembler and disassembler functions then
744
     the disassembler contains much of the assembler and vice-versa,
745
   - there's a lot of inlining possibilities as things grow,
746
   - using a switch statement avoids the function call overhead.
747
 
748
   This function could be moved into `print_insn_normal', but keeping it
749
   separate makes clear the interface between `print_insn_normal' and each of
750
   the handlers.  */
751
 
752
int
753
fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
754
                             int opindex,
755
                             CGEN_EXTRACT_INFO *ex_info,
756
                             CGEN_INSN_INT insn_value,
757
                             CGEN_FIELDS * fields,
758
                             bfd_vma pc)
759
{
760
  /* Assume success (for those operands that are nops).  */
761
  int length = 1;
762
  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
763
 
764
  switch (opindex)
765
    {
766
    case FR30_OPERAND_CRI :
767
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
768
      break;
769
    case FR30_OPERAND_CRJ :
770
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
771
      break;
772
    case FR30_OPERAND_R13 :
773
      break;
774
    case FR30_OPERAND_R14 :
775
      break;
776
    case FR30_OPERAND_R15 :
777
      break;
778
    case FR30_OPERAND_RI :
779
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
780
      break;
781
    case FR30_OPERAND_RIC :
782
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
783
      break;
784
    case FR30_OPERAND_RJ :
785
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
786
      break;
787
    case FR30_OPERAND_RJC :
788
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
789
      break;
790
    case FR30_OPERAND_RS1 :
791
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
792
      break;
793
    case FR30_OPERAND_RS2 :
794
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
795
      break;
796
    case FR30_OPERAND_CC :
797
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
798
      break;
799
    case FR30_OPERAND_CCC :
800
      length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
801
      break;
802
    case FR30_OPERAND_DIR10 :
803
      {
804
        long value;
805
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
806
        value = ((value) << (2));
807
        fields->f_dir10 = value;
808
      }
809
      break;
810
    case FR30_OPERAND_DIR8 :
811
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
812
      break;
813
    case FR30_OPERAND_DIR9 :
814
      {
815
        long value;
816
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
817
        value = ((value) << (1));
818
        fields->f_dir9 = value;
819
      }
820
      break;
821
    case FR30_OPERAND_DISP10 :
822
      {
823
        long value;
824
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
825
        value = ((value) << (2));
826
        fields->f_disp10 = value;
827
      }
828
      break;
829
    case FR30_OPERAND_DISP8 :
830
      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
831
      break;
832
    case FR30_OPERAND_DISP9 :
833
      {
834
        long value;
835
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
836
        value = ((value) << (1));
837
        fields->f_disp9 = value;
838
      }
839
      break;
840
    case FR30_OPERAND_I20 :
841
      {
842
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
843
        if (length <= 0) break;
844
        length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
845
        if (length <= 0) break;
846
{
847
  FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
848
}
849
      }
850
      break;
851
    case FR30_OPERAND_I32 :
852
      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
853
      break;
854
    case FR30_OPERAND_I8 :
855
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
856
      break;
857
    case FR30_OPERAND_LABEL12 :
858
      {
859
        long value;
860
        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);
861
        value = ((((value) << (1))) + (((pc) + (2))));
862
        fields->f_rel12 = value;
863
      }
864
      break;
865
    case FR30_OPERAND_LABEL9 :
866
      {
867
        long value;
868
        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);
869
        value = ((((value) << (1))) + (((pc) + (2))));
870
        fields->f_rel9 = value;
871
      }
872
      break;
873
    case FR30_OPERAND_M4 :
874
      {
875
        long value;
876
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
877
        value = ((value) | (((-1) << (4))));
878
        fields->f_m4 = value;
879
      }
880
      break;
881
    case FR30_OPERAND_PS :
882
      break;
883
    case FR30_OPERAND_REGLIST_HI_LD :
884
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
885
      break;
886
    case FR30_OPERAND_REGLIST_HI_ST :
887
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
888
      break;
889
    case FR30_OPERAND_REGLIST_LOW_LD :
890
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
891
      break;
892
    case FR30_OPERAND_REGLIST_LOW_ST :
893
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
894
      break;
895
    case FR30_OPERAND_S10 :
896
      {
897
        long value;
898
        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
899
        value = ((value) << (2));
900
        fields->f_s10 = value;
901
      }
902
      break;
903
    case FR30_OPERAND_U10 :
904
      {
905
        long value;
906
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
907
        value = ((value) << (2));
908
        fields->f_u10 = value;
909
      }
910
      break;
911
    case FR30_OPERAND_U4 :
912
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
913
      break;
914
    case FR30_OPERAND_U4C :
915
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
916
      break;
917
    case FR30_OPERAND_U8 :
918
      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
919
      break;
920
    case FR30_OPERAND_UDISP6 :
921
      {
922
        long value;
923
        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
924
        value = ((value) << (2));
925
        fields->f_udisp6 = value;
926
      }
927
      break;
928
 
929
    default :
930
      /* xgettext:c-format */
931
      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
932
               opindex);
933
      abort ();
934
    }
935
 
936
  return length;
937
}
938
 
939
cgen_insert_fn * const fr30_cgen_insert_handlers[] =
940
{
941
  insert_insn_normal,
942
};
943
 
944
cgen_extract_fn * const fr30_cgen_extract_handlers[] =
945
{
946
  extract_insn_normal,
947
};
948
 
949
int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
950
bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
951
 
952
/* Getting values from cgen_fields is handled by a collection of functions.
953
   They are distinguished by the type of the VALUE argument they return.
954
   TODO: floating point, inlining support, remove cases where result type
955
   not appropriate.  */
956
 
957
int
958
fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
959
                             int opindex,
960
                             const CGEN_FIELDS * fields)
961
{
962
  int value;
963
 
964
  switch (opindex)
965
    {
966
    case FR30_OPERAND_CRI :
967
      value = fields->f_CRi;
968
      break;
969
    case FR30_OPERAND_CRJ :
970
      value = fields->f_CRj;
971
      break;
972
    case FR30_OPERAND_R13 :
973
      value = 0;
974
      break;
975
    case FR30_OPERAND_R14 :
976
      value = 0;
977
      break;
978
    case FR30_OPERAND_R15 :
979
      value = 0;
980
      break;
981
    case FR30_OPERAND_RI :
982
      value = fields->f_Ri;
983
      break;
984
    case FR30_OPERAND_RIC :
985
      value = fields->f_Ric;
986
      break;
987
    case FR30_OPERAND_RJ :
988
      value = fields->f_Rj;
989
      break;
990
    case FR30_OPERAND_RJC :
991
      value = fields->f_Rjc;
992
      break;
993
    case FR30_OPERAND_RS1 :
994
      value = fields->f_Rs1;
995
      break;
996
    case FR30_OPERAND_RS2 :
997
      value = fields->f_Rs2;
998
      break;
999
    case FR30_OPERAND_CC :
1000
      value = fields->f_cc;
1001
      break;
1002
    case FR30_OPERAND_CCC :
1003
      value = fields->f_ccc;
1004
      break;
1005
    case FR30_OPERAND_DIR10 :
1006
      value = fields->f_dir10;
1007
      break;
1008
    case FR30_OPERAND_DIR8 :
1009
      value = fields->f_dir8;
1010
      break;
1011
    case FR30_OPERAND_DIR9 :
1012
      value = fields->f_dir9;
1013
      break;
1014
    case FR30_OPERAND_DISP10 :
1015
      value = fields->f_disp10;
1016
      break;
1017
    case FR30_OPERAND_DISP8 :
1018
      value = fields->f_disp8;
1019
      break;
1020
    case FR30_OPERAND_DISP9 :
1021
      value = fields->f_disp9;
1022
      break;
1023
    case FR30_OPERAND_I20 :
1024
      value = fields->f_i20;
1025
      break;
1026
    case FR30_OPERAND_I32 :
1027
      value = fields->f_i32;
1028
      break;
1029
    case FR30_OPERAND_I8 :
1030
      value = fields->f_i8;
1031
      break;
1032
    case FR30_OPERAND_LABEL12 :
1033
      value = fields->f_rel12;
1034
      break;
1035
    case FR30_OPERAND_LABEL9 :
1036
      value = fields->f_rel9;
1037
      break;
1038
    case FR30_OPERAND_M4 :
1039
      value = fields->f_m4;
1040
      break;
1041
    case FR30_OPERAND_PS :
1042
      value = 0;
1043
      break;
1044
    case FR30_OPERAND_REGLIST_HI_LD :
1045
      value = fields->f_reglist_hi_ld;
1046
      break;
1047
    case FR30_OPERAND_REGLIST_HI_ST :
1048
      value = fields->f_reglist_hi_st;
1049
      break;
1050
    case FR30_OPERAND_REGLIST_LOW_LD :
1051
      value = fields->f_reglist_low_ld;
1052
      break;
1053
    case FR30_OPERAND_REGLIST_LOW_ST :
1054
      value = fields->f_reglist_low_st;
1055
      break;
1056
    case FR30_OPERAND_S10 :
1057
      value = fields->f_s10;
1058
      break;
1059
    case FR30_OPERAND_U10 :
1060
      value = fields->f_u10;
1061
      break;
1062
    case FR30_OPERAND_U4 :
1063
      value = fields->f_u4;
1064
      break;
1065
    case FR30_OPERAND_U4C :
1066
      value = fields->f_u4c;
1067
      break;
1068
    case FR30_OPERAND_U8 :
1069
      value = fields->f_u8;
1070
      break;
1071
    case FR30_OPERAND_UDISP6 :
1072
      value = fields->f_udisp6;
1073
      break;
1074
 
1075
    default :
1076
      /* xgettext:c-format */
1077
      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1078
                       opindex);
1079
      abort ();
1080
  }
1081
 
1082
  return value;
1083
}
1084
 
1085
bfd_vma
1086
fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1087
                             int opindex,
1088
                             const CGEN_FIELDS * fields)
1089
{
1090
  bfd_vma value;
1091
 
1092
  switch (opindex)
1093
    {
1094
    case FR30_OPERAND_CRI :
1095
      value = fields->f_CRi;
1096
      break;
1097
    case FR30_OPERAND_CRJ :
1098
      value = fields->f_CRj;
1099
      break;
1100
    case FR30_OPERAND_R13 :
1101
      value = 0;
1102
      break;
1103
    case FR30_OPERAND_R14 :
1104
      value = 0;
1105
      break;
1106
    case FR30_OPERAND_R15 :
1107
      value = 0;
1108
      break;
1109
    case FR30_OPERAND_RI :
1110
      value = fields->f_Ri;
1111
      break;
1112
    case FR30_OPERAND_RIC :
1113
      value = fields->f_Ric;
1114
      break;
1115
    case FR30_OPERAND_RJ :
1116
      value = fields->f_Rj;
1117
      break;
1118
    case FR30_OPERAND_RJC :
1119
      value = fields->f_Rjc;
1120
      break;
1121
    case FR30_OPERAND_RS1 :
1122
      value = fields->f_Rs1;
1123
      break;
1124
    case FR30_OPERAND_RS2 :
1125
      value = fields->f_Rs2;
1126
      break;
1127
    case FR30_OPERAND_CC :
1128
      value = fields->f_cc;
1129
      break;
1130
    case FR30_OPERAND_CCC :
1131
      value = fields->f_ccc;
1132
      break;
1133
    case FR30_OPERAND_DIR10 :
1134
      value = fields->f_dir10;
1135
      break;
1136
    case FR30_OPERAND_DIR8 :
1137
      value = fields->f_dir8;
1138
      break;
1139
    case FR30_OPERAND_DIR9 :
1140
      value = fields->f_dir9;
1141
      break;
1142
    case FR30_OPERAND_DISP10 :
1143
      value = fields->f_disp10;
1144
      break;
1145
    case FR30_OPERAND_DISP8 :
1146
      value = fields->f_disp8;
1147
      break;
1148
    case FR30_OPERAND_DISP9 :
1149
      value = fields->f_disp9;
1150
      break;
1151
    case FR30_OPERAND_I20 :
1152
      value = fields->f_i20;
1153
      break;
1154
    case FR30_OPERAND_I32 :
1155
      value = fields->f_i32;
1156
      break;
1157
    case FR30_OPERAND_I8 :
1158
      value = fields->f_i8;
1159
      break;
1160
    case FR30_OPERAND_LABEL12 :
1161
      value = fields->f_rel12;
1162
      break;
1163
    case FR30_OPERAND_LABEL9 :
1164
      value = fields->f_rel9;
1165
      break;
1166
    case FR30_OPERAND_M4 :
1167
      value = fields->f_m4;
1168
      break;
1169
    case FR30_OPERAND_PS :
1170
      value = 0;
1171
      break;
1172
    case FR30_OPERAND_REGLIST_HI_LD :
1173
      value = fields->f_reglist_hi_ld;
1174
      break;
1175
    case FR30_OPERAND_REGLIST_HI_ST :
1176
      value = fields->f_reglist_hi_st;
1177
      break;
1178
    case FR30_OPERAND_REGLIST_LOW_LD :
1179
      value = fields->f_reglist_low_ld;
1180
      break;
1181
    case FR30_OPERAND_REGLIST_LOW_ST :
1182
      value = fields->f_reglist_low_st;
1183
      break;
1184
    case FR30_OPERAND_S10 :
1185
      value = fields->f_s10;
1186
      break;
1187
    case FR30_OPERAND_U10 :
1188
      value = fields->f_u10;
1189
      break;
1190
    case FR30_OPERAND_U4 :
1191
      value = fields->f_u4;
1192
      break;
1193
    case FR30_OPERAND_U4C :
1194
      value = fields->f_u4c;
1195
      break;
1196
    case FR30_OPERAND_U8 :
1197
      value = fields->f_u8;
1198
      break;
1199
    case FR30_OPERAND_UDISP6 :
1200
      value = fields->f_udisp6;
1201
      break;
1202
 
1203
    default :
1204
      /* xgettext:c-format */
1205
      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1206
                       opindex);
1207
      abort ();
1208
  }
1209
 
1210
  return value;
1211
}
1212
 
1213
void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1214
void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1215
 
1216
/* Stuffing values in cgen_fields is handled by a collection of functions.
1217
   They are distinguished by the type of the VALUE argument they accept.
1218
   TODO: floating point, inlining support, remove cases where argument type
1219
   not appropriate.  */
1220
 
1221
void
1222
fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1223
                             int opindex,
1224
                             CGEN_FIELDS * fields,
1225
                             int value)
1226
{
1227
  switch (opindex)
1228
    {
1229
    case FR30_OPERAND_CRI :
1230
      fields->f_CRi = value;
1231
      break;
1232
    case FR30_OPERAND_CRJ :
1233
      fields->f_CRj = value;
1234
      break;
1235
    case FR30_OPERAND_R13 :
1236
      break;
1237
    case FR30_OPERAND_R14 :
1238
      break;
1239
    case FR30_OPERAND_R15 :
1240
      break;
1241
    case FR30_OPERAND_RI :
1242
      fields->f_Ri = value;
1243
      break;
1244
    case FR30_OPERAND_RIC :
1245
      fields->f_Ric = value;
1246
      break;
1247
    case FR30_OPERAND_RJ :
1248
      fields->f_Rj = value;
1249
      break;
1250
    case FR30_OPERAND_RJC :
1251
      fields->f_Rjc = value;
1252
      break;
1253
    case FR30_OPERAND_RS1 :
1254
      fields->f_Rs1 = value;
1255
      break;
1256
    case FR30_OPERAND_RS2 :
1257
      fields->f_Rs2 = value;
1258
      break;
1259
    case FR30_OPERAND_CC :
1260
      fields->f_cc = value;
1261
      break;
1262
    case FR30_OPERAND_CCC :
1263
      fields->f_ccc = value;
1264
      break;
1265
    case FR30_OPERAND_DIR10 :
1266
      fields->f_dir10 = value;
1267
      break;
1268
    case FR30_OPERAND_DIR8 :
1269
      fields->f_dir8 = value;
1270
      break;
1271
    case FR30_OPERAND_DIR9 :
1272
      fields->f_dir9 = value;
1273
      break;
1274
    case FR30_OPERAND_DISP10 :
1275
      fields->f_disp10 = value;
1276
      break;
1277
    case FR30_OPERAND_DISP8 :
1278
      fields->f_disp8 = value;
1279
      break;
1280
    case FR30_OPERAND_DISP9 :
1281
      fields->f_disp9 = value;
1282
      break;
1283
    case FR30_OPERAND_I20 :
1284
      fields->f_i20 = value;
1285
      break;
1286
    case FR30_OPERAND_I32 :
1287
      fields->f_i32 = value;
1288
      break;
1289
    case FR30_OPERAND_I8 :
1290
      fields->f_i8 = value;
1291
      break;
1292
    case FR30_OPERAND_LABEL12 :
1293
      fields->f_rel12 = value;
1294
      break;
1295
    case FR30_OPERAND_LABEL9 :
1296
      fields->f_rel9 = value;
1297
      break;
1298
    case FR30_OPERAND_M4 :
1299
      fields->f_m4 = value;
1300
      break;
1301
    case FR30_OPERAND_PS :
1302
      break;
1303
    case FR30_OPERAND_REGLIST_HI_LD :
1304
      fields->f_reglist_hi_ld = value;
1305
      break;
1306
    case FR30_OPERAND_REGLIST_HI_ST :
1307
      fields->f_reglist_hi_st = value;
1308
      break;
1309
    case FR30_OPERAND_REGLIST_LOW_LD :
1310
      fields->f_reglist_low_ld = value;
1311
      break;
1312
    case FR30_OPERAND_REGLIST_LOW_ST :
1313
      fields->f_reglist_low_st = value;
1314
      break;
1315
    case FR30_OPERAND_S10 :
1316
      fields->f_s10 = value;
1317
      break;
1318
    case FR30_OPERAND_U10 :
1319
      fields->f_u10 = value;
1320
      break;
1321
    case FR30_OPERAND_U4 :
1322
      fields->f_u4 = value;
1323
      break;
1324
    case FR30_OPERAND_U4C :
1325
      fields->f_u4c = value;
1326
      break;
1327
    case FR30_OPERAND_U8 :
1328
      fields->f_u8 = value;
1329
      break;
1330
    case FR30_OPERAND_UDISP6 :
1331
      fields->f_udisp6 = value;
1332
      break;
1333
 
1334
    default :
1335
      /* xgettext:c-format */
1336
      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1337
                       opindex);
1338
      abort ();
1339
  }
1340
}
1341
 
1342
void
1343
fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1344
                             int opindex,
1345
                             CGEN_FIELDS * fields,
1346
                             bfd_vma value)
1347
{
1348
  switch (opindex)
1349
    {
1350
    case FR30_OPERAND_CRI :
1351
      fields->f_CRi = value;
1352
      break;
1353
    case FR30_OPERAND_CRJ :
1354
      fields->f_CRj = value;
1355
      break;
1356
    case FR30_OPERAND_R13 :
1357
      break;
1358
    case FR30_OPERAND_R14 :
1359
      break;
1360
    case FR30_OPERAND_R15 :
1361
      break;
1362
    case FR30_OPERAND_RI :
1363
      fields->f_Ri = value;
1364
      break;
1365
    case FR30_OPERAND_RIC :
1366
      fields->f_Ric = value;
1367
      break;
1368
    case FR30_OPERAND_RJ :
1369
      fields->f_Rj = value;
1370
      break;
1371
    case FR30_OPERAND_RJC :
1372
      fields->f_Rjc = value;
1373
      break;
1374
    case FR30_OPERAND_RS1 :
1375
      fields->f_Rs1 = value;
1376
      break;
1377
    case FR30_OPERAND_RS2 :
1378
      fields->f_Rs2 = value;
1379
      break;
1380
    case FR30_OPERAND_CC :
1381
      fields->f_cc = value;
1382
      break;
1383
    case FR30_OPERAND_CCC :
1384
      fields->f_ccc = value;
1385
      break;
1386
    case FR30_OPERAND_DIR10 :
1387
      fields->f_dir10 = value;
1388
      break;
1389
    case FR30_OPERAND_DIR8 :
1390
      fields->f_dir8 = value;
1391
      break;
1392
    case FR30_OPERAND_DIR9 :
1393
      fields->f_dir9 = value;
1394
      break;
1395
    case FR30_OPERAND_DISP10 :
1396
      fields->f_disp10 = value;
1397
      break;
1398
    case FR30_OPERAND_DISP8 :
1399
      fields->f_disp8 = value;
1400
      break;
1401
    case FR30_OPERAND_DISP9 :
1402
      fields->f_disp9 = value;
1403
      break;
1404
    case FR30_OPERAND_I20 :
1405
      fields->f_i20 = value;
1406
      break;
1407
    case FR30_OPERAND_I32 :
1408
      fields->f_i32 = value;
1409
      break;
1410
    case FR30_OPERAND_I8 :
1411
      fields->f_i8 = value;
1412
      break;
1413
    case FR30_OPERAND_LABEL12 :
1414
      fields->f_rel12 = value;
1415
      break;
1416
    case FR30_OPERAND_LABEL9 :
1417
      fields->f_rel9 = value;
1418
      break;
1419
    case FR30_OPERAND_M4 :
1420
      fields->f_m4 = value;
1421
      break;
1422
    case FR30_OPERAND_PS :
1423
      break;
1424
    case FR30_OPERAND_REGLIST_HI_LD :
1425
      fields->f_reglist_hi_ld = value;
1426
      break;
1427
    case FR30_OPERAND_REGLIST_HI_ST :
1428
      fields->f_reglist_hi_st = value;
1429
      break;
1430
    case FR30_OPERAND_REGLIST_LOW_LD :
1431
      fields->f_reglist_low_ld = value;
1432
      break;
1433
    case FR30_OPERAND_REGLIST_LOW_ST :
1434
      fields->f_reglist_low_st = value;
1435
      break;
1436
    case FR30_OPERAND_S10 :
1437
      fields->f_s10 = value;
1438
      break;
1439
    case FR30_OPERAND_U10 :
1440
      fields->f_u10 = value;
1441
      break;
1442
    case FR30_OPERAND_U4 :
1443
      fields->f_u4 = value;
1444
      break;
1445
    case FR30_OPERAND_U4C :
1446
      fields->f_u4c = value;
1447
      break;
1448
    case FR30_OPERAND_U8 :
1449
      fields->f_u8 = value;
1450
      break;
1451
    case FR30_OPERAND_UDISP6 :
1452
      fields->f_udisp6 = value;
1453
      break;
1454
 
1455
    default :
1456
      /* xgettext:c-format */
1457
      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1458
                       opindex);
1459
      abort ();
1460
  }
1461
}
1462
 
1463
/* Function to call before using the instruction builder tables.  */
1464
 
1465
void
1466
fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1467
{
1468
  cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1469
  cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1470
 
1471
  cd->insert_operand = fr30_cgen_insert_operand;
1472
  cd->extract_operand = fr30_cgen_extract_operand;
1473
 
1474
  cd->get_int_operand = fr30_cgen_get_int_operand;
1475
  cd->set_int_operand = fr30_cgen_set_int_operand;
1476
  cd->get_vma_operand = fr30_cgen_get_vma_operand;
1477
  cd->set_vma_operand = fr30_cgen_set_vma_operand;
1478
}

powered by: WebSVN 2.1.0

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