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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [opcodes/] [iq2000-ibld.c] - Blame information for rev 856

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

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

powered by: WebSVN 2.1.0

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