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 "frv-desc.h"
00043 #include "frv-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_spr
00069 PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned));
00070 static void print_hi
00071 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00072 static void print_lo
00073 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
00074
00075 static void
00076 print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00077 PTR dis_info,
00078 long reloc_ann ATTRIBUTE_UNUSED,
00079 long value ATTRIBUTE_UNUSED,
00080 bfd_vma pc ATTRIBUTE_UNUSED,
00081 int length ATTRIBUTE_UNUSED
00082 )
00083 {
00084 disassemble_info *info = (disassemble_info *) dis_info;
00085 (*info->fprintf_func) (info->stream, "@");
00086 }
00087
00088 static void
00089 print_spr (cd, dis_info, names, regno, attrs)
00090 CGEN_CPU_DESC cd;
00091 PTR dis_info;
00092 CGEN_KEYWORD *names;
00093 long regno;
00094 unsigned int attrs;
00095 {
00096
00097 if (cgen_keyword_lookup_value (names, regno) == NULL)
00098 {
00099 disassemble_info *info = (disassemble_info *) dis_info;
00100 (*info->fprintf_func) (info->stream, "spr[%ld]", regno);
00101 }
00102 else
00103 print_keyword (cd, dis_info, names, regno, attrs);
00104 }
00105
00106 static void
00107 print_hi (cd, dis_info, value, attrs, pc, length)
00108 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00109 PTR dis_info;
00110 long value;
00111 unsigned int attrs ATTRIBUTE_UNUSED;
00112 bfd_vma pc ATTRIBUTE_UNUSED;
00113 int length ATTRIBUTE_UNUSED;
00114 {
00115 disassemble_info *info = (disassemble_info *) dis_info;
00116 if (value)
00117 (*info->fprintf_func) (info->stream, "0x%lx", value);
00118 else
00119 (*info->fprintf_func) (info->stream, "hi(0x%lx)", value);
00120 }
00121
00122 static void
00123 print_lo (cd, dis_info, value, attrs, pc, length)
00124 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00125 PTR dis_info;
00126 long value;
00127 unsigned int attrs ATTRIBUTE_UNUSED;
00128 bfd_vma pc ATTRIBUTE_UNUSED;
00129 int length ATTRIBUTE_UNUSED;
00130 {
00131 disassemble_info *info = (disassemble_info *) dis_info;
00132 if (value)
00133 (*info->fprintf_func) (info->stream, "0x%lx", value);
00134 else
00135 (*info->fprintf_func) (info->stream, "lo(0x%lx)", value);
00136 }
00137
00138
00139
00140 void frv_cgen_print_operand
00141 PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
00142 void const *, bfd_vma, int));
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 void
00160 frv_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
00161 CGEN_CPU_DESC cd;
00162 int opindex;
00163 PTR xinfo;
00164 CGEN_FIELDS *fields;
00165 void const *attrs ATTRIBUTE_UNUSED;
00166 bfd_vma pc;
00167 int length;
00168 {
00169 disassemble_info *info = (disassemble_info *) xinfo;
00170
00171 switch (opindex)
00172 {
00173 case FRV_OPERAND_A0 :
00174 print_normal (cd, info, fields->f_A, 0, pc, length);
00175 break;
00176 case FRV_OPERAND_A1 :
00177 print_normal (cd, info, fields->f_A, 0, pc, length);
00178 break;
00179 case FRV_OPERAND_ACC40SI :
00180 print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Si, 0);
00181 break;
00182 case FRV_OPERAND_ACC40SK :
00183 print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Sk, 0);
00184 break;
00185 case FRV_OPERAND_ACC40UI :
00186 print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Ui, 0);
00187 break;
00188 case FRV_OPERAND_ACC40UK :
00189 print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Uk, 0);
00190 break;
00191 case FRV_OPERAND_ACCGI :
00192 print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGi, 0);
00193 break;
00194 case FRV_OPERAND_ACCGK :
00195 print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGk, 0);
00196 break;
00197 case FRV_OPERAND_CCI :
00198 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CCi, 0);
00199 break;
00200 case FRV_OPERAND_CPRDOUBLEK :
00201 print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0);
00202 break;
00203 case FRV_OPERAND_CPRI :
00204 print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRi, 0);
00205 break;
00206 case FRV_OPERAND_CPRJ :
00207 print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRj, 0);
00208 break;
00209 case FRV_OPERAND_CPRK :
00210 print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0);
00211 break;
00212 case FRV_OPERAND_CRI :
00213 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRi, 0);
00214 break;
00215 case FRV_OPERAND_CRJ :
00216 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj, 0);
00217 break;
00218 case FRV_OPERAND_CRJ_FLOAT :
00219 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_float, 0);
00220 break;
00221 case FRV_OPERAND_CRJ_INT :
00222 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_int, 0);
00223 break;
00224 case FRV_OPERAND_CRK :
00225 print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRk, 0);
00226 break;
00227 case FRV_OPERAND_FCCI_1 :
00228 print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_1, 0);
00229 break;
00230 case FRV_OPERAND_FCCI_2 :
00231 print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_2, 0);
00232 break;
00233 case FRV_OPERAND_FCCI_3 :
00234 print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_3, 0);
00235 break;
00236 case FRV_OPERAND_FCCK :
00237 print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCk, 0);
00238 break;
00239 case FRV_OPERAND_FRDOUBLEI :
00240 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
00241 break;
00242 case FRV_OPERAND_FRDOUBLEJ :
00243 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
00244 break;
00245 case FRV_OPERAND_FRDOUBLEK :
00246 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00247 break;
00248 case FRV_OPERAND_FRI :
00249 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
00250 break;
00251 case FRV_OPERAND_FRINTI :
00252 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
00253 break;
00254 case FRV_OPERAND_FRINTIEVEN :
00255 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
00256 break;
00257 case FRV_OPERAND_FRINTJ :
00258 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
00259 break;
00260 case FRV_OPERAND_FRINTJEVEN :
00261 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
00262 break;
00263 case FRV_OPERAND_FRINTK :
00264 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00265 break;
00266 case FRV_OPERAND_FRINTKEVEN :
00267 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00268 break;
00269 case FRV_OPERAND_FRJ :
00270 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
00271 break;
00272 case FRV_OPERAND_FRK :
00273 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00274 break;
00275 case FRV_OPERAND_FRKHI :
00276 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00277 break;
00278 case FRV_OPERAND_FRKLO :
00279 print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
00280 break;
00281 case FRV_OPERAND_GRDOUBLEK :
00282 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
00283 break;
00284 case FRV_OPERAND_GRI :
00285 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRi, 0);
00286 break;
00287 case FRV_OPERAND_GRJ :
00288 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRj, 0);
00289 break;
00290 case FRV_OPERAND_GRK :
00291 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
00292 break;
00293 case FRV_OPERAND_GRKHI :
00294 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
00295 break;
00296 case FRV_OPERAND_GRKLO :
00297 print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
00298 break;
00299 case FRV_OPERAND_ICCI_1 :
00300 print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_1, 0);
00301 break;
00302 case FRV_OPERAND_ICCI_2 :
00303 print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_2, 0);
00304 break;
00305 case FRV_OPERAND_ICCI_3 :
00306 print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_3, 0);
00307 break;
00308 case FRV_OPERAND_LI :
00309 print_normal (cd, info, fields->f_LI, 0, pc, length);
00310 break;
00311 case FRV_OPERAND_LRAD :
00312 print_normal (cd, info, fields->f_LRAD, 0, pc, length);
00313 break;
00314 case FRV_OPERAND_LRAE :
00315 print_normal (cd, info, fields->f_LRAE, 0, pc, length);
00316 break;
00317 case FRV_OPERAND_LRAS :
00318 print_normal (cd, info, fields->f_LRAS, 0, pc, length);
00319 break;
00320 case FRV_OPERAND_TLBPRL :
00321 print_normal (cd, info, fields->f_TLBPRL, 0, pc, length);
00322 break;
00323 case FRV_OPERAND_TLBPROPX :
00324 print_normal (cd, info, fields->f_TLBPRopx, 0, pc, length);
00325 break;
00326 case FRV_OPERAND_AE :
00327 print_normal (cd, info, fields->f_ae, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00328 break;
00329 case FRV_OPERAND_CALLANN :
00330 print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
00331 break;
00332 case FRV_OPERAND_CCOND :
00333 print_normal (cd, info, fields->f_ccond, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00334 break;
00335 case FRV_OPERAND_COND :
00336 print_normal (cd, info, fields->f_cond, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00337 break;
00338 case FRV_OPERAND_D12 :
00339 print_normal (cd, info, fields->f_d12, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
00340 break;
00341 case FRV_OPERAND_DEBUG :
00342 print_normal (cd, info, fields->f_debug, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00343 break;
00344 case FRV_OPERAND_EIR :
00345 print_normal (cd, info, fields->f_eir, 0, pc, length);
00346 break;
00347 case FRV_OPERAND_HINT :
00348 print_normal (cd, info, fields->f_hint, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00349 break;
00350 case FRV_OPERAND_HINT_NOT_TAKEN :
00351 print_keyword (cd, info, & frv_cgen_opval_h_hint_not_taken, fields->f_hint, 0);
00352 break;
00353 case FRV_OPERAND_HINT_TAKEN :
00354 print_keyword (cd, info, & frv_cgen_opval_h_hint_taken, fields->f_hint, 0);
00355 break;
00356 case FRV_OPERAND_LABEL16 :
00357 print_address (cd, info, fields->f_label16, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
00358 break;
00359 case FRV_OPERAND_LABEL24 :
00360 print_address (cd, info, fields->f_label24, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
00361 break;
00362 case FRV_OPERAND_LDANN :
00363 print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
00364 break;
00365 case FRV_OPERAND_LDDANN :
00366 print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
00367 break;
00368 case FRV_OPERAND_LOCK :
00369 print_normal (cd, info, fields->f_lock, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00370 break;
00371 case FRV_OPERAND_PACK :
00372 print_keyword (cd, info, & frv_cgen_opval_h_pack, fields->f_pack, 0);
00373 break;
00374 case FRV_OPERAND_S10 :
00375 print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00376 break;
00377 case FRV_OPERAND_S12 :
00378 print_normal (cd, info, fields->f_d12, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00379 break;
00380 case FRV_OPERAND_S16 :
00381 print_normal (cd, info, fields->f_s16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00382 break;
00383 case FRV_OPERAND_S5 :
00384 print_normal (cd, info, fields->f_s5, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00385 break;
00386 case FRV_OPERAND_S6 :
00387 print_normal (cd, info, fields->f_s6, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00388 break;
00389 case FRV_OPERAND_S6_1 :
00390 print_normal (cd, info, fields->f_s6_1, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00391 break;
00392 case FRV_OPERAND_SLO16 :
00393 print_lo (cd, info, fields->f_s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
00394 break;
00395 case FRV_OPERAND_SPR :
00396 print_spr (cd, info, & frv_cgen_opval_spr_names, fields->f_spr, 0|(1<<CGEN_OPERAND_VIRTUAL));
00397 break;
00398 case FRV_OPERAND_U12 :
00399 print_normal (cd, info, fields->f_u12, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
00400 break;
00401 case FRV_OPERAND_U16 :
00402 print_normal (cd, info, fields->f_u16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00403 break;
00404 case FRV_OPERAND_U6 :
00405 print_normal (cd, info, fields->f_u6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
00406 break;
00407 case FRV_OPERAND_UHI16 :
00408 print_hi (cd, info, fields->f_u16, 0, pc, length);
00409 break;
00410 case FRV_OPERAND_ULO16 :
00411 print_lo (cd, info, fields->f_u16, 0, pc, length);
00412 break;
00413
00414 default :
00415
00416 fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
00417 opindex);
00418 abort ();
00419 }
00420 }
00421
00422 cgen_print_fn * const frv_cgen_print_handlers[] =
00423 {
00424 print_insn_normal,
00425 };
00426
00427
00428 void
00429 frv_cgen_init_dis (cd)
00430 CGEN_CPU_DESC cd;
00431 {
00432 frv_cgen_init_opcode_table (cd);
00433 frv_cgen_init_ibld_table (cd);
00434 cd->print_handlers = & frv_cgen_print_handlers[0];
00435 cd->print_operand = frv_cgen_print_operand;
00436 }
00437
00438
00439
00440
00441 static void
00442 print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00443 void *dis_info,
00444 long value,
00445 unsigned int attrs,
00446 bfd_vma pc ATTRIBUTE_UNUSED,
00447 int length ATTRIBUTE_UNUSED)
00448 {
00449 disassemble_info *info = (disassemble_info *) dis_info;
00450
00451 #ifdef CGEN_PRINT_NORMAL
00452 CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
00453 #endif
00454
00455
00456 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
00457 ;
00458 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
00459 (*info->fprintf_func) (info->stream, "%ld", value);
00460 else
00461 (*info->fprintf_func) (info->stream, "0x%lx", value);
00462 }
00463
00464
00465
00466 static void
00467 print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00468 void *dis_info,
00469 bfd_vma value,
00470 unsigned int attrs,
00471 bfd_vma pc ATTRIBUTE_UNUSED,
00472 int length ATTRIBUTE_UNUSED)
00473 {
00474 disassemble_info *info = (disassemble_info *) dis_info;
00475
00476 #ifdef CGEN_PRINT_ADDRESS
00477 CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
00478 #endif
00479
00480
00481 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
00482 ;
00483 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
00484 (*info->print_address_func) (value, info);
00485 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
00486 (*info->print_address_func) (value, info);
00487 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
00488 (*info->fprintf_func) (info->stream, "%ld", (long) value);
00489 else
00490 (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
00491 }
00492
00493
00494
00495 static void
00496 print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00497 void *dis_info,
00498 CGEN_KEYWORD *keyword_table,
00499 long value,
00500 unsigned int attrs ATTRIBUTE_UNUSED)
00501 {
00502 disassemble_info *info = (disassemble_info *) dis_info;
00503 const CGEN_KEYWORD_ENTRY *ke;
00504
00505 ke = cgen_keyword_lookup_value (keyword_table, value);
00506 if (ke != NULL)
00507 (*info->fprintf_func) (info->stream, "%s", ke->name);
00508 else
00509 (*info->fprintf_func) (info->stream, "???");
00510 }
00511
00512
00513
00514
00515
00516
00517 static void
00518 print_insn_normal (CGEN_CPU_DESC cd,
00519 void *dis_info,
00520 const CGEN_INSN *insn,
00521 CGEN_FIELDS *fields,
00522 bfd_vma pc,
00523 int length)
00524 {
00525 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00526 disassemble_info *info = (disassemble_info *) dis_info;
00527 const CGEN_SYNTAX_CHAR_TYPE *syn;
00528
00529 CGEN_INIT_PRINT (cd);
00530
00531 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
00532 {
00533 if (CGEN_SYNTAX_MNEMONIC_P (*syn))
00534 {
00535 (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
00536 continue;
00537 }
00538 if (CGEN_SYNTAX_CHAR_P (*syn))
00539 {
00540 (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
00541 continue;
00542 }
00543
00544
00545 frv_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
00546 fields, CGEN_INSN_ATTRS (insn), pc, length);
00547 }
00548 }
00549
00550
00551
00552
00553
00554 static int
00555 read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00556 bfd_vma pc,
00557 disassemble_info *info,
00558 bfd_byte *buf,
00559 int buflen,
00560 CGEN_EXTRACT_INFO *ex_info,
00561 unsigned long *insn_value)
00562 {
00563 int status = (*info->read_memory_func) (pc, buf, buflen, info);
00564 if (status != 0)
00565 {
00566 (*info->memory_error_func) (status, pc, info);
00567 return -1;
00568 }
00569
00570 ex_info->dis_info = info;
00571 ex_info->valid = (1 << buflen) - 1;
00572 ex_info->insn_bytes = buf;
00573
00574 *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
00575 return 0;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 static int
00585 print_insn (CGEN_CPU_DESC cd,
00586 bfd_vma pc,
00587 disassemble_info *info,
00588 bfd_byte *buf,
00589 unsigned int buflen)
00590 {
00591 CGEN_INSN_INT insn_value;
00592 const CGEN_INSN_LIST *insn_list;
00593 CGEN_EXTRACT_INFO ex_info;
00594 int basesize;
00595
00596
00597 basesize = cd->base_insn_bitsize < buflen * 8 ?
00598 cd->base_insn_bitsize : buflen * 8;
00599 insn_value = cgen_get_insn_value (cd, buf, basesize);
00600
00601
00602
00603
00604
00605 ex_info.valid = (1 << buflen) - 1;
00606 ex_info.dis_info = info;
00607 ex_info.insn_bytes = buf;
00608
00609
00610
00611
00612 insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
00613 while (insn_list != NULL)
00614 {
00615 const CGEN_INSN *insn = insn_list->insn;
00616 CGEN_FIELDS fields;
00617 int length;
00618 unsigned long insn_value_cropped;
00619
00620 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
00621
00622
00623 if (! frv_cgen_insn_supported (cd, insn))
00624 {
00625 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
00626 continue;
00627 }
00628 #endif
00629
00630
00631
00632
00633
00634
00635
00636 if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
00637 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
00638 insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
00639 info->endian == BFD_ENDIAN_BIG);
00640 else
00641 insn_value_cropped = insn_value;
00642
00643 if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
00644 == CGEN_INSN_BASE_VALUE (insn))
00645 {
00646
00647
00648
00649
00650
00651
00652 if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
00653 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
00654 {
00655 unsigned long full_insn_value;
00656 int rc = read_insn (cd, pc, info, buf,
00657 CGEN_INSN_BITSIZE (insn) / 8,
00658 & ex_info, & full_insn_value);
00659 if (rc != 0)
00660 return rc;
00661 length = CGEN_EXTRACT_FN (cd, insn)
00662 (cd, insn, &ex_info, full_insn_value, &fields, pc);
00663 }
00664 else
00665 length = CGEN_EXTRACT_FN (cd, insn)
00666 (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
00667
00668
00669 if (length < 0)
00670 return length;
00671 if (length > 0)
00672 {
00673 CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
00674
00675 return length / 8;
00676 }
00677 }
00678
00679 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
00680 }
00681
00682 return 0;
00683 }
00684
00685
00686
00687
00688
00689 #ifndef CGEN_PRINT_INSN
00690 #define CGEN_PRINT_INSN default_print_insn
00691 #endif
00692
00693 static int
00694 default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
00695 {
00696 bfd_byte buf[CGEN_MAX_INSN_SIZE];
00697 int buflen;
00698 int status;
00699
00700
00701 buflen = cd->base_insn_bitsize / 8;
00702 status = (*info->read_memory_func) (pc, buf, buflen, info);
00703
00704
00705 if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
00706 {
00707 buflen = cd->min_insn_bitsize / 8;
00708 status = (*info->read_memory_func) (pc, buf, buflen, info);
00709 }
00710
00711 if (status != 0)
00712 {
00713 (*info->memory_error_func) (status, pc, info);
00714 return -1;
00715 }
00716
00717 return print_insn (cd, pc, info, buf, buflen);
00718 }
00719
00720
00721
00722
00723
00724 typedef struct cpu_desc_list {
00725 struct cpu_desc_list *next;
00726 int isa;
00727 int mach;
00728 int endian;
00729 CGEN_CPU_DESC cd;
00730 } cpu_desc_list;
00731
00732 int
00733 print_insn_frv (bfd_vma pc, disassemble_info *info)
00734 {
00735 static cpu_desc_list *cd_list = 0;
00736 cpu_desc_list *cl = 0;
00737 static CGEN_CPU_DESC cd = 0;
00738 static int prev_isa;
00739 static int prev_mach;
00740 static int prev_endian;
00741 int length;
00742 int isa,mach;
00743 int endian = (info->endian == BFD_ENDIAN_BIG
00744 ? CGEN_ENDIAN_BIG
00745 : CGEN_ENDIAN_LITTLE);
00746 enum bfd_architecture arch;
00747
00748
00749 #ifndef CGEN_BFD_ARCH
00750 #define CGEN_BFD_ARCH bfd_arch_frv
00751 #endif
00752 arch = info->arch;
00753 if (arch == bfd_arch_unknown)
00754 arch = CGEN_BFD_ARCH;
00755
00756
00757
00758 #ifdef CGEN_COMPUTE_MACH
00759 mach = CGEN_COMPUTE_MACH (info);
00760 #else
00761 mach = info->mach;
00762 #endif
00763
00764 #ifdef CGEN_COMPUTE_ISA
00765 isa = CGEN_COMPUTE_ISA (info);
00766 #else
00767 isa = info->insn_sets;
00768 #endif
00769
00770
00771 if (cd
00772 && (isa != prev_isa
00773 || mach != prev_mach
00774 || endian != prev_endian))
00775 {
00776 cd = 0;
00777 for (cl = cd_list; cl; cl = cl->next)
00778 {
00779 if (cl->isa == isa &&
00780 cl->mach == mach &&
00781 cl->endian == endian)
00782 {
00783 cd = cl->cd;
00784 break;
00785 }
00786 }
00787 }
00788
00789
00790 if (! cd)
00791 {
00792 const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
00793 const char *mach_name;
00794
00795 if (!arch_type)
00796 abort ();
00797 mach_name = arch_type->printable_name;
00798
00799 prev_isa = isa;
00800 prev_mach = mach;
00801 prev_endian = endian;
00802 cd = frv_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
00803 CGEN_CPU_OPEN_BFDMACH, mach_name,
00804 CGEN_CPU_OPEN_ENDIAN, prev_endian,
00805 CGEN_CPU_OPEN_END);
00806 if (!cd)
00807 abort ();
00808
00809
00810 cl = xmalloc (sizeof (struct cpu_desc_list));
00811 cl->cd = cd;
00812 cl->isa = isa;
00813 cl->mach = mach;
00814 cl->endian = endian;
00815 cl->next = cd_list;
00816 cd_list = cl;
00817
00818 frv_cgen_init_dis (cd);
00819 }
00820
00821
00822
00823
00824
00825
00826 length = CGEN_PRINT_INSN (cd, pc, info);
00827 if (length > 0)
00828 return length;
00829 if (length < 0)
00830 return -1;
00831
00832 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
00833 return cd->default_insn_bitsize / 8;
00834 }