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