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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [m32r-ibld.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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