1 1.1 christos /* Print SPARC instructions. 2 1.1.1.11 christos Copyright (C) 1989-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of the GNU opcodes library. 5 1.1 christos 6 1.1 christos This library is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT 12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 1.1 christos License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "sysdep.h" 22 1.1.1.2 christos #include <stdio.h> 23 1.1 christos #include "opcode/sparc.h" 24 1.1 christos #include "dis-asm.h" 25 1.1 christos #include "libiberty.h" 26 1.1 christos #include "opintl.h" 27 1.1 christos 28 1.1 christos /* Bitmask of v9 architectures. */ 29 1.1 christos #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \ 30 1.1 christos | (1 << SPARC_OPCODE_ARCH_V9A) \ 31 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9B) \ 32 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9C) \ 33 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9D) \ 34 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9E) \ 35 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9V) \ 36 1.1.1.7 christos | (1 << SPARC_OPCODE_ARCH_V9M) \ 37 1.1.1.7 christos | (1 << SPARC_OPCODE_ARCH_M8)) 38 1.1 christos /* 1 if INSN is for v9 only. */ 39 1.1 christos #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9)) 40 1.1 christos /* 1 if INSN is for v9. */ 41 1.1 christos #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0) 42 1.1 christos 43 1.1 christos /* The sorted opcode table. */ 44 1.1 christos static const sparc_opcode **sorted_opcodes; 45 1.1 christos 46 1.1 christos /* For faster lookup, after insns are sorted they are hashed. */ 47 1.1 christos /* ??? I think there is room for even more improvement. */ 48 1.1 christos 49 1.1 christos #define HASH_SIZE 256 50 1.1 christos /* It is important that we only look at insn code bits as that is how the 51 1.1 christos opcode table is hashed. OPCODE_BITS is a table of valid bits for each 52 1.1 christos of the main types (0,1,2,3). */ 53 1.1 christos static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 }; 54 1.1 christos #define HASH_INSN(INSN) \ 55 1.1 christos ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19)) 56 1.1 christos typedef struct sparc_opcode_hash 57 1.1 christos { 58 1.1 christos struct sparc_opcode_hash *next; 59 1.1 christos const sparc_opcode *opcode; 60 1.1 christos } sparc_opcode_hash; 61 1.1 christos 62 1.1 christos static sparc_opcode_hash *opcode_hash_table[HASH_SIZE]; 63 1.1 christos 64 1.1 christos /* Sign-extend a value which is N bits long. */ 65 1.1 christos #define SEX(value, bits) \ 66 1.1.1.8 christos ((int) (((value & ((1u << (bits - 1) << 1) - 1)) \ 67 1.1.1.8 christos ^ (1u << (bits - 1))) - (1u << (bits - 1)))) 68 1.1 christos 69 1.1 christos static char *reg_names[] = 70 1.1 christos { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", 71 1.1 christos "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", 72 1.1 christos "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", 73 1.1 christos "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", 74 1.1 christos "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 75 1.1 christos "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 76 1.1 christos "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 77 1.1 christos "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", 78 1.1 christos "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", 79 1.1 christos "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", 80 1.1 christos "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", 81 1.1 christos "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", 82 1.1 christos /* psr, wim, tbr, fpsr, cpsr are v8 only. */ 83 1.1 christos "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" 84 1.1 christos }; 85 1.1 christos 86 1.1 christos #define freg_names (®_names[4 * 8]) 87 1.1 christos 88 1.1 christos /* These are ordered according to there register number in 89 1.1 christos rdpr and wrpr insns. */ 90 1.1 christos static char *v9_priv_reg_names[] = 91 1.1 christos { 92 1.1 christos "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl", 93 1.1 christos "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", 94 1.1 christos "wstate", "fq", "gl" 95 1.1.1.5 christos /* "ver" and "pmcdper" - special cased */ 96 1.1 christos }; 97 1.1 christos 98 1.1 christos /* These are ordered according to there register number in 99 1.1 christos rdhpr and wrhpr insns. */ 100 1.1 christos static char *v9_hpriv_reg_names[] = 101 1.1 christos { 102 1.1 christos "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver", 103 1.1.1.5 christos "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13", 104 1.1 christos "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20", 105 1.1.1.5 christos "resv21", "resv22", "hmcdper", "hmcddfr", "resv25", "resv26", "hva_mask_nz", 106 1.1.1.4 christos "hstick_offset", "hstick_enable", "resv30", "hstick_cmpr" 107 1.1 christos }; 108 1.1 christos 109 1.1 christos /* These are ordered according to there register number in 110 1.1 christos rd and wr insns (-16). */ 111 1.1 christos static char *v9a_asr_reg_names[] = 112 1.1 christos { 113 1.1.1.5 christos "pcr", "pic", "dcr", "gsr", "softint_set", "softint_clear", 114 1.1.1.2 christos "softint", "tick_cmpr", "stick", "stick_cmpr", "cfr", 115 1.1.1.4 christos "pause", "mwait" 116 1.1 christos }; 117 1.1 christos 118 1.1 christos /* Macros used to extract instruction fields. Not all fields have 119 1.1 christos macros defined here, only those which are actually used. */ 120 1.1 christos 121 1.1 christos #define X_RD(i) (((i) >> 25) & 0x1f) 122 1.1 christos #define X_RS1(i) (((i) >> 14) & 0x1f) 123 1.1 christos #define X_LDST_I(i) (((i) >> 13) & 1) 124 1.1 christos #define X_ASI(i) (((i) >> 5) & 0xff) 125 1.1 christos #define X_RS2(i) (((i) >> 0) & 0x1f) 126 1.1.1.2 christos #define X_RS3(i) (((i) >> 9) & 0x1f) 127 1.1 christos #define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1)) 128 1.1 christos #define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n)) 129 1.1 christos #define X_DISP22(i) (((i) >> 0) & 0x3fffff) 130 1.1 christos #define X_IMM22(i) X_DISP22 (i) 131 1.1 christos #define X_DISP30(i) (((i) >> 0) & 0x3fffffff) 132 1.1.1.7 christos #define X_IMM2(i) (((i & 0x10) >> 3) | (i & 0x1)) 133 1.1 christos 134 1.1 christos /* These are for v9. */ 135 1.1 christos #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff)) 136 1.1.1.2 christos #define X_DISP10(i) (((((i) >> 19) & 3) << 8) | (((i) >> 5) & 0xff)) 137 1.1 christos #define X_DISP19(i) (((i) >> 0) & 0x7ffff) 138 1.1 christos #define X_MEMBAR(i) ((i) & 0x7f) 139 1.1 christos 140 1.1 christos /* Here is the union which was used to extract instruction fields 141 1.1 christos before the shift and mask macros were written. 142 1.1 christos 143 1.1 christos union sparc_insn 144 1.1 christos { 145 1.1 christos unsigned long int code; 146 1.1 christos struct 147 1.1 christos { 148 1.1 christos unsigned int anop:2; 149 1.1 christos #define op ldst.anop 150 1.1 christos unsigned int anrd:5; 151 1.1 christos #define rd ldst.anrd 152 1.1 christos unsigned int op3:6; 153 1.1 christos unsigned int anrs1:5; 154 1.1 christos #define rs1 ldst.anrs1 155 1.1 christos unsigned int i:1; 156 1.1 christos unsigned int anasi:8; 157 1.1 christos #define asi ldst.anasi 158 1.1 christos unsigned int anrs2:5; 159 1.1 christos #define rs2 ldst.anrs2 160 1.1 christos #define shcnt rs2 161 1.1 christos } ldst; 162 1.1 christos struct 163 1.1 christos { 164 1.1 christos unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1; 165 1.1 christos unsigned int IMM13:13; 166 1.1 christos #define imm13 IMM13.IMM13 167 1.1 christos } IMM13; 168 1.1 christos struct 169 1.1 christos { 170 1.1 christos unsigned int anop:2; 171 1.1 christos unsigned int a:1; 172 1.1 christos unsigned int cond:4; 173 1.1 christos unsigned int op2:3; 174 1.1 christos unsigned int DISP22:22; 175 1.1 christos #define disp22 branch.DISP22 176 1.1 christos #define imm22 disp22 177 1.1 christos } branch; 178 1.1 christos struct 179 1.1 christos { 180 1.1 christos unsigned int anop:2; 181 1.1 christos unsigned int a:1; 182 1.1 christos unsigned int z:1; 183 1.1 christos unsigned int rcond:3; 184 1.1 christos unsigned int op2:3; 185 1.1 christos unsigned int DISP16HI:2; 186 1.1 christos unsigned int p:1; 187 1.1 christos unsigned int _rs1:5; 188 1.1 christos unsigned int DISP16LO:14; 189 1.1 christos } branch16; 190 1.1 christos struct 191 1.1 christos { 192 1.1 christos unsigned int anop:2; 193 1.1 christos unsigned int adisp30:30; 194 1.1 christos #define disp30 call.adisp30 195 1.1 christos } call; 196 1.1 christos }; */ 197 1.1 christos 198 1.1 christos /* Nonzero if INSN is the opcode for a delayed branch. */ 199 1.1 christos 200 1.1 christos static int 201 1.1 christos is_delayed_branch (unsigned long insn) 202 1.1 christos { 203 1.1 christos sparc_opcode_hash *op; 204 1.1 christos 205 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) 206 1.1 christos { 207 1.1 christos const sparc_opcode *opcode = op->opcode; 208 1.1 christos 209 1.1 christos if ((opcode->match & insn) == opcode->match 210 1.1 christos && (opcode->lose & insn) == 0) 211 1.1 christos return opcode->flags & F_DELAYED; 212 1.1 christos } 213 1.1 christos return 0; 214 1.1 christos } 215 1.1 christos 216 1.1 christos /* extern void qsort (); */ 217 1.1 christos 218 1.1 christos /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value 219 1.1 christos to compare_opcodes. */ 220 1.1 christos static unsigned int current_arch_mask; 221 1.1 christos 222 1.1 christos /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */ 223 1.1 christos 224 1.1 christos static int 225 1.1 christos compute_arch_mask (unsigned long mach) 226 1.1 christos { 227 1.1 christos switch (mach) 228 1.1 christos { 229 1.1 christos case 0 : 230 1.1 christos case bfd_mach_sparc : 231 1.1.1.3 christos return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8) 232 1.1.1.3 christos | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_LEON)); 233 1.1 christos case bfd_mach_sparc_sparclet : 234 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET); 235 1.1 christos case bfd_mach_sparc_sparclite : 236 1.1 christos case bfd_mach_sparc_sparclite_le : 237 1.1 christos /* sparclites insns are recognized by default (because that's how 238 1.1 christos they've always been treated, for better or worse). Kludge this by 239 1.1 christos indicating generic v8 is also selected. */ 240 1.1 christos return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE) 241 1.1 christos | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)); 242 1.1 christos case bfd_mach_sparc_v8plus : 243 1.1 christos case bfd_mach_sparc_v9 : 244 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9); 245 1.1 christos case bfd_mach_sparc_v8plusa : 246 1.1 christos case bfd_mach_sparc_v9a : 247 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A); 248 1.1 christos case bfd_mach_sparc_v8plusb : 249 1.1 christos case bfd_mach_sparc_v9b : 250 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B); 251 1.1.1.5 christos case bfd_mach_sparc_v8plusc : 252 1.1.1.5 christos case bfd_mach_sparc_v9c : 253 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9C); 254 1.1.1.5 christos case bfd_mach_sparc_v8plusd : 255 1.1.1.5 christos case bfd_mach_sparc_v9d : 256 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9D); 257 1.1.1.5 christos case bfd_mach_sparc_v8pluse : 258 1.1.1.5 christos case bfd_mach_sparc_v9e : 259 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9E); 260 1.1.1.5 christos case bfd_mach_sparc_v8plusv : 261 1.1.1.5 christos case bfd_mach_sparc_v9v : 262 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9V); 263 1.1.1.5 christos case bfd_mach_sparc_v8plusm : 264 1.1.1.5 christos case bfd_mach_sparc_v9m : 265 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9M); 266 1.1.1.7 christos case bfd_mach_sparc_v8plusm8 : 267 1.1.1.7 christos case bfd_mach_sparc_v9m8 : 268 1.1.1.7 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_M8); 269 1.1 christos } 270 1.1 christos abort (); 271 1.1 christos } 272 1.1 christos 273 1.1 christos /* Compare opcodes A and B. */ 274 1.1 christos 275 1.1 christos static int 276 1.1 christos compare_opcodes (const void * a, const void * b) 277 1.1 christos { 278 1.1 christos sparc_opcode *op0 = * (sparc_opcode **) a; 279 1.1 christos sparc_opcode *op1 = * (sparc_opcode **) b; 280 1.1 christos unsigned long int match0 = op0->match, match1 = op1->match; 281 1.1 christos unsigned long int lose0 = op0->lose, lose1 = op1->lose; 282 1.1 christos register unsigned int i; 283 1.1 christos 284 1.1 christos /* If one (and only one) insn isn't supported by the current architecture, 285 1.1 christos prefer the one that is. If neither are supported, but they're both for 286 1.1 christos the same architecture, continue processing. Otherwise (both unsupported 287 1.1 christos and for different architectures), prefer lower numbered arch's (fudged 288 1.1 christos by comparing the bitmasks). */ 289 1.1 christos if (op0->architecture & current_arch_mask) 290 1.1 christos { 291 1.1 christos if (! (op1->architecture & current_arch_mask)) 292 1.1 christos return -1; 293 1.1 christos } 294 1.1 christos else 295 1.1 christos { 296 1.1 christos if (op1->architecture & current_arch_mask) 297 1.1 christos return 1; 298 1.1 christos else if (op0->architecture != op1->architecture) 299 1.1 christos return op0->architecture - op1->architecture; 300 1.1 christos } 301 1.1 christos 302 1.1 christos /* If a bit is set in both match and lose, there is something 303 1.1 christos wrong with the opcode table. */ 304 1.1 christos if (match0 & lose0) 305 1.1 christos { 306 1.1.1.7 christos opcodes_error_handler 307 1.1.1.7 christos /* xgettext:c-format */ 308 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"), 309 1.1 christos op0->name, match0, lose0); 310 1.1 christos op0->lose &= ~op0->match; 311 1.1 christos lose0 = op0->lose; 312 1.1 christos } 313 1.1 christos 314 1.1 christos if (match1 & lose1) 315 1.1 christos { 316 1.1.1.7 christos opcodes_error_handler 317 1.1.1.7 christos /* xgettext:c-format */ 318 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"), 319 1.1 christos op1->name, match1, lose1); 320 1.1 christos op1->lose &= ~op1->match; 321 1.1 christos lose1 = op1->lose; 322 1.1 christos } 323 1.1 christos 324 1.1 christos /* Because the bits that are variable in one opcode are constant in 325 1.1 christos another, it is important to order the opcodes in the right order. */ 326 1.1 christos for (i = 0; i < 32; ++i) 327 1.1 christos { 328 1.1.1.8 christos unsigned long int x = 1ul << i; 329 1.1 christos int x0 = (match0 & x) != 0; 330 1.1 christos int x1 = (match1 & x) != 0; 331 1.1 christos 332 1.1 christos if (x0 != x1) 333 1.1 christos return x1 - x0; 334 1.1 christos } 335 1.1 christos 336 1.1 christos for (i = 0; i < 32; ++i) 337 1.1 christos { 338 1.1.1.8 christos unsigned long int x = 1ul << i; 339 1.1 christos int x0 = (lose0 & x) != 0; 340 1.1 christos int x1 = (lose1 & x) != 0; 341 1.1 christos 342 1.1 christos if (x0 != x1) 343 1.1 christos return x1 - x0; 344 1.1 christos } 345 1.1 christos 346 1.1 christos /* They are functionally equal. So as long as the opcode table is 347 1.1 christos valid, we can put whichever one first we want, on aesthetic grounds. */ 348 1.1 christos 349 1.1 christos /* Our first aesthetic ground is that aliases defer to real insns. */ 350 1.1 christos { 351 1.1 christos int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS); 352 1.1 christos 353 1.1 christos if (alias_diff != 0) 354 1.1 christos /* Put the one that isn't an alias first. */ 355 1.1 christos return alias_diff; 356 1.1 christos } 357 1.1 christos 358 1.1 christos /* Except for aliases, two "identical" instructions had 359 1.1 christos better have the same opcode. This is a sanity check on the table. */ 360 1.1 christos i = strcmp (op0->name, op1->name); 361 1.1 christos if (i) 362 1.1 christos { 363 1.1.1.3 christos if (op0->flags & F_ALIAS) 364 1.1.1.3 christos { 365 1.1.1.3 christos if (op0->flags & F_PREFERRED) 366 1.1.1.3 christos return -1; 367 1.1.1.3 christos if (op1->flags & F_PREFERRED) 368 1.1.1.3 christos return 1; 369 1.1.1.3 christos 370 1.1.1.3 christos /* If they're both aliases, and neither is marked as preferred, 371 1.1.1.3 christos be arbitrary. */ 372 1.1.1.3 christos return i; 373 1.1.1.3 christos } 374 1.1 christos else 375 1.1.1.7 christos opcodes_error_handler 376 1.1.1.7 christos /* xgettext:c-format */ 377 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"), 378 1.1.1.7 christos op0->name, op1->name); 379 1.1 christos } 380 1.1 christos 381 1.1 christos /* Fewer arguments are preferred. */ 382 1.1 christos { 383 1.1 christos int length_diff = strlen (op0->args) - strlen (op1->args); 384 1.1 christos 385 1.1 christos if (length_diff != 0) 386 1.1 christos /* Put the one with fewer arguments first. */ 387 1.1 christos return length_diff; 388 1.1 christos } 389 1.1 christos 390 1.1.1.11 christos /* They are, as far as we can tell, identical. Keep the order in 391 1.1.1.11 christos the sparc_opcodes table. */ 392 1.1.1.11 christos if (op0 < op1) 393 1.1.1.11 christos return -1; 394 1.1.1.11 christos if (op0 > op1) 395 1.1.1.11 christos return 1; 396 1.1 christos return 0; 397 1.1 christos } 398 1.1 christos 399 1.1 christos /* Build a hash table from the opcode table. 400 1.1 christos OPCODE_TABLE is a sorted list of pointers into the opcode table. */ 401 1.1 christos 402 1.1 christos static void 403 1.1 christos build_hash_table (const sparc_opcode **opcode_table, 404 1.1 christos sparc_opcode_hash **hash_table, 405 1.1 christos int num_opcodes) 406 1.1 christos { 407 1.1 christos int i; 408 1.1 christos int hash_count[HASH_SIZE]; 409 1.1 christos static sparc_opcode_hash *hash_buf = NULL; 410 1.1 christos 411 1.1 christos /* Start at the end of the table and work backwards so that each 412 1.1 christos chain is sorted. */ 413 1.1 christos 414 1.1 christos memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0])); 415 1.1 christos memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0])); 416 1.1.1.8 christos free (hash_buf); 417 1.1 christos hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes); 418 1.1 christos for (i = num_opcodes - 1; i >= 0; --i) 419 1.1 christos { 420 1.1 christos int hash = HASH_INSN (opcode_table[i]->match); 421 1.1 christos sparc_opcode_hash *h = &hash_buf[i]; 422 1.1 christos 423 1.1 christos h->next = hash_table[hash]; 424 1.1 christos h->opcode = opcode_table[i]; 425 1.1 christos hash_table[hash] = h; 426 1.1 christos ++hash_count[hash]; 427 1.1 christos } 428 1.1 christos 429 1.1 christos #if 0 /* for debugging */ 430 1.1 christos { 431 1.1 christos int min_count = num_opcodes, max_count = 0; 432 1.1 christos int total; 433 1.1 christos 434 1.1 christos for (i = 0; i < HASH_SIZE; ++i) 435 1.1 christos { 436 1.1 christos if (hash_count[i] < min_count) 437 1.1 christos min_count = hash_count[i]; 438 1.1 christos if (hash_count[i] > max_count) 439 1.1 christos max_count = hash_count[i]; 440 1.1 christos total += hash_count[i]; 441 1.1 christos } 442 1.1 christos 443 1.1 christos printf ("Opcode hash table stats: min %d, max %d, ave %f\n", 444 1.1 christos min_count, max_count, (double) total / HASH_SIZE); 445 1.1 christos } 446 1.1 christos #endif 447 1.1 christos } 448 1.1 christos 449 1.1 christos /* Print one instruction from MEMADDR on INFO->STREAM. 450 1.1 christos 451 1.1 christos We suffix the instruction with a comment that gives the absolute 452 1.1 christos address involved, as well as its symbolic form, if the instruction 453 1.1 christos is preceded by a findable `sethi' and it either adds an immediate 454 1.1 christos displacement to that register, or it is an `add' or `or' instruction 455 1.1 christos on that register. */ 456 1.1 christos 457 1.1 christos int 458 1.1 christos print_insn_sparc (bfd_vma memaddr, disassemble_info *info) 459 1.1 christos { 460 1.1 christos FILE *stream = info->stream; 461 1.1 christos bfd_byte buffer[4]; 462 1.1 christos unsigned long insn; 463 1.1 christos sparc_opcode_hash *op; 464 1.1 christos /* Nonzero of opcode table has been initialized. */ 465 1.1 christos static int opcodes_initialized = 0; 466 1.1 christos /* bfd mach number of last call. */ 467 1.1 christos static unsigned long current_mach = 0; 468 1.1 christos bfd_vma (*getword) (const void *); 469 1.1 christos 470 1.1 christos if (!opcodes_initialized 471 1.1 christos || info->mach != current_mach) 472 1.1 christos { 473 1.1 christos int i; 474 1.1 christos 475 1.1 christos current_arch_mask = compute_arch_mask (info->mach); 476 1.1 christos 477 1.1 christos if (!opcodes_initialized) 478 1.1 christos sorted_opcodes = 479 1.1 christos xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *)); 480 1.1 christos /* Reset the sorted table so we can resort it. */ 481 1.1 christos for (i = 0; i < sparc_num_opcodes; ++i) 482 1.1 christos sorted_opcodes[i] = &sparc_opcodes[i]; 483 1.1 christos qsort ((char *) sorted_opcodes, sparc_num_opcodes, 484 1.1 christos sizeof (sorted_opcodes[0]), compare_opcodes); 485 1.1 christos 486 1.1 christos build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes); 487 1.1 christos current_mach = info->mach; 488 1.1 christos opcodes_initialized = 1; 489 1.1 christos } 490 1.1 christos 491 1.1 christos { 492 1.1 christos int status = 493 1.1 christos (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info); 494 1.1 christos 495 1.1 christos if (status != 0) 496 1.1 christos { 497 1.1 christos (*info->memory_error_func) (status, memaddr, info); 498 1.1 christos return -1; 499 1.1 christos } 500 1.1 christos } 501 1.1 christos 502 1.1 christos /* On SPARClite variants such as DANlite (sparc86x), instructions 503 1.1 christos are always big-endian even when the machine is in little-endian mode. */ 504 1.1 christos if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite) 505 1.1 christos getword = bfd_getb32; 506 1.1 christos else 507 1.1 christos getword = bfd_getl32; 508 1.1 christos 509 1.1 christos insn = getword (buffer); 510 1.1 christos 511 1.1 christos info->insn_info_valid = 1; /* We do return this info. */ 512 1.1 christos info->insn_type = dis_nonbranch; /* Assume non branch insn. */ 513 1.1 christos info->branch_delay_insns = 0; /* Assume no delay. */ 514 1.1 christos info->target = 0; /* Assume no target known. */ 515 1.1 christos 516 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) 517 1.1 christos { 518 1.1 christos const sparc_opcode *opcode = op->opcode; 519 1.1 christos 520 1.1 christos /* If the insn isn't supported by the current architecture, skip it. */ 521 1.1 christos if (! (opcode->architecture & current_arch_mask)) 522 1.1 christos continue; 523 1.1 christos 524 1.1 christos if ((opcode->match & insn) == opcode->match 525 1.1 christos && (opcode->lose & insn) == 0) 526 1.1 christos { 527 1.1 christos /* Nonzero means that we have found an instruction which has 528 1.1 christos the effect of adding or or'ing the imm13 field to rs1. */ 529 1.1 christos int imm_added_to_rs1 = 0; 530 1.1 christos int imm_ored_to_rs1 = 0; 531 1.1 christos 532 1.1 christos /* Nonzero means that we have found a plus sign in the args 533 1.1 christos field of the opcode table. */ 534 1.1 christos int found_plus = 0; 535 1.1 christos 536 1.1 christos /* Nonzero means we have an annulled branch. */ 537 1.1 christos int is_annulled = 0; 538 1.1 christos 539 1.1 christos /* Do we have an `add' or `or' instruction combining an 540 1.1 christos immediate with rs1? */ 541 1.1 christos if (opcode->match == 0x80102000) /* or */ 542 1.1 christos imm_ored_to_rs1 = 1; 543 1.1 christos if (opcode->match == 0x80002000) /* add */ 544 1.1 christos imm_added_to_rs1 = 1; 545 1.1 christos 546 1.1 christos if (X_RS1 (insn) != X_RD (insn) 547 1.1 christos && strchr (opcode->args, 'r') != 0) 548 1.1 christos /* Can't do simple format if source and dest are different. */ 549 1.1 christos continue; 550 1.1 christos if (X_RS2 (insn) != X_RD (insn) 551 1.1 christos && strchr (opcode->args, 'O') != 0) 552 1.1 christos /* Can't do simple format if source and dest are different. */ 553 1.1 christos continue; 554 1.1 christos 555 1.1.1.2 christos (*info->fprintf_func) (stream, "%s", opcode->name); 556 1.1 christos 557 1.1 christos { 558 1.1 christos const char *s; 559 1.1 christos 560 1.1 christos if (opcode->args[0] != ',') 561 1.1 christos (*info->fprintf_func) (stream, " "); 562 1.1 christos 563 1.1 christos for (s = opcode->args; *s != '\0'; ++s) 564 1.1 christos { 565 1.1 christos while (*s == ',') 566 1.1 christos { 567 1.1 christos (*info->fprintf_func) (stream, ","); 568 1.1 christos ++s; 569 1.1 christos switch (*s) 570 1.1 christos { 571 1.1 christos case 'a': 572 1.1 christos (*info->fprintf_func) (stream, "a"); 573 1.1 christos is_annulled = 1; 574 1.1 christos ++s; 575 1.1 christos continue; 576 1.1 christos case 'N': 577 1.1 christos (*info->fprintf_func) (stream, "pn"); 578 1.1 christos ++s; 579 1.1 christos continue; 580 1.1 christos 581 1.1 christos case 'T': 582 1.1 christos (*info->fprintf_func) (stream, "pt"); 583 1.1 christos ++s; 584 1.1 christos continue; 585 1.1 christos 586 1.1 christos default: 587 1.1 christos break; 588 1.1 christos } 589 1.1 christos } 590 1.1 christos 591 1.1 christos (*info->fprintf_func) (stream, " "); 592 1.1 christos 593 1.1 christos switch (*s) 594 1.1 christos { 595 1.1 christos case '+': 596 1.1 christos found_plus = 1; 597 1.1 christos /* Fall through. */ 598 1.1 christos 599 1.1 christos default: 600 1.1 christos (*info->fprintf_func) (stream, "%c", *s); 601 1.1 christos break; 602 1.1 christos 603 1.1 christos case '#': 604 1.1 christos (*info->fprintf_func) (stream, "0"); 605 1.1 christos break; 606 1.1 christos 607 1.1 christos #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n]) 608 1.1 christos case '1': 609 1.1 christos case 'r': 610 1.1 christos reg (X_RS1 (insn)); 611 1.1 christos break; 612 1.1 christos 613 1.1 christos case '2': 614 1.1 christos case 'O': 615 1.1 christos reg (X_RS2 (insn)); 616 1.1 christos break; 617 1.1 christos 618 1.1 christos case 'd': 619 1.1 christos reg (X_RD (insn)); 620 1.1 christos break; 621 1.1 christos #undef reg 622 1.1 christos 623 1.1 christos #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n]) 624 1.1 christos #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)]) 625 1.1 christos case 'e': 626 1.1 christos freg (X_RS1 (insn)); 627 1.1 christos break; 628 1.1 christos case 'v': /* Double/even. */ 629 1.1 christos case 'V': /* Quad/multiple of 4. */ 630 1.1.1.7 christos case ';': /* Double/even multiple of 8 doubles. */ 631 1.1 christos fregx (X_RS1 (insn)); 632 1.1 christos break; 633 1.1 christos 634 1.1 christos case 'f': 635 1.1 christos freg (X_RS2 (insn)); 636 1.1 christos break; 637 1.1 christos case 'B': /* Double/even. */ 638 1.1 christos case 'R': /* Quad/multiple of 4. */ 639 1.1.1.7 christos case ':': /* Double/even multiple of 8 doubles. */ 640 1.1 christos fregx (X_RS2 (insn)); 641 1.1 christos break; 642 1.1 christos 643 1.1.1.2 christos case '4': 644 1.1.1.2 christos freg (X_RS3 (insn)); 645 1.1.1.2 christos break; 646 1.1.1.2 christos case '5': /* Double/even. */ 647 1.1.1.2 christos fregx (X_RS3 (insn)); 648 1.1.1.2 christos break; 649 1.1.1.2 christos 650 1.1 christos case 'g': 651 1.1 christos freg (X_RD (insn)); 652 1.1 christos break; 653 1.1 christos case 'H': /* Double/even. */ 654 1.1 christos case 'J': /* Quad/multiple of 4. */ 655 1.1.1.4 christos case '}': /* Double/even. */ 656 1.1 christos fregx (X_RD (insn)); 657 1.1 christos break; 658 1.1.1.7 christos 659 1.1.1.7 christos case '^': /* Double/even multiple of 8 doubles. */ 660 1.1.1.7 christos fregx (X_RD (insn) & ~0x6); 661 1.1.1.7 christos break; 662 1.1.1.7 christos 663 1.1.1.7 christos case '\'': /* Double/even in FPCMPSHL. */ 664 1.1.1.7 christos fregx (X_RS2 (insn | 0x11)); 665 1.1.1.7 christos break; 666 1.1.1.7 christos 667 1.1 christos #undef freg 668 1.1 christos #undef fregx 669 1.1 christos 670 1.1 christos #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n)) 671 1.1 christos case 'b': 672 1.1 christos creg (X_RS1 (insn)); 673 1.1 christos break; 674 1.1 christos 675 1.1 christos case 'c': 676 1.1 christos creg (X_RS2 (insn)); 677 1.1 christos break; 678 1.1 christos 679 1.1 christos case 'D': 680 1.1 christos creg (X_RD (insn)); 681 1.1 christos break; 682 1.1 christos #undef creg 683 1.1 christos 684 1.1 christos case 'h': 685 1.1 christos (*info->fprintf_func) (stream, "%%hi(%#x)", 686 1.1.1.8 christos (unsigned) X_IMM22 (insn) << 10); 687 1.1 christos break; 688 1.1 christos 689 1.1 christos case 'i': /* 13 bit immediate. */ 690 1.1 christos case 'I': /* 11 bit immediate. */ 691 1.1 christos case 'j': /* 10 bit immediate. */ 692 1.1 christos { 693 1.1 christos int imm; 694 1.1 christos 695 1.1 christos if (*s == 'i') 696 1.1 christos imm = X_SIMM (insn, 13); 697 1.1 christos else if (*s == 'I') 698 1.1 christos imm = X_SIMM (insn, 11); 699 1.1 christos else 700 1.1 christos imm = X_SIMM (insn, 10); 701 1.1 christos 702 1.1 christos /* Check to see whether we have a 1+i, and take 703 1.1 christos note of that fact. 704 1.1 christos 705 1.1 christos Note: because of the way we sort the table, 706 1.1 christos we will be matching 1+i rather than i+1, 707 1.1 christos so it is OK to assume that i is after +, 708 1.1 christos not before it. */ 709 1.1 christos if (found_plus) 710 1.1 christos imm_added_to_rs1 = 1; 711 1.1 christos 712 1.1 christos if (imm <= 9) 713 1.1 christos (*info->fprintf_func) (stream, "%d", imm); 714 1.1 christos else 715 1.1 christos (*info->fprintf_func) (stream, "%#x", imm); 716 1.1 christos } 717 1.1 christos break; 718 1.1 christos 719 1.1.1.2 christos case ')': /* 5 bit unsigned immediate from RS3. */ 720 1.1.1.2 christos (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn)); 721 1.1.1.2 christos break; 722 1.1.1.2 christos 723 1.1 christos case 'X': /* 5 bit unsigned immediate. */ 724 1.1 christos case 'Y': /* 6 bit unsigned immediate. */ 725 1.1 christos { 726 1.1 christos int imm = X_IMM (insn, *s == 'X' ? 5 : 6); 727 1.1 christos 728 1.1 christos if (imm <= 9) 729 1.1 christos (info->fprintf_func) (stream, "%d", imm); 730 1.1 christos else 731 1.1 christos (info->fprintf_func) (stream, "%#x", (unsigned) imm); 732 1.1 christos } 733 1.1 christos break; 734 1.1 christos 735 1.1 christos case '3': 736 1.1 christos (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3)); 737 1.1 christos break; 738 1.1 christos 739 1.1 christos case 'K': 740 1.1 christos { 741 1.1 christos int mask = X_MEMBAR (insn); 742 1.1 christos int bit = 0x40, printed_one = 0; 743 1.1 christos const char *name; 744 1.1 christos 745 1.1 christos if (mask == 0) 746 1.1 christos (info->fprintf_func) (stream, "0"); 747 1.1 christos else 748 1.1 christos while (bit) 749 1.1 christos { 750 1.1 christos if (mask & bit) 751 1.1 christos { 752 1.1 christos if (printed_one) 753 1.1 christos (info->fprintf_func) (stream, "|"); 754 1.1 christos name = sparc_decode_membar (bit); 755 1.1 christos (info->fprintf_func) (stream, "%s", name); 756 1.1 christos printed_one = 1; 757 1.1 christos } 758 1.1 christos bit >>= 1; 759 1.1 christos } 760 1.1 christos break; 761 1.1 christos } 762 1.1 christos 763 1.1.1.2 christos case '=': 764 1.1.1.2 christos info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4; 765 1.1.1.2 christos (*info->print_address_func) (info->target, info); 766 1.1.1.2 christos break; 767 1.1.1.2 christos 768 1.1 christos case 'k': 769 1.1 christos info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4; 770 1.1 christos (*info->print_address_func) (info->target, info); 771 1.1 christos break; 772 1.1 christos 773 1.1 christos case 'G': 774 1.1 christos info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4; 775 1.1 christos (*info->print_address_func) (info->target, info); 776 1.1 christos break; 777 1.1 christos 778 1.1 christos case '6': 779 1.1 christos case '7': 780 1.1 christos case '8': 781 1.1 christos case '9': 782 1.1 christos (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0'); 783 1.1 christos break; 784 1.1 christos 785 1.1 christos case 'z': 786 1.1 christos (*info->fprintf_func) (stream, "%%icc"); 787 1.1 christos break; 788 1.1 christos 789 1.1 christos case 'Z': 790 1.1 christos (*info->fprintf_func) (stream, "%%xcc"); 791 1.1 christos break; 792 1.1 christos 793 1.1 christos case 'E': 794 1.1 christos (*info->fprintf_func) (stream, "%%ccr"); 795 1.1 christos break; 796 1.1 christos 797 1.1 christos case 's': 798 1.1 christos (*info->fprintf_func) (stream, "%%fprs"); 799 1.1 christos break; 800 1.1 christos 801 1.1.1.4 christos case '{': 802 1.1.1.4 christos (*info->fprintf_func) (stream, "%%mcdper"); 803 1.1.1.4 christos break; 804 1.1.1.4 christos 805 1.1.1.7 christos case '&': 806 1.1.1.7 christos (*info->fprintf_func) (stream, "%%entropy"); 807 1.1.1.7 christos break; 808 1.1.1.7 christos 809 1.1 christos case 'o': 810 1.1 christos (*info->fprintf_func) (stream, "%%asi"); 811 1.1 christos break; 812 1.1 christos 813 1.1 christos case 'W': 814 1.1 christos (*info->fprintf_func) (stream, "%%tick"); 815 1.1 christos break; 816 1.1 christos 817 1.1 christos case 'P': 818 1.1 christos (*info->fprintf_func) (stream, "%%pc"); 819 1.1 christos break; 820 1.1 christos 821 1.1 christos case '?': 822 1.1 christos if (X_RS1 (insn) == 31) 823 1.1 christos (*info->fprintf_func) (stream, "%%ver"); 824 1.1.1.5 christos else if (X_RS1 (insn) == 23) 825 1.1.1.5 christos (*info->fprintf_func) (stream, "%%pmcdper"); 826 1.1 christos else if ((unsigned) X_RS1 (insn) < 17) 827 1.1 christos (*info->fprintf_func) (stream, "%%%s", 828 1.1 christos v9_priv_reg_names[X_RS1 (insn)]); 829 1.1 christos else 830 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 831 1.1 christos break; 832 1.1 christos 833 1.1 christos case '!': 834 1.1.1.5 christos if (X_RD (insn) == 31) 835 1.1.1.5 christos (*info->fprintf_func) (stream, "%%ver"); 836 1.1.1.5 christos else if (X_RD (insn) == 23) 837 1.1.1.5 christos (*info->fprintf_func) (stream, "%%pmcdper"); 838 1.1.1.5 christos else if ((unsigned) X_RD (insn) < 17) 839 1.1 christos (*info->fprintf_func) (stream, "%%%s", 840 1.1 christos v9_priv_reg_names[X_RD (insn)]); 841 1.1 christos else 842 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 843 1.1 christos break; 844 1.1 christos 845 1.1 christos case '$': 846 1.1 christos if ((unsigned) X_RS1 (insn) < 32) 847 1.1 christos (*info->fprintf_func) (stream, "%%%s", 848 1.1 christos v9_hpriv_reg_names[X_RS1 (insn)]); 849 1.1 christos else 850 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 851 1.1 christos break; 852 1.1 christos 853 1.1 christos case '%': 854 1.1 christos if ((unsigned) X_RD (insn) < 32) 855 1.1 christos (*info->fprintf_func) (stream, "%%%s", 856 1.1 christos v9_hpriv_reg_names[X_RD (insn)]); 857 1.1 christos else 858 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 859 1.1 christos break; 860 1.1 christos 861 1.1 christos case '/': 862 1.1.1.2 christos if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28) 863 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 864 1.1 christos else 865 1.1 christos (*info->fprintf_func) (stream, "%%%s", 866 1.1 christos v9a_asr_reg_names[X_RS1 (insn)-16]); 867 1.1 christos break; 868 1.1 christos 869 1.1 christos case '_': 870 1.1.1.2 christos if (X_RD (insn) < 16 || X_RD (insn) > 28) 871 1.1 christos (*info->fprintf_func) (stream, "%%reserved"); 872 1.1 christos else 873 1.1 christos (*info->fprintf_func) (stream, "%%%s", 874 1.1 christos v9a_asr_reg_names[X_RD (insn)-16]); 875 1.1 christos break; 876 1.1 christos 877 1.1 christos case '*': 878 1.1 christos { 879 1.1 christos const char *name = sparc_decode_prefetch (X_RD (insn)); 880 1.1 christos 881 1.1 christos if (name) 882 1.1 christos (*info->fprintf_func) (stream, "%s", name); 883 1.1 christos else 884 1.1 christos (*info->fprintf_func) (stream, "%ld", X_RD (insn)); 885 1.1 christos break; 886 1.1 christos } 887 1.1 christos 888 1.1 christos case 'M': 889 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn)); 890 1.1 christos break; 891 1.1 christos 892 1.1 christos case 'm': 893 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn)); 894 1.1 christos break; 895 1.1 christos 896 1.1 christos case 'L': 897 1.1 christos info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4; 898 1.1 christos (*info->print_address_func) (info->target, info); 899 1.1 christos break; 900 1.1 christos 901 1.1 christos case 'n': 902 1.1 christos (*info->fprintf_func) 903 1.1 christos (stream, "%#x", SEX (X_DISP22 (insn), 22)); 904 1.1 christos break; 905 1.1 christos 906 1.1 christos case 'l': 907 1.1 christos info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4; 908 1.1 christos (*info->print_address_func) (info->target, info); 909 1.1 christos break; 910 1.1 christos 911 1.1 christos case 'A': 912 1.1 christos { 913 1.1 christos const char *name = sparc_decode_asi (X_ASI (insn)); 914 1.1 christos 915 1.1 christos if (name) 916 1.1 christos (*info->fprintf_func) (stream, "%s", name); 917 1.1 christos else 918 1.1 christos (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn)); 919 1.1 christos break; 920 1.1 christos } 921 1.1 christos 922 1.1 christos case 'C': 923 1.1 christos (*info->fprintf_func) (stream, "%%csr"); 924 1.1 christos break; 925 1.1 christos 926 1.1 christos case 'F': 927 1.1 christos (*info->fprintf_func) (stream, "%%fsr"); 928 1.1 christos break; 929 1.1 christos 930 1.1.1.2 christos case '(': 931 1.1.1.2 christos (*info->fprintf_func) (stream, "%%efsr"); 932 1.1.1.2 christos break; 933 1.1.1.2 christos 934 1.1 christos case 'p': 935 1.1 christos (*info->fprintf_func) (stream, "%%psr"); 936 1.1 christos break; 937 1.1 christos 938 1.1 christos case 'q': 939 1.1 christos (*info->fprintf_func) (stream, "%%fq"); 940 1.1 christos break; 941 1.1 christos 942 1.1 christos case 'Q': 943 1.1 christos (*info->fprintf_func) (stream, "%%cq"); 944 1.1 christos break; 945 1.1 christos 946 1.1 christos case 't': 947 1.1 christos (*info->fprintf_func) (stream, "%%tbr"); 948 1.1 christos break; 949 1.1 christos 950 1.1 christos case 'w': 951 1.1 christos (*info->fprintf_func) (stream, "%%wim"); 952 1.1 christos break; 953 1.1 christos 954 1.1 christos case 'x': 955 1.1 christos (*info->fprintf_func) (stream, "%ld", 956 1.1 christos ((X_LDST_I (insn) << 8) 957 1.1 christos + X_ASI (insn))); 958 1.1 christos break; 959 1.1 christos 960 1.1.1.7 christos case '|': /* 2-bit immediate */ 961 1.1.1.7 christos (*info->fprintf_func) (stream, "%ld", X_IMM2 (insn)); 962 1.1.1.7 christos break; 963 1.1.1.7 christos 964 1.1 christos case 'y': 965 1.1 christos (*info->fprintf_func) (stream, "%%y"); 966 1.1 christos break; 967 1.1 christos 968 1.1 christos case 'u': 969 1.1 christos case 'U': 970 1.1 christos { 971 1.1 christos int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn); 972 1.1 christos const char *name = sparc_decode_sparclet_cpreg (val); 973 1.1 christos 974 1.1 christos if (name) 975 1.1 christos (*info->fprintf_func) (stream, "%s", name); 976 1.1 christos else 977 1.1 christos (*info->fprintf_func) (stream, "%%cpreg(%d)", val); 978 1.1 christos break; 979 1.1 christos } 980 1.1 christos } 981 1.1 christos } 982 1.1 christos } 983 1.1 christos 984 1.1 christos /* If we are adding or or'ing something to rs1, then 985 1.1 christos check to see whether the previous instruction was 986 1.1 christos a sethi to the same register as in the sethi. 987 1.1 christos If so, attempt to print the result of the add or 988 1.1 christos or (in this context add and or do the same thing) 989 1.1 christos and its symbolic value. */ 990 1.1 christos if (imm_ored_to_rs1 || imm_added_to_rs1) 991 1.1 christos { 992 1.1 christos unsigned long prev_insn; 993 1.1 christos int errcode; 994 1.1 christos 995 1.1 christos if (memaddr >= 4) 996 1.1 christos errcode = 997 1.1 christos (*info->read_memory_func) 998 1.1 christos (memaddr - 4, buffer, sizeof (buffer), info); 999 1.1 christos else 1000 1.1 christos errcode = 1; 1001 1.1 christos 1002 1.1 christos prev_insn = getword (buffer); 1003 1.1 christos 1004 1.1 christos if (errcode == 0) 1005 1.1 christos { 1006 1.1 christos /* If it is a delayed branch, we need to look at the 1007 1.1 christos instruction before the delayed branch. This handles 1008 1.1 christos sequences such as: 1009 1.1 christos 1010 1.1 christos sethi %o1, %hi(_foo), %o1 1011 1.1 christos call _printf 1012 1.1 christos or %o1, %lo(_foo), %o1 */ 1013 1.1 christos 1014 1.1 christos if (is_delayed_branch (prev_insn)) 1015 1.1 christos { 1016 1.1 christos if (memaddr >= 8) 1017 1.1 christos errcode = (*info->read_memory_func) 1018 1.1 christos (memaddr - 8, buffer, sizeof (buffer), info); 1019 1.1 christos else 1020 1.1 christos errcode = 1; 1021 1.1 christos 1022 1.1 christos prev_insn = getword (buffer); 1023 1.1 christos } 1024 1.1 christos } 1025 1.1 christos 1026 1.1 christos /* If there was a problem reading memory, then assume 1027 1.1 christos the previous instruction was not sethi. */ 1028 1.1 christos if (errcode == 0) 1029 1.1 christos { 1030 1.1 christos /* Is it sethi to the same register? */ 1031 1.1 christos if ((prev_insn & 0xc1c00000) == 0x01000000 1032 1.1 christos && X_RD (prev_insn) == X_RS1 (insn)) 1033 1.1 christos { 1034 1.1 christos (*info->fprintf_func) (stream, "\t! "); 1035 1.1.1.8 christos info->target = (unsigned) X_IMM22 (prev_insn) << 10; 1036 1.1 christos if (imm_added_to_rs1) 1037 1.1 christos info->target += X_SIMM (insn, 13); 1038 1.1 christos else 1039 1.1 christos info->target |= X_SIMM (insn, 13); 1040 1.1 christos (*info->print_address_func) (info->target, info); 1041 1.1 christos info->insn_type = dis_dref; 1042 1.1 christos info->data_size = 4; /* FIXME!!! */ 1043 1.1 christos } 1044 1.1 christos } 1045 1.1 christos } 1046 1.1 christos 1047 1.1 christos if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR)) 1048 1.1 christos { 1049 1.1 christos /* FIXME -- check is_annulled flag. */ 1050 1.1 christos (void) is_annulled; 1051 1.1 christos if (opcode->flags & F_UNBR) 1052 1.1 christos info->insn_type = dis_branch; 1053 1.1 christos if (opcode->flags & F_CONDBR) 1054 1.1 christos info->insn_type = dis_condbranch; 1055 1.1 christos if (opcode->flags & F_JSR) 1056 1.1 christos info->insn_type = dis_jsr; 1057 1.1 christos if (opcode->flags & F_DELAYED) 1058 1.1 christos info->branch_delay_insns = 1; 1059 1.1 christos } 1060 1.1 christos 1061 1.1 christos return sizeof (buffer); 1062 1.1 christos } 1063 1.1 christos } 1064 1.1 christos 1065 1.1 christos info->insn_type = dis_noninsn; /* Mark as non-valid instruction. */ 1066 1.1 christos (*info->fprintf_func) (stream, _("unknown")); 1067 1.1 christos return sizeof (buffer); 1068 1.1 christos } 1069