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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [opcodes/] [fr30-ibld.c] - Blame information for rev 1782

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

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

powered by: WebSVN 2.1.0

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