From patchwork Fri Mar 30 03:17:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jia Liu X-Patchwork-Id: 149530 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 87F55B6EEF for ; Fri, 30 Mar 2012 14:20:05 +1100 (EST) Received: from localhost ([::1]:35598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDSNf-0004Kq-CH for incoming@patchwork.ozlabs.org; Thu, 29 Mar 2012 23:20:03 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47951) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDSNS-00048V-07 for qemu-devel@nongnu.org; Thu, 29 Mar 2012 23:19:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDSNO-0004ll-L9 for qemu-devel@nongnu.org; Thu, 29 Mar 2012 23:19:49 -0400 Received: from mail-iy0-f173.google.com ([209.85.210.173]:41963) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDSNO-0004ZK-E0 for qemu-devel@nongnu.org; Thu, 29 Mar 2012 23:19:46 -0400 Received: by mail-iy0-f173.google.com with SMTP id j26so432632iaf.4 for ; Thu, 29 Mar 2012 20:19:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :content-type; bh=2sT8iUWhfLboL/IzlgSbv1Efp9YR0S/+6ZAN0P+CwsM=; b=f+0FVjSOVg9b10wnRQwN7Riq/A4r3CTe9vLeXzsLIZh72at2F1DZBs4HxDuB7mGBxA K2yR4BnHgw3gq44KrteRm4NVHoA/bgJob3zNub55vl2Ufd5yPlRK2Uqo6u9I/wDqft2y bkmmew55QOAhH4soZjzJZIjBNBu+bKLg5duSflthKeLzNfia7VQhH7I7+dnlp1JCYRQu bxg+IxeHpGZgCmIUIm+1h8vWWj7dY3FCoGs7N/dtR4STFY5vE5o2Avxs5XVNuya5PbdJ injpQSnwUXSW5j1v3cYBIG9FiU1dgfBxMBk/7gySaeTD9kFuRo7OPqmFqJHUD3+M9iI+ f7gQ== Received: by 10.50.161.232 with SMTP id xv8mr341595igb.9.1333077585711; Thu, 29 Mar 2012 20:19:45 -0700 (PDT) Received: from localhost ([1.202.183.51]) by mx.google.com with ESMTPS id p5sm710796igl.2.2012.03.29.20.19.39 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 29 Mar 2012 20:19:44 -0700 (PDT) From: Jia Liu To: qemu-devel@nongnu.org Date: Fri, 30 Mar 2012 11:17:10 +0800 Message-Id: <1333077432-22228-10-git-send-email-proljc@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1333077432-22228-1-git-send-email-proljc@gmail.com> References: <1333077432-22228-1-git-send-email-proljc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.173 Cc: aurelien@aurel32.net, rth@twiddle.net Subject: [Qemu-devel] [PATCH V4 09/11] Add MIPS DSP Compare-Pick instructions Support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add MIPS DSP Compare-Pick instructions Support. Signed-off-by: Jia Liu --- target-mips/dsp_helper.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++ target-mips/helper.h | 17 +++ target-mips/translate.c | 135 ++++++++++++++++++ 3 files changed, 493 insertions(+), 0 deletions(-) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index 1c5e858..27949ab 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -3021,6 +3021,347 @@ uint32_t helper_insv(CPUMIPSState *env, uint32_t rs, uint32_t rt) return temp; } +/** DSP Compare-Pick Sub-class insns **/ +void helper_cmpu_eq_qb(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t flag; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 == rt3); + cc2 = (rs2 == rt2); + cc1 = (rs1 == rt1); + cc0 = (rs0 == rt0); + + flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + set_DSPControl_24(env, flag, 4); +} + +void helper_cmpu_lt_qb(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t flag; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 < rt3); + cc2 = (rs2 < rt2); + cc1 = (rs1 < rt1); + cc0 = (rs0 < rt0); + + flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + set_DSPControl_24(env, flag, 4); +} + +void helper_cmpu_le_qb(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t flag; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 <= rt3); + cc2 = (rs2 <= rt2); + cc1 = (rs1 <= rt1); + cc0 = (rs0 <= rt0); + + flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + set_DSPControl_24(env, flag, 4); +} + + +uint32_t helper_cmpgu_eq_qb(uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint8_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t temp; + uint32_t rd; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 == rt3); + cc2 = (rs2 == rt2); + cc1 = (rs1 == rt1); + cc0 = (rs0 == rt0); + + temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + rd = temp; + + return rd; +} + +uint32_t helper_cmpgu_lt_qb(uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t temp; + uint32_t rd; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 < rt3); + cc2 = (rs2 < rt2); + cc1 = (rs1 < rt1); + cc0 = (rs0 < rt0); + + temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + rd = temp; + + return rd; +} + +uint32_t helper_cmpgu_le_qb(uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint32_t cc3 = 0, cc2 = 0, cc1 = 0, cc0 = 0; + uint32_t temp; + uint32_t rd; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + cc3 = (rs3 <= rt3); + cc2 = (rs2 <= rt2); + cc1 = (rs1 <= rt1); + cc0 = (rs0 <= rt0); + + temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0; + rd = temp; + + return rd; +} + +void helper_cmp_eq_ph(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + int16_t rsh, rsl, rth, rtl; + int32_t flag; + int32_t ccA = 0, ccB = 0; + + rsh = (rs & MIPSDSP_HI) >> 16; + rsl = rs & MIPSDSP_LO; + rth = (rt & MIPSDSP_HI) >> 16; + rtl = rt & MIPSDSP_LO; + + ccB = (rsh == rth); + ccA = (rsl == rtl); + + flag = (ccB << 1) | ccA; + set_DSPControl_24(env, flag, 2); +} + +void helper_cmp_lt_ph(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + int16_t rsh, rsl, rth, rtl; + int32_t flag; + int32_t ccA = 0, ccB = 0; + + rsh = (rs & MIPSDSP_HI) >> 16; + rsl = rs & MIPSDSP_LO; + rth = (rt & MIPSDSP_HI) >> 16; + rtl = rt & MIPSDSP_LO; + + ccB = (rsh < rth); + ccA = (rsl < rtl); + + flag = (ccB << 1) | ccA; + set_DSPControl_24(env, flag, 2); +} + +void helper_cmp_le_ph(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + int16_t rsh, rsl, rth, rtl; + int32_t flag; + int32_t ccA = 0, ccB = 0; + + rsh = (rs & MIPSDSP_HI) >> 16; + rsl = rs & MIPSDSP_LO; + rth = (rt & MIPSDSP_HI) >> 16; + rtl = rt & MIPSDSP_LO; + + ccB = (rsh <= rth); + ccA = (rsl <= rtl); + + flag = (ccB << 1) | ccA; + set_DSPControl_24(env, flag, 2); +} + +uint32_t helper_pick_qb(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + uint8_t rs3, rs2, rs1, rs0; + uint8_t rt3, rt2, rt1, rt0; + uint8_t tp3, tp2, tp1, tp0; + + uint32_t dsp27, dsp26, dsp25, dsp24, rd; + target_ulong dsp; + + rs3 = (rs & MIPSDSP_Q3) >> 24; + rs2 = (rs & MIPSDSP_Q2) >> 16; + rs1 = (rs & MIPSDSP_Q1) >> 8; + rs0 = rs & MIPSDSP_Q0; + rt3 = (rt & MIPSDSP_Q3) >> 24; + rt2 = (rt & MIPSDSP_Q2) >> 16; + rt1 = (rt & MIPSDSP_Q1) >> 8; + rt0 = rt & MIPSDSP_Q0; + + dsp = env->active_tc.DSPControl; + dsp27 = (dsp >> 27) & 0x01; + dsp26 = (dsp >> 26) & 0x01; + dsp25 = (dsp >> 25) & 0x01; + dsp24 = (dsp >> 24) & 0x01; + + tp3 = dsp27 == 1 ? rs3 : rt3; + tp2 = dsp26 == 1 ? rs2 : rt2; + tp1 = dsp25 == 1 ? rs1 : rt1; + tp0 = dsp24 == 1 ? rs0 : rt0; + + rd = ((uint32_t)tp3 << 24) | \ + ((uint32_t)tp2 << 16) | \ + ((uint32_t)tp1 << 8) | \ + (uint32_t)tp0; + + return rd; +} + +uint32_t helper_pick_ph(CPUMIPSState *env, uint32_t rs, uint32_t rt) +{ + uint16_t rsh, rsl, rth, rtl; + uint16_t tempB, tempA; + uint32_t dsp25, dsp24; + uint32_t rd; + target_ulong dsp; + + rsh = (rs & MIPSDSP_HI) >> 16; + rsl = rs & MIPSDSP_LO; + rth = (rt & MIPSDSP_HI) >> 16; + rtl = rt & MIPSDSP_LO; + + dsp = env->active_tc.DSPControl; + dsp25 = (dsp >> 25) & 0x01; + dsp24 = (dsp >> 24) & 0x01; + + tempB = (dsp25 == 1) ? rsh : rth; + tempA = (dsp24 == 1) ? rsl : rtl; + rd = (((uint32_t)tempB << 16) & MIPSDSP_HI) | (uint32_t)tempA; + + return rd; +} + +uint32_t helper_append(uint32_t rt, uint32_t rs, int sa) +{ + int len; + uint32_t temp; + + len = sa & 0x1F; + + if (len == 0) { + temp = rt; + } else { + temp = (rt << len) | (rs & (((uint32_t)0x01 << len) - 1)); + } + rt = temp; + + return temp; +} + +uint32_t helper_prepend(int sa, uint32_t rs, uint32_t rt) +{ + uint32_t temp; + + if (sa == 0) { + temp = rt; + } else { + temp = (rs << (32 - sa)) | rt >> sa; + } + + rt = temp; + + return rt; +} + +uint32_t helper_balign(uint32_t rt, uint32_t rs, uint32_t bp) +{ + uint32_t temp; + bp = bp & 0x03; + + if (bp == 0 || bp == 2) { + return rt; + } else { + temp = (rt << (8 * bp)) | (rs >> (8 * (4 - bp))); + } + rt = temp; + + return rt; +} + +uint32_t helper_packrl_ph(uint32_t rs, uint32_t rt) +{ + uint16_t rsl, rth; + uint32_t rd; + + rsl = rs & MIPSDSP_LO; + rth = (rt & MIPSDSP_HI) >> 16; + rd = (rsl << 16) | rth; + + return rd; +} + #undef MIPSDSP_LHI #undef MIPSDSP_LLO #undef MIPSDSP_HI diff --git a/target-mips/helper.h b/target-mips/helper.h index 669537b..7737a22 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -414,4 +414,21 @@ DEF_HELPER_FLAGS_4(mulsa_w_ph, 0, void, env, int, i32, i32) DEF_HELPER_FLAGS_1(bitrev, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) DEF_HELPER_FLAGS_3(insv, 0, i32, env, i32, i32) +/* DSP Compare-Pick Sub-class insns */ +DEF_HELPER_FLAGS_3(cmpu_eq_qb, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_3(cmpu_lt_qb, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_3(cmpu_le_qb, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_2(cmpgu_eq_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) +DEF_HELPER_FLAGS_2(cmpgu_lt_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) +DEF_HELPER_FLAGS_2(cmpgu_le_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) +DEF_HELPER_FLAGS_3(cmp_eq_ph, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_3(cmp_lt_ph, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_3(cmp_le_ph, 0, void, env, i32, i32) +DEF_HELPER_FLAGS_3(pick_qb, 0, i32, env, i32, i32) +DEF_HELPER_FLAGS_3(pick_ph, 0, i32, env, i32, i32) +DEF_HELPER_FLAGS_3(append, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32, int) +DEF_HELPER_FLAGS_3(prepend, TCG_CALL_CONST | TCG_CALL_PURE, i32, int, i32, i32) +DEF_HELPER_FLAGS_3(balign, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32, i32) +DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) + #include "def-helper.h" diff --git a/target-mips/translate.c b/target-mips/translate.c index 7d385f2..f5d3859 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -329,6 +329,8 @@ enum { OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, /* DSP Bit/Manipulation Sub-class */ OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, + /* MIPS DSP Compare-Pick Sub-class */ + OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -448,6 +450,22 @@ enum { 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, + /* DSP Compare-Pick Sub-class */ + 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_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_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_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_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, }; #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) @@ -510,6 +528,14 @@ enum { OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, }; +#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) +enum { + /* MIPS DSP Compare-Pick Sub-class */ + OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, + OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, + OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, +}; + /* Coprocessor 0 (rs field) */ #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) @@ -12595,6 +12621,86 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) gen_helper_precrqu_s_qb_ph(cpu_gpr[rd], cpu_env, cpu_gpr[rs], cpu_gpr[rt]); break; + case OPC_CMPU_EQ_QB: + gen_helper_cmpu_eq_qb(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPU_LT_QB: + gen_helper_cmpu_lt_qb(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPU_LE_QB: + gen_helper_cmpu_le_qb(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPGU_EQ_QB: + gen_helper_cmpgu_eq_qb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPGU_LT_QB: + gen_helper_cmpgu_lt_qb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPGU_LE_QB: + gen_helper_cmpgu_le_qb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMPGDU_EQ_QB: + { + TCGv dspc, t0; + dspc = tcg_const_i32(0); + t0 = tcg_const_i32(0); + gen_helper_cmpgu_eq_qb(dspc, cpu_gpr[rs], cpu_gpr[rt]); + tcg_gen_mov_tl(cpu_gpr[rd], dspc); + tcg_gen_andi_i32(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_i32(t0, dspc, 24); + tcg_gen_or_i32(cpu_dspctrl, cpu_dspctrl, t0); + tcg_temp_free(dspc); + tcg_temp_free(t0); + break; + } + case OPC_CMPGDU_LT_QB: + { + TCGv dspc, t0; + dspc = tcg_const_i32(0); + t0 = tcg_const_i32(0); + gen_helper_cmpgu_lt_qb(dspc, cpu_gpr[rs], cpu_gpr[rt]); + tcg_gen_mov_tl(cpu_gpr[rd], dspc); + tcg_gen_andi_i32(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_i32(t0, dspc, 24); + tcg_gen_or_i32(cpu_dspctrl, cpu_dspctrl, t0); + tcg_temp_free(dspc); + tcg_temp_free(t0); + break; + } + case OPC_CMPGDU_LE_QB: + { + TCGv dspc, t0; + dspc = tcg_const_i32(0); + t0 = tcg_const_i32(0); + gen_helper_cmpgu_le_qb(dspc, cpu_gpr[rs], cpu_gpr[rt]); + tcg_gen_mov_tl(cpu_gpr[rd], dspc); + tcg_gen_andi_i32(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_i32(t0, dspc, 24); + tcg_gen_or_i32(cpu_dspctrl, cpu_dspctrl, t0); + tcg_temp_free(dspc); + tcg_temp_free(t0); + break; + } + case OPC_CMP_EQ_PH: + gen_helper_cmp_eq_ph(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMP_LT_PH: + gen_helper_cmp_lt_ph(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_CMP_LE_PH: + gen_helper_cmp_le_ph(cpu_env, cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_PICK_QB: + gen_helper_pick_qb(cpu_gpr[rd], cpu_env, + cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_PICK_PH: + gen_helper_pick_ph(cpu_gpr[rd], cpu_env, + cpu_gpr[rs], cpu_gpr[rt]); + break; + case OPC_PACKRL_PH: + gen_helper_packrl_ph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); + break; } break; case OPC_SHLL_QB_DSP: @@ -12876,6 +12982,35 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) } } break; + case OPC_APPEND_DSP: + op2 = MASK_APPEND(ctx->opcode); + switch (op2) { + 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_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; + } + 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; + } + } + break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: