00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024
00025 #include "sysdep.h"
00026 #include "opcode/sparc.h"
00027 #include "dis-asm.h"
00028 #include "libiberty.h"
00029 #include "opintl.h"
00030
00031
00032 #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
00033 | (1 << SPARC_OPCODE_ARCH_V9A) \
00034 | (1 << SPARC_OPCODE_ARCH_V9B))
00035
00036 #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
00037
00038 #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
00039
00040
00041 static const struct sparc_opcode **sorted_opcodes;
00042
00043
00044
00045
00046 #define HASH_SIZE 256
00047
00048
00049
00050 static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
00051 #define HASH_INSN(INSN) \
00052 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
00053 struct opcode_hash
00054 {
00055 struct opcode_hash *next;
00056 const struct sparc_opcode *opcode;
00057 };
00058 static struct opcode_hash *opcode_hash_table[HASH_SIZE];
00059
00060 static void build_hash_table
00061 PARAMS ((const struct sparc_opcode **, struct opcode_hash **, int));
00062 static int is_delayed_branch PARAMS ((unsigned long));
00063 static int compare_opcodes PARAMS ((const PTR, const PTR));
00064 static int compute_arch_mask PARAMS ((unsigned long));
00065
00066
00067 #define SEX(value, bits) \
00068 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
00069 >> ((8 * sizeof (int)) - bits) )
00070
00071 static char *reg_names[] =
00072 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
00073 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
00074 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
00075 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
00076 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
00077 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00078 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
00079 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
00080 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
00081 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
00082 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
00083 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
00084
00085 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
00086 };
00087
00088 #define freg_names (®_names[4 * 8])
00089
00090
00091
00092 static char *v9_priv_reg_names[] =
00093 {
00094 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
00095 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
00096 "wstate", "fq"
00097
00098 };
00099
00100
00101
00102 static char *v9a_asr_reg_names[] =
00103 {
00104 "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
00105 "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr"
00106 };
00107
00108
00109
00110
00111 #define X_RD(i) (((i) >> 25) & 0x1f)
00112 #define X_RS1(i) (((i) >> 14) & 0x1f)
00113 #define X_LDST_I(i) (((i) >> 13) & 1)
00114 #define X_ASI(i) (((i) >> 5) & 0xff)
00115 #define X_RS2(i) (((i) >> 0) & 0x1f)
00116 #define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
00117 #define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
00118 #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
00119 #define X_IMM22(i) X_DISP22 (i)
00120 #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
00121
00122
00123 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
00124 #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
00125 #define X_MEMBAR(i) ((i) & 0x7f)
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 static int
00189 is_delayed_branch (insn)
00190 unsigned long insn;
00191 {
00192 struct opcode_hash *op;
00193
00194 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
00195 {
00196 const struct sparc_opcode *opcode = op->opcode;
00197 if ((opcode->match & insn) == opcode->match
00198 && (opcode->lose & insn) == 0)
00199 return (opcode->flags & F_DELAYED);
00200 }
00201 return 0;
00202 }
00203
00204
00205
00206
00207
00208 static unsigned int current_arch_mask;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 int
00219 print_insn_sparc (memaddr, info)
00220 bfd_vma memaddr;
00221 disassemble_info *info;
00222 {
00223 FILE *stream = info->stream;
00224 bfd_byte buffer[4];
00225 unsigned long insn;
00226 register struct opcode_hash *op;
00227
00228 static int opcodes_initialized = 0;
00229
00230 static unsigned long current_mach = 0;
00231 bfd_vma (*getword) (const void *);
00232
00233 if (!opcodes_initialized
00234 || info->mach != current_mach)
00235 {
00236 int i;
00237
00238 current_arch_mask = compute_arch_mask (info->mach);
00239
00240 if (!opcodes_initialized)
00241 sorted_opcodes = (const struct sparc_opcode **)
00242 xmalloc (sparc_num_opcodes * sizeof (struct sparc_opcode *));
00243
00244 for (i = 0; i < sparc_num_opcodes; ++i)
00245 sorted_opcodes[i] = &sparc_opcodes[i];
00246 qsort ((char *) sorted_opcodes, sparc_num_opcodes,
00247 sizeof (sorted_opcodes[0]), compare_opcodes);
00248
00249 build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
00250 current_mach = info->mach;
00251 opcodes_initialized = 1;
00252 }
00253
00254 {
00255 int status =
00256 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
00257 if (status != 0)
00258 {
00259 (*info->memory_error_func) (status, memaddr, info);
00260 return -1;
00261 }
00262 }
00263
00264
00265
00266 if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
00267 getword = bfd_getb32;
00268 else
00269 getword = bfd_getl32;
00270
00271 insn = getword (buffer);
00272
00273 info->insn_info_valid = 1;
00274 info->insn_type = dis_nonbranch;
00275 info->branch_delay_insns = 0;
00276 info->target = 0;
00277
00278 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
00279 {
00280 const struct sparc_opcode *opcode = op->opcode;
00281
00282
00283 if (! (opcode->architecture & current_arch_mask))
00284 continue;
00285
00286 if ((opcode->match & insn) == opcode->match
00287 && (opcode->lose & insn) == 0)
00288 {
00289
00290
00291 int imm_added_to_rs1 = 0;
00292 int imm_ored_to_rs1 = 0;
00293
00294
00295
00296 int found_plus = 0;
00297
00298
00299 int is_annulled = 0;
00300
00301
00302
00303 if (opcode->match == 0x80102000)
00304 imm_ored_to_rs1 = 1;
00305 if (opcode->match == 0x80002000)
00306 imm_added_to_rs1 = 1;
00307
00308 if (X_RS1 (insn) != X_RD (insn)
00309 && strchr (opcode->args, 'r') != 0)
00310
00311 continue;
00312 if (X_RS2 (insn) != X_RD (insn)
00313 && strchr (opcode->args, 'O') != 0)
00314
00315 continue;
00316
00317 (*info->fprintf_func) (stream, opcode->name);
00318
00319 {
00320 register const char *s;
00321
00322 if (opcode->args[0] != ',')
00323 (*info->fprintf_func) (stream, " ");
00324
00325 for (s = opcode->args; *s != '\0'; ++s)
00326 {
00327 while (*s == ',')
00328 {
00329 (*info->fprintf_func) (stream, ",");
00330 ++s;
00331 switch (*s)
00332 {
00333 case 'a':
00334 (*info->fprintf_func) (stream, "a");
00335 is_annulled = 1;
00336 ++s;
00337 continue;
00338 case 'N':
00339 (*info->fprintf_func) (stream, "pn");
00340 ++s;
00341 continue;
00342
00343 case 'T':
00344 (*info->fprintf_func) (stream, "pt");
00345 ++s;
00346 continue;
00347
00348 default:
00349 break;
00350 }
00351 }
00352
00353 (*info->fprintf_func) (stream, " ");
00354
00355 switch (*s)
00356 {
00357 case '+':
00358 found_plus = 1;
00359
00360
00361 default:
00362 (*info->fprintf_func) (stream, "%c", *s);
00363 break;
00364
00365 case '#':
00366 (*info->fprintf_func) (stream, "0");
00367 break;
00368
00369 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
00370 case '1':
00371 case 'r':
00372 reg (X_RS1 (insn));
00373 break;
00374
00375 case '2':
00376 case 'O':
00377 reg (X_RS2 (insn));
00378 break;
00379
00380 case 'd':
00381 reg (X_RD (insn));
00382 break;
00383 #undef reg
00384
00385 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
00386 #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
00387 case 'e':
00388 freg (X_RS1 (insn));
00389 break;
00390 case 'v':
00391 case 'V':
00392 fregx (X_RS1 (insn));
00393 break;
00394
00395 case 'f':
00396 freg (X_RS2 (insn));
00397 break;
00398 case 'B':
00399 case 'R':
00400 fregx (X_RS2 (insn));
00401 break;
00402
00403 case 'g':
00404 freg (X_RD (insn));
00405 break;
00406 case 'H':
00407 case 'J':
00408 fregx (X_RD (insn));
00409 break;
00410 #undef freg
00411 #undef fregx
00412
00413 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
00414 case 'b':
00415 creg (X_RS1 (insn));
00416 break;
00417
00418 case 'c':
00419 creg (X_RS2 (insn));
00420 break;
00421
00422 case 'D':
00423 creg (X_RD (insn));
00424 break;
00425 #undef creg
00426
00427 case 'h':
00428 (*info->fprintf_func) (stream, "%%hi(%#x)",
00429 ((unsigned) 0xFFFFFFFF
00430 & ((int) X_IMM22 (insn) << 10)));
00431 break;
00432
00433 case 'i':
00434 case 'I':
00435 case 'j':
00436 {
00437 int imm;
00438
00439 if (*s == 'i')
00440 imm = X_SIMM (insn, 13);
00441 else if (*s == 'I')
00442 imm = X_SIMM (insn, 11);
00443 else
00444 imm = X_SIMM (insn, 10);
00445
00446
00447
00448
00449
00450
00451
00452
00453 if (found_plus)
00454 imm_added_to_rs1 = 1;
00455
00456 if (imm <= 9)
00457 (*info->fprintf_func) (stream, "%d", imm);
00458 else
00459 (*info->fprintf_func) (stream, "%#x", imm);
00460 }
00461 break;
00462
00463 case 'X':
00464 case 'Y':
00465 {
00466 int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
00467
00468 if (imm <= 9)
00469 (info->fprintf_func) (stream, "%d", imm);
00470 else
00471 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
00472 }
00473 break;
00474
00475 case '3':
00476 (info->fprintf_func) (stream, "%d", X_IMM (insn, 3));
00477 break;
00478
00479 case 'K':
00480 {
00481 int mask = X_MEMBAR (insn);
00482 int bit = 0x40, printed_one = 0;
00483 const char *name;
00484
00485 if (mask == 0)
00486 (info->fprintf_func) (stream, "0");
00487 else
00488 while (bit)
00489 {
00490 if (mask & bit)
00491 {
00492 if (printed_one)
00493 (info->fprintf_func) (stream, "|");
00494 name = sparc_decode_membar (bit);
00495 (info->fprintf_func) (stream, "%s", name);
00496 printed_one = 1;
00497 }
00498 bit >>= 1;
00499 }
00500 break;
00501 }
00502
00503 case 'k':
00504 info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
00505 (*info->print_address_func) (info->target, info);
00506 break;
00507
00508 case 'G':
00509 info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
00510 (*info->print_address_func) (info->target, info);
00511 break;
00512
00513 case '6':
00514 case '7':
00515 case '8':
00516 case '9':
00517 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
00518 break;
00519
00520 case 'z':
00521 (*info->fprintf_func) (stream, "%%icc");
00522 break;
00523
00524 case 'Z':
00525 (*info->fprintf_func) (stream, "%%xcc");
00526 break;
00527
00528 case 'E':
00529 (*info->fprintf_func) (stream, "%%ccr");
00530 break;
00531
00532 case 's':
00533 (*info->fprintf_func) (stream, "%%fprs");
00534 break;
00535
00536 case 'o':
00537 (*info->fprintf_func) (stream, "%%asi");
00538 break;
00539
00540 case 'W':
00541 (*info->fprintf_func) (stream, "%%tick");
00542 break;
00543
00544 case 'P':
00545 (*info->fprintf_func) (stream, "%%pc");
00546 break;
00547
00548 case '?':
00549 if (X_RS1 (insn) == 31)
00550 (*info->fprintf_func) (stream, "%%ver");
00551 else if ((unsigned) X_RS1 (insn) < 16)
00552 (*info->fprintf_func) (stream, "%%%s",
00553 v9_priv_reg_names[X_RS1 (insn)]);
00554 else
00555 (*info->fprintf_func) (stream, "%%reserved");
00556 break;
00557
00558 case '!':
00559 if ((unsigned) X_RD (insn) < 15)
00560 (*info->fprintf_func) (stream, "%%%s",
00561 v9_priv_reg_names[X_RD (insn)]);
00562 else
00563 (*info->fprintf_func) (stream, "%%reserved");
00564 break;
00565
00566 case '/':
00567 if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
00568 (*info->fprintf_func) (stream, "%%reserved");
00569 else
00570 (*info->fprintf_func) (stream, "%%%s",
00571 v9a_asr_reg_names[X_RS1 (insn)-16]);
00572 break;
00573
00574 case '_':
00575 if (X_RD (insn) < 16 || X_RD (insn) > 25)
00576 (*info->fprintf_func) (stream, "%%reserved");
00577 else
00578 (*info->fprintf_func) (stream, "%%%s",
00579 v9a_asr_reg_names[X_RD (insn)-16]);
00580 break;
00581
00582 case '*':
00583 {
00584 const char *name = sparc_decode_prefetch (X_RD (insn));
00585
00586 if (name)
00587 (*info->fprintf_func) (stream, "%s", name);
00588 else
00589 (*info->fprintf_func) (stream, "%d", X_RD (insn));
00590 break;
00591 }
00592
00593 case 'M':
00594 (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
00595 break;
00596
00597 case 'm':
00598 (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
00599 break;
00600
00601 case 'L':
00602 info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
00603 (*info->print_address_func) (info->target, info);
00604 break;
00605
00606 case 'n':
00607 (*info->fprintf_func)
00608 (stream, "%#x", SEX (X_DISP22 (insn), 22));
00609 break;
00610
00611 case 'l':
00612 info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
00613 (*info->print_address_func) (info->target, info);
00614 break;
00615
00616 case 'A':
00617 {
00618 const char *name = sparc_decode_asi (X_ASI (insn));
00619
00620 if (name)
00621 (*info->fprintf_func) (stream, "%s", name);
00622 else
00623 (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
00624 break;
00625 }
00626
00627 case 'C':
00628 (*info->fprintf_func) (stream, "%%csr");
00629 break;
00630
00631 case 'F':
00632 (*info->fprintf_func) (stream, "%%fsr");
00633 break;
00634
00635 case 'p':
00636 (*info->fprintf_func) (stream, "%%psr");
00637 break;
00638
00639 case 'q':
00640 (*info->fprintf_func) (stream, "%%fq");
00641 break;
00642
00643 case 'Q':
00644 (*info->fprintf_func) (stream, "%%cq");
00645 break;
00646
00647 case 't':
00648 (*info->fprintf_func) (stream, "%%tbr");
00649 break;
00650
00651 case 'w':
00652 (*info->fprintf_func) (stream, "%%wim");
00653 break;
00654
00655 case 'x':
00656 (*info->fprintf_func) (stream, "%d",
00657 ((X_LDST_I (insn) << 8)
00658 + X_ASI (insn)));
00659 break;
00660
00661 case 'y':
00662 (*info->fprintf_func) (stream, "%%y");
00663 break;
00664
00665 case 'u':
00666 case 'U':
00667 {
00668 int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
00669 const char *name = sparc_decode_sparclet_cpreg (val);
00670
00671 if (name)
00672 (*info->fprintf_func) (stream, "%s", name);
00673 else
00674 (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
00675 break;
00676 }
00677 }
00678 }
00679 }
00680
00681
00682
00683
00684
00685
00686
00687 if (imm_ored_to_rs1 || imm_added_to_rs1)
00688 {
00689 unsigned long prev_insn;
00690 int errcode;
00691
00692 if (memaddr >= 4)
00693 errcode =
00694 (*info->read_memory_func)
00695 (memaddr - 4, buffer, sizeof (buffer), info);
00696 else
00697 errcode = 1;
00698
00699 prev_insn = getword (buffer);
00700
00701 if (errcode == 0)
00702 {
00703
00704
00705
00706
00707
00708
00709
00710
00711 if (is_delayed_branch (prev_insn))
00712 {
00713 if (memaddr >= 8)
00714 errcode = (*info->read_memory_func)
00715 (memaddr - 8, buffer, sizeof (buffer), info);
00716 else
00717 errcode = 1;
00718
00719 prev_insn = getword (buffer);
00720 }
00721 }
00722
00723
00724
00725 if (errcode == 0)
00726 {
00727
00728 if ((prev_insn & 0xc1c00000) == 0x01000000
00729 && X_RD (prev_insn) == X_RS1 (insn))
00730 {
00731 (*info->fprintf_func) (stream, "\t! ");
00732 info->target =
00733 ((unsigned) 0xFFFFFFFF
00734 & ((int) X_IMM22 (prev_insn) << 10));
00735 if (imm_added_to_rs1)
00736 info->target += X_SIMM (insn, 13);
00737 else
00738 info->target |= X_SIMM (insn, 13);
00739 (*info->print_address_func) (info->target, info);
00740 info->insn_type = dis_dref;
00741 info->data_size = 4;
00742 }
00743 }
00744 }
00745
00746 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
00747 {
00748
00749 if (opcode->flags & F_UNBR)
00750 info->insn_type = dis_branch;
00751 if (opcode->flags & F_CONDBR)
00752 info->insn_type = dis_condbranch;
00753 if (opcode->flags & F_JSR)
00754 info->insn_type = dis_jsr;
00755 if (opcode->flags & F_DELAYED)
00756 info->branch_delay_insns = 1;
00757 }
00758
00759 return sizeof (buffer);
00760 }
00761 }
00762
00763 info->insn_type = dis_noninsn;
00764 (*info->fprintf_func) (stream, _("unknown"));
00765 return sizeof (buffer);
00766 }
00767
00768
00769
00770 static int
00771 compute_arch_mask (mach)
00772 unsigned long mach;
00773 {
00774 switch (mach)
00775 {
00776 case 0 :
00777 case bfd_mach_sparc :
00778 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
00779 case bfd_mach_sparc_sparclet :
00780 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
00781 case bfd_mach_sparc_sparclite :
00782 case bfd_mach_sparc_sparclite_le :
00783
00784
00785
00786 return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
00787 | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
00788 case bfd_mach_sparc_v8plus :
00789 case bfd_mach_sparc_v9 :
00790 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
00791 case bfd_mach_sparc_v8plusa :
00792 case bfd_mach_sparc_v9a :
00793 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
00794 case bfd_mach_sparc_v8plusb :
00795 case bfd_mach_sparc_v9b :
00796 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
00797 }
00798 abort ();
00799 }
00800
00801
00802
00803 static int
00804 compare_opcodes (a, b)
00805 const PTR a;
00806 const PTR b;
00807 {
00808 struct sparc_opcode *op0 = * (struct sparc_opcode **) a;
00809 struct sparc_opcode *op1 = * (struct sparc_opcode **) b;
00810 unsigned long int match0 = op0->match, match1 = op1->match;
00811 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
00812 register unsigned int i;
00813
00814
00815
00816
00817
00818
00819 if (op0->architecture & current_arch_mask)
00820 {
00821 if (! (op1->architecture & current_arch_mask))
00822 return -1;
00823 }
00824 else
00825 {
00826 if (op1->architecture & current_arch_mask)
00827 return 1;
00828 else if (op0->architecture != op1->architecture)
00829 return op0->architecture - op1->architecture;
00830 }
00831
00832
00833
00834 if (match0 & lose0)
00835 {
00836 fprintf
00837 (stderr,
00838
00839 _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
00840 op0->name, match0, lose0);
00841 op0->lose &= ~op0->match;
00842 lose0 = op0->lose;
00843 }
00844
00845 if (match1 & lose1)
00846 {
00847 fprintf
00848 (stderr,
00849
00850 _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
00851 op1->name, match1, lose1);
00852 op1->lose &= ~op1->match;
00853 lose1 = op1->lose;
00854 }
00855
00856
00857
00858 for (i = 0; i < 32; ++i)
00859 {
00860 unsigned long int x = 1 << i;
00861 int x0 = (match0 & x) != 0;
00862 int x1 = (match1 & x) != 0;
00863
00864 if (x0 != x1)
00865 return x1 - x0;
00866 }
00867
00868 for (i = 0; i < 32; ++i)
00869 {
00870 unsigned long int x = 1 << i;
00871 int x0 = (lose0 & x) != 0;
00872 int x1 = (lose1 & x) != 0;
00873
00874 if (x0 != x1)
00875 return x1 - x0;
00876 }
00877
00878
00879
00880
00881
00882 {
00883 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
00884 if (alias_diff != 0)
00885
00886 return alias_diff;
00887 }
00888
00889
00890
00891 i = strcmp (op0->name, op1->name);
00892 if (i)
00893 {
00894 if (op0->flags & F_ALIAS)
00895 return i;
00896 else
00897 fprintf (stderr,
00898
00899 _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
00900 op0->name, op1->name);
00901 }
00902
00903
00904 {
00905 int length_diff = strlen (op0->args) - strlen (op1->args);
00906 if (length_diff != 0)
00907
00908 return length_diff;
00909 }
00910
00911
00912 {
00913 char *p0 = (char *) strchr (op0->args, '+');
00914 char *p1 = (char *) strchr (op1->args, '+');
00915
00916 if (p0 && p1)
00917 {
00918
00919
00920
00921 if (p0[-1] == 'i' && p1[1] == 'i')
00922
00923 return 1;
00924 if (p0[1] == 'i' && p1[-1] == 'i')
00925
00926 return -1;
00927 }
00928 }
00929
00930
00931 {
00932 int i0 = strncmp (op0->args, "i,1", 3) == 0;
00933 int i1 = strncmp (op1->args, "i,1", 3) == 0;
00934
00935 if (i0 ^ i1)
00936 return i0 - i1;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945 return 0;
00946 }
00947
00948
00949
00950
00951 static void
00952 build_hash_table (opcode_table, hash_table, num_opcodes)
00953 const struct sparc_opcode **opcode_table;
00954 struct opcode_hash **hash_table;
00955 int num_opcodes;
00956 {
00957 register int i;
00958 int hash_count[HASH_SIZE];
00959 static struct opcode_hash *hash_buf = NULL;
00960
00961
00962
00963
00964 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
00965 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
00966 if (hash_buf != NULL)
00967 free (hash_buf);
00968 hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
00969 for (i = num_opcodes - 1; i >= 0; --i)
00970 {
00971 register int hash = HASH_INSN (opcode_table[i]->match);
00972 register struct opcode_hash *h = &hash_buf[i];
00973 h->next = hash_table[hash];
00974 h->opcode = opcode_table[i];
00975 hash_table[hash] = h;
00976 ++hash_count[hash];
00977 }
00978
00979 #if 0
00980 {
00981 int min_count = num_opcodes, max_count = 0;
00982 int total;
00983
00984 for (i = 0; i < HASH_SIZE; ++i)
00985 {
00986 if (hash_count[i] < min_count)
00987 min_count = hash_count[i];
00988 if (hash_count[i] > max_count)
00989 max_count = hash_count[i];
00990 total += hash_count[i];
00991 }
00992
00993 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
00994 min_count, max_count, (double) total / HASH_SIZE);
00995 }
00996 #endif
00997 }