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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [opcodes/] [m32r-ibld.c] - Blame information for rev 106

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

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

powered by: WebSVN 2.1.0

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