]> Git Repo - binutils.git/blob - opcodes/lm32-ibld.c
Add libctf to update-copyright.py
[binutils.git] / opcodes / lm32-ibld.c
1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2 /* Instruction building/extraction support for lm32. -*- 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-2020 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 "lm32-desc.h"
35 #include "lm32-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 * lm32_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 lm32_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 LM32_OPERAND_BRANCH :
582       {
583         long value = fields->f_branch;
584         value = ((SI) (((value) - (pc))) >> (2));
585         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, buffer);
586       }
587       break;
588     case LM32_OPERAND_CALL :
589       {
590         long value = fields->f_call;
591         value = ((SI) (((value) - (pc))) >> (2));
592         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, buffer);
593       }
594       break;
595     case LM32_OPERAND_CSR :
596       errmsg = insert_normal (cd, fields->f_csr, 0, 0, 25, 5, 32, total_length, buffer);
597       break;
598     case LM32_OPERAND_EXCEPTION :
599       errmsg = insert_normal (cd, fields->f_exception, 0, 0, 25, 26, 32, total_length, buffer);
600       break;
601     case LM32_OPERAND_GOT16 :
602       errmsg = insert_normal (cd, fields->f_imm, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
603       break;
604     case LM32_OPERAND_GOTOFFHI16 :
605       errmsg = insert_normal (cd, fields->f_imm, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
606       break;
607     case LM32_OPERAND_GOTOFFLO16 :
608       errmsg = insert_normal (cd, fields->f_imm, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
609       break;
610     case LM32_OPERAND_GP16 :
611       errmsg = insert_normal (cd, fields->f_imm, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
612       break;
613     case LM32_OPERAND_HI16 :
614       errmsg = insert_normal (cd, fields->f_uimm, 0, 0, 15, 16, 32, total_length, buffer);
615       break;
616     case LM32_OPERAND_IMM :
617       errmsg = insert_normal (cd, fields->f_imm, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
618       break;
619     case LM32_OPERAND_LO16 :
620       errmsg = insert_normal (cd, fields->f_uimm, 0, 0, 15, 16, 32, total_length, buffer);
621       break;
622     case LM32_OPERAND_R0 :
623       errmsg = insert_normal (cd, fields->f_r0, 0, 0, 25, 5, 32, total_length, buffer);
624       break;
625     case LM32_OPERAND_R1 :
626       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 20, 5, 32, total_length, buffer);
627       break;
628     case LM32_OPERAND_R2 :
629       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 15, 5, 32, total_length, buffer);
630       break;
631     case LM32_OPERAND_SHIFT :
632       errmsg = insert_normal (cd, fields->f_shift, 0, 0, 4, 5, 32, total_length, buffer);
633       break;
634     case LM32_OPERAND_UIMM :
635       errmsg = insert_normal (cd, fields->f_uimm, 0, 0, 15, 16, 32, total_length, buffer);
636       break;
637     case LM32_OPERAND_USER :
638       errmsg = insert_normal (cd, fields->f_user, 0, 0, 10, 11, 32, total_length, buffer);
639       break;
640
641     default :
642       /* xgettext:c-format */
643       opcodes_error_handler
644         (_("internal error: unrecognized field %d while building insn"),
645          opindex);
646       abort ();
647   }
648
649   return errmsg;
650 }
651
652 int lm32_cgen_extract_operand
653   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
654
655 /* Main entry point for operand extraction.
656    The result is <= 0 for error, >0 for success.
657    ??? Actual values aren't well defined right now.
658
659    This function is basically just a big switch statement.  Earlier versions
660    used tables to look up the function to use, but
661    - if the table contains both assembler and disassembler functions then
662      the disassembler contains much of the assembler and vice-versa,
663    - there's a lot of inlining possibilities as things grow,
664    - using a switch statement avoids the function call overhead.
665
666    This function could be moved into `print_insn_normal', but keeping it
667    separate makes clear the interface between `print_insn_normal' and each of
668    the handlers.  */
669
670 int
671 lm32_cgen_extract_operand (CGEN_CPU_DESC cd,
672                              int opindex,
673                              CGEN_EXTRACT_INFO *ex_info,
674                              CGEN_INSN_INT insn_value,
675                              CGEN_FIELDS * fields,
676                              bfd_vma pc)
677 {
678   /* Assume success (for those operands that are nops).  */
679   int length = 1;
680   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
681
682   switch (opindex)
683     {
684     case LM32_OPERAND_BRANCH :
685       {
686         long value;
687         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value);
688         value = ((pc) + (((((((((value) & (65535))) << (2))) ^ (131072))) - (131072))));
689         fields->f_branch = value;
690       }
691       break;
692     case LM32_OPERAND_CALL :
693       {
694         long value;
695         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, pc, & value);
696         value = ((pc) + (((((((((value) & (67108863))) << (2))) ^ (134217728))) - (134217728))));
697         fields->f_call = value;
698       }
699       break;
700     case LM32_OPERAND_CSR :
701       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_csr);
702       break;
703     case LM32_OPERAND_EXCEPTION :
704       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 26, 32, total_length, pc, & fields->f_exception);
705       break;
706     case LM32_OPERAND_GOT16 :
707       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_imm);
708       break;
709     case LM32_OPERAND_GOTOFFHI16 :
710       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_imm);
711       break;
712     case LM32_OPERAND_GOTOFFLO16 :
713       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_imm);
714       break;
715     case LM32_OPERAND_GP16 :
716       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_imm);
717       break;
718     case LM32_OPERAND_HI16 :
719       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm);
720       break;
721     case LM32_OPERAND_IMM :
722       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_imm);
723       break;
724     case LM32_OPERAND_LO16 :
725       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm);
726       break;
727     case LM32_OPERAND_R0 :
728       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r0);
729       break;
730     case LM32_OPERAND_R1 :
731       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r1);
732       break;
733     case LM32_OPERAND_R2 :
734       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r2);
735       break;
736     case LM32_OPERAND_SHIFT :
737       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_shift);
738       break;
739     case LM32_OPERAND_UIMM :
740       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm);
741       break;
742     case LM32_OPERAND_USER :
743       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_user);
744       break;
745
746     default :
747       /* xgettext:c-format */
748       opcodes_error_handler
749         (_("internal error: unrecognized field %d while decoding insn"),
750          opindex);
751       abort ();
752     }
753
754   return length;
755 }
756
757 cgen_insert_fn * const lm32_cgen_insert_handlers[] =
758 {
759   insert_insn_normal,
760 };
761
762 cgen_extract_fn * const lm32_cgen_extract_handlers[] =
763 {
764   extract_insn_normal,
765 };
766
767 int lm32_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
768 bfd_vma lm32_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
769
770 /* Getting values from cgen_fields is handled by a collection of functions.
771    They are distinguished by the type of the VALUE argument they return.
772    TODO: floating point, inlining support, remove cases where result type
773    not appropriate.  */
774
775 int
776 lm32_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
777                              int opindex,
778                              const CGEN_FIELDS * fields)
779 {
780   int value;
781
782   switch (opindex)
783     {
784     case LM32_OPERAND_BRANCH :
785       value = fields->f_branch;
786       break;
787     case LM32_OPERAND_CALL :
788       value = fields->f_call;
789       break;
790     case LM32_OPERAND_CSR :
791       value = fields->f_csr;
792       break;
793     case LM32_OPERAND_EXCEPTION :
794       value = fields->f_exception;
795       break;
796     case LM32_OPERAND_GOT16 :
797       value = fields->f_imm;
798       break;
799     case LM32_OPERAND_GOTOFFHI16 :
800       value = fields->f_imm;
801       break;
802     case LM32_OPERAND_GOTOFFLO16 :
803       value = fields->f_imm;
804       break;
805     case LM32_OPERAND_GP16 :
806       value = fields->f_imm;
807       break;
808     case LM32_OPERAND_HI16 :
809       value = fields->f_uimm;
810       break;
811     case LM32_OPERAND_IMM :
812       value = fields->f_imm;
813       break;
814     case LM32_OPERAND_LO16 :
815       value = fields->f_uimm;
816       break;
817     case LM32_OPERAND_R0 :
818       value = fields->f_r0;
819       break;
820     case LM32_OPERAND_R1 :
821       value = fields->f_r1;
822       break;
823     case LM32_OPERAND_R2 :
824       value = fields->f_r2;
825       break;
826     case LM32_OPERAND_SHIFT :
827       value = fields->f_shift;
828       break;
829     case LM32_OPERAND_UIMM :
830       value = fields->f_uimm;
831       break;
832     case LM32_OPERAND_USER :
833       value = fields->f_user;
834       break;
835
836     default :
837       /* xgettext:c-format */
838       opcodes_error_handler
839         (_("internal error: unrecognized field %d while getting int operand"),
840          opindex);
841       abort ();
842   }
843
844   return value;
845 }
846
847 bfd_vma
848 lm32_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
849                              int opindex,
850                              const CGEN_FIELDS * fields)
851 {
852   bfd_vma value;
853
854   switch (opindex)
855     {
856     case LM32_OPERAND_BRANCH :
857       value = fields->f_branch;
858       break;
859     case LM32_OPERAND_CALL :
860       value = fields->f_call;
861       break;
862     case LM32_OPERAND_CSR :
863       value = fields->f_csr;
864       break;
865     case LM32_OPERAND_EXCEPTION :
866       value = fields->f_exception;
867       break;
868     case LM32_OPERAND_GOT16 :
869       value = fields->f_imm;
870       break;
871     case LM32_OPERAND_GOTOFFHI16 :
872       value = fields->f_imm;
873       break;
874     case LM32_OPERAND_GOTOFFLO16 :
875       value = fields->f_imm;
876       break;
877     case LM32_OPERAND_GP16 :
878       value = fields->f_imm;
879       break;
880     case LM32_OPERAND_HI16 :
881       value = fields->f_uimm;
882       break;
883     case LM32_OPERAND_IMM :
884       value = fields->f_imm;
885       break;
886     case LM32_OPERAND_LO16 :
887       value = fields->f_uimm;
888       break;
889     case LM32_OPERAND_R0 :
890       value = fields->f_r0;
891       break;
892     case LM32_OPERAND_R1 :
893       value = fields->f_r1;
894       break;
895     case LM32_OPERAND_R2 :
896       value = fields->f_r2;
897       break;
898     case LM32_OPERAND_SHIFT :
899       value = fields->f_shift;
900       break;
901     case LM32_OPERAND_UIMM :
902       value = fields->f_uimm;
903       break;
904     case LM32_OPERAND_USER :
905       value = fields->f_user;
906       break;
907
908     default :
909       /* xgettext:c-format */
910       opcodes_error_handler
911         (_("internal error: unrecognized field %d while getting vma operand"),
912          opindex);
913       abort ();
914   }
915
916   return value;
917 }
918
919 void lm32_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
920 void lm32_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
921
922 /* Stuffing values in cgen_fields is handled by a collection of functions.
923    They are distinguished by the type of the VALUE argument they accept.
924    TODO: floating point, inlining support, remove cases where argument type
925    not appropriate.  */
926
927 void
928 lm32_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
929                              int opindex,
930                              CGEN_FIELDS * fields,
931                              int value)
932 {
933   switch (opindex)
934     {
935     case LM32_OPERAND_BRANCH :
936       fields->f_branch = value;
937       break;
938     case LM32_OPERAND_CALL :
939       fields->f_call = value;
940       break;
941     case LM32_OPERAND_CSR :
942       fields->f_csr = value;
943       break;
944     case LM32_OPERAND_EXCEPTION :
945       fields->f_exception = value;
946       break;
947     case LM32_OPERAND_GOT16 :
948       fields->f_imm = value;
949       break;
950     case LM32_OPERAND_GOTOFFHI16 :
951       fields->f_imm = value;
952       break;
953     case LM32_OPERAND_GOTOFFLO16 :
954       fields->f_imm = value;
955       break;
956     case LM32_OPERAND_GP16 :
957       fields->f_imm = value;
958       break;
959     case LM32_OPERAND_HI16 :
960       fields->f_uimm = value;
961       break;
962     case LM32_OPERAND_IMM :
963       fields->f_imm = value;
964       break;
965     case LM32_OPERAND_LO16 :
966       fields->f_uimm = value;
967       break;
968     case LM32_OPERAND_R0 :
969       fields->f_r0 = value;
970       break;
971     case LM32_OPERAND_R1 :
972       fields->f_r1 = value;
973       break;
974     case LM32_OPERAND_R2 :
975       fields->f_r2 = value;
976       break;
977     case LM32_OPERAND_SHIFT :
978       fields->f_shift = value;
979       break;
980     case LM32_OPERAND_UIMM :
981       fields->f_uimm = value;
982       break;
983     case LM32_OPERAND_USER :
984       fields->f_user = value;
985       break;
986
987     default :
988       /* xgettext:c-format */
989       opcodes_error_handler
990         (_("internal error: unrecognized field %d while setting int operand"),
991          opindex);
992       abort ();
993   }
994 }
995
996 void
997 lm32_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
998                              int opindex,
999                              CGEN_FIELDS * fields,
1000                              bfd_vma value)
1001 {
1002   switch (opindex)
1003     {
1004     case LM32_OPERAND_BRANCH :
1005       fields->f_branch = value;
1006       break;
1007     case LM32_OPERAND_CALL :
1008       fields->f_call = value;
1009       break;
1010     case LM32_OPERAND_CSR :
1011       fields->f_csr = value;
1012       break;
1013     case LM32_OPERAND_EXCEPTION :
1014       fields->f_exception = value;
1015       break;
1016     case LM32_OPERAND_GOT16 :
1017       fields->f_imm = value;
1018       break;
1019     case LM32_OPERAND_GOTOFFHI16 :
1020       fields->f_imm = value;
1021       break;
1022     case LM32_OPERAND_GOTOFFLO16 :
1023       fields->f_imm = value;
1024       break;
1025     case LM32_OPERAND_GP16 :
1026       fields->f_imm = value;
1027       break;
1028     case LM32_OPERAND_HI16 :
1029       fields->f_uimm = value;
1030       break;
1031     case LM32_OPERAND_IMM :
1032       fields->f_imm = value;
1033       break;
1034     case LM32_OPERAND_LO16 :
1035       fields->f_uimm = value;
1036       break;
1037     case LM32_OPERAND_R0 :
1038       fields->f_r0 = value;
1039       break;
1040     case LM32_OPERAND_R1 :
1041       fields->f_r1 = value;
1042       break;
1043     case LM32_OPERAND_R2 :
1044       fields->f_r2 = value;
1045       break;
1046     case LM32_OPERAND_SHIFT :
1047       fields->f_shift = value;
1048       break;
1049     case LM32_OPERAND_UIMM :
1050       fields->f_uimm = value;
1051       break;
1052     case LM32_OPERAND_USER :
1053       fields->f_user = value;
1054       break;
1055
1056     default :
1057       /* xgettext:c-format */
1058       opcodes_error_handler
1059         (_("internal error: unrecognized field %d while setting vma operand"),
1060          opindex);
1061       abort ();
1062   }
1063 }
1064
1065 /* Function to call before using the instruction builder tables.  */
1066
1067 void
1068 lm32_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1069 {
1070   cd->insert_handlers = & lm32_cgen_insert_handlers[0];
1071   cd->extract_handlers = & lm32_cgen_extract_handlers[0];
1072
1073   cd->insert_operand = lm32_cgen_insert_operand;
1074   cd->extract_operand = lm32_cgen_extract_operand;
1075
1076   cd->get_int_operand = lm32_cgen_get_int_operand;
1077   cd->set_int_operand = lm32_cgen_set_int_operand;
1078   cd->get_vma_operand = lm32_cgen_get_vma_operand;
1079   cd->set_vma_operand = lm32_cgen_set_vma_operand;
1080 }
This page took 0.088249 seconds and 4 git commands to generate.