forked from Imagelibrary/binutils-gdb
Add support for MIPS R6.
bfd/ * aoutx.h (NAME (aout, machine_type)): Add mips32r6 and mips64r6. * archures.c (bfd_architecture): Likewise. * bfd-in2.h (bfd_architecture): Likewise. (bfd_reloc_code_real): Add relocs BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3 and BFD_RELOC_MIPS_19_PCREL_S2. * cpu-mips.c (arch_info_struct): Add mips32r6 and mips64r6. * elf32-mips.c: Define relocs R_MIPS_PC21_S2, R_MIPS_PC26_S2 R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16 and R_MIPS_PCLO16. (mips_reloc_map): Add entries for BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and BFD_RELOC_LO16_PCREL. * elf64-mips.c: Define REL, and RELA relocations R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16 and R_MIPS_PCLO16. (mips_reloc_map): Add entries for BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and BFD_RELOC_LO16_PCREL. * elfn32-mips.c: Likewise. * elfxx-mips.c (MIPSR6_P): New define. (mipsr6_exec_plt_entry): New array. (hi16_reloc_p): Add support for R_MIPS_PCHI16. (lo16_reloc_p): Add support for R_MIPS_PCLO16. (aligned_pcrel_reloc_p): New function. (mips_elf_relocation_needs_la25_stub): Add support for relocs: R_MIPS_PC21_S2 and R_MIPS_PC26_S2. (mips_elf_calculate_relocation): Add support for relocs: R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16 and R_MIPS_PCLO16. (_bfd_elf_mips_mach): Add support for mips32r6 and mips64r6. (mips_elf_add_lo16_rel_addend): Add support for R_MIPS_PCHI16. (_bfd_mips_elf_check_relocs): Add support for relocs: R_MIPS_PC21_S2 and R_MIPS_PC26_S2. (_bfd_mips_elf_relocate_section): Add a check for unaligned pc relative relocs. (_bfd_mips_elf_finish_dynamic_symbol): Add support for MIPS r6 plt entry. (mips_set_isa_flags): Add support for mips32r6 and mips64r6. (_bfd_mips_elf_print_private_bfd_data): Likewise. (mips_32bit_flags_p): Add support for mips32r6. * libbfd.h (bfd_reloc_code_real_names): Add entries for BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3 and BFD_RELOC_MIPS_19_PCREL_S2. * reloc.c: Document relocs BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3 and BFD_RELOC_MIPS_19_PCREL_S2. binutils/ * readelf.c (get_machine_flags): Add support for mips32r6 and mips64r6. elfcpp/ * mips.h (E_MIPS_ARCH_32R6, E_MIPS_ARCH_64R6): New enum constants. gas/ * config/tc-mips.c (mips_nan2008): New static global. (mips_flag_nan2008): Removed. (LL_SC_FMT): New define. (COP12_FMT): Updated. (ISA_IS_R6): New define. (ISA_HAS_64BIT_REGS): Add mips64r6. (ISA_HAS_DROR): Likewise. (ISA_HAS_64BIT_FPRS): Add mips32r6 and mips64r6. (ISA_HAS_ROR): Likewise. (ISA_HAS_ODD_SINGLE_FPR): Likewise. (ISA_HAS_MXHC1): Likewise. (hilo_interlocks): Likewise. (md_longopts): Likewise. (ISA_HAS_LEGACY_NAN): New define. (options): Add OPTION_MIPS32R6 and OPTION_MIPS64R6. (mips_ase): Add field rem_rev. (mips_ases): Updated to add which ISA an ASE was removed in. (mips_isa_rev): Add support for mips32r6 and mips64r6. (mips_check_isa_supports_ase): Add support to check if an ASE has been removed in the specified MIPS ISA revision. (validate_mips_insn): Skip '-' character. (macro_build): Likewise. (mips_check_options): Prevent R6 working with fp32, mips16, micromips, or branch relaxation. (file_mips_check_options): Set R6 floating point registers to 64 bit. Also deal with the nan2008 option. (limited_pcrel_reloc_p): Add relocs: BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and BFD_RELOC_LO16_PCREL. (operand_reg_mask): Add support for OP_SAME_RS_RT, OP_CHECK_PREV and OP_NON_ZERO_REG. (match_check_prev_operand): New static function. (match_same_rs_rt_operand): New static function. (match_non_zero_reg_operand): New static function. (match_operand): Added entries for: OP_SAME_RS_RT, OP_CHECK_PREV and OP_NON_ZERO_REG. (insns_between): Added case to deal with forbidden slots. (append_insn): Added support for relocs: BFD_RELOC_MIPS_21_PCREL_S2 and BFD_RELOC_MIPS_26_PCREL_S2. (match_insn): Add support for operands -A, -B, +' and +". Also skip '-' character. (mips_percent_op): Add entries for %pcrel_hi and %pcrel_lo. (md_parse_option): Add support for mips32r6 and mips64r6. Also update the nan option handling. (md_pcrel_from): Add cases for relocs: BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2. (mips_force_relocation): Prevent forced relaxation for MIPS r6. (md_apply_fix): Add support for relocs: BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and BFD_RELOC_LO16_PCREL. (s_mipsset): Add support for mips32r6 and mips64r6. (s_nan): Update to support the new nan2008 framework. (tc_gen_reloc): Add relocs: BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and BFD_RELOC_LO16_PCREL. (mips_elf_final_processing): Updated to use the mips_nan2008. (mips_cpu_info_table): Add entries for mips32r6 and mips64r6. (macro): Enable ldc2, sdc2, ll, lld, swc2, sc, scd, cache, pref macros for R6. (mips_fix_adjustable): Make PC relative R6 relocations relative to the symbol and not the section. * configure.ac: Add support for mips32r6 and mips64r6. * configure: Regenerate. * doc/c-mips.texi: Document the -mips32r6 and -mips64r6 command line options. * doc/as.texinfo: Likewise. gas/testsuite/ * gas/mips/24k-triple-stores-1.s: If testing for r6 prevent non-supported instructions from being tested. * gas/mips/24k-triple-stores-2.s: Likewise. * gas/mips/24k-triple-stores-3.s: Likewise. * gas/mips/24k-triple-stores-6.s: Likewise. * gas/mips/beq.s: Likewise. * gas/mips/eva.s: Likewise. * gas/mips/ld-zero-3.s: Likewise. * gas/mips/mips32-cp2.s: Likewise. * gas/mips/mips32.s: Likewise. * gas/mips/mips4.s: Likewise. * gas/mips/add.s: Don't test the add instructions if r6, and add padding. * gas/mips/add.d: Check for a triple dot not a nop at the end of the disassembly output. * gas/mips/micromips@add.d: Likewise. * gas/mips/mipsr6@24k-branch-delay-1.d: New file. * gas/mips/mipsr6@24k-triple-stores-1.d: New file. * gas/mips/mipsr6@24k-triple-stores-2-llsc.d: New file. * gas/mips/mipsr6@24k-triple-stores-2.d: New file. * gas/mips/mipsr6@24k-triple-stores-3.d: New file. * gas/mips/mipsr6@24k-triple-stores-6.d: New file. * gas/mips/mipsr6@add.d: New file. * gas/mips/mipsr6@attr-gnu-4-1-msingle-float.l: New file. * gas/mips/mipsr6@attr-gnu-4-1-msingle-float.s: New file. * gas/mips/mipsr6@attr-gnu-4-1-msoft-float.l: New file. * gas/mips/mipsr6@attr-gnu-4-1-msoft-float.s: New file. * gas/mips/mipsr6@attr-gnu-4-2-mdouble-float.l: New file. * gas/mips/mipsr6@attr-gnu-4-2-mdouble-float.s: New file. * gas/mips/mipsr6@beq.d: New file. * gas/mips/mipsr6@bge.d: New file. * gas/mips/mipsr6@bgeu.d: New file. * gas/mips/mipsr6@blt.d: New file. * gas/mips/mipsr6@bltu.d: New file. * gas/mips/mipsr6@branch-misc-1.d: New file. * gas/mips/mipsr6@branch-misc-2-64.d: New file. * gas/mips/mipsr6@branch-misc-2pic-64.d: New file. * gas/mips/mipsr6@branch-misc-4-64.d: New file. * gas/mips/mipsr6@cache.d: New file. * gas/mips/mipsr6@eva.d: New file. * gas/mips/mipsr6@jal-svr4pic-noreorder.d: New file. * gas/mips/mipsr6@jal-svr4pic.d: New file. * gas/mips/mipsr6@ld-zero-2.d: New file. * gas/mips/mipsr6@ld-zero-3.d: New file. * gas/mips/mipsr6@loc-swap-dis.d: New file. * gas/mips/mipsr6@mips32-cp2.d: New file. * gas/mips/mipsr6@mips32-imm.d: New file. * gas/mips/mipsr6@mips32.d: New file. * gas/mips/mipsr6@mips32r2.d: New file. * gas/mips/mipsr6@mips4-fp.d: New file. * gas/mips/mipsr6@mips4-fp.l: New file. * gas/mips/mipsr6@mips4-fp.s: New file. * gas/mips/mipsr6@mips4.d: New file. * gas/mips/mipsr6@mips5-fp.d: New file. * gas/mips/mipsr6@mips5-fp.l: New file. * gas/mips/mipsr6@mips5-fp.s: New file. * gas/mips/mipsr6@mips64.d: New file. * gas/mips/mipsr6@msa-branch.d: New file. * gas/mips/mipsr6@msa.d: New file. * gas/mips/mipsr6@pref.d: New file. * gas/mips/mipsr6@relax-swap3.d: New file. * gas/mips/r6-64-n32.d: New file. * gas/mips/r6-64-n64.d: New file. * gas/mips/r6-64-removed.l: New file. * gas/mips/r6-64-removed.s: New file. * gas/mips/r6-64.s: New file. * gas/mips/r6-attr-none-double.d: New file. * gas/mips/r6-n32.d: New file. * gas/mips/r6-n64.d: New file. * gas/mips/r6-removed.l: New file. * gas/mips/r6-removed.s: New file. * gas/mips/r6.d: New file. * gas/mips/r6.s: New file. * gas/mips/mipsr6@mips32-dsp.d: New file. * gas/mips/mipsr6@mips32-dspr2.d: New file. * gas/mips/mipsr6@mips32r2-ill.l: New file. * gas/mips/mipsr6@mips32r2-ill.s: New file. * gas/mips/cache.s: Add r6 instruction varients. * gas/mips/mips.exp: Add support for the mips32r6 and mips64r6 architectures. Also prevent non r6 supported tests from running. Finally, add in support for running the new r6 tests. (run_dump_test_arch): Add support for mipsr6 tests. (run_list_test_arch): Add support for using files of the form arch@testname.l . include/elf/ * mips.h: Add relocs: R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16 and R_MIPS_PCLO16. (E_MIPS_ARCH_32R6): New define. (E_MIPS_ARCH_64R6): New define. include/opcode/ * mips.h (mips_operand_type): Add new entries: OP_SAME_RS_RT, OP_CHECK_PREV and OP_NON_ZERO_REG. Add descriptions for the MIPS R6 instruction arguments: -a, -b, -d, -s, -t, -u, -v, -w, -x, -y, -A, -B, +I, +O, +R, +:, +\, +", +; (mips_check_prev_operand): New struct. (INSN2_FORBIDDEN_SLOT): New define. (INSN_ISA32R6): New define. (INSN_ISA64R6): New define. (INSN_UPTO32R6): New define. (INSN_UPTO64R6): New define. (mips_isa_table): Add INSN_UPTO32R6 and INSN_UPTO64R6. (ISA_MIPS32R6): New define. (ISA_MIPS64R6): New define. (CPU_MIPS32R6): New define. (CPU_MIPS64R6): New define. (cpu_is_member): Add cases for CPU_MIPS32R6, and CPU_MIPS64R6. ld/ * ldmain.c (get_emulation): Add support for -mips32r6 and -mips64r6. opcodes/ * mips-dis.c (mips_arch_choices): Add entries for mips32r6 and mips64r6. (parse_mips_dis_option): Allow MSA and virtualization support for mips64r6. (mips_print_arg_state): Add fields dest_regno and seen_dest. (mips_seen_register): New function. (print_insn_arg): Refactored code to use mips_seen_register function. Add support for OP_SAME_RS_RT, OP_CHECK_PREV and OP_NON_ZERO_REG. Changed OP_REPEAT_DEST_REG case to print out the register rather than aborting. (print_insn_args): Add length argument. Add code to correctly calculate the instruction address for pc relative instructions. (validate_insn_args): New static function. (print_insn_mips): Prevent jalx disassembling for r6. Use validate_insn_args. (print_insn_micromips): Use validate_insn_args. all the arguments are valid. * mips-formats.h (PREV_CHECK): New define. * mips-opc.c (decode_mips_operand): Add support for -a, -b, -d, -s, -t, -u, -v, -w, -x, -y, -A, -B, +I, +O, +R, +:, +\, +", +; (RD_pc): New define. (FS): New define. (I37): New define. (I69): New define. (mips_builtin_opcodes): Add MIPS R6 instructions. Exclude recoded MIPS R6 instructions from MIPS R2 instructions.
This commit is contained in:
@@ -572,6 +572,14 @@ const struct mips_arch_choice mips_arch_choices[] =
|
||||
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
|
||||
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
|
||||
|
||||
{ "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
|
||||
ISA_MIPS32R6,
|
||||
(ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
|
||||
| ASE_DSPR2),
|
||||
mips_cp0_names_mips3264r2,
|
||||
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
|
||||
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
|
||||
|
||||
/* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
|
||||
{ "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
|
||||
ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
|
||||
@@ -603,6 +611,14 @@ const struct mips_arch_choice mips_arch_choices[] =
|
||||
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
|
||||
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
|
||||
|
||||
{ "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
|
||||
ISA_MIPS64R6,
|
||||
(ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
|
||||
| ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2),
|
||||
mips_cp0_names_mips3264r2,
|
||||
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
|
||||
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
|
||||
|
||||
{ "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
|
||||
ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
|
||||
mips_cp0_names_sb1,
|
||||
@@ -832,7 +848,8 @@ parse_mips_dis_option (const char *option, unsigned int len)
|
||||
mips_ase |= ASE_MSA;
|
||||
if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5)
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
|
||||
mips_ase |= ASE_MSA64;
|
||||
return;
|
||||
}
|
||||
@@ -842,7 +859,8 @@ parse_mips_dis_option (const char *option, unsigned int len)
|
||||
mips_ase |= ASE_VIRT;
|
||||
if (mips_isa & ISA_MIPS64R2
|
||||
|| mips_isa & ISA_MIPS64R3
|
||||
|| mips_isa & ISA_MIPS64R5)
|
||||
|| mips_isa & ISA_MIPS64R5
|
||||
|| mips_isa & ISA_MIPS64R6)
|
||||
mips_ase |= ASE_VIRT64;
|
||||
return;
|
||||
}
|
||||
@@ -1084,6 +1102,8 @@ struct mips_print_arg_state {
|
||||
OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
|
||||
enum mips_reg_operand_type last_reg_type;
|
||||
unsigned int last_regno;
|
||||
unsigned int dest_regno;
|
||||
unsigned int seen_dest;
|
||||
};
|
||||
|
||||
/* Initialize STATE for the start of an instruction. */
|
||||
@@ -1113,6 +1133,23 @@ print_vu0_channel (struct disassemble_info *info,
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Record information about a register operand. */
|
||||
|
||||
static void
|
||||
mips_seen_register (struct mips_print_arg_state *state,
|
||||
unsigned int regno,
|
||||
enum mips_reg_operand_type reg_type)
|
||||
{
|
||||
state->last_reg_type = reg_type;
|
||||
state->last_regno = regno;
|
||||
|
||||
if (!state->seen_dest)
|
||||
{
|
||||
state->seen_dest = 1;
|
||||
state->dest_regno = regno;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
|
||||
UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
|
||||
the base address for OP_PCREL operands. */
|
||||
@@ -1179,8 +1216,7 @@ print_insn_arg (struct disassemble_info *info,
|
||||
uval = mips_decode_reg_operand (reg_op, uval);
|
||||
print_reg (info, opcode, reg_op->reg_type, uval);
|
||||
|
||||
state->last_reg_type = reg_op->reg_type;
|
||||
state->last_regno = uval;
|
||||
mips_seen_register (state, uval, reg_op->reg_type);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1246,6 +1282,15 @@ print_insn_arg (struct disassemble_info *info,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SAME_RS_RT:
|
||||
case OP_CHECK_PREV:
|
||||
case OP_NON_ZERO_REG:
|
||||
{
|
||||
print_reg (info, opcode, OP_REG_GP, uval & 31);
|
||||
mips_seen_register (state, uval, OP_REG_GP);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_LWM_SWM_LIST:
|
||||
if (operand->size == 2)
|
||||
{
|
||||
@@ -1368,8 +1413,8 @@ print_insn_arg (struct disassemble_info *info,
|
||||
break;
|
||||
|
||||
case OP_REPEAT_DEST_REG:
|
||||
/* Should always match OP_REPEAT_PREV_REG first. */
|
||||
abort ();
|
||||
print_reg (info, opcode, state->last_reg_type, state->dest_regno);
|
||||
break;
|
||||
|
||||
case OP_PC:
|
||||
infprintf (is, "$pc");
|
||||
@@ -1392,15 +1437,130 @@ print_insn_arg (struct disassemble_info *info,
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate the arguments for INSN, which is described by OPCODE.
|
||||
Use DECODE_OPERAND to get the encoding of each operand. */
|
||||
|
||||
static bfd_boolean
|
||||
validate_insn_args (const struct mips_opcode *opcode,
|
||||
const struct mips_operand *(*decode_operand) (const char *),
|
||||
unsigned int insn)
|
||||
{
|
||||
struct mips_print_arg_state state;
|
||||
const struct mips_operand *operand;
|
||||
const char *s;
|
||||
unsigned int uval;
|
||||
|
||||
init_print_arg_state (&state);
|
||||
for (s = opcode->args; *s; ++s)
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
case ',':
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case '#':
|
||||
++s;
|
||||
break;
|
||||
|
||||
default:
|
||||
operand = decode_operand (s);
|
||||
|
||||
if (operand)
|
||||
{
|
||||
uval = mips_extract_operand (operand, insn);
|
||||
switch (operand->type)
|
||||
{
|
||||
case OP_REG:
|
||||
case OP_OPTIONAL_REG:
|
||||
{
|
||||
const struct mips_reg_operand *reg_op;
|
||||
|
||||
reg_op = (const struct mips_reg_operand *) operand;
|
||||
uval = mips_decode_reg_operand (reg_op, uval);
|
||||
mips_seen_register (&state, uval, reg_op->reg_type);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SAME_RS_RT:
|
||||
{
|
||||
unsigned int reg1, reg2;
|
||||
|
||||
reg1 = uval & 31;
|
||||
reg2 = uval >> 5;
|
||||
|
||||
if (reg1 != reg2 || reg1 == 0)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_CHECK_PREV:
|
||||
{
|
||||
const struct mips_check_prev_operand *prev_op;
|
||||
|
||||
prev_op = (const struct mips_check_prev_operand *) operand;
|
||||
|
||||
if (!prev_op->zero_ok && uval == 0)
|
||||
return FALSE;
|
||||
|
||||
if (((prev_op->less_than_ok && uval < state.last_regno)
|
||||
|| (prev_op->greater_than_ok && uval > state.last_regno)
|
||||
|| (prev_op->equal_ok && uval == state.last_regno)))
|
||||
break;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case OP_NON_ZERO_REG:
|
||||
{
|
||||
if (uval == 0)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_INT:
|
||||
case OP_MAPPED_INT:
|
||||
case OP_MSB:
|
||||
case OP_REG_PAIR:
|
||||
case OP_PCREL:
|
||||
case OP_PERF_REG:
|
||||
case OP_ADDIUSP_INT:
|
||||
case OP_CLO_CLZ_DEST:
|
||||
case OP_LWM_SWM_LIST:
|
||||
case OP_ENTRY_EXIT_LIST:
|
||||
case OP_MDMX_IMM_REG:
|
||||
case OP_REPEAT_PREV_REG:
|
||||
case OP_REPEAT_DEST_REG:
|
||||
case OP_PC:
|
||||
case OP_VU0_SUFFIX:
|
||||
case OP_VU0_MATCH_SUFFIX:
|
||||
case OP_IMM_INDEX:
|
||||
case OP_REG_INDEX:
|
||||
break;
|
||||
|
||||
case OP_SAVE_RESTORE_LIST:
|
||||
/* Should be handled by the caller due to extend behavior. */
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (*s == 'm' || *s == '+' || *s == '-')
|
||||
++s;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Print the arguments for INSN, which is described by OPCODE.
|
||||
Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
|
||||
as the base of OP_PCREL operands. */
|
||||
as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
|
||||
operand is for a branch or jump. */
|
||||
|
||||
static void
|
||||
print_insn_args (struct disassemble_info *info,
|
||||
const struct mips_opcode *opcode,
|
||||
const struct mips_operand *(*decode_operand) (const char *),
|
||||
unsigned int insn, bfd_vma base_pc)
|
||||
unsigned int insn, bfd_vma insn_pc, unsigned int length)
|
||||
{
|
||||
const fprintf_ftype infprintf = info->fprintf_func;
|
||||
void *is = info->stream;
|
||||
@@ -1462,9 +1622,27 @@ print_insn_args (struct disassemble_info *info,
|
||||
infprintf (is, "$%d,%d", reg, sel);
|
||||
}
|
||||
else
|
||||
print_insn_arg (info, &state, opcode, operand, base_pc,
|
||||
mips_extract_operand (operand, insn));
|
||||
if (*s == 'm' || *s == '+')
|
||||
{
|
||||
bfd_vma base_pc = insn_pc;
|
||||
|
||||
/* Adjust the PC relative base so that branch/jump insns use
|
||||
the following PC as the base but genuinely PC relative
|
||||
operands use the current PC. */
|
||||
if (operand->type == OP_PCREL)
|
||||
{
|
||||
const struct mips_pcrel_operand *pcrel_op;
|
||||
|
||||
pcrel_op = (const struct mips_pcrel_operand *) operand;
|
||||
/* The include_isa_bit flag is sufficient to distinguish
|
||||
branch/jump from other PC relative operands. */
|
||||
if (pcrel_op->include_isa_bit)
|
||||
base_pc += length;
|
||||
}
|
||||
|
||||
print_insn_arg (info, &state, opcode, operand, base_pc,
|
||||
mips_extract_operand (operand, insn));
|
||||
}
|
||||
if (*s == 'm' || *s == '+' || *s == '-')
|
||||
++s;
|
||||
break;
|
||||
}
|
||||
@@ -1530,9 +1708,11 @@ print_insn_mips (bfd_vma memaddr,
|
||||
&& !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
|
||||
&& (word & op->mask) == op->match)
|
||||
{
|
||||
/* We always allow to disassemble the jalx instruction. */
|
||||
/* We always disassemble the jalx instruction, except for MIPS r6. */
|
||||
if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
|
||||
&& strcmp (op->name, "jalx"))
|
||||
&& (strcmp (op->name, "jalx")
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
|
||||
|| (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
|
||||
continue;
|
||||
|
||||
/* Figure out instruction type and branch delay information. */
|
||||
@@ -1557,6 +1737,9 @@ print_insn_mips (bfd_vma memaddr,
|
||||
| INSN_LOAD_MEMORY)) != 0)
|
||||
info->insn_type = dis_dref;
|
||||
|
||||
if (!validate_insn_args (op, decode_mips_operand, word))
|
||||
continue;
|
||||
|
||||
infprintf (is, "%s", op->name);
|
||||
if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
|
||||
{
|
||||
@@ -1571,7 +1754,7 @@ print_insn_mips (bfd_vma memaddr,
|
||||
{
|
||||
infprintf (is, "\t");
|
||||
print_insn_args (info, op, decode_mips_operand, word,
|
||||
memaddr + 4);
|
||||
memaddr, 4);
|
||||
}
|
||||
|
||||
return INSNLEN;
|
||||
@@ -2077,13 +2260,16 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
|
||||
&& ((length == 2 && (op->mask & 0xffff0000) == 0)
|
||||
|| (length == 4 && (op->mask & 0xffff0000) != 0)))
|
||||
{
|
||||
if (!validate_insn_args (op, decode_micromips_operand, insn))
|
||||
continue;
|
||||
|
||||
infprintf (is, "%s", op->name);
|
||||
|
||||
if (op->args[0])
|
||||
{
|
||||
infprintf (is, "\t");
|
||||
print_insn_args (info, op, decode_micromips_operand, insn,
|
||||
memaddr + length + 1);
|
||||
memaddr + 1, length);
|
||||
}
|
||||
|
||||
/* Figure out instruction type and branch delay information. */
|
||||
|
||||
Reference in New Issue
Block a user