* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.
[platform/upstream/binutils.git] / opcodes / m32r-dis.c
1 /* Disassembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3
4 THIS FILE IS USED TO GENERATE m32r-dis.c.
5
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 #include "sysdep.h"
25 #include <stdio.h>
26 #include "ansidecl.h"
27 #include "dis-asm.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "m32r-opc.h"
31 #include "opintl.h"
32
33 #undef INLINE
34 #ifdef __GNUC__
35 #define INLINE __inline__
36 #else
37 #define INLINE
38 #endif
39
40 /* Default text to print if an instruction isn't recognized.  */
41 #define UNKNOWN_INSN_MSG _("*unknown*")
42
43 /* Used by the ifield rtx function.  */
44 #define FLD(f) (fields->f)
45
46 static int extract_normal
47      PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
48               unsigned int, unsigned int, unsigned int, unsigned int,
49               unsigned int, unsigned int, bfd_vma, long *));
50 static void print_normal
51      PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
52 static void print_address
53      PARAMS ((CGEN_OPCODE_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
54 static void print_keyword
55      PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
56 static int extract_insn_normal
57      PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
58               CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
59 static void print_insn_normal
60      PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
61               bfd_vma, int));
62 static int print_insn PARAMS ((CGEN_OPCODE_DESC, bfd_vma,
63                                disassemble_info *, char *, int));
64 static int default_print_insn
65      PARAMS ((CGEN_OPCODE_DESC, bfd_vma, disassemble_info *));
66 \f
67 /* -- disassembler routines inserted here */
68 /* -- dis.c */
69
70 /* Immediate values are prefixed with '#'.  */
71
72 #define CGEN_PRINT_NORMAL(od, info, value, attrs, pc, length) \
73 do { \
74   if ((attrs) & (1 << CGEN_OPERAND_HASH_PREFIX)) \
75     (*info->fprintf_func) (info->stream, "#"); \
76 } while (0)
77
78 /* Handle '#' prefixes as operands.  */
79
80 static void
81 print_hash (od, dis_info, value, attrs, pc, length)
82      CGEN_OPCODE_DESC od;
83      PTR dis_info;
84      long value;
85      unsigned int attrs;
86      bfd_vma pc;
87      int length;
88 {
89   disassemble_info *info = dis_info;
90   (*info->fprintf_func) (info->stream, "#");
91 }
92
93 #undef CGEN_PRINT_INSN
94 #define CGEN_PRINT_INSN my_print_insn
95
96 static int
97 my_print_insn (od, pc, info)
98      CGEN_OPCODE_DESC od;
99      bfd_vma pc;
100      disassemble_info *info;
101 {
102   char buffer[CGEN_MAX_INSN_SIZE];
103   char *buf = buffer;
104   int status;
105   int buflen = (pc & 3) == 0 ? 4 : 2;
106
107   /* Read the base part of the insn.  */
108
109   status = (*info->read_memory_func) (pc, buf, buflen, info);
110   if (status != 0)
111     {
112       (*info->memory_error_func) (status, pc, info);
113       return -1;
114     }
115
116   /* 32 bit insn?  */
117   if ((pc & 3) == 0 && (buf[0] & 0x80) != 0)
118     return print_insn (od, pc, info, buf, buflen);
119
120   /* Print the first insn.  */
121   if ((pc & 3) == 0)
122     {
123       if (print_insn (od, pc, info, buf, 2) == 0)
124         (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
125       buf += 2;
126     }
127
128   if (buf[0] & 0x80)
129     {
130       /* Parallel.  */
131       (*info->fprintf_func) (info->stream, " || ");
132       buf[0] &= 0x7f;
133     }
134   else
135     (*info->fprintf_func) (info->stream, " -> ");
136
137   /* The "& 3" is to pass a consistent address.
138      Parallel insns arguably both begin on the word boundary.
139      Also, branch insns are calculated relative to the word boundary.  */
140   if (print_insn (od, pc & ~ (bfd_vma) 3, info, buf, 2) == 0)
141     (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
142
143   return (pc & 3) ? 2 : 4;
144 }
145
146 /* -- */
147
148 /* Main entry point for operand extraction.
149
150    This function is basically just a big switch statement.  Earlier versions
151    used tables to look up the function to use, but
152    - if the table contains both assembler and disassembler functions then
153      the disassembler contains much of the assembler and vice-versa,
154    - there's a lot of inlining possibilities as things grow,
155    - using a switch statement avoids the function call overhead.
156
157    This function could be moved into `print_insn_normal', but keeping it
158    separate makes clear the interface between `print_insn_normal' and each of
159    the handlers.
160 */
161
162 int
163 m32r_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
164      CGEN_OPCODE_DESC od;
165      int opindex;
166      CGEN_EXTRACT_INFO *ex_info;
167      CGEN_INSN_INT insn_value;
168      CGEN_FIELDS * fields;
169      bfd_vma pc;
170 {
171   int length;
172   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
173
174   switch (opindex)
175     {
176     case M32R_OPERAND_SR :
177       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
178       break;
179     case M32R_OPERAND_DR :
180       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
181       break;
182     case M32R_OPERAND_SRC1 :
183       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
184       break;
185     case M32R_OPERAND_SRC2 :
186       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
187       break;
188     case M32R_OPERAND_SCR :
189       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
190       break;
191     case M32R_OPERAND_DCR :
192       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
193       break;
194     case M32R_OPERAND_SIMM8 :
195       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
196       break;
197     case M32R_OPERAND_SIMM16 :
198       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
199       break;
200     case M32R_OPERAND_UIMM4 :
201       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
202       break;
203     case M32R_OPERAND_UIMM5 :
204       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
205       break;
206     case M32R_OPERAND_UIMM16 :
207       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
208       break;
209 /* start-sanitize-m32rx */
210     case M32R_OPERAND_IMM1 :
211       {
212         long value;
213         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 15, 1, 32, total_length, pc, & value);
214         value = ((value) + (1));
215         fields->f_imm1 = value;
216       }
217       break;
218 /* end-sanitize-m32rx */
219 /* start-sanitize-m32rx */
220     case M32R_OPERAND_ACCD :
221       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 2, 32, total_length, pc, & fields->f_accd);
222       break;
223 /* end-sanitize-m32rx */
224 /* start-sanitize-m32rx */
225     case M32R_OPERAND_ACCS :
226       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 2, 32, total_length, pc, & fields->f_accs);
227       break;
228 /* end-sanitize-m32rx */
229 /* start-sanitize-m32rx */
230     case M32R_OPERAND_ACC :
231       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 1, 32, total_length, pc, & fields->f_acc);
232       break;
233 /* end-sanitize-m32rx */
234     case M32R_OPERAND_HASH :
235       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
236       break;
237     case M32R_OPERAND_HI16 :
238       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
239       break;
240     case M32R_OPERAND_SLO16 :
241       length = extract_normal (od, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
242       break;
243     case M32R_OPERAND_ULO16 :
244       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
245       break;
246     case M32R_OPERAND_UIMM24 :
247       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24);
248       break;
249     case M32R_OPERAND_DISP8 :
250       {
251         long value;
252         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
253         value = ((((value) << (2))) + (((pc) & (-4))));
254         fields->f_disp8 = value;
255       }
256       break;
257     case M32R_OPERAND_DISP16 :
258       {
259         long value;
260         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value);
261         value = ((((value) << (2))) + (pc));
262         fields->f_disp16 = value;
263       }
264       break;
265     case M32R_OPERAND_DISP24 :
266       {
267         long value;
268         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value);
269         value = ((((value) << (2))) + (pc));
270         fields->f_disp24 = value;
271       }
272       break;
273
274     default :
275       /* xgettext:c-format */
276       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
277                opindex);
278       abort ();
279     }
280
281   return length;
282 }
283
284 /* Main entry point for printing operands.
285
286    This function is basically just a big switch statement.  Earlier versions
287    used tables to look up the function to use, but
288    - if the table contains both assembler and disassembler functions then
289      the disassembler contains much of the assembler and vice-versa,
290    - there's a lot of inlining possibilities as things grow,
291    - using a switch statement avoids the function call overhead.
292
293    This function could be moved into `print_insn_normal', but keeping it
294    separate makes clear the interface between `print_insn_normal' and each of
295    the handlers.
296 */
297
298 void
299 m32r_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
300      CGEN_OPCODE_DESC od;
301      int opindex;
302      disassemble_info * info;
303      CGEN_FIELDS * fields;
304      void const * attrs;
305      bfd_vma pc;
306      int length;
307 {
308   switch (opindex)
309     {
310     case M32R_OPERAND_SR :
311       print_keyword (od, info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
312       break;
313     case M32R_OPERAND_DR :
314       print_keyword (od, info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
315       break;
316     case M32R_OPERAND_SRC1 :
317       print_keyword (od, info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
318       break;
319     case M32R_OPERAND_SRC2 :
320       print_keyword (od, info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
321       break;
322     case M32R_OPERAND_SCR :
323       print_keyword (od, info, & m32r_cgen_opval_h_cr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
324       break;
325     case M32R_OPERAND_DCR :
326       print_keyword (od, info, & m32r_cgen_opval_h_cr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
327       break;
328     case M32R_OPERAND_SIMM8 :
329       print_normal (od, info, fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
330       break;
331     case M32R_OPERAND_SIMM16 :
332       print_normal (od, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
333       break;
334     case M32R_OPERAND_UIMM4 :
335       print_normal (od, info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
336       break;
337     case M32R_OPERAND_UIMM5 :
338       print_normal (od, info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
339       break;
340     case M32R_OPERAND_UIMM16 :
341       print_normal (od, info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
342       break;
343 /* start-sanitize-m32rx */
344     case M32R_OPERAND_IMM1 :
345       print_normal (od, info, fields->f_imm1, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
346       break;
347 /* end-sanitize-m32rx */
348 /* start-sanitize-m32rx */
349     case M32R_OPERAND_ACCD :
350       print_keyword (od, info, & m32r_cgen_opval_h_accums, fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED));
351       break;
352 /* end-sanitize-m32rx */
353 /* start-sanitize-m32rx */
354     case M32R_OPERAND_ACCS :
355       print_keyword (od, info, & m32r_cgen_opval_h_accums, fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED));
356       break;
357 /* end-sanitize-m32rx */
358 /* start-sanitize-m32rx */
359     case M32R_OPERAND_ACC :
360       print_keyword (od, info, & m32r_cgen_opval_h_accums, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED));
361       break;
362 /* end-sanitize-m32rx */
363     case M32R_OPERAND_HASH :
364       print_hash (od, info, fields->f_nil, 0, pc, length);
365       break;
366     case M32R_OPERAND_HI16 :
367       print_normal (od, info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
368       break;
369     case M32R_OPERAND_SLO16 :
370       print_normal (od, info, fields->f_simm16, 0, pc, length);
371       break;
372     case M32R_OPERAND_ULO16 :
373       print_normal (od, info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
374       break;
375     case M32R_OPERAND_UIMM24 :
376       print_address (od, info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
377       break;
378     case M32R_OPERAND_DISP8 :
379       print_address (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
380       break;
381     case M32R_OPERAND_DISP16 :
382       print_address (od, info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
383       break;
384     case M32R_OPERAND_DISP24 :
385       print_address (od, info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
386       break;
387
388     default :
389       /* xgettext:c-format */
390       fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
391                opindex);
392     abort ();
393   }
394 }
395
396 cgen_extract_fn * const m32r_cgen_extract_handlers[] = 
397 {
398   0, /* default */
399   extract_insn_normal,
400 };
401
402 cgen_print_fn * const m32r_cgen_print_handlers[] = 
403 {
404   0, /* default */
405   print_insn_normal,
406 };
407
408
409 void
410 m32r_cgen_init_dis (od)
411      CGEN_OPCODE_DESC od;
412 {
413 }
414
415 \f
416 #if ! CGEN_INT_INSN_P
417
418 /* Subroutine of extract_normal.
419    Ensure sufficient bytes are cached in EX_INFO.
420    OFFSET is the offset in bytes from the start of the insn of the value.
421    BYTES is the length of the needed value.
422    Returns 1 for success, 0 for failure.  */
423
424 static INLINE int
425 fill_cache (od, ex_info, offset, bytes, pc)
426      CGEN_OPCODE_DESC od;
427      CGEN_EXTRACT_INFO *ex_info;
428      int offset, bytes;
429      bfd_vma pc;
430 {
431   /* It's doubtful that the middle part has already been fetched so
432      we don't optimize that case.  kiss.  */
433   int mask;
434   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
435
436   /* First do a quick check.  */
437   mask = (1 << bytes) - 1;
438   if (((ex_info->valid >> offset) & mask) == mask)
439     return 1;
440
441   /* Search for the first byte we need to read.  */
442   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
443     if (! (mask & ex_info->valid))
444       break;
445
446   if (bytes)
447     {
448       int status;
449
450       pc += offset;
451       status = (*info->read_memory_func)
452         (pc, ex_info->insn_bytes + offset, bytes, info);
453
454       if (status != 0)
455         {
456           (*info->memory_error_func) (status, pc, info);
457           return 0;
458         }
459
460       ex_info->valid |= ((1 << bytes) - 1) << offset;
461     }
462
463   return 1;
464 }
465
466 /* Subroutine of extract_normal.  */
467
468 static INLINE long
469 extract_1 (od, ex_info, start, length, word_length, bufp, pc)
470      CGEN_OPCODE_DESC od;
471      CGEN_EXTRACT_INFO *ex_info;
472      int start,length,word_length;
473      unsigned char *bufp;
474      bfd_vma pc;
475 {
476   unsigned long x,mask;
477   int shift;
478   int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
479
480   switch (word_length)
481     {
482     case 8:
483       x = *bufp;
484       break;
485     case 16:
486       if (big_p)
487         x = bfd_getb16 (bufp);
488       else
489         x = bfd_getl16 (bufp);
490       break;
491     case 24:
492       /* ??? This may need reworking as these cases don't necessarily
493          want the first byte and the last two bytes handled like this.  */
494       if (big_p)
495         x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
496       else
497         x = bfd_getl16 (bufp) | (bufp[2] << 16);
498       break;
499     case 32:
500       if (big_p)
501         x = bfd_getb32 (bufp);
502       else
503         x = bfd_getl32 (bufp);
504       break;
505     default :
506       abort ();
507     }
508
509   /* Written this way to avoid undefined behaviour.  */
510   mask = (((1L << (length - 1)) - 1) << 1) | 1;
511   if (CGEN_INSN_LSB0_P)
512     shift = (start + 1) - length;
513   else
514     shift = (word_length - (start + length));
515   return (x >> shift) & mask;
516 }
517
518 #endif /* ! CGEN_INT_INSN_P */
519
520 /* Default extraction routine.
521
522    INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
523    or sometimes less for cases like the m32r where the base insn size is 32
524    but some insns are 16 bits.
525    ATTRS is a mask of the boolean attributes.  We only need `UNSIGNED',
526    but for generality we take a bitmask of all of them.
527    WORD_OFFSET is the offset in bits from the start of the insn of the value.
528    WORD_LENGTH is the length of the word in bits in which the value resides.
529    START is the starting bit number in the word, architecture origin.
530    LENGTH is the length of VALUE in bits.
531    TOTAL_LENGTH is the total length of the insn in bits.
532
533    Returns 1 for success, 0 for failure.  */
534
535 /* ??? The return code isn't properly used.  wip.  */
536
537 /* ??? This doesn't handle bfd_vma's.  Create another function when
538    necessary.  */
539
540 static int
541 extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
542                 word_length, total_length, pc, valuep)
543      CGEN_OPCODE_DESC od;
544      CGEN_EXTRACT_INFO *ex_info;
545      CGEN_INSN_INT insn_value;
546      unsigned int attrs;
547      unsigned int word_offset, start, length, word_length, total_length;
548      bfd_vma pc;
549      long *valuep;
550 {
551   CGEN_INSN_INT value;
552
553   /* If LENGTH is zero, this operand doesn't contribute to the value
554      so give it a standard value of zero.  */
555   if (length == 0)
556     {
557       *valuep = 0;
558       return 1;
559     }
560
561   if (CGEN_INT_INSN_P
562       && word_offset != 0)
563     abort ();
564
565   if (word_length > 32)
566     abort ();
567
568   /* For architectures with insns smaller than the insn-base-bitsize,
569      word_length may be too big.  */
570 #if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
571   if (word_offset == 0
572       && word_length > total_length)
573     word_length = total_length;
574 #endif
575
576   /* Does the value reside in INSN_VALUE?  */
577
578   if (word_offset == 0)
579     {
580       /* Written this way to avoid undefined behaviour.  */
581       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
582
583       if (CGEN_INSN_LSB0_P)
584         value = insn_value >> ((start + 1) - length);
585       else
586         value = insn_value >> (word_length - (start + length));
587       value &= mask;
588       /* sign extend? */
589       if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
590           && (value & (1L << (length - 1))))
591         value |= ~mask;
592     }
593
594 #if ! CGEN_INT_INSN_P
595
596   else
597     {
598       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
599
600       if (word_length > 32)
601         abort ();
602
603       if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0)
604         return 0;
605
606       value = extract_1 (od, ex_info, start, length, word_length, bufp, pc);
607     }
608
609 #endif /* ! CGEN_INT_INSN_P */
610
611   *valuep = value;
612
613   return 1;
614 }
615
616 /* Default print handler.  */
617
618 static void
619 print_normal (od, dis_info, value, attrs, pc, length)
620      CGEN_OPCODE_DESC od;
621      PTR dis_info;
622      long value;
623      unsigned int attrs;
624      bfd_vma pc;
625      int length;
626 {
627   disassemble_info *info = (disassemble_info *) dis_info;
628
629 #ifdef CGEN_PRINT_NORMAL
630   CGEN_PRINT_NORMAL (od, info, value, attrs, pc, length);
631 #endif
632
633   /* Print the operand as directed by the attributes.  */
634   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
635     ; /* nothing to do */
636   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
637     (*info->fprintf_func) (info->stream, "0x%lx", value);
638   else
639     (*info->fprintf_func) (info->stream, "%ld", value);
640 }
641
642 /* Default address handler.  */
643
644 static void
645 print_address (od, dis_info, value, attrs, pc, length)
646      CGEN_OPCODE_DESC od;
647      PTR dis_info;
648      bfd_vma value;
649      unsigned int attrs;
650      bfd_vma pc;
651      int length;
652 {
653   disassemble_info *info = (disassemble_info *) dis_info;
654
655 #ifdef CGEN_PRINT_ADDRESS
656   CGEN_PRINT_ADDRESS (od, info, value, attrs, pc, length);
657 #endif
658
659   /* Print the operand as directed by the attributes.  */
660   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
661     ; /* nothing to do */
662   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
663     (*info->print_address_func) (value, info);
664   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
665     (*info->print_address_func) (value, info);
666   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
667     (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
668   else
669     (*info->fprintf_func) (info->stream, "%ld", (long) value);
670 }
671
672 /* Keyword print handler.  */
673
674 static void
675 print_keyword (od, dis_info, keyword_table, value, attrs)
676      CGEN_OPCODE_DESC od;
677      PTR dis_info;
678      CGEN_KEYWORD *keyword_table;
679      long value;
680      unsigned int attrs;
681 {
682   disassemble_info *info = (disassemble_info *) dis_info;
683   const CGEN_KEYWORD_ENTRY *ke;
684
685   ke = cgen_keyword_lookup_value (keyword_table, value);
686   if (ke != NULL)
687     (*info->fprintf_func) (info->stream, "%s", ke->name);
688   else
689     (*info->fprintf_func) (info->stream, "???");
690 }
691 \f
692 /* Default insn extractor.
693
694    INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
695    The extracted fields are stored in FIELDS.
696    EX_INFO is used to handle reading variable length insns.
697    Return the length of the insn in bits, or 0 if no match,
698    or -1 if an error occurs fetching data (memory_error_func will have
699    been called).  */
700
701 static int
702 extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
703      CGEN_OPCODE_DESC od;
704      const CGEN_INSN *insn;
705      CGEN_EXTRACT_INFO *ex_info;
706      CGEN_INSN_INT insn_value;
707      CGEN_FIELDS *fields;
708      bfd_vma pc;
709 {
710   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
711   const unsigned char *syn;
712
713   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
714
715   CGEN_INIT_EXTRACT (od);
716
717   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
718     {
719       int length;
720
721       if (CGEN_SYNTAX_CHAR_P (*syn))
722         continue;
723
724       length = m32r_cgen_extract_operand (od, CGEN_SYNTAX_FIELD (*syn),
725                                             ex_info, insn_value, fields, pc);
726       if (length <= 0)
727         return length;
728     }
729
730   /* We recognized and successfully extracted this insn.  */
731   return CGEN_INSN_BITSIZE (insn);
732 }
733
734 /* Default insn printer.
735
736    DIS_INFO is defined as `PTR' so the disassembler needn't know anything
737    about disassemble_info.  */
738
739 static void
740 print_insn_normal (od, dis_info, insn, fields, pc, length)
741      CGEN_OPCODE_DESC od;
742      PTR dis_info;
743      const CGEN_INSN *insn;
744      CGEN_FIELDS *fields;
745      bfd_vma pc;
746      int length;
747 {
748   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
749   disassemble_info *info = (disassemble_info *) dis_info;
750   const unsigned char *syn;
751
752   CGEN_INIT_PRINT (od);
753
754   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
755     {
756       if (CGEN_SYNTAX_MNEMONIC_P (*syn))
757         {
758           (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
759           continue;
760         }
761       if (CGEN_SYNTAX_CHAR_P (*syn))
762         {
763           (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
764           continue;
765         }
766
767       /* We have an operand.  */
768       m32r_cgen_print_operand (od, CGEN_SYNTAX_FIELD (*syn), info,
769                                  fields, CGEN_INSN_ATTRS (insn), pc, length);
770     }
771 }
772 \f
773 /* Utility to print an insn.
774    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
775    The result is the size of the insn in bytes or zero for an unknown insn
776    or -1 if an error occurs fetching data (memory_error_func will have
777    been called).  */
778
779 static int
780 print_insn (od, pc, info, buf, buflen)
781      CGEN_OPCODE_DESC od;
782      bfd_vma pc;
783      disassemble_info *info;
784      char *buf;
785      int buflen;
786 {
787   unsigned long insn_value;
788   const CGEN_INSN_LIST *insn_list;
789   CGEN_EXTRACT_INFO ex_info;
790
791   ex_info.dis_info = info;
792   ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
793   ex_info.insn_bytes = buf;
794
795   switch (buflen)
796     {
797     case 1:
798       insn_value = buf[0];
799       break;
800     case 2:
801       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
802       break;
803     case 4:
804       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
805       break;
806     default:
807       abort ();
808     }
809
810   /* The instructions are stored in hash lists.
811      Pick the first one and keep trying until we find the right one.  */
812
813   insn_list = CGEN_DIS_LOOKUP_INSN (od, buf, insn_value);
814   while (insn_list != NULL)
815     {
816       const CGEN_INSN *insn = insn_list->insn;
817       CGEN_FIELDS fields;
818       int length;
819
820 #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
821       /* Supported by this cpu?  */
822       if (! m32r_cgen_insn_supported (od, insn))
823         continue;
824 #endif
825
826       /* Basic bit mask must be correct.  */
827       /* ??? May wish to allow target to defer this check until the extract
828          handler.  */
829       if ((insn_value & CGEN_INSN_BASE_MASK (insn))
830           == CGEN_INSN_BASE_VALUE (insn))
831         {
832           /* Printing is handled in two passes.  The first pass parses the
833              machine insn and extracts the fields.  The second pass prints
834              them.  */
835
836           length = (*CGEN_EXTRACT_FN (insn)) (od, insn, &ex_info, insn_value,
837                                               &fields, pc);
838           /* length < 0 -> error */
839           if (length < 0)
840             return length;
841           if (length > 0)
842             {
843               (*CGEN_PRINT_FN (insn)) (od, info, insn, &fields, pc, length);
844               /* length is in bits, result is in bytes */
845               return length / 8;
846             }
847         }
848
849       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
850     }
851
852   return 0;
853 }
854
855 /* Default value for CGEN_PRINT_INSN.
856    The result is the size of the insn in bytes or zero for an unknown insn
857    or -1 if an error occured fetching bytes.  */
858
859 #ifndef CGEN_PRINT_INSN
860 #define CGEN_PRINT_INSN default_print_insn
861 #endif
862
863 static int
864 default_print_insn (od, pc, info)
865      CGEN_OPCODE_DESC od;
866      bfd_vma pc;
867      disassemble_info *info;
868 {
869   char buf[CGEN_MAX_INSN_SIZE];
870   int status;
871
872   /* Read the base part of the insn.  */
873
874   status = (*info->read_memory_func) (pc, buf, CGEN_BASE_INSN_SIZE, info);
875   if (status != 0)
876     {
877       (*info->memory_error_func) (status, pc, info);
878       return -1;
879     }
880
881   return print_insn (od, pc, info, buf, CGEN_BASE_INSN_SIZE);
882 }
883
884 /* Main entry point.
885    Print one instruction from PC on INFO->STREAM.
886    Return the size of the instruction (in bytes).  */
887
888 int
889 print_insn_m32r (pc, info)
890      bfd_vma pc;
891      disassemble_info *info;
892 {
893   int length;
894   static CGEN_OPCODE_DESC od = 0;
895   int mach = info->mach;
896   int big_p = info->endian == BFD_ENDIAN_BIG;
897
898   /* If we haven't initialized yet, initialize the opcode table.  */
899   if (! od)
900     {
901       od = m32r_cgen_opcode_open (mach,
902                                     big_p ?
903                                     CGEN_ENDIAN_BIG
904                                     : CGEN_ENDIAN_LITTLE);
905       m32r_cgen_init_dis (od);
906     }
907   /* If we've switched cpu's, re-initialize.  */
908   /* ??? Perhaps we should use BFD_ENDIAN.  */
909   else if (mach != CGEN_OPCODE_MACH (od)
910            || (CGEN_OPCODE_ENDIAN (od)
911                != (big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE)))
912     {
913       cgen_set_cpu (od, mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
914     }
915
916   /* We try to have as much common code as possible.
917      But at this point some targets need to take over.  */
918   /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
919      but if not possible try to move this hook elsewhere rather than
920      have two hooks.  */
921   length = CGEN_PRINT_INSN (od, pc, info);
922   if (length > 0)
923     return length;
924   if (length < 0)
925     return -1;
926
927   (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
928   return CGEN_DEFAULT_INSN_SIZE;
929 }