1 /* Disassembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS USED TO GENERATE fr30-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 /* Used by the ifield rtx function. */
44 #define FLD(f) (fields->f)
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
*,
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
*));
67 /* -- disassembler routines inserted here */
71 print_register_list (dis_info
, value
, offset
, load_store
)
75 int load_store
; /* 0 == load, 1 == store */
77 disassemble_info
*info
= dis_info
;
89 (*info
->fprintf_func
) (info
->stream
, "r%i", index
+ offset
);
93 for (index
= 1; index
<= 7; ++index
)
102 (*info
->fprintf_func
) (info
->stream
, "%sr%i", comma
, index
+ offset
);
109 print_hi_register_list_ld (od
, dis_info
, value
, attrs
, pc
, length
)
117 print_register_list (dis_info
, value
, 8, 0/*load*/);
121 print_low_register_list_ld (od
, dis_info
, value
, attrs
, pc
, length
)
129 print_register_list (dis_info
, value
, 0, 0/*load*/);
133 print_hi_register_list_st (od
, dis_info
, value
, attrs
, pc
, length
)
141 print_register_list (dis_info
, value
, 8, 1/*store*/);
145 print_low_register_list_st (od
, dis_info
, value
, attrs
, pc
, length
)
153 print_register_list (dis_info
, value
, 0, 1/*store*/);
157 print_m4 (od
, dis_info
, value
, attrs
, pc
, length
)
165 disassemble_info
*info
= (disassemble_info
*) dis_info
;
166 (*info
->fprintf_func
) (info
->stream
, "%ld", value
);
170 /* Main entry point for operand extraction.
172 This function is basically just a big switch statement. Earlier versions
173 used tables to look up the function to use, but
174 - if the table contains both assembler and disassembler functions then
175 the disassembler contains much of the assembler and vice-versa,
176 - there's a lot of inlining possibilities as things grow,
177 - using a switch statement avoids the function call overhead.
179 This function could be moved into `print_insn_normal', but keeping it
180 separate makes clear the interface between `print_insn_normal' and each of
185 fr30_cgen_extract_operand (od
, opindex
, ex_info
, insn_value
, fields
, pc
)
188 CGEN_EXTRACT_INFO
*ex_info
;
189 CGEN_INSN_INT insn_value
;
190 CGEN_FIELDS
* fields
;
194 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
198 case FR30_OPERAND_RI
:
199 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, pc
, & fields
->f_Ri
);
201 case FR30_OPERAND_RJ
:
202 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rj
);
204 case FR30_OPERAND_RIC
:
205 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 12, 4, 16, total_length
, pc
, & fields
->f_Ric
);
207 case FR30_OPERAND_RJC
:
208 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 8, 4, 16, total_length
, pc
, & fields
->f_Rjc
);
210 case FR30_OPERAND_CRI
:
211 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 12, 4, 16, total_length
, pc
, & fields
->f_CRi
);
213 case FR30_OPERAND_CRJ
:
214 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 8, 4, 16, total_length
, pc
, & fields
->f_CRj
);
216 case FR30_OPERAND_RS1
:
217 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rs1
);
219 case FR30_OPERAND_RS2
:
220 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, pc
, & fields
->f_Rs2
);
222 case FR30_OPERAND_R13
:
223 length
= extract_normal (od
, ex_info
, insn_value
, 0, 0, 0, 0, 0, total_length
, pc
, & fields
->f_nil
);
225 case FR30_OPERAND_R14
:
226 length
= extract_normal (od
, ex_info
, insn_value
, 0, 0, 0, 0, 0, total_length
, pc
, & fields
->f_nil
);
228 case FR30_OPERAND_R15
:
229 length
= extract_normal (od
, ex_info
, insn_value
, 0, 0, 0, 0, 0, total_length
, pc
, & fields
->f_nil
);
231 case FR30_OPERAND_PS
:
232 length
= extract_normal (od
, ex_info
, insn_value
, 0, 0, 0, 0, 0, total_length
, pc
, & fields
->f_nil
);
234 case FR30_OPERAND_U4
:
235 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, pc
, & fields
->f_u4
);
237 case FR30_OPERAND_U4C
:
238 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, pc
, & fields
->f_u4c
);
240 case FR30_OPERAND_U8
:
241 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_u8
);
243 case FR30_OPERAND_I8
:
244 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 4, 8, 16, total_length
, pc
, & fields
->f_i8
);
246 case FR30_OPERAND_UDISP6
:
249 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, pc
, & value
);
250 value
= ((value
) << (2));
251 fields
->f_udisp6
= value
;
254 case FR30_OPERAND_DISP8
:
255 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 0, 4, 8, 16, total_length
, pc
, & fields
->f_disp8
);
257 case FR30_OPERAND_DISP9
:
260 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 0, 4, 8, 16, total_length
, pc
, & value
);
261 value
= ((value
) << (1));
262 fields
->f_disp9
= value
;
265 case FR30_OPERAND_DISP10
:
268 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 0, 4, 8, 16, total_length
, pc
, & value
);
269 value
= ((value
) << (2));
270 fields
->f_disp10
= value
;
273 case FR30_OPERAND_S10
:
276 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 0, 8, 8, 16, total_length
, pc
, & value
);
277 value
= ((value
) << (2));
278 fields
->f_s10
= value
;
281 case FR30_OPERAND_U10
:
284 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & value
);
285 value
= ((value
) << (2));
286 fields
->f_u10
= value
;
289 case FR30_OPERAND_I32
:
290 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 0, 32, 32, total_length
, pc
, & fields
->f_i32
);
292 case FR30_OPERAND_M4
:
295 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, pc
, & value
);
296 value
= ((value
) | (((-1) << (4))));
297 fields
->f_m4
= value
;
300 case FR30_OPERAND_I20
:
302 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
)|(1<<CGEN_OPERAND_VIRTUAL
), 0, 8, 4, 16, total_length
, pc
, & fields
->f_i20_4
);
303 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
)|(1<<CGEN_OPERAND_VIRTUAL
), 16, 0, 16, 16, total_length
, pc
, & fields
->f_i20_16
);
305 FLD (f_i20
) = ((((FLD (f_i20_4
)) << (16))) | (FLD (f_i20_16
)));
309 case FR30_OPERAND_DIR8
:
310 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_dir8
);
312 case FR30_OPERAND_DIR9
:
315 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & value
);
316 value
= ((value
) << (1));
317 fields
->f_dir9
= value
;
320 case FR30_OPERAND_DIR10
:
323 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & value
);
324 value
= ((value
) << (2));
325 fields
->f_dir10
= value
;
328 case FR30_OPERAND_LABEL9
:
331 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
), 0, 8, 8, 16, total_length
, pc
, & value
);
332 value
= ((((value
) << (1))) + (((pc
) + (2))));
333 fields
->f_rel9
= value
;
336 case FR30_OPERAND_LABEL12
:
339 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
), 0, 5, 11, 16, total_length
, pc
, & value
);
340 value
= ((((value
) << (1))) + (((pc
) + (2))));
341 fields
->f_rel12
= value
;
344 case FR30_OPERAND_REGLIST_LOW_LD
:
345 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_ld
);
347 case FR30_OPERAND_REGLIST_HI_LD
:
348 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_ld
);
350 case FR30_OPERAND_REGLIST_LOW_ST
:
351 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_st
);
353 case FR30_OPERAND_REGLIST_HI_ST
:
354 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_st
);
356 case FR30_OPERAND_CC
:
357 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 4, 4, 16, total_length
, pc
, & fields
->f_cc
);
359 case FR30_OPERAND_CCC
:
360 length
= extract_normal (od
, ex_info
, insn_value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 0, 8, 16, total_length
, pc
, & fields
->f_ccc
);
364 /* xgettext:c-format */
365 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
373 /* Main entry point for printing operands.
375 This function is basically just a big switch statement. Earlier versions
376 used tables to look up the function to use, but
377 - if the table contains both assembler and disassembler functions then
378 the disassembler contains much of the assembler and vice-versa,
379 - there's a lot of inlining possibilities as things grow,
380 - using a switch statement avoids the function call overhead.
382 This function could be moved into `print_insn_normal', but keeping it
383 separate makes clear the interface between `print_insn_normal' and each of
388 fr30_cgen_print_operand (od
, opindex
, info
, fields
, attrs
, pc
, length
)
391 disassemble_info
* info
;
392 CGEN_FIELDS
* fields
;
399 case FR30_OPERAND_RI
:
400 print_keyword (od
, info
, & fr30_cgen_opval_h_gr
, fields
->f_Ri
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
402 case FR30_OPERAND_RJ
:
403 print_keyword (od
, info
, & fr30_cgen_opval_h_gr
, fields
->f_Rj
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
405 case FR30_OPERAND_RIC
:
406 print_keyword (od
, info
, & fr30_cgen_opval_h_gr
, fields
->f_Ric
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
408 case FR30_OPERAND_RJC
:
409 print_keyword (od
, info
, & fr30_cgen_opval_h_gr
, fields
->f_Rjc
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
411 case FR30_OPERAND_CRI
:
412 print_keyword (od
, info
, & fr30_cgen_opval_h_cr
, fields
->f_CRi
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
414 case FR30_OPERAND_CRJ
:
415 print_keyword (od
, info
, & fr30_cgen_opval_h_cr
, fields
->f_CRj
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
417 case FR30_OPERAND_RS1
:
418 print_keyword (od
, info
, & fr30_cgen_opval_h_dr
, fields
->f_Rs1
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
420 case FR30_OPERAND_RS2
:
421 print_keyword (od
, info
, & fr30_cgen_opval_h_dr
, fields
->f_Rs2
, 0|(1<<CGEN_OPERAND_UNSIGNED
));
423 case FR30_OPERAND_R13
:
424 print_keyword (od
, info
, & fr30_cgen_opval_h_r13
, fields
->f_nil
, 0);
426 case FR30_OPERAND_R14
:
427 print_keyword (od
, info
, & fr30_cgen_opval_h_r14
, fields
->f_nil
, 0);
429 case FR30_OPERAND_R15
:
430 print_keyword (od
, info
, & fr30_cgen_opval_h_r15
, fields
->f_nil
, 0);
432 case FR30_OPERAND_PS
:
433 print_keyword (od
, info
, & fr30_cgen_opval_h_ps
, fields
->f_nil
, 0);
435 case FR30_OPERAND_U4
:
436 print_normal (od
, info
, fields
->f_u4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
438 case FR30_OPERAND_U4C
:
439 print_normal (od
, info
, fields
->f_u4c
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
441 case FR30_OPERAND_U8
:
442 print_normal (od
, info
, fields
->f_u8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
444 case FR30_OPERAND_I8
:
445 print_normal (od
, info
, fields
->f_i8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
447 case FR30_OPERAND_UDISP6
:
448 print_normal (od
, info
, fields
->f_udisp6
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
450 case FR30_OPERAND_DISP8
:
451 print_normal (od
, info
, fields
->f_disp8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
453 case FR30_OPERAND_DISP9
:
454 print_normal (od
, info
, fields
->f_disp9
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
456 case FR30_OPERAND_DISP10
:
457 print_normal (od
, info
, fields
->f_disp10
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
459 case FR30_OPERAND_S10
:
460 print_normal (od
, info
, fields
->f_s10
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), pc
, length
);
462 case FR30_OPERAND_U10
:
463 print_normal (od
, info
, fields
->f_u10
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
465 case FR30_OPERAND_I32
:
466 print_normal (od
, info
, fields
->f_i32
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
468 case FR30_OPERAND_M4
:
469 print_m4 (od
, info
, fields
->f_m4
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
471 case FR30_OPERAND_I20
:
472 print_normal (od
, info
, fields
->f_i20
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
)|(1<<CGEN_OPERAND_VIRTUAL
), pc
, length
);
474 case FR30_OPERAND_DIR8
:
475 print_normal (od
, info
, fields
->f_dir8
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
477 case FR30_OPERAND_DIR9
:
478 print_normal (od
, info
, fields
->f_dir9
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
480 case FR30_OPERAND_DIR10
:
481 print_normal (od
, info
, fields
->f_dir10
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
483 case FR30_OPERAND_LABEL9
:
484 print_address (od
, info
, fields
->f_rel9
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
), pc
, length
);
486 case FR30_OPERAND_LABEL12
:
487 print_address (od
, info
, fields
->f_rel12
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
), pc
, length
);
489 case FR30_OPERAND_REGLIST_LOW_LD
:
490 print_low_register_list_ld (od
, info
, fields
->f_reglist_low_ld
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
492 case FR30_OPERAND_REGLIST_HI_LD
:
493 print_hi_register_list_ld (od
, info
, fields
->f_reglist_hi_ld
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
495 case FR30_OPERAND_REGLIST_LOW_ST
:
496 print_low_register_list_st (od
, info
, fields
->f_reglist_low_st
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
498 case FR30_OPERAND_REGLIST_HI_ST
:
499 print_hi_register_list_st (od
, info
, fields
->f_reglist_hi_st
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
501 case FR30_OPERAND_CC
:
502 print_normal (od
, info
, fields
->f_cc
, 0|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
504 case FR30_OPERAND_CCC
:
505 print_normal (od
, info
, fields
->f_ccc
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), pc
, length
);
509 /* xgettext:c-format */
510 fprintf (stderr
, _("Unrecognized field %d while printing insn.\n"),
516 cgen_extract_fn
* const fr30_cgen_extract_handlers
[] =
522 cgen_print_fn
* const fr30_cgen_print_handlers
[] =
530 fr30_cgen_init_dis (od
)
536 #if ! CGEN_INT_INSN_P
538 /* Subroutine of extract_normal.
539 Ensure sufficient bytes are cached in EX_INFO.
540 OFFSET is the offset in bytes from the start of the insn of the value.
541 BYTES is the length of the needed value.
542 Returns 1 for success, 0 for failure. */
545 fill_cache (od
, ex_info
, offset
, bytes
, pc
)
547 CGEN_EXTRACT_INFO
*ex_info
;
551 /* It's doubtful that the middle part has already been fetched so
552 we don't optimize that case. kiss. */
554 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
556 /* First do a quick check. */
557 mask
= (1 << bytes
) - 1;
558 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
561 /* Search for the first byte we need to read. */
562 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
563 if (! (mask
& ex_info
->valid
))
571 status
= (*info
->read_memory_func
)
572 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
576 (*info
->memory_error_func
) (status
, pc
, info
);
580 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
586 /* Subroutine of extract_normal. */
589 extract_1 (od
, ex_info
, start
, length
, word_length
, bufp
, pc
)
591 CGEN_EXTRACT_INFO
*ex_info
;
592 int start
,length
,word_length
;
596 unsigned long x
,mask
;
598 int big_p
= CGEN_OPCODE_INSN_ENDIAN (od
) == CGEN_ENDIAN_BIG
;
607 x
= bfd_getb16 (bufp
);
609 x
= bfd_getl16 (bufp
);
612 /* ??? This may need reworking as these cases don't necessarily
613 want the first byte and the last two bytes handled like this. */
615 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
617 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
621 x
= bfd_getb32 (bufp
);
623 x
= bfd_getl32 (bufp
);
629 /* Written this way to avoid undefined behaviour. */
630 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
631 if (CGEN_INSN_LSB0_P
)
632 shift
= (start
+ 1) - length
;
634 shift
= (word_length
- (start
+ length
));
635 return (x
>> shift
) & mask
;
638 #endif /* ! CGEN_INT_INSN_P */
640 /* Default extraction routine.
642 INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
643 or sometimes less for cases like the m32r where the base insn size is 32
644 but some insns are 16 bits.
645 ATTRS is a mask of the boolean attributes. We only need `UNSIGNED',
646 but for generality we take a bitmask of all of them.
647 WORD_OFFSET is the offset in bits from the start of the insn of the value.
648 WORD_LENGTH is the length of the word in bits in which the value resides.
649 START is the starting bit number in the word, architecture origin.
650 LENGTH is the length of VALUE in bits.
651 TOTAL_LENGTH is the total length of the insn in bits.
653 Returns 1 for success, 0 for failure. */
655 /* ??? The return code isn't properly used. wip. */
657 /* ??? This doesn't handle bfd_vma's. Create another function when
661 extract_normal (od
, ex_info
, insn_value
, attrs
, word_offset
, start
, length
,
662 word_length
, total_length
, pc
, valuep
)
664 CGEN_EXTRACT_INFO
*ex_info
;
665 CGEN_INSN_INT insn_value
;
667 unsigned int word_offset
, start
, length
, word_length
, total_length
;
673 /* If LENGTH is zero, this operand doesn't contribute to the value
674 so give it a standard value of zero. */
685 if (word_length
> 32)
688 /* For architectures with insns smaller than the insn-base-bitsize,
689 word_length may be too big. */
690 #if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
692 && word_length
> total_length
)
693 word_length
= total_length
;
696 /* Does the value reside in INSN_VALUE? */
698 if (word_offset
== 0)
700 /* Written this way to avoid undefined behaviour. */
701 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
703 if (CGEN_INSN_LSB0_P
)
704 value
= insn_value
>> ((start
+ 1) - length
);
706 value
= insn_value
>> (word_length
- (start
+ length
));
709 if (! CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_UNSIGNED
)
710 && (value
& (1L << (length
- 1))))
714 #if ! CGEN_INT_INSN_P
718 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
720 if (word_length
> 32)
723 if (fill_cache (od
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
726 value
= extract_1 (od
, ex_info
, start
, length
, word_length
, bufp
, pc
);
729 #endif /* ! CGEN_INT_INSN_P */
736 /* Default print handler. */
739 print_normal (od
, dis_info
, value
, attrs
, pc
, length
)
747 disassemble_info
*info
= (disassemble_info
*) dis_info
;
749 #ifdef CGEN_PRINT_NORMAL
750 CGEN_PRINT_NORMAL (od
, info
, value
, attrs
, pc
, length
);
753 /* Print the operand as directed by the attributes. */
754 if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_SEM_ONLY
))
755 ; /* nothing to do */
756 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_UNSIGNED
))
757 (*info
->fprintf_func
) (info
->stream
, "0x%lx", value
);
759 (*info
->fprintf_func
) (info
->stream
, "%ld", value
);
762 /* Default address handler. */
765 print_address (od
, dis_info
, value
, attrs
, pc
, length
)
773 disassemble_info
*info
= (disassemble_info
*) dis_info
;
775 #ifdef CGEN_PRINT_ADDRESS
776 CGEN_PRINT_ADDRESS (od
, info
, value
, attrs
, pc
, length
);
779 /* Print the operand as directed by the attributes. */
780 if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_SEM_ONLY
))
781 ; /* nothing to do */
782 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_PCREL_ADDR
))
783 (*info
->print_address_func
) (value
, info
);
784 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_ABS_ADDR
))
785 (*info
->print_address_func
) (value
, info
);
786 else if (CGEN_BOOL_ATTR (attrs
, CGEN_OPERAND_UNSIGNED
))
787 (*info
->fprintf_func
) (info
->stream
, "0x%lx", (long) value
);
789 (*info
->fprintf_func
) (info
->stream
, "%ld", (long) value
);
792 /* Keyword print handler. */
795 print_keyword (od
, dis_info
, keyword_table
, value
, attrs
)
798 CGEN_KEYWORD
*keyword_table
;
802 disassemble_info
*info
= (disassemble_info
*) dis_info
;
803 const CGEN_KEYWORD_ENTRY
*ke
;
805 ke
= cgen_keyword_lookup_value (keyword_table
, value
);
807 (*info
->fprintf_func
) (info
->stream
, "%s", ke
->name
);
809 (*info
->fprintf_func
) (info
->stream
, "???");
812 /* Default insn extractor.
814 INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
815 The extracted fields are stored in FIELDS.
816 EX_INFO is used to handle reading variable length insns.
817 Return the length of the insn in bits, or 0 if no match,
818 or -1 if an error occurs fetching data (memory_error_func will have
822 extract_insn_normal (od
, insn
, ex_info
, insn_value
, fields
, pc
)
824 const CGEN_INSN
*insn
;
825 CGEN_EXTRACT_INFO
*ex_info
;
826 CGEN_INSN_INT insn_value
;
830 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
831 const unsigned char *syn
;
833 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
835 CGEN_INIT_EXTRACT (od
);
837 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
841 if (CGEN_SYNTAX_CHAR_P (*syn
))
844 length
= fr30_cgen_extract_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
845 ex_info
, insn_value
, fields
, pc
);
850 /* We recognized and successfully extracted this insn. */
851 return CGEN_INSN_BITSIZE (insn
);
854 /* Default insn printer.
856 DIS_INFO is defined as `PTR' so the disassembler needn't know anything
857 about disassemble_info. */
860 print_insn_normal (od
, dis_info
, insn
, fields
, pc
, length
)
863 const CGEN_INSN
*insn
;
868 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
869 disassemble_info
*info
= (disassemble_info
*) dis_info
;
870 const unsigned char *syn
;
872 CGEN_INIT_PRINT (od
);
874 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
876 if (CGEN_SYNTAX_MNEMONIC_P (*syn
))
878 (*info
->fprintf_func
) (info
->stream
, "%s", CGEN_INSN_MNEMONIC (insn
));
881 if (CGEN_SYNTAX_CHAR_P (*syn
))
883 (*info
->fprintf_func
) (info
->stream
, "%c", CGEN_SYNTAX_CHAR (*syn
));
887 /* We have an operand. */
888 fr30_cgen_print_operand (od
, CGEN_SYNTAX_FIELD (*syn
), info
,
889 fields
, CGEN_INSN_ATTRS (insn
), pc
, length
);
893 /* Utility to print an insn.
894 BUF is the base part of the insn, target byte order, BUFLEN bytes long.
895 The result is the size of the insn in bytes or zero for an unknown insn
896 or -1 if an error occurs fetching data (memory_error_func will have
900 print_insn (od
, pc
, info
, buf
, buflen
)
903 disassemble_info
*info
;
907 unsigned long insn_value
;
908 const CGEN_INSN_LIST
*insn_list
;
909 CGEN_EXTRACT_INFO ex_info
;
911 ex_info
.dis_info
= info
;
912 ex_info
.valid
= (1 << CGEN_BASE_INSN_SIZE
) - 1;
913 ex_info
.insn_bytes
= buf
;
921 insn_value
= info
->endian
== BFD_ENDIAN_BIG
? bfd_getb16 (buf
) : bfd_getl16 (buf
);
924 insn_value
= info
->endian
== BFD_ENDIAN_BIG
? bfd_getb32 (buf
) : bfd_getl32 (buf
);
930 /* The instructions are stored in hash lists.
931 Pick the first one and keep trying until we find the right one. */
933 insn_list
= CGEN_DIS_LOOKUP_INSN (od
, buf
, insn_value
);
934 while (insn_list
!= NULL
)
936 const CGEN_INSN
*insn
= insn_list
->insn
;
940 #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
941 /* Supported by this cpu? */
942 if (! fr30_cgen_insn_supported (od
, insn
))
946 /* Basic bit mask must be correct. */
947 /* ??? May wish to allow target to defer this check until the extract
949 if ((insn_value
& CGEN_INSN_BASE_MASK (insn
))
950 == CGEN_INSN_BASE_VALUE (insn
))
952 /* Printing is handled in two passes. The first pass parses the
953 machine insn and extracts the fields. The second pass prints
956 length
= (*CGEN_EXTRACT_FN (insn
)) (od
, insn
, &ex_info
, insn_value
,
958 /* length < 0 -> error */
963 (*CGEN_PRINT_FN (insn
)) (od
, info
, insn
, &fields
, pc
, length
);
964 /* length is in bits, result is in bytes */
969 insn_list
= CGEN_DIS_NEXT_INSN (insn_list
);
975 /* Default value for CGEN_PRINT_INSN.
976 The result is the size of the insn in bytes or zero for an unknown insn
977 or -1 if an error occured fetching bytes. */
979 #ifndef CGEN_PRINT_INSN
980 #define CGEN_PRINT_INSN default_print_insn
984 default_print_insn (od
, pc
, info
)
987 disassemble_info
*info
;
989 char buf
[CGEN_MAX_INSN_SIZE
];
992 /* Read the base part of the insn. */
994 status
= (*info
->read_memory_func
) (pc
, buf
, CGEN_BASE_INSN_SIZE
, info
);
997 (*info
->memory_error_func
) (status
, pc
, info
);
1001 return print_insn (od
, pc
, info
, buf
, CGEN_BASE_INSN_SIZE
);
1004 /* Main entry point.
1005 Print one instruction from PC on INFO->STREAM.
1006 Return the size of the instruction (in bytes). */
1009 print_insn_fr30 (pc
, info
)
1011 disassemble_info
*info
;
1014 static CGEN_OPCODE_DESC od
= 0;
1015 int mach
= info
->mach
;
1016 int big_p
= info
->endian
== BFD_ENDIAN_BIG
;
1018 /* If we haven't initialized yet, initialize the opcode table. */
1021 od
= fr30_cgen_opcode_open (mach
,
1024 : CGEN_ENDIAN_LITTLE
);
1025 fr30_cgen_init_dis (od
);
1027 /* If we've switched cpu's, re-initialize. */
1028 /* ??? Perhaps we should use BFD_ENDIAN. */
1029 else if (mach
!= CGEN_OPCODE_MACH (od
)
1030 || (CGEN_OPCODE_ENDIAN (od
)
1031 != (big_p
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE
)))
1033 cgen_set_cpu (od
, mach
, big_p
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE
);
1036 /* We try to have as much common code as possible.
1037 But at this point some targets need to take over. */
1038 /* ??? Some targets may need a hook elsewhere. Try to avoid this,
1039 but if not possible try to move this hook elsewhere rather than
1041 length
= CGEN_PRINT_INSN (od
, pc
, info
);
1047 (*info
->fprintf_func
) (info
->stream
, UNKNOWN_INSN_MSG
);
1048 return CGEN_DEFAULT_INSN_SIZE
;