diff -burN orig.binutils-2.22/bfd/archures.c binutils-2.22/bfd/archures.c --- orig.binutils-2.22/bfd/archures.c 2011-08-02 01:04:19.000000000 +0200 +++ binutils-2.22/bfd/archures.c 2012-01-04 16:18:30.404282447 +0100 @@ -175,6 +175,7 @@ .#define bfd_mach_mips_loongson_2f 3002 .#define bfd_mach_mips_loongson_3a 3003 .#define bfd_mach_mips_sb1 12310201 {* octal 'SB', 01 *} +.#define bfd_mach_mips_allegrex 10111431 {* octal 'AL', 31 *} .#define bfd_mach_mips_octeon 6501 .#define bfd_mach_mips_xlr 887682 {* decimal 'XLR' *} .#define bfd_mach_mipsisa32 32 diff -burN orig.binutils-2.22/bfd/bfd-in2.h binutils-2.22/bfd/bfd-in2.h --- orig.binutils-2.22/bfd/bfd-in2.h 2011-09-16 03:15:18.000000000 +0200 +++ binutils-2.22/bfd/bfd-in2.h 2012-01-04 16:18:30.406282423 +0100 @@ -1882,6 +1882,7 @@ #define bfd_mach_mips_loongson_2f 3002 #define bfd_mach_mips_loongson_3a 3003 #define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ +#define bfd_mach_mips_allegrex 10111431 /* octal 'AL', 31 */ #define bfd_mach_mips_octeon 6501 #define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */ #define bfd_mach_mipsisa32 32 diff -burN orig.binutils-2.22/bfd/cpu-mips.c binutils-2.22/bfd/cpu-mips.c --- orig.binutils-2.22/bfd/cpu-mips.c 2011-07-24 16:20:05.000000000 +0200 +++ binutils-2.22/bfd/cpu-mips.c 2012-01-04 16:18:30.415282321 +0100 @@ -89,6 +89,7 @@ I_mipsisa64, I_mipsisa64r2, I_sb1, + I_allegrex, I_loongson_2e, I_loongson_2f, I_loongson_3a, @@ -130,6 +131,7 @@ N (64, 64, bfd_mach_mipsisa64, "mips:isa64", FALSE, NN(I_mipsisa64)), N (64, 64, bfd_mach_mipsisa64r2,"mips:isa64r2", FALSE, NN(I_mipsisa64r2)), N (64, 64, bfd_mach_mips_sb1, "mips:sb1", FALSE, NN(I_sb1)), + N (32, 32, bfd_mach_mips_allegrex, "mips:allegrex", FALSE, NN(I_allegrex)), N (64, 64, bfd_mach_mips_loongson_2e, "mips:loongson_2e", FALSE, NN(I_loongson_2e)), N (64, 64, bfd_mach_mips_loongson_2f, "mips:loongson_2f", FALSE, NN(I_loongson_2f)), N (64, 64, bfd_mach_mips_loongson_3a, "mips:loongson_3a", FALSE, NN(I_loongson_3a)), diff -burN orig.binutils-2.22/bfd/elfxx-mips.c binutils-2.22/bfd/elfxx-mips.c --- orig.binutils-2.22/bfd/elfxx-mips.c 2011-11-21 10:29:27.000000000 +0100 +++ binutils-2.22/bfd/elfxx-mips.c 2012-01-04 16:34:40.245420280 +0100 @@ -6173,14 +6173,19 @@ case E_MIPS_MACH_SB1: return bfd_mach_mips_sb1; + case E_MIPS_MACH_ALLEGREX: + return bfd_mach_mips_allegrex; + case E_MIPS_MACH_LS2E: return bfd_mach_mips_loongson_2e; case E_MIPS_MACH_LS2F: return bfd_mach_mips_loongson_2f; + /* case E_MIPS_MACH_LS3A: return bfd_mach_mips_loongson_3a; + */ case E_MIPS_MACH_OCTEON: return bfd_mach_mips_octeon; @@ -10882,6 +10887,10 @@ val = E_MIPS_ARCH_64 | E_MIPS_MACH_SB1; break; + case bfd_mach_mips_allegrex: + val = E_MIPS_ARCH_2 | E_MIPS_MACH_ALLEGREX; + break; + case bfd_mach_mips_loongson_3a: val = E_MIPS_ARCH_64 | E_MIPS_MACH_LS3A; break; @@ -13544,6 +13553,7 @@ /* MIPS II extensions. */ { bfd_mach_mips4000, bfd_mach_mips6000 }, { bfd_mach_mipsisa32, bfd_mach_mips6000 }, + { bfd_mach_mips_allegrex, bfd_mach_mips6000 }, /* MIPS I extensions. */ { bfd_mach_mips6000, bfd_mach_mips3000 }, diff -burN orig.binutils-2.22/bfd/version.h binutils-2.22/bfd/version.h --- orig.binutils-2.22/bfd/version.h 2011-11-21 10:29:28.000000000 +0100 +++ binutils-2.22/bfd/version.h 2012-01-04 16:18:30.454281876 +0100 @@ -1,4 +1,4 @@ -#define BFD_VERSION_DATE 20111121 +#define BFD_VERSION_DATE (PSNPT 20120103) #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff -burN orig.binutils-2.22/binutils/readelf.c binutils-2.22/binutils/readelf.c --- orig.binutils-2.22/binutils/readelf.c 2011-09-21 22:49:13.000000000 +0200 +++ binutils-2.22/binutils/readelf.c 2012-01-04 22:48:15.610613183 +0100 @@ -2395,10 +2395,11 @@ case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break; case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break; case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break; - case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; + /* case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; */ case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break; case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break; case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break; + case E_MIPS_MACH_ALLEGREX: strcat(buf, ", allegrex"); break; case 0: /* We simply ignore the field in this case to avoid confusion: MIPS ELF does not specify EF_MIPS_MACH, it is a GNU diff -burN orig.binutils-2.22/config.sub binutils-2.22/config.sub --- orig.binutils-2.22/config.sub 2011-06-06 12:36:06.000000000 +0200 +++ binutils-2.22/config.sub 2012-01-04 22:48:59.316081182 +0100 @@ -279,6 +279,7 @@ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ + | mipsallegrex | mipsallegrexel \ | mn10200 | mn10300 \ | moxie \ | mt \ @@ -389,6 +390,7 @@ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ + | mipsallegrex-* | mipsallegrexel-* \ | mmix-* \ | mt-* \ | msp430-* \ @@ -788,6 +790,10 @@ basic_machine=m68k-atari os=-mint ;; + psp) + basic_machine=mipsallegrexel-psp + os=-elf + ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; diff -burN orig.binutils-2.22/configure binutils-2.22/configure --- orig.binutils-2.22/configure 2011-08-14 14:28:15.000000000 +0200 +++ binutils-2.22/configure 2012-01-04 16:18:36.756209883 +0100 @@ -2667,7 +2667,7 @@ # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. # If --enable-gold is used, "gold" may replace "ld". -host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools" +host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb etc expect dejagnu m4 utils guile fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. libgcj="target-libffi \ @@ -3568,7 +3568,6 @@ mips*-*-linux*) ;; mips*-*-*) - noconfigdirs="$noconfigdirs gprof" ;; sh-*-* | sh64-*-*) case "${target}" in diff -burN orig.binutils-2.22/gas/config/tc-mips.c binutils-2.22/gas/config/tc-mips.c --- orig.binutils-2.22/gas/config/tc-mips.c 2011-11-21 10:29:32.000000000 +0100 +++ binutils-2.22/gas/config/tc-mips.c 2012-01-14 23:46:05.823744072 +0100 @@ -91,8 +91,32 @@ #define ZERO 0 #define ATREG 1 +#define V0 2 +#define V1 3 +#define A0 4 +#define A1 5 +#define A2 6 +#define A3 7 +#define T0 8 +#define T1 9 +#define T2 10 +#define T3 11 +#define T4 12 +#define T5 13 +#define T6 14 +#define T7 15 #define S0 16 +#define S1 17 +#define S2 18 +#define S3 19 +#define S4 20 +#define S5 21 +#define S6 22 #define S7 23 +#define T8 24 +#define T9 25 +#define K0 26 +#define K1 27 #define TREG 24 #define PIC_CALL_REG 25 #define KT0 26 @@ -490,11 +514,14 @@ /* Return true if the given CPU supports the microMIPS ASE. */ #define CPU_HAS_MICROMIPS(cpu) 0 +/* True if the given CPU belongs to the Allegrex family. */ +#define CPU_IS_ALLEGREX(CPU) ((CPU) == CPU_ALLEGREX) + /* True if CPU has a dror instruction. */ #define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500) /* True if CPU has a ror instruction. */ -#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU) +#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU) || CPU_IS_ALLEGREX (CPU) /* True if CPU has seq/sne and seqi/snei instructions. */ #define CPU_HAS_SEQ(CPU) ((CPU) == CPU_OCTEON) @@ -528,6 +555,7 @@ || mips_opts.arch == CPU_R16000 \ || mips_opts.arch == CPU_RM7000 \ || mips_opts.arch == CPU_VR5500 \ + || mips_opts.arch == CPU_ALLEGREX \ || mips_opts.micromips \ ) @@ -1563,6 +1591,8 @@ static expressionS imm_expr; static expressionS imm2_expr; static expressionS offset_expr; +static expressionS vimm_expr[4]; +static expressionS voffset_expr[4]; /* Relocs associated with imm_expr and offset_expr. */ @@ -1571,6 +1601,15 @@ static bfd_reloc_code_real_type offset_reloc[3] = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED}; +/* set by vfpu code for prefix instructions */ + +static bfd_boolean vfpu_dprefix; +static char vfpu_dprefix_str[64]; +static bfd_boolean vfpu_sprefix; +static char vfpu_sprefix_str[64]; +static bfd_boolean vfpu_tprefix; +static char vfpu_tprefix_str[64]; + /* This is set to the resulting size of the instruction to be produced by mips16_ip if an explicit extension is used or by mips_ip if an explicit size is supplied. */ @@ -2580,6 +2619,56 @@ return; } + /* If we've generated operands for a VFPU prefix instruction then we need + to assemble and append the prefix instruction before emitting the + instruction it prefixes. Note that in mips_ip prefix operands do not + cause any side effects with imm_expr or offset_expr. If they did + we'd have to save and restore them here. */ + if (CPU_IS_ALLEGREX (mips_opts.arch) && ((vfpu_dprefix || vfpu_sprefix || vfpu_tprefix))) + { + + if (mips_opts.noreorder + && ( history[0].insn_mo->pinfo & (INSN_UNCOND_BRANCH_DELAY + | INSN_COND_BRANCH_DELAY + | INSN_COND_BRANCH_LIKELY))) + { + as_bad (_("instruction with prefix cannot be used in branch delay slot")); + } + + if (vfpu_dprefix) + { + struct mips_cl_insn prefix; + char buf[256]; + + sprintf (buf, "vpfxd %s", vfpu_dprefix_str); + mips_ip (buf, &prefix); + append_insn (&prefix, NULL, unused_reloc, FALSE); + vfpu_dprefix = FALSE; + } + + if (vfpu_sprefix) + { + struct mips_cl_insn prefix; + char buf[256]; + + sprintf (buf, "vpfxs %s", vfpu_sprefix_str); + mips_ip (buf, &prefix); + append_insn ( &prefix, NULL, unused_reloc, FALSE); + vfpu_sprefix = FALSE; + } + + if (vfpu_tprefix) + { + struct mips_cl_insn prefix; + char buf[256]; + + sprintf (buf, "vpfxt %s", vfpu_tprefix_str); + mips_ip (buf, &prefix); + append_insn (&prefix, NULL, unused_reloc, FALSE); + vfpu_tprefix = FALSE; + } + } + if (insn.insn_mo->pinfo == INSN_MACRO) { macro_start (); @@ -5085,6 +5174,55 @@ } continue; + /* VFPU fields */ + case '?': + switch (*fmt++) + { + case 'o': + *r = (bfd_reloc_code_real_type) va_arg (args, int); + gas_assert (*r == BFD_RELOC_GPREL16 + || *r == BFD_RELOC_MIPS_LITERAL + || *r == BFD_RELOC_MIPS_HIGHER + || *r == BFD_RELOC_HI16_S + || *r == BFD_RELOC_LO16 + || *r == BFD_RELOC_MIPS_GOT16 + || *r == BFD_RELOC_MIPS_CALL16 + || *r == BFD_RELOC_MIPS_GOT_DISP + || *r == BFD_RELOC_MIPS_GOT_PAGE + || *r == BFD_RELOC_MIPS_GOT_OFST + || *r == BFD_RELOC_MIPS_GOT_LO16 + || *r == BFD_RELOC_MIPS_CALL_LO16); + break; + case 'd': + insn.insn_opcode |= va_arg (args, int) << VF_SH_VD; + fmt += 2; + break; + case 's': + insn.insn_opcode |= va_arg (args, int) << VF_SH_VS; + fmt += 2; + break; + case 'm': + { + int vtreg = va_arg (args, int); + insn.insn_opcode |= (vtreg & VF_MASK_VML) << VF_SH_VML; + insn.insn_opcode |= ((vtreg >> 5) & VF_MASK_VMH) << VF_SH_VMH; + fmt += 2; + } + break; + case 'n': + { + int vtreg = va_arg (args, int); + insn.insn_opcode |= (vtreg & VF_MASK_VNL) << VF_SH_VNL; + insn.insn_opcode |= ((vtreg >> 5) & VF_MASK_VNH) << VF_SH_VNH; + fmt += 2; + } + break; + case 'e': + insn.insn_opcode |= va_arg (args, int) << VF_SH_MCOND; + break; + } + continue; + default: internalError (); } @@ -6241,6 +6379,7 @@ macro (struct mips_cl_insn *ip) { unsigned int treg, sreg, dreg, breg; + int vsreg, vtreg, vdreg, vmreg, vwb; unsigned int tempreg; int mask; int used_at = 0; @@ -6272,6 +6411,13 @@ sreg = breg = EXTRACT_OPERAND (mips_opts.micromips, RS, *ip); mask = ip->insn_mo->mask; + vmreg = ((ip->insn_opcode >> 16) & 0x1f) + | ((ip->insn_opcode << 5) & 0x60); + vtreg = (ip->insn_opcode >> 16) & 0x7f; + vsreg = (ip->insn_opcode >> 8) & 0x7f; + vdreg = (ip->insn_opcode >> 0) & 0x7f; + vwb = (ip->insn_opcode >> 1) & 0x1; + label_expr.X_op = O_constant; label_expr.X_op_symbol = NULL; label_expr.X_add_symbol = NULL; @@ -7964,6 +8110,34 @@ /* Itbl support may require additional care here. */ coproc = 1; goto ld_st; + case M_LV_S_AB: + s = "lv.s"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?m0x,?o(b)"; + treg = vmreg; + goto ld; + case M_LV_Q_AB: + s = "lv.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld; + case M_LVL_Q_AB: + s = "lvl.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld; + case M_LVR_Q_AB: + s = "lvr.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld; case M_LWL_AB: ab = 1; case M_LWL_OB: @@ -8125,6 +8299,37 @@ /* Itbl support may require additional care here. */ coproc = 1; goto ld_st; + case M_SV_S_AB: + s = "sv.s"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?m0x,?o(b)"; + treg = vmreg; + goto ld_st; + case M_SV_Q_AB: + if (vwb) + s = "vwb.q"; + else + s = "sv.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld_st; + case M_SVL_Q_AB: + s = "svl.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld_st; + case M_SVR_Q_AB: + s = "svr.q"; + /* Itbl support may require additional care here. */ + coproc = 1; + fmt = "?n3x,?o(b)"; + treg = vmreg; + goto ld_st; case M_SWL_AB: ab = 1; case M_SWL_OB: @@ -8654,6 +8859,138 @@ break; } + case M_LVI_S_SS: + case M_LVI_P_SS: + case M_LVI_T_SS: + case M_LVI_Q_SS: + { + int mtx = (vtreg >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; + int idx = (vtreg >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; + int fsl = 0; + int rxc = 0; + int vtreg_s = 0; + int vnum = 0; + int vat = 0; + int i; + + switch (mask) + { + case M_LVI_S_SS: + vnum = 1; + fsl = (vtreg >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; + rxc = 0; + break; + case M_LVI_P_SS: + vnum = 2; + fsl = ((vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL) << 1; + rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + break; + case M_LVI_T_SS: + vnum = 3; + fsl = (vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; + rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + break; + case M_LVI_Q_SS: + vnum = 4; + fsl = 0; + rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + break; + } + if (rxc) + vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_FSL) + | (fsl << VF_SH_MR_IDX); + else + vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_IDX) + | (fsl << VF_SH_MR_FSL); + + for (i = 0; i < vnum; i++) { + imm_expr = vimm_expr[i]; + offset_expr = voffset_expr[i]; + + if (imm_expr.X_op == O_constant) + { + load_register (AT, &imm_expr, 0); + macro_build ((expressionS *) NULL, + "mtv", "t,?d0z", AT, vtreg_s); + vat = 1; + } + else + { + gas_assert (offset_expr.X_op == O_symbol + && strcmp (segment_name (S_GET_SEGMENT + (offset_expr.X_add_symbol)), + ".lit4") == 0 + && offset_expr.X_add_number == 0); + macro_build (&offset_expr, + "lv.s", "?m0x,?o(b)", vtreg_s, + (int) BFD_RELOC_MIPS_LITERAL, mips_gp_register); + } + + if (rxc) + vtreg_s += (1 << VF_SH_MR_IDX); + else + vtreg_s += (1 << VF_SH_MR_FSL); + } + + if (vat) + break; + else + return; + } + + case M_LVHI_S_SS: + case M_LVHI_P_SS: + { + int mtx = (vtreg >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; + int idx = (vtreg >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; + int fsl = 0; + int rxc = 0; + int vtreg_s = 0; + int vnum = 0; + int i; + unsigned int f16v; + char f16v_str[16]; + + switch (mask) + { + case M_LVHI_S_SS: + vnum = 2; + fsl = (vtreg >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; + rxc = 0; + break; + case M_LVHI_P_SS: + vnum = 4; + fsl = ((vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL) << 1; + rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + break; + } + if (rxc) + vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_FSL) + | (fsl << VF_SH_MR_IDX); + else + vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_IDX) + | (fsl << VF_SH_MR_FSL); + + + for (i = 0; i < vnum; i += 2) { + f16v = ((vimm_expr[i + 1].X_add_number & 0xffff) << 16) + | (vimm_expr[i].X_add_number & 0xffff); + sprintf(f16v_str, "0x%08x", f16v); + my_getExpression (&imm_expr, f16v_str); + + load_register (AT, &imm_expr, 0); + macro_build ((expressionS *) NULL, + "mtv", "t,?d0z", AT, vtreg_s); + + if (rxc) + vtreg_s += (1 << VF_SH_MR_IDX); + else + vtreg_s += (1 << VF_SH_MR_FSL); + } + + break; + } + case M_LI_D: /* Check if we have a constant in IMM_EXPR. If the GPRs are 64 bits wide, IMM_EXPR is the entire value. Otherwise IMM_EXPR is the high @@ -9164,6 +9501,27 @@ move_register (dreg, sreg); break; + case M_VCMOV_S: + s = "vcmovt.s"; + fmt = "?d0d,?s0s,?e"; + goto vcmov; + case M_VCMOV_P: + s = "vcmovt.p"; + fmt = "?d1d,?s1s,?e"; + goto vcmov; + case M_VCMOV_T: + s = "vcmovt.t"; + fmt = "?d2d,?s2s,?e"; + goto vcmov; + case M_VCMOV_Q: + s = "vcmovt.q"; + fmt = "?d3d,?s3s,?e"; + vcmov: + macro_build ((expressionS *) NULL, s, fmt, + vdreg, vsreg, + (ip->insn_opcode >> VF_SH_MCOND) & VF_MASK_MCOND); + return; + case M_DMUL: dbl = 1; case M_MUL: @@ -9779,6 +10137,40 @@ off12 = mips_opts.micromips; off = 3; goto uld_st; + + case M_ULV_S: + if (mips_opts.arch == CPU_ALLEGREX) + as_bad (_("opcode not supported on this processor")); + off = 3; + if (offset_expr.X_add_number >= 0x8000 - off) + as_bad (_("operand overflow")); + if (! target_big_endian) + offset_expr.X_add_number += off; + macro_build (&offset_expr, "lwl", "t,o(b)", + AT, (int) BFD_RELOC_LO16, breg); + if (! target_big_endian) + offset_expr.X_add_number -= off; + else + offset_expr.X_add_number += off; + macro_build (&offset_expr, "lwr", "t,o(b)", + AT, (int) BFD_RELOC_LO16, breg); + + macro_build ((expressionS *) NULL, "mtv", "t,?d0z", + AT, vmreg); + break; + + case M_ULV_Q: + off = 12; + if (offset_expr.X_add_number >= 0x8000 - off) + as_bad (_("operand overflow")); + offset_expr.X_add_number += off; + macro_build (&offset_expr, "lvl.q", "?n3x,?o(b)", + vmreg, (int) BFD_RELOC_LO16, breg); + offset_expr.X_add_number -= off; + macro_build (&offset_expr, "lvr.q", "?n3x,?o(b)", + vmreg, (int) BFD_RELOC_LO16, breg); + return; + case M_ULD_A: ab = 1; case M_ULD: @@ -9804,6 +10196,56 @@ off = 3; ust = 1; goto uld_st; + + case M_USV_S: + off = 3; + if (offset_expr.X_add_number >= 0x8000 - off) + as_bad (_("operand overflow")); + macro_build ((expressionS *) NULL, "mfv", "t,?d0z", + AT, vmreg); + if (mips_opts.arch != CPU_ALLEGREX) + { + if (! target_big_endian) + offset_expr.X_add_number += off; + macro_build (&offset_expr, "swl", "t,o(b)", + AT, (int) BFD_RELOC_LO16, breg); + if (! target_big_endian) + offset_expr.X_add_number -= off; + else + offset_expr.X_add_number += off; + macro_build (&offset_expr, "swr", "t,o(b)", + AT, (int) BFD_RELOC_LO16, breg); + } + else + { + if (target_big_endian) + offset_expr.X_add_number += off; + while (off-- >= 0) + { + macro_build (&offset_expr, "sb", "t,o(b)", + AT, (int) BFD_RELOC_LO16, breg); + macro_build ((expressionS *) NULL, "ror", + "d,w,<", AT, AT, 8); + if (target_big_endian) + --offset_expr.X_add_number; + else + ++offset_expr.X_add_number; + } + } + break; + + case M_USV_Q: + off = 12; + if (offset_expr.X_add_number >= 0x8000 - off) + as_bad (_("operand overflow")); + offset_expr.X_add_number += off; + macro_build (&offset_expr, "svl.q", "?n3x,?o(b)", + vmreg, (int) BFD_RELOC_LO16, breg); + offset_expr.X_add_number -= off; + macro_build (&offset_expr, "svr.q", "?n3x,?o(b)", + vmreg, (int) BFD_RELOC_LO16, breg); + return; + case M_USD_A: ab = 1; case M_USD: @@ -10279,6 +10721,103 @@ case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break; case '[': break; case ']': break; + + /* VFPU fields */ + case '?': + switch (c = *p++) + { + case '[': break; + case ']': break; + case 'y': + { + if ((*p != '0') && (*p != '1') && (*p != '2') && (*p != '3')) + { + as_bad (_("internal: bad mips opcode : %s %s"), + opc->name, opc->args); + return 0; + } + p++; + } + break; + + case 'o': USE_BITS (VF_MASK_OFFSET, VF_SH_OFFSET); break; + + case 's': + case 't': + case 'd': + case 'v': + case 'x': + case 'm': + case 'n': + { + if ((*p != '0') && (*p != '1') && (*p != '2') && (*p != '3') + && (*p != '5') && (*p != '6') && (*p != '7')) + { + as_bad (_("internal: bad mips opcode (vreg type `?%c'): %s %s"), + *p, opc->name, opc->args); + return 0; + } + p++; + + if ((*p != 's') && (*p != 't') && (*p != 'd') + && (*p != 'y') && (*p != 'x') && (*p != 'z') + && (*p != 'w') && (*p != 'm')) + { + as_bad (_("internal: bad mips opcode (vreg type `?%c'): %s %s"), + *(p - 1), opc->name, opc->args); + } + p++; + + switch (c) + { + case 's': USE_BITS (VF_MASK_VS, VF_SH_VS); break; + case 't': USE_BITS (VF_MASK_VT, VF_SH_VT); break; + case 'd': + case 'v': + case 'x': USE_BITS (VF_MASK_VD, VF_SH_VD); break; + case 'm': USE_BITS (VF_MASK_VML, VF_SH_VML); + USE_BITS (VF_MASK_VMH, VF_SH_VMH); break; + case 'n': USE_BITS (VF_MASK_VNL, VF_SH_VNL); + USE_BITS (VF_MASK_VNH, VF_SH_VNH); break; + } + } + break; + + case 'f': USE_BITS (VF_MASK_CC, VF_SH_CC); + p++; break; + + case 'a': USE_BITS (VF_MASK_CONST, VF_SH_CONST); break; + case 'b': USE_BITS (VF_MASK_SCALE, VF_SH_SCALE); break; + case 'c': USE_BITS (VF_MASK_BCOND, VF_SH_BCOND); break; + case 'e': USE_BITS (VF_MASK_MCOND, VF_SH_MCOND); break; + + case 'i': USE_BITS (VF_MASK_WRAP, VF_SH_WRAP); break; + + case 'q': USE_BITS (VF_MASK_VCD, VF_SH_VCD); break; + case 'r': USE_BITS (VF_MASK_VCS, VF_SH_VCS); break; + + case 'u': USE_BITS (VF_MASK_HFLOAT, VF_SH_HFLOAT); break; + + case 'w': USE_BITS (VF_MASK_ROT, VF_SH_ROT); break; + case 'z': USE_BITS (VF_MASK_RWB, VF_SH_RWB); break; + + case '0': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '1': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '2': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '3': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '4': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '5': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '6': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + case '7': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; + + default: + as_bad (_("internal: bad mips opcode (unknown extension operand type `?%c'): %s %s"), + c, opc->name, opc->args); + return 0; + + } + break; + case '1': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break; case '2': USE_BITS (OP_MASK_BP, OP_SH_BP); break; case '3': USE_BITS (OP_MASK_SA3, OP_SH_SA3); break; @@ -10585,7 +11124,7 @@ char c = 0; struct mips_opcode *insn; char *argsStart; - unsigned int regno; + unsigned int regno = 0; unsigned int lastregno; unsigned int destregno = 0; unsigned int lastpos = 0; @@ -10598,6 +11137,9 @@ unsigned int rtype; char *dot; long end; + unsigned int vdregno = 0xffff; + char vdregt = 0; + char vdregl = 0; insn_error = NULL; @@ -11683,6 +12225,1151 @@ case 'y': /* ALNV.PS source register. */ gas_assert (mips_opts.micromips); goto do_reg; + + /* VFPU fields */ + case '?': + switch (*++args) + { + case '[': + case ']': + if (*s++ == *args) + continue; + break; + + case 'y': /* immediate separator */ + ++args; + vimm_expr[*args - '0'] = imm_expr; + voffset_expr[*args - '0'] = offset_expr; + + imm_expr.X_op = O_absent; + offset_expr.X_op = O_absent; + imm_reloc[0] = BFD_RELOC_UNUSED; + imm_reloc[1] = BFD_RELOC_UNUSED; + imm_reloc[2] = BFD_RELOC_UNUSED; + offset_reloc[0] = BFD_RELOC_UNUSED; + offset_reloc[1] = BFD_RELOC_UNUSED; + offset_reloc[2] = BFD_RELOC_UNUSED; + + continue; + + case 'o': /* 16 bit offset */ + /* Check whether there is only a single bracketed expression + left. If so, it must be the base register and the + constant must be zero. */ + if (*s == '(' && strchr (s + 1, '(') == 0) + { + offset_expr.X_op = O_constant; + offset_expr.X_add_number = 0; + continue; + } + + /* If this value won't fit into a 16 bit offset, then go + find a macro that will generate the 32 bit offset + code pattern. */ + if (my_getSmallExpression (&offset_expr, offset_reloc, s) == 0 + && (offset_expr.X_op != O_constant + || offset_expr.X_add_number >= 0x8000 + || offset_expr.X_add_number < -0x8000)) + break; + + s = expr_end; + continue; + + case 's': /* VFPU source register */ + case 't': /* VFPU target register */ + case 'd': /* VFPU destination register */ + case 'v': /* VFPU destination register */ + case 'x': /* VFPU destination register */ + case 'm': /* VFPU target regsiter (load/store) */ + case 'n': /* VFPU target regsiter (load/store) */ + { + int dtype_err = 0; + int dnum_err = 0; + int dlen = 0; + char dtype = s[0]; + char regtype = *(args + 1); + + int mtx = 0; + int idx = 0; + int rxc = 0; + int fsl = 0; + int vidx = 0; + int vfsl = 0; + + if (ISDIGIT (s[1])) + { + int num = 0; + s++; + do + { + num *= 10; + num += *s - '0'; + dlen++; + s++; + } + while (ISDIGIT (*s)); + + if ((s[0] == '.') + && (s[1] == 's' || s[1] == 'p' + || s[1] == 't' || s[1] == 'q')) + s += 2; + + if (ISUPPER(dtype)) + dtype -= 'A' - 'a'; + + if (dtype == '$') + { + regno = num; + if (regno > VF_MAX_MR) + as_bad (_("Invalid VFPU register number (%d)"), + regno); + + idx = (num >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; + vfsl = (num >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; + switch (regtype) + { + case '0': /* single word */ + break; + case '1': /* pare word */ + dnum_err = (vfsl & 0x1); + break; + case '2': /* triple word */ + dnum_err = (vfsl > 1); + break; + case '3': /* quad word */ + dnum_err = (vfsl > 0); + break; + case '5': /* 2x2 word */ + dnum_err = (vfsl & 0x1) || (idx & 0x1); + break; + case '6': /* 3x3 word */ + dnum_err = (vfsl > 1) || (idx > 1); + break; + case '7': /* 4x4 word */ + dnum_err = (vfsl > 0) || (idx > 0); + break; + } + + if (dnum_err) + as_bad (_("Improper VFPU register number (%d)"), + regno); + + } + else if ((dlen == 3) + && ((dtype == 's') + || (dtype == 'c') || (dtype == 'r') + || (dtype == 'm') || (dtype == 'e'))) + { + mtx = num / 100; + if ((dtype == 'r') || (dtype == 'e')) + { + vfsl = (num / 10) % 10; + vidx = num % 10; + rxc = 1; + } + else + { + vidx = (num / 10) % 10; + vfsl = num % 10; + rxc = 0; + } + + switch (regtype) + { + case '0': /* single word */ + idx = vidx; + fsl = vfsl; + dtype_err = (dtype != 's'); + break; + case '1': /* pare word */ + idx = vidx; + fsl = (vfsl & 0x2) | rxc; + dnum_err = (vfsl & 0x1); + dtype_err = (dtype != 'c') && (dtype != 'r'); + break; + case '2': /* triple word */ + idx = vidx; + fsl = ((vfsl & 0x1) << 1) | rxc; + dnum_err = (vfsl > 1); + dtype_err = (dtype != 'c') && (dtype != 'r'); + break; + case '3': /* quad word */ + idx = vidx; + fsl = rxc; + dnum_err = (vfsl > 0); + dtype_err = (dtype != 'c') && (dtype != 'r'); + break; + case '5': /* 2x2 word */ + idx = vidx & 0x2; + fsl = (vfsl & 0x2) | rxc; + dnum_err = (vfsl & 0x1) || (vidx & 0x1); + dtype_err = (dtype != 'm') && (dtype != 'e'); + break; + case '6': /* 3x3 word */ + idx = vidx & 0x1; + fsl = ((vfsl & 0x1) << 1) | rxc; + dnum_err = (vfsl > 1) || (vidx > 1); + dtype_err = (dtype != 'm') && (dtype != 'e'); + break; + case '7': /* 4x4 word */ + idx = 0; + fsl = rxc; + dnum_err = (vfsl > 0) || (vidx > 0); + dtype_err = (dtype != 'm') && (dtype != 'e'); + break; + } + + if (dtype_err) + as_bad (_("Improper VFPU register prefix '%c'"), + dtype); + if (dnum_err) + as_bad (_("Improper VFPU register number (%03d)"), + num); + + if (mtx > VF_MAX_MR_MTX) + as_bad (_("VFPU matrix range over %d"), mtx); + if (vidx > VF_MAX_MR_IDX) + as_bad (_("VFPU index range over %d"), idx); + if (vfsl > VF_MAX_MR_FSL) + as_bad (_("VFPU field select range over %d"), fsl); + + regno = ((fsl & VF_MASK_MR_FSL) << VF_SH_MR_FSL) + | ((mtx & VF_MASK_MR_MTX) << VF_SH_MR_MTX) + | ((idx & VF_MASK_MR_IDX) << VF_SH_MR_IDX); + } + else + { + as_bad (_("Improper VFPU register prefix '%c'"), + dtype); + } + } + else + { + as_bad (_("bad operand %s"), s); + } + + if ((*args == 'v') || (*args == 'x')) + { + vdregno = regno; + vdregt = regtype; + vdregl = (*args == 'v'); + } + else if (vdregno <= VF_MAX_MR) + { + static unsigned short used_vreg[8][16] = { + { 0x0001, 0x0010, 0x0100, 0x1000, + 0x0002, 0x0020, 0x0200, 0x2000, + 0x0004, 0x0040, 0x0400, 0x4000, + 0x0008, 0x0080, 0x0800, 0x8000 }, + { 0x0003, 0x0030, 0x0300, 0x3000, + 0x0011, 0x0022, 0x0044, 0x0088, + 0x000c, 0x00c0, 0x0c00, 0xc000, + 0x1100, 0x2200, 0x4400, 0x8800 }, + { 0x0007, 0x0070, 0x0700, 0x7000, + 0x0111, 0x0222, 0x0444, 0x0888, + 0x000e, 0x00e0, 0x0e00, 0xe000, + 0x1110, 0x2220, 0x4440, 0x8880 }, + { 0x000f, 0x00f0, 0x0f00, 0xf000, + 0x1111, 0x2222, 0x4444, 0x8888, + 0x000f, 0x00f0, 0x0f00, 0xf000, + 0x1111, 0x2222, 0x4444, 0x8888 }, + { 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 }, + { 0x0033, 0x0033, 0x3300, 0x3300, + 0x0033, 0x0033, 0x00cc, 0x00cc, + 0x00cc, 0x00cc, 0xcc00, 0xcc00, + 0x3300, 0x3300, 0xcc00, 0xcc00 }, + { 0x0777, 0x7770, 0x0777, 0x7770, + 0x0777, 0x0eee, 0x0777, 0x0eee, + 0x0eee, 0xeee0, 0x0eee, 0xeee0, + 0x7770, 0xeee0, 0x7770, 0xeee0 }, + { 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff }, + }; + int dmtx, smtx; + int dfsl, sfsl; + int didx, sidx; + int drxc, srxc; + + dmtx = (vdregno >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; + smtx = (regno >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; + + if (dmtx == smtx) + { + unsigned short dused, sused; + int dtype2, stype; + + dfsl = (vdregno >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; + didx = (vdregno >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; + drxc = (vdregno >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + sfsl = (regno >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; + sidx = (regno >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; + srxc = (regno >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; + + dtype2 = vdregt - '0'; + stype = regtype - '0'; + dused = used_vreg[dtype2][(dfsl << 2) + didx]; + sused = used_vreg[stype][(sfsl << 2) + sidx]; + + if ((dused & sused) + && (vdregl || (dused ^ sused) || (drxc != srxc))) + { + int dvfsl; + dvfsl = (vdregno >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; + switch (vdregt) + { + case '1': + dvfsl <<= 1; + case '2': + case '3': + if (drxc) + as_bad (_("VFPU register conflict(R%d%d%d)"), + dmtx, dvfsl, didx); + else + as_bad (_("VFPU register conflict(C%d%d%d)"), + dmtx, didx, dvfsl); + break; + case '5': + dvfsl <<= 1; + case '6': + case '7': + if (drxc) + as_bad (_("VFPU register conflict(E%d%d%d)"), + dmtx, dvfsl, didx); + else + as_bad (_("VFPU register conflict(M%d%d%d)"), + dmtx, didx, dvfsl); + break; + } + } + } + } + + switch (*args++) + { + case 's': + if ( + (ip->insn_opcode + & VFPU_MASK_RPT_MMUL) == VFPU_INST_RPT_MMUL) + { + if (regno & (VF_MASK_MR_RXC << VF_SH_MR_RXC)) + regno &= ~(VF_MASK_MR_RXC << VF_SH_MR_RXC); + else + regno |= (VF_MASK_MR_RXC << VF_SH_MR_RXC); + } + ip->insn_opcode |= (regno & VF_MASK_VS) << VF_SH_VS; + break; + case 't': + ip->insn_opcode |= (regno & VF_MASK_VT) << VF_SH_VT; + break; + case 'd': + case 'v': + case 'x': + ip->insn_opcode |= (regno & VF_MASK_VD) << VF_SH_VD; + break; + case 'm': + { + int vmregL = (regno >> 0) & VF_MASK_VML; + int vmregH = (regno >> 5) & VF_MASK_VMH; + ip->insn_opcode |= (vmregL << VF_SH_VML) + | (vmregH << VF_SH_VMH); + } + break; + case 'n': + { + int vmregL = (regno >> 0) & VF_MASK_VNL; + int vmregH = (regno >> 5) & VF_MASK_VNH; + ip->insn_opcode |= (vmregL << VF_SH_VNL) + | (vmregH << VF_SH_VNH); + } + break; + } + args++; + + /* now check for vfpu prefixes if necessary */ + if (*s == '[') + { + char *prefix_out = NULL; + bfd_boolean *prefix_bool = NULL; + char *prefix_type = NULL; + int num_args = 0; + char *ob = ++s; + bfd_boolean has_w = FALSE; + bfd_boolean has_z = FALSE; + bfd_boolean has_y = FALSE; + bfd_boolean has_operator = FALSE; + bfd_boolean has_saturater = FALSE; + + switch (*args) + { + case 'w': /* only swizzle */ + case 's': /* source prefix */ + prefix_bool = &vfpu_sprefix; + prefix_out = vfpu_sprefix_str; + prefix_type = "source"; + break; + case 't': /* target prefix */ + prefix_bool = &vfpu_tprefix; + prefix_out = vfpu_tprefix_str; + prefix_type = "target"; + break; + case 'm': /* only write mask */ + case 'd': /* destination prefix */ + prefix_bool = &vfpu_dprefix; + prefix_out = vfpu_dprefix_str; + prefix_type = "destination"; + break; + case 'y': /* inhibit */ + prefix_bool = NULL; + prefix_type = "source"; + break; + case 'x': /* inhibit */ + prefix_bool = NULL; + prefix_type = "target"; + break; + case 'z': /* inhibit */ + prefix_bool = NULL; + prefix_type = "destination"; + break; + } + + for ( ; *s != '\0' && *s != ']'; s++) + { + switch (*s) + { + case ',': + /* count no. of params for syntax check */ + num_args++; + break; + case ' ': + case '\t': + break; + case 'm': + case 'M': + case 'x': + case 'X': + break; + case 'y': + case 'Y': + has_y = TRUE; + break; + case 'z': + case 'Z': + has_z = TRUE; + break; + case 'w': + case 'W': + has_w = TRUE; + break; + default: + if (*args == 'w') + has_operator = TRUE; + if (*args == 'm') + has_saturater = TRUE; + } + } + + if (*s == ']') + { + if (prefix_bool) + { + *prefix_bool = TRUE; + strncpy (prefix_out, ob, s - ob); + prefix_out[s - ob] = '\0'; + s++; + } + else + { + as_bad (_("%s cannot use %s prefix"), + insn->name, prefix_type); + s++; + continue; + } + } + else + { + as_bad (_("parse error (%s)"), ob - 1); + return; + } + + if (num_args != regtype - '0') + { + as_bad (_("%s prefix specification requires %d parameters - [%s]"), + prefix_type, regtype - '0' + 1, + prefix_out); + } + else + { + int i = 8 - ((3 - num_args) * 2); + char dummy_d[] = " m,m,m,m"; + char dummy_st[] = " x,y,z,w"; + + if (*args == 'd' || *args == 'm') + { + strcat (prefix_out, dummy_d + i); + if (has_saturater) + { + as_bad (_("%s is restricted to mask destination prefixes only"), + insn->name); + } + } + else + { + strcat (prefix_out, dummy_st + i); + if (has_operator) + { + as_bad (_("%s is restricted to swizzle %s prefixes only"), + insn->name, prefix_type); + } + /* semantic check, w can't be specified for + s, p, or t instructions same goes for + z for p and s, and y for scalars */ + if ((has_y && num_args == 0) + || (has_z && num_args < 2) + || (has_w && num_args < 3)) + { + as_bad (_("%s swizzle operand is out of range in [%s]"), + prefix_type, prefix_out); + } + } + } + } + + continue; + } + break; + + case 'q': /* VFPU destination control register */ + case 'r': /* VFPU source control register */ + { + if ((s[0] == '$') && ISDIGIT (s[1])) + { + s++; + regno = 0; + do + { + regno *= 10; + regno += *s - '0'; + ++s; + } + while (ISDIGIT (*s)); + + if ((regno < VF_MIN_CR) || (regno > VF_MAX_CR)) + as_bad (_("Invalid VFPU control register number (%d)"), + regno); + + else if (!((regno >= VF_MIN_VCR) && (regno <= VF_MAX_VCR))) + as_bad (_("Improper VFPU control register number (%d)"), + regno); + + switch (*args) + { + case 'q': + ip->insn_opcode |= (regno & VF_MASK_VCD) << VF_SH_VCD; + break; + case 'r': + ip->insn_opcode |= (regno & VF_MASK_VCS) << VF_SH_VCS; + break; + } + } + else + { + as_bad (_("Invalid VFPU control register name (%s)"), s); + } + + continue; + } + break; + + case 'f': /* condition code */ + { + int cond = 0; + if (ISDIGIT (s[0])) + { + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + cond = imm_expr.X_add_number; + if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC)) + as_bad (_("Invalid VFPU condition code (%d)"), cond); + imm_expr.X_op = O_absent; + s = expr_end; + } + else + { + static const char * const vfpu_cond_names[] = { + "FL", "EQ", "LT", "LE", + "TR", "NE", "GE", "GT", + "EZ", "EN", "EI", "ES", + "NZ", "NN", "NI", "NS" }; + for (cond = VF_MIN_CC; cond <= VF_MAX_CC; cond++) + { + if (strncasecmp(vfpu_cond_names[cond], s, 2) == 0) + break; + } + if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC)) + as_bad (_("Invalid VFPU condition code (%s)"), s); + + s += 2; + } + + args++; + if ((cond == 0) || (cond == 4)) + { + } + else if (cond & 0x8) + { + if (*args - '0' < 1) + as_bad (_("Invalid VFPU condition oparetion")); + } + else + { + if (*args - '0' < 2) + as_bad (_("Invalid VFPU condition oparetion")); + } + + ip->insn_opcode |= (cond & VF_MASK_CC) << VF_SH_CC; + continue; + } + break; + + case 'a': /* constant code */ + { + int cst = 0; + if (ISDIGIT (s[0])) + { + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + cst = imm_expr.X_add_number; + if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST)) + { + as_bad (_("Improper constant code (%d)"), cst); + cst &= VF_MASK_CONST; + } + imm_expr.X_op = O_absent; + s = expr_end; + } + else + { + static const char * const vfpu_const_names[] = { + "", "VFPU_HUGE", "VFPU_SQRT2", "VFPU_SQRT1_2", + "VFPU_2_SQRTPI", "VFPU_2_PI", "VFPU_1_PI", "VFPU_PI_4", + "VFPU_PI_2", "VFPU_PI", "VFPU_E", "VFPU_LOG2E", + "VFPU_LOG10E", "VFPU_LN2", "VFPU_LN10", "VFPU_2PI", + "VFPU_PI_6", "VFPU_LOG10TWO", "VFPU_LOG2TEN", + "VFPU_SQRT3_2"}; + for (cst = VF_MIN_CONST; cst <= VF_MAX_CONST; cst++) + { + if (strcasecmp(vfpu_const_names[cst], s) == 0) + break; + } + if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST)) + as_bad (_("Invalid constant code (%s)"), s); + else + s += strlen(vfpu_const_names[cst]); + } + + ip->insn_opcode |= cst << VF_SH_CONST; + } + continue; + + case 'b': /* scale exponent */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_SCALE) + { + as_bad (_("Improper scale (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_SCALE; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_SCALE; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'c': /* branch condition code bit */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_BCOND) + { + as_bad (_("Improper condition bit (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_BCOND; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_BCOND; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'e': /* move condition code bit */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_MCOND) + { + as_bad (_("Improper condition bit (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_MCOND; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_MCOND; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'i': /* wrap exponent */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_WRAP) + { + as_bad (_("Improper wrap (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_WRAP; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_WRAP; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'w': /* rotation code */ + if (s[0] == '[') + { + char *rot_str = s; + int rot_idx = 0; + int rot_neg = 0; + int rot_sin = 3; + int rot_cos = 3; + int rot_err = 0; + int rot_n; + int rot_neg_n = 0; + int rot_sin_n = 0; + int rot_cos_n = 0; + int rot_code; + + if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_PAIR) + rot_n = 2; + else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_TRIPLE) + rot_n = 3; + else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_QUAD) + rot_n = 4; + else + rot_n = 0; + + s++; + while ((s[0] != ']') && (s[0] != '\0')) + { + if (s[0] == '-') + { + if ((s[1] != 's') && (s[1] != 'S')) + { + rot_err = 1; + break; + } + rot_neg = 1; + rot_neg_n++; + s++; + } + + if (s[0] == ',') + rot_idx++; + else if ((s[0] == 'c') || (s[0] == 'C')) + { + rot_cos = rot_idx; + rot_cos_n++; + } + else if ((s[0] == 's') || (s[0] == 'S')) + { + rot_sin = rot_idx; + rot_sin_n++; + } + else if (ISSPACE(s[0]) || (s[0] == '0')) + ; + else + { + rot_err = 1; + break; + } + + s++; + } + + if (s[0] == ']') + rot_idx++; + else + rot_err = 1; + s++; + + if ((rot_sin_n == 0) && (rot_cos_n == 0)) + { + if (rot_n == 2) + rot_sin = 2; + else if ((rot_n == 4) || (rot_n == 3)) + rot_err = 1; + } + + if (rot_cos_n > 1) + rot_err = 1; + + if (rot_sin_n > 1) + { + if (((rot_sin_n + rot_cos_n) != rot_n) + || ((rot_n == 4) && (rot_cos_n == 0))) + rot_err = 1; + } + + if (rot_neg && (rot_neg_n != rot_sin_n)) + rot_err = 1; + + if (rot_sin_n > 1) + rot_sin = rot_cos; + + if (rot_err || (rot_n != rot_idx)) + as_bad (_("Invalid rotation code (%s)"), rot_str); + + rot_code = ((rot_neg & VF_MASK_ROT_NEG) << VF_SH_ROT_NEG) + | ((rot_cos & VF_MASK_ROT_COS) << VF_SH_ROT_COS) + | ((rot_sin & VF_MASK_ROT_SIN) << VF_SH_ROT_SIN); + ip->insn_opcode |= rot_code << VF_SH_ROT; + } + else + { + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_ROT) + { + as_bad (_("Improper rotation code (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_ROT; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_ROT; + imm_expr.X_op = O_absent; + s = expr_end; + } + continue; + + case 'u': /* half float */ + if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) + { + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > VF_MAX_HFLOAT) + { + as_bad (_("Improper half floating point constant: (%lu)"), + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= VF_MASK_HFLOAT; + } + ip->insn_opcode |= imm_expr.X_add_number << VF_SH_HFLOAT; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + } + else + { + char *save_in; + char *err; + int len; + unsigned char temp[8]; + unsigned int f32, f16; + int exponent32, exponent16; + int fraction32, fraction16; + int sign; + char f16_str[8]; + + save_in = input_line_pointer; + input_line_pointer = s; + err = md_atof ('f', (char *) temp, &len); + s = input_line_pointer; + input_line_pointer = save_in; + if (err != NULL && *err != '\0') + { + as_bad (_("Bad half floating point constant: %s"), err); + memset (temp, '\0', sizeof temp); + } + + if (! target_big_endian) + f32 = bfd_getl32 (temp); + else + f32 = bfd_getb32 (temp); + + sign = (f32 >> VF_SH_F32_SIGN) & VF_MASK_F32_SIGN; + exponent32 = (f32 >> VF_SH_F32_EXP) & VF_MASK_F32_EXP; + fraction32 = (f32 >> VF_SH_F32_FRA) & VF_MASK_F32_FRA; + exponent16 = exponent32 + - VF_BIAS_F32_EXP + VF_BIAS_F16_EXP; + + if (exponent16 < VF_MIN_F16_EXP) + { + if ((exponent32 == VF_MIN_F32_EXP) + && (fraction32 == 0)) + { // zero + exponent16 = VF_MIN_F16_EXP; + fraction16 = 0; + } + else + { // underflow + float* p; + p = (float*) &f32; + as_warn (_("Half floating point underflow: %g"), + *p); + exponent16 = VF_MIN_F16_EXP; + fraction16 = 0; + } + } + else if (exponent16 > VF_MAX_F16_EXP) + { + if (exponent32 != VF_MAX_F32_EXP) + { // overflow + float* p; + p = (float*) &f32; + as_warn (_("Half floating point overflow: %g"), + *p); + exponent16 = VF_MAX_F16_EXP; + fraction16 = 0; + } + else + { + if (fraction32 == 0) + { // infinity + exponent16 = VF_MAX_F16_EXP; + fraction16 = 0; + } + else + { // NaN + exponent16 = VF_MAX_F16_EXP; + fraction16 = 1; + } + } + } + else + { + fraction16 = (f32 >> (VF_SH_F32_EXP - VF_SH_F16_EXP)) + & VF_MASK_F16_FRA; + } + + f16 = (sign << VF_SH_F16_SIGN) + | (exponent16 << VF_SH_F16_EXP) + | (fraction16 << VF_SH_F16_FRA); + ip->insn_opcode |= (f16 & VF_MASK_HFLOAT) << VF_SH_HFLOAT; + + sprintf(f16_str, "0x%04x", f16); + my_getExpression (&imm_expr, f16_str); + + continue; + } + break; + + case 'z': /* read/write access code */ + { + int rwb = 0; + + if (strncasecmp (s, "WT", 2) == 0) + rwb = 0x0; + else if (strncasecmp (s, "WB", 2) == 0) + rwb = 0x1; + else + as_bad (_("Invalid memory access type (%s)"), s); + + s += 2; + ip->insn_opcode |= (rwb & VF_MASK_RWB) << VF_SH_RWB; + + continue; + } + + case '0': /* source or target prefix code (X) */ + case '1': /* source or target prefix code (Y) */ + case '2': /* source or target prefix code (Z) */ + case '3': /* source or target prefix code (W) */ + { + int operand; + int shift; + + int pfx_neg = 0; + int pfx_cst = 0; + int pfx_abs = 0; + int pfx_swz = 0; + int pfx_err = 0; + int cst = 0; + char *pfx_str = s; + + if (s[0] == '-') + { // sign code + pfx_neg = 1; + s++; + } + + if (ISDIGIT (s[0])) + { // constant + pfx_cst = 1; + + if (s[0] == '0') + cst = 0; + else if (s[0] == '1') + { + if (s[1] == '/') + { + s += 2; + if (s[0] == '2') + cst = 3; + else if (s[0] == '3') + cst = 5; + else if (s[0] == '4') + cst = 6; + else if (s[0] == '6') + cst = 7; + else + pfx_err = 1; + } + else + { + cst = 1; + } + } + else if (s[0] == '2') + cst = 2; + else if (s[0] == '3') + cst = 4; + else + pfx_err = 1; + + pfx_abs = (cst >> 2) & 0x1; + pfx_swz = (cst >> 0) & 0x3; + s++; + } + else + { // variable + + if (s[0] == '|') + { // abs + pfx_abs = 1; + s++; + } + + if ((s[0] == 'X') || (s[0] == 'x')) + { + pfx_swz = 0; + s++; + } + else if ((s[0] == 'Y') || (s[0] == 'y')) + { + pfx_swz = 1; + s++; + } + else if ((s[0] == 'Z') || (s[0] == 'z')) + { + pfx_swz = 2; + s++; + } + else if ((s[0] == 'W') || (s[0] == 'w')) + { + pfx_swz = 3; + s++; + } + else if ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]) + || (s[0] == '|')) + { + pfx_swz = *args - '0'; + } + else + pfx_err = 1; + + if (pfx_err == 0) + { + if (s[0] == '|') + { + s++; + if (pfx_abs == 0) + pfx_err = 1; + } + else + { + if (pfx_abs == 1) + pfx_err = 1; + } + } + } + + if (! ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]))) + pfx_err = 1; + + if (pfx_err) + as_bad (_("Invalid prefix format (%s)"), pfx_str); + + shift = *args - '0'; + + operand = (pfx_neg << (VF_SH_PFX_NEG + shift)) + | (pfx_cst << (VF_SH_PFX_CST + shift)) + | (pfx_abs << (VF_SH_PFX_ABS + shift)) + | (pfx_swz << (VF_SH_PFX_SWZ + shift * 2)); + + ip->insn_opcode |= operand; + continue; + } + + case '4': /* destination prefix code (X) */ + case '5': /* destination prefix code (Y) */ + case '6': /* destination prefix code (Z) */ + case '7': /* destination prefix code (W) */ + { + int operand; + int shift; + static const char order[] = "xyzwXYZW"; + + int pfx_msk = 0; + int pfx_sat = 0; + char *pfx_str = s; + + if (s[0] == '[') + s++; + if (s[0] == '-') /* -1:1, skip the minus symbol */ + s++; + + if ((s[0] == 'm') || (s[0] == 'M')) + { + pfx_msk = 1; + s++; + } + else if (s[0] == '0') /* 0:1 */ + { + pfx_sat = 1; + s++; + } + else if (s[0] == '1') /* -1:1 or -1:+1 */ + { + pfx_sat = 3; + s++; + } + else if ((s[0] == order[(*args) - '4']) + || (s[0] == order[(*args) - '4' + 4])) + { + pfx_sat = 0; + s++; + } + + if (s[0] == ':') /* skip the :1 or :+1 part of the expression */ + { + s++; + if (s[0] == '+') + s++; + if (s[0] == '1') + s++; + } + if (s[0] == ']') + s++; + + if (! ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]))) + as_bad (_("Invalid prefix format (%s)"), pfx_str); + + shift = *args - '4'; + operand = (pfx_msk << (VF_SH_PFX_MSK + shift)) + | (pfx_sat << (VF_SH_PFX_SAT + shift * 2)); + + ip->insn_opcode |= operand; + continue; + } + } + break; + case 'x': /* Ignore register name. */ case 'U': /* Destination register (CLO/CLZ). */ case 'g': /* Coprocessor destination register. */ @@ -11877,6 +13564,7 @@ { if ((regno & 1) != 0 && HAVE_32BIT_FPRS + && ! CPU_IS_ALLEGREX (mips_opts.arch) && !mips_oddfpreg_ok (ip->insn_mo, argnum)) as_warn (_("Float register should be even, was %d"), regno); @@ -18227,7 +19915,7 @@ | RELAX_DELAY_SLOT_SIZE_SECOND); msg = macro_warning (s); if (msg != NULL) - as_warn_where (fragp->fr_file, fragp->fr_line, msg); + as_warn_where (fragp->fr_file, fragp->fr_line, "%s", msg); subtype &= ~s; } @@ -18241,7 +19929,7 @@ & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT)); msg = macro_warning (s); if (msg != NULL) - as_warn_where (fragp->fr_file, fragp->fr_line, msg); + as_warn_where (fragp->fr_file, fragp->fr_line, "%s", msg); subtype &= ~s; } @@ -18913,6 +20601,8 @@ /* MIPS II */ { "r6000", 0, ISA_MIPS2, CPU_R6000 }, + /* Sony PSP "Allegrex" CPU core */ + { "allegrex", 0, ISA_MIPS2, CPU_ALLEGREX }, /* MIPS III */ { "r4000", 0, ISA_MIPS3, CPU_R4000 }, diff -burN orig.binutils-2.22/gas/configure binutils-2.22/gas/configure --- orig.binutils-2.22/gas/configure 2011-05-18 11:41:14.000000000 +0200 +++ binutils-2.22/gas/configure 2012-01-04 16:18:36.289215219 +0100 @@ -12043,6 +12043,9 @@ mips64vr | mips64vrel) mips_cpu=vr4100 ;; + mipsallegrex | mipsallegrexel) + mips_cpu=allegrex + ;; mipsisa32r2* | mipsisa64r2*) mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'` ;; diff -burN orig.binutils-2.22/gas/configure.in binutils-2.22/gas/configure.in --- orig.binutils-2.22/gas/configure.in 2011-05-18 11:41:14.000000000 +0200 +++ binutils-2.22/gas/configure.in 2012-01-04 16:18:36.289215219 +0100 @@ -213,6 +213,9 @@ mips64vr | mips64vrel) mips_cpu=vr4100 ;; + mipsallegrex | mipsallegrexel) + mips_cpu=allegrex + ;; mipsisa32r2* | mipsisa64r2*) changequote(,)dnl mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'` diff -burN orig.binutils-2.22/gas/testsuite/gas/mips/mips.exp binutils-2.22/gas/testsuite/gas/mips/mips.exp --- orig.binutils-2.22/gas/testsuite/gas/mips/mips.exp 2011-11-21 10:29:32.000000000 +0100 +++ binutils-2.22/gas/testsuite/gas/mips/mips.exp 2012-01-04 16:18:34.940230631 +0100 @@ -409,6 +409,9 @@ mips_arch_create sb1 64 mips64 { mips3d } \ { -march=sb1 -mtune=sb1 } { -mmips:sb1 } \ { mipsisa64sb1-*-* mipsisa64sb1el-*-* } +mips_arch_create allegrex 32 mips2 { ror } \ + { -march=allegrex -mtune=allegrex } { -mmips:allegrex } \ + { mipsallegrex-*-* mipsallegrexel-*-* } mips_arch_create octeon 64 mips64r2 {} \ { -march=octeon -mtune=octeon } { -mmips:octeon } \ { mips64octeon*-*-* } diff -burN orig.binutils-2.22/include/elf/common.h binutils-2.22/include/elf/common.h --- orig.binutils-2.22/include/elf/common.h 2011-07-22 22:22:36.000000000 +0200 +++ binutils-2.22/include/elf/common.h 2012-01-04 16:18:36.333214716 +0100 @@ -96,6 +96,7 @@ #define ET_HIOS 0xFEFF /* Operating system-specific */ #define ET_LOPROC 0xFF00 /* Processor-specific */ #define ET_HIPROC 0xFFFF /* Processor-specific */ +#define ET_PSPEXEC 0xFFA0 /* Sony PSP executable file */ /* Values for e_machine, which identifies the architecture. These numbers are officially assigned by registry@sco.com. See below for a list of diff -burN orig.binutils-2.22/include/elf/mips.h binutils-2.22/include/elf/mips.h --- orig.binutils-2.22/include/elf/mips.h 2011-07-24 16:20:12.000000000 +0200 +++ binutils-2.22/include/elf/mips.h 2012-01-04 16:32:22.726926151 +0100 @@ -265,6 +265,7 @@ #define E_MIPS_MACH_5400 0x00910000 #define E_MIPS_MACH_5500 0x00980000 #define E_MIPS_MACH_9000 0x00990000 +#define E_MIPS_MACH_ALLEGREX 0x00A20000 #define E_MIPS_MACH_LS2E 0x00A00000 #define E_MIPS_MACH_LS2F 0x00A10000 #define E_MIPS_MACH_LS3A 0x00A20000 diff -burN orig.binutils-2.22/include/opcode/mips.h binutils-2.22/include/opcode/mips.h --- orig.binutils-2.22/include/opcode/mips.h 2011-08-09 17:20:03.000000000 +0200 +++ binutils-2.22/include/opcode/mips.h 2012-01-04 16:18:36.338214659 +0100 @@ -216,6 +216,228 @@ #define MDMX_FMTSEL_VEC_QH 0x15 #define MDMX_FMTSEL_VEC_OB 0x16 +#include "vfpu.h" + +#define VF_MASK_VT 0x7f +#define VF_SH_VT 16 +#define VF_MASK_VS 0x7f +#define VF_SH_VS 8 +#define VF_MASK_VD 0x7f +#define VF_SH_VD 0 +#define VF_MASK_VML 0x1f +#define VF_SH_VML 16 +#define VF_MASK_VMH 0x3 +#define VF_SH_VMH 0 +#define VF_MASK_VNL 0x1f +#define VF_SH_VNL 16 +#define VF_MASK_VNH 0x1 +#define VF_SH_VNH 0 +#define VF_MASK_OFFSET 0x3fff +#define VF_SH_OFFSET 2 +#define VF_MASK_CC 0xf +#define VF_SH_CC 0 +#define VF_MASK_CONST 0x1f +#define VF_SH_CONST 16 +#define VF_MASK_SCALE 0x1f +#define VF_SH_SCALE 16 +#define VF_MASK_BCOND 0x7 +#define VF_SH_BCOND 18 +#define VF_MASK_MCOND 0x7 +#define VF_SH_MCOND 16 +#define VF_MASK_VCD 0xff +#define VF_SH_VCD 0 +#define VF_MASK_VCS 0xff +#define VF_SH_VCS 8 +#define VF_MASK_ROT 0x1f +#define VF_SH_ROT 16 +#define VF_MASK_WRAP 0xff +#define VF_SH_WRAP 16 +#define VF_MASK_TSIGN 0x1 +#define VF_SH_TSIGN 5 +#define VF_MASK_BMCOND 0x1f +#define VF_SH_BMCOND 0 +#define VF_MASK_HFLOAT 0xffff +#define VF_SH_HFLOAT 0 +#define VF_MASK_PFX 0xffffff +#define VF_SH_PFX 0 +#define VF_MASK_RWB 0x1 +#define VF_SH_RWB 1 + +#define VF_MASK_PFX_SWZ 0x3 +#define VF_SH_PFX_SWZ 0 +#define VF_MASK_PFX_ABS 0x1 +#define VF_SH_PFX_ABS 8 +#define VF_MASK_PFX_CST 0x1 +#define VF_SH_PFX_CST 12 +#define VF_MASK_PFX_NEG 0x1 +#define VF_SH_PFX_NEG 16 +#define VF_MASK_PFX_SAT 0x3 +#define VF_SH_PFX_SAT 0 +#define VF_MASK_PFX_MSK 0x1 +#define VF_SH_PFX_MSK 8 + +#define VF_MASK_ROT_COS 0x3 +#define VF_SH_ROT_COS 0 +#define VF_MASK_ROT_SIN 0x3 +#define VF_SH_ROT_SIN 2 +#define VF_MASK_ROT_NEG 0x1 +#define VF_SH_ROT_NEG 4 + +#define VF_MASK_MR_MTX 0x7 +#define VF_SH_MR_MTX 2 +#define VF_MASK_MR_IDX 0x3 +#define VF_SH_MR_IDX 0 +#define VF_MASK_MR_FSL 0x3 +#define VF_SH_MR_FSL 5 +#define VF_MASK_MR_RXC 0x1 +#define VF_SH_MR_RXC 5 +#define VF_MASK_MR_VFSL 0x1 +#define VF_SH_MR_VFSL 6 + +#define VF_MAX_MR_MTX 7 +#define VF_MAX_MR_IDX 3 +#define VF_MAX_MR_FSL 3 +#define VF_MAX_MR_VIDX 1 +#define VF_MAX_MR_VFSL 1 + +#define VF_MIN_MR 0 +#define VF_MAX_MR 127 +#define VF_MIN_CR 128 +#define VF_MAX_CR 255 +#define VF_MIN_VCR 128 +#define VF_MAX_VCR 143 +#define VF_MIN_CC 0 +#define VF_MAX_CC 15 +#define VF_MIN_CONST 1 +#define VF_MAX_CONST 19 +#define VF_MIN_SCALE 0 +#define VF_MAX_SCALE 31 +#define VF_MIN_BCOND 0 +#define VF_MAX_BCOND 5 +#define VF_MIN_MCOND 0 +#define VF_MAX_MCOND 6 +#define VF_MIN_WRAP 0 +#define VF_MAX_WRAP 255 +#define VF_MIN_ROT 0 +#define VF_MAX_ROT 31 +#define VF_MIN_TSIGN 0 +#define VF_MAX_TSIGN 1 +#define VF_MIN_BMCOND 0 +#define VF_MAX_BMCOND 31 +#define VF_MIN_HFLOAT 0 +#define VF_MAX_HFLOAT 0xffff + +#define VF_MASK_F32_SIGN 0x1 +#define VF_SH_F32_SIGN 31 +#define VF_MASK_F32_EXP 0xff +#define VF_SH_F32_EXP 23 +#define VF_MASK_F32_FRA 0x7fffff +#define VF_SH_F32_FRA 0 +#define VF_MASK_F16_SIGN 0x1 +#define VF_SH_F16_SIGN 15 +#define VF_MASK_F16_EXP 0x1f +#define VF_SH_F16_EXP 10 +#define VF_MASK_F16_FRA 0x3ff +#define VF_SH_F16_FRA 0 + +#define VF_MIN_F32_EXP 0 +#define VF_MAX_F32_EXP 255 +#define VF_BIAS_F32_EXP 127 +#define VF_MIN_F16_EXP 0 +#define VF_MAX_F16_EXP 31 +#define VF_BIAS_F16_EXP 15 + +#define OP_SH_VFPU_DELTA 0 +#define OP_MASK_VFPU_DELTA 0xfffc +#define OP_SH_VFPU_IMM3 16 +#define OP_MASK_VFPU_IMM3 0x7 +#define OP_SH_VFPU_IMM5 16 +#define OP_MASK_VFPU_IMM5 0x1f +#define OP_SH_VFPU_IMM8 16 +#define OP_MASK_VFPU_IMM8 0xff +#define OP_SH_VFPU_CC 18 /* Condition code. */ +#define OP_MASK_VFPU_CC 0x7 +#define OP_SH_VFPU_CONST 16 +#define OP_MASK_VFPU_CONST 0x1f +#define OP_SH_VFPU_COND 0 /* Conditional compare. */ +#define OP_MASK_VFPU_COND 0xf +#define OP_SH_VFPU_VMTVC 0 +#define OP_MASK_VFPU_VMTVC 0xff +#define OP_SH_VFPU_VMFVC 8 +#define OP_MASK_VFPU_VMFVC 0xff +#define OP_SH_VFPU_RWB 1 +#define OP_MASK_VFPU_RWB 0x1 +#define OP_SH_VFPU_ROT 16 /* Rotators used in vrot. */ +#define OP_MASK_VFPU_ROT 0x1f +#define OP_SH_VFPU_FLOAT16 0 +#define OP_MASK_VFPU_FLOAT16 0xffff + +/* VFPU registers. */ +#define OP_SH_VFPU_VD 0 +#define OP_MASK_VFPU_VD 0x7f +#define OP_SH_VFPU_VS 8 +#define OP_MASK_VFPU_VS 0x7f +#define OP_SH_VFPU_VT 16 +#define OP_MASK_VFPU_VT 0x7f +#define OP_SH_VFPU_VT_LO 16 /* Bits 0-4 of vt. */ +#define OP_MASK_VFPU_VT_LO 0x1f +#define OP_SH_VFPU_VT_HI 5 /* Right-shifted. */ +#define OP_MASK_VFPU_VT_HI1 0x1 /* Bit 5 of vt. */ +#define OP_MASK_VFPU_VT_HI2 0x3 /* Bits 5-6 of vt. */ +/* Special handling of vs in vmmul instructions. */ +#define VFPU_OP_VT_VS_VD 0xff800000 +#define VFPU_OPCODE_VMMUL 0xf0000000 + +/* VFPU condition codes. FL and TR accept no arguments, while any conditions + above and including EZ only accept one argument. The rest require two + arguments. */ +enum +{ + VFPU_COND_FL, VFPU_COND_EQ, VFPU_COND_LT, VFPU_COND_LE, + VFPU_COND_TR, VFPU_COND_NE, VFPU_COND_GE, VFPU_COND_GT, + VFPU_COND_EZ, VFPU_COND_EN, VFPU_COND_EI, VFPU_COND_ES, + VFPU_COND_NZ, VFPU_COND_NN, VFPU_COND_NI, VFPU_COND_NS, + VFPU_NUM_CONDS +}; + +/* VFPU prefix instruction operands. The *_SH_* values really specify where + the bitfield begins, as VFPU prefix instructions have four operands + encoded within the immediate field. */ +#define VFPU_SH_PFX_NEG 16 +#define VFPU_MASK_PFX_NEG 0x1 /* Negation. */ +#define VFPU_SH_PFX_CST 12 +#define VFPU_MASK_PFX_CST 0x1 /* Constant. */ +#define VFPU_SH_PFX_ABS_CSTHI 8 +#define VFPU_MASK_PFX_ABS_CSTHI 0x1 /* Abs/Constant (bit 2). */ +#define VFPU_SH_PFX_SWZ_CSTLO 0 +#define VFPU_MASK_PFX_SWZ_CSTLO 0x3 /* Swizzle/Constant (bits 0-1). */ +#define VFPU_SH_PFX_MASK 8 +#define VFPU_MASK_PFX_MASK 0x1 /* Mask. */ +#define VFPU_SH_PFX_SAT 0 +#define VFPU_MASK_PFX_SAT 0x3 /* Saturation. */ + +/* Special handling of the vrot instructions. */ +#define VFPU_MASK_OP_SIZE 0x8080 /* Masks the operand size (pair, triple, quad). */ +#define VFPU_OP_SIZE_PAIR 0x80 +#define VFPU_OP_SIZE_TRIPLE 0x8000 +#define VFPU_OP_SIZE_QUAD 0x8080 +/* Note that these are within the rotators field, and not the full opcode. */ +#define VFPU_SH_ROT_HI 2 +#define VFPU_MASK_ROT_HI 0x3 +#define VFPU_SH_ROT_LO 0 +#define VFPU_MASK_ROT_LO 0x3 +#define VFPU_SH_ROT_NEG 4 /* Negation. */ +#define VFPU_MASK_ROT_NEG 0x1 + +/* VFPU 16-bit floating-point format. */ +#define VFPU_FLOAT16_EXP_MAX 0x1f +#define VFPU_SH_FLOAT16_SIGN 15 +#define VFPU_MASK_FLOAT16_SIGN 0x1 +#define VFPU_SH_FLOAT16_EXP 10 +#define VFPU_MASK_FLOAT16_EXP 0x1f +#define VFPU_SH_FLOAT16_FRAC 0 +#define VFPU_MASK_FLOAT16_FRAC 0x3ff + /* UDI */ #define OP_SH_UDI1 6 #define OP_MASK_UDI1 0x1f @@ -416,6 +638,29 @@ Requires that "+A" or "+E" occur first to set position. Enforces: 32 < (pos+size) <= 64. + Sony Allegrex VFPU instructions: + "?o" + "?0" - "?3" + "?4" - "?7" + "?a" + "?b" + "?c" + "?e" + "?f" + "?i" + "?q" + "?r" + "?u" + "?w" + "?d" + "?m" + "?n" + "?s" + "?t" + "?v" + "?x" + "?z" + Floating point instructions: "D" 5 bit destination register (OP_*_FD) "M" 3 bit compare condition code (OP_*_CCC) (only used for mips4 and up) @@ -750,6 +995,8 @@ #define INSN_5400 0x01000000 /* NEC VR5500 instruction. */ #define INSN_5500 0x02000000 +/* Sony Allegrex instruction. */ +#define INSN_ALLEGREX 0x10000000 /* MDMX ASE */ #define INSN_MDMX 0x04000000 @@ -819,6 +1066,7 @@ #define CPU_MIPS64 64 #define CPU_MIPS64R2 65 #define CPU_SB1 12310201 /* octal 'SB', 01. */ +#define CPU_ALLEGREX 10111431 /* octal 'AL', 31. */ #define CPU_LOONGSON_2E 3001 #define CPU_LOONGSON_2F 3002 #define CPU_LOONGSON_3A 3003 @@ -851,6 +1099,7 @@ || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0) \ || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0) \ || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0) \ + || (cpu == CPU_ALLEGREX && ((insn)->membership & INSN_ALLEGREX) != 0) \ || (cpu == CPU_LOONGSON_2E \ && ((insn)->membership & INSN_LOONGSON_2E) != 0) \ || (cpu == CPU_LOONGSON_2F \ @@ -1005,11 +1254,27 @@ M_LI_DD, M_LI_S, M_LI_SS, + M_LVHI_S_SS, + M_LVHI_P_SS, + M_LVI_S_SS, + M_LVI_P_SS, + M_LVI_T_SS, + M_LVI_Q_SS, M_LL_AB, M_LL_OB, M_LLD_AB, M_LLD_OB, M_LS_A, + M_LVHI_P, + M_LVHI_S, + M_LVI_P, + M_LVI_Q, + M_LVI_S, + M_LVI_T, + M_LVL_Q_AB, + M_LVR_Q_AB, + M_LV_Q_AB, + M_LV_Q_AB_2, M_LW_A, M_LW_AB, M_LWC0_A, @@ -1021,6 +1286,7 @@ M_LWC2_OB, M_LWC3_A, M_LWC3_AB, + M_LV_S_AB, M_LWL_A, M_LWL_AB, M_LWL_OB, @@ -1130,6 +1396,10 @@ M_SUB_I, M_SUBU_I, M_SUBU_I_2, + M_SVL_Q_AB, + M_SV_Q_AB, + M_SVR_Q_AB, + M_SV_S_AB, M_TEQ_I, M_TGE_I, M_TGEU_I, @@ -1144,14 +1414,24 @@ M_ULH_A, M_ULHU, M_ULHU_A, + M_ULV_Q, + M_ULV_Q_AB, + M_ULV_S, M_ULW, M_ULW_A, M_USH, M_USH_A, + M_USV_Q, + M_USV_Q_AB, + M_USV_S, M_USW, M_USW_A, M_USD, M_USD_A, + M_VCMOV_P, + M_VCMOV_Q, + M_VCMOV_S, + M_VCMOV_T, M_XOR_I, M_COP0, M_COP1, diff -burN orig.binutils-2.22/include/opcode/vfpu.h binutils-2.22/include/opcode/vfpu.h --- orig.binutils-2.22/include/opcode/vfpu.h 1970-01-01 01:00:00.000000000 +0100 +++ binutils-2.22/include/opcode/vfpu.h 2012-01-04 16:18:36.338214659 +0100 @@ -0,0 +1,261 @@ +#ifndef _VFPU_H_ +#define _VFPU_H_ + +//////////////////////////////////// +// data type +#define VFPU_MASK_DTYPE 0x8080 +#define VFPU_QUAD 0x8080 +#define VFPU_TRIPLE 0x8000 +#define VFPU_PAIR 0x0080 +#define VFPU_SINGLE 0x0000 + +//////////////////////////////////// +// register index +#define VFPU_MASK_VT 0x7f0000 +#define VFPU_MASK_VS 0x007f00 +#define VFPU_MASK_VD 0x00007f + +//////////////////////////////////// +// condition and comapre inst +#define VFPU_PADD_BIN_CMP 0x70 + +//////////////////////////////////// +// load/store left/right +#define VFPU_MASK_LDST_LR 0x2 +#define VFPU_LDST_L 0x0 +#define VFPU_LDST_R 0x2 + +//////////////////////////////////// +// load/store memory/buffer +#define VFPU_MASK_LDST_MB 0x2 +#define VFPU_LDST_M 0x0 +#define VFPU_LDST_B 0x2 + +//////////////////////////////////// +// coprocessor move +#define VFPU_MASK_COP_MV 0xff80 +#define VFPU_MASK_COP_MVC 0xff00 + +//////////////////////////////////// +// sync code +#define VFPU_MASK_SYNC_CODE 0xffff +#define VFPU_SYNC_CODE_DEFAULT 0x0320 +#define VFPU_SYNC_CODE_NOP 0x0000 +#define VFPU_SYNC_CODE_FLUSH 0x040d + +//////////////////////////////////// +#define VFPU_INST_BR_F 0x49000000 +#define VFPU_MASK_BR_F 0xffe30000 +#define VFPU_INST_BR_FL 0x49020000 +#define VFPU_MASK_BR_FL 0xffe30000 +#define VFPU_INST_BR_T 0x49010000 +#define VFPU_MASK_BR_T 0xffe30000 +#define VFPU_INST_BR_TL 0x49030000 +#define VFPU_MASK_BR_TL 0xffe30000 + +#define VFPU_INST_COP_LD_S 0xc8000000 +#define VFPU_MASK_COP_LD_S 0xfc000000 +#define VFPU_INST_COP_ST_S 0xe8000000 +#define VFPU_MASK_COP_ST_S 0xfc000000 +#define VFPU_INST_COP_LD_Q 0xd8000000 +#define VFPU_MASK_COP_LD_Q 0xfc000000 +#define VFPU_INST_COP_ST_Q 0xf8000000 +#define VFPU_MASK_COP_ST_Q 0xfc000000 +#define VFPU_INST_COP_LD_U 0xd4000000 +#define VFPU_MASK_COP_LD_U 0xfc000000 +#define VFPU_INST_COP_ST_U 0xf4000000 +#define VFPU_MASK_COP_ST_U 0xfc000000 +#define VFPU_INST_COP_MF 0x48600000 +#define VFPU_MASK_COP_MF 0xffe00000 +#define VFPU_INST_COP_MT 0x48e00000 +#define VFPU_MASK_COP_MT 0xffe00000 + +#define VFPU_INST_BIN_ADD 0x60000000 +#define VFPU_MASK_BIN_ADD 0xff800000 +#define VFPU_INST_BIN_SUB 0x60800000 +#define VFPU_MASK_BIN_SUB 0xff800000 +#define VFPU_INST_BIN_SBN 0x61000000 +#define VFPU_MASK_BIN_SBN 0xff800000 +#define VFPU_INST_BIN_DIV 0x63800000 +#define VFPU_MASK_BIN_DIV 0xff800000 +#define VFPU_INST_BIN_MUL 0x64000000 +#define VFPU_MASK_BIN_MUL 0xff800000 +#define VFPU_INST_BIN_DOT 0x64800000 +#define VFPU_MASK_BIN_DOT 0xff800000 +#define VFPU_INST_BIN_SCL 0x65000000 +#define VFPU_MASK_BIN_SCL 0xff800000 +#define VFPU_INST_BIN_HDP 0x66000000 +#define VFPU_MASK_BIN_HDP 0xff800000 +#define VFPU_INST_BIN_CRS 0x66800000 +#define VFPU_MASK_BIN_CRS 0xff800000 +#define VFPU_INST_BIN_DET 0x67000000 +#define VFPU_MASK_BIN_DET 0xff800000 +#define VFPU_INST_BIN_CMP 0x6c000000 +#define VFPU_MASK_BIN_CMP 0xff800000 +#define VFPU_INST_BIN_MIN 0x6d000000 +#define VFPU_MASK_BIN_MIN 0xff800000 +#define VFPU_INST_BIN_MAX 0x6d800000 +#define VFPU_MASK_BIN_MAX 0xff800000 +#define VFPU_INST_BIN_SCMP 0x6e800000 +#define VFPU_MASK_BIN_SCMP 0xff800000 +#define VFPU_INST_BIN_SGE 0x6f000000 +#define VFPU_MASK_BIN_SGE 0xff800000 +#define VFPU_INST_BIN_SLT 0x6f800000 +#define VFPU_MASK_BIN_SLT 0xff800000 + +#define VFPU_INST_UNR_MOV 0xd0000000 +#define VFPU_MASK_UNR_MOV 0xffff0000 +#define VFPU_INST_UNR_ABS 0xd0010000 +#define VFPU_MASK_UNR_ABS 0xffff0000 +#define VFPU_INST_UNR_NEG 0xd0020000 +#define VFPU_MASK_UNR_NEG 0xffff0000 +#define VFPU_INST_UNR_IDT 0xd0030000 +#define VFPU_MASK_UNR_IDT 0xffff0000 +#define VFPU_INST_UNR_SAT0 0xd0040000 +#define VFPU_MASK_UNR_SAT0 0xffff0000 +#define VFPU_INST_UNR_SAT1 0xd0050000 +#define VFPU_MASK_UNR_SAT1 0xffff0000 +#define VFPU_INST_UNR_ZERO 0xd0060000 +#define VFPU_MASK_UNR_ZERO 0xffff0000 +#define VFPU_INST_UNR_ONE 0xd0070000 +#define VFPU_MASK_UNR_ONE 0xffff0000 +#define VFPU_INST_UNR_RCP 0xd0100000 +#define VFPU_MASK_UNR_RCP 0xffff0000 +#define VFPU_INST_UNR_RSQ 0xd0110000 +#define VFPU_MASK_UNR_RSQ 0xffff0000 +#define VFPU_INST_UNR_SIN 0xd0120000 +#define VFPU_MASK_UNR_SIN 0xffff0000 +#define VFPU_INST_UNR_COS 0xd0130000 +#define VFPU_MASK_UNR_COS 0xffff0000 +#define VFPU_INST_UNR_EXP2 0xd0140000 +#define VFPU_MASK_UNR_EXP2 0xffff0000 +#define VFPU_INST_UNR_LOG2 0xd0150000 +#define VFPU_MASK_UNR_LOG2 0xffff0000 +#define VFPU_INST_UNR_SQR 0xd0160000 +#define VFPU_MASK_UNR_SQR 0xffff0000 +#define VFPU_INST_UNR_ASIN 0xd0170000 +#define VFPU_MASK_UNR_ASIN 0xffff0000 +#define VFPU_INST_UNR_NRCP 0xd0180000 +#define VFPU_MASK_UNR_NRCP 0xffff0000 +#define VFPU_INST_UNR_NSIN 0xd01a0000 +#define VFPU_MASK_UNR_NSIN 0xffff0000 +#define VFPU_INST_UNR_REXP2 0xd01c0000 +#define VFPU_MASK_UNR_REXP2 0xffff0000 +#define VFPU_INST_UNR_RNDS 0xd0200000 +#define VFPU_MASK_UNR_RNDS 0xffff0000 +#define VFPU_INST_UNR_RNDI 0xd0210000 +#define VFPU_MASK_UNR_RNDI 0xffff0000 +#define VFPU_INST_UNR_RNDF1 0xd0220000 +#define VFPU_MASK_UNR_RNDF1 0xffff0000 +#define VFPU_INST_UNR_RNDF2 0xd0230000 +#define VFPU_MASK_UNR_RNDF2 0xffff0000 +#define VFPU_INST_UNR_F2H 0xd0320000 +#define VFPU_MASK_UNR_F2H 0xffff0000 +#define VFPU_INST_UNR_H2F 0xd0330000 +#define VFPU_MASK_UNR_H2F 0xffff0000 +#define VFPU_INST_UNR_SBZ 0xd0360000 +#define VFPU_MASK_UNR_SBZ 0xffff0000 +#define VFPU_INST_UNR_LGB 0xd0370000 +#define VFPU_MASK_UNR_LGB 0xffff0000 +#define VFPU_INST_UNR_US2I 0xd03a0000 +#define VFPU_MASK_UNR_US2I 0xffff0000 +#define VFPU_INST_UNR_S2I 0xd03b0000 +#define VFPU_MASK_UNR_S2I 0xffff0000 +#define VFPU_INST_UNR_I2UC 0xd03c0000 +#define VFPU_MASK_UNR_I2UC 0xffff0000 +#define VFPU_INST_UNR_I2C 0xd03d0000 +#define VFPU_MASK_UNR_I2C 0xffff0000 +#define VFPU_INST_UNR_I2US 0xd03e0000 +#define VFPU_MASK_UNR_I2US 0xffff0000 +#define VFPU_INST_UNR_I2S 0xd03f0000 +#define VFPU_MASK_UNR_I2S 0xffff0000 +#define VFPU_INST_UNR_SRT1 0xd0400000 +#define VFPU_MASK_UNR_SRT1 0xffff0000 +#define VFPU_INST_UNR_SRT2 0xd0410000 +#define VFPU_MASK_UNR_SRT2 0xffff0000 +#define VFPU_INST_UNR_BFY1 0xd0420000 +#define VFPU_MASK_UNR_BFY1 0xffff0000 +#define VFPU_INST_UNR_BFY2 0xd0430000 +#define VFPU_MASK_UNR_BFY2 0xffff0000 +#define VFPU_INST_UNR_OCP 0xd0440000 +#define VFPU_MASK_UNR_OCP 0xffff0000 +#define VFPU_INST_UNR_SOCP 0xd0450000 +#define VFPU_MASK_UNR_SOCP 0xffff0000 +#define VFPU_INST_UNR_FAD 0xd0460000 +#define VFPU_MASK_UNR_FAD 0xffff0000 +#define VFPU_INST_UNR_AVG 0xd0470000 +#define VFPU_MASK_UNR_AVG 0xffff0000 +#define VFPU_INST_UNR_SRT3 0xd0480000 +#define VFPU_MASK_UNR_SRT3 0xffff0000 +#define VFPU_INST_UNR_SRT4 0xd0490000 +#define VFPU_MASK_UNR_SRT4 0xffff0000 +#define VFPU_INST_UNR_SGN 0xd04a0000 +#define VFPU_MASK_UNR_SGN 0xffff0000 +#define VFPU_INST_UNR_CF 0xd0500000 +#define VFPU_MASK_UNR_CF 0xffff0080 +#define VFPU_INST_UNR_CT 0xd0510000 +#define VFPU_MASK_UNR_CT 0xffff8000 +#define VFPU_INST_UNR_T4444 0xd0590000 +#define VFPU_MASK_UNR_T4444 0xffff0000 +#define VFPU_INST_UNR_T5551 0xd05a0000 +#define VFPU_MASK_UNR_T5551 0xffff0000 +#define VFPU_INST_UNR_T5650 0xd05b0000 +#define VFPU_MASK_UNR_T5650 0xffff0000 +#define VFPU_INST_UNR_CST 0xd0600000 +#define VFPU_MASK_UNR_CST 0xffe00000 + +#define VFPU_INST_UNRI_F2I_N 0xd2000000 +#define VFPU_MASK_UNRI_F2I_N 0xffe00000 +#define VFPU_INST_UNRI_F2I_Z 0xd2200000 +#define VFPU_MASK_UNRI_F2I_Z 0xffe00000 +#define VFPU_INST_UNRI_F2I_U 0xd2400000 +#define VFPU_MASK_UNRI_F2I_U 0xffe00000 +#define VFPU_INST_UNRI_F2I_D 0xd2600000 +#define VFPU_MASK_UNRI_F2I_D 0xffe00000 +#define VFPU_INST_UNRI_I2F 0xd2800000 +#define VFPU_MASK_UNRI_I2F 0xffe00000 +#define VFPU_INST_UNRI_CMOV_T 0xd2a00000 +#define VFPU_MASK_UNRI_CMOV_T 0xfff80000 +#define VFPU_INST_UNRI_CMOV_F 0xd2a80000 +#define VFPU_MASK_UNRI_CMOV_F 0xfff80000 +#define VFPU_INST_UNRI_WBN 0xd3000000 +#define VFPU_MASK_UNRI_WBN 0xff000000 + +#define VFPU_INST_PFX_RA 0xdc000000 +#define VFPU_MASK_PFX_RA 0xff000000 +#define VFPU_INST_PFX_RB 0xdd000000 +#define VFPU_MASK_PFX_RB 0xff000000 +#define VFPU_INST_PFX_W 0xde000000 +#define VFPU_MASK_PFX_W 0xff000000 +#define VFPU_INST_IIM 0xdf000000 +#define VFPU_MASK_IIM 0xff800000 +#define VFPU_INST_FIM 0xdf800000 +#define VFPU_MASK_FIM 0xff800000 + +#define VFPU_INST_RPT_MMUL 0xf0000000 +#define VFPU_MASK_RPT_MMUL 0xff800000 +#define VFPU_INST_RPT_TFM2 0xf0800000 +#define VFPU_MASK_RPT_TFM2 0xff800000 +#define VFPU_INST_RPT_TFM3 0xf1000000 +#define VFPU_MASK_RPT_TFM3 0xff800000 +#define VFPU_INST_RPT_TFM4 0xf1800000 +#define VFPU_MASK_RPT_TFM4 0xff800000 +#define VFPU_INST_RPT_MSCL 0xf2000000 +#define VFPU_MASK_RPT_MSCL 0xff800000 +#define VFPU_INST_RPT_QMUL 0xf2800000 +#define VFPU_MASK_RPT_QMUL 0xff800000 +#define VFPU_INST_RPT_MMOV 0xf3800000 +#define VFPU_MASK_RPT_MMOV 0xffff0000 +#define VFPU_INST_RPT_MIDT 0xf3830000 +#define VFPU_MASK_RPT_MIDT 0xffff0000 +#define VFPU_INST_RPT_MZERO 0xf3860000 +#define VFPU_MASK_RPT_MZERO 0xffff0000 +#define VFPU_INST_RPT_MONE 0xf3870000 +#define VFPU_MASK_RPT_MONE 0xffff0000 +#define VFPU_INST_RPT_ROT 0xf3a00000 +#define VFPU_MASK_RPT_ROT 0xffe00000 + +#define VFPU_INST_SYNC 0xffff0000 +#define VFPU_MASK_SYNC 0xffff0000 + +#endif /* _VFPU_H_ */ diff -burN orig.binutils-2.22/ld/configure.tgt binutils-2.22/ld/configure.tgt --- orig.binutils-2.22/ld/configure.tgt 2011-11-21 10:29:37.000000000 +0100 +++ binutils-2.22/ld/configure.tgt 2012-01-04 16:18:36.578211917 +0100 @@ -383,6 +383,8 @@ mips*vr4100-*-elf*) targ_emul=elf32b4300 ;; mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;; mips*vr5000-*-elf*) targ_emul=elf32b4300 ;; +mips*allegrexel-psp-elf*) targ_emul=elf_mipsallegrexel_psp + targ_extra_emuls="elf32elmip" ;; mips*el-sde-elf*) targ_emul=elf32ltsmip targ_extra_emuls="elf32btsmip elf32ltsmipn32 elf64ltsmip elf32btsmipn32 elf64btsmip" ;; mips*-sde-elf*) targ_emul=elf32btsmip diff -burN orig.binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh --- orig.binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh 1970-01-01 01:00:00.000000000 +0100 +++ binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh 2012-01-04 16:18:36.368214315 +0100 @@ -0,0 +1,22 @@ +# Based off of the default elf32 MIPS target. However, we use a seperate +# script template because the PSP architecture defines sections that normally +# cannot be overriden here and would normally get absorbed (i.e. +# .rodata.sceModuleInfo would be absorbed into .rodata). + +EMBEDDED=yes +. ${srcdir}/emulparams/elf32lmip.sh +unset NONPAGED_TEXT_START_ADDR +unset SHLIB_TEXT_START_ADDR +unset COMMONPAGESIZE + +SCRIPT_NAME=elf_psp +TEXT_START_ADDR=0x08900000 +MAXPAGESIZE=256 +ARCH="mips:allegrex" +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +DYNAMIC_LINK=FALSE + +# Discard the .comment and .pdr sections. +OTHER_SECTIONS="/DISCARD/ : { *(.comment) *(.pdr) }" diff -burN orig.binutils-2.22/ld/Makefile.am binutils-2.22/ld/Makefile.am --- orig.binutils-2.22/ld/Makefile.am 2011-07-22 22:22:37.000000000 +0200 +++ binutils-2.22/ld/Makefile.am 2012-01-04 17:02:20.728460268 +0100 @@ -262,6 +262,7 @@ eelf_i386_ldso.c \ eelf_i386_sol2.c \ eelf_i386_vxworks.c \ + eelf_mipsallegrexel_psp.o \ eelf_s390.c \ egld960.c \ egld960coff.c \ @@ -1196,6 +1197,9 @@ $(srcdir)/emulparams/vxworks.sh $(srcdir)/emultempl/vxworks.em \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf_i386_vxworks "$(tdir_elf_i386_vxworks)" +eelf_mipsallegrexel_psp.c: $(srcdir)/emulparams/elf_mipsallegrexel_psp.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf_psp.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_mipsallegrexel_psp "$(tdir_elf_mipsallegrexel_psp)" eelf_s390.c: $(srcdir)/emulparams/elf_s390.sh \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf_s390 "$(tdir_elf_s390)" diff -burN orig.binutils-2.22/ld/Makefile.in binutils-2.22/ld/Makefile.in --- orig.binutils-2.22/ld/Makefile.in 2011-07-22 22:22:37.000000000 +0200 +++ binutils-2.22/ld/Makefile.in 2012-01-04 17:02:25.531403806 +0100 @@ -568,6 +568,7 @@ eelf_i386_ldso.c \ eelf_i386_sol2.c \ eelf_i386_vxworks.c \ + eelf_mipsallegrexel_psp.o \ eelf_s390.c \ egld960.c \ egld960coff.c \ @@ -2649,6 +2650,9 @@ $(srcdir)/emulparams/vxworks.sh $(srcdir)/emultempl/vxworks.em \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf_i386_vxworks "$(tdir_elf_i386_vxworks)" +eelf_mipsallegrexel_psp.c: $(srcdir)/emulparams/elf_mipsallegrexel_psp.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf_psp.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_mipsallegrexel_psp "$(tdir_elf_mipsallegrexel_psp)" eelf_s390.c: $(srcdir)/emulparams/elf_s390.sh \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf_s390 "$(tdir_elf_s390)" diff -burN orig.binutils-2.22/ld/scripttempl/elf_psp.sc binutils-2.22/ld/scripttempl/elf_psp.sc --- orig.binutils-2.22/ld/scripttempl/elf_psp.sc 1970-01-01 01:00:00.000000000 +0100 +++ binutils-2.22/ld/scripttempl/elf_psp.sc 2012-01-04 16:18:36.380214179 +0100 @@ -0,0 +1,496 @@ +# +# Unusual variables checked by this code: +# NOP - four byte opcode for no-op (defaults to 0) +# NO_SMALL_DATA - no .sbss/.sbss2/.sdata/.sdata2 sections if not +# empty. +# SMALL_DATA_CTOR - .ctors contains small data. +# SMALL_DATA_DTOR - .dtors contains small data. +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# INITIAL_READONLY_SECTIONS - at start of text segment +# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... +# (e.g., .PARISC.milli) +# OTHER_TEXT_SECTIONS - these get put in .text when relocating +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_RELRO_SECTIONS - other than .data.rel.ro ... +# (e.g. PPC32 .fixup, .got[12]) +# OTHER_BSS_SECTIONS - other than .bss .sbss ... +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_ADDR - the first byte of the text segment, after any +# headers. +# TEXT_BASE_ADDRESS - the first byte of the text segment. +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_GOT_SYMBOLS - symbols defined just before .got. +# OTHER_GOT_SECTIONS - sections just after .got. +# OTHER_SDATA_SECTIONS - sections just after .sdata. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# DATA_PLT - .plt should be in data segment, not text segment. +# PLT_BEFORE_GOT - .plt just before .got when .plt is in data segement. +# BSS_PLT - .plt should be in bss segment +# TEXT_DYNAMIC - .dynamic in text segment, not data segment. +# EMBEDDED - whether this is for an embedded system. +# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set +# start address of shared library. +# INPUT_FILES - INPUT command of files to always include +# WRITABLE_RODATA - if set, the .rodata section should be writable +# INIT_START, INIT_END - statements just before and just after +# combination of .init sections. +# FINI_START, FINI_END - statements just before and just after +# combination of .fini sections. +# STACK_ADDR - start of a .stack section. +# OTHER_END_SYMBOLS - symbols to place right at the end of the script. +# SEPARATE_GOTPLT - if set, .got.plt should be separate output section, +# so that .got can be in the RELRO area. It should be set to +# the number of bytes in the beginning of .got.plt which can be +# in the RELRO area as well. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# + +# Many sections come in three flavours. There is the 'real' section, +# like ".data". Then there are the per-procedure or per-variable +# sections, generated by -ffunction-sections and -fdata-sections in GCC, +# and useful for --gc-sections, which for a variable "foo" might be +# ".data.foo". Then there are the linkonce sections, for which the linker +# eliminates duplicates, which are named like ".gnu.linkonce.d.foo". +# The exact correspondences are: +# +# Section Linkonce section +# .text .gnu.linkonce.t.foo +# .rodata .gnu.linkonce.r.foo +# .data .gnu.linkonce.d.foo +# .bss .gnu.linkonce.b.foo +# .sdata .gnu.linkonce.s.foo +# .sbss .gnu.linkonce.sb.foo +# .sdata2 .gnu.linkonce.s2.foo +# .sbss2 .gnu.linkonce.sb2.foo +# .debug_info .gnu.linkonce.wi.foo +# .tdata .gnu.linkonce.td.foo +# .tbss .gnu.linkonce.tb.foo +# +# Each of these can also have corresponding .rel.* and .rela.* sections. + +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test -z "${ELFSIZE}" && ELFSIZE=32 +test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8" +test "$LD_FLAG" = "N" && DATA_ADDR=. +test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE="" +test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE="" +test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT +DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))" +DATA_SEGMENT_RELRO_END="" +DATA_SEGMENT_RELRO_GOTPLT_END="" +DATA_SEGMENT_END="" +if test -n "${COMMONPAGESIZE}"; then + DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})" + DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);" + if test -n "${SEPARATE_GOTPLT}"; then + DATA_SEGMENT_RELRO_GOTPLT_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT}, .);" + else + DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (0, .);" + fi +fi +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" +if test -z "$GOT"; then + if test -z "$SEPARATE_GOTPLT"; then + GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" + else + GOT=".got ${RELOCATING-0} : { *(.got) }" + GOTPLT="${RELOCATING+${DATA_SEGMENT_RELRO_GOTPLT_END}} + .got.plt ${RELOCATING-0} : { *(.got.plt) }" + fi +fi +DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" +RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" +DATARELRO=".data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }" +STACKNOTE="/DISCARD/ : { *(.note.GNU-stack) }" +if test -z "${NO_SMALL_DATA}"; then + SBSS=".sbss ${RELOCATING-0} : + { + ${RELOCATING+PROVIDE (__sbss_start = .);} + ${RELOCATING+PROVIDE (___sbss_start = .);} + ${CREATE_SHLIB+*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)} + *(.dynsbss) + *(.sbss${RELOCATING+ .sbss.* .gnu.linkonce.sb.*}) + *(.scommon) + ${RELOCATING+PROVIDE (__sbss_end = .);} + ${RELOCATING+PROVIDE (___sbss_end = .);} + }" + SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2${RELOCATING+ .sbss2.* .gnu.linkonce.sb2.*}) }" + SDATA="/* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : + { + ${RELOCATING+${SDATA_START_SYMBOLS}} + ${CREATE_SHLIB+*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)} + *(.sdata${RELOCATING+ .sdata.* .gnu.linkonce.s.*}) + }" + SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2${RELOCATING+ .sdata2.* .gnu.linkonce.s2.*}) }" + REL_SDATA=".rel.sdata ${RELOCATING-0} : { *(.rel.sdata${RELOCATING+ .rel.sdata.* .rel.gnu.linkonce.s.*}) } + .rela.sdata ${RELOCATING-0} : { *(.rela.sdata${RELOCATING+ .rela.sdata.* .rela.gnu.linkonce.s.*}) }" + REL_SBSS=".rel.sbss ${RELOCATING-0} : { *(.rel.sbss${RELOCATING+ .rel.sbss.* .rel.gnu.linkonce.sb.*}) } + .rela.sbss ${RELOCATING-0} : { *(.rela.sbss${RELOCATING+ .rela.sbss.* .rela.gnu.linkonce.sb.*}) }" + REL_SDATA2=".rel.sdata2 ${RELOCATING-0} : { *(.rel.sdata2${RELOCATING+ .rel.sdata2.* .rel.gnu.linkonce.s2.*}) } + .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2${RELOCATING+ .rela.sdata2.* .rela.gnu.linkonce.s2.*}) }" + REL_SBSS2=".rel.sbss2 ${RELOCATING-0} : { *(.rel.sbss2${RELOCATING+ .rel.sbss2.* .rel.gnu.linkonce.sb2.*}) } + .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2${RELOCATING+ .rela.sbss2.* .rela.gnu.linkonce.sb2.*}) }" +else + NO_SMALL_DATA=" " +fi +test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" " +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${CTOR_START}} + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin*.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend*.o $OTHER_EXCLUDE_FILES) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ${CONSTRUCTING+${CTOR_END}} + }" +DTOR=".dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${DTOR_START}} + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o $OTHER_EXCLUDE_FILES) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ${CONSTRUCTING+${DTOR_END}} + }" +STACK=" .stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} : + { + ${RELOCATING+_stack = .;} + *(.stack) + }" + +# if this is for an embedded system, don't add SIZEOF_HEADERS. +if [ -z "$EMBEDDED" ]; then + test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS" +else + test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}" +fi + +cat <> OP_SH_FT) & OP_MASK_FT); break; + case '?': + /* VFPU extensions. */ + d++; + switch (*d) + { + case '\0': + /* xgettext:c-format */ + (*info->fprintf_func) (info->stream, + _("# internal error, incomplete VFPU extension sequence (?)")); + return; + + case 'o': + delta = (l >> OP_SH_VFPU_DELTA) & OP_MASK_VFPU_DELTA; + if (delta & 0x8000) + delta |= ~0xffff; + (*info->fprintf_func) (info->stream, "%d", + delta); + break; + + case '0': + case '1': + case '2': + case '3': + { + unsigned int pos = *d, base = '0'; + unsigned int negation = (l >> (pos - (base - VFPU_SH_PFX_NEG))) & VFPU_MASK_PFX_NEG; + unsigned int constant = (l >> (pos - (base - VFPU_SH_PFX_CST))) & VFPU_MASK_PFX_CST; + unsigned int abs_consthi = + (l >> (pos - (base - VFPU_SH_PFX_ABS_CSTHI))) & VFPU_MASK_PFX_ABS_CSTHI; + unsigned int swz_constlo = (l >> ((pos - base) * 2)) & VFPU_MASK_PFX_SWZ_CSTLO; + + if (negation) + (*info->fprintf_func) (info->stream, "-"); + if (constant) + { + (*info->fprintf_func) (info->stream, "%s", + pfx_cst_names[(abs_consthi << 2) | swz_constlo]); + } + else + { + if (abs_consthi) + (*info->fprintf_func) (info->stream, "|%s|", + pfx_swz_names[swz_constlo]); + else + (*info->fprintf_func) (info->stream, "%s", + pfx_swz_names[swz_constlo]); + } + } + break; + + case '4': + case '5': + case '6': + case '7': + { + unsigned int pos = *d, base = '4'; + unsigned int mask = (l >> (pos - (base - VFPU_SH_PFX_MASK))) & VFPU_MASK_PFX_MASK; + unsigned int saturation = (l >> ((pos - base) * 2)) & VFPU_MASK_PFX_SAT; + + if (mask) + (*info->fprintf_func) (info->stream, "m"); + else + (*info->fprintf_func) (info->stream, "%s", + pfx_sat_names[saturation]); + } + break; + + case 'a': + { + unsigned int c = (l >> OP_SH_VFPU_CONST) & OP_MASK_VFPU_CONST; + if (c < vfpu_num_constants) + { + (*info->fprintf_func) (info->stream, "%s", + vfpu_const_names[c]); + } + break; + } + + case 'b': + /* 5-bit immediate value. */ + (*info->fprintf_func) (info->stream, "%d", + (l >> OP_SH_VFPU_IMM5) & OP_MASK_VFPU_IMM5); + break; + + case 'c': + /* VFPU condition code. */ + (*info->fprintf_func) (info->stream, "%d", + (l >> OP_SH_VFPU_CC) & OP_MASK_VFPU_CC); + break; + + case 'e': + /* 3-bit immediate value. */ + (*info->fprintf_func) (info->stream, "%d", + (l >> OP_SH_VFPU_IMM3) & OP_MASK_VFPU_IMM3); + break; + + case 'f': + /* Conditional compare. */ + (*info->fprintf_func) (info->stream, "%s", + vfpu_cond_names[(l >> OP_SH_VFPU_COND) & OP_MASK_VFPU_COND]); + /* Apparently this specifier is unused. */ + d++; + break; + + case 'i': + /* 8-bit immediate value. */ + (*info->fprintf_func) (info->stream, "0x%02x", + (l >> OP_SH_VFPU_IMM8) & OP_MASK_VFPU_IMM8); + break; + + case 'q': + /* VFPU control register (vmtvc). */ + (*info->fprintf_func) (info->stream, "$%d", + (l >> OP_SH_VFPU_VMTVC) & OP_MASK_VFPU_VMTVC); + break; + + case 'r': + /* VFPU control register (vmfvc). */ + (*info->fprintf_func) (info->stream, "$%d", + (l >> OP_SH_VFPU_VMFVC) & OP_MASK_VFPU_VMFVC); + break; + + case 'u': + /* Convert a VFPU 16-bit floating-point number to IEEE754. */ + { + union float2int { + unsigned int i; + float f; + } float2int; + unsigned short float16 = (l >> OP_SH_VFPU_FLOAT16) & OP_MASK_VFPU_FLOAT16; + unsigned int sign = (float16 >> VFPU_SH_FLOAT16_SIGN) & VFPU_MASK_FLOAT16_SIGN; + int exponent = (float16 >> VFPU_SH_FLOAT16_EXP) & VFPU_MASK_FLOAT16_EXP; + unsigned int fraction = float16 & VFPU_MASK_FLOAT16_FRAC; + char signchar = '+' + ((sign == 1) * 2); + + if (exponent == VFPU_FLOAT16_EXP_MAX) + { + if (fraction == 0) + (*info->fprintf_func) (info->stream, "%cInf", signchar); + else + (*info->fprintf_func) (info->stream, "%cNaN", signchar); + } + else if (exponent == 0 && fraction == 0) + { + (*info->fprintf_func) (info->stream, "%c0", signchar); + } + else + { + if (exponent == 0) + { + do + { + fraction <<= 1; + exponent--; + } + while (!(fraction & (VFPU_MASK_FLOAT16_FRAC + 1))); + + fraction &= VFPU_MASK_FLOAT16_FRAC; + } + + /* Convert to 32-bit single-precision IEEE754. */ + float2int.i = sign << 31; + float2int.i |= (exponent + 112) << 23; + float2int.i |= fraction << 13; + (*info->fprintf_func) (info->stream, "%g", float2int.f); + } + } + break; + + case 'w': + { + const char *elements[4]; + unsigned int opcode = l & VFPU_MASK_OP_SIZE; + unsigned int rotators = (l >> OP_SH_VFPU_ROT) & OP_MASK_VFPU_ROT; + unsigned int opsize, rothi, rotlo, negation, i; + + /* Determine the operand size so we'll know how many elements to output. */ + if (opcode == VFPU_OP_SIZE_PAIR) + opsize = 2; + else if (opcode == VFPU_OP_SIZE_TRIPLE) + opsize = 3; + else + opsize = (opcode == VFPU_OP_SIZE_QUAD) * 4; /* Sanity check. */ + + rothi = (rotators >> VFPU_SH_ROT_HI) & VFPU_MASK_ROT_HI; + rotlo = (rotators >> VFPU_SH_ROT_LO) & VFPU_MASK_ROT_LO; + negation = (rotators >> VFPU_SH_ROT_NEG) & VFPU_MASK_ROT_NEG; + + if (rothi == rotlo) + { + if (negation) + { + elements[0] = "-s"; + elements[1] = "-s"; + elements[2] = "-s"; + elements[3] = "-s"; + } + else + { + elements[0] = "s"; + elements[1] = "s"; + elements[2] = "s"; + elements[3] = "s"; + } + } + else + { + elements[0] = "0"; + elements[1] = "0"; + elements[2] = "0"; + elements[3] = "0"; + } + if (negation) + elements[rothi] = "-s"; + else + elements[rothi] = "s"; + elements[rotlo] = "c"; + + (*info->fprintf_func) (info->stream, "["); + i = 0; + for (;;) + { + (*info->fprintf_func) (info->stream, "%s", + elements[i++]); + if (i >= opsize) + break; + (*info->fprintf_func) (info->stream, ","); + } + (*info->fprintf_func) (info->stream, "]"); + } + break; + + case 'd': + case 'm': + case 'n': + case 's': + case 't': + case 'v': + case 'x': + { + unsigned int vreg = 0; + + /* The first char specifies the bitfield that contains the register number. */ + switch (*d) + { + case 'd': + case 'v': + case 'x': + vreg = (l >> OP_SH_VFPU_VD) & OP_MASK_VFPU_VD; + break; + + case 'm': + /* Combine bits 0-4 of vt with bits 5-6 of vt. */ + vreg = ((l >> OP_SH_VFPU_VT_LO) & OP_MASK_VFPU_VT_LO) + | ((l & OP_MASK_VFPU_VT_HI2) << OP_SH_VFPU_VT_HI); + break; + + case 'n': + /* Combine bits 0-4 of vt with bit 5 of vt. */ + vreg = ((l >> OP_SH_VFPU_VT_LO) & OP_MASK_VFPU_VT_LO) + | ((l & OP_MASK_VFPU_VT_HI1) << OP_SH_VFPU_VT_HI); + break; + + case 's': + { + unsigned int temp_vreg = l >> OP_SH_VFPU_VS; + + vreg = temp_vreg & OP_MASK_VFPU_VS; + if ((l & VFPU_OP_VT_VS_VD) == VFPU_OPCODE_VMMUL) + { + /* vmmul instructions have the RXC bit (bit 13) inverted. */ + if (temp_vreg & 0x20) + vreg = temp_vreg & 0x5f; + else + vreg |= 0x20; + } + } + break; + + case 't': + vreg = (l >> OP_SH_VFPU_VT) & OP_MASK_VFPU_VT; + break; + } + + /* The next char is the register set vreg comes from. */ + d++; + switch (*d) + { + case '0': + (*info->fprintf_func) (info->stream, "%s.s", + vfpu_sreg_names[vreg]); + break; + + case '1': + (*info->fprintf_func) (info->stream, "%s.p", + vfpu_vpreg_names[vreg]); + break; + + case '2': + (*info->fprintf_func) (info->stream, "%s.t", + vfpu_vtreg_names[vreg]); + break; + + case '3': + (*info->fprintf_func) (info->stream, "%s.q", + vfpu_vqreg_names[vreg]); + break; + + case '5': + (*info->fprintf_func) (info->stream, "%s.p", + vfpu_mpreg_names[vreg]); + break; + + case '6': + (*info->fprintf_func) (info->stream, "%s.t", + vfpu_mtreg_names[vreg]); + break; + + case '7': + (*info->fprintf_func) (info->stream, "%s.q", + vfpu_mqreg_names[vreg]); + break; + + default: + /* xgettext:c-format */ + (*info->fprintf_func) (info->stream, + _("# internal error, undefined vreg modifier(%c)"), + *d); + break; + } + + /* The last char is unused for disassembly. */ + d++; + } + break; + + case 'z': + (*info->fprintf_func) (info->stream, "%s", + vfpu_rwb_names[(l >> OP_SH_VFPU_RWB) & OP_MASK_VFPU_RWB]); + break; + } + break; + default: /* xgettext:c-format */ (*info->fprintf_func) (info->stream, diff -burN orig.binutils-2.22/opcodes/mips-opc.c binutils-2.22/opcodes/mips-opc.c --- orig.binutils-2.22/opcodes/mips-opc.c 2011-08-09 17:20:03.000000000 +0200 +++ binutils-2.22/opcodes/mips-opc.c 2012-01-12 22:06:52.133470527 +0100 @@ -121,6 +121,7 @@ #define N5 (INSN_5400 | INSN_5500) #define N54 INSN_5400 #define N55 INSN_5500 +#define AL INSN_ALLEGREX #define IOCT INSN_OCTEON #define XLR INSN_XLR @@ -402,6 +403,7 @@ {"bnel", "s,t,p", 0x54000000, 0xfc000000, CBL|RD_s|RD_t, 0, I2|T3 }, {"bnel", "s,I,p", 0, (int) M_BNEL_I, INSN_MACRO, 0, I2|T3 }, {"break", "", 0x0000000d, 0xffffffff, TRAP, 0, I1 }, +{"break", "B", 0x0000000d, 0xfc00003f, TRAP, 0, AL }, {"break", "c", 0x0000000d, 0xfc00ffff, TRAP, 0, I1 }, {"break", "c,q", 0x0000000d, 0xfc00003f, TRAP, 0, I1 }, {"c.f.d", "S,T", 0x46200030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, @@ -584,7 +586,7 @@ {"flushd", "", 0xbc020000, 0xffffffff, 0, 0, L1 }, {"flushid", "", 0xbc030000, 0xffffffff, 0, 0, L1 }, {"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, 0, L1 }, -{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3_32|T3}, +{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3_32|T3|AL}, {"cache", "k,A(b)", 0, (int) M_CACHE_AB, INSN_MACRO, 0, I3_32|T3}, {"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, {"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, @@ -602,7 +604,9 @@ {"cins", "t,r,+P,+S",0x70000033, 0xfc00003f, WR_t|RD_s, 0, IOCT }, /* cins32 */ {"cins", "t,r,+p,+s",0x70000032, 0xfc00003f, WR_t|RD_s, 0, IOCT }, {"clo", "U,s", 0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, +{"clo", "d,s", 0x00000017, 0xfc1f07ff, WR_d|RD_s, 0, AL }, {"clz", "U,s", 0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, +{"clz", "d,s", 0x00000016, 0xfc1f07ff, WR_d|RD_s, 0, AL }, {"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, {"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, @@ -627,16 +631,16 @@ {"cvt.ps.s","D,V,T", 0x46000026, 0xffe0003f, WR_D|RD_S|RD_T|FP_S|FP_D, 0, I5_33 }, {"cvt.pw.ps", "D,S", 0x46c00024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, {"dabs", "d,v", 0, (int) M_DABS, INSN_MACRO, 0, I3 }, +{"max", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, AL }, {"dadd", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, {"dadd", "t,r,I", 0, (int) M_DADD_I, INSN_MACRO, 0, I3 }, -{"dadd", "D,S,T", 0x45e00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dadd", "D,S,T", 0x4b60000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F|IL3A }, {"daddi", "t,r,j", 0x60000000, 0xfc000000, WR_t|RD_s, 0, I3 }, {"daddiu", "t,r,j", 0x64000000, 0xfc000000, WR_t|RD_s, 0, I3 }, +{"min", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, AL }, {"daddu", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, {"daddu", "t,r,I", 0, (int) M_DADDU_I, INSN_MACRO, 0, I3 }, {"daddwc", "d,s,t", 0x70000038, 0xfc0007ff, WR_d|RD_s|RD_t|WR_C0|RD_C0, 0, XLR }, -{"dbreak", "", 0x7000003f, 0xffffffff, 0, 0, N5 }, +{"dbreak", "", 0x7000003f, 0xffffffff, 0, 0, N5|AL }, {"dclo", "U,s", 0x70000025, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, {"dclz", "U,s", 0x70000024, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, /* dctr and dctw are used on the r5000. */ @@ -725,7 +729,7 @@ {"dremu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, {"dremu", "d,v,t", 0, (int) M_DREMU_3, INSN_MACRO, 0, I3 }, {"dremu", "d,v,I", 0, (int) M_DREMU_3I, INSN_MACRO, 0, I3 }, -{"dret", "", 0x7000003e, 0xffffffff, 0, 0, N5 }, +{"dret", "", 0x7000003e, 0xffffffff, 0, 0, N5|AL }, {"drol", "d,v,t", 0, (int) M_DROL, INSN_MACRO, 0, I3 }, {"drol", "d,v,I", 0, (int) M_DROL_I, INSN_MACRO, 0, I3 }, {"dror", "d,v,t", 0, (int) M_DROR, INSN_MACRO, 0, I3 }, @@ -774,10 +778,10 @@ {"ei", "t", 0x41606020, 0xffe0ffff, WR_t|WR_C0, 0, I33|IOCT}, {"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, {"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"eret", "", 0x42000018, 0xffffffff, NODS, 0, I3_32 }, +{"eret", "", 0x42000018, 0xffffffff, NODS, 0, I3_32|AL }, {"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, +{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33|AL }, {"exts32", "t,r,+p,+S",0x7000003b, 0xfc00003f, WR_t|RD_s, 0, IOCT }, {"exts", "t,r,+P,+S",0x7000003b, 0xfc00003f, WR_t|RD_s, 0, IOCT }, /* exts32 */ {"exts", "t,r,+p,+s",0x7000003a, 0xfc00003f, WR_t|RD_s, 0, IOCT }, @@ -786,7 +790,7 @@ {"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, {"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, {"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, -{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 }, +{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33|AL }, {"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC }, {"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with @@ -829,18 +833,10 @@ {"ldaddw", "t,b", 0x70000010, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, {"ldaddwu", "t,b", 0x70000011, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, {"ldaddd", "t,b", 0x70000012, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, -{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, -{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, -{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, -{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, -{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, /* ldc1 */ -{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, INSN2_M_FP_D, I1 }, -{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, INSN2_M_FP_D, I1 }, -{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, -{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, 0, I2 }, -{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, -{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, 0, I2 }, -{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, +/* ldc1 is at the bottom of the table. */ +/* ldc2 is at the bottom of the table. */ +/* ldc3 is at the bottom of the table. */ +{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3|AL }, {"ldl", "t,A(b)", 0, (int) M_LDL_AB, INSN_MACRO, 0, I3 }, {"ldr", "t,o(b)", 0x6c000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, {"ldr", "t,A(b)", 0, (int) M_LDR_AB, INSN_MACRO, 0, I3 }, @@ -870,8 +866,7 @@ {"lwc1", "E,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, {"l.s", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, 0, I1 }, /* lwc1 */ {"l.s", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, -{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, -{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, 0, I1 }, +/* lwc2 is at the bottom of the table. */ {"lwc3", "E,o(b)", 0xcc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, {"lwc3", "E,A(b)", 0, (int) M_LWC3_AB, INSN_MACRO, 0, I1 }, {"lwl", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, @@ -911,12 +906,14 @@ {"madd.ps", "D,S,T", 0x45600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, {"madd.ps", "D,S,T", 0x71600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, {"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, {"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, {"madd", "7,s,t", 0x70000000, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, {"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, {"maddp", "s,t", 0x70000441, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, {"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, {"maddu", "7,s,t", 0x70000001, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, @@ -957,7 +954,7 @@ /* mfc2 is at the bottom of the table. */ /* mfhc2 is at the bottom of the table. */ /* mfc3 is at the bottom of the table. */ -{"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, +{"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5|AL }, {"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, 0, I1 }, {"mfhi", "d,9", 0x00000010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, {"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, 0, I1 }, @@ -979,7 +976,7 @@ {"movf.l", "X,Y,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 }, {"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 }, -{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F }, +{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F|AL }, {"movnz", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IL2E|IL2F|IL3A }, {"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, {"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 }, @@ -993,7 +990,7 @@ {"movt.l", "X,Y,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 }, {"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 }, -{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F }, +{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F|AL }, {"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, {"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 }, {"movz.l", "D,S,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, @@ -1021,9 +1018,11 @@ {"msub.ps", "D,S,T", 0x45600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, {"msub.ps", "D,S,T", 0x71600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, {"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"msub", "s,t", 0x0000002e, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, {"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"msub", "7,s,t", 0x70000004, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, {"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"msubu", "s,t", 0x0000002f, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, {"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"msubu", "7,s,t", 0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, {"mtpc", "t,P", 0x4080c801, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 }, @@ -1038,7 +1037,7 @@ /* mtc2 is at the bottom of the table. */ /* mthc2 is at the bottom of the table. */ /* mtc3 is at the bottom of the table. */ -{"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, +{"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5|AL }, {"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, 0, I1 }, {"mthi", "s,7", 0x00000011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, {"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, 0, I1 }, @@ -1223,13 +1222,13 @@ {"rol", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I1 }, {"ror", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I1 }, {"ror", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I1 }, -{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT }, -{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT }, -{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT }, -{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT }, -{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT }, -{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT }, -{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT }, +{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT|AL }, +{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT|AL }, +{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT|AL }, +{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT|AL }, +{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT|AL }, +{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT|AL }, +{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT|AL }, {"round.l.d", "D,S", 0x46200008, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, {"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, {"round.w.d", "D,S", 0x4620000c, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, @@ -1262,24 +1261,17 @@ {"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, 0, G2 }, {"sdbbp", "", 0x7000003f, 0xffffffff, TRAP, 0, I32 }, {"sdbbp", "B", 0x7000003f, 0xfc00003f, TRAP, 0, I32 }, -{"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, -{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, -{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I2 }, -{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, 0, I2 }, -{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, 0, I2 }, -{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, 0, I2 }, -{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, INSN2_M_FP_D, I1 }, -{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, INSN2_M_FP_D, I1 }, -{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, +/* sdc1 is at the bottom of the table. */ +/* sdc2 is at the bottom of the table. */ +/* sdc3 is at the bottom of the table. */ +/* s.d (sdc1 is at the bottom of the table. */ +{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, 0, I3|AL }, {"sdl", "t,A(b)", 0, (int) M_SDL_AB, INSN_MACRO, 0, I3 }, {"sdr", "t,o(b)", 0xb4000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, {"sdr", "t,A(b)", 0, (int) M_SDR_AB, INSN_MACRO, 0, I3 }, {"sdxc1", "S,t(b)", 0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_D, 0, I4_33 }, -{"seb", "d,w", 0x7c000420, 0xffe007ff, WR_d|RD_t, 0, I33 }, -{"seh", "d,w", 0x7c000620, 0xffe007ff, WR_d|RD_t, 0, I33 }, +{"seb", "d,w", 0x7c000420, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, +{"seh", "d,w", 0x7c000620, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, {"selsl", "d,v,t", 0x00000005, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, {"selsr", "d,v,t", 0x00000001, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, {"seq", "d,v,t", 0x7000002a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IOCT }, @@ -1399,8 +1391,7 @@ {"swc1", "E,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, {"s.s", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, 0, I1 }, /* swc1 */ {"s.s", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, -{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I1 }, -{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, 0, I1 }, +/* swc2 is at the bottom of the table. */ {"swc3", "E,o(b)", 0xec000000, 0xfc000000, SM|RD_C3|RD_b, 0, I1 }, {"swc3", "E,A(b)", 0, (int) M_SWC3_AB, INSN_MACRO, 0, I1 }, {"swl", "t,o(b)", 0xa8000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, @@ -1497,7 +1488,8 @@ {"wait", "J", 0x42000020, 0xfe00003f, NODS, 0, I32|N55 }, {"waiti", "", 0x42000020, 0xffffffff, NODS, 0, L1 }, {"wrpgpr", "d,w", 0x41c00000, 0xffe007ff, RD_t, 0, I33 }, -{"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33 }, +{"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, +{"wsbw", "d,t", 0x7c0000e0, 0xffe007ff, WR_d|RD_t, 0, AL }, {"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, {"xor", "t,r,I", 0, (int) M_XOR_I, INSN_MACRO, 0, I1 }, {"xor", "D,S,T", 0x47800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, @@ -1511,6 +1503,321 @@ {"yield", "s", 0x7c000009, 0xfc1fffff, NODS|RD_s, 0, MT32 }, {"yield", "d,s", 0x7c000009, 0xfc1f07ff, NODS|WR_d|RD_s, 0, MT32 }, +/* Sony Allegrex CPU core. */ +{"bitrev", "d,t", 0x7c000520, 0xffe007ff, WR_d|RD_t, 0, AL }, +/* From "MIPS DSP ASU", because instructions with the same name need to be next to each other */ +{"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, +{"mfic", "t,G", 0x70000024, 0xffe007ff, LCD|WR_t|RD_C0, 0, AL }, +{"mtic", "t,G", 0x70000026, 0xffe007ff, COD|RD_t|WR_C0, 0, AL }, + +/* Sony Allegrex VFPU instructions. */ +{"bvf", "?c,p", 0x49000000, 0xffe30000, CBD|RD_CC, 0, AL }, +{"bvfl", "?c,p", 0x49020000, 0xffe30000, CBL|RD_CC, 0, AL }, +{"bvt", "?c,p", 0x49010000, 0xffe30000, CBD|RD_CC, 0, AL }, +{"bvtl", "?c,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, AL }, +{"lv.s", "?m0x,?o(b)", 0xc8000000, 0xfc000000, CLD|RD_s|WR_CC, 0, AL }, +{"lv.s", "?m0x,A(b)", 0, (int) M_LV_Q_AB, INSN_MACRO, 0, AL }, +{"ulv.s", "?m0x,o(b)", 0, (int) M_ULV_S, INSN_MACRO, 0, AL }, +{"lv.q", "?n3x,?o(b)", 0xd8000000, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, +{"lv.q", "?n3x,A(b)", 0, (int) M_LV_Q_AB_2, INSN_MACRO, 0, AL }, +{"ulv.q", "?n3x,?o(b)", 0, (int) M_ULV_Q, INSN_MACRO, 0, AL }, +{"ulv.q", "?n3x,A(b)", 0, (int) M_ULV_Q_AB, INSN_MACRO, 0, AL }, +{"lvi.s", "?t0x,l?y0", 0, (int) M_LVI_S, INSN_MACRO, 0, AL }, +{"lvi.p", "?t1x,?[l?y0,l?y1?]", 0, (int) M_LVI_P, INSN_MACRO, 0, AL }, +{"lvi.t", "?t2x,?[l?y0,l?y1,l?y2?]", 0, (int) M_LVI_T, INSN_MACRO, 0, AL }, +{"lvi.q", "?t3x,?[l?y0,l?y1,l?y2,l?y3?]", 0, (int) M_LVI_Q, INSN_MACRO, 0, AL }, +{"lvhi.s", "?t0x,?[?u?y0,?u?y1?]", 0, (int) M_LVHI_S, INSN_MACRO, 0, AL }, +{"lvhi.p", "?t1x,?[?u?y0,?u?y1,?u?y2,?u?y3?]", 0, (int) M_LVHI_P, INSN_MACRO, 0, AL }, +{"sv.s", "?m0x,?o(b)", 0xe8000000, 0xfc000000, SM|RD_s|RD_C2, 0, AL }, +{"sv.s", "?m0x,A(b)", 0, (int) M_SV_S_AB, INSN_MACRO, 0, AL }, +{"usv.s", "?m0x,o(b)", 0, (int) M_USV_S, INSN_MACRO, 0, AL }, +{"sv.q", "?n3x,?o(b)", 0xf8000000, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, +{"sv.q", "?n3x,?o(b),?z", 0xf8000000, 0xfc000000, SM|RD_s|RD_C2, 0, AL }, +{"sv.q", "?n3x,A(b)", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, +{"sv.q", "?n3x,A(b),?z", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, +{"sv.q", "?n3x,A,?z", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, +{"usv.q", "?n3x,?o(b)", 0, (int) M_USV_Q, INSN_MACRO, 0, AL }, +{"usv.q", "?n3x,A(b)", 0, (int) M_USV_Q_AB, INSN_MACRO, 0, AL }, +{"vwb.q", "?n3x,?o(b)", 0xf8000002, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, +{"lvl.q", "?n3x,?o(b)", 0xd4000000, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, +{"lvl.q", "?n3x,A(b)", 0, (int) M_LVL_Q_AB, INSN_MACRO, 0, AL }, +{"lvr.q", "?n3x,?o(b)", 0xd4000002, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, +{"lvr.q", "?n3x,A(b)", 0, (int) M_LVR_Q_AB, INSN_MACRO, 0, AL }, +{"svl.q", "?n3x,?o(b)", 0xf4000000, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, +{"svl.q", "?n3x,A(b)", 0, (int) M_SVL_Q_AB, INSN_MACRO, 0, AL }, +{"svr.q", "?n3x,?o(b)", 0xf4000002, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, +{"svr.q", "?n3x,A(b)", 0, (int) M_SVR_Q_AB, INSN_MACRO, 0, AL }, +{"mtv", "t,?d0z", 0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2, 0, AL }, +{"mfv", "t,?d0z", 0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0, AL }, +{"mtvc", "t,?q", 0x48e00000, 0xffe0ff00, LCD|WR_t|WR_C2, 0, AL }, +{"mfvc", "t,?q", 0x48600000, 0xffe0ff00, COD|RD_t|WR_CC|RD_C2, 0, AL }, +{"vmtvc", "?q,?s0y", 0xd0510000, 0xffff8000, WR_C2, 0, AL }, +{"vmfvc", "?d0z,?r", 0xd0500000, 0xffff0080, RD_C2, 0, AL }, +{"vadd.q", "?d3d,?s3s,?t3t", 0x60008080, 0xff808080, RD_C2, 0, AL }, +{"vsub.q", "?d3d,?s3s,?t3t", 0x60808080, 0xff808080, RD_C2, 0, AL }, +{"vdiv.q", "?x3z,?s3y,?t3x", 0x63808080, 0xff808080, RD_C2, 0, AL }, +{"vmul.q", "?d3d,?s3s,?t3t", 0x64008080, 0xff808080, RD_C2, 0, AL }, +{"vdot.q", "?d0d,?s3s,?t3t", 0x64808080, 0xff808080, RD_C2, 0, AL }, +{"vscl.q", "?d3d,?s3s,?t0x", 0x65008080, 0xff808080, RD_C2, 0, AL }, +{"vhdp.q", "?d0d,?s3y,?t3t", 0x66008080, 0xff808080, RD_C2, 0, AL }, +{"vcmp.q", "?f2,?s3s,?t3t", 0x6c008080, 0xff8080f0, RD_C2, 0, AL }, +{"vcmp.q", "?f1,?s3s", 0x6c008080, 0xffff80f0, RD_C2, 0, AL }, +{"vcmp.q", "?f0", 0x6c008080, 0xfffffff0, RD_C2, 0, AL }, +{"vmin.q", "?d3d,?s3s,?t3t", 0x6d008080, 0xff808080, RD_C2, 0, AL }, +{"vmax.q", "?d3d,?s3s,?t3t", 0x6d808080, 0xff808080, RD_C2, 0, AL }, +{"vsgn.q", "?d3d,?s3s", 0xd04a8080, 0xffff8080, RD_C2, 0, AL }, +{"vcst.q", "?d3d,?a", 0xd0608080, 0xffe0ff80, RD_C2, 0, AL }, +{"vscmp.q", "?d3d,?s3s,?t3t", 0x6e808080, 0xff808080, RD_C2, 0, AL }, +{"vsge.q", "?d3d,?s3s,?t3t", 0x6f008080, 0xff808080, RD_C2, 0, AL }, +{"vslt.q", "?d3d,?s3s,?t3t", 0x6f808080, 0xff808080, RD_C2, 0, AL }, +{"vi2uc.q", "?d0m,?s3w", 0xd03c8080, 0xffff8080, RD_C2, 0, AL }, +{"vi2c.q", "?d0m,?s3w", 0xd03d8080, 0xffff8080, RD_C2, 0, AL }, +{"vi2us.q", "?d1m,?s3w", 0xd03e8080, 0xffff8080, RD_C2, 0, AL }, +{"vi2s.q", "?d1m,?s3w", 0xd03f8080, 0xffff8080, RD_C2, 0, AL }, +{"vmov.q", "?d3d,?s3s", 0xd0008080, 0xffff8080, RD_C2, 0, AL }, +{"vabs.q", "?d3d,?s3w", 0xd0018080, 0xffff8080, RD_C2, 0, AL }, +{"vneg.q", "?d3d,?s3w", 0xd0028080, 0xffff8080, RD_C2, 0, AL }, +{"vidt.q", "?d3d", 0xd0038080, 0xffffff80, RD_C2, 0, AL }, +{"vsat0.q", "?d3z,?s3s", 0xd0048080, 0xffff8080, RD_C2, 0, AL }, +{"vsat1.q", "?d3z,?s3s", 0xd0058080, 0xffff8080, RD_C2, 0, AL }, +{"vzero.q", "?d3d", 0xd0068080, 0xffffff80, RD_C2, 0, AL }, +{"vone.q", "?d3d", 0xd0078080, 0xffffff80, RD_C2, 0, AL }, +{"vrcp.q", "?x3z,?s3y", 0xd0108080, 0xffff8080, RD_C2, 0, AL }, +{"vrsq.q", "?x3z,?s3y", 0xd0118080, 0xffff8080, RD_C2, 0, AL }, +{"vsin.q", "?x3z,?s3y", 0xd0128080, 0xffff8080, RD_C2, 0, AL }, +{"vcos.q", "?x3z,?s3y", 0xd0138080, 0xffff8080, RD_C2, 0, AL }, +{"vexp2.q", "?x3z,?s3y", 0xd0148080, 0xffff8080, RD_C2, 0, AL }, +{"vlog2.q", "?x3z,?s3y", 0xd0158080, 0xffff8080, RD_C2, 0, AL }, +{"vsqrt.q", "?x3z,?s3y", 0xd0168080, 0xffff8080, RD_C2, 0, AL }, +{"vasin.q", "?x3z,?s3y", 0xd0178080, 0xffff8080, RD_C2, 0, AL }, +{"vnrcp.q", "?x3z,?s3y", 0xd0188080, 0xffff8080, RD_C2, 0, AL }, +{"vnsin.q", "?x3z,?s3y", 0xd01a8080, 0xffff8080, RD_C2, 0, AL }, +{"vrexp2.q", "?x3z,?s3y", 0xd01c8080, 0xffff8080, RD_C2, 0, AL }, +{"vrndi.q", "?d3z", 0xd0218080, 0xffffff80, RD_C2, 0, AL }, +{"vrndf1.q", "?d3z", 0xd0228080, 0xffffff80, RD_C2, 0, AL }, +{"vrndf2.q", "?d3z", 0xd0238080, 0xffffff80, RD_C2, 0, AL }, +{"vf2h.q", "?d1m,?s3s", 0xd0328080, 0xffff8080, RD_C2, 0, AL }, +{"vsrt1.q", "?d3d,?s3s", 0xd0408080, 0xffff8080, RD_C2, 0, AL }, +{"vsrt2.q", "?d3d,?s3s", 0xd0418080, 0xffff8080, RD_C2, 0, AL }, +{"vsrt3.q", "?d3d,?s3s", 0xd0488080, 0xffff8080, RD_C2, 0, AL }, +{"vsrt4.q", "?d3d,?s3s", 0xd0498080, 0xffff8080, RD_C2, 0, AL }, +{"vbfy1.q", "?d3d,?s3s", 0xd0428080, 0xffff8080, RD_C2, 0, AL }, +{"vbfy2.q", "?d3d,?s3s", 0xd0438080, 0xffff8080, RD_C2, 0, AL }, +{"vocp.q", "?d3d,?s3y", 0xd0448080, 0xffff8080, RD_C2, 0, AL }, +{"vfad.q", "?d0d,?s3s", 0xd0468080, 0xffff8080, RD_C2, 0, AL }, +{"vavg.q", "?d0d,?s3s", 0xd0478080, 0xffff8080, RD_C2, 0, AL }, +{"vf2in.q", "?d3m,?s3s,?b", 0xd2008080, 0xffe08080, RD_C2, 0, AL }, +{"vf2iz.q", "?d3m,?s3s,?b", 0xd2208080, 0xffe08080, RD_C2, 0, AL }, +{"vf2iu.q", "?d3m,?s3s,?b", 0xd2408080, 0xffe08080, RD_C2, 0, AL }, +{"vf2id.q", "?d3m,?s3s,?b", 0xd2608080, 0xffe08080, RD_C2, 0, AL }, +{"vi2f.q", "?d3d,?s3w,?b", 0xd2808080, 0xffe08080, RD_C2, 0, AL }, +{"vcmov.q", "?d3d,?s3s,?e", 0, (int) M_VCMOV_Q, INSN_MACRO, 0, AL }, +{"vcmovt.q", "?d3d,?s3s,?e", 0xd2a08080, 0xfff88080, RD_C2, 0, AL }, +{"vcmovf.q", "?d3d,?s3s,?e", 0xd2a88080, 0xfff88080, RD_C2, 0, AL }, +{"vmmul.q", "?v7z,?s7y,?t7x", 0xf0008080, 0xff808080, RD_C2, 0, AL }, +{"vtfm4.q", "?v3z,?s7y,?t3x", 0xf1808080, 0xff808080, RD_C2, 0, AL }, +{"vhtfm4.q", "?v3z,?s7y,?t3x", 0xf1808000, 0xff808080, RD_C2, 0, AL }, +{"vmscl.q", "?x7z,?s7y,?t0x", 0xf2008080, 0xff808080, RD_C2, 0, AL }, +{"vqmul.q", "?v3z,?s3y,?t3x", 0xf2808080, 0xff808080, RD_C2, 0, AL }, +{"vmmov.q", "?x7z,?s7y", 0xf3808080, 0xffff8080, RD_C2, 0, AL }, +{"vmidt.q", "?d7z", 0xf3838080, 0xffffff80, RD_C2, 0, AL }, +{"vmzero.q", "?d7z", 0xf3868080, 0xffffff80, RD_C2, 0, AL }, +{"vmone.q", "?d7z", 0xf3878080, 0xffffff80, RD_C2, 0, AL }, +{"vrot.q", "?x3z,?s0y,?w", 0xf3a08080, 0xffe08080, RD_C2, 0, AL }, +{"vt4444.q", "?d1z,?s3w", 0xd0598080, 0xffff8080, RD_C2, 0, AL }, +{"vt5551.q", "?d1z,?s3w", 0xd05a8080, 0xffff8080, RD_C2, 0, AL }, +{"vt5650.q", "?d1z,?s3w", 0xd05b8080, 0xffff8080, RD_C2, 0, AL }, +{"vadd.t", "?d2d,?s2s,?t2t", 0x60008000, 0xff808080, RD_C2, 0, AL }, +{"vsub.t", "?d2d,?s2s,?t2t", 0x60808000, 0xff808080, RD_C2, 0, AL }, +{"vdiv.t", "?x2z,?s2y,?t2x", 0x63808000, 0xff808080, RD_C2, 0, AL }, +{"vmul.t", "?d2d,?s2s,?t2t", 0x64008000, 0xff808080, RD_C2, 0, AL }, +{"vdot.t", "?d0d,?s2s,?t2t", 0x64808000, 0xff808080, RD_C2, 0, AL }, +{"vscl.t", "?d2d,?s2s,?t0x", 0x65008000, 0xff808080, RD_C2, 0, AL }, +{"vhdp.t", "?d0d,?s2y,?t2t", 0x66008000, 0xff808080, RD_C2, 0, AL }, +{"vcrs.t", "?d2d,?s2y,?t2x", 0x66808000, 0xff808080, RD_C2, 0, AL }, +{"vcmp.t", "?f2,?s2s,?t2t", 0x6c008000, 0xff8080f0, RD_C2, 0, AL }, +{"vcmp.t", "?f1,?s2s", 0x6c008000, 0xffff80f0, RD_C2, 0, AL }, +{"vcmp.t", "?f0", 0x6c008000, 0xfffffff0, RD_C2, 0, AL }, +{"vmin.t", "?d2d,?s2s,?t2t", 0x6d008000, 0xff808080, RD_C2, 0, AL }, +{"vmax.t", "?d2d,?s2s,?t2t", 0x6d808000, 0xff808080, RD_C2, 0, AL }, +{"vsgn.t", "?d2d,?s2s", 0xd04a8000, 0xffff8080, RD_C2, 0, AL }, +{"vcst.t", "?d2d,?a", 0xd0608000, 0xffe0ff80, RD_C2, 0, AL }, +{"vscmp.t", "?d2d,?s2s,?t2t", 0x6e808000, 0xff808080, RD_C2, 0, AL }, +{"vsge.t", "?d2d,?s2s,?t2t", 0x6f008000, 0xff808080, RD_C2, 0, AL }, +{"vslt.t", "?d2d,?s2s,?t2t", 0x6f808000, 0xff808080, RD_C2, 0, AL }, +{"vmov.t", "?d2d,?s2s", 0xd0008000, 0xffff8080, RD_C2, 0, AL }, +{"vabs.t", "?d2d,?s2w", 0xd0018000, 0xffff8080, RD_C2, 0, AL }, +{"vneg.t", "?d2d,?s2w", 0xd0028000, 0xffff8080, RD_C2, 0, AL }, +{"vsat0.t", "?d2z,?s2s", 0xd0048000, 0xffff8080, RD_C2, 0, AL }, +{"vsat1.t", "?d2z,?s2s", 0xd0058000, 0xffff8080, RD_C2, 0, AL }, +{"vzero.t", "?d2d", 0xd0068000, 0xffffff80, RD_C2, 0, AL }, +{"vone.t", "?d2d", 0xd0078000, 0xffffff80, RD_C2, 0, AL }, +{"vrcp.t", "?x2z,?s2y", 0xd0108000, 0xffff8080, RD_C2, 0, AL }, +{"vrsq.t", "?x2z,?s2y", 0xd0118000, 0xffff8080, RD_C2, 0, AL }, +{"vsin.t", "?x2z,?s2y", 0xd0128000, 0xffff8080, RD_C2, 0, AL }, +{"vcos.t", "?x2z,?s2y", 0xd0138000, 0xffff8080, RD_C2, 0, AL }, +{"vexp2.t", "?x2z,?s2y", 0xd0148000, 0xffff8080, RD_C2, 0, AL }, +{"vlog2.t", "?x2z,?s2y", 0xd0158000, 0xffff8080, RD_C2, 0, AL }, +{"vsqrt.t", "?x2z,?s2y", 0xd0168000, 0xffff8080, RD_C2, 0, AL }, +{"vasin.t", "?x2z,?s2y", 0xd0178000, 0xffff8080, RD_C2, 0, AL }, +{"vnrcp.t", "?x2z,?s2y", 0xd0188000, 0xffff8080, RD_C2, 0, AL }, +{"vnsin.t", "?x2z,?s2y", 0xd01a8000, 0xffff8080, RD_C2, 0, AL }, +{"vrexp2.t", "?x2z,?s2y", 0xd01c8000, 0xffff8080, RD_C2, 0, AL }, +{"vrndi.t", "?d2z", 0xd0218000, 0xffffff80, RD_C2, 0, AL }, +{"vrndf1.t", "?d2z", 0xd0228000, 0xffffff80, RD_C2, 0, AL }, +{"vrndf2.t", "?d2z", 0xd0238000, 0xffffff80, RD_C2, 0, AL }, +{"vocp.t", "?d2d,?s2y", 0xd0448000, 0xffff8080, RD_C2, 0, AL }, +{"vfad.t", "?d0d,?s2s", 0xd0468000, 0xffff8080, RD_C2, 0, AL }, +{"vavg.t", "?d0d,?s2s", 0xd0478000, 0xffff8080, RD_C2, 0, AL }, +{"vf2in.t", "?d2m,?s2s,?b", 0xd2008000, 0xffe08080, RD_C2, 0, AL }, +{"vf2iz.t", "?d2m,?s2s,?b", 0xd2208000, 0xffe08080, RD_C2, 0, AL }, +{"vf2iu.t", "?d2m,?s2s,?b", 0xd2408000, 0xffe08080, RD_C2, 0, AL }, +{"vf2id.t", "?d2m,?s2s,?b", 0xd2608000, 0xffe08080, RD_C2, 0, AL }, +{"vi2f.t", "?d2d,?s2w,?b", 0xd2808000, 0xffe08080, RD_C2, 0, AL }, +{"vcmov.t", "?d2d,?s2s,?e", 0, (int) M_VCMOV_T, INSN_MACRO, 0, AL }, +{"vcmovt.t", "?d2d,?s2s,?e", 0xd2a08000, 0xfff88080, RD_C2, 0, AL }, +{"vcmovf.t", "?d2d,?s2s,?e", 0xd2a88000, 0xfff88080, RD_C2, 0, AL }, +{"vmmul.t", "?v6z,?s6y,?t6x", 0xf0008000, 0xff808080, RD_C2, 0, AL }, +{"vtfm3.t", "?v2z,?s6y,?t2x", 0xf1008000, 0xff808080, RD_C2, 0, AL }, +{"vhtfm3.t", "?v2z,?s6y,?t2x", 0xf1000080, 0xff808080, RD_C2, 0, AL }, +{"vmscl.t", "?x6z,?s6y,?t0x", 0xf2008000, 0xff808080, RD_C2, 0, AL }, +{"vmmov.t", "?x6z,?s6y", 0xf3808000, 0xffff8080, RD_C2, 0, AL }, +{"vmidt.t", "?d6z", 0xf3838000, 0xffffff80, RD_C2, 0, AL }, +{"vmzero.t", "?d6z", 0xf3868000, 0xffffff80, RD_C2, 0, AL }, +{"vmone.t", "?d6z", 0xf3878000, 0xffffff80, RD_C2, 0, AL }, +{"vrot.t", "?x2z,?s0y,?w", 0xf3a08000, 0xffe08080, RD_C2, 0, AL }, +{"vcrsp.t", "?d2z,?s2y,?t2x", 0xf2808000, 0xff808080, RD_C2, 0, AL }, +{"vadd.p", "?d1d,?s1s,?t1t", 0x60000080, 0xff808080, RD_C2, 0, AL }, +{"vsub.p", "?d1d,?s1s,?t1t", 0x60800080, 0xff808080, RD_C2, 0, AL }, +{"vdiv.p", "?x1z,?s1y,?t1x", 0x63800080, 0xff808080, RD_C2, 0, AL }, +{"vmul.p", "?d1d,?s1s,?t1t", 0x64000080, 0xff808080, RD_C2, 0, AL }, +{"vdot.p", "?d0d,?s1s,?t1t", 0x64800080, 0xff808080, RD_C2, 0, AL }, +{"vscl.p", "?d1d,?s1s,?t0x", 0x65000080, 0xff808080, RD_C2, 0, AL }, +{"vhdp.p", "?d0d,?s1y,?t1t", 0x66000080, 0xff808080, RD_C2, 0, AL }, +{"vdet.p", "?d0d,?s1s,?t1x", 0x67000080, 0xff808080, RD_C2, 0, AL }, +{"vcmp.p", "?f2,?s1s,?t1t", 0x6c000080, 0xff8080f0, RD_C2, 0, AL }, +{"vcmp.p", "?f1,?s1s", 0x6c000080, 0xffff80f0, RD_C2, 0, AL }, +{"vcmp.p", "?f0", 0x6c000080, 0xfffffff0, RD_C2, 0, AL }, +{"vmin.p", "?d1d,?s1s,?t1t", 0x6d000080, 0xff808080, RD_C2, 0, AL }, +{"vmax.p", "?d1d,?s1s,?t1t", 0x6d800080, 0xff808080, RD_C2, 0, AL }, +{"vsgn.p", "?d1d,?s1s", 0xd04a0080, 0xffff8080, RD_C2, 0, AL }, +{"vcst.p", "?d1d,?a", 0xd0600080, 0xffe0ff80, RD_C2, 0, AL }, +{"vscmp.p", "?d1d,?s1s,?t1t", 0x6e800080, 0xff808080, RD_C2, 0, AL }, +{"vsge.p", "?d1d,?s1s,?t1t", 0x6f000080, 0xff808080, RD_C2, 0, AL }, +{"vslt.p", "?d1d,?s1s,?t1t", 0x6f800080, 0xff808080, RD_C2, 0, AL }, +{"vus2i.p", "?d3m,?s1y", 0xd03a0080, 0xffff8080, RD_C2, 0, AL }, +{"vs2i.p", "?d3m,?s1y", 0xd03b0080, 0xffff8080, RD_C2, 0, AL }, +{"vi2us.p", "?d0m,?s1w", 0xd03e0080, 0xffff8080, RD_C2, 0, AL }, +{"vi2s.p", "?d0m,?s1w", 0xd03f0080, 0xffff8080, RD_C2, 0, AL }, +{"vmov.p", "?d1d,?s1s", 0xd0000080, 0xffff8080, RD_C2, 0, AL }, +{"vabs.p", "?d1d,?s1w", 0xd0010080, 0xffff8080, RD_C2, 0, AL }, +{"vneg.p", "?d1d,?s1w", 0xd0020080, 0xffff8080, RD_C2, 0, AL }, +{"vidt.p", "?d1d", 0xd0030080, 0xffffff80, RD_C2, 0, AL }, +{"vsat0.p", "?d1z,?s1s", 0xd0040080, 0xffff8080, RD_C2, 0, AL }, +{"vsat1.p", "?d1z,?s1s", 0xd0050080, 0xffff8080, RD_C2, 0, AL }, +{"vzero.p", "?d1d", 0xd0060080, 0xffffff80, RD_C2, 0, AL }, +{"vone.p", "?d1d", 0xd0070080, 0xffffff80, RD_C2, 0, AL }, +{"vrcp.p", "?x1z,?s1y", 0xd0100080, 0xffff8080, RD_C2, 0, AL }, +{"vrsq.p", "?x1z,?s1y", 0xd0110080, 0xffff8080, RD_C2, 0, AL }, +{"vsin.p", "?x1z,?s1y", 0xd0120080, 0xffff8080, RD_C2, 0, AL }, +{"vcos.p", "?x1z,?s1y", 0xd0130080, 0xffff8080, RD_C2, 0, AL }, +{"vexp2.p", "?x1z,?s1y", 0xd0140080, 0xffff8080, RD_C2, 0, AL }, +{"vlog2.p", "?x1z,?s1y", 0xd0150080, 0xffff8080, RD_C2, 0, AL }, +{"vsqrt.p", "?x1z,?s1y", 0xd0160080, 0xffff8080, RD_C2, 0, AL }, +{"vasin.p", "?x1z,?s1y", 0xd0170080, 0xffff8080, RD_C2, 0, AL }, +{"vnrcp.p", "?x1z,?s1y", 0xd0180080, 0xffff8080, RD_C2, 0, AL }, +{"vnsin.p", "?x1z,?s1y", 0xd01a0080, 0xffff8080, RD_C2, 0, AL }, +{"vrexp2.p", "?x1z,?s1y", 0xd01c0080, 0xffff8080, RD_C2, 0, AL }, +{"vrndi.p", "?d1z", 0xd0210080, 0xffffff80, RD_C2, 0, AL }, +{"vrndf1.p", "?d1z", 0xd0220080, 0xffffff80, RD_C2, 0, AL }, +{"vrndf2.p", "?d1z", 0xd0230080, 0xffffff80, RD_C2, 0, AL }, +{"vf2h.p", "?d0m,?s1s", 0xd0320080, 0xffff8080, RD_C2, 0, AL }, +{"vh2f.p", "?d3d,?s1y", 0xd0330080, 0xffff8080, RD_C2, 0, AL }, +{"vbfy1.p", "?d1d,?s1s", 0xd0420080, 0xffff8080, RD_C2, 0, AL }, +{"vocp.p", "?d1d,?s1y", 0xd0440080, 0xffff8080, RD_C2, 0, AL }, +{"vsocp.p", "?d3z,?s1y", 0xd0450080, 0xffff8080, RD_C2, 0, AL }, +{"vfad.p", "?d0d,?s1s", 0xd0460080, 0xffff8080, RD_C2, 0, AL }, +{"vavg.p", "?d0d,?s1s", 0xd0470080, 0xffff8080, RD_C2, 0, AL }, +{"vf2in.p", "?d1m,?s1s,?b", 0xd2000080, 0xffe08080, RD_C2, 0, AL }, +{"vf2iz.p", "?d1m,?s1s,?b", 0xd2200080, 0xffe08080, RD_C2, 0, AL }, +{"vf2iu.p", "?d1m,?s1s,?b", 0xd2400080, 0xffe08080, RD_C2, 0, AL }, +{"vf2id.p", "?d1m,?s1s,?b", 0xd2600080, 0xffe08080, RD_C2, 0, AL }, +{"vi2f.p", "?d1d,?s1w,?b", 0xd2800080, 0xffe08080, RD_C2, 0, AL }, +{"vcmov.p", "?d1d,?s1s,?e", 0, (int) M_VCMOV_P, INSN_MACRO, 0, AL }, +{"vcmovt.p", "?d1d,?s1s,?e", 0xd2a00080, 0xfff88080, RD_C2, 0, AL }, +{"vcmovf.p", "?d1d,?s1s,?e", 0xd2a80080, 0xfff88080, RD_C2, 0, AL }, +{"vmmul.p", "?v5z,?s5y,?t5x", 0xf0000080, 0xff808080, RD_C2, 0, AL }, +{"vtfm2.p", "?v1z,?s5y,?t1x", 0xf0800080, 0xff808080, RD_C2, 0, AL }, +{"vhtfm2.p", "?v1z,?s5y,?t1x", 0xf0800000, 0xff808080, RD_C2, 0, AL }, +{"vmscl.p", "?x5z,?s5y,?t0x", 0xf2000080, 0xff808080, RD_C2, 0, AL }, +{"vmmov.p", "?x5z,?s5y", 0xf3800080, 0xffff8080, RD_C2, 0, AL }, +{"vmidt.p", "?d5z", 0xf3830080, 0xffffff80, RD_C2, 0, AL }, +{"vmzero.p", "?d5z", 0xf3860080, 0xffffff80, RD_C2, 0, AL }, +{"vmone.p", "?d5z", 0xf3870080, 0xffffff80, RD_C2, 0, AL }, +{"vrot.p", "?x1z,?s0y,?w", 0xf3a00080, 0xffe08080, RD_C2, 0, AL }, +{"vadd.s", "?d0d,?s0s,?t0t", 0x60000000, 0xff808080, RD_C2, 0, AL }, +{"vsub.s", "?d0d,?s0s,?t0t", 0x60800000, 0xff808080, RD_C2, 0, AL }, +{"vdiv.s", "?x0d,?s0s,?t0t", 0x63800000, 0xff808080, RD_C2, 0, AL }, +{"vmul.s", "?d0d,?s0s,?t0t", 0x64000000, 0xff808080, RD_C2, 0, AL }, +{"vcmp.s", "?f2,?s0s,?t0t", 0x6c000000, 0xff8080f0, RD_C2, 0, AL }, +{"vcmp.s", "?f1,?s0s", 0x6c000000, 0xffff80f0, RD_C2, 0, AL }, +{"vcmp.s", "?f0", 0x6c000000, 0xfffffff0, RD_C2, 0, AL }, +{"vmin.s", "?d0d,?s0s,?t0t", 0x6d000000, 0xff808080, RD_C2, 0, AL }, +{"vmax.s", "?d0d,?s0s,?t0t", 0x6d800000, 0xff808080, RD_C2, 0, AL }, +{"vsgn.s", "?d0d,?s0s", 0xd04a0000, 0xffff8080, RD_C2, 0, AL }, +{"vcst.s", "?d0d,?a", 0xd0600000, 0xffe0ff80, RD_C2, 0, AL }, +{"vscmp.s", "?d0d,?s0s,?t0t", 0x6e800000, 0xff808080, RD_C2, 0, AL }, +{"vsge.s", "?d0d,?s0s,?t0t", 0x6f000000, 0xff808080, RD_C2, 0, AL }, +{"vslt.s", "?d0d,?s0s,?t0t", 0x6f800000, 0xff808080, RD_C2, 0, AL }, +{"vus2i.s", "?d1m,?s0y", 0xd03a0000, 0xffff8080, RD_C2, 0, AL }, +{"vs2i.s", "?d1m,?s0y", 0xd03b0000, 0xffff8080, RD_C2, 0, AL }, +{"vmov.s", "?d0d,?s0s", 0xd0000000, 0xffff8080, RD_C2, 0, AL }, +{"vabs.s", "?d0d,?s0w", 0xd0010000, 0xffff8080, RD_C2, 0, AL }, +{"vneg.s", "?d0d,?s0w", 0xd0020000, 0xffff8080, RD_C2, 0, AL }, +{"vsat0.s", "?d0z,?s0s", 0xd0040000, 0xffff8080, RD_C2, 0, AL }, +{"vsat1.s", "?d0z,?s0s", 0xd0050000, 0xffff8080, RD_C2, 0, AL }, +{"vzero.s", "?d0d", 0xd0060000, 0xffffff80, RD_C2, 0, AL }, +{"vone.s", "?d0d", 0xd0070000, 0xffffff80, RD_C2, 0, AL }, +{"vrcp.s", "?x0d,?s0s", 0xd0100000, 0xffff8080, RD_C2, 0, AL }, +{"vrsq.s", "?x0d,?s0s", 0xd0110000, 0xffff8080, RD_C2, 0, AL }, +{"vsin.s", "?x0d,?s0s", 0xd0120000, 0xffff8080, RD_C2, 0, AL }, +{"vcos.s", "?x0d,?s0s", 0xd0130000, 0xffff8080, RD_C2, 0, AL }, +{"vexp2.s", "?x0d,?s0s", 0xd0140000, 0xffff8080, RD_C2, 0, AL }, +{"vlog2.s", "?x0d,?s0s", 0xd0150000, 0xffff8080, RD_C2, 0, AL }, +{"vsqrt.s", "?x0d,?s0s", 0xd0160000, 0xffff8080, RD_C2, 0, AL }, +{"vasin.s", "?x0d,?s0s", 0xd0170000, 0xffff8080, RD_C2, 0, AL }, +{"vnrcp.s", "?x0d,?s0y", 0xd0180000, 0xffff8080, RD_C2, 0, AL }, +{"vnsin.s", "?x0d,?s0y", 0xd01a0000, 0xffff8080, RD_C2, 0, AL }, +{"vrexp2.s", "?x0d,?s0y", 0xd01c0000, 0xffff8080, RD_C2, 0, AL }, +{"vrnds.s", "?s0y", 0xd0200000, 0xffff80ff, RD_C2, 0, AL }, +{"vrndi.s", "?d0d", 0xd0210000, 0xffffff80, RD_C2, 0, AL }, +{"vrndf1.s", "?d0d", 0xd0220000, 0xffffff80, RD_C2, 0, AL }, +{"vrndf2.s", "?d0d", 0xd0230000, 0xffffff80, RD_C2, 0, AL }, +{"vh2f.s", "?d1d,?s0y", 0xd0330000, 0xffff8080, RD_C2, 0, AL }, +{"vsbz.s", "?d0d,?s0s", 0xd0360000, 0xffff8080, RD_C2, 0, AL }, +{"vsbn.s", "?d0d,?s0s,?t0t", 0x61000000, 0xff808080, RD_C2, 0, AL }, +{"vlgb.s", "?d0d,?s0s", 0xd0370000, 0xffff8080, RD_C2, 0, AL }, +{"vocp.s", "?d0d,?s0y", 0xd0440000, 0xffff8080, RD_C2, 0, AL }, +{"vsocp.s", "?d1z,?s0y", 0xd0450000, 0xffff8080, RD_C2, 0, AL }, +{"vf2in.s", "?d0m,?s0s,?b", 0xd2000000, 0xffe08080, RD_C2, 0, AL }, +{"vf2iz.s", "?d0m,?s0s,?b", 0xd2200000, 0xffe08080, RD_C2, 0, AL }, +{"vf2iu.s", "?d0m,?s0s,?b", 0xd2400000, 0xffe08080, RD_C2, 0, AL }, +{"vf2id.s", "?d0m,?s0s,?b", 0xd2600000, 0xffe08080, RD_C2, 0, AL }, +{"vi2f.s", "?d0d,?s0w,?b", 0xd2800000, 0xffe08080, RD_C2, 0, AL }, +{"vcmov.s", "?d0d,?s0s,?e", 0, (int) M_VCMOV_S, INSN_MACRO, 0, AL }, +{"vcmovt.s", "?d0d,?s0s,?e", 0xd2a00000, 0xfff88080, RD_C2, 0, AL }, +{"vcmovf.s", "?d0d,?s0s,?e", 0xd2a80000, 0xfff88080, RD_C2, 0, AL }, +{"vwbn.s", "?d0d,?s0s,?i", 0xd3000000, 0xff008080, RD_C2, 0, AL }, +{"vpfxs", "?0,?1,?2,?3", 0xdc000000, 0xff000000, RD_C2, 0, AL }, +{"vpfxt", "?0,?1,?2,?3", 0xdd000000, 0xff000000, RD_C2, 0, AL }, +{"vpfxd", "?4,?5,?6,?7", 0xde000000, 0xff000000, RD_C2, 0, AL }, +{"viim.s", "?t0d,j", 0xdf000000, 0xff800000, RD_C2, 0, AL }, +{"vfim.s", "?t0d,?u", 0xdf800000, 0xff800000, RD_C2, 0, AL }, +{"vnop", "", 0xffff0000, 0xffffffff, RD_C2, 0, AL }, +{"vflush", "", 0xffff040d, 0xffffffff, RD_C2, 0, AL }, +{"vsync", "", 0xffff0320, 0xffffffff, RD_C2, 0, AL }, +{"vsync", "i", 0xffff0000, 0xffff0000, RD_C2, 0, AL }, + /* 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 }, @@ -1606,6 +1913,36 @@ {"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33 }, {"mthc2", "t,i", 0x48e00000, 0xffe00000, COD|RD_t|WR_C2|WR_CC, 0, I33 }, +/* Coprocessor 2 load/store operations overlap with the Allegrex VFPU + instructions so they are here for the latters to take precedence. */ +/* COP1 ldc1 and sdc1 and COP3 ldc3 and sdc3 also overlap with the VFPU. */ +{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, +{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, +{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, +{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, +{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, /* ldc1 */ +{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, 0, I1 }, +{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, 0, I1 }, +{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, +{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, 0, I2 }, +{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, +{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, 0, I2 }, +{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, +{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, 0, I1 }, +{"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, +{"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, +{"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, 0, I2 }, +{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, 0, I2 }, +{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, +{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, 0, I1 }, +{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, 0, I1 }, +{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I2 }, +{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, 0, I2 }, +{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, 0, I2 }, +{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, 0, I2 }, +{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I1 }, +{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, 0, I1 }, + /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X instructions, so they are here for the latters to take precedence. */ {"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1 }, @@ -1643,7 +1980,6 @@ {"addu_s.ob", "d,s,t", 0x7c000114, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, {"addu_s.qb", "d,s,t", 0x7c000110, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, {"addwc", "d,s,t", 0x7c000450, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, {"bposge32", "p", 0x041c0000, 0xffff0000, CBD, 0, D32 }, {"bposge64", "p", 0x041d0000, 0xffff0000, CBD, 0, D64 }, {"cmp.eq.ph", "s,t", 0x7c000211, 0xfc00ffff, RD_s|RD_t, 0, D32 },