diff options
author | Steve Ellcey <Steve.Ellcey@imgtec.com> | 2014-12-18 10:41:50 -0800 |
---|---|---|
committer | Steve Ellcey <Steve.Ellcey@imgtec.com> | 2014-12-18 10:41:50 -0800 |
commit | b3e9a4171187f64c03d1858c2c840113df6b02de (patch) | |
tree | 24ed906374d33eabcbd3cfccc5d5b6ea9b4f5f51 /binutils-2.25/gas/config/tc-mips.c | |
parent | bbff162609624c737f72b070e2b53aeb5ed1e958 (diff) | |
download | toolchain_binutils-b3e9a4171187f64c03d1858c2c840113df6b02de.zip toolchain_binutils-b3e9a4171187f64c03d1858c2c840113df6b02de.tar.gz toolchain_binutils-b3e9a4171187f64c03d1858c2c840113df6b02de.tar.bz2 |
Add MIPS specific changes to binutils 2.25 (prerelease) for MIPSR6 bug fixes,
MXU support, and a fix to needed by gdbserver.
Diffstat (limited to 'binutils-2.25/gas/config/tc-mips.c')
-rw-r--r-- | binutils-2.25/gas/config/tc-mips.c | 184 |
1 files changed, 172 insertions, 12 deletions
diff --git a/binutils-2.25/gas/config/tc-mips.c b/binutils-2.25/gas/config/tc-mips.c index cfc4fa5..0f7e0c5 100644 --- a/binutils-2.25/gas/config/tc-mips.c +++ b/binutils-2.25/gas/config/tc-mips.c @@ -1409,10 +1409,14 @@ enum options OPTION_NO_SMARTMIPS, OPTION_DSPR2, OPTION_NO_DSPR2, + OPTION_DSPR6, + OPTION_NO_DSPR6, OPTION_EVA, OPTION_NO_EVA, OPTION_XPA, OPTION_NO_XPA, + OPTION_MXU, + OPTION_NO_MXU, OPTION_MICROMIPS, OPTION_NO_MICROMIPS, OPTION_MCU, @@ -1521,6 +1525,8 @@ struct option md_longopts[] = {"mno-smartmips", no_argument, NULL, OPTION_NO_SMARTMIPS}, {"mdspr2", no_argument, NULL, OPTION_DSPR2}, {"mno-dspr2", no_argument, NULL, OPTION_NO_DSPR2}, + {"mdspr6", no_argument, NULL, OPTION_DSPR6}, + {"mno-dspr6", no_argument, NULL, OPTION_NO_DSPR6}, {"meva", no_argument, NULL, OPTION_EVA}, {"mno-eva", no_argument, NULL, OPTION_NO_EVA}, {"mmicromips", no_argument, NULL, OPTION_MICROMIPS}, @@ -1533,6 +1539,8 @@ struct option md_longopts[] = {"mno-msa", no_argument, NULL, OPTION_NO_MSA}, {"mxpa", no_argument, NULL, OPTION_XPA}, {"mno-xpa", no_argument, NULL, OPTION_NO_XPA}, + {"mmxu", no_argument, NULL, OPTION_MXU}, + {"mno-mxu", no_argument, NULL, OPTION_NO_MXU}, /* Old-style architecture options. Don't add more of these. */ {"m4650", no_argument, NULL, OPTION_M4650}, @@ -1662,6 +1670,11 @@ static const struct mips_ase mips_ases[] = { 2, 2, 2, 2, -1 }, + { "dspr6", ASE_DSP | ASE_DSPR2 | ASE_DSPR6, 0, + OPTION_DSPR6, OPTION_NO_DSPR6, + 6, 6, 6, 6, + -1 }, + { "eva", ASE_EVA, 0, OPTION_EVA, OPTION_NO_EVA, 2, 2, 2, 2, @@ -1708,6 +1721,11 @@ static const struct mips_ase mips_ases[] = { OPTION_XPA, OPTION_NO_XPA, 2, 2, -1, -1, -1 }, + + { "mxu", ASE_MXU, 0, + OPTION_MXU, OPTION_NO_MXU, + 1, 1, -1, -1, + -1 }, }; /* The set of ASEs that require -mfp64. */ @@ -1715,7 +1733,7 @@ static const struct mips_ase mips_ases[] = { /* Groups of ASE_* flags that represent different revisions of an ASE. */ static const unsigned int mips_ase_groups[] = { - ASE_DSP | ASE_DSPR2 + ASE_DSP | ASE_DSPR2 | ASE_DSPR6 }; /* Pseudo-op table. @@ -2490,7 +2508,7 @@ struct regname { }; #define RNUM_MASK 0x00000ff -#define RTYPE_MASK 0x0ffff00 +#define RTYPE_MASK 0x1ffff00 #define RTYPE_NUM 0x0000100 #define RTYPE_FPU 0x0000200 #define RTYPE_FCC 0x0000400 @@ -2507,6 +2525,7 @@ struct regname { #define RTYPE_R5900_R 0x0200000 #define RTYPE_R5900_ACC 0x0400000 #define RTYPE_MSA 0x0800000 +#define RTYPE_MXU 0x1000000 #define RWARN 0x8000000 #define GENERIC_REGISTER_NUMBERS \ @@ -2711,6 +2730,26 @@ struct regname { {"$ac2", RTYPE_ACC | 2}, \ {"$ac3", RTYPE_ACC | 3} +#define MXU_REGISTER_NAMES \ + {"xr0", RTYPE_MXU | 0}, \ + {"xr1", RTYPE_MXU | 1}, \ + {"xr2", RTYPE_MXU | 2}, \ + {"xr3", RTYPE_MXU | 3}, \ + {"xr4", RTYPE_MXU | 4}, \ + {"xr5", RTYPE_MXU | 5}, \ + {"xr6", RTYPE_MXU | 6}, \ + {"xr7", RTYPE_MXU | 7}, \ + {"xr8", RTYPE_MXU | 8}, \ + {"xr9", RTYPE_MXU | 9}, \ + {"xr10", RTYPE_MXU | 10}, \ + {"xr11", RTYPE_MXU | 11}, \ + {"xr12", RTYPE_MXU | 12}, \ + {"xr13", RTYPE_MXU | 13}, \ + {"xr14", RTYPE_MXU | 14}, \ + {"xr15", RTYPE_MXU | 15}, \ + {"xr16", RTYPE_MXU | 16}, \ + {"mxu_cr", RTYPE_MXU | 16} + static const struct regname reg_names[] = { GENERIC_REGISTER_NUMBERS, FPU_REGISTER_NAMES, @@ -2730,6 +2769,7 @@ static const struct regname reg_names[] = { R5900_R_NAMES, R5900_ACC_NAMES, MIPS_DSP_ACCUMULATOR_NAMES, + MXU_REGISTER_NAMES, {0, 0} }; @@ -3361,7 +3401,7 @@ validate_mips_insn (const struct mips_opcode *opcode, used_bits &= ~(mask & 0x700); } /* Skip prefix characters. */ - if (decode_operand && (*s == '+' || *s == 'm' || *s == '-')) + if (decode_operand && (*s == '+' || *s == 'm' || *s == '-' || *s == '`')) ++s; opno += 1; break; @@ -4415,6 +4455,8 @@ operand_reg_mask (const struct mips_cl_insn *insn, case OP_VU0_SUFFIX: case OP_VU0_MATCH_SUFFIX: case OP_IMM_INDEX: + case OP_MAPPED_STRING: + case OP_MXU_STRIDE: abort (); case OP_REG: @@ -4788,6 +4830,12 @@ convert_reg_type (const struct mips_opcode *opcode, { switch (type) { + case OP_REG_MXU: + return RTYPE_NUM | RTYPE_MXU; + + case OP_REG_MXU_GP: + return RTYPE_GP | RTYPE_MXU; + case OP_REG_GP: return RTYPE_NUM | RTYPE_GP; @@ -5113,6 +5161,65 @@ match_msb_operand (struct mips_arg_info *arg, return TRUE; } + +/* OP_MAPPED_STRING matcher. */ + +static bfd_boolean +match_string_operand (struct mips_arg_info *arg, + const struct mips_operand *operand_base) +{ + const struct mips_mapped_string_operand *operand; + expressionS ex; + bfd_reloc_code_real_type r[3]; + int i; + unsigned int store_val; + const char * symbol_name; + bfd_boolean match; + + operand = (const struct mips_mapped_string_operand *) operand_base; + + if (!match_expression (arg, &ex, r)) + return FALSE; + + if (operand->allow_constants && ex.X_op == O_constant + && r[0] == BFD_RELOC_UNUSED) + store_val = ex.X_add_number; + else if (r[0] == BFD_RELOC_UNUSED && ex.X_op == O_symbol + && ex.X_add_number == 0 && ex.X_op_symbol == NULL) + { + symbol_name = S_GET_NAME (ex.X_add_symbol); + match = FALSE; + + for (i = 0 ; i < (1 << operand_base->size) ; i++) + { + if (strcmp (operand->strings[i], symbol_name) == 0) + { + store_val = i; + match = TRUE; + break; + } + } + + if (!match) + { + set_insn_error (arg->argnum, _("Invalid string in operand")); + return FALSE; + } + } + else + return FALSE; + + if (store_val >= (unsigned int) (1 << operand_base->size)) + { + match_out_of_range (arg); + return FALSE; + } + + insn_insert_operand (arg->insn, operand_base, store_val); + return TRUE; +} + + /* OP_REG matcher. */ static bfd_boolean @@ -5138,6 +5245,13 @@ match_reg_operand (struct mips_arg_info *arg, else uval = regno; + if (operand_base->size > 0 + && uval >= (unsigned int) (1 << operand_base->size)) + { + match_out_of_range (arg); + return FALSE; + } + arg->last_regno = regno; if (arg->opnum == 1) arg->dest_regno = regno; @@ -5665,6 +5779,24 @@ match_imm_index_operand (struct mips_arg_info *arg, return TRUE; } +/* OP_MXU_STRIDE matcher. */ + +static bfd_boolean +match_mxu_stride_operand (struct mips_arg_info *arg, + const struct mips_operand *operand) +{ + offsetT sval; + + if (!match_const_int (arg, &sval)) + return FALSE; + + if (sval < 0 || sval > 2) + return FALSE; + + insn_insert_operand (arg->insn, operand, sval); + return TRUE; +} + /* OP_REG_INDEX matcher. */ static bfd_boolean @@ -5941,6 +6073,9 @@ match_operand (struct mips_arg_info *arg, case OP_MSB: return match_msb_operand (arg, operand); + case OP_MAPPED_STRING: + return match_string_operand (arg, operand); + case OP_REG: case OP_OPTIONAL_REG: return match_reg_operand (arg, operand); @@ -6001,6 +6136,9 @@ match_operand (struct mips_arg_info *arg, case OP_NON_ZERO_REG: return match_non_zero_reg_operand (arg, operand); + + case OP_MXU_STRIDE: + return match_mxu_stride_operand (arg, operand); } abort (); } @@ -6777,6 +6915,11 @@ get_append_method (struct mips_cl_insn *ip, expressionS *address_expr, if (mips_relax.sequence == 2) return APPEND_ADD; + /* Convert a non-compact to compact branch/jump instruction. */ + if (ISA_IS_R6 (mips_opts.isa) + && (ip->insn_mo->pinfo2 & INSN2_CONVERTED_TO_COMPACT)) + return APPEND_ADD_COMPACT; + /* We must not dabble with instructions in a ".set norerorder" block. */ if (mips_opts.noreorder) return APPEND_ADD; @@ -7455,12 +7598,20 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, break; case APPEND_ADD_COMPACT: - /* Convert MIPS16 jr/jalr into a "compact" jump. */ - gas_assert (mips_opts.mips16); - ip->insn_opcode |= 0x0080; - find_altered_mips16_opcode (ip); - install_insn (ip); - insert_into_history (0, 1, ip); + gas_assert(mips_opts.mips16 || ISA_IS_R6 (mips_opts.isa)); + if (mips_opts.mips16) + { + /* Convert MIPS16 jr/jalr into a "compact" jump. */ + ip->insn_opcode |= 0x0080; + find_altered_mips16_opcode (ip); + install_insn (ip); + insert_into_history (0, 1, ip); + } + else + { + install_insn (ip); + insert_into_history (0, 1, ip); + } break; case APPEND_SWAP: @@ -7497,8 +7648,9 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, } /* If we have just completed an unconditional branch, clear the history. */ - if ((delayed_branch_p (&history[1]) && uncond_branch_p (&history[1])) + if (((delayed_branch_p (&history[1]) && uncond_branch_p (&history[1])) || (compact_branch_p (&history[0]) && uncond_branch_p (&history[0]))) + && !(history[0].insn_mo->pinfo2 & INSN2_CONVERTED_TO_COMPACT)) { unsigned int i; @@ -7876,7 +8028,7 @@ match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode, abort (); /* Skip prefixes. */ - if (*args == '+' || *args == 'm' || *args == '-') + if (*args == '+' || *args == 'm' || *args == '-' || *args == '`') args++; if (mips_optional_operand_p (operand) @@ -8530,7 +8682,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...) uval |= (uval << 5); insn_insert_operand (&insn, operand, uval); - if (*fmt == '+' || *fmt == 'm' || *fmt == '-') + if (*fmt == '+' || *fmt == 'm' || *fmt == '-' || *fmt == '`') ++fmt; break; } @@ -17906,6 +18058,8 @@ mips_convert_ase_flags (int ase) ext_ases |= AFL_ASE_DSP; if (ase & ASE_DSPR2) ext_ases |= AFL_ASE_DSPR2; + if (ase & ASE_DSPR6) + ext_ases |= AFL_ASE_DSPR6; if (ase & ASE_EVA) ext_ases |= AFL_ASE_EVA; if (ase & ASE_MCU) @@ -18680,6 +18834,9 @@ static const struct mips_cpu_info mips_cpu_info_table[] = MIPS64R2 rather than MIPS64. */ { "xlp", 0, 0, ISA_MIPS64R2, CPU_XLR }, + /* i6400. */ + { "i6400", 0, ASE_MSA, ISA_MIPS64R6, CPU_MIPS64R6}, + /* End marker */ { NULL, 0, 0, 0, 0 } }; @@ -18918,6 +19075,9 @@ MIPS options:\n\ -mxpa generate eXtended Physical Address (XPA) instructions\n\ -mno-xpa do not generate eXtended Physical Address (XPA) instructions\n")); fprintf (stream, _("\ +-mmxu generate MXU instructions\n\ +-mno-mxu do not generate MXU instructions\n")); + fprintf (stream, _("\ -mvirt generate Virtualization instructions\n\ -mno-virt do not generate Virtualization instructions\n")); fprintf (stream, _("\ |