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