diff --git a/packages/devel/binutils/package.mk b/packages/devel/binutils/package.mk index 71f57e72c55..c587b2df835 100644 --- a/packages/devel/binutils/package.mk +++ b/packages/devel/binutils/package.mk @@ -17,7 +17,15 @@ ################################################################################ PKG_NAME="binutils" -PKG_VERSION="2.28" +case "$LINUX" in + ci20) + # mxu patch requires 2.23: + PKG_VERSION="2.23.2" + ;; + *) + PKG_VERSION="2.28" + ;; +esac PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/devel/binutils/patches/2.23.2/mips/binutils-999-mxu.patch b/packages/devel/binutils/patches/2.23.2/mips/binutils-999-mxu.patch new file mode 100644 index 00000000000..ef33a7c9d27 --- /dev/null +++ b/packages/devel/binutils/patches/2.23.2/mips/binutils-999-mxu.patch @@ -0,0 +1,1517 @@ +diff -N -ru binutils-2.23.2/gas/config/tc-mips.c binutils-2.23/gas/config/tc-mips.c +--- binutils-2.23.2/gas/config/tc-mips.c 2012-09-04 16:21:03.000000000 +0200 ++++ binutils-2.23/gas/config/tc-mips.c 2017-04-14 12:10:05.503317940 +0200 +@@ -218,6 +218,7 @@ + int ase_dsp; + int ase_dspr2; + int ase_mt; ++ int ase_mxu; + int ase_mcu; + /* Whether we are assembling for the mips16 processor. 0 if we are + not, 1 if we are, and -1 if the value has not been initialized. +@@ -293,7 +294,7 @@ + { + /* isa */ ISA_UNKNOWN, /* ase_mips3d */ -1, /* ase_mdmx */ -1, + /* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1, +- /* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0, ++ /* ase_mxu*/ -1, /* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0, + /* at */ ATREG, /* warn_about_macros */ 0, /* nomove */ 0, /* nobopt */ 0, + /* noautoextend */ 0, /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN, + /* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE +@@ -350,6 +351,9 @@ + command line (e.g., by -march). */ + static int file_ase_dsp; + ++/* True if -mmxu was passed. */ ++static int file_ase_mxu; ++ + #define ISA_SUPPORTS_DSP_ASE (mips_opts.isa == ISA_MIPS32R2 \ + || mips_opts.isa == ISA_MIPS64R2 \ + || mips_opts.micromips) +@@ -1387,6 +1391,7 @@ + #define MIPS_CPU_ASE_MDMX 0x0020 /* CPU implements MDMX ASE */ + #define MIPS_CPU_ASE_DSPR2 0x0040 /* CPU implements DSP R2 ASE */ + #define MIPS_CPU_ASE_MCU 0x0080 /* CPU implements MCU ASE */ ++#define MIPS_CPU_ASE_MXU 0x0100 /* CPU implements MXU ASE */ + + static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *); + static const struct mips_cpu_info *mips_cpu_info_from_isa (int); +@@ -1827,12 +1832,45 @@ + #undef CONFLICT + } + ++struct args { ++ const char *opt; ++ char *value; ++}; ++ ++const struct args args_opt[] = { ++ {"WW", "0"}, ++ {"LW", "1"}, ++ {"HW", "2"}, ++ {"XW", "3"}, ++ {"0", "0"}, ++ {"1", "1"}, ++ {"2", "2"}, ++ {"3", "3"}, ++}; ++const struct args args_apt[] = { ++ {"AA", "0"}, ++ {"AS", "1"}, ++ {"SA", "2"}, ++ {"SS", "3"} ++}; ++ ++const struct args args_ept[] = { ++ {"ptn0", "0"}, ++ {"ptn1", "1"}, ++ {"ptn2", "2"}, ++ {"ptn3", "3"}, ++ {"ptn4", "4"}, ++ {"ptn5", "5"}, ++ {"ptn6", "6"}, ++ {"ptn7", "7"}, ++}; ++ + struct regname { + const char *name; + unsigned int num; + }; + +-#define RTYPE_MASK 0x1ff00 ++#define RTYPE_MASK 0x3ff00 + #define RTYPE_NUM 0x00100 + #define RTYPE_FPU 0x00200 + #define RTYPE_FCC 0x00400 +@@ -1842,6 +1880,7 @@ + #define RTYPE_PC 0x04000 + #define RTYPE_ACC 0x08000 + #define RTYPE_CCC 0x10000 ++#define RTYPE_JZ 0x20000 + #define RNUM_MASK 0x000ff + #define RWARN 0x80000 + +@@ -2035,6 +2074,25 @@ + {"$ac2", RTYPE_ACC | 2}, \ + {"$ac3", RTYPE_ACC | 3} + ++#define MIPS32_JZ_REGISTER_NAMES \ ++ {"xr0", RTYPE_JZ | 0}, \ ++ {"xr1", RTYPE_JZ | 1}, \ ++ {"xr2", RTYPE_JZ | 2}, \ ++ {"xr3", RTYPE_JZ | 3}, \ ++ {"xr4", RTYPE_JZ | 4}, \ ++ {"xr5", RTYPE_JZ | 5}, \ ++ {"xr6", RTYPE_JZ | 6}, \ ++ {"xr7", RTYPE_JZ | 7}, \ ++ {"xr8", RTYPE_JZ | 8}, \ ++ {"xr9", RTYPE_JZ | 9}, \ ++ {"xr10", RTYPE_JZ | 10}, \ ++ {"xr11", RTYPE_JZ | 11}, \ ++ {"xr12", RTYPE_JZ | 12}, \ ++ {"xr13", RTYPE_JZ | 13}, \ ++ {"xr14", RTYPE_JZ | 14}, \ ++ {"xr15", RTYPE_JZ | 15}, \ ++ {"xr16", RTYPE_JZ | 16} ++ + static const struct regname reg_names[] = { + GENERIC_REGISTER_NUMBERS, + FPU_REGISTER_NAMES, +@@ -2050,6 +2108,7 @@ + MIPS16_SPECIAL_REGISTER_NAMES, + MDMX_VECTOR_REGISTER_NAMES, + MIPS_DSP_ACCUMULATOR_NAMES, ++ MIPS32_JZ_REGISTER_NAMES, + {0, 0} + }; + +@@ -2190,6 +2249,8 @@ + int isa = mips_opts.isa; + int fp_s, fp_d; + ++ if (mips_opts.ase_mxu) ++ isa |= INSN_MXU; + if (mips_opts.ase_mdmx) + isa |= INSN_MDMX; + if (mips_opts.ase_dsp) +@@ -10314,6 +10375,70 @@ + case '\\': USE_BITS (OP_MASK_3BITPOS, OP_SH_3BITPOS); break; + case '~': USE_BITS (OP_MASK_OFFSET12, OP_SH_OFFSET12); break; + case 'g': USE_BITS (OP_MASK_RD, OP_SH_RD); break; ++ ++/************** JZ SPECIAL ISA **************/ ++ /* m and n is used for S32M2I and S32I2M */ ++ case 'm': USE_BITS (OP_MASK_RA, OP_SH_RA); break; ++ case '=': USE_BITS (OP_MASK_XRA, OP_SH_XRA); ++ while (*p) ++ switch (*p++) ++ { ++ case ',': break; ++ case 'a': USE_BITS (OP_MASK_LPTN2, OP_SH_LPTN2); break; ++ case 'b': USE_BITS (OP_MASK_XRB, OP_SH_XRB); break; ++ case 'c': USE_BITS (OP_MASK_XRC, OP_SH_XRC); break; ++ case 'd': USE_BITS (OP_MASK_XRD, OP_SH_XRD); break; ++ case 'e': USE_BITS (OP_MASK_EPTN3, OP_SH_EPTN3); break; ++ case 'f': USE_BITS (OP_MASK_SFT4, OP_SH_SFT4); break; ++ case 'i': USE_BITS (OP_MASK_XIM12, OP_SH_XIM12); break; ++ case 'q': ++ case 'o': USE_BITS (OP_MASK_RPTN2, OP_SH_RPTN2); break; ++ case 'P': ++ case 'p': USE_BITS (OP_MASK_PTN, OP_SH_PTN); break; ++ case 'r': USE_BITS (OP_MASK_LSTRD2, OP_SH_LSTRD2); break; ++ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); break; ++ case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break; ++ case 'A': USE_BITS (OP_MASK_XAS, OP_SH_XAS); break; ++ case 'U': ++ case 'B': USE_BITS (OP_MASK_XIM8, OP_SH_XIM8); break; ++ case 'E': USE_BITS (OP_MASK_LPTN2, OP_SH_LPTN2); break; ++ case 'I': USE_BITS (OP_MASK_XIM10, OP_SH_XIM10); break; ++ case 'O': USE_BITS (OP_MASK_OPTN3, OP_SH_OPTN3); break; ++ case 'S': USE_BITS (OP_MASK_XRS, OP_SH_XRS); break; ++ case 'T': USE_BITS (OP_MASK_RT, OP_SH_RT); break; ++ default: ++ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"), c, opc->name, opc->args); ++ return 0; ++ } ++ break; ++ ++ case 'n': USE_BITS (OP_MASK_RD, OP_SH_RD); ++ while (*p) ++ switch(*p++) ++ { ++ case ',': break; ++ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); break; ++ case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break; ++ case 'R': USE_BITS (OP_MASK_RSTRD2, OP_SH_RSTRD2); break; ++ default: ++ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"), c, opc->name, opc->args); ++ return 0; ++ } ++ break; ++ ++ case 'y': USE_BITS (OP_MASK_XRB, OP_SH_XRB); ++ while (*p) ++ switch (*p++) ++ { ++ case ',': break; ++ case 'D': USE_BITS (OP_MASK_XRC, OP_SH_XRC); break; ++ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); break; ++ default: ++ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"), c, opc->name, opc->args); ++ return 0; ++ } ++ break; ++ + default: + as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"), + c, opc->name, opc->args); +@@ -11753,7 +11878,86 @@ + break; + + case 'y': /* ALNV.PS source register. */ +- gas_assert (mips_opts.micromips); ++ if (!mips_opts.micromips) ++ { ++ for (; ; args++) { ++ switch (*args) { ++ /* end of args */ ++ case '\0': ++ if (*s == '\0') ++ return; ++ break; ++ case ',': ++ if (*s++ == *args) ++ continue; ++ break; ++ ++ case 'y': ++ case 'D': ++ case 's': ++ s_reset = s; ++ if (*args == 's') { ++ rtype = RTYPE_NUM | RTYPE_GP; ++ ok = reg_lookup (&s, rtype, ®no); ++ if (regno == AT && mips_opts.at) ++ { ++ if (mips_opts.at == ATREG) ++ as_warn (_("used $at without \".set noat\"")); ++ else ++ as_warn (_("used $%u with \".set at=$%u\""), ++ regno, mips_opts.at); ++ } ++ } else { ++ rtype = RTYPE_JZ | RTYPE_GP; ++ ok = reg_lookup (&s, rtype, ®no); ++ if (!ok) ++ break; ++ if (regno > 15) { ++ as_bad (_("regno out of range(%d)\n"), regno); ++ internalError (); ++ } ++ } ++ if (ok) ++ { ++ c = *args; ++ if (*s == ' ') ++ ++s; ++ if (args[1] != *s) ++ { ++ if (c == 'r' || c == 'v' || c == 'w') ++ { ++ regno = lastregno; ++ s = s_reset; ++ ++args; ++ } ++ } ++ /* Now that we have assembled one operand, we use the args string ++ * to figure out where it goes in the instruction. */ ++ switch (c) ++ { ++ case 'y': ++ INSERT_OPERAND (0, XRB, *ip, regno); ++ break; ++ case 'D': ++ INSERT_OPERAND (0, XRC, *ip, regno); ++ break; ++ case 's': ++ INSERT_OPERAND (0, RS, *ip, regno); ++ break; ++ } ++ lastregno = regno; ++ continue; ++ } ++ break; ++ default: ++ as_bad (_("bad char = '%c'\n"), *args); ++ internalError (); ++ } ++ break; ++ } ++ break; ++ } ++ + goto do_reg; + case 'x': /* Ignore register name. */ + case 'U': /* Destination register (CLO/CLZ). */ +@@ -12427,7 +12631,15 @@ + continue; + + case 'm': /* Opcode extension character. */ +- gas_assert (mips_opts.micromips); ++ if (!mips_opts.micromips) ++ { ++ /* JZ S32M2I and JZS32I2M special command */ ++ if (!reg_lookup (&s, RTYPE_NUM | RTYPE_JZ, ®no)) ++ break; ++ ++ INSERT_OPERAND (0, RA, *ip, regno); ++ continue; ++ } + c = *++args; + switch (c) + { +@@ -13135,7 +13347,80 @@ + break; + + case 'n': /* Register list for 32-bit lwm and swm. */ +- gas_assert (mips_opts.micromips); ++ if (!mips_opts.micromips) ++ { ++ for (; ; args++) { ++ switch (*args) { ++ /* end of args */ ++ case '\0': ++ if (*s == '\0') ++ return; ++ break; ++ case ',': ++ if (*s++ == *args) ++ continue; ++ break; ++ ++ case 'R': /* rstrd2 */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ ++ /* the range of strd2 from 0 to 2 */ ++ if ((unsigned long) imm_expr.X_add_number > 0x2) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, RSTRD2, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'n': ++ case 's': ++ case 't': ++ s_reset = s; ++ ok = reg_lookup (&s, RTYPE_NUM | RTYPE_GP, ®no); ++ if (regno == AT && mips_opts.at) ++ { ++ if (mips_opts.at == ATREG) ++ as_warn (_("used $at without \".set noat\"")); ++ else ++ as_warn (_("used $%u with \".set at=$%u\""), ++ regno, mips_opts.at); ++ } ++ if (ok) ++ { ++ c = *args; ++ if (*s == ' ') ++ ++s; ++ ++ /* Now that we have assembled one operand, we use the args string ++ * to figure out where it goes in the instruction. */ ++ switch (c) ++ { ++ case 'n': ++ INSERT_OPERAND (0, RD, *ip, regno); ++ break; ++ case 's': ++ INSERT_OPERAND (0, RS, *ip, regno); ++ break; ++ case 't': ++ INSERT_OPERAND (0, RT, *ip, regno); ++ break; ++ } ++ lastregno = regno; ++ continue; ++ } ++ break; ++ default: ++ as_bad (_("bad char = '%c'\n"), *args); ++ internalError (); ++ } ++ break; ++ } ++ break; ++ } ++ + { + /* A comma-separated list of registers and/or + dash-separated contiguous ranges including +@@ -13186,6 +13471,413 @@ + s = expr_end; + continue; + ++/************** JZ SPECIAL ISA ****************/ /* S32MTI and S32I2M is added by 'm', 'n' above */ ++ ++ case '=': ++ for (; ; args++) { ++ int i; ++ char tmp[8]; ++ char *p = tmp; ++ switch (*args) { ++ /* end of args */ ++ case '\0': ++ if (*s == '\0') ++ return; ++ break; ++ case ',': ++ if (*s++ == *args) ++ continue; ++ break; ++ ++ case 'a': ++ /* phrase the aptn */ ++ strcpy(tmp, s); ++ p = strtok(tmp, ","); ++ for (i = 0; i < 4; i++) ++ if (!strcmp(p, args_apt[i].opt)) { ++ s += 2; ++ strcpy(tmp, args_apt[i].value); ++ break; ++ } ++ if (i == 4) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ s = strcat(tmp, s); ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_RPTN2) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, LPTN2, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'f': /* SFT4 */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_SFT4) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, SFT4, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'e': /* eptn3 */ ++ for (i = 0; i < 8; i++) { ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ } ++ if (i == 8) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_EPTN3) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, EPTN3, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ ++ case 'i': /* s[12:2] */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ /* the immediate must be fully divisioned by 4 */ ++ if ((signed long) imm_expr.X_add_number % 4 != 0 ) ++ as_bad (_("bad immediate = '%s'\n"), s); ++ /* the immediate must not be out of range */ ++ if ((signed long) imm_expr.X_add_number > 2044 || ++ (signed long)imm_expr.X_add_number < -2048) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (signed long) imm_expr.X_add_number); ++ /* the bit in the command express multiple by 4 */ ++ INSERT_OPERAND (0, XIM12, *ip, (imm_expr.X_add_number >> 2) & 0x3ff); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'o': /* OPTN2 */ ++ case 'q': /* s16mad, OPTN2 */ ++ for (i = 0; i < 8; i++) ++ if (!strcmp(args_opt[i].opt, s)) { ++ s = args_opt[i].value; ++ break; ++ } ++ if (i == 8) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_RPTN2) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, RPTN2, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'p': /* ptn */ ++ for (i = 0; i < 4; i++) ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ if (i == 4) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ ++ /* the range of strd2 from 0 to 1 */ ++ if ((unsigned long) imm_expr.X_add_number > 0x1) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, PTN, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'P': /* ptn */ ++ for (i = 0; i < 4; i++) ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ if (i == 4) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ ++ /* the range of strd2 from 0 to 1 */ ++ if ((unsigned long) imm_expr.X_add_number > 0x3) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, PTN, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'r': /* lstrd2 */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ ++ /* the range of strd2 from 0 to 2 */ ++ if ((unsigned long) imm_expr.X_add_number > 0x2) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, LSTRD2, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'A': /* special s32mad command */ ++ strcpy(tmp, s); ++ p = strtok(tmp, ","); ++ if (strcmp(p, "A") && strcmp(p, "S")) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ if (*s == 'S') ++ *s = '1'; ++ else if (*s == 'A') ++ *s = '0'; ++ my_getExpression (&imm_expr, s); ++ INSERT_OPERAND (0, XAS, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'B': /* s8[7:0] */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ /* the immediate must not be out of range */ ++ if ((signed long) imm_expr.X_add_number > 127 || ++ (signed long)imm_expr.X_add_number < -128) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (signed long) imm_expr.X_add_number); ++ /* the bit in the command express multiple by 4 */ ++ INSERT_OPERAND (0, XIM8, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'U': /* u8[7:0] */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ /* the immediate must not be out of range */ ++ if ((signed long) imm_expr.X_add_number > 255 || ++ (signed long)imm_expr.X_add_number < -128) ++ as_bad (_("Code (%c) for %s not in range (%ld)"), *args, ++ ip->insn_mo->name, ++ (signed long) imm_expr.X_add_number); ++ /* the bit in the command express multiple by 4 */ ++ INSERT_OPERAND (0, XIM8, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'E': /* phrase the s32sfl(aptn) */ ++ for (i = 0; i < 4; i++) ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ if (i == 4) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > 0x3) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, LPTN2, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'I': /* s10[9:1] */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ /* the immediate must be fully divisioned by 4 */ ++ if ((signed long) imm_expr.X_add_number % 2 != 0 ) ++ as_bad (_("bad immediate = '%s'\n"), s); ++ /* the immediate must not be out of range */ ++ if ((signed long) imm_expr.X_add_number > 510 || ++ (signed long)imm_expr.X_add_number < -512) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (signed long) imm_expr.X_add_number); ++ /* the bit in the command express multiple by 2 */ ++ INSERT_OPERAND (0, XIM10, *ip, (imm_expr.X_add_number >> 1)); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'O': /* optn3 */ ++ for (i = 0; i < 8; i++) { ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ } ++ if (i == 8) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_OPTN3) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, OPTN3, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'S': /* s3[2:0] */ ++ for (i = 0; i < 4; i++) ++ if (!strcmp(args_ept[i].opt, s)) { ++ s = args_ept[i].value; ++ break; ++ } ++ if (i == 4) { ++ as_bad (_("bad command args = '%s'\n"), s); ++ internalError (); ++ } ++ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > 0x4) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, XRS, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ ++ ++ case 'T': /* bits5 */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > OP_MASK_RT) ++ as_bad (_("Code (%c) for %s not in range (%lu)"), *args, ++ ip->insn_mo->name, ++ (unsigned long) imm_expr.X_add_number); ++ INSERT_OPERAND (0, RT, *ip, imm_expr.X_add_number); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case '=': ++ case 'b': ++ case 'c': ++ case 'd': ++ case 's': ++ case 't': ++ s_reset = s; ++ if (*args == 's' || *args == 't') { ++ rtype = RTYPE_NUM | RTYPE_GP; ++ ok = reg_lookup (&s, rtype, ®no); ++ if (regno == AT && mips_opts.at) ++ { ++ if (mips_opts.at == ATREG) ++ as_warn (_("used $at without \".set noat\"")); ++ else ++ as_warn (_("used $%u with \".set at=$%u\""), ++ regno, mips_opts.at); ++ } ++ } else { ++ rtype = RTYPE_JZ | RTYPE_GP; ++ ok = reg_lookup (&s, rtype, ®no); ++ if (!ok) ++ break; ++ if (regno > 15) { ++ as_bad (_("regno out of range(%d)\n"), regno); ++ internalError (); ++ } ++ } ++ if (ok) ++ { ++ c = *args; ++ if (*s == ' ') ++ ++s; ++ if (args[1] != *s) ++ { ++ if (c == 'r' || c == 'v' || c == 'w') ++ { ++ regno = lastregno; ++ s = s_reset; ++ ++args; ++ } ++ } ++ /* Now that we have assembled one operand, we use the args string ++ * to figure out where it goes in the instruction. */ ++ switch (c) ++ { ++ /* '=' 'b' 'c' 'd' express jz special register XRA XRB XRC XRD */ ++ case '=': ++ INSERT_OPERAND (0, XRA, *ip, regno); ++ break; ++ case 'b': ++ INSERT_OPERAND (0, XRB, *ip, regno); ++ break; ++ case 'c': ++ INSERT_OPERAND (0, XRC, *ip, regno); ++ break; ++ case 'd': ++ INSERT_OPERAND (0, XRD, *ip, regno); ++ break; ++ /* regular register s and t*/ ++ case 's': ++ INSERT_OPERAND (0, RS, *ip, regno); ++ break; ++ case 't': ++ INSERT_OPERAND (0, RT, *ip, regno); ++ break; ++ } ++ lastregno = regno; ++ continue; ++ } ++ break; ++ default: ++ as_bad (_("bad char = '%c'\n"), *args); ++ internalError (); ++ } ++ break; ++ } ++ break; ++ + default: + as_bad (_("Bad char = '%c'\n"), *args); + internalError (); +@@ -14298,6 +14990,8 @@ + OPTION_NO_DSP, + OPTION_MT, + OPTION_NO_MT, ++ OPTION_MXU, ++ OPTION_NO_MXU, + OPTION_SMARTMIPS, + OPTION_NO_SMARTMIPS, + OPTION_DSPR2, +@@ -14394,6 +15088,8 @@ + {"mno-dsp", no_argument, NULL, OPTION_NO_DSP}, + {"mmt", no_argument, NULL, OPTION_MT}, + {"mno-mt", no_argument, NULL, OPTION_NO_MT}, ++ {"mmxu", no_argument, NULL, OPTION_MXU}, ++ {"mno-mxu", no_argument, NULL, OPTION_NO_MXU}, + {"msmartmips", no_argument, NULL, OPTION_SMARTMIPS}, + {"mno-smartmips", no_argument, NULL, OPTION_NO_SMARTMIPS}, + {"mdspr2", no_argument, NULL, OPTION_DSPR2}, +@@ -14648,6 +15344,14 @@ + mips_opts.ase_dsp = 0; + break; + ++ case OPTION_MXU: ++ mips_opts.ase_mxu = 1; ++ break; ++ ++ case OPTION_NO_MXU: ++ mips_opts.ase_mxu = 0; ++ break; ++ + case OPTION_MT: + mips_opts.ase_mt = 1; + break; +@@ -15172,12 +15876,16 @@ + as_warn (_("%s ISA does not support MCU ASE"), + mips_cpu_info_from_isa (mips_opts.isa)->name); + ++ if (mips_opts.ase_mxu == -1) ++ mips_opts.ase_mxu = (arch_info->flags & MIPS_CPU_ASE_MXU) ? 1 : 0; ++ + file_mips_isa = mips_opts.isa; + file_ase_mips3d = mips_opts.ase_mips3d; + file_ase_mdmx = mips_opts.ase_mdmx; + file_ase_smartmips = mips_opts.ase_smartmips; + file_ase_dsp = mips_opts.ase_dsp; + file_ase_dspr2 = mips_opts.ase_dspr2; ++ file_ase_mxu = mips_opts.ase_mxu; + file_ase_mt = mips_opts.ase_mt; + mips_opts.gp32 = file_mips_gp32; + mips_opts.fp32 = file_mips_fp32; +@@ -16224,6 +16932,10 @@ + } + else if (strcmp (name, "nomt") == 0) + mips_opts.ase_mt = 0; ++ else if (strcmp (name, "mxu") == 0) ++ mips_opts.ase_mxu = 1; ++ else if (strcmp (name, "nomxu") == 0) ++ mips_opts.ase_mxu = 0; + else if (strcmp (name, "mcu") == 0) + mips_opts.ase_mcu = 1; + else if (strcmp (name, "nomcu") == 0) +@@ -19409,6 +20121,9 @@ + -mmcu generate MCU instructions\n\ + -mno-mcu do not generate MCU instructions\n")); + fprintf (stream, _("\ ++-mmxu generate MXU instructions\n\ ++-mno-mxu do not generate MXU instructions\n")); ++ fprintf (stream, _("\ + -mfix-loongson2f-jump work around Loongson2F JUMP instructions\n\ + -mfix-loongson2f-nop work around Loongson2F NOP errata\n\ + -mfix-vr4120 work around certain VR4120 errata\n\ +diff -N -ru binutils-2.23.2/include/opcode/mips.h binutils-2.23/include/opcode/mips.h +--- binutils-2.23.2/include/opcode/mips.h 2012-09-04 16:21:05.000000000 +0200 ++++ binutils-2.23/include/opcode/mips.h 2017-04-14 12:10:05.503317940 +0200 +@@ -328,6 +328,60 @@ + #define OP_MASK_IMMY 0 + #define OP_SH_IMMY 0 + ++/********** JZ SPECIAL ISA *************/ ++#define OP_MASK_XRA 0xf ++#define OP_SH_XRA 6 ++#define OP_MASK_XRB 0xf ++#define OP_SH_XRB 10 ++#define OP_MASK_XRC 0xf ++#define OP_SH_XRC 14 ++#define OP_MASK_XRD 0xf ++#define OP_SH_XRD 18 ++ ++/* special s32mad */ ++#define OP_MASK_XAS 0x1 ++#define OP_SH_XAS 24 ++ ++/* aptn2 optn2 eptn2 optn3 eptn3 sft4 strd2(1|2) S3[2:0] ptn*/ ++#define OP_MASK_RPTN2 0x3 ++#define OP_SH_RPTN2 22 ++#define OP_MASK_LPTN2 0x3 ++#define OP_SH_LPTN2 24 ++#define OP_MASK_LSTRD2 0x3 ++#define OP_SH_LSTRD2 14 ++#define OP_MASK_RSTRD2 0x3 ++#define OP_SH_RSTRD2 9 ++#define OP_MASK_SFT4 0xf ++#define OP_SH_SFT4 22 ++#define OP_MASK_XRS 0x7 ++#define OP_SH_XRS 23 ++#define OP_MASK_OPTN3 0x7 ++#define OP_SH_OPTN3 23 ++#define OP_MASK_EPTN3 0x7 ++#define OP_SH_EPTN3 18 ++#define OP_MASK_PTN 0x3 ++#define OP_SH_PTN 19 ++ ++/* S32M2I S32I2M XRA */ ++#define OP_MASK_RA 0x1f ++#define OP_SH_RA 6 ++ ++/* register rb(rs) rc(rt) s12[11:2] s8[7:0] s10[9:1]*/ ++/* ++#define OP_MASK_RB OP_MASK_RS ++#define OP_SH_RB OP_SH_RS ++#define OP_MASK_RC OP_MASK_RT ++#define OP_SH_RC OP_SH_RT ++*/ ++#define OP_MASK_XIM8 0xff ++#define OP_MASK_XIM10 0x1ff ++#define OP_MASK_XIM12 0x3ff ++#define OP_SH_XIM8 10 ++#define OP_SH_XIM10 10 ++#define OP_SH_XIM12 10 ++ ++/********** END JZ ISA ***********/ ++ + /* This structure holds information for a particular instruction. */ + + struct mips_opcode +@@ -726,7 +780,7 @@ + #define INSN_OCTEON2 0x00000100 + + /* Masks used for MIPS-defined ASEs. */ +-#define INSN_ASE_MASK 0x3c00f010 ++#define INSN_ASE_MASK 0x3c00f050 + + /* DSP ASE */ + #define INSN_DSP 0x00001000 +@@ -774,6 +828,8 @@ + #define INSN_LOONGSON_3A 0x00000400 + /* RMI Xlr instruction */ + #define INSN_XLR 0x00000020 ++/* Ingenic MXU instruction */ ++#define INSN_MXU 0x00000040 + + /* MCU (MicroController) ASE */ + #define INSN_MCU 0x00000010 +@@ -1619,6 +1675,43 @@ + #define MICROMIPSOP_MASK_RZ 0 + #define MICROMIPSOP_SH_FZ 0 + #define MICROMIPSOP_MASK_FZ 0 ++#define MICROMIPSOP_SH_RA 0 ++#define MICROMIPSOP_MASK_RA 0 ++#define MICROMIPSOP_SH_XRA 0 ++#define MICROMIPSOP_MASK_XRA 0 ++#define MICROMIPSOP_SH_XRB 0 ++#define MICROMIPSOP_MASK_XRB 0 ++#define MICROMIPSOP_SH_XRC 0 ++#define MICROMIPSOP_MASK_XRC 0 ++#define MICROMIPSOP_SH_XRD 0 ++#define MICROMIPSOP_MASK_XRD 0 ++#define MICROMIPSOP_SH_LPTN2 0 ++#define MICROMIPSOP_MASK_LPTN2 0 ++#define MICROMIPSOP_SH_SFT4 0 ++#define MICROMIPSOP_MASK_SFT4 0 ++#define MICROMIPSOP_SH_EPTN3 0 ++#define MICROMIPSOP_MASK_EPTN3 0 ++#define MICROMIPSOP_SH_RSTRD2 0 ++#define MICROMIPSOP_MASK_RSTRD2 0 ++#define MICROMIPSOP_SH_XAS 0 ++#define MICROMIPSOP_MASK_XAS 0 ++#define MICROMIPSOP_SH_XRS 0 ++#define MICROMIPSOP_MASK_XRS 0 ++#define MICROMIPSOP_SH_OPTN3 0 ++#define MICROMIPSOP_MASK_OPTN3 0 ++#define MICROMIPSOP_SH_XIM8 0 ++#define MICROMIPSOP_MASK_XIM8 0 ++#define MICROMIPSOP_SH_XIM10 0 ++#define MICROMIPSOP_MASK_XIM10 0 ++#define MICROMIPSOP_SH_XIM12 0 ++#define MICROMIPSOP_MASK_XIM12 0 ++#define MICROMIPSOP_SH_LSTRD2 0 ++#define MICROMIPSOP_MASK_LSTRD2 0 ++#define MICROMIPSOP_SH_PTN 0 ++#define MICROMIPSOP_MASK_PTN 0 ++#define MICROMIPSOP_SH_RPTN2 0 ++#define MICROMIPSOP_MASK_RPTN2 0 ++ + + /* These are the characters which may appears in the args field of a microMIPS + instruction. They appear in the order in which the fields appear +diff -N -ru binutils-2.23.2/opcodes/mips-dis.c binutils-2.23/opcodes/mips-dis.c +--- binutils-2.23.2/opcodes/mips-dis.c 2012-09-04 16:23:13.000000000 +0200 ++++ binutils-2.23/opcodes/mips-dis.c 2017-04-14 12:10:05.503317940 +0200 +@@ -44,6 +44,41 @@ + + /* FIXME: These should be shared with gdb somehow. */ + ++/***** used for JZ special ISA *****/ ++struct args { ++ const char *opt; ++ int value; ++}; ++ ++const struct args args_opt[] = { ++ {"WW", 0}, ++ {"LW", 1}, ++ {"HW", 2}, ++ {"XW", 3} ++}; ++const struct args args_apt[] = { ++ {"AA", 0}, ++ {"AS", 1}, ++ {"SA", 2}, ++ {"SS", 3} ++}; ++ ++const struct args args_ept[] = { ++ {"ptn0", 0}, ++ {"ptn1", 1}, ++ {"ptn2", 2}, ++ {"ptn3", 3}, ++ {"ptn4", 4}, ++ {"ptn5", 5}, ++ {"ptn6", 6}, ++ {"ptn7", 7}, ++}; ++static const char * const mips_gpr_names_xr[17] = { ++ "xr0", "xr1", "xr2", "xr3", "xr4", "xr5", "xr6", "xr7", ++ "xr8", "xr9", "xr10", "xr11", "xr12", "xr13", "xr14", "xr15", ++ "xr16" ++}; ++ + struct mips_cp0sel_name + { + unsigned int cp0reg; +@@ -557,14 +592,14 @@ + MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), + page 1. */ + { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, +- ISA_MIPS32 | INSN_SMARTMIPS, ++ ISA_MIPS32 | INSN_SMARTMIPS | INSN_MXU, + mips_cp0_names_mips3264, + mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), + mips_hwr_names_numeric }, + + { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, + (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2 +- | INSN_MIPS3D | INSN_MT | INSN_MCU), ++ | INSN_MIPS3D | INSN_MT | INSN_MCU | INSN_MXU), + mips_cp0_names_mips3264r2, + mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), + mips_hwr_names_mips3264r2 }, +@@ -926,6 +961,34 @@ + return NULL; + } + ++/**** phrase the JZ special option as (aptn,optn,A,S) ****/ ++static void phrase_aptn(char *dst, int delta) ++{ ++ int i; ++ for (i = 0; i < 4; i++) { ++ if (delta == args_apt[i].value) { ++ strcpy(dst, args_apt[i].opt); ++ } ++ } ++} ++static void phrase_optn(char *dst, int delta) ++{ ++ int i; ++ for (i = 0; i < 4; i++) { ++ if (delta == args_opt[i].value) { ++ strcpy(dst, args_opt[i].opt); ++ } ++ } ++} ++static void phrase_eptn(char *dst, int delta) ++{ ++ int i; ++ for (i = 0; i < 8; i++) { ++ if (delta == args_ept[i].value) { ++ strcpy(dst, args_ept[i].opt); ++ } ++ } ++} + /* Print insn arguments for 32/64-bit code. */ + + static void +@@ -938,7 +1001,7 @@ + const fprintf_ftype infprintf = info->fprintf_func; + unsigned int lsb, msb, msbd; + void *is = info->stream; +- int op; ++ int op, delta; + + lsb = 0; + +@@ -1406,6 +1469,225 @@ + infprintf (is, "$v%d", GET_OP (l, FT)); + break; + ++ /************** JZ SEPCIAL ISA *****************/ ++ case 'm': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_RA) & OP_MASK_RA]); ++ break; ++ ++ case '=': ++ for (; *d != '\0'; d++) ++ { ++ ++ char tmp[4] = {}; ++ switch (*d) ++ { ++ case ',': ++ (*info->fprintf_func) (info->stream, "%c", *d); ++ break; ++ case 'a': ++ delta = (l >> OP_SH_LPTN2) & OP_MASK_LPTN2; ++ phrase_aptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'e': ++ delta = (l >> OP_SH_EPTN3) & OP_MASK_EPTN3; ++ phrase_eptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'f': ++ delta = (l >> OP_SH_SFT4) & OP_MASK_SFT4; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'i': ++ delta = (l >> OP_SH_XIM12) & OP_MASK_XIM12; ++ delta <<= 2; ++ /* if the delta < 0 */ ++ if (delta & 0x800) { ++ delta |= 0xfffff << 12; ++ } ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'q': ++ delta = (l >> OP_SH_RPTN2) & OP_MASK_RPTN2; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'o': ++ delta = (l >> OP_SH_RPTN2) & OP_MASK_RPTN2; ++ phrase_optn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'p': ++ case 'P': ++ delta = (l >> OP_SH_PTN) & OP_MASK_PTN; ++ phrase_eptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'r': ++ delta = (l >> OP_SH_LSTRD2) & OP_MASK_LSTRD2; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'A': ++ delta = (l >> OP_SH_XAS) & OP_MASK_XAS; ++ if (delta == 0) ++ strcpy(tmp, "A"); ++ else ++ strcpy(tmp, "S"); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'B': ++ delta = (l >> OP_SH_XIM8) & OP_MASK_XIM8; ++ /* if the delta < 0 */ ++ if (delta & 0x80) { ++ delta |= 0xffffff << 8; ++ } ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'U': ++ delta = (l >> OP_SH_XIM8) & OP_MASK_XIM8; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'E': ++ delta = (l >> OP_SH_LPTN2) & OP_MASK_LPTN2; ++ phrase_eptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'I': ++ delta = (l >> OP_SH_XIM10) & OP_MASK_XIM10; ++ delta <<= 1; ++ /* if the delta < 0 */ ++ if (delta & 0x100) { ++ delta |= 0x3fffff << 10; ++ } ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ ++ case 'O': ++ delta = (l >> OP_SH_OPTN3) & OP_MASK_OPTN3; ++ phrase_eptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ case 'S': ++ delta = (l >> OP_SH_XRS) & OP_MASK_XRS; ++ phrase_eptn(tmp, delta); ++ (*info->fprintf_func) (info->stream, "%s", ++ tmp); ++ break; ++ ++ case 'T': ++ delta = (l >> OP_SH_RT) & OP_MASK_RT; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case '=': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRA) & OP_MASK_XRA]); ++ break; ++ case 'b': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRB) & OP_MASK_XRB]); ++ break; ++ case 'c': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRC) & OP_MASK_XRC]); ++ break; ++ case 'd': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRD) & OP_MASK_XRD]); ++ break; ++ case 's': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); ++ break; ++ case 't': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); ++ break; ++ ++ default: ++ /* xgettext:c-format */ ++ (*info->fprintf_func) (info->stream, ++ _("# internal error, undefined modifier(%c)"), ++ *d); ++ } ++ } ++ return; ++ case 'y': ++ for (; *d != '\0'; d++) ++ { ++ switch (*d) ++ { ++ case ',': ++ (*info->fprintf_func) (info->stream, "%c", *d); ++ break; ++ case 'y': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRB) & OP_MASK_XRB]); ++ break; ++ case 'D': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names_xr[(l >> OP_SH_XRC) & OP_MASK_XRC]); ++ break; ++ case 's': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); ++ break; ++ default: ++ /* xgettext:c-format */ ++ (*info->fprintf_func) (info->stream, ++ _("# internal error, undefined modifier(%c)"), ++ *d); ++ } ++ } ++ return; ++ case 'n': ++ for (; *d != '\0'; d++) ++ { ++ switch (*d) ++ { ++ case ',': ++ (*info->fprintf_func) (info->stream, "%c", *d); ++ break; ++ case 'R': ++ delta = (l >> OP_SH_RSTRD2) & OP_MASK_RSTRD2; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ case 'n': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]); ++ break; ++ case 's': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); ++ break; ++ case 't': ++ (*info->fprintf_func) (info->stream, "%s", ++ mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); ++ break; ++ default: ++ /* xgettext:c-format */ ++ (*info->fprintf_func) (info->stream, ++ _("# internal error, undefined modifier(%c)"), ++ *d); ++ } ++ } ++ return; ++ + default: + /* xgettext:c-format */ + infprintf (is, _("# internal error, undefined modifier (%c)"), *d); +diff -N -ru binutils-2.23.2/opcodes/mips-opc.c binutils-2.23/opcodes/mips-opc.c +--- binutils-2.23.2/opcodes/mips-opc.c 2012-09-04 16:21:10.000000000 +0200 ++++ binutils-2.23/opcodes/mips-opc.c 2017-04-14 12:10:05.507317925 +0200 +@@ -179,6 +179,9 @@ + /* MIPS MCU (MicroController) ASE support. */ + #define MC INSN_MCU + ++/* Ingenic MXU ASE support. */ ++#define MXU INSN_MXU ++ + /* The order of overloaded instructions matters. Label arguments and + register arguments look the same. Instructions that can have either + for arguments must apear in the correct order in this table for the +@@ -972,8 +975,12 @@ + {"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 }, + {"mfc0", "t,+D",0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, + {"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, ++{"mfc1", "t,S", 0x44000002, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, MXU }, ++{"mfc1", "t,G", 0x44000002, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, MXU }, + {"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 }, + {"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 }, ++{"mfhc1", "t,S", 0x44600002, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, MXU }, ++{"mfhc1", "t,G", 0x44600002, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, MXU }, + {"mfhc1", "t,S", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 }, + {"mfhc1", "t,G", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 }, + /* mfc2 is at the bottom of the table. */ +@@ -1053,8 +1060,12 @@ + {"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I1 }, + {"mtc0", "t,+D", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 }, + {"mtc0", "t,G,H", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 }, ++{"mtc1", "t,S", 0x44800002, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, MXU }, ++{"mtc1", "t,G", 0x44800002, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, MXU }, + {"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 }, + {"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 }, ++{"mthc1", "t,S", 0x44e00002, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, MXU }, ++{"mthc1", "t,G", 0x44e00002, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, MXU }, + {"mthc1", "t,S", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 }, + {"mthc1", "t,G", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 }, + /* mtc2 is at the bottom of the table. */ +@@ -1550,6 +1561,9 @@ + {"zcb", "(b)", 0x7000071f, 0xfc1fffff, SM|RD_b, 0, IOCT2 }, + {"zcbt", "(b)", 0x7000075f, 0xfc1fffff, SM|RD_b, 0, IOCT2 }, + ++/********************** JS SPECIAL ISA ********************************/ ++#include "mxu-opc.c" ++ + /* User Defined Instruction. */ + {"udi0", "s,t,d,+1",0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, + {"udi0", "s,t,+2", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +diff -N -ru binutils-2.23.2/opcodes/mxu-opc.c binutils-2.23/opcodes/mxu-opc.c +--- binutils-2.23.2/opcodes/mxu-opc.c 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.23/opcodes/mxu-opc.c 2017-04-14 12:10:05.507317925 +0200 +@@ -0,0 +1,127 @@ ++/********************** JS SPECIAL ISA ********************************/ ++/* name, args, match, mask, pinfo, pinfo2, membership */ ++{"d16mul", "=,b,c,d,o", 0x70000008, 0xff00003f, TRAP, 0, MXU}, ++{"d16mulf", "=,b,c,o", 0x70000009, 0xff3c003f, TRAP, 0, MXU}, ++{"d16mule", "=,b,c,o", 0x71000009, 0xff3c003f, TRAP, 0, MXU}, ++{"d16mac", "=,b,c,d,a,o", 0x7000000a, 0xfc00003f, TRAP, 0, MXU}, ++{"d16macf", "=,b,c,d,a,o", 0x7000000b, 0xfc00003f, TRAP, 0, MXU}, ++{"d16madl", "=,b,c,d,a,o", 0x7000000c, 0xfc00003f, TRAP, 0, MXU}, ++{"s16mad", "=,b,c,d,A,q", 0x7000000d, 0xfe00003f, TRAP, 0, MXU}, ++{"q16add", "=,b,c,d,a,o", 0x7000000e, 0xfc00003f, TRAP, 0, MXU}, ++{"d16mace", "=,b,c,d,a,o", 0x7000000f, 0xfc00003f, TRAP, 0, MXU}, ++ ++{"q8mul", "=,b,c,d", 0x70000038, 0xffc0003f, TRAP, 0, MXU}, ++{"q8mulsu", "=,b,c,d", 0x70800038, 0xffc0003f, TRAP, 0, MXU}, ++{"q8movz", "=,b,c", 0x70000039, 0xfffc003f, TRAP, 0, MXU}, ++{"q8movn", "=,b,c", 0x70040039, 0xfffc003f, TRAP, 0, MXU}, ++{"d16movz", "=,b,c", 0x70080039, 0xfffc003f, TRAP, 0, MXU}, ++{"d16movn", "=,b,c", 0x700c0039, 0xfffc003f, TRAP, 0, MXU}, ++{"s32movz", "=,b,c", 0x70100039, 0xfffc003f, TRAP, 0, MXU}, ++{"s32movn", "=,b,c", 0x70140039, 0xfffc003f, TRAP, 0, MXU}, ++{"q8mac", "=,b,c,d,a", 0x7000003a, 0xfcc0003f, TRAP, 0, MXU}, ++{"q8macsu", "=,b,c,d,a", 0x7080003a, 0xfcc0003f, TRAP, 0, MXU}, ++{"q16scop", "=,b,c,d", 0x7000003b, 0xffc0003f, TRAP, 0, MXU}, ++{"q8madl", "=,b,c,d,a", 0x7000003c, 0xfcc0003f, TRAP, 0, MXU}, ++{"s32sfl", "=,b,c,d,E", 0x7000003d, 0xfcc0003f, TRAP, 0, MXU}, ++{"q8sad", "=,b,c,d", 0x7000003e, 0xffc0003f, TRAP, 0, MXU}, ++ ++{"d32add", "=,b,c,d,a", 0x70000018, 0xfcc0003f, TRAP, 0, MXU}, ++{"d32addc", "=,b,c,d", 0x70400018, 0xffc0003f, TRAP, 0, MXU}, ++{"d32acc", "=,b,c,d,a", 0x70000019, 0xfcc0003f, TRAP, 0, MXU}, ++{"d32accm", "=,b,c,d,a", 0x70400019, 0xfcc0003f, TRAP, 0, MXU}, ++{"d32asum", "=,b,c,d,a", 0x70800019, 0xfcc0003f, TRAP, 0, MXU}, ++{"q16acc", "=,b,c,d,a", 0x7000001b, 0xfcc0003f, TRAP, 0, MXU}, ++{"q16accm", "=,b,c,d,a", 0x7040001b, 0xfcc0003f, TRAP, 0, MXU}, ++{"d16asum", "=,b,c,d,a", 0x7080001b, 0xfcc0003f, TRAP, 0, MXU}, ++{"q8adde", "=,b,c,d,a", 0x7000001c, 0xfcc0003f, TRAP, 0, MXU}, ++{"d8sum", "=,b,c", 0x7040001c, 0xfffc003f, TRAP, 0, MXU}, ++{"d8sumc", "=,b,c", 0x7080001c, 0xfffc003f, TRAP, 0, MXU}, ++{"q8acce", "=,b,c,d,a", 0x7000001d, 0xfcc0003f, TRAP, 0, MXU}, ++ ++{"s32cps", "=,b,c", 0x70000007, 0xfffc003f, TRAP, 0, MXU}, ++{"d16cps", "=,b,c", 0x70080007, 0xfffc003f, TRAP, 0, MXU}, ++{"q8abd", "=,b,c", 0x70100007, 0xfffc003f, TRAP, 0, MXU}, ++{"q16sat", "=,b,c", 0x70180007, 0xfffc003f, TRAP, 0, MXU}, ++ ++{"s32slt", "=,b,c", 0x70000006, 0xfffc003f, TRAP, 0, MXU}, ++{"d16slt", "=,b,c", 0x70040006, 0xfffc003f, TRAP, 0, MXU}, ++{"d16avg", "=,b,c", 0x70080006, 0xfffc003f, TRAP, 0, MXU}, ++{"d16avgr", "=,b,c", 0x700c0006, 0xfffc003f, TRAP, 0, MXU}, ++{"q8avg", "=,b,c", 0x70100006, 0xfffc003f, TRAP, 0, MXU}, ++{"q8avgr", "=,b,c", 0x70140006, 0xfffc003f, TRAP, 0, MXU}, ++{"q8add", "=,b,c,a", 0x701c0006, 0xfcfc003f, TRAP, 0, MXU}, ++ ++{"s32max", "=,b,c", 0x70000003, 0xfffc003f, TRAP, 0, MXU}, ++{"s32min", "=,b,c", 0x70040003, 0xfffc003f, TRAP, 0, MXU}, ++{"d16max", "=,b,c", 0x70080003, 0xfffc003f, TRAP, 0, MXU}, ++{"d16min", "=,b,c", 0x700c0003, 0xfffc003f, TRAP, 0, MXU}, ++{"q8max", "=,b,c", 0x70100003, 0xfffc003f, TRAP, 0, MXU}, ++{"q8min", "=,b,c", 0x70140003, 0xfffc003f, TRAP, 0, MXU}, ++{"q8slt", "=,b,c", 0x70180003, 0xfffc003f, TRAP, 0, MXU}, ++{"q8sltu", "=,b,c", 0x701c0003, 0xfffc003f, TRAP, 0, MXU}, ++ ++{"d32sll", "=,b,c,d,f", 0x70000030, 0xfc00003f, TRAP, 0, MXU}, ++{"d32slr", "=,b,c,d,f", 0x70000031, 0xfc00003f, TRAP, 0, MXU}, ++{"d32sarl", "=,b,c,f", 0x70000032, 0xfc3c003f, TRAP, 0, MXU}, ++{"d32sar", "=,b,c,d,f", 0x70000033, 0xfc00003f, TRAP, 0, MXU}, ++{"q16sll", "=,b,c,d,f", 0x70000034, 0xfc00003f, TRAP, 0, MXU}, ++{"q16slr", "=,b,c,d,f", 0x70000035, 0xfc00003f, TRAP, 0, MXU}, ++{"q16sar", "=,b,c,d,f", 0x70000037, 0xfc00003f, TRAP, 0, MXU}, ++ ++{"d32sllv", "y,D,s", 0x70000036, 0xfc1c03ff, TRAP, 0, MXU}, ++{"d32slrv", "y,D,s", 0x70040036, 0xfc1c03ff, TRAP, 0, MXU}, ++{"d32sarv", "y,D,s", 0x700c0036, 0xfc1c03ff, TRAP, 0, MXU}, ++{"q16sllv", "y,D,s", 0x70100036, 0xfc1c03ff, TRAP, 0, MXU}, ++{"q16slrv", "y,D,s", 0x70140036, 0xfc1c03ff, TRAP, 0, MXU}, ++{"q16sarv", "y,D,s", 0x701c0036, 0xfc1c03ff, TRAP, 0, MXU}, ++ ++{"s32madd", "=,b,s,t", 0x70008000, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32maddu", "=,b,s,t", 0x70008001, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32msub", "=,b,s,t", 0x70008004, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32msubu", "=,b,s,t", 0x70008005, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32mul", "=,b,s,t", 0x70000026, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32mulu", "=,b,s,t", 0x70004026, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32extr", "=,b,s,T", 0x70008026, 0xfc00c03f, TRAP, 0, MXU}, ++{"s32extrv", "=,b,s,t", 0x7000c026, 0xfc00c03f, TRAP, 0, MXU}, ++ ++{"d32sarw", "=,b,c,s", 0x70000027, 0xfc1c003f, TRAP, 0, MXU}, ++{"s32aln", "=,b,c,s", 0x70040027, 0xfc1c003f, TRAP, 0, MXU}, ++{"s32alni", "=,b,c,S", 0x70080027, 0xfc7c003f, TRAP, 0, MXU}, ++{"s32lui", "=,U,O", 0x700c0027, 0xfc7c003f, TRAP, 0, MXU}, ++{"s32nor", "=,b,c", 0x70100027, 0xfffc003f, TRAP, 0, MXU}, ++{"s32and", "=,b,c", 0x70140027, 0xfffc003f, TRAP, 0, MXU}, ++{"s32or", "=,b,c", 0x70180027, 0xfffc003f, TRAP, 0, MXU}, ++{"s32xor", "=,b,c", 0x701c0027, 0xfffc003f, TRAP, 0, MXU}, ++ ++{"lxb", "n,s,t,R", 0x70000028, 0xfc0001ff, TRAP, 0, MXU}, ++{"lxbu", "n,s,t,R", 0x70000128, 0xfc0001ff, TRAP, 0, MXU}, ++{"lxh", "n,s,t,R", 0x70000068, 0xfc0001ff, TRAP, 0, MXU}, ++{"lxhu", "n,s,t,R", 0x70000168, 0xfc0001ff, TRAP, 0, MXU}, ++{"lxw", "n,s,t,R", 0x700000e8, 0xfc0001ff, TRAP, 0, MXU}, ++{"s16ldd", "=,s,I,P", 0x7000002a, 0xfc00003f, TRAP, 0, MXU}, ++{"s16std", "=,s,I,p", 0x7000002b, 0xfc00003f, TRAP, 0, MXU}, ++{"s16ldi", "=,s,I,P", 0x7000002c, 0xfc00003f, TRAP, 0, MXU}, ++{"s16sdi", "=,s,I,p", 0x7000002d, 0xfc00003f, TRAP, 0, MXU}, ++{"s32m2i", "m,t", 0x7000002e, 0xffe0f83f, TRAP, 0, MXU}, ++{"s32i2m", "m,t", 0x7000002f, 0xffe0f83f, TRAP, 0, MXU}, ++ ++{"s32lddv", "=,s,t,r", 0x70000012, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32lddvr", "=,s,t,r", 0x70000412, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32stdv", "=,s,t,r", 0x70000013, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32stdvr", "=,s,t,r", 0x70000413, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32ldiv", "=,s,t,r", 0x70000016, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32ldivr", "=,s,t,r", 0x70000416, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32sdiv", "=,s,t,r", 0x70000017, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32sdivr", "=,s,t,r", 0x70000417, 0xfc003c3f, TRAP, 0, MXU}, ++{"s32ldd", "=,s,i", 0x70000010, 0xfc10003f, TRAP, 0, MXU}, ++{"s32lddr", "=,s,i", 0x70100010, 0xfc10003f, TRAP, 0, MXU}, ++{"s32std", "=,s,i", 0x70000011, 0xfc10003f, TRAP, 0, MXU}, ++{"s32stdr", "=,s,i", 0x70100011, 0xfc10003f, TRAP, 0, MXU}, ++{"s32ldi", "=,s,i", 0x70000014, 0xfc10003f, TRAP, 0, MXU}, ++{"s32ldir", "=,s,i", 0x70100014, 0xfc10003f, TRAP, 0, MXU}, ++{"s32sdi", "=,s,i", 0x70000015, 0xfc10003f, TRAP, 0, MXU}, ++{"s32sdir", "=,s,i", 0x70100015, 0xfc10003f, TRAP, 0, MXU}, ++{"s8ldd", "=,s,B,e", 0x70000022, 0xfc00003f, TRAP, 0, MXU}, ++{"s8std", "=,s,B,e", 0x70000023, 0xfc00003f, TRAP, 0, MXU}, ++{"s8ldi", "=,s,B,e", 0x70000024, 0xfc00003f, TRAP, 0, MXU}, ++{"s8sdi", "=,s,B,e", 0x70000025, 0xfc00003f, TRAP, 0, MXU}, diff --git a/packages/devel/binutils/patches/2.23.2/mips/binutils-doc-typos.patch b/packages/devel/binutils/patches/2.23.2/mips/binutils-doc-typos.patch new file mode 100644 index 00000000000..ccedd19008f --- /dev/null +++ b/packages/devel/binutils/patches/2.23.2/mips/binutils-doc-typos.patch @@ -0,0 +1,21 @@ +diff -ru ref/bfd/doc/bfd.texinfo binutils-2.23.2/bfd/doc/bfd.texinfo +--- ref/bfd/doc/bfd.texinfo 2010-10-28 13:40:25.000000000 +0200 ++++ binutils-2.23.2/bfd/doc/bfd.texinfo 2017-04-14 13:00:19.318435617 +0200 +@@ -322,7 +322,7 @@ + @printindex cp + + @tex +-% I think something like @colophon should be in texinfo. In the ++% I think something like colophon should be in texinfo. In the + % meantime: + \long\def\colophon{\hbox to0pt{}\vfill + \centerline{The body of this manual is set in} +@@ -333,7 +333,7 @@ + \centerline{{\sl\fontname\tensl\/}} + \centerline{are used for emphasis.}\vfill} + \page\colophon +-% Blame: doc@cygnus.com, 28mar91. ++% Blame: doccygnus.com, 28mar91. + @end tex + + @bye