Message ID | 1331541159-5218-4-git-send-email-proljc@gmail.com |
---|---|
State | New |
Headers | show |
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); >
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; 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){ + /* 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; + } default: /* Invalid */ MIPS_INVAL("regimm"); generate_exception(ctx, EXCP_RI);
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(-)