Vector registers are named differently depending on their size (1, 2, 3 or 4 elements). They can also be grouped as rows or columns (R vs C). Register suffixes are optional and help indicating the register size.
Signed-off-by: David Guillen Fandos <[email protected]> --- gas/config/tc-mips.c | 191 ++++++++++++++++++++++++- gas/testsuite/gas/mips/allegrex-vfpu.d | 51 +++++++ gas/testsuite/gas/mips/allegrex-vfpu.s | 52 +++++++ include/opcode/mips.h | 28 ++++ opcodes/mips-dis.c | 57 ++++++++ opcodes/mips-formats.h | 11 ++ opcodes/mips-opc.c | 60 ++++++++ 7 files changed, 445 insertions(+), 5 deletions(-) diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 4440fb7cafb..f46d81ecfa2 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -3116,6 +3116,16 @@ struct regname { {"$ac2", RTYPE_ACC | 2}, \ {"$ac3", RTYPE_ACC | 3} +/* Register shapes for VFPU registers. */ +enum mips_vfpu_reg_shape { + /* A vector register, number of elements from 1 to 4. */ + VFPU_REG_SHAPE_VECTOR_1, + VFPU_REG_SHAPE_VECTOR_2, + VFPU_REG_SHAPE_VECTOR_3, + VFPU_REG_SHAPE_VECTOR_4, + VFPU_REG_SHAPE_VECTOR_UNKNOWN +}; + static const struct regname reg_names[] = { GENERIC_REGISTER_NUMBERS, FPU_REGISTER_NAMES, @@ -3314,6 +3324,108 @@ mips_parse_vu0_channels (char *s, unsigned int *channels) return s; } +/* Try to parse a VFPU register and fill its shape (if specified). */ +static bool +mips_vfpu_parse_register (char **sptr, unsigned int *regval, + enum mips_vfpu_reg_shape *regshape) +{ + char *s = *sptr; + char regtype = TOLOWER(*s++); + unsigned int suffix = 0; + unsigned int m, c, r; + + static const enum mips_vfpu_reg_shape vecsz[] = { + VFPU_REG_SHAPE_VECTOR_UNKNOWN, + VFPU_REG_SHAPE_VECTOR_1, VFPU_REG_SHAPE_VECTOR_2, + VFPU_REG_SHAPE_VECTOR_3, VFPU_REG_SHAPE_VECTOR_4 + }; + + if (s[0] < '0' || s[0] > '7' || + s[1] < '0' || s[1] > '3' || + s[2] < '0' || s[2] > '3') + return false; + + m = *s++ - '0'; + c = *s++ - '0'; + r = *s++ - '0'; + + /* Try to parse suffix (.s/.p/.t/.q). */ + if (*s == '.') { + s++; + switch (*s++) { + case 's': suffix = 1; break; + case 'p': suffix = 2; break; + case 't': suffix = 3; break; + case 'q': suffix = 4; break; + default: + return false; + }; + } + + if ((regtype == 's' && suffix > 1) || + (regtype != 's' && suffix == 1)) + return false; + + switch (regtype) { + case 's': + *regval = c + m * 4 + r * 32; + *regshape = VFPU_REG_SHAPE_VECTOR_1; + break; + + case 'c': + switch (r) { + case 0: + *regval = c + m * 4; + *regshape = vecsz[suffix]; + break; + case 1: + if (suffix && suffix != 3) + return false; + *regval = c + m * 4 + 64; + *regshape = VFPU_REG_SHAPE_VECTOR_3; + break; + case 2: + if (suffix && suffix != 2) + return false; + *regval = c + m * 4 + 64; + *regshape = VFPU_REG_SHAPE_VECTOR_2; + break; + default: + return false; + }; + break; + + case 'r': + switch (c) { + case 0: + *regval = r + m * 4 + 32; + *regshape = vecsz[suffix]; + break; + case 1: + if (suffix && suffix != 3) + return false; + *regval = r + m * 4 + 96; + *regshape = VFPU_REG_SHAPE_VECTOR_3; + break; + case 2: + if (suffix && suffix != 2) + return false; + *regval = r + m * 4 + 96; + *regshape = VFPU_REG_SHAPE_VECTOR_2; + break; + default: + return false; + }; + break; + + default: + return false; + }; + + *sptr = s; + return true; +} + /* Token types for parsed operand lists. */ enum mips_operand_token_type { /* A plain register, e.g. $f2. */ @@ -3331,6 +3443,9 @@ enum mips_operand_token_type { /* A continuous range of registers, e.g. $s0-$s4. */ OT_REG_RANGE, + /* A VFPU register, eg. S000.s. */ + OT_REG_VFPU, + /* A (possibly relocated) expression. */ OT_INTEGER, @@ -3370,6 +3485,12 @@ struct mips_operand_token unsigned int regno2; } reg_range; + /* The register symbol value for an OT_REG_VFPU and its shape. */ + struct { + unsigned int regno; + enum mips_vfpu_reg_shape shape; + } reg_vfpu; + /* The value of an OT_INTEGER. The value is represented as an expression and the relocation operators that were applied to that expression. The reloc entries are BFD_RELOC_UNUSED if no @@ -3471,7 +3592,8 @@ mips_parse_base_start (char *s) mips_parse_arguments. */ static char * -mips_parse_argument_token (char *s, char float_format) +mips_parse_argument_token (char *s, char float_format, + const struct mips_opcode *mo) { char *end, *save_in; const char *err; @@ -3493,6 +3615,15 @@ mips_parse_argument_token (char *s, char float_format) return s; } + /* Handle VFPU registers. */ + if ((mo->membership & INSN_ALLEGREX) + && mips_vfpu_parse_register (&s, ®no1, &token.u.reg_vfpu.shape)) + { + token.u.reg_vfpu.regno = regno1; + mips_add_token (&token, OT_REG_VFPU); + return s; + } + /* Handle tokens that start with a register. */ if (mips_parse_register (&s, ®no1, &channels)) { @@ -3601,14 +3732,14 @@ mips_parse_argument_token (char *s, char float_format) must obstack_free the list after use. */ static struct mips_operand_token * -mips_parse_arguments (char *s, char float_format) +mips_parse_arguments (char *s, char float_format, const struct mips_opcode *mo) { struct mips_operand_token token; SKIP_SPACE_TABS (s); while (*s) { - s = mips_parse_argument_token (s, float_format); + s = mips_parse_argument_token (s, float_format, mo); if (!s) { obstack_free (&mips_operand_tokens, @@ -3830,6 +3961,9 @@ validate_mips_insn (const struct mips_opcode *opcode, /* Skip prefix characters. */ if (decode_operand && (*s == '+' || *s == 'm' || *s == '-')) ++s; + if (decode_operand && (*s == '?')) + s += 2; + opno += 1; break; } @@ -4964,6 +5098,7 @@ operand_reg_mask (const struct mips_cl_insn *insn, case OP_PC: case OP_VU0_SUFFIX: case OP_VU0_MATCH_SUFFIX: + case OP_VFPU_REG: case OP_IMM_INDEX: abort (); @@ -6548,6 +6683,47 @@ match_vu0_suffix_operand (struct mips_arg_info *arg, return true; } +/* Matches VFPU register operands. */ +static bfd_boolean +match_vfpu_reg_operand (struct mips_arg_info *arg, + const struct mips_operand *operand) +{ + const struct mips_vfpu_reg_operand *regvfpuop; + enum mips_vfpu_reg_shape rshape; + unsigned int uval = arg->token->u.reg_vfpu.regno; + + /* Validate register type, to ensure we use the right register prefix */ + static const struct { + enum mips_vfpu_reg_shape gen, spc; + const char *errmsg; + } val_shap[] = { + { VFPU_REG_SHAPE_VECTOR_1, VFPU_REG_SHAPE_VECTOR_1, "single" }, + { VFPU_REG_SHAPE_VECTOR_UNKNOWN, VFPU_REG_SHAPE_VECTOR_2, "pair" }, + { VFPU_REG_SHAPE_VECTOR_UNKNOWN, VFPU_REG_SHAPE_VECTOR_3, "triple" }, + { VFPU_REG_SHAPE_VECTOR_UNKNOWN, VFPU_REG_SHAPE_VECTOR_4, "quad" }, + }; + + if (arg->token->type != OT_REG_VFPU || uval >= 128) + return false; + + rshape = arg->token->u.reg_vfpu.shape; + regvfpuop = (struct mips_vfpu_reg_operand*)operand; + + if (rshape != val_shap[regvfpuop->rsize].gen && + rshape != val_shap[regvfpuop->rsize].spc) + { + set_insn_error_ss(arg->argnum, + "Invalid VFPU register size: a %s %s is required", + val_shap[regvfpuop->rsize].errmsg, "register"); + return false; + } + + insn_insert_operand (arg->insn, operand, uval); + + ++arg->token; + return true; +} + /* Try to match a token from ARG against OPERAND. Consume the token and return true on success, otherwise return false. */ @@ -6615,6 +6791,9 @@ match_operand (struct mips_arg_info *arg, case OP_VU0_MATCH_SUFFIX: return match_vu0_suffix_operand (arg, operand, true); + case OP_VFPU_REG: + return match_vfpu_reg_operand (arg, operand); + case OP_IMM_INDEX: return match_imm_index_operand (arg, operand); @@ -8775,6 +8954,8 @@ match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode, /* Skip prefixes. */ if (*args == '+' || *args == 'm' || *args == '-') args++; + if (*args == '?') + args += 2; if (mips_optional_operand_p (operand) && args[1] == ',' @@ -14665,7 +14846,7 @@ mips_ip (char *str, struct mips_cl_insn *insn) format = 'd'; else format = 0; - tokens = mips_parse_arguments (str + end, format); + tokens = mips_parse_arguments (str + end, format, first); if (!tokens) return; @@ -14727,7 +14908,7 @@ mips16_ip (char *str, struct mips_cl_insn *insn) return; } - tokens = mips_parse_arguments (s, 0); + tokens = mips_parse_arguments (s, 0, first); if (!tokens) return; diff --git a/gas/testsuite/gas/mips/allegrex-vfpu.d b/gas/testsuite/gas/mips/allegrex-vfpu.d index be6554c825e..e5fb8e13595 100644 --- a/gas/testsuite/gas/mips/allegrex-vfpu.d +++ b/gas/testsuite/gas/mips/allegrex-vfpu.d @@ -12,4 +12,55 @@ Disassembly of section .text: 0x0000000c ffff007b vsync 0x7b 0x00000010 ffff0320 vsync 0x00000014 ffff040d vflush +0x00000018 606b3f00 vadd.s S000.s,S731.s,S233.s +0x0000001c 605858f8 vadd.p R620.p,C602.p,C602.p +0x00000020 6058d878 vadd.t R610.t,C601.t,C601.t +0x00000024 600484a0 vadd.q R000.q,C100.q,C100.q +0x00000028 d0474c8e vavg.p S320.s,C302.p +0x0000002c d047cc0d vavg.t S310.s,C301.t +0x00000030 d0478480 vavg.q S000.s,C100.q +0x00000034 64a808ab vdot.p S231.s,C200.p,R200.p +0x00000038 64a88869 vdot.t S213.s,C200.t,R200.t +0x0000003c 64a888eb vdot.q S233.s,C200.q,R200.q +0x00000040 d04660ff vfad.p S733.s,R020.p +0x00000044 d046e07e vfad.t S723.s,R010.t +0x00000048 d046a0df vfad.q S732.s,R000.q +0x0000004c d00300e4 vidt.p R120.p +0x00000050 d0038084 vidt.q C100.q +0x00000054 6da10120 vmax.s S001.s,S010.s,S011.s +0x00000058 6df5758e vmax.p C320.p,R521.p,R521.p +0x0000005c 6df5b50d vmax.t C310.t,R501.t,R511.t +0x00000060 6db5b58d vmax.q C310.q,R501.q,R501.q +0x00000064 6d210120 vmin.s S001.s,S010.s,S011.s +0x00000068 6d697986 vmin.p C120.p,R621.p,R221.p +0x0000006c 6d69b905 vmin.t C110.t,R601.t,R211.t +0x00000070 6d29b985 vmin.q C110.q,R601.q,R201.q +0x00000074 d0002401 vmov.s S010.s,S101.s +0x00000078 d00025c1 vmov.p C012.p,R101.p +0x0000007c d000a541 vmov.t C011.t,R101.t +0x00000080 d000a581 vmov.q C010.q,R101.q +0x00000084 644a0240 vmul.s S002.s,S020.s,S222.s +0x00000088 642408a8 vmul.p R200.p,C200.p,R100.p +0x0000008c 64248828 vmul.t R200.t,C200.t,R100.t +0x00000090 642488a8 vmul.q R200.q,C200.q,R100.q +0x00000094 6f424002 vsge.s S020.s,S002.s,S022.s +0x00000098 6f252581 vsge.p C010.p,R101.p,R101.p +0x0000009c 6f25a501 vsge.t C010.t,R101.t,R101.t +0x000000a0 6f25a581 vsge.q C010.q,R101.q,R101.q +0x000000a4 d04a4002 vsgn.s S020.s,S002.s +0x000000a8 d04a2581 vsgn.p C010.p,R101.p +0x000000ac d04aa501 vsgn.t C010.t,R101.t +0x000000b0 d04aa581 vsgn.q C010.q,R101.q +0x000000b4 6fc24002 vslt.s S020.s,S002.s,S022.s +0x000000b8 6fa52581 vslt.p C010.p,R101.p,R101.p +0x000000bc 6fa5a501 vslt.t C010.t,R101.t,R101.t +0x000000c0 6fa5a581 vslt.q C010.q,R101.q,R101.q +0x000000c4 60e73f00 vsub.s S000.s,S731.s,S133.s +0x000000c8 60c458f8 vsub.p R620.p,C602.p,C102.p +0x000000cc 60ccd878 vsub.t R610.t,C601.t,C301.t +0x000000d0 608884a0 vsub.q R000.q,C100.q,C200.q +0x000000d4 d006006f vzero.s S333.s +0x000000d8 d00600e4 vzero.p R120.p +0x000000dc d0068028 vzero.t R200.t +0x000000e0 d00680a8 vzero.q R200.q \.\.\. diff --git a/gas/testsuite/gas/mips/allegrex-vfpu.s b/gas/testsuite/gas/mips/allegrex-vfpu.s index ca01c2b3a47..7bbe5db61b9 100644 --- a/gas/testsuite/gas/mips/allegrex-vfpu.s +++ b/gas/testsuite/gas/mips/allegrex-vfpu.s @@ -8,6 +8,58 @@ vsync 800 vsync 1037 + vadd.s S000, S731, S233 + vadd.p R620, C602, C602 + vadd.t R610, C601, C601 + vadd.q R000, C100, C100 + vavg.p S320, C302 + vavg.t S310, C301 + vavg.q S000, C100 + vdot.p S231, C200, R200 + vdot.t S213, C200, R200 + vdot.q S233, C200, R200 + vfad.p S733, R020 + vfad.t S723, R010 + vfad.q S732, R000 + vidt.p R120.p + vidt.q C100.q + vmax.s S001, S010, S011 + vmax.p C320, R521, R521 + vmax.t C310, R501, R511 + vmax.q C310, R501, R501 + vmin.s S001, S010, S011 + vmin.p C120, R621, R221 + vmin.t C110, R601, R211 + vmin.q C110, R601, R201 + vmov.s S010, S101 + vmov.p C012, R101 + vmov.t C011, R101 + vmov.q C010, R101 + vmul.s S002, S020, S222 + vmul.p R200, C200, R100 + vmul.t R200, C200, R100 + vmul.q R200, C200, R100 + vsge.s S020, S002, S022 + vsge.p C010, R101, R101 + vsge.t C010, R101, R101 + vsge.q C010, R101, R101 + vsgn.s S020, S002 + vsgn.p C010, R101 + vsgn.t C010, R101 + vsgn.q C010, R101 + vslt.s S020, S002, S022 + vslt.p C010, R101, R101 + vslt.t C010, R101, R101 + vslt.q C010, R101, R101 + vsub.s S000, S731, S133 + vsub.p R620, C602, C102 + vsub.t R610, C601, C301 + vsub.q R000, C100, C200 + vzero.s S333 + vzero.p R120 + vzero.t R200 + vzero.q R200 + # Force some (non-delay-slot) zero bytes, to make 'objdump' print ... .align 4, 0 .space 16 diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 1edacd88499..7c177f6a283 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -168,6 +168,9 @@ enum mips_operand_type { been set. Any suffix used here must match the previous value. */ OP_VU0_MATCH_SUFFIX, + /* A VFPU register. */ + OP_VFPU_REG, + /* An index selected by an integer, e.g. [1]. */ OP_IMM_INDEX, @@ -236,6 +239,17 @@ enum mips_reg_operand_type { OP_REG_MSA_CTRL }; +/* Enumerates the types of VFPU register. */ +enum mips_vfpu_reg_type { + /* Source registers. */ + OP_VFPU_REG_S, + OP_VFPU_REG_T, + + /* Destination registers. */ + OP_VFPU_REG_D +}; + + /* Base class for all operands. */ struct mips_operand { @@ -369,6 +383,20 @@ struct mips_pcrel_operand unsigned int flip_isa_bit : 1; }; +/* Describes a VFPU register, containing information on the addressed + register size as well as type. */ +struct mips_vfpu_reg_operand +{ + /* Encodes the offset. */ + struct mips_operand root; + + /* Register (sub)type. */ + enum mips_vfpu_reg_type regtype; + + /* Register access size. */ + unsigned int rsize; +}; + /* Return true if the assembly syntax allows OPERAND to be omitted. */ static inline bool diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index c0e3509a1ba..7ed84a952a4 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -1334,6 +1334,54 @@ print_vu0_channel (struct disassemble_info *info, abort (); } +/* Print OP_VFPU_REG operand OPERAND, whose value is given by UVAL. */ +static void +print_vfpu_reg (struct disassemble_info *info, + const struct mips_operand *operand, unsigned int uval) +{ + const fprintf_styled_ftype infprintf = info->fprintf_styled_func; + void *is = info->stream; + const struct mips_vfpu_reg_operand *vfpureg_op; + + unsigned int rmtx = (uval >> 2) & 7; /* Matrix number. */ + unsigned int ridx = (uval >> 0) & 3; /* Register index. */ + unsigned int rffl = (uval >> 5) & 3; /* Register full field. */ + unsigned int rfsl = (uval >> 6) & 1; /* Register field. */ + unsigned int rrxc = (uval >> 5) & 1; /* Register direction. */ + + vfpureg_op = (const struct mips_vfpu_reg_operand *) operand; + + switch (vfpureg_op->rsize) { + case 0: + infprintf (is, dis_style_register, "S%u%u%u.s", rmtx, ridx, rffl); + break; + case 1: + if (rrxc) + infprintf (is, dis_style_register, "R%d%d%d.p", rmtx, rfsl << 1, ridx); + else + infprintf (is, dis_style_register, "C%d%d%d.p", rmtx, ridx, rfsl << 1); + break; + case 2: + if (rrxc) + infprintf (is, dis_style_register, "R%d%d%d.t", rmtx, rfsl, ridx); + else + infprintf (is, dis_style_register, "C%d%d%d.t", rmtx, ridx, rfsl); + break; + case 3: + if (uval >= 64) + infprintf (is, dis_style_register, "????.q"); + else + { + if (rrxc) + infprintf (is, dis_style_register, "R%d%d%d.q", rmtx, rfsl, ridx); + else + infprintf (is, dis_style_register, "C%d%d%d.q", rmtx, ridx, rfsl); + } + break; + } +} + + /* Record information about a register operand. */ static void @@ -1543,6 +1591,10 @@ print_insn_arg (struct disassemble_info *info, } break; + case OP_VFPU_REG: + print_vfpu_reg (info, operand, uval); + break; + case OP_PERF_REG: infprintf (is, dis_style_register, "%d", uval); break; @@ -1882,11 +1934,14 @@ validate_insn_args (const struct mips_opcode *opcode, case OP_IMM_INDEX: case OP_REG_INDEX: case OP_SAVE_RESTORE_LIST: + case OP_VFPU_REG: break; } } if (*s == 'm' || *s == '+' || *s == '-') ++s; + if (*s == '?') + s += 2; } } return true; @@ -2003,6 +2058,8 @@ print_insn_args (struct disassemble_info *info, } if (*s == 'm' || *s == '+' || *s == '-') ++s; + if (*s == '?') + s += 2; break; } } diff --git a/opcodes/mips-formats.h b/opcodes/mips-formats.h index aa90b2f085c..87d85e06dae 100644 --- a/opcodes/mips-formats.h +++ b/opcodes/mips-formats.h @@ -112,6 +112,17 @@ return &op.root; \ } +#define VFPU_REG(SIZE, LSB, REGTYPE, REGSIZE) \ + { \ + static const struct mips_vfpu_reg_operand op[] = { \ + { { OP_VFPU_REG, SIZE, LSB }, OP_VFPU_REG_##REGTYPE, 0 }, \ + { { OP_VFPU_REG, SIZE, LSB }, OP_VFPU_REG_##REGTYPE, 1 }, \ + { { OP_VFPU_REG, SIZE, LSB }, OP_VFPU_REG_##REGTYPE, 2 }, \ + { { OP_VFPU_REG, SIZE, LSB }, OP_VFPU_REG_##REGTYPE, 3 }, \ + }; \ + return &op[REGSIZE].root; \ + } + #define PCREL(SIZE, LSB, IS_SIGNED, SHIFT, ALIGN_LOG2, INCLUDE_ISA_BIT, \ FLIP_ISA_BIT) \ { \ diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c index 223fb89de19..f9341c94af9 100644 --- a/opcodes/mips-opc.c +++ b/opcodes/mips-opc.c @@ -142,6 +142,15 @@ decode_mips_operand (const char *p) } break; + case '?': + switch (p[1]) + { + case 'd': VFPU_REG(7, 0, D, p[2] - '0'); + case 's': VFPU_REG(7, 8, S, p[2] - '0'); + case 't': VFPU_REG(7, 16, T, p[2] - '0'); + } + break; + case '<': BIT (5, 6, 0); /* (0 .. 31) */ case '>': BIT (5, 6, 32); /* (32 .. 63) */ case '%': UINT (3, 21); @@ -668,9 +677,60 @@ const struct mips_opcode mips_builtin_opcodes[] = {"vnop", "", 0xffff0000, 0xffffffff, CP, 0, ALX, 0, 0 }, /* Allegrex VFPU coprocessor. Redefines coprocessor 2 and 3 (and other unused opcodes). */ +{"vadd.p", "?d1,?s1,?t1", 0x60000080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vadd.q", "?d3,?s3,?t3", 0x60008080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vadd.s", "?d0,?s0,?t0", 0x60000000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vadd.t", "?d2,?s2,?t2", 0x60008000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vavg.p", "?d0,?s1", 0xd0470080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vavg.q", "?d0,?s3", 0xd0478080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vavg.t", "?d0,?s2", 0xd0478000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vdot.p", "?d0,?s1,?t1", 0x64800080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vdot.q", "?d0,?s3,?t3", 0x64808080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vdot.t", "?d0,?s2,?t2", 0x64808000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vfad.p", "?d0,?s1", 0xd0460080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vfad.q", "?d0,?s3", 0xd0468080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vfad.t", "?d0,?s2", 0xd0468000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, {"vflush", "", 0xffff040d, 0xffffffff, CP, 0, ALX, 0, 0 }, +{"vidt.p", "?d1", 0xd0030080, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, +{"vidt.q", "?d3", 0xd0038080, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, +{"vmax.p", "?d1,?s1,?t1", 0x6d800080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmax.q", "?d3,?s3,?t3", 0x6d808080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmax.s", "?d0,?s0,?t0", 0x6d800000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmax.t", "?d2,?s2,?t2", 0x6d808000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmin.p", "?d1,?s1,?t1", 0x6d000080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmin.q", "?d3,?s3,?t3", 0x6d008080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmin.s", "?d0,?s0,?t0", 0x6d000000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmin.t", "?d2,?s2,?t2", 0x6d008000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmov.p", "?d1,?s1", 0xd0000080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmov.q", "?d3,?s3", 0xd0008080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmov.s", "?d0,?s0", 0xd0000000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmov.t", "?d2,?s2", 0xd0008000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmul.p", "?d1,?s1,?t1", 0x64000080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmul.q", "?d3,?s3,?t3", 0x64008080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmul.s", "?d0,?s0,?t0", 0x64000000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vmul.t", "?d2,?s2,?t2", 0x64008000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsge.p", "?d1,?s1,?t1", 0x6f000080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsge.q", "?d3,?s3,?t3", 0x6f008080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsge.s", "?d0,?s0,?t0", 0x6f000000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsge.t", "?d2,?s2,?t2", 0x6f008000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsgn.p", "?d1,?s1", 0xd04a0080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsgn.q", "?d3,?s3", 0xd04a8080, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsgn.s", "?d0,?s0", 0xd04a0000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsgn.t", "?d2,?s2", 0xd04a8000, 0xffff8080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vslt.p", "?d1,?s1,?t1", 0x6f800080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vslt.q", "?d3,?s3,?t3", 0x6f808080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vslt.s", "?d0,?s0,?t0", 0x6f800000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vslt.t", "?d2,?s2,?t2", 0x6f808000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsub.p", "?d1,?s1,?t1", 0x60800080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsub.q", "?d3,?s3,?t3", 0x60808080, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsub.s", "?d0,?s0,?t0", 0x60800000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, +{"vsub.t", "?d2,?s2,?t2", 0x60808000, 0xff808080, RD_C2|WR_C2, 0, ALX, 0, 0 }, {"vsync", "", 0xffff0320, 0xffffffff, CP, 0, ALX, 0, 0 }, {"vsync", "i", 0xffff0000, 0xffff0000, CP, 0, ALX, 0, 0 }, +{"vzero.p", "?d1", 0xd0060080, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, +{"vzero.q", "?d3", 0xd0068080, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, +{"vzero.s", "?d0", 0xd0060000, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, +{"vzero.t", "?d2", 0xd0068000, 0xffffff80, WR_C2, 0, ALX, 0, 0 }, {"abs", "d,v", 0, (int) M_ABS, INSN_MACRO, 0, I1, 0, 0 }, {"abs.s", "D,V", 0x46000005, 0xffff003f, WR_1|RD_2|FP_S, 0, I1, 0, 0 }, -- 2.51.1
