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