From: Stefan Weil <sw@weilnetz.de>
To: Jia Liu <proljc@gmail.com>
Cc: qemu-devel@nongnu.org, aurelien@aurel32.net
Subject: Re: [Qemu-devel] [PATCH 3/4] add MIPS DSP translation
Date: Wed, 21 Mar 2012 09:33:24 +0100 [thread overview]
Message-ID: <4F699254.6010402@weilnetz.de> (raw)
In-Reply-To: <1331541159-5218-4-git-send-email-proljc@gmail.com>
Please see my inline comments.
Regards,
Stefan Weil
Am 12.03.2012 09:32, schrieb Jia Liu:
> This patch is the translation of MIPS ASE DSP.
>
> Signed-off-by: Jia Liu<proljc@gmail.com>
> ---
> target-mips/translate.c | 1114 +++++++++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 1088 insertions(+), 26 deletions(-)
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 8361d88..1fa5b28 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -249,6 +249,11 @@ enum {
> OPC_SYNCI = (0x1F<< 16) | OPC_REGIMM,
> };
>
> +/* REGIMM mipsdsp opcodes */
> +enum {
> + OPC_BPOSGE32 = (0x1C<< 16) | OPC_REGIMM,
> +};
> +
> /* Special2 opcodes */
> #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op& 0x3F)
>
> @@ -312,6 +317,21 @@ enum {
> OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
> OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
> OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
> +
> + /* MIPS DSP */
> + OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
> + OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
> + /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
> + /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
> + OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
> + OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
> + OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
> + OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
> + OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
> + OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
> + /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
> + /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
> + OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
> };
>
> /* BSHFL opcodes */
> @@ -331,6 +351,231 @@ enum {
> OPC_DSHD = (0x05<< 6) | OPC_DBSHFL,
> };
>
> +#define MASK_ABSQ_S_PH(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_ABSQ_S_PH = (0x09<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_ABSQ_S_W = (0x11<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_BITREV = (0x1B<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQ_W_PHL = (0x0C<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQ_W_PHR = (0x0D<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQU_PH_QBL = (0x04<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQU_PH_QBLA = (0x06<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQU_PH_QBR = (0x05<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEQU_PH_QBRA = (0x07<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEU_PH_QBL = (0x1C<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEU_PH_QBLA = (0x1E<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEU_PH_QBR = (0x1D<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_PRECEU_PH_QBRA = (0x1F<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_REPL_PH = (0x0A<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_REPL_QB = (0x02<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_REPLV_PH = (0x0B<< 6) | OPC_ABSQ_S_PH_DSP,
> + OPC_REPLV_QB = (0x03<< 6) | OPC_ABSQ_S_PH_DSP,
> +};
> +
> +/* MIPS DSPR2 */
> +enum {
> + OPC_ABSQ_S_QB = (0x01<< 6) | OPC_ABSQ_S_PH_DSP,
> +};
> +
> +#define MASK_ADDU_QB(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_ADDQ_PH = (0x0A<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDQ_S_PH = (0x0E<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDQ_S_W = (0x16<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDSC = (0x10<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDU_QB = (0x00<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDU_S_QB = (0x04<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDWC = (0x11<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MODSUB = (0x12<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULEQ_S_W_PHL = (0x1C<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULEQ_S_W_PHR = (0x1D<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULEU_S_PH_QBL = (0x06<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULEU_S_PH_QBR = (0x07<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULQ_RS_PH = (0x1F<< 6) | OPC_ADDU_QB_DSP,
> + OPC_RADDU_W_QB = (0x14<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBQ_PH = (0x0B<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBQ_S_PH = (0x0F<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBQ_S_W = (0x17<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBU_QB = (0x01<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBU_S_QB = (0x05<< 6) | OPC_ADDU_QB_DSP,
> +};
> +
> +/* MIPS DSPR2 */
> +enum {
> + OPC_ADDU_PH = (0x08<< 6) | OPC_ADDU_QB_DSP,
> + OPC_ADDU_S_PH = (0x0C<< 6) | OPC_ADDU_QB_DSP,
> + OPC_MULQ_S_PH = (0x1E<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBU_PH = (0x09<< 6) | OPC_ADDU_QB_DSP,
> + OPC_SUBU_S_PH = (0x0D<< 6) | OPC_ADDU_QB_DSP,
> +};
> +
> +#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
> +#define MASK_ADDUH_QB(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSPR2 */
> +enum {
> + OPC_ADDQH_PH = (0x08<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_ADDQH_R_PH = (0x0A<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_ADDQH_W = (0x10<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_ADDQH_R_W = (0x12<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_ADDUH_QB = (0x00<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_ADDUH_R_QB = (0x02<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_MUL_PH = (0x0C<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_MUL_S_PH = (0x0E<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBQH_PH = (0x09<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBQH_R_PH = (0x0B<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBQH_W = (0x11<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBQH_R_W = (0x13<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBUH_QB = (0x01<< 6) | OPC_ADDUH_QB_DSP,
> + OPC_SUBUH_R_QB = (0x03<< 6) | OPC_ADDUH_QB_DSP,
> +};
> +
> +#define OPC_MUL_PH_DSP OPC_ADDUH_QB_DSP
> +/* #define MASK_MUL_PH(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6)) */
> +/* MIPS DSPR2 */
> +enum {
> + OPC_MULQ_RS_W = (0x17<< 6) | OPC_MUL_PH_DSP,
> + OPC_MULQ_S_W = (0x16<< 6) | OPC_MUL_PH_DSP,
> +};
> +
> +#define MASK_APPEND(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSPR2 */
> +enum {
> + OPC_APPEND = (0x00<< 6) | OPC_APPEND_DSP,
> + OPC_BALIGN = (0x10<< 6) | OPC_APPEND_DSP,
> + OPC_PREPEND = (0x01<< 6) | OPC_APPEND_DSP,
> +};
> +
> +#define MASK_CMPU_EQ_QB(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_CMP_EQ_PH = (0x08<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMP_LT_PH = (0x09<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMP_LE_PH = (0x0A<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPGU_EQ_QB = (0x04<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPGU_LT_QB = (0x05<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPGU_LE_QB = (0x06<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPU_EQ_QB = (0x00<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPU_LT_QB = (0x01<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPU_LE_QB = (0x02<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PACKRL_PH = (0x0E<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PICK_QB = (0x03<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PICK_PH = (0x0B<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECRQ_QB_PH = (0x0C<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECRQ_PH_W = (0x14<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECRQ_RS_PH_W = (0x15<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECRQU_S_QB_PH = (0x0F<< 6) | OPC_CMPU_EQ_QB_DSP,
> +};
> +
> +/* MIPS DSPR2 */
> +enum {
> + OPC_CMPGDU_EQ_QB = (0x18<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPGDU_LT_QB = (0x19<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_CMPGDU_LE_QB = (0x1A<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECR_QB_PH = (0x0D<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECR_SRA_PH_W = (0x1E<< 6) | OPC_CMPU_EQ_QB_DSP,
> + OPC_PRECR_SRA_R_PH_W = (0x1F<< 6) | OPC_CMPU_EQ_QB_DSP,
> +};
> +
> +#define MASK_DPA_W_PH(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_DPAQ_S_W_PH = (0x04<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAQ_SA_L_W = (0x0C<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAU_H_QBL = (0x03<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAU_H_QBR = (0x07<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSQ_S_W_PH = (0x05<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSQ_SA_L_W = (0x0D<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSU_H_QBL = (0x0B<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSU_H_QBR = (0x0F<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MAQ_S_W_PHL = (0x14<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MAQ_SA_W_PHL = (0x10<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MAQ_S_W_PHR = (0x16<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MAQ_SA_W_PHR = (0x12<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MULSAQ_S_W_PH = (0x06<< 6) | OPC_DPA_W_PH_DSP,
> +};
> +
> +/* MIPS DSPR2 */
> +enum{
> + OPC_DPA_W_PH = (0x00<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAQX_S_W_PH = (0x18<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAQX_SA_W_PH = (0x1A<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPAX_W_PH = (0x08<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPS_W_PH = (0x01<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSQX_S_W_PH = (0x19<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSQX_SA_W_PH = (0x1B<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_DPSX_W_PH = (0x09<< 6) | OPC_DPA_W_PH_DSP,
> + OPC_MULSA_W_PH = (0x02<< 6) | OPC_DPA_W_PH_DSP,
> +};
> +
> +#define MASK_EXTR_W(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_EXTP = (0x02<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTPDP = (0x0A<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTPDPV = (0x0B<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTPV = (0x03<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTR_S_H = (0x0E<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTR_W = (0x00<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTR_R_W = (0x04<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTR_RS_W = (0x06<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTRV_S_H = (0x0F<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTRV_W = (0x01<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTRV_R_W = (0x05<< 6) | OPC_EXTR_W_DSP,
> + OPC_EXTRV_RS_W = (0x07<< 6) | OPC_EXTR_W_DSP,
> + OPC_MTHLIP = (0x1F<< 6) | OPC_EXTR_W_DSP,
> + OPC_RDDSP = (0x12<< 6) | OPC_EXTR_W_DSP,
> + OPC_SHILO = (0x1A<< 6) | OPC_EXTR_W_DSP,
> + OPC_SHILOV = (0x1B<< 6) | OPC_EXTR_W_DSP,
> + OPC_WRDSP = (0x13<< 6) | OPC_EXTR_W_DSP,
> +};
> +
> +#define MASK_INSV(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_INSV = (0x00<< 6) | OPC_INSV_DSP,
> +};
> +
> +#define MASK_LX(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_LBUX = (0x06<< 6) | OPC_LX_DSP,
> + OPC_LHX = (0x04<< 6) | OPC_LX_DSP,
> + OPC_LWX = (0x00<< 6) | OPC_LX_DSP,
> +};
> +
> +#define MASK_SHLL_QB(op) MASK_SPECIAL3(op) | (op& (0x1F<< 6))
> +/* MIPS DSP */
> +enum {
> + OPC_SHLL_PH = (0x08<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLL_S_PH = (0x0C<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLL_QB = (0x00<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLL_S_W = (0x14<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLLV_PH = (0x0A<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLLV_S_PH = (0x0E<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLLV_QB = (0x02<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHLLV_S_W = (0x16<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRA_PH = (0x09<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRA_R_PH = (0x0D<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRA_R_W = (0x15<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRAV_PH = (0x0B<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRAV_R_PH = (0x0F<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRAV_R_W = (0x17<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRL_QB = (0x01<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRLV_QB = (0x03<< 6) | OPC_SHLL_QB_DSP,
> +};
> +
> +/* MIPS DSPR2 */
> +enum {
> + OPC_SHRA_QB = (0x04<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRA_R_QB = (0x05<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRAV_QB = (0x06<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRAV_R_QB = (0x07<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRL_PH = (0x19<< 6) | OPC_SHLL_QB_DSP,
> + OPC_SHRLV_PH = (0x1B<< 6) | OPC_SHLL_QB_DSP,
> +};
> +
> /* Coprocessor 0 (rs field) */
> #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op& (0x1F<< 21))
>
> @@ -1972,6 +2217,7 @@ static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
> static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
> {
> const char *opn = "hilo";
> + int acc = 0;
>
acc is an unsigned value, isn't it?
Is the initialization with 0 needed here?
>
> if (reg == 0&& (opc == OPC_MFHI || opc == OPC_MFLO)) {
> /* Treat as NOP. */
> @@ -1980,25 +2226,29 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
> }
> switch (opc) {
> case OPC_MFHI:
> - tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
> + acc = ((ctx->opcode)>> 21)& 0x03;
> + tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
> opn = "mfhi";
> break;
> case OPC_MFLO:
> - tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
> + acc = ((ctx->opcode)>> 21)& 0x03;
> + tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
> opn = "mflo";
> break;
> case OPC_MTHI:
> + acc = ((ctx->opcode)>> 11)& 0x03;
> if (reg != 0)
> - tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
> + tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
> else
> - tcg_gen_movi_tl(cpu_HI[0], 0);
> + tcg_gen_movi_tl(cpu_HI[acc], 0);
> opn = "mthi";
> break;
> case OPC_MTLO:
> + acc = ((ctx->opcode)>> 11)& 0x03;
> if (reg != 0)
> - tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
> + tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
> else
> - tcg_gen_movi_tl(cpu_LO[0], 0);
> + tcg_gen_movi_tl(cpu_LO[acc], 0);
> opn = "mtlo";
> break;
> }
> @@ -2011,6 +2261,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> const char *opn = "mul/div";
> TCGv t0, t1;
> + int acc = 0;
>
> switch (opc) {
> case OPC_DIV:
> @@ -2073,6 +2324,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode>> 11)& 0x03;
>
> tcg_gen_ext_tl_i64(t2, t0);
> tcg_gen_ext_tl_i64(t3, t1);
> @@ -2082,8 +2334,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> }
> opn = "mult";
> break;
> @@ -2091,6 +2343,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode>> 11)& 0x03;
>
> tcg_gen_ext32u_tl(t0, t0);
> tcg_gen_ext32u_tl(t1, t1);
> @@ -2102,9 +2355,9 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> - }
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> + }
> opn = "multu";
> break;
> #if defined(TARGET_MIPS64)
> @@ -2150,41 +2403,43 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode>> 11)& 0x03;
>
> tcg_gen_ext_tl_i64(t2, t0);
> tcg_gen_ext_tl_i64(t3, t1);
> tcg_gen_mul_i64(t2, t2, t3);
> - tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
> + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
> tcg_gen_add_i64(t2, t2, t3);
> tcg_temp_free_i64(t3);
> tcg_gen_trunc_i64_tl(t0, t2);
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> - }
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> + }
> opn = "madd";
> break;
> case OPC_MADDU:
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode)& 0x03;
>
> tcg_gen_ext32u_tl(t0, t0);
> tcg_gen_ext32u_tl(t1, t1);
> tcg_gen_extu_tl_i64(t2, t0);
> tcg_gen_extu_tl_i64(t3, t1);
> tcg_gen_mul_i64(t2, t2, t3);
> - tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
> + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
> tcg_gen_add_i64(t2, t2, t3);
> tcg_temp_free_i64(t3);
> tcg_gen_trunc_i64_tl(t0, t2);
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> }
> opn = "maddu";
> break;
> @@ -2192,19 +2447,20 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode>> 11)& 0x03;
>
> tcg_gen_ext_tl_i64(t2, t0);
> tcg_gen_ext_tl_i64(t3, t1);
> tcg_gen_mul_i64(t2, t2, t3);
> - tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
> + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
> tcg_gen_sub_i64(t2, t3, t2);
> tcg_temp_free_i64(t3);
> tcg_gen_trunc_i64_tl(t0, t2);
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> }
> opn = "msub";
> break;
> @@ -2212,21 +2468,22 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> {
> TCGv_i64 t2 = tcg_temp_new_i64();
> TCGv_i64 t3 = tcg_temp_new_i64();
> + acc = (ctx->opcode>> 11)& 0x03;
>
> tcg_gen_ext32u_tl(t0, t0);
> tcg_gen_ext32u_tl(t1, t1);
> tcg_gen_extu_tl_i64(t2, t0);
> tcg_gen_extu_tl_i64(t3, t1);
> tcg_gen_mul_i64(t2, t2, t3);
> - tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
> + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
> tcg_gen_sub_i64(t2, t3, t2);
> tcg_temp_free_i64(t3);
> tcg_gen_trunc_i64_tl(t0, t2);
> tcg_gen_shri_i64(t2, t2, 32);
> tcg_gen_trunc_i64_tl(t1, t2);
> tcg_temp_free_i64(t2);
> - tcg_gen_ext32s_tl(cpu_LO[0], t0);
> - tcg_gen_ext32s_tl(cpu_HI[0], t1);
> + tcg_gen_ext32s_tl(cpu_LO[acc], t0);
> + tcg_gen_ext32s_tl(cpu_HI[acc], t1);
> }
> opn = "msubu";
> break;
> @@ -2743,6 +3000,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
> }
> btgt = ctx->pc + insn_bytes + offset;
> break;
> + case OPC_BPOSGE32:
> + t0 = cpu_dspctrl;
> + tcg_gen_andi_i32(t0, t0, 0x3F);
> + bcond_compute = 1;
> + btgt = ctx->pc + insn_bytes + offset;
> + break;
> case OPC_J:
> case OPC_JAL:
> case OPC_JALX:
> @@ -2931,6 +3194,10 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
> tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
> MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
> goto likely;
> + case OPC_BPOSGE32:
> + tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 31);
> + MIPS_DEBUG("bposge32 %s, " TARGET_FMT_lx, t0, btgt);
> + goto not_likely;
> case OPC_BLTZALS:
> case OPC_BLTZAL:
> ctx->hflags |= (opc == OPC_BLTZALS
> @@ -11168,8 +11435,6 @@ static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
> *is_branch = 1;
> break;
> case BPOSGE64:
> - case BPOSGE32:
> - /* MIPS DSP: not implemented */
> /* Fall through */
> default:
> MIPS_INVAL("pool32i");
> @@ -12033,10 +12298,801 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
> break;
> case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
> case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
> + /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
> + * the same mask and op1. */
> + if(op1 == OPC_MULT_G_2E){
> + int is_mult_g_2e = 0;
> + op2 = MASK_ADDUH_QB(ctx->opcode);
> + switch(op2){
> + /* MIPS DSPR2 */
> + case OPC_ADDQH_PH:
> + gen_helper_addqhph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDQH_R_PH:
> + gen_helper_addqhrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDQH_W:
> + gen_helper_addqhw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDQH_R_W:
> + gen_helper_addqhrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDUH_QB:
> + gen_helper_adduhqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDUH_R_QB:
> + gen_helper_adduhrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MUL_PH:
> + gen_helper_mulph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MUL_S_PH:
> + gen_helper_mulsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQH_PH:
> + gen_helper_subqhph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQH_R_PH:
> + gen_helper_subqhrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQH_W:
> + gen_helper_subqhw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQH_R_W:
> + gen_helper_subqhrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBUH_QB:
> + gen_helper_subuhqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBUH_R_QB:
> + gen_helper_subuhrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + /* OPC_MUL_PH_DSP */
> + /* MIPS DSPR2 */
> + case OPC_MULQ_RS_W:
> + gen_helper_mulqrsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULQ_S_W:
> + gen_helper_mulqsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + default:
> + is_mult_g_2e = 1;
> + break;
> + }
> + if(0 == is_mult_g_2e)
> + break;
> + }
> case OPC_MOD_G_2E ... OPC_MODU_G_2E:
> check_insn(env, ctx, INSN_LOONGSON2E);
> gen_loongson_integer(ctx, op1, rd, rs, rt);
> break;
> + /* MIPS DSP opcodes */
> + case OPC_ABSQ_S_PH_DSP:
> + op2 = MASK_ABSQ_S_PH(ctx->opcode);
> + switch(op2){
> + /* MIPS DSP */
> + case OPC_ABSQ_S_PH:
> + gen_helper_absqsph(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_ABSQ_S_W:
> + gen_helper_absqsw (cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_BITREV:
> + gen_helper_bitrev(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQ_W_PHL:
> + gen_helper_preceqwphl(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQ_W_PHR:
> + gen_helper_preceqwphr(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQU_PH_QBL:
> + gen_helper_precequphqbl(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQU_PH_QBLA:
> + gen_helper_precequphqbla(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQU_PH_QBR:
> + gen_helper_precequphqbr(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEQU_PH_QBRA:
> + gen_helper_precequphqbra(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEU_PH_QBL:
> + gen_helper_preceuphqbl(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEU_PH_QBLA:
> + gen_helper_preceuphqbla(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEU_PH_QBR:
> + gen_helper_preceuphqbr(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_PRECEU_PH_QBRA:
> + gen_helper_preceuphqbra(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_REPL_PH:
> + {
> + TCGv temp_imm;
> + imm = (ctx->opcode>>16)& 0x03FF;
> + temp_imm = tcg_const_i32(imm);
> + gen_helper_replph(cpu_gpr[rd], temp_imm);
> + tcg_temp_free(temp_imm);
> + break;
> + }
> + case OPC_REPL_QB:
> + {
> + TCGv temp_imm;
> + imm = (ctx->opcode>> 16)& 0xFF;
> + temp_imm = tcg_const_i32(imm);
> + gen_helper_replqb(cpu_gpr[rd], temp_imm);
> + tcg_temp_free(temp_imm);
> + break;
> + }
> + case OPC_REPLV_PH:
> + gen_helper_replvph(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + case OPC_REPLV_QB:
> + gen_helper_replvqb(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + /* MIPS DSPR2 */
> + case OPC_ABSQ_S_QB:
> + gen_helper_absqsqb(cpu_gpr[rd], cpu_gpr[rt]);
> + break;
> + }
> + break;
> + case OPC_ADDU_QB_DSP:
> + op2 = MASK_ADDU_QB(ctx->opcode);
> + switch(op2){
> + /* MIPS DSP */
> + case OPC_ADDQ_PH:
> + gen_helper_addqph (cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDQ_S_PH:
> + gen_helper_addqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDQ_S_W:
> + gen_helper_addqsw (cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDSC:
> + gen_helper_addsc(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDU_QB:
> + gen_helper_adduqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDU_S_QB:
> + gen_helper_addusqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDWC:
> + gen_helper_addwc(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MODSUB:
> + gen_helper_modsub(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULEQ_S_W_PHL:
> + gen_helper_muleqswphl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULEQ_S_W_PHR:
> + gen_helper_muleqswphr(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULEU_S_PH_QBL:
> + gen_helper_muleusphqbl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULEU_S_PH_QBR:
> + gen_helper_muleusphqbr(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULQ_RS_PH:
> + gen_helper_mulqrsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_RADDU_W_QB:
> + gen_helper_radduwqb(cpu_gpr[rd], cpu_gpr[rs]);
> + break;
> + case OPC_SUBQ_PH:
> + gen_helper_subqph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQ_S_PH:
> + gen_helper_subqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBQ_S_W:
> + gen_helper_subqsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBU_QB:
> + gen_helper_subuqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBU_S_QB:
> + gen_helper_subusqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + /* MIPS DSPR2 */
> + case OPC_ADDU_PH:
> + gen_helper_adduph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_ADDU_S_PH:
> + gen_helper_addusph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_MULQ_S_PH:
> + gen_helper_mulqsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBU_PH:
> + gen_helper_subuph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SUBU_S_PH:
> + gen_helper_subusph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + }
> + break;
> + case OPC_APPEND_DSP:
> + op2 = MASK_APPEND(ctx->opcode);
> + switch(op2){
> + /* MIPS DSPR2 */
> + case OPC_APPEND:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_append(cpu_gpr[rt], cpu_gpr[rt],
> + cpu_gpr[rs], temp_rd);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_BALIGN:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_balign(cpu_gpr[rt], cpu_gpr[rt],
> + cpu_gpr[rs], temp_rd);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_PREPEND:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_prepend(cpu_gpr[rt], temp_rd,
> + cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + }
> + break;
> + case OPC_CMPU_EQ_QB_DSP:
> + op2 = MASK_CMPU_EQ_QB(ctx->opcode);
> + switch(op2){
> + /* MIPS DSP */
> + case OPC_CMP_EQ_PH:
> + gen_helper_cmpeqph(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMP_LT_PH:
> + gen_helper_cmpltph(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMP_LE_PH:
> + gen_helper_cmpleph(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPGU_EQ_QB:
> + gen_helper_cmpgueqqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPGU_LT_QB:
> + gen_helper_cmpgultqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPGU_LE_QB:
> + gen_helper_cmpguleqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPU_EQ_QB:
> + gen_helper_cmpueqqb(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPU_LT_QB:
> + gen_helper_cmpultqb(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPU_LE_QB:
> + gen_helper_cmpuleqb(cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PACKRL_PH:
> + gen_helper_packrlph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PICK_QB:
> + gen_helper_pickqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PICK_PH:
> + gen_helper_pickph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECRQ_QB_PH:
> + gen_helper_precrqqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECRQ_PH_W:
> + gen_helper_precrqphw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECRQ_RS_PH_W:
> + gen_helper_precrqrsphw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECRQU_S_QB_PH:
> + gen_helper_precrqusqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + /* MIPS DSPR2 */
> + case OPC_CMPGDU_EQ_QB:
> + gen_helper_cmpgdueqqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPGDU_LT_QB:
> + gen_helper_cmpgdultqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_CMPGDU_LE_QB:
> + gen_helper_cmpgduleqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECR_QB_PH:
> + gen_helper_precrqbph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_PRECR_SRA_PH_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_precrsraphw(cpu_gpr[rt], temp_rd,
> + cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_PRECR_SRA_R_PH_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_precrsrarphw(cpu_gpr[rt], temp_rd,
> + cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + }
> + }
> + break;
> + case OPC_DPA_W_PH_DSP:
> + op2 = MASK_DPA_W_PH(ctx->opcode);
> + switch(op2){
> + /* MIPS DSP */
> + case OPC_DPAQ_S_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpaqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAQ_SA_L_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpaqsalw(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAU_H_QBL:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpauhqbl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAU_H_QBR:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpauhqbr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSQ_S_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSQ_SA_L_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsqsalw(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSU_H_QBL:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsuhqbl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSU_H_QBR:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsuhqbr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MAQ_S_W_PHL:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_maqswphl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MAQ_SA_W_PHL:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_maqsawphl(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MAQ_S_W_PHR:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_maqswphr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MAQ_SA_W_PHR:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_maqsawphr(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MULSAQ_S_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_mulsaqswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + /* MIPS DSPR2 */
> + case OPC_DPA_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAQX_S_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpaqxswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAQX_SA_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpaqxsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPAX_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpaxwph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPS_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSQX_S_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsqxswph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSQX_SA_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsqxsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_DPSX_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_dpsxwph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_MULSA_W_PH:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_mulsawph(temp_rd, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + }
> + break;
> + case OPC_EXTR_W_DSP:
> + op2 = MASK_EXTR_W(ctx->opcode);
> + switch(op2){
> + /* MIPS DSP */
> + case OPC_EXTP:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extp(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTPDP:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extpdp(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTPDPV:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extpdpv(temp_rd, cpu_gpr[rs], temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTPV:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extpv(temp_rd, cpu_gpr[rs], temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTR_S_H:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrsh(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTR_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrw(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTR_R_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrrw(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTR_RS_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rs = tcg_const_i32(rs);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrrsw(temp_rd, temp_rs, temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rs);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTRV_S_H:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_extrvsh(cpu_gpr[rt], temp_rd, cpu_gpr[rs]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_EXTRV_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrvw(temp_rd, cpu_gpr[rs], temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTRV_R_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrvrw(temp_rd, cpu_gpr[rs], temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_EXTRV_RS_W:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_extrvrsw(temp_rd, cpu_gpr[rs], temp_rt);
> + tcg_temp_free(temp_rd);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + case OPC_MTHLIP:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_mthlip(temp_rd, cpu_gpr[rs]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_RDDSP:
> + {
> + TCGv temp_imm;
> + imm = (ctx->opcode>> 16)& 0x03FF;
> + temp_imm = tcg_const_i32(imm);
> + gen_helper_rddsp(cpu_gpr[rd], temp_imm);
> + tcg_temp_free(temp_imm);
> + break;
> + }
> + case OPC_SHILO:
> + {
> + TCGv temp_imm;
> + TCGv temp_rd = tcg_const_i32(rd);
> + imm = (ctx->opcode>> 20)& 0x3F;
> + temp_imm = tcg_const_i32(imm);
> + gen_helper_shilo(temp_rd, temp_imm);
> + tcg_temp_free(temp_imm);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_SHILOV:
> + {
> + TCGv temp_rd = tcg_const_i32(rd);
> + gen_helper_shilov(temp_rd, cpu_gpr[rs]);
> + tcg_temp_free(temp_rd);
> + break;
> + }
> + case OPC_WRDSP:
> + {
> + TCGv temp_imm;
> + imm = (ctx->opcode>> 11)& 0x3FF;
> + temp_imm = tcg_const_i32(imm);
> + gen_helper_wrdsp(cpu_gpr[rs], temp_imm);
> + tcg_temp_free(temp_imm);
> + break;
> + }
> + }
> + break;
> + case OPC_INSV_DSP:
> + op2 = MASK_INSV(ctx->opcode);
> + switch(op2) {
> + /* MIPS DSP */
> + case OPC_INSV:
> + {
> + TCGv temp_rt = tcg_const_i32(rt);
> + gen_helper_insv(temp_rt, cpu_gpr[rs], cpu_gpr[rt]);
> + tcg_temp_free(temp_rt);
> + break;
> + }
> + }
> + break;
> + case OPC_LX_DSP:
> + op2 = MASK_LX(ctx->opcode);
> + switch(op2) {
> + case OPC_LBUX:
> + {
> + TCGv addr = tcg_temp_new();
> + TCGv temp_mem = tcg_temp_new();
> +
> + save_cpu_state(ctx, 1);
> + gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
> + temp_mem = tcg_const_i32(ctx->mem_idx);
> + gen_helper_lbux(cpu_gpr[rd], addr, temp_mem);
> + tcg_temp_free_i32(addr);
> + tcg_temp_free_i32(temp_mem);
> + break;
> + }
> + case OPC_LHX:
> + {
> + TCGv addr = tcg_temp_new();
> + TCGv temp_mem = tcg_temp_new();
> +
> + save_cpu_state(ctx, 1);
> + gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
> + temp_mem = tcg_const_i32(ctx->mem_idx);
> + gen_helper_lhx(cpu_gpr[rd], addr, temp_mem);
> + tcg_temp_free_i32(addr);
> + tcg_temp_free_i32(temp_mem);
> + break;
> + }
> + case OPC_LWX:
> + {
> + TCGv addr = tcg_temp_new();
> + TCGv temp_mem = tcg_temp_new();
> +
> + save_cpu_state(ctx, 1);
> + gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]);
> + temp_mem = tcg_const_i32(ctx->mem_idx);
> + gen_helper_lwx(cpu_gpr[rd], addr, temp_mem);
> + tcg_temp_free_i32(addr);
> + tcg_temp_free_i32(temp_mem);
> + break;
> + }
> + }
> + break;
> + case OPC_SHLL_QB_DSP:
> + {
> + TCGv temp_rs = tcg_const_i32(rs);
> + op2 = MASK_SHLL_QB(ctx->opcode);
> + switch(op2){
>
Missing space before {. There are more lines like this.
> + /* MIPS DSP */
> + case OPC_SHLL_PH:
> + gen_helper_shllph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHLL_S_PH:
> + gen_helper_shllsph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHLL_QB:
> + gen_helper_shllqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHLL_S_W:
> + gen_helper_shllsw(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHLLV_PH:
> + gen_helper_shllvph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHLLV_S_PH:
> + gen_helper_shllvsph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHLLV_QB:
> + gen_helper_shllvqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHLLV_S_W:
> + gen_helper_shllvsw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRA_PH:
> + gen_helper_shraph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRA_R_PH:
> + gen_helper_shrarph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRA_R_W:
> + gen_helper_shrarw(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRAV_PH:
> + gen_helper_shravph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRAV_R_PH:
> + gen_helper_shravrph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRAV_R_W:
> + gen_helper_shravrw(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRL_QB:
> + gen_helper_shrlqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRLV_QB:
> + gen_helper_shrlvqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + /* MIPS DSPR2 */
> + case OPC_SHRA_QB:
> + gen_helper_shraqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRA_R_QB:
> + gen_helper_shrarqb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRAV_QB:
> + gen_helper_shravqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRAV_R_QB:
> + gen_helper_shravrqb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + case OPC_SHRL_PH:
> + gen_helper_shrlph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
> + break;
> + case OPC_SHRLV_PH:
> + gen_helper_shrlvph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> + break;
> + }
> + tcg_temp_free(temp_rs);
> + break;
> + }
> #if defined(TARGET_MIPS64)
> case OPC_DEXTM ... OPC_DEXT:
> case OPC_DINSM ... OPC_DINS:
> @@ -12079,6 +13135,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
> check_insn(env, ctx, ISA_MIPS32R2);
> /* Treat as NOP. */
> break;
> + case OPC_BPOSGE32: /* mipsdsp branch */
> + {
> + gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm<< 2);
> + *is_branch = 1;
> + break;
> + }
>
Is there any reason for the {} used here?
> default: /* Invalid */
> MIPS_INVAL("regimm");
> generate_exception(ctx, EXCP_RI);
>
next prev parent reply other threads:[~2012-03-21 8:33 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-12 8:32 [Qemu-devel] [PATCH 0/4] MIPS ASE DSP Support for Qemu Jia Liu
2012-03-12 8:32 ` [Qemu-devel] [PATCH 1/4] add MIPS DSP helpers define Jia Liu
2012-03-21 8:17 ` Stefan Weil
2012-03-22 13:45 ` Jia Liu
2012-03-12 8:32 ` [Qemu-devel] [PATCH 2/4] add MIPS DSP helpers implement Jia Liu
2012-03-21 8:22 ` Stefan Weil
2012-03-12 8:32 ` [Qemu-devel] [PATCH 3/4] add MIPS DSP translation Jia Liu
2012-03-21 8:33 ` Stefan Weil [this message]
2012-03-12 8:32 ` [Qemu-devel] [PATCH 4/4] add MIPS DSP testcase Jia Liu
2012-03-21 8:38 ` Stefan Weil
2012-03-21 0:12 ` [Qemu-devel] [PATCH 0/4] MIPS ASE DSP Support for Qemu Jia Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F699254.6010402@weilnetz.de \
--to=sw@weilnetz.de \
--cc=aurelien@aurel32.net \
--cc=proljc@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).