for homebrew PSP development. WWW: http://www.ps2dev.org PR: ports/132323, ports/132324, ports/132325, ports/132326 ports/132327, ports/132328, ports/132329, ports/132330 Submitted by: Tassilo Philipp <tphilipp@potion-studios.com>
557 lines
18 KiB
C
557 lines
18 KiB
C
--- opcodes/mips-dis.c.orig 2005-09-06 19:46:57.000000000 +0100
|
|
+++ opcodes/mips-dis.c 2007-02-08 20:06:04.000000000 +0000
|
|
@@ -133,6 +133,139 @@
|
|
"c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
|
|
};
|
|
|
|
+static const char * const vfpu_sreg_names[128] = {
|
|
+ "S000", "S010", "S020", "S030", "S100", "S110", "S120", "S130",
|
|
+ "S200", "S210", "S220", "S230", "S300", "S310", "S320", "S330",
|
|
+ "S400", "S410", "S420", "S430", "S500", "S510", "S520", "S530",
|
|
+ "S600", "S610", "S620", "S630", "S700", "S710", "S720", "S730",
|
|
+ "S001", "S011", "S021", "S031", "S101", "S111", "S121", "S131",
|
|
+ "S201", "S211", "S221", "S231", "S301", "S311", "S321", "S331",
|
|
+ "S401", "S411", "S421", "S431", "S501", "S511", "S521", "S531",
|
|
+ "S601", "S611", "S621", "S631", "S701", "S711", "S721", "S731",
|
|
+ "S002", "S012", "S022", "S032", "S102", "S112", "S122", "S132",
|
|
+ "S202", "S212", "S222", "S232", "S302", "S312", "S322", "S332",
|
|
+ "S402", "S412", "S422", "S432", "S502", "S512", "S522", "S532",
|
|
+ "S602", "S612", "S622", "S632", "S702", "S712", "S722", "S732",
|
|
+ "S003", "S013", "S023", "S033", "S103", "S113", "S123", "S133",
|
|
+ "S203", "S213", "S223", "S233", "S303", "S313", "S323", "S333",
|
|
+ "S403", "S413", "S423", "S433", "S503", "S513", "S523", "S533",
|
|
+ "S603", "S613", "S623", "S633", "S703", "S713", "S723", "S733"
|
|
+};
|
|
+
|
|
+static const char * const vfpu_vpreg_names[128] = {
|
|
+ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130",
|
|
+ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330",
|
|
+ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530",
|
|
+ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730",
|
|
+ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103",
|
|
+ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303",
|
|
+ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503",
|
|
+ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703",
|
|
+ "C002", "C012", "C022", "C032", "C102", "C112", "C122", "C132",
|
|
+ "C202", "C212", "C222", "C232", "C302", "C312", "C322", "C332",
|
|
+ "C402", "C412", "C422", "C432", "C502", "C512", "C522", "C532",
|
|
+ "C602", "C612", "C622", "C632", "C702", "C712", "C722", "C732",
|
|
+ "R020", "R021", "R022", "R023", "R120", "R121", "R122", "R123",
|
|
+ "R220", "R221", "R222", "R223", "R320", "R321", "R322", "R323",
|
|
+ "R420", "R421", "R422", "R423", "R520", "R521", "R522", "R523",
|
|
+ "R620", "R621", "R622", "R623", "R720", "R721", "R722", "R723"
|
|
+};
|
|
+
|
|
+static const char * const vfpu_vtreg_names[128] = {
|
|
+ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130",
|
|
+ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330",
|
|
+ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530",
|
|
+ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730",
|
|
+ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103",
|
|
+ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303",
|
|
+ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503",
|
|
+ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703",
|
|
+ "C001", "C011", "C021", "C031", "C101", "C111", "C121", "C131",
|
|
+ "C201", "C211", "C221", "C231", "C301", "C311", "C321", "C331",
|
|
+ "C401", "C411", "C421", "C431", "C501", "C511", "C521", "C531",
|
|
+ "C601", "C611", "C621", "C631", "C701", "C711", "C721", "C731",
|
|
+ "R010", "R011", "R012", "R013", "R110", "R111", "R112", "R113",
|
|
+ "R210", "R211", "R212", "R213", "R310", "R311", "R312", "R313",
|
|
+ "R410", "R411", "R412", "R413", "R510", "R511", "R512", "R513",
|
|
+ "R610", "R611", "R612", "R613", "R710", "R711", "R712", "R713"
|
|
+};
|
|
+
|
|
+static const char * const vfpu_vqreg_names[128] = {
|
|
+ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130",
|
|
+ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330",
|
|
+ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530",
|
|
+ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730",
|
|
+ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103",
|
|
+ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303",
|
|
+ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503",
|
|
+ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", ""
|
|
+};
|
|
+
|
|
+static const char * const vfpu_mpreg_names[128] = {
|
|
+ "M000", "", "M020", "", "M100", "", "M120", "",
|
|
+ "M200", "", "M220", "", "M300", "", "M320", "",
|
|
+ "M400", "", "M420", "", "M500", "", "M520", "",
|
|
+ "M600", "", "M620", "", "M700", "", "M720", "",
|
|
+ "E000", "", "E002", "", "E100", "", "E102", "",
|
|
+ "E200", "", "E202", "", "E300", "", "E302", "",
|
|
+ "E400", "", "E402", "", "E500", "", "E502", "",
|
|
+ "E600", "", "E602", "", "E700", "", "E702", "",
|
|
+ "M002", "", "M022", "", "M102", "", "M122", "",
|
|
+ "M202", "", "M222", "", "M302", "", "M322", "",
|
|
+ "M402", "", "M422", "", "M502", "", "M522", "",
|
|
+ "M602", "", "M622", "", "M702", "", "M722", "",
|
|
+ "E020", "", "E022", "", "E120", "", "E122", "",
|
|
+ "E220", "", "E222", "", "E320", "", "E322", "",
|
|
+ "E420", "", "E422", "", "E520", "", "E522", "",
|
|
+ "E620", "", "E622", "", "E720", "", "E722", ""
|
|
+};
|
|
+
|
|
+static const char * const vfpu_mtreg_names[128] = {
|
|
+ "M000", "M010", "", "", "M100", "M110", "", "",
|
|
+ "M200", "M210", "", "", "M300", "M310", "", "",
|
|
+ "M400", "M410", "", "", "M500", "M510", "", "",
|
|
+ "M600", "M610", "", "", "M700", "M710", "", "",
|
|
+ "E000", "E001", "", "", "E100", "E101", "", "",
|
|
+ "E200", "E201", "", "", "E300", "E301", "", "",
|
|
+ "E400", "E401", "", "", "E500", "E501", "", "",
|
|
+ "E600", "E601", "", "", "E700", "E701", "", "",
|
|
+ "M001", "M011", "", "", "M101", "M111", "", "",
|
|
+ "M201", "M211", "", "", "M301", "M311", "", "",
|
|
+ "M401", "M411", "", "", "M501", "M511", "", "",
|
|
+ "M601", "M611", "", "", "M701", "M711", "", "",
|
|
+ "E010", "E011", "", "", "E110", "E111", "", "",
|
|
+ "E210", "E211", "", "", "E310", "E311", "", "",
|
|
+ "E410", "E411", "", "", "E510", "E511", "", "",
|
|
+ "E610", "E611", "", "", "E710", "E711", "", ""
|
|
+};
|
|
+
|
|
+static const char * const vfpu_mqreg_names[128] = {
|
|
+ "M000", "", "", "", "M100", "", "", "",
|
|
+ "M200", "", "", "", "M300", "", "", "",
|
|
+ "M400", "", "", "", "M500", "", "", "",
|
|
+ "M600", "", "", "", "M700", "", "", "",
|
|
+ "E000", "", "", "", "E100", "", "", "",
|
|
+ "E200", "", "", "", "E300", "", "", "",
|
|
+ "E400", "", "", "", "E500", "", "", "",
|
|
+ "E600", "", "", "", "E700", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", "",
|
|
+ "", "", "", "", "", "", "", ""
|
|
+};
|
|
+
|
|
static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
|
|
{
|
|
{ 16, 1, "c0_config1" },
|
|
@@ -288,6 +421,55 @@
|
|
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
|
|
};
|
|
|
|
+static const char * const vfpu_cond_names[16] = {
|
|
+ "FL", "EQ", "LT", "LE", "TR", "NE", "GE", "GT",
|
|
+ "EZ", "EN", "EI", "ES", "NZ", "NN", "NI", "NS"
|
|
+};
|
|
+
|
|
+static const char * const vfpu_const_names[20] = {
|
|
+ "",
|
|
+ "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"
|
|
+};
|
|
+
|
|
+#define VFPU_NUM_CONSTANTS \
|
|
+ ((sizeof vfpu_const_names) / (sizeof (vfpu_const_names[0])))
|
|
+const unsigned int vfpu_num_constants = VFPU_NUM_CONSTANTS;
|
|
+
|
|
+static const char * const vfpu_rwb_names[4] = {
|
|
+ "wt", "wb", "", ""
|
|
+};
|
|
+
|
|
+static const char * const pfx_cst_names[8] = {
|
|
+ "0", "1", "2", "1/2", "3", "1/3", "1/4", "1/6"
|
|
+};
|
|
+
|
|
+static const char * const pfx_swz_names[4] = {
|
|
+ "x", "y", "z", "w"
|
|
+};
|
|
+
|
|
+static const char * const pfx_sat_names[4] = {
|
|
+ "", "[0:1]", "", "[-1:1]"
|
|
+};
|
|
+
|
|
+
|
|
struct mips_abi_choice
|
|
{
|
|
const char * name;
|
|
@@ -363,6 +545,8 @@
|
|
mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
|
|
{ "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
|
|
mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
|
|
+ { "allegrex", 1, bfd_mach_mips_allegrex, CPU_ALLEGREX, ISA_MIPS2,
|
|
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
|
|
|
|
/* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
|
|
Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
|
|
@@ -1147,6 +1331,349 @@
|
|
(l >> 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_MASK_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, "%ld",
|
|
+ (l >> OP_SH_VFPU_IMM5) & OP_MASK_VFPU_IMM5);
|
|
+ break;
|
|
+
|
|
+ case 'c':
|
|
+ /* VFPU condition code. */
|
|
+ (*info->fprintf_func) (info->stream, "%ld",
|
|
+ (l >> OP_SH_VFPU_CC) & OP_MASK_VFPU_CC);
|
|
+ break;
|
|
+
|
|
+ case 'e':
|
|
+ /* 3-bit immediate value. */
|
|
+ (*info->fprintf_func) (info->stream, "%ld",
|
|
+ (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%02lx",
|
|
+ (l >> OP_SH_VFPU_IMM8) & OP_MASK_VFPU_IMM8);
|
|
+ break;
|
|
+
|
|
+ case 'q':
|
|
+ /* VFPU control register (vmtvc). */
|
|
+ (*info->fprintf_func) (info->stream, "$%ld",
|
|
+ (l >> OP_SH_VFPU_VMTVC) & OP_MASK_VFPU_VMTVC);
|
|
+ break;
|
|
+
|
|
+ case 'r':
|
|
+ /* VFPU control register (vmfvc). */
|
|
+ (*info->fprintf_func) (info->stream, "$%ld",
|
|
+ (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,
|