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 #include "dis-asm.h"
00027 #include "sysdep.h"
00028 #include "opcode/cris.h"
00029 #include "libiberty.h"
00030
00031
00032
00033
00034 #ifndef MAX_BYTES_PER_CRIS_INSN
00035 #define MAX_BYTES_PER_CRIS_INSN 8
00036 #endif
00037
00038
00039
00040 #ifndef PARSE_PREFIX
00041 #define PARSE_PREFIX 1
00042 #endif
00043
00044
00045 #define REGISTER_PREFIX_CHAR '$'
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifndef TRACE_CASE
00069 #define TRACE_CASE (disdata->trace_case)
00070 #endif
00071
00072 enum cris_disass_family
00073 { cris_dis_v0_v10, cris_dis_common_v10_v32, cris_dis_v32 };
00074
00075
00076 struct cris_disasm_data
00077 {
00078
00079
00080 bfd_boolean trace_case;
00081
00082
00083
00084 enum cris_disass_family distype;
00085 };
00086
00087
00088 static long case_offset = 0;
00089
00090
00091 static long case_offset_counter = 0;
00092
00093
00094 static long no_of_case_offsets = 0;
00095
00096
00097 static long last_immediate = 0;
00098
00099 static int number_of_bits
00100 PARAMS ((unsigned int));
00101 static char *format_hex
00102 PARAMS ((unsigned long, char *, struct cris_disasm_data *));
00103 static char *format_dec
00104 PARAMS ((long, char *, int));
00105 static char *format_reg
00106 PARAMS ((struct cris_disasm_data *, int, char *, bfd_boolean));
00107 static char *format_sup_reg
00108 PARAMS ((unsigned int, char *, bfd_boolean));
00109 static int cris_constraint
00110 PARAMS ((const char *, unsigned int, unsigned int,
00111 struct cris_disasm_data *));
00112 static unsigned bytes_to_skip
00113 PARAMS ((unsigned int, const struct cris_opcode *,
00114 enum cris_disass_family));
00115 static char *print_flags
00116 PARAMS ((struct cris_disasm_data *, unsigned int, char *));
00117 static void print_with_operands
00118 PARAMS ((const struct cris_opcode *, unsigned int, unsigned char *,
00119 bfd_vma, disassemble_info *, const struct cris_opcode *,
00120 unsigned int, unsigned char *, bfd_boolean));
00121 static const struct cris_spec_reg *spec_reg_info
00122 PARAMS ((unsigned int, enum cris_disass_family));
00123 static int print_insn_cris_generic
00124 PARAMS ((bfd_vma, disassemble_info *, bfd_boolean));
00125 static int print_insn_cris_with_register_prefix
00126 PARAMS ((bfd_vma, disassemble_info *));
00127 static int print_insn_cris_without_register_prefix
00128 PARAMS ((bfd_vma, disassemble_info *));
00129 static int print_insn_crisv32_with_register_prefix
00130 PARAMS ((bfd_vma, disassemble_info *));
00131 static int print_insn_crisv32_without_register_prefix
00132 PARAMS ((bfd_vma, disassemble_info *));
00133 static int print_insn_crisv10_v32_with_register_prefix
00134 PARAMS ((bfd_vma, disassemble_info *));
00135 static int print_insn_crisv10_v32_without_register_prefix
00136 PARAMS ((bfd_vma, disassemble_info *));
00137 static bfd_boolean cris_parse_disassembler_options
00138 PARAMS ((disassemble_info *, enum cris_disass_family));
00139 static const struct cris_opcode *get_opcode_entry
00140 PARAMS ((unsigned int, unsigned int, struct cris_disasm_data *));
00141
00142
00143
00144
00145 static bfd_boolean
00146 cris_parse_disassembler_options (info, distype)
00147 disassemble_info *info;
00148 enum cris_disass_family distype;
00149 {
00150 struct cris_disasm_data *disdata;
00151
00152 info->private_data = calloc (1, sizeof (struct cris_disasm_data));
00153 disdata = (struct cris_disasm_data *) info->private_data;
00154 if (disdata == NULL)
00155 return FALSE;
00156
00157
00158 disdata->trace_case
00159 = (info->disassembler_options == NULL
00160 || (strcmp (info->disassembler_options, "nocase") != 0));
00161
00162 disdata->distype = distype;
00163 return TRUE;
00164 }
00165
00166
00167 static const struct cris_spec_reg *
00168 spec_reg_info (sreg, distype)
00169 unsigned int sreg;
00170 enum cris_disass_family distype;
00171 {
00172 int i;
00173 for (i = 0; cris_spec_regs[i].name != NULL; i++)
00174 {
00175 if (cris_spec_regs[i].number == sreg)
00176 {
00177 if (distype == cris_dis_v32)
00178 switch (cris_spec_regs[i].applicable_version)
00179 {
00180 case cris_ver_warning:
00181 case cris_ver_version_all:
00182 case cris_ver_v3p:
00183 case cris_ver_v8p:
00184 case cris_ver_v10p:
00185 case cris_ver_v32p:
00186
00187 if (cris_spec_regs[i].warning == NULL)
00188 return &cris_spec_regs[i];
00189 default:
00190 ;
00191 }
00192 else if (cris_spec_regs[i].applicable_version != cris_ver_v32p)
00193 return &cris_spec_regs[i];
00194 }
00195 }
00196
00197 return NULL;
00198 }
00199
00200
00201
00202 static int
00203 number_of_bits (val)
00204 unsigned int val;
00205 {
00206 int bits;
00207
00208 for (bits = 0; val != 0; val &= val - 1)
00209 bits++;
00210
00211 return bits;
00212 }
00213
00214
00215
00216 static const struct cris_opcode *
00217 get_opcode_entry (insn, prefix_insn, disdata)
00218 unsigned int insn;
00219 unsigned int prefix_insn;
00220 struct cris_disasm_data *disdata;
00221 {
00222
00223
00224 static const struct cris_opcode **opc_table = NULL;
00225
00226 const struct cris_opcode *max_matchedp = NULL;
00227 const struct cris_opcode **prefix_opc_table = NULL;
00228
00229
00230 static const struct cris_opcode **dip_prefixes = NULL;
00231 static const struct cris_opcode **bdapq_m1_prefixes = NULL;
00232 static const struct cris_opcode **bdapq_m2_prefixes = NULL;
00233 static const struct cris_opcode **bdapq_m4_prefixes = NULL;
00234 static const struct cris_opcode **rest_prefixes = NULL;
00235
00236
00237 if (opc_table == NULL)
00238 {
00239 opc_table = malloc (65536 * sizeof (opc_table[0]));
00240 if (opc_table == NULL)
00241 return NULL;
00242
00243 memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *));
00244
00245 dip_prefixes
00246 = malloc (65536 * sizeof (const struct cris_opcode **));
00247 if (dip_prefixes == NULL)
00248 return NULL;
00249
00250 memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0]));
00251
00252 bdapq_m1_prefixes
00253 = malloc (65536 * sizeof (const struct cris_opcode **));
00254 if (bdapq_m1_prefixes == NULL)
00255 return NULL;
00256
00257 memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0]));
00258
00259 bdapq_m2_prefixes
00260 = malloc (65536 * sizeof (const struct cris_opcode **));
00261 if (bdapq_m2_prefixes == NULL)
00262 return NULL;
00263
00264 memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0]));
00265
00266 bdapq_m4_prefixes
00267 = malloc (65536 * sizeof (const struct cris_opcode **));
00268 if (bdapq_m4_prefixes == NULL)
00269 return NULL;
00270
00271 memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0]));
00272
00273 rest_prefixes
00274 = malloc (65536 * sizeof (const struct cris_opcode **));
00275 if (rest_prefixes == NULL)
00276 return NULL;
00277
00278 memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0]));
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 if (prefix_insn != NO_CRIS_PREFIX)
00288 {
00289 const struct cris_opcode *popcodep
00290 = (opc_table[prefix_insn] != NULL
00291 ? opc_table[prefix_insn]
00292 : get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata));
00293
00294 if (popcodep == NULL)
00295 return NULL;
00296
00297 if (popcodep->match == BDAP_QUICK_OPCODE)
00298 {
00299
00300
00301 int offset = (prefix_insn & 255);
00302
00303 if (offset > 127)
00304 offset -= 256;
00305
00306 switch (offset)
00307 {
00308 case -4:
00309 prefix_opc_table = bdapq_m4_prefixes;
00310 break;
00311
00312 case -2:
00313 prefix_opc_table = bdapq_m2_prefixes;
00314 break;
00315
00316 case -1:
00317 prefix_opc_table = bdapq_m1_prefixes;
00318 break;
00319
00320 default:
00321 prefix_opc_table = rest_prefixes;
00322 break;
00323 }
00324 }
00325 else if (popcodep->match == DIP_OPCODE)
00326
00327
00328 prefix_opc_table = dip_prefixes;
00329 else
00330 prefix_opc_table = rest_prefixes;
00331 }
00332
00333 if (prefix_insn != NO_CRIS_PREFIX
00334 && prefix_opc_table[insn] != NULL)
00335 max_matchedp = prefix_opc_table[insn];
00336 else if (prefix_insn == NO_CRIS_PREFIX && opc_table[insn] != NULL)
00337 max_matchedp = opc_table[insn];
00338 else
00339 {
00340 const struct cris_opcode *opcodep;
00341 int max_level_of_match = -1;
00342
00343 for (opcodep = cris_opcodes;
00344 opcodep->name != NULL;
00345 opcodep++)
00346 {
00347 int level_of_match;
00348
00349 if (disdata->distype == cris_dis_v32)
00350 {
00351 switch (opcodep->applicable_version)
00352 {
00353 case cris_ver_version_all:
00354 break;
00355
00356 case cris_ver_v0_3:
00357 case cris_ver_v0_10:
00358 case cris_ver_v3_10:
00359 case cris_ver_sim_v0_10:
00360 case cris_ver_v8_10:
00361 case cris_ver_v10:
00362 case cris_ver_warning:
00363 continue;
00364
00365 case cris_ver_v3p:
00366 case cris_ver_v8p:
00367 case cris_ver_v10p:
00368 case cris_ver_v32p:
00369 break;
00370
00371 case cris_ver_v8:
00372 abort ();
00373 default:
00374 abort ();
00375 }
00376 }
00377 else
00378 {
00379 switch (opcodep->applicable_version)
00380 {
00381 case cris_ver_version_all:
00382 case cris_ver_v0_3:
00383 case cris_ver_v3p:
00384 case cris_ver_v0_10:
00385 case cris_ver_v8p:
00386 case cris_ver_v8_10:
00387 case cris_ver_v10:
00388 case cris_ver_sim_v0_10:
00389 case cris_ver_v10p:
00390 case cris_ver_warning:
00391 break;
00392
00393 case cris_ver_v32p:
00394 continue;
00395
00396 case cris_ver_v8:
00397 abort ();
00398 default:
00399 abort ();
00400 }
00401 }
00402
00403
00404
00405
00406
00407
00408
00409 if ((opcodep->match & insn) == opcodep->match
00410 && (opcodep->lose & insn) == 0
00411 && ((level_of_match
00412 = cris_constraint (opcodep->args,
00413 insn,
00414 prefix_insn,
00415 disdata))
00416 >= 0)
00417 && ((level_of_match
00418 += 2 * number_of_bits (opcodep->match
00419 | opcodep->lose))
00420 > max_level_of_match))
00421 {
00422 max_matchedp = opcodep;
00423 max_level_of_match = level_of_match;
00424
00425
00426
00427 if (level_of_match >= 2 * 16)
00428 break;
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438 if (prefix_insn == NO_CRIS_PREFIX)
00439 opc_table[insn] = max_matchedp;
00440 else
00441 prefix_opc_table[insn] = max_matchedp;
00442 }
00443
00444 return max_matchedp;
00445 }
00446
00447
00448
00449 static char *
00450 format_hex (number, outbuffer, disdata)
00451 unsigned long number;
00452 char *outbuffer;
00453 struct cris_disasm_data *disdata;
00454 {
00455
00456 number &= 0xffffffff;
00457
00458 sprintf (outbuffer, "0x%lx", number);
00459
00460
00461 if (TRACE_CASE)
00462 last_immediate = number;
00463
00464 return outbuffer + strlen (outbuffer);
00465 }
00466
00467
00468
00469
00470
00471 static char *
00472 format_dec (number, outbuffer, signedp)
00473 long number;
00474 char *outbuffer;
00475 int signedp;
00476 {
00477 last_immediate = number;
00478 sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
00479
00480 return outbuffer + strlen (outbuffer);
00481 }
00482
00483
00484
00485 static char *
00486 format_reg (disdata, regno, outbuffer_start, with_reg_prefix)
00487 struct cris_disasm_data *disdata;
00488 int regno;
00489 char *outbuffer_start;
00490 bfd_boolean with_reg_prefix;
00491 {
00492 char *outbuffer = outbuffer_start;
00493
00494 if (with_reg_prefix)
00495 *outbuffer++ = REGISTER_PREFIX_CHAR;
00496
00497 switch (regno)
00498 {
00499 case 15:
00500
00501 if (disdata->distype == cris_dis_v32)
00502 strcpy (outbuffer, "acr");
00503 else
00504 strcpy (outbuffer, "pc");
00505 break;
00506
00507 case 14:
00508 strcpy (outbuffer, "sp");
00509 break;
00510
00511 default:
00512 sprintf (outbuffer, "r%d", regno);
00513 break;
00514 }
00515
00516 return outbuffer_start + strlen (outbuffer_start);
00517 }
00518
00519
00520
00521 static char *
00522 format_sup_reg (regno, outbuffer_start, with_reg_prefix)
00523 unsigned int regno;
00524 char *outbuffer_start;
00525 bfd_boolean with_reg_prefix;
00526 {
00527 char *outbuffer = outbuffer_start;
00528 int i;
00529
00530 if (with_reg_prefix)
00531 *outbuffer++ = REGISTER_PREFIX_CHAR;
00532
00533 for (i = 0; cris_support_regs[i].name != NULL; i++)
00534 if (cris_support_regs[i].number == regno)
00535 {
00536 sprintf (outbuffer, "%s", cris_support_regs[i].name);
00537 return outbuffer_start + strlen (outbuffer_start);
00538 }
00539
00540
00541
00542 sprintf (outbuffer, "format_sup_reg-BUG");
00543 return outbuffer_start + strlen (outbuffer_start);
00544 }
00545
00546
00547
00548
00549
00550 static int
00551 cris_constraint (cs, insn, prefix_insn, disdata)
00552 const char *cs;
00553 unsigned int insn;
00554 unsigned int prefix_insn;
00555 struct cris_disasm_data *disdata;
00556 {
00557 int retval = 0;
00558 int tmp;
00559 int prefix_ok = 0;
00560
00561 const char *s;
00562 for (s = cs; *s; s++)
00563 switch (*s)
00564 {
00565 case '!':
00566
00567
00568 if (prefix_insn != NO_CRIS_PREFIX
00569 || disdata->distype != cris_dis_v0_v10)
00570 return -1;
00571 break;
00572
00573 case 'U':
00574
00575 return -1;
00576
00577 case 'M':
00578
00579
00580
00581
00582 tmp = ((insn >> 12) & 0xf);
00583 if (tmp != 0 && tmp != 4 && tmp != 8)
00584 return -1;
00585 break;
00586
00587 case 'm':
00588 if ((insn & 0x30) == 0x30)
00589 return -1;
00590 break;
00591
00592 case 'S':
00593
00594 if (prefix_insn != NO_CRIS_PREFIX && (insn & 0x400) == 0)
00595 {
00596 prefix_ok = 1;
00597 break;
00598 }
00599 else
00600 return -1;
00601
00602 case 's':
00603 case 'y':
00604 case 'Y':
00605
00606
00607 if (prefix_insn != NO_CRIS_PREFIX)
00608 {
00609 if (insn & 0x400)
00610 {
00611 const struct cris_opcode *prefix_opcodep
00612 = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
00613
00614 if (prefix_opcodep->match == DIP_OPCODE)
00615 return -1;
00616 }
00617
00618 prefix_ok = 1;
00619 }
00620 break;
00621
00622 case 'B':
00623
00624 prefix_ok = 1;
00625
00626
00627
00628 if (prefix_insn != NO_CRIS_PREFIX)
00629 {
00630
00631 const struct cris_opcode *prefix_opcodep
00632 = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
00633
00634 if (prefix_opcodep->match == BDAP_QUICK_OPCODE)
00635 {
00636 int pushsize = (prefix_insn & 255);
00637
00638 if (pushsize > 127)
00639 pushsize -= 256;
00640
00641 if (s[1] == 'P')
00642 {
00643 unsigned int spec_reg = (insn >> 12) & 15;
00644 const struct cris_spec_reg *sregp
00645 = spec_reg_info (spec_reg, disdata->distype);
00646
00647
00648
00649 if (sregp && sregp->reg_size == (unsigned int) -pushsize)
00650 break;
00651 }
00652 else if (s[1] == 'R')
00653 {
00654 if ((insn & 0x30) == 0x20 && pushsize == -4)
00655 break;
00656 }
00657
00658
00659 }
00660 }
00661 return -1;
00662
00663 case 'D':
00664 retval = (((insn >> 12) & 15) == (insn & 15));
00665 if (!retval)
00666 return -1;
00667 else
00668 retval += 4;
00669 break;
00670
00671 case 'P':
00672 {
00673 const struct cris_spec_reg *sregp
00674 = spec_reg_info ((insn >> 12) & 15, disdata->distype);
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 if (sregp != NULL)
00689 {
00690 retval += 3;
00691 break;
00692 }
00693 else
00694 return -1;
00695 }
00696 }
00697
00698 if (prefix_insn != NO_CRIS_PREFIX && ! prefix_ok)
00699 return -1;
00700
00701 return retval;
00702 }
00703
00704
00705
00706 static unsigned
00707 bytes_to_skip (insn, matchedp, distype)
00708 unsigned int insn;
00709 const struct cris_opcode *matchedp;
00710 enum cris_disass_family distype;
00711 {
00712
00713 unsigned to_skip = 2;
00714 const char *template = matchedp->args;
00715 const char *s;
00716
00717 for (s = template; *s; s++)
00718 if ((*s == 's' || *s == 'N' || *s == 'Y')
00719 && (insn & 0x400) && (insn & 15) == 15)
00720 {
00721
00722
00723 int mode_size = 1 << ((insn >> 4) & (*template == 'z' ? 1 : 3));
00724
00725 if (matchedp->imm_oprnd_size == SIZE_FIX_32)
00726 to_skip += 4;
00727 else if (matchedp->imm_oprnd_size == SIZE_SPEC_REG)
00728 {
00729 const struct cris_spec_reg *sregp
00730 = spec_reg_info ((insn >> 12) & 15, distype);
00731
00732
00733
00734 if (sregp == NULL)
00735 return 2;
00736
00737
00738
00739
00740 to_skip +=
00741 distype == cris_dis_v32 ? 4 : (sregp->reg_size + 1) & ~1;
00742 }
00743 else
00744 to_skip += (mode_size + 1) & ~1;
00745 }
00746 else if (*s == 'n')
00747 to_skip += 4;
00748 else if (*s == 'b')
00749 to_skip += 2;
00750
00751 return to_skip;
00752 }
00753
00754
00755
00756 static char *
00757 print_flags (disdata, insn, cp)
00758 struct cris_disasm_data *disdata;
00759 unsigned int insn;
00760 char *cp;
00761 {
00762
00763
00764
00765
00766
00767 static const char v8_fnames[] = "cvznxibm";
00768 static const char v32_fnames[] = "cvznxiup";
00769 const char *fnames
00770 = disdata->distype == cris_dis_v32 ? v32_fnames : v8_fnames;
00771
00772 unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));
00773 int i;
00774
00775 for (i = 0; i < 8; i++)
00776 if (flagbits & (1 << i))
00777 *cp++ = fnames[i];
00778
00779 return cp;
00780 }
00781
00782
00783
00784
00785
00786 static void
00787 print_with_operands (opcodep, insn, buffer, addr, info, prefix_opcodep,
00788 prefix_insn, prefix_buffer, with_reg_prefix)
00789 const struct cris_opcode *opcodep;
00790 unsigned int insn;
00791 unsigned char *buffer;
00792 bfd_vma addr;
00793 disassemble_info *info;
00794
00795
00796
00797 const struct cris_opcode *prefix_opcodep;
00798 unsigned int prefix_insn;
00799 unsigned char *prefix_buffer;
00800 bfd_boolean with_reg_prefix;
00801 {
00802
00803
00804 char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
00805 char *tp = temp;
00806 static const char mode_char[] = "bwd?";
00807 const char *s;
00808 const char *cs;
00809 struct cris_disasm_data *disdata
00810 = (struct cris_disasm_data *) info->private_data;
00811
00812
00813 (*info->fprintf_func) (info->stream, "%s", opcodep->name);
00814
00815 cs = opcodep->args;
00816 s = cs;
00817
00818
00819 if (*s == 'p')
00820 s++;
00821
00822 if (*s == 'm' || *s == 'M' || *s == 'z')
00823 {
00824 *tp++ = '.';
00825
00826
00827 *tp++ = *s == 'M'
00828 ? (insn & 0x8000 ? 'd'
00829 : insn & 0x4000 ? 'w' : 'b')
00830 : mode_char[(insn >> 4) & (*s == 'z' ? 1 : 3)];
00831
00832
00833 s += 2;
00834 }
00835
00836
00837
00838 if (opcodep->match != (BRANCH_PC_LOW + BRANCH_INCR_HIGH * 256))
00839 *tp++ = ' ';
00840
00841
00842
00843 if (opcodep->name[0] == 'j')
00844 {
00845 if (strncmp (opcodep->name, "jsr", 3) == 0)
00846
00847 info->insn_type = dis_jsr;
00848 else
00849
00850 info->insn_type = dis_branch;
00851 }
00852
00853
00854 info->branch_delay_insns = opcodep->delayed;
00855
00856
00857 for (; *s; s++)
00858 {
00859 switch (*s)
00860 {
00861 case 'T':
00862 tp = format_sup_reg ((insn >> 12) & 15, tp, with_reg_prefix);
00863 break;
00864
00865 case 'A':
00866 if (with_reg_prefix)
00867 *tp++ = REGISTER_PREFIX_CHAR;
00868 *tp++ = 'a';
00869 *tp++ = 'c';
00870 *tp++ = 'r';
00871 break;
00872
00873 case '[':
00874 case ']':
00875 case ',':
00876 *tp++ = *s;
00877 break;
00878
00879 case '!':
00880
00881
00882
00883 break;
00884
00885 case 'd':
00886
00887
00888 break;
00889
00890 case 'B':
00891
00892
00893
00894 prefix_opcodep = NULL;
00895 break;
00896
00897 case 'D':
00898 case 'r':
00899 tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
00900 break;
00901
00902 case 'R':
00903 tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
00904 break;
00905
00906 case 'n':
00907 {
00908
00909 unsigned long number
00910 = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536
00911 + buffer[5] * 0x1000000 + addr);
00912
00913
00914 *tp = 0;
00915 if (temp[0])
00916 (*info->fprintf_func) (info->stream, "%s", temp);
00917 tp = temp;
00918
00919 (*info->print_address_func) ((bfd_vma) number, info);
00920 }
00921 break;
00922
00923 case 'u':
00924 {
00925
00926 unsigned long number = (buffer[0] & 0xf) * 2 + addr;
00927
00928
00929 *tp = 0;
00930 if (temp[0])
00931 (*info->fprintf_func) (info->stream, "%s", temp);
00932 tp = temp;
00933
00934 (*info->print_address_func) ((bfd_vma) number, info);
00935 }
00936 break;
00937
00938 case 'N':
00939 case 'y':
00940 case 'Y':
00941 case 'S':
00942 case 's':
00943
00944 if ((insn & 0x400) && (insn & 15) == 15)
00945 {
00946
00947
00948 long number;
00949 int signedp
00950 = ((*cs == 'z' && (insn & 0x20))
00951 || opcodep->match == BDAP_QUICK_OPCODE);
00952 int nbytes;
00953
00954 if (opcodep->imm_oprnd_size == SIZE_FIX_32)
00955 nbytes = 4;
00956 else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
00957 {
00958 const struct cris_spec_reg *sregp
00959 = spec_reg_info ((insn >> 12) & 15, disdata->distype);
00960
00961
00962
00963
00964 if (sregp == NULL)
00965
00966 nbytes = 42;
00967 else
00968
00969
00970
00971 nbytes = disdata->distype == cris_dis_v32
00972 ? 4 : (sregp->reg_size + 1) & ~1;
00973 }
00974 else
00975 {
00976 int mode_size = 1 << ((insn >> 4) & (*cs == 'z' ? 1 : 3));
00977
00978 if (mode_size == 1)
00979 nbytes = 2;
00980 else
00981 nbytes = mode_size;
00982 }
00983
00984 switch (nbytes)
00985 {
00986 case 1:
00987 number = buffer[2];
00988 if (signedp && number > 127)
00989 number -= 256;
00990 break;
00991
00992 case 2:
00993 number = buffer[2] + buffer[3] * 256;
00994 if (signedp && number > 32767)
00995 number -= 65536;
00996 break;
00997
00998 case 4:
00999 number
01000 = buffer[2] + buffer[3] * 256 + buffer[4] * 65536
01001 + buffer[5] * 0x1000000;
01002 break;
01003
01004 default:
01005 strcpy (tp, "bug");
01006 tp += 3;
01007 number = 42;
01008 }
01009
01010 if ((*cs == 'z' && (insn & 0x20))
01011 || (opcodep->match == BDAP_QUICK_OPCODE
01012 && (nbytes <= 2 || buffer[1 + nbytes] == 0)))
01013 tp = format_dec (number, tp, signedp);
01014 else
01015 {
01016 unsigned int highbyte = (number >> 24) & 0xff;
01017
01018
01019
01020
01021
01022
01023 if (nbytes == 4
01024 && (highbyte == ((addr >> 24) & 0xff)
01025 || (highbyte != 0 && highbyte != 0xff)
01026 || info->insn_type == dis_branch
01027 || info->insn_type == dis_jsr))
01028 {
01029
01030 *tp = 0;
01031 tp = temp;
01032 if (temp[0])
01033 (*info->fprintf_func) (info->stream, "%s", temp);
01034
01035 (*info->print_address_func) ((bfd_vma) number, info);
01036
01037 info->target = number;
01038 }
01039 else
01040 tp = format_hex (number, tp, disdata);
01041 }
01042 }
01043 else
01044 {
01045
01046
01047 if (info->insn_type != dis_nonbranch)
01048 {
01049 int mode_size
01050 = 1 << ((insn >> 4)
01051 & (opcodep->args[0] == 'z' ? 1 : 3));
01052 int size;
01053 info->insn_type = dis_dref;
01054 info->flags |= CRIS_DIS_FLAG_MEMREF;
01055
01056 if (opcodep->imm_oprnd_size == SIZE_FIX_32)
01057 size = 4;
01058 else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
01059 {
01060 const struct cris_spec_reg *sregp
01061 = spec_reg_info ((insn >> 12) & 15, disdata->distype);
01062
01063
01064
01065 if (sregp == NULL)
01066 size = 4;
01067 else
01068 size = sregp->reg_size;
01069 }
01070 else
01071 size = mode_size;
01072
01073 info->data_size = size;
01074 }
01075
01076 *tp++ = '[';
01077
01078 if (prefix_opcodep
01079
01080
01081 && ((insn & 0x400) == 0
01082 || prefix_opcodep->match != DIP_OPCODE))
01083 {
01084 if (insn & 0x400)
01085 {
01086 tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
01087 *tp++ = '=';
01088 }
01089
01090
01091
01092
01093 switch (prefix_opcodep->match)
01094 {
01095 case DIP_OPCODE:
01096
01097 if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
01098 {
01099
01100
01101 unsigned long number
01102 = prefix_buffer[2] + prefix_buffer[3] * 256
01103 + prefix_buffer[4] * 65536
01104 + prefix_buffer[5] * 0x1000000;
01105
01106 info->target = (bfd_vma) number;
01107
01108
01109
01110 *tp = 0;
01111 tp = temp;
01112 if (temp[0])
01113 (*info->fprintf_func) (info->stream, "%s", temp);
01114
01115 (*info->print_address_func) ((bfd_vma) number, info);
01116 }
01117 else
01118 {
01119
01120
01121 info->flags
01122 |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
01123 | CRIS_DIS_FLAG_MEM_TARGET2_MEM);
01124
01125 info->target2 = prefix_insn & 15;
01126
01127 *tp++ = '[';
01128 tp = format_reg (disdata, prefix_insn & 15, tp,
01129 with_reg_prefix);
01130 if (prefix_insn & 0x400)
01131 *tp++ = '+';
01132 *tp++ = ']';
01133 }
01134 break;
01135
01136 case BDAP_QUICK_OPCODE:
01137 {
01138 int number;
01139
01140 number = prefix_buffer[0];
01141 if (number > 127)
01142 number -= 256;
01143
01144
01145 tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
01146 with_reg_prefix);
01147 if (number >= 0)
01148 *tp++ = '+';
01149 tp = format_dec (number, tp, 1);
01150
01151 info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
01152 info->target = (prefix_insn >> 12) & 15;
01153 info->target2 = (bfd_vma) number;
01154 break;
01155 }
01156
01157 case BIAP_OPCODE:
01158
01159 tp = format_reg (disdata, prefix_insn & 15, tp,
01160 with_reg_prefix);
01161 *tp++ = '+';
01162 tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
01163 with_reg_prefix);
01164 *tp++ = '.';
01165 *tp++ = mode_char[(prefix_insn >> 4) & 3];
01166
01167 info->flags
01168 |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
01169 | CRIS_DIS_FLAG_MEM_TARGET_IS_REG
01170
01171 | ((prefix_insn & 0x8000)
01172 ? CRIS_DIS_FLAG_MEM_TARGET2_MULT4
01173 : ((prefix_insn & 0x8000)
01174 ? CRIS_DIS_FLAG_MEM_TARGET2_MULT2 : 0)));
01175
01176
01177 if (insn == 0xf83f && (prefix_insn & ~0xf000) == 0x55f)
01178
01179 case_offset_counter = no_of_case_offsets;
01180 break;
01181
01182 case BDAP_INDIR_OPCODE:
01183
01184
01185 tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
01186 with_reg_prefix);
01187
01188 if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
01189 {
01190 long number;
01191 unsigned int nbytes;
01192
01193
01194 int mode_size = 1 << ((prefix_insn >> 4) & 3);
01195
01196 if (mode_size == 1)
01197 nbytes = 2;
01198 else
01199 nbytes = mode_size;
01200
01201 switch (nbytes)
01202 {
01203 case 1:
01204 number = prefix_buffer[2];
01205 if (number > 127)
01206 number -= 256;
01207 break;
01208
01209 case 2:
01210 number = prefix_buffer[2] + prefix_buffer[3] * 256;
01211 if (number > 32767)
01212 number -= 65536;
01213 break;
01214
01215 case 4:
01216 number
01217 = prefix_buffer[2] + prefix_buffer[3] * 256
01218 + prefix_buffer[4] * 65536
01219 + prefix_buffer[5] * 0x1000000;
01220 break;
01221
01222 default:
01223 strcpy (tp, "bug");
01224 tp += 3;
01225 number = 42;
01226 }
01227
01228 info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
01229 info->target2 = (bfd_vma) number;
01230
01231
01232
01233 if (nbytes == 4)
01234 {
01235
01236
01237 *tp++ = '+';
01238 *tp = 0;
01239 tp = temp;
01240 (*info->fprintf_func) (info->stream, "%s", temp);
01241
01242 (*info->print_address_func) ((bfd_vma) number, info);
01243 }
01244 else
01245 {
01246 if (number >= 0)
01247 *tp++ = '+';
01248 tp = format_dec (number, tp, 1);
01249 }
01250 }
01251 else
01252 {
01253
01254 *tp++ = '+';
01255 *tp++ = '[';
01256 tp = format_reg (disdata, prefix_insn & 15, tp,
01257 with_reg_prefix);
01258 if (prefix_insn & 0x400)
01259 *tp++ = '+';
01260 *tp++ = ']';
01261 *tp++ = '.';
01262 *tp++ = mode_char[(prefix_insn >> 4) & 3];
01263
01264 info->flags
01265 |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
01266 | CRIS_DIS_FLAG_MEM_TARGET2_MEM
01267 | CRIS_DIS_FLAG_MEM_TARGET_IS_REG
01268
01269 | (((prefix_insn >> 4) == 2)
01270 ? 0
01271 : (((prefix_insn >> 4) & 3) == 1
01272 ? CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD
01273 : CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE)));
01274 }
01275 break;
01276
01277 default:
01278 (*info->fprintf_func) (info->stream, "?prefix-bug");
01279 }
01280
01281
01282 prefix_opcodep = NULL;
01283 }
01284 else
01285 {
01286 tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
01287
01288 info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
01289 info->target = insn & 15;
01290
01291 if (insn & 0x400)
01292 *tp++ = '+';
01293 }
01294 *tp++ = ']';
01295 }
01296 break;
01297
01298 case 'x':
01299 tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
01300 *tp++ = '.';
01301 *tp++ = mode_char[(insn >> 4) & 3];
01302 break;
01303
01304 case 'I':
01305 tp = format_dec (insn & 63, tp, 0);
01306 break;
01307
01308 case 'b':
01309 {
01310 int where = buffer[2] + buffer[3] * 256;
01311
01312 if (where > 32767)
01313 where -= 65536;
01314
01315 where += addr + ((disdata->distype == cris_dis_v32) ? 0 : 4);
01316
01317 if (insn == BA_PC_INCR_OPCODE)
01318 info->insn_type = dis_branch;
01319 else
01320 info->insn_type = dis_condbranch;
01321
01322 info->target = (bfd_vma) where;
01323
01324 *tp = 0;
01325 tp = temp;
01326 (*info->fprintf_func) (info->stream, "%s%s ",
01327 temp, cris_cc_strings[insn >> 12]);
01328
01329 (*info->print_address_func) ((bfd_vma) where, info);
01330 }
01331 break;
01332
01333 case 'c':
01334 tp = format_dec (insn & 31, tp, 0);
01335 break;
01336
01337 case 'C':
01338 tp = format_dec (insn & 15, tp, 0);
01339 break;
01340
01341 case 'o':
01342 {
01343 long offset = insn & 0xfe;
01344 bfd_vma target;
01345
01346 if (insn & 1)
01347 offset |= ~0xff;
01348
01349 if (opcodep->match == BA_QUICK_OPCODE)
01350 info->insn_type = dis_branch;
01351 else
01352 info->insn_type = dis_condbranch;
01353
01354 target = addr + ((disdata->distype == cris_dis_v32) ? 0 : 2) + offset;
01355 info->target = target;
01356 *tp = 0;
01357 tp = temp;
01358 (*info->fprintf_func) (info->stream, "%s", temp);
01359 (*info->print_address_func) (target, info);
01360 }
01361 break;
01362
01363 case 'Q':
01364 case 'O':
01365 {
01366 long number = buffer[0];
01367
01368 if (number > 127)
01369 number = number - 256;
01370
01371 tp = format_dec (number, tp, 1);
01372 *tp++ = ',';
01373 tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
01374 }
01375 break;
01376
01377 case 'f':
01378 tp = print_flags (disdata, insn, tp);
01379 break;
01380
01381 case 'i':
01382 tp = format_dec ((insn & 32) ? (insn & 31) | ~31 : insn & 31, tp, 1);
01383 break;
01384
01385 case 'P':
01386 {
01387 const struct cris_spec_reg *sregp
01388 = spec_reg_info ((insn >> 12) & 15, disdata->distype);
01389
01390 if (sregp->name == NULL)
01391
01392 *tp++ = '?';
01393 else
01394 {
01395 if (with_reg_prefix)
01396 *tp++ = REGISTER_PREFIX_CHAR;
01397 strcpy (tp, sregp->name);
01398 tp += strlen (tp);
01399 }
01400 }
01401 break;
01402
01403 default:
01404 strcpy (tp, "???");
01405 tp += 3;
01406 }
01407 }
01408
01409 *tp = 0;
01410
01411 if (prefix_opcodep)
01412 (*info->fprintf_func) (info->stream, " (OOPS unused prefix \"%s: %s\")",
01413 prefix_opcodep->name, prefix_opcodep->args);
01414
01415 (*info->fprintf_func) (info->stream, "%s", temp);
01416
01417
01418
01419
01420 if (TRACE_CASE && case_offset_counter == 0)
01421 {
01422 if (strncmp (opcodep->name, "sub", 3) == 0)
01423 case_offset = last_immediate;
01424
01425
01426 else if (strncmp (opcodep->name, "add", 3) == 0)
01427 {
01428
01429 case_offset = -last_immediate;
01430 }
01431
01432 else if (strncmp (opcodep->name, "bound", 5) == 0)
01433 {
01434 no_of_case_offsets = last_immediate + 1;
01435 }
01436
01437
01438 else if (info->insn_type == dis_jsr
01439 || info->insn_type == dis_branch
01440 || info->insn_type == dis_condbranch)
01441 case_offset = 0;
01442 }
01443 }
01444
01445
01446
01447
01448
01449
01450 static int
01451 print_insn_cris_generic (memaddr, info, with_reg_prefix)
01452 bfd_vma memaddr;
01453 disassemble_info *info;
01454 bfd_boolean with_reg_prefix;
01455 {
01456 int nbytes;
01457 unsigned int insn;
01458 const struct cris_opcode *matchedp;
01459 int advance = 0;
01460 struct cris_disasm_data *disdata
01461 = (struct cris_disasm_data *) info->private_data;
01462
01463
01464
01465 unsigned char buffer[MAX_BYTES_PER_CRIS_INSN];
01466 unsigned char *bufp;
01467 int status = 0;
01468 bfd_vma addr;
01469
01470
01471
01472
01473
01474
01475
01476
01477 for (nbytes = MAX_BYTES_PER_CRIS_INSN; nbytes > 0; nbytes -= 2)
01478 {
01479 status = (*info->read_memory_func) (memaddr, buffer, nbytes, info);
01480 if (status == 0)
01481 break;
01482 }
01483
01484
01485
01486 if (nbytes != MAX_BYTES_PER_CRIS_INSN)
01487 memset (buffer + nbytes, 0, MAX_BYTES_PER_CRIS_INSN - nbytes);
01488
01489 addr = memaddr;
01490 bufp = buffer;
01491
01492
01493 info->insn_info_valid = 1;
01494 info->branch_delay_insns = 0;
01495 info->data_size = 0;
01496 info->insn_type = dis_nonbranch;
01497 info->flags = 0;
01498 info->target = 0;
01499 info->target2 = 0;
01500
01501
01502 if (nbytes != 0)
01503 {
01504 matchedp = NULL;
01505
01506 insn = bufp[0] + bufp[1] * 256;
01507
01508
01509 if (TRACE_CASE && case_offset_counter != 0)
01510 {
01511 info->insn_type = dis_noninsn;
01512 advance += 2;
01513
01514
01515 (*info->fprintf_func) (info->stream, "case %d%s: -> ",
01516 case_offset + no_of_case_offsets
01517 - case_offset_counter,
01518 case_offset_counter == 1 ? "/default" :
01519 "");
01520
01521 (*info->print_address_func) ((bfd_vma)
01522 ((short) (insn)
01523 + (long) (addr
01524 - (no_of_case_offsets
01525 - case_offset_counter)
01526 * 2)), info);
01527 case_offset_counter--;
01528
01529
01530
01531 if (case_offset_counter == 0)
01532 case_offset = 0;
01533 }
01534 else if (insn == 0)
01535 {
01536
01537
01538
01539
01540 (*info->fprintf_func) (info->stream,
01541 disdata->distype == cris_dis_v32
01542 ? "bcc ." : "bcc .+2");
01543 info->insn_type = dis_noninsn;
01544 advance += 2;
01545 }
01546 else
01547 {
01548 const struct cris_opcode *prefix_opcodep = NULL;
01549 unsigned char *prefix_buffer = bufp;
01550 unsigned int prefix_insn = insn;
01551 int prefix_size = 0;
01552
01553 matchedp = get_opcode_entry (insn, NO_CRIS_PREFIX, disdata);
01554
01555
01556
01557 if (matchedp != NULL && PARSE_PREFIX && matchedp->args[0] == 'p')
01558 {
01559
01560
01561 prefix_size = bytes_to_skip (prefix_insn, matchedp,
01562 disdata->distype);
01563 prefix_opcodep = matchedp;
01564
01565 insn = bufp[prefix_size] + bufp[prefix_size + 1] * 256;
01566 matchedp = get_opcode_entry (insn, prefix_insn, disdata);
01567
01568 if (matchedp != NULL)
01569 {
01570 addr += prefix_size;
01571 bufp += prefix_size;
01572 advance += prefix_size;
01573 }
01574 else
01575 {
01576
01577
01578
01579 matchedp = prefix_opcodep;
01580 insn = prefix_insn;
01581 prefix_opcodep = NULL;
01582 }
01583 }
01584
01585 if (matchedp == NULL)
01586 {
01587 (*info->fprintf_func) (info->stream, "??0x%lx", insn);
01588 advance += 2;
01589
01590 info->insn_type = dis_noninsn;
01591 }
01592 else
01593 {
01594 advance += bytes_to_skip (insn, matchedp, disdata->distype);
01595
01596
01597
01598 print_with_operands (matchedp, insn, bufp, addr, info,
01599 prefix_opcodep, prefix_insn,
01600 prefix_buffer, with_reg_prefix);
01601 }
01602 }
01603 }
01604 else
01605 info->insn_type = dis_noninsn;
01606
01607
01608
01609
01610 if (status != 0 && (nbytes == 0 || advance > nbytes))
01611 {
01612 (*info->memory_error_func) (status, memaddr, info);
01613 return -1;
01614 }
01615
01616
01617 info->bytes_per_line = MAX_BYTES_PER_CRIS_INSN;
01618
01619
01620
01621
01622
01623 info->bytes_per_chunk = 2;
01624
01625
01626
01627
01628
01629
01630 info->display_endian = BFD_ENDIAN_BIG;
01631
01632 return advance;
01633 }
01634
01635
01636
01637 static int
01638 print_insn_cris_with_register_prefix (vma, info)
01639 bfd_vma vma;
01640 disassemble_info *info;
01641 {
01642 if (info->private_data == NULL
01643 && !cris_parse_disassembler_options (info, cris_dis_v0_v10))
01644 return -1;
01645 return print_insn_cris_generic (vma, info, TRUE);
01646 }
01647
01648
01649
01650 static int
01651 print_insn_crisv32_with_register_prefix (vma, info)
01652 bfd_vma vma;
01653 disassemble_info *info;
01654 {
01655 if (info->private_data == NULL
01656 && !cris_parse_disassembler_options (info, cris_dis_v32))
01657 return -1;
01658 return print_insn_cris_generic (vma, info, TRUE);
01659 }
01660
01661
01662
01663
01664 static int
01665 print_insn_crisv10_v32_with_register_prefix (vma, info)
01666 bfd_vma vma;
01667 disassemble_info *info;
01668 {
01669 if (info->private_data == NULL
01670 && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32))
01671 return -1;
01672 return print_insn_cris_generic (vma, info, TRUE);
01673 }
01674
01675
01676
01677 static int
01678 print_insn_cris_without_register_prefix (vma, info)
01679 bfd_vma vma;
01680 disassemble_info *info;
01681 {
01682 if (info->private_data == NULL
01683 && !cris_parse_disassembler_options (info, cris_dis_v0_v10))
01684 return -1;
01685 return print_insn_cris_generic (vma, info, FALSE);
01686 }
01687
01688
01689
01690 static int
01691 print_insn_crisv32_without_register_prefix (vma, info)
01692 bfd_vma vma;
01693 disassemble_info *info;
01694 {
01695 if (info->private_data == NULL
01696 && !cris_parse_disassembler_options (info, cris_dis_v32))
01697 return -1;
01698 return print_insn_cris_generic (vma, info, FALSE);
01699 }
01700
01701
01702
01703
01704 static int
01705 print_insn_crisv10_v32_without_register_prefix (vma, info)
01706 bfd_vma vma;
01707 disassemble_info *info;
01708 {
01709 if (info->private_data == NULL
01710 && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32))
01711 return -1;
01712 return print_insn_cris_generic (vma, info, FALSE);
01713 }
01714
01715
01716
01717
01718
01719
01720 disassembler_ftype
01721 cris_get_disassembler (abfd)
01722 bfd *abfd;
01723 {
01724
01725
01726
01727 if (abfd == NULL)
01728 return print_insn_cris_with_register_prefix;
01729
01730 if (bfd_get_symbol_leading_char (abfd) == 0)
01731 {
01732 if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
01733 return print_insn_crisv32_with_register_prefix;
01734 if (bfd_get_mach (abfd) == bfd_mach_cris_v10_v32)
01735 return print_insn_crisv10_v32_with_register_prefix;
01736
01737
01738
01739 return print_insn_cris_with_register_prefix;
01740 }
01741
01742 if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
01743 return print_insn_crisv32_without_register_prefix;
01744 if (bfd_get_mach (abfd) == bfd_mach_cris_v10_v32)
01745 return print_insn_crisv10_v32_without_register_prefix;
01746 return print_insn_cris_without_register_prefix;
01747 }
01748
01749
01750
01751
01752
01753
01754