qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH V3 09/12] Add helper functions for MIPS DSP Compare-


From: Jia Liu
Subject: [Qemu-devel] [PATCH V3 09/12] Add helper functions for MIPS DSP Compare-Pick instructions
Date: Tue, 27 Mar 2012 17:24:47 +0800

Add helper functions for MIPS DSP Compare-Pick instructions.

Signed-off-by: Jia Liu <address@hidden>
---
 target-mips/dsp_helper.c |  496 ++++++++++++++++++++++++++++++++++++++++++++++
 target-mips/helper.h     |   21 ++
 2 files changed, 517 insertions(+), 0 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index cd9764f..14c460c 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -2996,6 +2996,502 @@ uint32_t helper_replv_ph(uint32_t rt)
     return rd;
 }
 
+/** DSP Compare-Pick Sub-class insns **/
+void helper_cmpu_eq_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 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;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+void helper_cmpu_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 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;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+void helper_cmpu_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 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;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+}
+
+uint32_t helper_cmpgdu_eq_qb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+uint32_t helper_cmpgdu_lt_qb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+uint32_t helper_cmpgdu_le_qb(uint32_t rs, uint32_t rt)
+{
+    uint32_t rd;
+    uint8_t  rs0, rs1, rs2, rs3;
+    uint8_t  rt0, rt1, rt2, rt3;
+    uint32_t cc0 = 0, cc1 = 0, cc2 = 0, cc3 = 0;
+    uint32_t flag;
+
+    rs0 =  rs & MIPSDSP_Q0;
+    rs1 = (rs & MIPSDSP_Q1) >>  8;
+    rs2 = (rs & MIPSDSP_Q2) >> 16;
+    rs3 = (rs & MIPSDSP_Q3) >> 24;
+
+    rt0 =  rt & MIPSDSP_Q0;
+    rt1 = (rt & MIPSDSP_Q1) >>  8;
+    rt2 = (rt & MIPSDSP_Q2) >> 16;
+    rt3 = (rt & MIPSDSP_Q3) >> 24;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    flag = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    set_DSPControl_24(flag, 4);
+    rd = flag;
+
+    return rd;
+}
+
+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;
+
+    if (rs3 == rt3)
+        cc3 = 1;
+
+    if (rs2 == rt2)
+        cc2 = 1;
+
+    if (rs1 == rt1)
+        cc1 = 1;
+
+    if (rs0 == rt0)
+        cc0 = 1;
+
+    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;
+
+    if (rs3 < rt3)
+        cc3 = 1;
+
+    if (rs2 < rt2)
+        cc2 = 1;
+
+    if (rs1 < rt1)
+        cc1 = 1;
+
+    if (rs0 < rt0)
+        cc0 = 1;
+
+    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;
+
+    if (rs3 <= rt3)
+        cc3 = 1;
+
+    if (rs2 <= rt2)
+        cc2 = 1;
+
+    if (rs1 <= rt1)
+        cc1 = 1;
+
+    if (rs0 <= rt0)
+        cc0 = 1;
+
+    temp = (cc3 << 3) | (cc2 << 2) | (cc1 << 1) | cc0;
+    rd = temp;
+
+    return rd;
+}
+
+void helper_cmp_eq_ph(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;
+
+    if (rsh == rth)
+        ccB = 1;
+    if (rsl == rtl)
+        ccA = 1;
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+void helper_cmp_lt_ph(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;
+
+    if (rsh < rth)
+        ccB = 1;
+
+    if (rsl < rtl)
+        ccA = 1;
+
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+void helper_cmp_le_ph(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;
+
+    if (rsh <= rth)
+        ccB = 1;
+
+    if (rsl <= rtl)
+        ccA = 1;
+
+    flag = (ccB << 1) | ccA;
+    set_DSPControl_24(flag, 2);
+}
+
+uint32_t helper_pick_qb(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(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
diff --git a/target-mips/helper.h b/target-mips/helper.h
index c45c173..36d6c19 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -421,4 +421,25 @@ DEF_HELPER_FLAGS_1(replv_qb, TCG_CALL_CONST | 
TCG_CALL_PURE, i32, i32)
 DEF_HELPER_FLAGS_1(repl_ph, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32)
 DEF_HELPER_FLAGS_1(replv_ph, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32)
 
+/* DSP Compare-Pick Sub-class insns */
+DEF_HELPER_2(cmpu_eq_qb, void, i32, i32)
+DEF_HELPER_2(cmpu_lt_qb, void, i32, i32)
+DEF_HELPER_2(cmpu_le_qb, void, i32, i32)
+DEF_HELPER_FLAGS_2(cmpgdu_eq_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32)
+DEF_HELPER_FLAGS_2(cmpgdu_lt_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32)
+DEF_HELPER_FLAGS_2(cmpgdu_le_qb, TCG_CALL_CONST | TCG_CALL_PURE, i32, 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_2(cmp_eq_ph, void, i32, i32)
+DEF_HELPER_2(cmp_lt_ph, void, i32, i32)
+DEF_HELPER_2(cmp_le_ph, void, i32, i32)
+DEF_HELPER_2(pick_qb, i32, i32, i32)
+DEF_HELPER_2(pick_ph, i32, 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"
-- 
1.7.5.4




reply via email to

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