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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [opcodes/] [iq2000-ibld.c] - Blame information for rev 330

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

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

powered by: WebSVN 2.1.0

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