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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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