* dvp-opc.c (*): pke,gpuif renamed to vif,gif.
[deliverable/binutils-gdb.git] / opcodes / m32r-dis.c
CommitLineData
9c03036a
DE
1/* Disassembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4This file is used to generate m32r-dis.c.
5
6Copyright (C) 1996, 1997 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
23cf992f 24#include "sysdep.h"
9c03036a
DE
25#include <stdio.h>
26#include "ansidecl.h"
27#include "dis-asm.h"
9c03036a 28#include "bfd.h"
23cf992f 29#include "m32r-opc.h"
9c03036a
DE
30
31/* ??? The layout of this stuff is still work in progress.
32 For speed in assembly/disassembly, we use inline functions. That of course
33 will only work for GCC. When this stuff is finished, we can decide whether
34 to keep the inline functions (and only get the performance increase when
35 compiled with GCC), or switch to macros, or use something else.
36*/
37
38/* Default text to print if an instruction isn't recognized. */
39#define UNKNOWN_INSN_MSG "*unknown*"
40
41/* FIXME: Machine generate. */
42#ifndef CGEN_PCREL_OFFSET
43#define CGEN_PCREL_OFFSET 0
44#endif
45
46static int print_insn PARAMS ((bfd_vma, disassemble_info *, char *, int));
47
48static int extract_insn_normal
23cf992f 49 PARAMS ((const CGEN_INSN *, void *, cgen_insn_t, CGEN_FIELDS *));
9c03036a 50static void print_insn_normal
23cf992f 51 PARAMS ((void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int));
9c03036a
DE
52\f
53/* Default extraction routine.
54
55 ATTRS is a mask of the boolean attributes. We only need `unsigned',
56 but for generality we take a bitmask of all of them. */
57
58static int
59extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length, valuep)
853713a7
DE
60 void *buf_ctrl;
61 cgen_insn_t insn_value;
9c03036a 62 unsigned int attrs;
853713a7
DE
63 int start, length, shift, total_length;
64 long *valuep;
9c03036a
DE
65{
66 long value;
67
68#ifdef CGEN_INT_INSN
69#if 0
70 value = ((insn_value >> (CGEN_BASE_INSN_BITSIZE - (start + length)))
71 & ((1 << length) - 1));
72#else
73 value = ((insn_value >> (total_length - (start + length)))
74 & ((1 << length) - 1));
75#endif
76 if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
77 && (value & (1 << (length - 1))))
78 value -= 1 << length;
79#else
80 /* FIXME: unfinished */
81#endif
82
83 /* This is backwards as we undo the effects of insert_normal. */
84 if (shift < 0)
85 value >>= -shift;
86 else
87 value <<= shift;
88
853713a7 89 *valuep = value;
9c03036a
DE
90 return 1;
91}
92
93/* Default print handler. */
94
95static void
96print_normal (dis_info, value, attrs, pc, length)
853713a7
DE
97 void *dis_info;
98 long value;
99 unsigned int attrs;
9c03036a 100 unsigned long pc; /* FIXME: should be bfd_vma */
853713a7 101 int length;
9c03036a 102{
853713a7 103 disassemble_info *info = dis_info;
9c03036a
DE
104
105 /* Print the operand as directed by the attributes. */
106 if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_FAKE))
107 ; /* nothing to do (??? at least not yet) */
108 else if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_PCREL_ADDR))
109 (*info->print_address_func) (pc + CGEN_PCREL_OFFSET + value, info);
110 /* ??? Not all cases of this are currently caught. */
111 else if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_ABS_ADDR))
112 /* FIXME: Why & 0xffffffff? */
113 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
114 else if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
115 (*info->fprintf_func) (info->stream, "0x%lx", value);
116 else
117 (*info->fprintf_func) (info->stream, "%ld", value);
118}
119
120/* Keyword print handler. */
121
122static void
123print_keyword (dis_info, keyword_table, value, attrs)
853713a7
DE
124 void *dis_info;
125 CGEN_KEYWORD *keyword_table;
126 long value;
127 CGEN_ATTR *attrs;
9c03036a 128{
853713a7
DE
129 disassemble_info *info = dis_info;
130 const CGEN_KEYWORD_ENTRY *ke;
9c03036a
DE
131
132 ke = cgen_keyword_lookup_value (keyword_table, value);
853713a7
DE
133 if (ke != NULL)
134 (*info->fprintf_func) (info->stream, "%s", ke->name);
135 else
136 (*info->fprintf_func) (info->stream, "???");
9c03036a
DE
137}
138\f
139/* -- disassembler routines inserted here */
853713a7
DE
140/* -- dis.c */
141
142#undef CGEN_PRINT_INSN
143#define CGEN_PRINT_INSN my_print_insn
144
145static int
146my_print_insn (pc, info, buf, buflen)
147 bfd_vma pc;
148 disassemble_info *info;
149 char *buf;
150 int buflen;
151{
152 /* 32 bit insn? */
153 if ((pc & 3) == 0 && (buf[0] & 0x80) != 0)
154 return print_insn (pc, info, buf, buflen);
155
156 /* Print the first insn. */
157 if ((pc & 3) == 0)
158 {
159 if (print_insn (pc, info, buf, 16) == 0)
160 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
161 buf += 2;
162 }
163
164 if (buf[0] & 0x80)
165 {
166 /* Parallel. */
167 (*info->fprintf_func) (info->stream, " || ");
168 buf[0] &= 0x7f;
169 }
170 else
171 (*info->fprintf_func) (info->stream, " -> ");
172
173 /* The "& 3" is to ensure the branch address is computed correctly
174 [if it is a branch]. */
175 if (print_insn (pc & ~ (bfd_vma) 3, info, buf, 16) == 0)
176 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
177
178 return (pc & 3) ? 2 : 4;
179}
180
181/* -- */
182
183/* Main entry point for operand extraction.
184
185 This function is basically just a big switch statement. Earlier versions
186 used tables to look up the function to use, but
187 - if the table contains both assembler and disassembler functions then
188 the disassembler contains much of the assembler and vice-versa,
189 - there's a lot of inlining possibilities as things grow,
190 - using a switch statement avoids the function call overhead.
191
192 This function could be moved into `print_insn_normal', but keeping it
193 separate makes clear the interface between `print_insn_normal' and each of
194 the handlers.
195*/
196
197CGEN_INLINE int
198m32r_cgen_extract_operand (opindex, buf_ctrl, insn_value, fields)
5d07b6cf
DE
199 int opindex;
200 void * buf_ctrl;
201 cgen_insn_t insn_value;
853713a7
DE
202 CGEN_FIELDS * fields;
203{
204 int length;
205
206 switch (opindex)
207 {
208 case M32R_OPERAND_SR :
209 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
210 break;
211 case M32R_OPERAND_DR :
212 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
213 break;
214 case M32R_OPERAND_SRC1 :
215 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
216 break;
217 case M32R_OPERAND_SRC2 :
218 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
219 break;
220 case M32R_OPERAND_SCR :
221 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
222 break;
223 case M32R_OPERAND_DCR :
224 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
225 break;
226 case M32R_OPERAND_SIMM8 :
227 length = extract_normal (NULL /*FIXME*/, insn_value, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm8);
228 break;
229 case M32R_OPERAND_SIMM16 :
230 length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm16);
231 break;
232 case M32R_OPERAND_UIMM4 :
233 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm4);
234 break;
235 case M32R_OPERAND_UIMM5 :
236 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm5);
237 break;
238 case M32R_OPERAND_UIMM16 :
239 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm16);
240 break;
241 case M32R_OPERAND_HI16 :
242 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_hi16);
243 break;
244 case M32R_OPERAND_SLO16 :
245 length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm16);
246 break;
247 case M32R_OPERAND_ULO16 :
248 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm16);
249 break;
250 case M32R_OPERAND_UIMM24 :
251 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm24);
252 break;
253 case M32R_OPERAND_DISP8 :
254 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, 2, CGEN_FIELDS_BITSIZE (fields), & fields->f_disp8);
255 break;
256 case M32R_OPERAND_DISP16 :
257 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, 2, CGEN_FIELDS_BITSIZE (fields), & fields->f_disp16);
258 break;
259 case M32R_OPERAND_DISP24 :
260 length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, 2, CGEN_FIELDS_BITSIZE (fields), & fields->f_disp24);
261 break;
262
263 default :
264 fprintf (stderr, "Unrecognized field %d while decoding insn.\n",
265 opindex);
266 abort ();
267 }
268
269 return length;
270}
271
272/* Main entry point for printing operands.
273
274 This function is basically just a big switch statement. Earlier versions
275 used tables to look up the function to use, but
276 - if the table contains both assembler and disassembler functions then
277 the disassembler contains much of the assembler and vice-versa,
278 - there's a lot of inlining possibilities as things grow,
279 - using a switch statement avoids the function call overhead.
280
281 This function could be moved into `print_insn_normal', but keeping it
282 separate makes clear the interface between `print_insn_normal' and each of
283 the handlers.
284*/
285
286CGEN_INLINE void
287m32r_cgen_print_operand (opindex, info, fields, attrs, pc, length)
5d07b6cf 288 int opindex;
853713a7 289 disassemble_info * info;
5d07b6cf
DE
290 CGEN_FIELDS * fields;
291 void const * attrs;
292 bfd_vma pc;
293 int length;
853713a7
DE
294{
295 switch (opindex)
296 {
297 case M32R_OPERAND_SR :
298 print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
299 break;
300 case M32R_OPERAND_DR :
301 print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
302 break;
303 case M32R_OPERAND_SRC1 :
304 print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
305 break;
306 case M32R_OPERAND_SRC2 :
307 print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
308 break;
309 case M32R_OPERAND_SCR :
310 print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
311 break;
312 case M32R_OPERAND_DCR :
313 print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
314 break;
315 case M32R_OPERAND_SIMM8 :
316 print_normal (info, fields->f_simm8, 0, pc, length);
317 break;
318 case M32R_OPERAND_SIMM16 :
319 print_normal (info, fields->f_simm16, 0, pc, length);
320 break;
321 case M32R_OPERAND_UIMM4 :
322 print_normal (info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
323 break;
324 case M32R_OPERAND_UIMM5 :
325 print_normal (info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
326 break;
327 case M32R_OPERAND_UIMM16 :
328 print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
329 break;
330 case M32R_OPERAND_HI16 :
331 print_normal (info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
332 break;
333 case M32R_OPERAND_SLO16 :
334 print_normal (info, fields->f_simm16, 0, pc, length);
335 break;
336 case M32R_OPERAND_ULO16 :
337 print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
338 break;
339 case M32R_OPERAND_UIMM24 :
340 print_normal (info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
341 break;
342 case M32R_OPERAND_DISP8 :
343 print_normal (info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
344 break;
345 case M32R_OPERAND_DISP16 :
346 print_normal (info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
347 break;
348 case M32R_OPERAND_DISP24 :
349 print_normal (info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
350 break;
351
352 default :
353 fprintf (stderr, "Unrecognized field %d while printing insn.\n",
354 opindex);
355 abort ();
356 }
357}
358
359cgen_extract_fn * m32r_cgen_extract_handlers[] =
5d07b6cf
DE
360{
361 0, /* default */
853713a7
DE
362 extract_insn_normal,
363};
364
365cgen_print_fn * m32r_cgen_print_handlers[] =
5d07b6cf
DE
366{
367 0, /* default */
853713a7
DE
368 print_insn_normal,
369};
370
371
372void
373m32r_cgen_init_dis (mach, endian)
374 int mach;
375 enum cgen_endian endian;
376{
377 m32r_cgen_init_tables (mach);
378 cgen_set_cpu (& m32r_cgen_opcode_data, mach, endian);
379 cgen_dis_init ();
380}
381
9c03036a
DE
382\f
383/* Default insn extractor.
384
385 The extracted fields are stored in DIS_FLDS.
386 BUF_CTRL is used to handle reading variable length insns (FIXME: not done).
387 Return the length of the insn in bits, or 0 if no match. */
388
389static int
390extract_insn_normal (insn, buf_ctrl, insn_value, fields)
853713a7
DE
391 const CGEN_INSN *insn;
392 void *buf_ctrl;
393 cgen_insn_t insn_value;
394 CGEN_FIELDS *fields;
9c03036a 395{
853713a7
DE
396 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
397 const unsigned char *syn;
9c03036a 398
9c03036a
DE
399 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
400
401 CGEN_INIT_EXTRACT ();
402
853713a7 403 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
9c03036a
DE
404 {
405 int length;
406
853713a7 407 if (CGEN_SYNTAX_CHAR_P (*syn))
9c03036a
DE
408 continue;
409
853713a7 410 length = m32r_cgen_extract_operand (CGEN_SYNTAX_FIELD (*syn),
9c03036a
DE
411 buf_ctrl, insn_value, fields);
412 if (length == 0)
413 return 0;
414 }
415
23cf992f
NC
416 /* We recognized and successfully extracted this insn. */
417 return CGEN_INSN_BITSIZE (insn);
9c03036a
DE
418}
419
420/* Default insn printer.
421
422 DIS_INFO is defined as `void *' so the disassembler needn't know anything
423 about disassemble_info.
424*/
425
426static void
427print_insn_normal (dis_info, insn, fields, pc, length)
853713a7
DE
428 void *dis_info;
429 const CGEN_INSN *insn;
430 CGEN_FIELDS *fields;
431 bfd_vma pc;
432 int length;
9c03036a 433{
853713a7
DE
434 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
435 disassemble_info *info = dis_info;
436 const unsigned char *syn;
9c03036a
DE
437
438 CGEN_INIT_PRINT ();
439
853713a7 440 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
9c03036a 441 {
853713a7 442 if (CGEN_SYNTAX_MNEMONIC_P (*syn))
23cf992f 443 {
853713a7 444 (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
23cf992f
NC
445 continue;
446 }
853713a7 447 if (CGEN_SYNTAX_CHAR_P (*syn))
9c03036a 448 {
853713a7 449 (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
9c03036a
DE
450 continue;
451 }
452
453 /* We have an operand. */
853713a7 454 m32r_cgen_print_operand (CGEN_SYNTAX_FIELD (*syn), info,
9c03036a
DE
455 fields, CGEN_INSN_ATTRS (insn), pc, length);
456 }
457}
458\f
459/* Default value for CGEN_PRINT_INSN.
5d07b6cf 460 Given BUFLEN bits (target byte order) read into BUF, look up the
9c03036a
DE
461 insn in the instruction table and disassemble it.
462
463 The result is the size of the insn in bytes. */
464
465#ifndef CGEN_PRINT_INSN
466#define CGEN_PRINT_INSN print_insn
467#endif
468
469static int
470print_insn (pc, info, buf, buflen)
853713a7
DE
471 bfd_vma pc;
472 disassemble_info *info;
473 char *buf;
474 int buflen;
9c03036a 475{
853713a7
DE
476 int i;
477 unsigned long insn_value;
478 const CGEN_INSN_LIST *insn_list;
479
9c03036a
DE
480 switch (buflen)
481 {
482 case 8:
483 insn_value = buf[0];
484 break;
485 case 16:
486 insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
487 break;
488 case 32:
489 insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
490 break;
491 default:
492 abort ();
493 }
494
495 /* The instructions are stored in hash lists.
496 Pick the first one and keep trying until we find the right one. */
497
498 insn_list = CGEN_DIS_LOOKUP_INSN (buf, insn_value);
499 while (insn_list != NULL)
500 {
853713a7
DE
501 const CGEN_INSN *insn = insn_list->insn;
502 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
503 CGEN_FIELDS fields;
504 int length;
9c03036a
DE
505
506#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
507 /* Supported by this cpu? */
508 if (! m32r_cgen_insn_supported (insn))
509 continue;
510#endif
511
512 /* Basic bit mask must be correct. */
513 /* ??? May wish to allow target to defer this check until the extract
514 handler. */
853713a7 515 if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
9c03036a
DE
516 {
517 /* Printing is handled in two passes. The first pass parses the
518 machine insn and extracts the fields. The second pass prints
519 them. */
520
853713a7 521 length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
9c03036a
DE
522 if (length > 0)
523 {
853713a7 524 (*CGEN_PRINT_FN (insn)) (info, insn, &fields, pc, length);
9c03036a 525 /* length is in bits, result is in bytes */
853713a7 526 return length / 8;
9c03036a
DE
527 }
528 }
853713a7 529
9c03036a
DE
530 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
531 }
532
853713a7 533 return 0;
9c03036a
DE
534}
535
536/* Main entry point.
537 Print one instruction from PC on INFO->STREAM.
538 Return the size of the instruction (in bytes). */
539
540int
541print_insn_m32r (pc, info)
853713a7
DE
542 bfd_vma pc;
543 disassemble_info *info;
9c03036a 544{
853713a7
DE
545 char buffer[CGEN_MAX_INSN_SIZE];
546 int status, length;
547 static int initialized = 0;
548 static int current_mach = 0;
549 static int current_big_p = 0;
550 int mach = info->mach;
551 int big_p = info->endian == BFD_ENDIAN_BIG;
9c03036a
DE
552
553 /* If we haven't initialized yet, or if we've switched cpu's, initialize. */
853713a7 554 if (!initialized || mach != current_mach || big_p != current_big_p)
9c03036a 555 {
853713a7
DE
556 initialized = 1;
557 current_mach = mach;
558 current_big_p = big_p;
559 m32r_cgen_init_dis (mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
9c03036a
DE
560 }
561
562 /* Read enough of the insn so we can look it up in the hash lists. */
563
853713a7 564 status = (*info->read_memory_func) (pc, buffer, CGEN_BASE_INSN_SIZE, info);
9c03036a
DE
565 if (status != 0)
566 {
853713a7 567 (*info->memory_error_func) (status, pc, info);
9c03036a
DE
568 return -1;
569 }
570
571 /* We try to have as much common code as possible.
572 But at this point some targets need to take over. */
573 /* ??? Some targets may need a hook elsewhere. Try to avoid this,
23cf992f 574 but if not possible try to move this hook elsewhere rather than
9c03036a
DE
575 have two hooks. */
576 length = CGEN_PRINT_INSN (pc, info, buffer, CGEN_BASE_INSN_BITSIZE);
577 if (length)
578 return length;
579
853713a7 580 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
9c03036a
DE
581 return CGEN_DEFAULT_INSN_SIZE;
582}
This page took 0.067716 seconds and 4 git commands to generate.