00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "sysdep.h"
00036 #include <stdio.h>
00037 #include "ansidecl.h"
00038 #include "dis-asm.h"
00039 #include "bfd.h"
00040 #include "symcat.h"
00041 #include "libiberty.h"
00042 #include "fr30-desc.h"
00043 #include "fr30-opc.h"
00044 #include "opintl.h"
00045
00046
00047 #define UNKNOWN_INSN_MSG _("*unknown*")
00048
00049 static void print_normal
00050 (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
00051 static void print_address
00052 (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
00053 static void print_keyword
00054 (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
00055 static void print_insn_normal
00056 (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
00057 static int print_insn
00058 (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
00059 static int default_print_insn
00060 (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
00061 static int read_insn
00062 (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
00063 unsigned long *);
00064
00065
00066
00067
00068 static void print_register_list
00069 PARAMS ((PTR, long, long, int));
00070 static void print_hi_register_list_ld
00071 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00072 static void print_low_register_list_ld
00073 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00074 static void print_hi_register_list_st
00075 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00076 static void print_low_register_list_st
00077 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00078 static void print_m4
00079 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00080
00081 static void
00082 print_register_list (dis_info, value, offset, load_store)
00083 PTR dis_info;
00084 long value;
00085 long offset;
00086 int load_store;
00087 {
00088 disassemble_info *info = dis_info;
00089 int mask;
00090 int index = 0;
00091 char* comma = "";
00092
00093 if (load_store)
00094 mask = 0x80;
00095 else
00096 mask = 1;
00097
00098 if (value & mask)
00099 {
00100 (*info->fprintf_func) (info->stream, "r%i", index + offset);
00101 comma = ",";
00102 }
00103
00104 for (index = 1; index <= 7; ++index)
00105 {
00106 if (load_store)
00107 mask >>= 1;
00108 else
00109 mask <<= 1;
00110
00111 if (value & mask)
00112 {
00113 (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
00114 comma = ",";
00115 }
00116 }
00117 }
00118
00119 static void
00120 print_hi_register_list_ld (cd, dis_info, value, attrs, pc, length)
00121 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00122 PTR dis_info;
00123 long value;
00124 unsigned int attrs ATTRIBUTE_UNUSED;
00125 bfd_vma pc ATTRIBUTE_UNUSED;
00126 int length ATTRIBUTE_UNUSED;
00127 {
00128 print_register_list (dis_info, value, 8, 0);
00129 }
00130
00131 static void
00132 print_low_register_list_ld (cd, dis_info, value, attrs, pc, length)
00133 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00134 PTR dis_info;
00135 long value;
00136 unsigned int attrs ATTRIBUTE_UNUSED;
00137 bfd_vma pc ATTRIBUTE_UNUSED;
00138 int length ATTRIBUTE_UNUSED;
00139 {
00140 print_register_list (dis_info, value, 0, 0);
00141 }
00142
00143 static void
00144 print_hi_register_list_st (cd, dis_info, value, attrs, pc, length)
00145 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00146 PTR dis_info;
00147 long value;
00148 unsigned int attrs ATTRIBUTE_UNUSED;
00149 bfd_vma pc ATTRIBUTE_UNUSED;
00150 int length ATTRIBUTE_UNUSED;
00151 {
00152 print_register_list (dis_info, value, 8, 1);
00153 }
00154
00155 static void
00156 print_low_register_list_st (cd, dis_info, value, attrs, pc, length)
00157 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00158 PTR dis_info;
00159 long value;
00160 unsigned int attrs ATTRIBUTE_UNUSED;
00161 bfd_vma pc ATTRIBUTE_UNUSED;
00162 int length ATTRIBUTE_UNUSED;
00163 {
00164 print_register_list (dis_info, value, 0, 1);
00165 }
00166
00167 static void
00168 print_m4 (cd, dis_info, value, attrs, pc, length)
00169 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00170 PTR dis_info;
00171 long value;
00172 unsigned int attrs ATTRIBUTE_UNUSED;
00173 bfd_vma pc ATTRIBUTE_UNUSED;
00174 int length ATTRIBUTE_UNUSED;
00175 {
00176 disassemble_info *info = (disassemble_info *) dis_info;
00177 (*info->fprintf_func) (info->stream, "%ld", value);
00178 }
00179
00180
00181 void fr30_cgen_print_operand
00182 PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
00183 void const *, bfd_vma, int));
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 void
00201 fr30_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
00202 CGEN_CPU_DESC cd;
00203 int opindex;
00204 PTR xinfo;
00205 CGEN_FIELDS *fields;
00206 void const *attrs ATTRIBUTE_UNUSED;
00207 bfd_vma pc;
00208 int length;
00209 {
00210 disassemble_info *info = (disassemble_info *) xinfo;
00211
00212 switch (opindex)
00213 {
00214 case FR30_OPERAND_CRI :
00215 print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRi, 0);
00216 break;
00217 case FR30_OPERAND_CRJ :
00218 print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRj, 0);
00219 break;
00220 case FR30_OPERAND_R13 :
00221 print_keyword (cd, info, & fr30_cgen_opval_h_r13, 0, 0);
00222 break;
00223 case FR30_OPERAND_R14 :
00224 print_keyword (cd, info, & fr30_cgen_opval_h_r14, 0, 0);
00225 break;
00226 case FR30_OPERAND_R15 :
00227 print_keyword (cd, info, & fr30_cgen_opval_h_r15, 0, 0);
00228 break;
00229 case FR30_OPERAND_RI :
00230 print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ri, 0);
00231 break;
00232 case FR30_OPERAND_RIC :
00233 print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ric, 0);
00234 break;
00235 case FR30_OPERAND_RJ :
00236 print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rj, 0);
00237 break;
00238 case FR30_OPERAND_RJC :
00239 print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rjc, 0);
00240 break;
00241 case FR30_OPERAND_RS1 :
00242 print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs1, 0);
00243 break;
00244 case FR30_OPERAND_RS2 :
00245 print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs2, 0);
00246 break;
00247 case FR30_OPERAND_CC :
00248 print_normal (cd, info, fields->f_cc, 0, pc, length);
00249 break;
00250 case FR30_OPERAND_CCC :
00251 print_normal (cd, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00252 break;
00253 case FR30_OPERAND_DIR10 :
00254 print_normal (cd, info, fields->f_dir10, 0, pc, length);
00255 break;
00256 case FR30_OPERAND_DIR8 :
00257 print_normal (cd, info, fields->f_dir8, 0, pc, length);
00258 break;
00259 case FR30_OPERAND_DIR9 :
00260 print_normal (cd, info, fields->f_dir9, 0, pc, length);
00261 break;
00262 case FR30_OPERAND_DISP10 :
00263 print_normal (cd, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00264 break;
00265 case FR30_OPERAND_DISP8 :
00266 print_normal (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00267 break;
00268 case FR30_OPERAND_DISP9 :
00269 print_normal (cd, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00270 break;
00271 case FR30_OPERAND_I20 :
00272 print_normal (cd, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
00273 break;
00274 case FR30_OPERAND_I32 :
00275 print_normal (cd, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
00276 break;
00277 case FR30_OPERAND_I8 :
00278 print_normal (cd, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00279 break;
00280 case FR30_OPERAND_LABEL12 :
00281 print_address (cd, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
00282 break;
00283 case FR30_OPERAND_LABEL9 :
00284 print_address (cd, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
00285 break;
00286 case FR30_OPERAND_M4 :
00287 print_m4 (cd, info, fields->f_m4, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00288 break;
00289 case FR30_OPERAND_PS :
00290 print_keyword (cd, info, & fr30_cgen_opval_h_ps, 0, 0);
00291 break;
00292 case FR30_OPERAND_REGLIST_HI_LD :
00293 print_hi_register_list_ld (cd, info, fields->f_reglist_hi_ld, 0, pc, length);
00294 break;
00295 case FR30_OPERAND_REGLIST_HI_ST :
00296 print_hi_register_list_st (cd, info, fields->f_reglist_hi_st, 0, pc, length);
00297 break;
00298 case FR30_OPERAND_REGLIST_LOW_LD :
00299 print_low_register_list_ld (cd, info, fields->f_reglist_low_ld, 0, pc, length);
00300 break;
00301 case FR30_OPERAND_REGLIST_LOW_ST :
00302 print_low_register_list_st (cd, info, fields->f_reglist_low_st, 0, pc, length);
00303 break;
00304 case FR30_OPERAND_S10 :
00305 print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00306 break;
00307 case FR30_OPERAND_U10 :
00308 print_normal (cd, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00309 break;
00310 case FR30_OPERAND_U4 :
00311 print_normal (cd, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00312 break;
00313 case FR30_OPERAND_U4C :
00314 print_normal (cd, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00315 break;
00316 case FR30_OPERAND_U8 :
00317 print_normal (cd, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00318 break;
00319 case FR30_OPERAND_UDISP6 :
00320 print_normal (cd, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00321 break;
00322
00323 default :
00324
00325 fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
00326 opindex);
00327 abort ();
00328 }
00329 }
00330
00331 cgen_print_fn * const fr30_cgen_print_handlers[] =
00332 {
00333 print_insn_normal,
00334 };
00335
00336
00337 void
00338 fr30_cgen_init_dis (cd)
00339 CGEN_CPU_DESC cd;
00340 {
00341 fr30_cgen_init_opcode_table (cd);
00342 fr30_cgen_init_ibld_table (cd);
00343 cd->print_handlers = & fr30_cgen_print_handlers[0];
00344 cd->print_operand = fr30_cgen_print_operand;
00345 }
00346
00347
00348
00349
00350 static void
00351 print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00352 void *dis_info,
00353 long value,
00354 unsigned int attrs,
00355 bfd_vma pc ATTRIBUTE_UNUSED,
00356 int length ATTRIBUTE_UNUSED)
00357 {
00358 disassemble_info *info = (disassemble_info *) dis_info;
00359
00360 #ifdef CGEN_PRINT_NORMAL
00361 CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
00362 #endif
00363
00364
00365 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
00366 ;
00367 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
00368 (*info->fprintf_func) (info->stream, "%ld", value);
00369 else
00370 (*info->fprintf_func) (info->stream, "0x%lx", value);
00371 }
00372
00373
00374
00375 static void
00376 print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00377 void *dis_info,
00378 bfd_vma value,
00379 unsigned int attrs,
00380 bfd_vma pc ATTRIBUTE_UNUSED,
00381 int length ATTRIBUTE_UNUSED)
00382 {
00383 disassemble_info *info = (disassemble_info *) dis_info;
00384
00385 #ifdef CGEN_PRINT_ADDRESS
00386 CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
00387 #endif
00388
00389
00390 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
00391 ;
00392 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
00393 (*info->print_address_func) (value, info);
00394 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
00395 (*info->print_address_func) (value, info);
00396 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
00397 (*info->fprintf_func) (info->stream, "%ld", (long) value);
00398 else
00399 (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
00400 }
00401
00402
00403
00404 static void
00405 print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00406 void *dis_info,
00407 CGEN_KEYWORD *keyword_table,
00408 long value,
00409 unsigned int attrs ATTRIBUTE_UNUSED)
00410 {
00411 disassemble_info *info = (disassemble_info *) dis_info;
00412 const CGEN_KEYWORD_ENTRY *ke;
00413
00414 ke = cgen_keyword_lookup_value (keyword_table, value);
00415 if (ke != NULL)
00416 (*info->fprintf_func) (info->stream, "%s", ke->name);
00417 else
00418 (*info->fprintf_func) (info->stream, "???");
00419 }
00420
00421
00422
00423
00424
00425
00426 static void
00427 print_insn_normal (CGEN_CPU_DESC cd,
00428 void *dis_info,
00429 const CGEN_INSN *insn,
00430 CGEN_FIELDS *fields,
00431 bfd_vma pc,
00432 int length)
00433 {
00434 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00435 disassemble_info *info = (disassemble_info *) dis_info;
00436 const CGEN_SYNTAX_CHAR_TYPE *syn;
00437
00438 CGEN_INIT_PRINT (cd);
00439
00440 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
00441 {
00442 if (CGEN_SYNTAX_MNEMONIC_P (*syn))
00443 {
00444 (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
00445 continue;
00446 }
00447 if (CGEN_SYNTAX_CHAR_P (*syn))
00448 {
00449 (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
00450 continue;
00451 }
00452
00453
00454 fr30_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
00455 fields, CGEN_INSN_ATTRS (insn), pc, length);
00456 }
00457 }
00458
00459
00460
00461
00462
00463 static int
00464 read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00465 bfd_vma pc,
00466 disassemble_info *info,
00467 bfd_byte *buf,
00468 int buflen,
00469 CGEN_EXTRACT_INFO *ex_info,
00470 unsigned long *insn_value)
00471 {
00472 int status = (*info->read_memory_func) (pc, buf, buflen, info);
00473 if (status != 0)
00474 {
00475 (*info->memory_error_func) (status, pc, info);
00476 return -1;
00477 }
00478
00479 ex_info->dis_info = info;
00480 ex_info->valid = (1 << buflen) - 1;
00481 ex_info->insn_bytes = buf;
00482
00483 *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
00484 return 0;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493 static int
00494 print_insn (CGEN_CPU_DESC cd,
00495 bfd_vma pc,
00496 disassemble_info *info,
00497 bfd_byte *buf,
00498 unsigned int buflen)
00499 {
00500 CGEN_INSN_INT insn_value;
00501 const CGEN_INSN_LIST *insn_list;
00502 CGEN_EXTRACT_INFO ex_info;
00503 int basesize;
00504
00505
00506 basesize = cd->base_insn_bitsize < buflen * 8 ?
00507 cd->base_insn_bitsize : buflen * 8;
00508 insn_value = cgen_get_insn_value (cd, buf, basesize);
00509
00510
00511
00512
00513
00514 ex_info.valid = (1 << buflen) - 1;
00515 ex_info.dis_info = info;
00516 ex_info.insn_bytes = buf;
00517
00518
00519
00520
00521 insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
00522 while (insn_list != NULL)
00523 {
00524 const CGEN_INSN *insn = insn_list->insn;
00525 CGEN_FIELDS fields;
00526 int length;
00527 unsigned long insn_value_cropped;
00528
00529 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
00530
00531
00532 if (! fr30_cgen_insn_supported (cd, insn))
00533 {
00534 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
00535 continue;
00536 }
00537 #endif
00538
00539
00540
00541
00542
00543
00544
00545 if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
00546 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
00547 insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
00548 info->endian == BFD_ENDIAN_BIG);
00549 else
00550 insn_value_cropped = insn_value;
00551
00552 if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
00553 == CGEN_INSN_BASE_VALUE (insn))
00554 {
00555
00556
00557
00558
00559
00560
00561 if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
00562 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
00563 {
00564 unsigned long full_insn_value;
00565 int rc = read_insn (cd, pc, info, buf,
00566 CGEN_INSN_BITSIZE (insn) / 8,
00567 & ex_info, & full_insn_value);
00568 if (rc != 0)
00569 return rc;
00570 length = CGEN_EXTRACT_FN (cd, insn)
00571 (cd, insn, &ex_info, full_insn_value, &fields, pc);
00572 }
00573 else
00574 length = CGEN_EXTRACT_FN (cd, insn)
00575 (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
00576
00577
00578 if (length < 0)
00579 return length;
00580 if (length > 0)
00581 {
00582 CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
00583
00584 return length / 8;
00585 }
00586 }
00587
00588 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
00589 }
00590
00591 return 0;
00592 }
00593
00594
00595
00596
00597
00598 #ifndef CGEN_PRINT_INSN
00599 #define CGEN_PRINT_INSN default_print_insn
00600 #endif
00601
00602 static int
00603 default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
00604 {
00605 bfd_byte buf[CGEN_MAX_INSN_SIZE];
00606 int buflen;
00607 int status;
00608
00609
00610 buflen = cd->base_insn_bitsize / 8;
00611 status = (*info->read_memory_func) (pc, buf, buflen, info);
00612
00613
00614 if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
00615 {
00616 buflen = cd->min_insn_bitsize / 8;
00617 status = (*info->read_memory_func) (pc, buf, buflen, info);
00618 }
00619
00620 if (status != 0)
00621 {
00622 (*info->memory_error_func) (status, pc, info);
00623 return -1;
00624 }
00625
00626 return print_insn (cd, pc, info, buf, buflen);
00627 }
00628
00629
00630
00631
00632
00633 typedef struct cpu_desc_list {
00634 struct cpu_desc_list *next;
00635 int isa;
00636 int mach;
00637 int endian;
00638 CGEN_CPU_DESC cd;
00639 } cpu_desc_list;
00640
00641 int
00642 print_insn_fr30 (bfd_vma pc, disassemble_info *info)
00643 {
00644 static cpu_desc_list *cd_list = 0;
00645 cpu_desc_list *cl = 0;
00646 static CGEN_CPU_DESC cd = 0;
00647 static int prev_isa;
00648 static int prev_mach;
00649 static int prev_endian;
00650 int length;
00651 int isa,mach;
00652 int endian = (info->endian == BFD_ENDIAN_BIG
00653 ? CGEN_ENDIAN_BIG
00654 : CGEN_ENDIAN_LITTLE);
00655 enum bfd_architecture arch;
00656
00657
00658 #ifndef CGEN_BFD_ARCH
00659 #define CGEN_BFD_ARCH bfd_arch_fr30
00660 #endif
00661 arch = info->arch;
00662 if (arch == bfd_arch_unknown)
00663 arch = CGEN_BFD_ARCH;
00664
00665
00666
00667 #ifdef CGEN_COMPUTE_MACH
00668 mach = CGEN_COMPUTE_MACH (info);
00669 #else
00670 mach = info->mach;
00671 #endif
00672
00673 #ifdef CGEN_COMPUTE_ISA
00674 isa = CGEN_COMPUTE_ISA (info);
00675 #else
00676 isa = info->insn_sets;
00677 #endif
00678
00679
00680 if (cd
00681 && (isa != prev_isa
00682 || mach != prev_mach
00683 || endian != prev_endian))
00684 {
00685 cd = 0;
00686 for (cl = cd_list; cl; cl = cl->next)
00687 {
00688 if (cl->isa == isa &&
00689 cl->mach == mach &&
00690 cl->endian == endian)
00691 {
00692 cd = cl->cd;
00693 break;
00694 }
00695 }
00696 }
00697
00698
00699 if (! cd)
00700 {
00701 const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
00702 const char *mach_name;
00703
00704 if (!arch_type)
00705 abort ();
00706 mach_name = arch_type->printable_name;
00707
00708 prev_isa = isa;
00709 prev_mach = mach;
00710 prev_endian = endian;
00711 cd = fr30_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
00712 CGEN_CPU_OPEN_BFDMACH, mach_name,
00713 CGEN_CPU_OPEN_ENDIAN, prev_endian,
00714 CGEN_CPU_OPEN_END);
00715 if (!cd)
00716 abort ();
00717
00718
00719 cl = xmalloc (sizeof (struct cpu_desc_list));
00720 cl->cd = cd;
00721 cl->isa = isa;
00722 cl->mach = mach;
00723 cl->endian = endian;
00724 cl->next = cd_list;
00725 cd_list = cl;
00726
00727 fr30_cgen_init_dis (cd);
00728 }
00729
00730
00731
00732
00733
00734
00735 length = CGEN_PRINT_INSN (cd, pc, info);
00736 if (length > 0)
00737 return length;
00738 if (length < 0)
00739 return -1;
00740
00741 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
00742 return cd->default_insn_bitsize / 8;
00743 }