1 /* Disassembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS USED TO GENERATE m32r-dis.c.
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
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)
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.
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. */
35 #define INLINE __inline__
40 /* Default text to print if an instruction isn't recognized. */
41 #define UNKNOWN_INSN_MSG _("*unknown*")
43 static int extract_normal
44 PARAMS ((CGEN_OPCODE_DESC
, CGEN_EXTRACT_INFO
*, CGEN_INSN_BYTES
,
45 unsigned int, int, int, int, long *));
46 static void print_normal
47 PARAMS ((CGEN_OPCODE_DESC
, PTR
, long, unsigned int, bfd_vma
, int));
48 static void print_address
49 PARAMS ((CGEN_OPCODE_DESC
, PTR
, bfd_vma
, unsigned int, bfd_vma
, int));
50 static void print_keyword
51 PARAMS ((CGEN_OPCODE_DESC
, PTR
, CGEN_KEYWORD
*, long, unsigned int));
52 static int extract_insn_normal
53 PARAMS ((CGEN_OPCODE_DESC
, const CGEN_INSN
*, CGEN_EXTRACT_INFO
*,
54 unsigned long, CGEN_FIELDS
*, bfd_vma
));
55 static void print_insn_normal
56 PARAMS ((CGEN_OPCODE_DESC
, PTR
, const CGEN_INSN
*, CGEN_FIELDS
*,
58 static int print_insn
PARAMS ((CGEN_OPCODE_DESC
, bfd_vma
,
59 disassemble_info
*, char *, int));
60 static int default_print_insn
61 PARAMS ((CGEN_OPCODE_DESC
, bfd_vma
, disassemble_info
*));
63 /* -- disassembler routines inserted here */
66 /* Immediate values are prefixed with '#'. */
68 #define CGEN_PRINT_NORMAL(od, info, value, attrs, pc, length) \
70 if ((attrs) & (1 << CGEN_OPERAND_HASH_PREFIX)) \
71 (*info->fprintf_func) (info->stream, "#"); \
74 /* Handle '#' prefixes as operands. */
77 print_hash (od
, dis_info
, value
, attrs
, pc
, length
)
85 disassemble_info
*info
= dis_info
;
86 (*info
->fprintf_func
) (info
->stream
, "#");
89 #undef CGEN_PRINT_INSN
90 #define CGEN_PRINT_INSN my_print_insn
93 my_print_insn (od
, pc
, info
)
96 disassemble_info
*info
;
98 char buffer
[CGEN_MAX_INSN_SIZE
];
101 int buflen
= (pc
& 3) == 0 ? 4 : 2;
103 /* Read the base part of the insn. */
105 status
= (*info
->read_memory_func
) (pc
, buf
, buflen
, info
);
108 (*info
->memory_error_func
) (status
, pc
, info
);
113 if ((pc
& 3) == 0 && (buf
[0] & 0x80) != 0)
114 return print_insn (od
, pc
, info
, buf
, buflen
);
116 /* Print the first insn. */
119 if (print_insn (od
, pc
, info
, buf
, 2) == 0)
120 (*info
->fprintf_func
) (info
->stream
, UNKNOWN_INSN_MSG
);
127 (*info
->fprintf_func
) (info
->stream
, " || ");
131 (*info
->fprintf_func
) (info
->stream
, " -> ");
133 /* The "& 3" is to pass a consistent address.
134 Parallel insns arguably both begin on the word boundary.
135 Also, branch insns are calculated relative to the word boundary. */
136 if (print_insn (od
, pc
& ~ (bfd_vma
) 3, info
, buf
, 2) == 0)
137 (*info
->fprintf_func
) (info
->stream
, UNKNOWN_INSN_MSG
);
139 return (pc
& 3) ? 2 : 4;
144 /* Main entry point for operand extraction.
146 This function is basically just a big switch statement. Earlier versions
147 used tables to look up the function to use, but
148 - if the table contains both assembler and disassembler functions then
149 the disassembler contains much of the assembler and vice-versa,
150 - there's a lot of inlining possibilities as things grow,
151 - using a switch statement avoids the function call overhead.
153 This function could be moved into `print_insn_normal', but keeping it
154 separate makes clear the interface between `print_insn_normal' and each of
159 m32r_cgen_extract_operand (od
, opindex
, ex_info
, insn_value
, fields
, pc
)
162 CGEN_EXTRACT_INFO
*ex_info
;
163 CGEN_INSN_BYTES insn_value
;
164 CGEN_FIELDS
* fields
;
171 case M32R_OPERAND_SR
:
172 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r2
);
174 case M32R_OPERAND_DR
:
175 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r1
);
177 case M32R_OPERAND_SRC1
:
178 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r1
);
180 case M32R_OPERAND_SRC2
:
181 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r2
);
183 case M32R_OPERAND_SCR
:
184 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r2
);
186 case M32R_OPERAND_DCR
:
187 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_r1
);
189 case M32R_OPERAND_SIMM8
:
190 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_simm8
);
192 case M32R_OPERAND_SIMM16
:
193 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_simm16
);
195 case M32R_OPERAND_UIMM4
:
196 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_uimm4
);
198 case M32R_OPERAND_UIMM5
:
199 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 11, 5, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_uimm5
);
201 case M32R_OPERAND_UIMM16
:
202 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_uimm16
);
204 /* start-sanitize-m32rx */
205 case M32R_OPERAND_IMM1
:
208 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 15, 1, CGEN_FIELDS_BITSIZE (fields
), & value
);
209 value
= ((value
) + (1));
210 fields
->f_imm1
= value
;
213 /* end-sanitize-m32rx */
214 /* start-sanitize-m32rx */
215 case M32R_OPERAND_ACCD
:
216 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 2, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_accd
);
218 /* end-sanitize-m32rx */
219 /* start-sanitize-m32rx */
220 case M32R_OPERAND_ACCS
:
221 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 2, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_accs
);
223 /* end-sanitize-m32rx */
224 /* start-sanitize-m32rx */
225 case M32R_OPERAND_ACC
:
226 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 1, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_acc
);
228 /* end-sanitize-m32rx */
229 case M32R_OPERAND_HASH
:
230 length
= extract_normal (od
, ex_info
, insn_value
, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_nil
);
232 case M32R_OPERAND_HI16
:
233 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_hi16
);
235 case M32R_OPERAND_SLO16
:
236 length
= extract_normal (od
, ex_info
, insn_value
, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_simm16
);
238 case M32R_OPERAND_ULO16
:
239 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_uimm16
);
241 case M32R_OPERAND_UIMM24
:
242 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
), 8, 24, CGEN_FIELDS_BITSIZE (fields
), & fields
->f_uimm24
);
244 case M32R_OPERAND_DISP8
:
247 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), & value
);
248 value
= ((((value
) << (2))) + (((pc
) & (-4))));
249 fields
->f_disp8
= value
;
252 case M32R_OPERAND_DISP16
:
255 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), & value
);
256 value
= ((((value
) << (2))) + (pc
));
257 fields
->f_disp16
= value
;
260 case M32R_OPERAND_DISP24
:
263 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 8, 24, CGEN_FIELDS_BITSIZE (fields
), & value
);
264 value
= ((((value
) << (2))) + (pc
));
265 fields
->f_disp24
= value
;
270 /* xgettext:c-format */
271 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
279 /* Main entry point for printing operands.
281 This function is basically just a big switch statement. Earlier versions
282 used tables to look up the function to use, but
283 - if the table contains both assembler and disassembler functions then
284 the disassembler contains much of the assembler and vice-versa,
285 - there's a lot of inlining possibilities as things grow,
286 - using a switch statement avoids the function call overhead.
288 This function could be moved into `print_insn_normal', but keeping it
289 separate makes clear the interface between `print_insn_normal' and each of
294 m32r_cgen_print_operand (od
, opindex
, info
, fields
, attrs
, pc
, length
)
297 disassemble_info
* info
;
298 CGEN_FIELDS
* fields
;
305 case M32R_OPERAND_SR
:
306 print_keyword (od
, info
, & m32r_cgen_opval_h_gr
, fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
308 case M32R_OPERAND_DR
:
309 print_keyword (od
, info
, & m32r_cgen_opval_h_gr
, fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
311 case M32R_OPERAND_SRC1
:
312 print_keyword (od
, info
, & m32r_cgen_opval_h_gr
, fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
314 case M32R_OPERAND_SRC2
:
315 print_keyword (od
, info
, & m32r_cgen_opval_h_gr
, fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
317 case M32R_OPERAND_SCR
:
318 print_keyword (od
, info
, & m32r_cgen_opval_h_cr
, fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
320 case M32R_OPERAND_DCR
:
321 print_keyword (od
, info
, & m32r_cgen_opval_h_cr
, fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
323 case M32R_OPERAND_SIMM8
:
324 print_normal (od
, info
, fields
->f_simm8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
326 case M32R_OPERAND_SIMM16
:
327 print_normal (od
, info
, fields
->f_simm16
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
329 case M32R_OPERAND_UIMM4
:
330 print_normal (od
, info
, fields
->f_uimm4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
332 case M32R_OPERAND_UIMM5
:
333 print_normal (od
, info
, fields
->f_uimm5
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
335 case M32R_OPERAND_UIMM16
:
336 print_normal (od
, info
, fields
->f_uimm16
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
338 /* start-sanitize-m32rx */
339 case M32R_OPERAND_IMM1
:
340 print_normal (od
, info
, fields
->f_imm1
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
342 /* end-sanitize-m32rx */
343 /* start-sanitize-m32rx */
344 case M32R_OPERAND_ACCD
:
345 print_keyword (od
, info
, & m32r_cgen_opval_h_accums
, fields
->f_accd
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
347 /* end-sanitize-m32rx */
348 /* start-sanitize-m32rx */
349 case M32R_OPERAND_ACCS
:
350 print_keyword (od
, info
, & m32r_cgen_opval_h_accums
, fields
->f_accs
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
352 /* end-sanitize-m32rx */
353 /* start-sanitize-m32rx */
354 case M32R_OPERAND_ACC
:
355 print_keyword (od
, info
, & m32r_cgen_opval_h_accums
, fields
->f_acc
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
357 /* end-sanitize-m32rx */
358 case M32R_OPERAND_HASH
:
359 print_hash (od
, info
, fields
->f_nil
, 0, pc
, length
);
361 case M32R_OPERAND_HI16
:
362 print_normal (od
, info
, fields
->f_hi16
, 0|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
364 case M32R_OPERAND_SLO16
:
365 print_normal (od
, info
, fields
->f_simm16
, 0, pc
, length
);
367 case M32R_OPERAND_ULO16
:
368 print_normal (od
, info
, fields
->f_uimm16
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
370 case M32R_OPERAND_UIMM24
:
371 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
);
373 case M32R_OPERAND_DISP8
:
374 print_address (od
, info
, fields
->f_disp8
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), pc
, length
);
376 case M32R_OPERAND_DISP16
:
377 print_address (od
, info
, fields
->f_disp16
, 0|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), pc
, length
);
379 case M32R_OPERAND_DISP24
:
380 print_address (od
, info
, fields
->f_disp24
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), pc
, length
);
384 /* xgettext:c-format */
385 fprintf (stderr
, _("Unrecognized field %d while printing insn.\n"),
391 cgen_extract_fn
* const m32r_cgen_extract_handlers
[] =
397 cgen_print_fn
* const m32r_cgen_print_handlers
[] =
405 m32r_cgen_init_dis (od
)
411 #if ! CGEN_INT_INSN_P
413 /* Subroutine of extract_normal. */
416 extract_1 (od
, ex_info
, start
, length
, word_length
, bufp
)
418 CGEN_EXTRACT_INFO
*info
;
419 int start
,length
,word_length
;
422 unsigned long x
,mask
;
424 int big_p
= CGEN_OPCODE_INSN_ENDIAN (od
) == CGEN_ENDIAN_BIG
;
426 /* FIXME: Need to use ex_info to ensure bytes have been fetched. */
435 x
= bfd_getb16 (bufp
);
437 x
= bfd_getl16 (bufp
);
440 /* ??? This may need reworking as these cases don't necessarily
441 want the first byte and the last two bytes handled like this. */
443 x
= (bfd_getb8 (bufp
) << 16) | bfd_getb16 (bufp
+ 1);
445 x
= bfd_getl16 (bufp
) | (bfd_getb8 (bufp
+ 2) << 16);
449 x
= bfd_getb32 (bufp
);
451 x
= bfd_getl32 (bufp
);
457 /* Written this way to avoid undefined behaviour. */
458 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
459 if (CGEN_INSN_LSB0_P
)
462 shift
= (word_length
- (start
+ length
));
463 return (x
>> shift
) & mask
;
466 #endif /* ! CGEN_INT_INSN_P */
468 /* Default extraction routine.
470 ATTRS is a mask of the boolean attributes. We only need `unsigned',
471 but for generality we take a bitmask of all of them. */
473 /* ??? This doesn't handle bfd_vma's. Create another function when
477 extract_normal (od
, ex_info
, insn_value
, attrs
, start
, length
, total_length
, valuep
)
479 CGEN_EXTRACT_INFO
*ex_info
;
480 CGEN_INSN_BYTES insn_value
;
482 int start
, length
, total_length
;
487 /* If LENGTH is zero, this operand doesn't contribute to the value
488 so give it a standard value of zero. */
498 /* Written this way to avoid undefined behaviour. */
499 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
501 if (CGEN_INSN_LSB0_P
)
502 value
= insn_value
>> start
;
504 value
= insn_value
>> (total_length
- (start
+ length
));
507 if (! (attrs
& CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED
))
508 && (value
& (1L << (length
- 1))))
514 /* The hard case is probably too slow for the normal cases.
515 It's certainly more difficult to understand than the normal case.
516 Thus this is split into two. Keep it that way. The hard case is defined
517 to be when a field straddles a (loosely defined) word boundary
518 (??? which may require target specific help to determine). */
522 #define HARD_CASE_P 0 /* FIXME:wip */
530 unsigned char *bufp
= (unsigned char *) insn_value
;
535 /* Adjust start,total_length,bufp to point to the pseudo-word that holds
536 the value. For example in a 48 bit insn where the value to insert
537 (say an immediate value) is the last 16 bits then word_length here
538 would be 16. To handle a 24 bit insn with an 18 bit immediate,
539 extract_1 handles 24 bits (using a combination of bfd_get8,16). */
541 if (total_length
> 32)
543 int needed_width
= start
% 8 + length
;
544 int fetch_length
= (needed_width
<= 8 ? 8
545 : needed_width
<= 16 ? 16
548 if (CGEN_INSN_LSB0_P
)
550 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
556 int offset
= start
& ~7;
560 total_length
-= offset
;
565 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
567 int offset
= start
& ~7;
571 total_length
-= offset
;
580 /* FIXME: which bytes are being extracted have been lost. */
581 value
= extract_1 (od
, ex_info
, start
, length
, total_length
, bufp
);
584 #endif /* ! CGEN_INT_INSN_P */
592 /* Default print handler. */
595 print_normal (od
, dis_info
, value
, attrs
, pc
, length
)
603 disassemble_info
*info
= (disassemble_info
*) dis_info
;
605 #ifdef CGEN_PRINT_NORMAL
606 CGEN_PRINT_NORMAL (od
, info
, value
, attrs
, pc
, length
);
609 /* Print the operand as directed by the attributes. */
610 if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_SEM_ONLY
))
611 ; /* nothing to do */
612 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_UNSIGNED
))
613 (*info
->fprintf_func
) (info
->stream
, "0x%lx", value
);
615 (*info
->fprintf_func
) (info
->stream
, "%ld", value
);
618 /* Default address handler. */
621 print_address (od
, dis_info
, value
, attrs
, pc
, length
)
629 disassemble_info
*info
= (disassemble_info
*) dis_info
;
631 #ifdef CGEN_PRINT_ADDRESS
632 CGEN_PRINT_ADDRESS (od
, info
, value
, attrs
, pc
, length
);
635 /* Print the operand as directed by the attributes. */
636 if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_SEM_ONLY
))
637 ; /* nothing to do */
638 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_PCREL_ADDR
))
639 (*info
->print_address_func
) (value
, info
);
640 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_ABS_ADDR
))
641 (*info
->print_address_func
) (value
, info
);
642 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_UNSIGNED
))
643 (*info
->fprintf_func
) (info
->stream
, "0x%lx", (long) value
);
645 (*info
->fprintf_func
) (info
->stream
, "%ld", (long) value
);
648 /* Keyword print handler. */
651 print_keyword (od
, dis_info
, keyword_table
, value
, attrs
)
654 CGEN_KEYWORD
*keyword_table
;
658 disassemble_info
*info
= (disassemble_info
*) dis_info
;
659 const CGEN_KEYWORD_ENTRY
*ke
;
661 ke
= cgen_keyword_lookup_value (keyword_table
, value
);
663 (*info
->fprintf_func
) (info
->stream
, "%s", ke
->name
);
665 (*info
->fprintf_func
) (info
->stream
, "???");
668 /* Default insn extractor.
670 INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
671 The extracted fields are stored in FIELDS.
672 EX_INFO is used to handle reading variable length insns.
673 Return the length of the insn in bits, or 0 if no match,
674 or -1 if an error occurs fetching data (memory_error_func will have
678 extract_insn_normal (od
, insn
, ex_info
, insn_value
, fields
, pc
)
680 const CGEN_INSN
*insn
;
681 CGEN_EXTRACT_INFO
*ex_info
;
682 unsigned long insn_value
;
686 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
687 const unsigned char *syn
;
689 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
691 CGEN_INIT_EXTRACT (od
);
693 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
697 if (CGEN_SYNTAX_CHAR_P (*syn
))
700 length
= m32r_cgen_extract_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
701 ex_info
, insn_value
, fields
, pc
);
706 /* We recognized and successfully extracted this insn. */
707 return CGEN_INSN_BITSIZE (insn
);
710 /* Default insn printer.
712 DIS_INFO is defined as `PTR' so the disassembler needn't know anything
713 about disassemble_info. */
716 print_insn_normal (od
, dis_info
, insn
, fields
, pc
, length
)
719 const CGEN_INSN
*insn
;
724 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
725 disassemble_info
*info
= (disassemble_info
*) dis_info
;
726 const unsigned char *syn
;
728 CGEN_INIT_PRINT (od
);
730 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
732 if (CGEN_SYNTAX_MNEMONIC_P (*syn
))
734 (*info
->fprintf_func
) (info
->stream
, "%s", CGEN_INSN_MNEMONIC (insn
));
737 if (CGEN_SYNTAX_CHAR_P (*syn
))
739 (*info
->fprintf_func
) (info
->stream
, "%c", CGEN_SYNTAX_CHAR (*syn
));
743 /* We have an operand. */
744 m32r_cgen_print_operand (od
, CGEN_SYNTAX_FIELD (*syn
), info
,
745 fields
, CGEN_INSN_ATTRS (insn
), pc
, length
);
749 /* Utility to print an insn.
750 BUF is the base part of the insn, target byte order, BUFLEN bytes long.
751 The result is the size of the insn in bytes or zero for an unknown insn
752 or -1 if an error occurs fetching data (memory_error_func will have
756 print_insn (od
, pc
, info
, buf
, buflen
)
759 disassemble_info
*info
;
763 unsigned long insn_value
;
764 const CGEN_INSN_LIST
*insn_list
;
765 CGEN_EXTRACT_INFO ex_info
;
767 ex_info
.dis_info
= info
;
768 ex_info
.valid
= (1 << CGEN_BASE_INSN_SIZE
) - 1;
777 insn_value
= info
->endian
== BFD_ENDIAN_BIG
? bfd_getb16 (buf
) : bfd_getl16 (buf
);
780 insn_value
= info
->endian
== BFD_ENDIAN_BIG
? bfd_getb32 (buf
) : bfd_getl32 (buf
);
786 /* The instructions are stored in hash lists.
787 Pick the first one and keep trying until we find the right one. */
789 insn_list
= CGEN_DIS_LOOKUP_INSN (od
, buf
, insn_value
);
790 while (insn_list
!= NULL
)
792 const CGEN_INSN
*insn
= insn_list
->insn
;
796 #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
797 /* Supported by this cpu? */
798 if (! m32r_cgen_insn_supported (od
, insn
))
802 /* Basic bit mask must be correct. */
803 /* ??? May wish to allow target to defer this check until the extract
805 if ((insn_value
& CGEN_INSN_MASK (insn
)) == CGEN_INSN_VALUE (insn
))
807 /* Printing is handled in two passes. The first pass parses the
808 machine insn and extracts the fields. The second pass prints
811 length
= (*CGEN_EXTRACT_FN (insn
)) (od
, insn
, &ex_info
, insn_value
,
813 /* length < 0 -> error */
818 (*CGEN_PRINT_FN (insn
)) (od
, info
, insn
, &fields
, pc
, length
);
819 /* length is in bits, result is in bytes */
824 insn_list
= CGEN_DIS_NEXT_INSN (insn_list
);
830 /* Default value for CGEN_PRINT_INSN.
831 The result is the size of the insn in bytes or zero for an unknown insn
832 or -1 if an error occured fetching bytes. */
834 #ifndef CGEN_PRINT_INSN
835 #define CGEN_PRINT_INSN default_print_insn
839 default_print_insn (od
, pc
, info
)
842 disassemble_info
*info
;
844 char buf
[CGEN_MAX_INSN_SIZE
];
847 /* Read the base part of the insn. */
849 status
= (*info
->read_memory_func
) (pc
, buf
, CGEN_BASE_INSN_SIZE
, info
);
852 (*info
->memory_error_func
) (status
, pc
, info
);
856 return print_insn (od
, pc
, info
, buf
, CGEN_BASE_INSN_SIZE
);
860 Print one instruction from PC on INFO->STREAM.
861 Return the size of the instruction (in bytes). */
864 print_insn_m32r (pc
, info
)
866 disassemble_info
*info
;
869 static CGEN_OPCODE_DESC od
= 0;
870 int mach
= info
->mach
;
871 int big_p
= info
->endian
== BFD_ENDIAN_BIG
;
873 /* If we haven't initialized yet, initialize the opcode table. */
876 od
= m32r_cgen_opcode_open (mach
,
879 : CGEN_ENDIAN_LITTLE
);
880 m32r_cgen_init_dis (od
);
882 /* If we've switched cpu's, re-initialize. */
883 /* ??? Perhaps we should use BFD_ENDIAN. */
884 else if (mach
!= CGEN_OPCODE_MACH (od
)
885 || (CGEN_OPCODE_ENDIAN (od
)
886 != (big_p
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE
)))
888 cgen_set_cpu (od
, mach
, big_p
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE
);
891 /* We try to have as much common code as possible.
892 But at this point some targets need to take over. */
893 /* ??? Some targets may need a hook elsewhere. Try to avoid this,
894 but if not possible try to move this hook elsewhere rather than
896 length
= CGEN_PRINT_INSN (od
, pc
, info
);
902 (*info
->fprintf_func
) (info
->stream
, UNKNOWN_INSN_MSG
);
903 return CGEN_DEFAULT_INSN_SIZE
;