- switch (*s)
- {
- case ',':
- case '(':
- case ')':
- infprintf (is, "%c", *s);
- break;
-
- case '.':
- infprintf (is, "%d", GET_OP_S (insn, OFFSET10));
- break;
-
- case '1':
- infprintf (is, "0x%x", GET_OP (insn, STYPE));
- break;
-
- case '2':
- infprintf (is, "0x%x", GET_OP (insn, BP));
- break;
-
- case '3':
- infprintf (is, "0x%x", GET_OP (insn, SA3));
- break;
-
- case '4':
- infprintf (is, "0x%x", GET_OP (insn, SA4));
- break;
-
- case '5':
- infprintf (is, "0x%x", GET_OP (insn, IMM8));
- break;
-
- case '6':
- infprintf (is, "0x%x", GET_OP (insn, RS));
- break;
-
- case '7':
- infprintf (is, "$ac%d", GET_OP (insn, DSPACC));
- break;
-
- case '8':
- infprintf (is, "0x%x", GET_OP (insn, WRDSP));
- break;
-
- case '0': /* DSP 6-bit signed immediate in bit 16. */
- delta = (GET_OP (insn, DSPSFT) ^ 0x20) - 0x20;
- infprintf (is, "%d", delta);
- break;
-
- case '<':
- infprintf (is, "0x%x", GET_OP (insn, SHAMT));
- break;
-
- case '\\':
- infprintf (is, "0x%x", GET_OP (insn, 3BITPOS));
- break;
-
- case '^':
- infprintf (is, "0x%x", GET_OP (insn, RD));
- break;
-
- case '|':
- infprintf (is, "0x%x", GET_OP (insn, TRAP));
- break;
-
- case '~':
- infprintf (is, "%d", GET_OP_S (insn, OFFSET12));
- break;
-
- case 'a':
- if (strcmp (op->name, "jalx") == 0)
- info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
- | (GET_OP (insn, TARGET) << 2));
- else
- info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
- | (GET_OP (insn, TARGET) << 1));
- /* For gdb disassembler, force odd address on jalx. */
- if (info->flavour == bfd_target_unknown_flavour
- && strcmp (op->name, "jalx") == 0)
- info->target |= 1;
- (*info->print_address_func) (info->target, info);
- break;
-
- case 'b':
- case 'r':
- case 's':
- case 'v':
- infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
- break;
-
- case 'c':
- infprintf (is, "0x%x", GET_OP (insn, CODE));
- break;
-
- case 'd':
- infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
- break;
-
- case 'h':
- infprintf (is, "0x%x", GET_OP (insn, PREFX));
- break;
-
- case 'i':
- case 'u':
- infprintf (is, "0x%x", GET_OP (insn, IMMEDIATE));
- break;
-
- case 'j': /* Same as i, but sign-extended. */
- case 'o':
- infprintf (is, "%d", GET_OP_S (insn, DELTA));
- break;
-
- case 'k':
- infprintf (is, "0x%x", GET_OP (insn, CACHE));
- break;
-
- case 'n':
- {
- int s_reg_encode;
-
- immed = GET_OP (insn, RT);
- s_reg_encode = immed & 0xf;
- if (s_reg_encode != 0)
- {
- if (s_reg_encode == 1)
- infprintf (is, "%s", mips_gpr_names[16]);
- else if (s_reg_encode < 9)
- infprintf (is, "%s-%s",
- mips_gpr_names[16],
- mips_gpr_names[15 + s_reg_encode]);
- else if (s_reg_encode == 9)
- infprintf (is, "%s-%s,%s",
- mips_gpr_names[16],
- mips_gpr_names[23],
- mips_gpr_names[30]);
- else
- infprintf (is, "UNKNOWN");
- }
-
- if (immed & 0x10) /* For ra. */
- {
- if (s_reg_encode == 0)
- infprintf (is, "%s", mips_gpr_names[31]);
- else
- infprintf (is, ",%s", mips_gpr_names[31]);
- }
- break;
- }
-
- case 'p':
- /* Sign-extend the displacement. */
- delta = GET_OP_S (insn, DELTA);
- info->target = (delta << 1) + memaddr + length;
- (*info->print_address_func) (info->target, info);
- break;
-
- case 'q':
- infprintf (is, "0x%x", GET_OP (insn, CODE2));
- break;
-
- case 't':
- case 'w':
- infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
- break;
-
- case 'y':
- infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
- break;
-
- case 'z':
- infprintf (is, "%s", mips_gpr_names[0]);
- break;
-
- case '@': /* DSP 10-bit signed immediate in bit 16. */
- delta = (GET_OP (insn, IMM10) ^ 0x200) - 0x200;
- infprintf (is, "%d", delta);
- break;
-
- case 'B':
- infprintf (is, "0x%x", GET_OP (insn, CODE10));
- break;
-
- case 'C':
- infprintf (is, "0x%x", GET_OP (insn, COPZ));
- break;
-
- case 'D':
- infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
- break;
-
- case 'E':
- /* Coprocessor register for lwcN instructions, et al.
-
- Note that there is no load/store cp0 instructions, and
- that FPU (cp1) instructions disassemble this field using
- 'T' format. Therefore, until we gain understanding of
- cp2 register names, we can simply print the register
- numbers. */
- infprintf (is, "$%d", GET_OP (insn, RT));
- break;
-
- case 'G':
- /* Coprocessor register for mtcN instructions, et al. Note
- that FPU (cp1) instructions disassemble this field using
- 'S' format. Therefore, we only need to worry about cp0,
- cp2, and cp3.
- The microMIPS encoding does not have a coprocessor
- identifier field as such, so we must work out the
- coprocessor number by looking at the opcode. */
- switch (insn
- & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
- | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
- {
- case 0x000000fc: /* mfc0 */
- case 0x000002fc: /* mtc0 */
- case 0x580000fc: /* dmfc0 */
- case 0x580002fc: /* dmtc0 */
- infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
- break;
- default:
- infprintf (is, "$%d", GET_OP (insn, RS));
- break;
- }
- break;
-
- case 'H':
- infprintf (is, "%d", GET_OP (insn, SEL));
- break;
-
- case 'K':
- infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
- break;
-
- case 'M':
- infprintf (is, "$fcc%d", GET_OP (insn, CCC));
- break;
-
- case 'N':
- infprintf (is,
- (op->pinfo & (FP_D | FP_S)) != 0
- ? "$fcc%d" : "$cc%d",
- GET_OP (insn, BCC));
- break;
-
- case 'R':
- infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
- break;
-
- case 'S':
- case 'V':
- infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
- break;
-
- case 'T':
- infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
- break;
-
- case '+':
- /* Extension character; switch for second char. */
- s++;
- switch (*s)
- {
- case 'A':
- lsb = GET_OP (insn, EXTLSB);
- infprintf (is, "0x%x", lsb);
- break;
-
- case 'B':
- msb = GET_OP (insn, INSMSB);
- infprintf (is, "0x%x", msb - lsb + 1);
- break;
-
- case 'C':
- case 'H':
- msbd = GET_OP (insn, EXTMSBD);
- infprintf (is, "0x%x", msbd + 1);
- break;
-
- case 'D':
- {
- const struct mips_cp0sel_name *n;
- unsigned int cp0reg, sel;
-
- cp0reg = GET_OP (insn, RS);
- sel = GET_OP (insn, SEL);
-
- /* CP0 register including 'sel' code for mtcN
- (et al.), to be printed textually if known.
- If not known, print both CP0 register name and
- sel numerically since CP0 register with sel 0 may
- have a name unrelated to register being printed. */
- n = lookup_mips_cp0sel_name (mips_cp0sel_names,
- mips_cp0sel_names_len,
- cp0reg, sel);
- if (n != NULL)
- infprintf (is, "%s", n->name);
- else
- infprintf (is, "$%d,%d", cp0reg, sel);
- break;
- }
-
- case 'E':
- lsb = GET_OP (insn, EXTLSB) + 32;
- infprintf (is, "0x%x", lsb);
- break;
-
- case 'F':
- msb = GET_OP (insn, INSMSB) + 32;
- infprintf (is, "0x%x", msb - lsb + 1);
- break;
-
- case 'G':
- msbd = GET_OP (insn, EXTMSBD) + 32;
- infprintf (is, "0x%x", msbd + 1);
- break;
-
- default:
- /* xgettext:c-format */
- infprintf (is,
- _("# internal disassembler error, "
- "unrecognized modifier (+%c)"),
- *s);
- abort ();
- }
- break;
-
- case 'm':
- /* Extension character; switch for second char. */
- s++;
- switch (*s)
- {
- case 'a': /* global pointer. */
- infprintf (is, "%s", mips_gpr_names[28]);
- break;
-
- case 'b':
- regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'c':
- regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'd':
- regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'e':
- regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'f':
- /* Save lastregno for "mt" to print out later. */
- lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
- infprintf (is, "%s", mips_gpr_names[lastregno]);
- break;
-
- case 'g':
- regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'h':
- regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'i':
- regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'j':
- infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
- break;
-
- case 'l':
- regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'm':
- regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'n':
- regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'p':
- /* Save lastregno for "mt" to print out later. */
- lastregno = GET_OP (insn, MP);
- infprintf (is, "%s", mips_gpr_names[lastregno]);
- break;
-
- case 'q':
- regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
- infprintf (is, "%s", mips_gpr_names[regno]);
- break;
-
- case 'r': /* program counter. */
- infprintf (is, "$pc");
- break;
-
- case 's': /* stack pointer. */
- lastregno = 29;
- infprintf (is, "%s", mips_gpr_names[29]);
- break;
-
- case 't':
- infprintf (is, "%s", mips_gpr_names[lastregno]);
- break;
-
- case 'z': /* $0. */
- infprintf (is, "%s", mips_gpr_names[0]);
- break;
-
- case 'A':
- /* Sign-extend the immediate. */
- immed = GET_OP_S (insn, IMMA) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'B':
- immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
- infprintf (is, "%d", immed);
- break;
-
- case 'C':
- immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
- infprintf (is, "0x%x", immed);
- break;
-
- case 'D':
- /* Sign-extend the displacement. */
- delta = GET_OP_S (insn, IMMD);
- info->target = (delta << 1) + memaddr + length;
- (*info->print_address_func) (info->target, info);
- break;
-
- case 'E':
- /* Sign-extend the displacement. */
- delta = GET_OP_S (insn, IMME);
- info->target = (delta << 1) + memaddr + length;
- (*info->print_address_func) (info->target, info);
- break;
-
- case 'F':
- immed = GET_OP (insn, IMMF);
- infprintf (is, "0x%x", immed);
- break;
-
- case 'G':
- immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
- immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
- infprintf (is, "%d", immed);
- break;
-
- case 'H':
- immed = GET_OP (insn, IMMH) << 1;
- infprintf (is, "%d", immed);
- break;
-
- case 'I':
- immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
- immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
- infprintf (is, "%d", immed);
- break;
-
- case 'J':
- immed = GET_OP (insn, IMMJ) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'L':
- immed = GET_OP (insn, IMML);
- infprintf (is, "%d", immed);
- break;
-
- case 'M':
- immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
- immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
- infprintf (is, "%d", immed);
- break;
-
- case 'N':
- immed = GET_OP (insn, IMMN);
- if (immed == 0)
- infprintf (is, "%s,%s",
- mips_gpr_names[16],
- mips_gpr_names[31]);
- else
- infprintf (is, "%s-%s,%s",
- mips_gpr_names[16],
- mips_gpr_names[16 + immed],
- mips_gpr_names[31]);
- break;
-
- case 'O':
- immed = GET_OP (insn, IMMO);
- infprintf (is, "0x%x", immed);
- break;
-
- case 'P':
- immed = GET_OP (insn, IMMP) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'Q':
- /* Sign-extend the immediate. */
- immed = GET_OP_S (insn, IMMQ) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'U':
- immed = GET_OP (insn, IMMU) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'W':
- immed = GET_OP (insn, IMMW) << 2;
- infprintf (is, "%d", immed);
- break;
-
- case 'X':
- /* Sign-extend the immediate. */
- immed = GET_OP_S (insn, IMMX);
- infprintf (is, "%d", immed);
- break;
-
- case 'Y':
- /* Sign-extend the immediate. */
- immed = GET_OP_S (insn, IMMY) << 2;
- if ((unsigned int) (immed + 8) < 16)
- immed ^= 0x400;
- infprintf (is, "%d", immed);
- break;
-
- default:
- /* xgettext:c-format */
- infprintf (is,
- _("# internal disassembler error, "
- "unrecognized modifier (m%c)"),
- *s);
- abort ();
- }
- break;
-
- default:
- /* xgettext:c-format */
- infprintf (is,
- _("# internal disassembler error, "
- "unrecognized modifier (%c)"),
- *s);
- abort ();
- }