qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH V4 10/11] Add MIPS DSP Accumulator and DSPControl Ac


From: Jia Liu
Subject: [Qemu-devel] [PATCH V4 10/11] Add MIPS DSP Accumulator and DSPControl Access instructions Support
Date: Fri, 30 Mar 2012 11:17:11 +0800

Add MIPS DSP Accumulator and DSPControl Access instructions Support.

Signed-off-by: Jia Liu <address@hidden>
---
 target-mips/dsp_helper.c |  465 ++++++++++++++++++++++++++++++++++++++++++++++
 target-mips/helper.h     |   19 ++
 target-mips/translate.c  |  175 +++++++++++++++++
 3 files changed, 659 insertions(+), 0 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 27949ab..c1ccddc 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3362,6 +3362,471 @@ uint32_t helper_packrl_ph(uint32_t rs, uint32_t rt)
     return rd;
 }
 
+/** DSP Accumulator and DSPControl Access Sub-class insns **/
+uint32_t helper_extr_w(CPUMIPSState *env, int ac, int shift)
+{
+    int32_t tempI;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempI = (tempDL[0] >> 1) & MIPSDSP_LLO;
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+
+    if ((!(tempDL[1] == 0 && (tempDL[0] & MIPSDSP_LHI) == 0x00)) && \
+        (!(tempDL[1] == 1 && (tempDL[0] & MIPSDSP_LHI) == MIPSDSP_LHI))) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    return tempI;
+}
+
+uint32_t helper_extr_r_w(CPUMIPSState *env, int ac, int shift)
+{
+    int32_t tempI;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 && (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+    tempI = tempDL[0] >> 1;
+
+    return tempI;
+}
+
+uint32_t helper_extr_rs_w(CPUMIPSState *env, int ac, int shift)
+{
+    int32_t tempI, temp64;
+    int64_t tempDL[2];
+
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+    tempI = tempDL[0] >> 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        temp64 = tempDL[1];
+        if (temp64 == 0) {
+            tempI = 0x7FFFFFFF;
+        } else {
+            tempI = 0x80000000;
+        }
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    return tempI;
+}
+
+uint32_t helper_extr_s_h(CPUMIPSState *env, int ac, int shift)
+{
+    int64_t temp;
+    uint32_t tempI;
+
+    temp = mipsdsp_rashift_short_acc(env, ac, shift);
+    if (temp > 0x0000000000007FFFull) {
+        temp &= MIPSDSP_LHI;
+        temp |= 0x00007FFF;
+        set_DSPControl_overflow_flag(env, 1, 23);
+    } else if (temp < 0xFFFFFFFFFFFF8000ull) {
+        temp &= MIPSDSP_LHI;
+        temp |= 0xFFFF8000;
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempI = temp & 0xFFFFFFFF;
+    return tempI;
+}
+
+uint32_t helper_extrv_s_h(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    uint32_t rd;
+    int32_t shift, tempI;
+    int64_t tempL;
+
+    shift = rs & 0x0F;
+    tempL = mipsdsp_rashift_short_acc(env, ac, shift);
+    if (tempL > 0x000000000007FFFull) {
+        tempI = 0x00007FFF;
+        set_DSPControl_overflow_flag(env, 1, 23);
+    } else if (tempL < 0xFFFFFFFFFFF8000ull) {
+        tempI = 0xFFFF8000;
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+    rd = tempI;
+
+    return rd;
+}
+
+uint32_t helper_extrv_w(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempI = tempDL[0] >> 1;
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    return tempI;
+}
+
+uint32_t helper_extrv_r_w(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+    tempI = tempDL[0] >> 1;
+
+    return tempI;
+}
+
+uint32_t helper_extrv_rs_w(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t shift, tempI;
+    int64_t tempDL[2];
+
+    shift = rs & 0x0F;
+    mipsdsp__rashift_short_acc(env, tempDL, ac, shift);
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    tempDL[0] += 1;
+    if (tempDL[0] == 0) {
+        tempDL[1] += 1;
+    }
+    tempI = tempDL[0] >> 1;
+
+    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \
+        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
+        if (tempDL[1] == 0) {
+            tempI = 0x7FFFFFFF;
+        } else {
+            tempI = 0x80000000;
+        }
+        set_DSPControl_overflow_flag(env, 1, 23);
+    }
+
+    return tempI;
+}
+
+uint32_t helper_extp(CPUMIPSState *env, int ac, int size)
+{
+    int32_t start_pos;
+    uint32_t temp;
+    uint64_t acc;
+
+    temp = 0;
+    start_pos = get_DSPControl_pos(env);
+    if (start_pos - (size + 1) >= -1) {
+        acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+              ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+        set_DSPControl_efi(env, 0);
+    } else {
+        set_DSPControl_efi(env, 1);
+    }
+
+    return temp;
+}
+
+uint32_t helper_extpv(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t start_pos, size;
+    uint32_t temp;
+    uint64_t acc;
+
+    temp = 0;
+    start_pos = get_DSPControl_pos(env);
+    size = rs & 0x1F;
+
+    if (start_pos - (size + 1) >= -1) {
+        acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+              ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+        set_DSPControl_efi(env, 0);
+    } else {
+        set_DSPControl_efi(env, 1);
+    }
+
+    return temp;
+}
+
+uint32_t helper_extpdp(CPUMIPSState *env, int ac, int size)
+{
+    int32_t start_pos;
+    uint32_t temp;
+    uint64_t acc;
+
+    temp = 0;
+    start_pos = get_DSPControl_pos(env);
+    if (start_pos - (size + 1) >= -1) {
+        acc  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+               ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & \
+               (((uint32_t)0x01 << (size + 1)) - 1);
+
+        set_DSPControl_pos(env, start_pos - (size + 1));
+        set_DSPControl_efi(env, 0);
+    } else {
+        set_DSPControl_efi(env, 1);
+    }
+
+    return temp;
+}
+
+uint32_t helper_extpdpv(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t start_pos, size;
+    uint32_t temp;
+    uint64_t acc;
+
+    temp = 0;
+    start_pos = get_DSPControl_pos(env);
+    size = rs & 0x1F;
+
+    if (start_pos - (size + 1) >= -1) {
+        acc  = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+               ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+        temp = (acc >> (start_pos - size)) & (((int)0x01 << (size + 1)) - 1);
+        set_DSPControl_pos(env, start_pos - (size + 1));
+        set_DSPControl_efi(env, 0);
+    } else {
+        set_DSPControl_efi(env, 1);
+    }
+
+    return temp;
+}
+
+void helper_shilo(CPUMIPSState *env, int ac, int shift)
+{
+    uint8_t  sign;
+    uint64_t temp, acc;
+
+    shift = (shift << 26) >> 26;
+    sign  = (shift >>  5) & 0x01;
+    shift = (sign == 0) ? shift : -shift;
+    acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \
+          ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+
+    if (shift == 0) {
+        temp = acc;
+    } else {
+        if (sign == 0) {
+            temp = acc >> shift;
+        } else {
+            temp = acc << shift;
+        }
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+void helper_shilov(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    uint8_t sign;
+    int8_t  rs5_0;
+    uint64_t temp, acc;
+
+    rs5_0 = rs & 0x3F;
+    rs    = (rs5_0 << 2) >> 2;
+    sign  = (rs5_0 >> 5) & 0x01;
+    rs5_0 = (sign == 0) ? rs : -rs;
+    acc   = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \
+            ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
+    if (rs5_0 == 0) {
+        temp = acc;
+    } else {
+        if (sign == 0) {
+            temp = acc >> rs5_0;
+        } else {
+            temp = acc << rs5_0;
+        }
+    }
+
+    env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32;
+    env->active_tc.LO[ac] =  temp & MIPSDSP_LLO;
+}
+
+void helper_mthlip(CPUMIPSState *env, int ac, uint32_t rs)
+{
+    int32_t tempA, tempB, pos;
+
+    tempA = rs;
+    tempB = env->active_tc.LO[ac];
+    env->active_tc.HI[ac] = tempB;
+    env->active_tc.LO[ac] = tempA;
+    pos = get_DSPControl_pos(env);
+
+    if (pos > 32) {
+        return;
+    } else {
+        set_DSPControl_pos(env, pos + 32);
+    }
+}
+
+void helper_wrdsp(CPUMIPSState *env, uint32_t rs, int mask_num)
+{
+    uint8_t  mask[6];
+    uint8_t  i;
+    uint32_t newbits, overwrite;
+    target_ulong dsp;
+
+    newbits   = 0x00;
+    overwrite = 0xFFFFFFFF;
+    dsp = env->active_tc.DSPControl;
+
+    for (i = 0; i < 6; i++) {
+        mask[i] = (mask_num >> i) & 0x01;
+    }
+
+    if (mask[0] == 1) {
+        overwrite &= 0xFFFFFFC0;
+        newbits   &= 0xFFFFFFC0;
+        newbits   |= 0x0000003F & rs;
+    }
+
+    if (mask[1] == 1) {
+        overwrite &= 0xFFFFE07F;
+        newbits   &= 0xFFFFE07F;
+        newbits   |= 0x00001F80 & rs;
+    }
+
+    if (mask[2] == 1) {
+        overwrite &= 0xFFFFDFFF;
+        newbits   &= 0xFFFFDFFF;
+        newbits   |= 0x00002000 & rs;
+    }
+
+    if (mask[3] == 1) {
+        overwrite &= 0xFF00FFFF;
+        newbits   &= 0xFF00FFFF;
+        newbits   |= 0x00FF0000 & rs;
+    }
+
+    if (mask[4] == 1) {
+        overwrite &= 0x00FFFFFF;
+        newbits   &= 0x00FFFFFF;
+        newbits   |= 0xFF000000 & rs;
+    }
+
+    if (mask[5] == 1) {
+        overwrite &= 0xFFFFBFFF;
+        newbits   &= 0xFFFFBFFF;
+        newbits   |= 0x00004000 & rs;
+    }
+
+    dsp = dsp & overwrite;
+    dsp = dsp | newbits;
+    env->active_tc.DSPControl = dsp;
+}
+
+uint32_t helper_rddsp(CPUMIPSState *env, uint32_t masknum)
+{
+    uint8_t  mask[6];
+    uint32_t ruler, i;
+    uint32_t temp;
+    uint32_t rd;
+    target_ulong dsp;
+
+    ruler = 0x01;
+    for (i = 0; i < 6; i++) {
+        mask[i] = (masknum & ruler) >> i ;
+        ruler = ruler << 1;
+    }
+
+    temp  = 0x00;
+    dsp = env->active_tc.DSPControl;
+
+    if (mask[0] == 1) {
+        temp |= dsp & 0x3F;
+    }
+
+    if (mask[1] == 1) {
+        temp |= dsp & 0x1F80;
+    }
+
+    if (mask[2] == 1) {
+        temp |= dsp & 0x2000;
+    }
+
+    if (mask[3] == 1) {
+        temp |= dsp & 0x00FF0000;
+    }
+
+    if (mask[4] == 1) {
+        temp |= dsp & 0xFF000000;
+    }
+
+    if (mask[5] == 1) {
+        temp |= dsp & 0x4000;
+    }
+
+    rd = temp;
+
+    return rd;
+}
+
 #undef MIPSDSP_LHI
 #undef MIPSDSP_LLO
 #undef MIPSDSP_HI
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 7737a22..446e66a 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -431,4 +431,23 @@ 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)
 
+/* DSP Accumulator and DSPControl Access Sub-class insns */
+DEF_HELPER_FLAGS_3(extr_w, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extr_r_w, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extr_rs_w, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extr_s_h, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extrv_s_h, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(extrv_w, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(extrv_r_w, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(extrv_rs_w, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(extp, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extpv, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(extpdp, 0, i32, env, int, int)
+DEF_HELPER_FLAGS_3(extpdpv, 0, i32, env, int, i32)
+DEF_HELPER_FLAGS_3(shilo, 0, void, env, int, int)
+DEF_HELPER_FLAGS_3(shilov, 0, void, env, int, i32)
+DEF_HELPER_FLAGS_3(mthlip, 0, void, env, int, i32)
+DEF_HELPER_FLAGS_3(wrdsp, 0, void, env, i32, int)
+DEF_HELPER_FLAGS_2(rddsp, 0, i32, env, i32)
+
 #include "def-helper.h"
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f5d3859..d6561c2 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -331,6 +331,8 @@ enum {
     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
     /* MIPS DSP Compare-Pick Sub-class */
     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
+    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
+    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 };
 
 /* BSHFL opcodes */
@@ -536,6 +538,28 @@ enum {
     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 };
 
+#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
+enum {
+    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
+    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_EXTR_S_H   = (0x0E << 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_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
+    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
+    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
+    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
+    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
+    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
+    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
+};
+
 /* Coprocessor 0 (rs field) */
 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 
@@ -13011,6 +13035,157 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx, int *is_branch)
                 }
             }
             break;
+        case OPC_EXTR_W_DSP:
+            op2 = MASK_EXTR_W(ctx->opcode);
+            switch (op2) {
+            case OPC_EXTR_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extr_w(cpu_gpr[rt], cpu_env, temp_rd, temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTR_R_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extr_r_w(cpu_gpr[rt], cpu_env, temp_rd, 
temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTR_RS_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extr_rs_w(cpu_gpr[rt], cpu_env,
+                                         temp_rd, temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTR_S_H:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extr_s_h(cpu_gpr[rt], cpu_env, temp_rd, 
temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTRV_S_H:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extrv_s_h(cpu_gpr[rt], cpu_env,
+                                         temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTRV_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extrv_w(cpu_gpr[rt], cpu_env,
+                                       temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTRV_R_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extrv_r_w(cpu_gpr[rt], cpu_env,
+                                         temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTRV_RS_W:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extrv_rs_w(cpu_gpr[rt], cpu_env,
+                                          temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extp(cpu_gpr[rt], cpu_env, temp_rd, temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTPV:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extpv(cpu_gpr[rt], cpu_env,
+                                     temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_EXTPDP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    TCGv temp_rs = tcg_const_i32(rs);
+                    gen_helper_extpdp(cpu_gpr[rt], cpu_env, temp_rd, temp_rs);
+                    tcg_temp_free(temp_rd);
+                    tcg_temp_free(temp_rs);
+                    break;
+                }
+            case OPC_EXTPDPV:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_extpdpv(cpu_gpr[rt], cpu_env,
+                                       temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    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(cpu_env, 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(cpu_env, temp_rd, cpu_gpr[rs]);
+                    tcg_temp_free(temp_rd);
+                    break;
+                }
+            case OPC_MTHLIP:
+                {
+                    TCGv temp_rd = tcg_const_i32(rd);
+                    gen_helper_mthlip(cpu_env, 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_env, cpu_gpr[rs], temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            case OPC_RDDSP:
+                {
+                    TCGv temp_imm;
+                    imm = (ctx->opcode >> 16) & 0x03FF;
+                    temp_imm = tcg_const_i32(imm);
+                    gen_helper_rddsp(cpu_gpr[rd], cpu_env, temp_imm);
+                    tcg_temp_free(temp_imm);
+                    break;
+                }
+            }
+            break;
 #if defined(TARGET_MIPS64)
         case OPC_DEXTM ... OPC_DEXT:
         case OPC_DINSM ... OPC_DINS:
-- 
1.7.5.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]