1/* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2/* Instruction building/extraction support for or1k. -*- 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-2022 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 "or1k-desc.h"
35#include "or1k-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
48static 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);
51static const char * insert_insn_normal
52  (CGEN_CPU_DESC, const CGEN_INSN *,
53   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54static 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 *);
58static 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
62static 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
66static CGEN_INLINE void insert_1
67  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68static CGEN_INLINE int fill_cache
69  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
70static CGEN_INLINE long extract_1
71  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72#endif
73
74/* Operand insertion.  */
75
76#if ! CGEN_INT_INSN_P
77
78/* Subroutine of insert_normal.  */
79
80static CGEN_INLINE void
81insert_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
122static const char *
123insert_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
249static const char *
250insert_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
304static void
305put_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
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
336static CGEN_INLINE int
337fill_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
380static CGEN_INLINE long
381extract_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
423static int
424extract_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
518static int
519extract_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
550/* Machine generated code added here.  */
551
552const char * or1k_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
569const char *
570or1k_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 OR1K_OPERAND_DISP21 :
582      {
583        long value = fields->f_disp21;
584        value = ((((SI) (value) >> (13))) - (((SI) (pc) >> (13))));
585        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer);
586      }
587      break;
588    case OR1K_OPERAND_DISP26 :
589      {
590        long value = fields->f_disp26;
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 OR1K_OPERAND_RA :
596      errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
597      break;
598    case OR1K_OPERAND_RAD32F :
599      {
600{
601  FLD (f_r2) = ((FLD (f_rad32)) & (31));
602  FLD (f_raoff_9_1) = ((((SI) (FLD (f_rad32)) >> (5))) & (1));
603}
604        errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
605        if (errmsg)
606          break;
607        errmsg = insert_normal (cd, fields->f_raoff_9_1, 0, 0, 9, 1, 32, total_length, buffer);
608        if (errmsg)
609          break;
610      }
611      break;
612    case OR1K_OPERAND_RADI :
613      {
614{
615  FLD (f_r2) = ((FLD (f_rad32)) & (31));
616  FLD (f_raoff_9_1) = ((((SI) (FLD (f_rad32)) >> (5))) & (1));
617}
618        errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
619        if (errmsg)
620          break;
621        errmsg = insert_normal (cd, fields->f_raoff_9_1, 0, 0, 9, 1, 32, total_length, buffer);
622        if (errmsg)
623          break;
624      }
625      break;
626    case OR1K_OPERAND_RASF :
627      errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
628      break;
629    case OR1K_OPERAND_RB :
630      errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
631      break;
632    case OR1K_OPERAND_RBD32F :
633      {
634{
635  FLD (f_r3) = ((FLD (f_rbd32)) & (31));
636  FLD (f_rboff_8_1) = ((((SI) (FLD (f_rbd32)) >> (5))) & (1));
637}
638        errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
639        if (errmsg)
640          break;
641        errmsg = insert_normal (cd, fields->f_rboff_8_1, 0, 0, 8, 1, 32, total_length, buffer);
642        if (errmsg)
643          break;
644      }
645      break;
646    case OR1K_OPERAND_RBDI :
647      {
648{
649  FLD (f_r3) = ((FLD (f_rbd32)) & (31));
650  FLD (f_rboff_8_1) = ((((SI) (FLD (f_rbd32)) >> (5))) & (1));
651}
652        errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
653        if (errmsg)
654          break;
655        errmsg = insert_normal (cd, fields->f_rboff_8_1, 0, 0, 8, 1, 32, total_length, buffer);
656        if (errmsg)
657          break;
658      }
659      break;
660    case OR1K_OPERAND_RBSF :
661      errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
662      break;
663    case OR1K_OPERAND_RD :
664      errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
665      break;
666    case OR1K_OPERAND_RDD32F :
667      {
668{
669  FLD (f_r1) = ((FLD (f_rdd32)) & (31));
670  FLD (f_rdoff_10_1) = ((((SI) (FLD (f_rdd32)) >> (5))) & (1));
671}
672        errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
673        if (errmsg)
674          break;
675        errmsg = insert_normal (cd, fields->f_rdoff_10_1, 0, 0, 10, 1, 32, total_length, buffer);
676        if (errmsg)
677          break;
678      }
679      break;
680    case OR1K_OPERAND_RDDI :
681      {
682{
683  FLD (f_r1) = ((FLD (f_rdd32)) & (31));
684  FLD (f_rdoff_10_1) = ((((SI) (FLD (f_rdd32)) >> (5))) & (1));
685}
686        errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
687        if (errmsg)
688          break;
689        errmsg = insert_normal (cd, fields->f_rdoff_10_1, 0, 0, 10, 1, 32, total_length, buffer);
690        if (errmsg)
691          break;
692      }
693      break;
694    case OR1K_OPERAND_RDSF :
695      errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
696      break;
697    case OR1K_OPERAND_SIMM16 :
698      errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_SIGN_OPT), 0, 15, 16, 32, total_length, buffer);
699      break;
700    case OR1K_OPERAND_SIMM16_SPLIT :
701      {
702{
703  FLD (f_imm16_25_5) = ((((INT) (FLD (f_simm16_split)) >> (11))) & (31));
704  FLD (f_imm16_10_11) = ((FLD (f_simm16_split)) & (2047));
705}
706        errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer);
707        if (errmsg)
708          break;
709        errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer);
710        if (errmsg)
711          break;
712      }
713      break;
714    case OR1K_OPERAND_UIMM16 :
715      errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 15, 16, 32, total_length, buffer);
716      break;
717    case OR1K_OPERAND_UIMM16_SPLIT :
718      {
719{
720  FLD (f_imm16_25_5) = ((((UINT) (FLD (f_uimm16_split)) >> (11))) & (31));
721  FLD (f_imm16_10_11) = ((FLD (f_uimm16_split)) & (2047));
722}
723        errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer);
724        if (errmsg)
725          break;
726        errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer);
727        if (errmsg)
728          break;
729      }
730      break;
731    case OR1K_OPERAND_UIMM6 :
732      errmsg = insert_normal (cd, fields->f_uimm6, 0, 0, 5, 6, 32, total_length, buffer);
733      break;
734
735    default :
736      /* xgettext:c-format */
737      opcodes_error_handler
738	(_("internal error: unrecognized field %d while building insn"),
739	 opindex);
740      abort ();
741  }
742
743  return errmsg;
744}
745
746int or1k_cgen_extract_operand
747  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
748
749/* Main entry point for operand extraction.
750   The result is <= 0 for error, >0 for success.
751   ??? Actual values aren't well defined right now.
752
753   This function is basically just a big switch statement.  Earlier versions
754   used tables to look up the function to use, but
755   - if the table contains both assembler and disassembler functions then
756     the disassembler contains much of the assembler and vice-versa,
757   - there's a lot of inlining possibilities as things grow,
758   - using a switch statement avoids the function call overhead.
759
760   This function could be moved into `print_insn_normal', but keeping it
761   separate makes clear the interface between `print_insn_normal' and each of
762   the handlers.  */
763
764int
765or1k_cgen_extract_operand (CGEN_CPU_DESC cd,
766			     int opindex,
767			     CGEN_EXTRACT_INFO *ex_info,
768			     CGEN_INSN_INT insn_value,
769			     CGEN_FIELDS * fields,
770			     bfd_vma pc)
771{
772  /* Assume success (for those operands that are nops).  */
773  int length = 1;
774  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
775
776  switch (opindex)
777    {
778    case OR1K_OPERAND_DISP21 :
779      {
780        long value;
781        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value);
782        value = ((((value) + (((SI) (pc) >> (13))))) * (8192));
783        fields->f_disp21 = value;
784      }
785      break;
786    case OR1K_OPERAND_DISP26 :
787      {
788        long value;
789        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);
790        value = ((((value) * (4))) + (pc));
791        fields->f_disp26 = value;
792      }
793      break;
794    case OR1K_OPERAND_RA :
795      length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
796      break;
797    case OR1K_OPERAND_RAD32F :
798      {
799        length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
800        if (length <= 0) break;
801        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 1, 32, total_length, pc, & fields->f_raoff_9_1);
802        if (length <= 0) break;
803  FLD (f_rad32) = ((FLD (f_r2)) | (((FLD (f_raoff_9_1)) << (5))));
804      }
805      break;
806    case OR1K_OPERAND_RADI :
807      {
808        length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
809        if (length <= 0) break;
810        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 1, 32, total_length, pc, & fields->f_raoff_9_1);
811        if (length <= 0) break;
812  FLD (f_rad32) = ((FLD (f_r2)) | (((FLD (f_raoff_9_1)) << (5))));
813      }
814      break;
815    case OR1K_OPERAND_RASF :
816      length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
817      break;
818    case OR1K_OPERAND_RB :
819      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
820      break;
821    case OR1K_OPERAND_RBD32F :
822      {
823        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
824        if (length <= 0) break;
825        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_rboff_8_1);
826        if (length <= 0) break;
827  FLD (f_rbd32) = ((FLD (f_r3)) | (((FLD (f_rboff_8_1)) << (5))));
828      }
829      break;
830    case OR1K_OPERAND_RBDI :
831      {
832        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
833        if (length <= 0) break;
834        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_rboff_8_1);
835        if (length <= 0) break;
836  FLD (f_rbd32) = ((FLD (f_r3)) | (((FLD (f_rboff_8_1)) << (5))));
837      }
838      break;
839    case OR1K_OPERAND_RBSF :
840      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
841      break;
842    case OR1K_OPERAND_RD :
843      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
844      break;
845    case OR1K_OPERAND_RDD32F :
846      {
847        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
848        if (length <= 0) break;
849        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_rdoff_10_1);
850        if (length <= 0) break;
851  FLD (f_rdd32) = ((FLD (f_r1)) | (((FLD (f_rdoff_10_1)) << (5))));
852      }
853      break;
854    case OR1K_OPERAND_RDDI :
855      {
856        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
857        if (length <= 0) break;
858        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_rdoff_10_1);
859        if (length <= 0) break;
860  FLD (f_rdd32) = ((FLD (f_r1)) | (((FLD (f_rdoff_10_1)) << (5))));
861      }
862      break;
863    case OR1K_OPERAND_RDSF :
864      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
865      break;
866    case OR1K_OPERAND_SIMM16 :
867      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_SIGN_OPT), 0, 15, 16, 32, total_length, pc, & fields->f_simm16);
868      break;
869    case OR1K_OPERAND_SIMM16_SPLIT :
870      {
871        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5);
872        if (length <= 0) break;
873        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11);
874        if (length <= 0) break;
875  FLD (f_simm16_split) = ((HI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11)))));
876      }
877      break;
878    case OR1K_OPERAND_UIMM16 :
879      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm16);
880      break;
881    case OR1K_OPERAND_UIMM16_SPLIT :
882      {
883        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5);
884        if (length <= 0) break;
885        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11);
886        if (length <= 0) break;
887  FLD (f_uimm16_split) = ((UHI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11)))));
888      }
889      break;
890    case OR1K_OPERAND_UIMM6 :
891      length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_uimm6);
892      break;
893
894    default :
895      /* xgettext:c-format */
896      opcodes_error_handler
897	(_("internal error: unrecognized field %d while decoding insn"),
898	 opindex);
899      abort ();
900    }
901
902  return length;
903}
904
905cgen_insert_fn * const or1k_cgen_insert_handlers[] =
906{
907  insert_insn_normal,
908};
909
910cgen_extract_fn * const or1k_cgen_extract_handlers[] =
911{
912  extract_insn_normal,
913};
914
915int or1k_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
916bfd_vma or1k_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
917
918/* Getting values from cgen_fields is handled by a collection of functions.
919   They are distinguished by the type of the VALUE argument they return.
920   TODO: floating point, inlining support, remove cases where result type
921   not appropriate.  */
922
923int
924or1k_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
925			     int opindex,
926			     const CGEN_FIELDS * fields)
927{
928  int value;
929
930  switch (opindex)
931    {
932    case OR1K_OPERAND_DISP21 :
933      value = fields->f_disp21;
934      break;
935    case OR1K_OPERAND_DISP26 :
936      value = fields->f_disp26;
937      break;
938    case OR1K_OPERAND_RA :
939      value = fields->f_r2;
940      break;
941    case OR1K_OPERAND_RAD32F :
942      value = fields->f_rad32;
943      break;
944    case OR1K_OPERAND_RADI :
945      value = fields->f_rad32;
946      break;
947    case OR1K_OPERAND_RASF :
948      value = fields->f_r2;
949      break;
950    case OR1K_OPERAND_RB :
951      value = fields->f_r3;
952      break;
953    case OR1K_OPERAND_RBD32F :
954      value = fields->f_rbd32;
955      break;
956    case OR1K_OPERAND_RBDI :
957      value = fields->f_rbd32;
958      break;
959    case OR1K_OPERAND_RBSF :
960      value = fields->f_r3;
961      break;
962    case OR1K_OPERAND_RD :
963      value = fields->f_r1;
964      break;
965    case OR1K_OPERAND_RDD32F :
966      value = fields->f_rdd32;
967      break;
968    case OR1K_OPERAND_RDDI :
969      value = fields->f_rdd32;
970      break;
971    case OR1K_OPERAND_RDSF :
972      value = fields->f_r1;
973      break;
974    case OR1K_OPERAND_SIMM16 :
975      value = fields->f_simm16;
976      break;
977    case OR1K_OPERAND_SIMM16_SPLIT :
978      value = fields->f_simm16_split;
979      break;
980    case OR1K_OPERAND_UIMM16 :
981      value = fields->f_uimm16;
982      break;
983    case OR1K_OPERAND_UIMM16_SPLIT :
984      value = fields->f_uimm16_split;
985      break;
986    case OR1K_OPERAND_UIMM6 :
987      value = fields->f_uimm6;
988      break;
989
990    default :
991      /* xgettext:c-format */
992      opcodes_error_handler
993	(_("internal error: unrecognized field %d while getting int operand"),
994	 opindex);
995      abort ();
996  }
997
998  return value;
999}
1000
1001bfd_vma
1002or1k_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1003			     int opindex,
1004			     const CGEN_FIELDS * fields)
1005{
1006  bfd_vma value;
1007
1008  switch (opindex)
1009    {
1010    case OR1K_OPERAND_DISP21 :
1011      value = fields->f_disp21;
1012      break;
1013    case OR1K_OPERAND_DISP26 :
1014      value = fields->f_disp26;
1015      break;
1016    case OR1K_OPERAND_RA :
1017      value = fields->f_r2;
1018      break;
1019    case OR1K_OPERAND_RAD32F :
1020      value = fields->f_rad32;
1021      break;
1022    case OR1K_OPERAND_RADI :
1023      value = fields->f_rad32;
1024      break;
1025    case OR1K_OPERAND_RASF :
1026      value = fields->f_r2;
1027      break;
1028    case OR1K_OPERAND_RB :
1029      value = fields->f_r3;
1030      break;
1031    case OR1K_OPERAND_RBD32F :
1032      value = fields->f_rbd32;
1033      break;
1034    case OR1K_OPERAND_RBDI :
1035      value = fields->f_rbd32;
1036      break;
1037    case OR1K_OPERAND_RBSF :
1038      value = fields->f_r3;
1039      break;
1040    case OR1K_OPERAND_RD :
1041      value = fields->f_r1;
1042      break;
1043    case OR1K_OPERAND_RDD32F :
1044      value = fields->f_rdd32;
1045      break;
1046    case OR1K_OPERAND_RDDI :
1047      value = fields->f_rdd32;
1048      break;
1049    case OR1K_OPERAND_RDSF :
1050      value = fields->f_r1;
1051      break;
1052    case OR1K_OPERAND_SIMM16 :
1053      value = fields->f_simm16;
1054      break;
1055    case OR1K_OPERAND_SIMM16_SPLIT :
1056      value = fields->f_simm16_split;
1057      break;
1058    case OR1K_OPERAND_UIMM16 :
1059      value = fields->f_uimm16;
1060      break;
1061    case OR1K_OPERAND_UIMM16_SPLIT :
1062      value = fields->f_uimm16_split;
1063      break;
1064    case OR1K_OPERAND_UIMM6 :
1065      value = fields->f_uimm6;
1066      break;
1067
1068    default :
1069      /* xgettext:c-format */
1070      opcodes_error_handler
1071	(_("internal error: unrecognized field %d while getting vma operand"),
1072	 opindex);
1073      abort ();
1074  }
1075
1076  return value;
1077}
1078
1079void or1k_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1080void or1k_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1081
1082/* Stuffing values in cgen_fields is handled by a collection of functions.
1083   They are distinguished by the type of the VALUE argument they accept.
1084   TODO: floating point, inlining support, remove cases where argument type
1085   not appropriate.  */
1086
1087void
1088or1k_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1089			     int opindex,
1090			     CGEN_FIELDS * fields,
1091			     int value)
1092{
1093  switch (opindex)
1094    {
1095    case OR1K_OPERAND_DISP21 :
1096      fields->f_disp21 = value;
1097      break;
1098    case OR1K_OPERAND_DISP26 :
1099      fields->f_disp26 = value;
1100      break;
1101    case OR1K_OPERAND_RA :
1102      fields->f_r2 = value;
1103      break;
1104    case OR1K_OPERAND_RAD32F :
1105      fields->f_rad32 = value;
1106      break;
1107    case OR1K_OPERAND_RADI :
1108      fields->f_rad32 = value;
1109      break;
1110    case OR1K_OPERAND_RASF :
1111      fields->f_r2 = value;
1112      break;
1113    case OR1K_OPERAND_RB :
1114      fields->f_r3 = value;
1115      break;
1116    case OR1K_OPERAND_RBD32F :
1117      fields->f_rbd32 = value;
1118      break;
1119    case OR1K_OPERAND_RBDI :
1120      fields->f_rbd32 = value;
1121      break;
1122    case OR1K_OPERAND_RBSF :
1123      fields->f_r3 = value;
1124      break;
1125    case OR1K_OPERAND_RD :
1126      fields->f_r1 = value;
1127      break;
1128    case OR1K_OPERAND_RDD32F :
1129      fields->f_rdd32 = value;
1130      break;
1131    case OR1K_OPERAND_RDDI :
1132      fields->f_rdd32 = value;
1133      break;
1134    case OR1K_OPERAND_RDSF :
1135      fields->f_r1 = value;
1136      break;
1137    case OR1K_OPERAND_SIMM16 :
1138      fields->f_simm16 = value;
1139      break;
1140    case OR1K_OPERAND_SIMM16_SPLIT :
1141      fields->f_simm16_split = value;
1142      break;
1143    case OR1K_OPERAND_UIMM16 :
1144      fields->f_uimm16 = value;
1145      break;
1146    case OR1K_OPERAND_UIMM16_SPLIT :
1147      fields->f_uimm16_split = value;
1148      break;
1149    case OR1K_OPERAND_UIMM6 :
1150      fields->f_uimm6 = value;
1151      break;
1152
1153    default :
1154      /* xgettext:c-format */
1155      opcodes_error_handler
1156	(_("internal error: unrecognized field %d while setting int operand"),
1157	 opindex);
1158      abort ();
1159  }
1160}
1161
1162void
1163or1k_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1164			     int opindex,
1165			     CGEN_FIELDS * fields,
1166			     bfd_vma value)
1167{
1168  switch (opindex)
1169    {
1170    case OR1K_OPERAND_DISP21 :
1171      fields->f_disp21 = value;
1172      break;
1173    case OR1K_OPERAND_DISP26 :
1174      fields->f_disp26 = value;
1175      break;
1176    case OR1K_OPERAND_RA :
1177      fields->f_r2 = value;
1178      break;
1179    case OR1K_OPERAND_RAD32F :
1180      fields->f_rad32 = value;
1181      break;
1182    case OR1K_OPERAND_RADI :
1183      fields->f_rad32 = value;
1184      break;
1185    case OR1K_OPERAND_RASF :
1186      fields->f_r2 = value;
1187      break;
1188    case OR1K_OPERAND_RB :
1189      fields->f_r3 = value;
1190      break;
1191    case OR1K_OPERAND_RBD32F :
1192      fields->f_rbd32 = value;
1193      break;
1194    case OR1K_OPERAND_RBDI :
1195      fields->f_rbd32 = value;
1196      break;
1197    case OR1K_OPERAND_RBSF :
1198      fields->f_r3 = value;
1199      break;
1200    case OR1K_OPERAND_RD :
1201      fields->f_r1 = value;
1202      break;
1203    case OR1K_OPERAND_RDD32F :
1204      fields->f_rdd32 = value;
1205      break;
1206    case OR1K_OPERAND_RDDI :
1207      fields->f_rdd32 = value;
1208      break;
1209    case OR1K_OPERAND_RDSF :
1210      fields->f_r1 = value;
1211      break;
1212    case OR1K_OPERAND_SIMM16 :
1213      fields->f_simm16 = value;
1214      break;
1215    case OR1K_OPERAND_SIMM16_SPLIT :
1216      fields->f_simm16_split = value;
1217      break;
1218    case OR1K_OPERAND_UIMM16 :
1219      fields->f_uimm16 = value;
1220      break;
1221    case OR1K_OPERAND_UIMM16_SPLIT :
1222      fields->f_uimm16_split = value;
1223      break;
1224    case OR1K_OPERAND_UIMM6 :
1225      fields->f_uimm6 = value;
1226      break;
1227
1228    default :
1229      /* xgettext:c-format */
1230      opcodes_error_handler
1231	(_("internal error: unrecognized field %d while setting vma operand"),
1232	 opindex);
1233      abort ();
1234  }
1235}
1236
1237/* Function to call before using the instruction builder tables.  */
1238
1239void
1240or1k_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1241{
1242  cd->insert_handlers = & or1k_cgen_insert_handlers[0];
1243  cd->extract_handlers = & or1k_cgen_extract_handlers[0];
1244
1245  cd->insert_operand = or1k_cgen_insert_operand;
1246  cd->extract_operand = or1k_cgen_extract_operand;
1247
1248  cd->get_int_operand = or1k_cgen_get_int_operand;
1249  cd->set_int_operand = or1k_cgen_set_int_operand;
1250  cd->get_vma_operand = or1k_cgen_get_vma_operand;
1251  cd->set_vma_operand = or1k_cgen_set_vma_operand;
1252}
1253