From: Jia Liu <proljc@gmail.com>
To: qemu-devel@nongnu.org
Cc: aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH V3 10/12] Add helper functions for MIPS DSP Accumulator and DSPControl Access instrutions helpers
Date: Tue, 27 Mar 2012 17:24:48 +0800 [thread overview]
Message-ID: <1332840290-24553-11-git-send-email-proljc@gmail.com> (raw)
In-Reply-To: <1332840290-24553-1-git-send-email-proljc@gmail.com>
Add helper functions for MIPS DSP Accumulator and DSPControl Access instrutions.
Signed-off-by: Jia Liu <proljc@gmail.com>
---
target-mips/dsp_helper.c | 434 ++++++++++++++++++++++++++++++++++++++++++++++
target-mips/helper.h | 18 ++
2 files changed, 452 insertions(+), 0 deletions(-)
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 14c460c..8973cb0 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3493,6 +3493,440 @@ 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(int ac, int shift)
+{
+ int32_t tempI;
+ int64_t tempDL[2];
+
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+
+ return tempI;
+}
+
+uint32_t helper_extr_r_w(int ac, int shift)
+{
+ int32_t tempI;
+ int64_t tempDL[2];
+
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+ tempI = tempDL[0] >> 1;
+
+ return tempI;
+}
+
+uint32_t helper_extr_rs_w(int ac, int shift)
+{
+ int32_t tempI, temp64;
+ int64_t tempDL[2];
+
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+ }
+
+ return tempI;
+}
+
+uint32_t helper_extr_s_h(int ac, int shift)
+{
+ int64_t temp;
+ uint32_t tempI;
+
+ temp = mipsdsp_rashift_short_acc(ac, shift);
+ if (temp > 0x0000000000007FFFull) {
+ temp &= MIPSDSP_LHI;
+ temp |= 0x00007FFF;
+ set_DSPControl_overflow_flag(1, 23);
+ } else if (temp < 0xFFFFFFFFFFFF8000ull) {
+ temp &= MIPSDSP_LHI;
+ temp |= 0xFFFF8000;
+ set_DSPControl_overflow_flag(1, 23);
+ }
+
+ tempI = temp & 0xFFFFFFFF;
+ return tempI;
+}
+
+uint32_t helper_extrv_s_h(int ac, uint32_t rs)
+{
+ uint32_t rd;
+ int32_t shift, tempI;
+ int64_t tempL;
+
+ shift = rs & 0x0F;
+ tempL = mipsdsp_rashift_short_acc(ac, shift);
+ if (tempL > 0x000000000007FFFull) {
+ tempI = 0x00007FFF;
+ set_DSPControl_overflow_flag(1, 23);
+ } else if (tempL < 0xFFFFFFFFFFF8000ull) {
+ tempI = 0xFFFF8000;
+ set_DSPControl_overflow_flag(1, 23);
+ }
+ rd = tempI;
+
+ return rd;
+}
+
+uint32_t helper_extrv_w(int ac, uint32_t rs)
+{
+ int32_t shift, tempI;
+ int64_t tempDL[2];
+
+ shift = rs & 0x0F;
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+
+ return tempI;
+}
+
+uint32_t helper_extrv_r_w(int ac, uint32_t rs)
+{
+ int32_t shift, tempI;
+ int64_t tempDL[2];
+
+ shift = rs & 0x0F;
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+ tempI = tempDL[0] >> 1;
+
+ return tempI;
+}
+
+uint32_t helper_extrv_rs_w(int ac, uint32_t rs)
+{
+ int32_t shift, tempI;
+ int64_t tempDL[2];
+
+ shift = rs & 0x0F;
+ mipsdsp__rashift_short_acc(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(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(1, 23);
+ }
+
+ return tempI;
+}
+
+uint32_t helper_extp(int ac, int size)
+{
+ int32_t start_pos;
+ uint32_t temp;
+ uint64_t acc;
+
+ temp = 0;
+ start_pos = get_DSPControl_pos();
+ 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(0);
+ } else {
+ set_DSPControl_efi(1);
+ }
+
+ return temp;
+}
+
+uint32_t helper_extpv(int ac, uint32_t rs)
+{
+ int32_t start_pos, size;
+ uint32_t temp;
+ uint64_t acc;
+
+ temp = 0;
+ start_pos = get_DSPControl_pos();
+ 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(0);
+ } else
+ set_DSPControl_efi(1);
+
+ return temp;
+}
+
+uint32_t helper_extpdp(int ac, int size)
+{
+ int32_t start_pos;
+ uint32_t temp;
+ uint64_t acc;
+
+ temp = 0;
+ start_pos = get_DSPControl_pos();
+ 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(start_pos - (size + 1));
+ set_DSPControl_efi(0);
+ } else
+ set_DSPControl_efi(1);
+
+ return temp;
+}
+
+uint32_t helper_extpdpv(int ac, uint32_t rs)
+{
+ int32_t start_pos, size;
+ uint32_t temp;
+ uint64_t acc;
+
+ temp = 0;
+ start_pos = get_DSPControl_pos();
+ 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(start_pos - (size + 1));
+ set_DSPControl_efi(0);
+ } else
+ set_DSPControl_efi(1);
+
+ return temp;
+}
+
+void helper_shilo(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(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(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();
+
+ if (pos > 32)
+ return;
+ else
+ set_DSPControl_pos(pos + 32);
+}
+
+void helper_wrdsp(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(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 36d6c19..8fab999 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -441,5 +441,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_2(extr_w, i32, int, int)
+DEF_HELPER_2(extr_r_w, i32, int, int)
+DEF_HELPER_2(extr_rs_w, i32, int, int)
+DEF_HELPER_2(extr_s_h, i32, int, int)
+DEF_HELPER_2(extrv_s_h, i32, int, i32)
+DEF_HELPER_2(extrv_w, i32, int, i32)
+DEF_HELPER_2(extrv_r_w, i32, int, i32)
+DEF_HELPER_2(extrv_rs_w, i32, int, i32)
+DEF_HELPER_2(extp, i32, int, int)
+DEF_HELPER_2(extpv, i32, int, i32)
+DEF_HELPER_2(extpdp, i32, int, int)
+DEF_HELPER_2(extpdpv, i32, int, i32)
+DEF_HELPER_2(shilo, void, int, int)
+DEF_HELPER_2(shilov, void, int, i32)
+DEF_HELPER_2(mthlip, void, int, i32)
+DEF_HELPER_2(wrdsp, void, i32, int)
+DEF_HELPER_1(rddsp, i32, i32)
#include "def-helper.h"
--
1.7.5.4
next prev parent reply other threads:[~2012-03-27 9:27 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-27 9:24 [Qemu-devel] [PATCH V3 00/12] Qemu MIPS ASE DSP Support Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 01/12] add MIPS DSP internal functions Jia Liu
2012-03-27 15:33 ` Richard Henderson
2012-03-28 2:03 ` Jia Liu
2012-03-29 11:16 ` Richard Henderson
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 02/12] Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number Jia Liu
2012-03-27 15:34 ` Richard Henderson
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 03/12] Add MIPS DSP Branch instruction Support Jia Liu
2012-03-27 15:46 ` Richard Henderson
2012-03-28 1:27 ` Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 04/12] Add MIPS DSP Load instructions Support Jia Liu
2012-03-27 15:49 ` Richard Henderson
2012-03-28 1:46 ` Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 05/12] Add helper functions for MIPS DSP Arithmetic instructions Jia Liu
2012-03-27 16:03 ` Richard Henderson
2012-03-28 1:45 ` Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 06/12] Add helper functions for MIPS DSP GPR-Based Shift instructions Jia Liu
2012-03-27 16:11 ` Richard Henderson
2012-03-28 1:43 ` Jia Liu
2012-03-29 13:09 ` Richard Henderson
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 07/12] Add helper functions for MIPS DSP Multiply instructions Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 08/12] Add helper functions for MIPS DSP Bit/Manipulation instructions Jia Liu
2012-03-27 16:23 ` Richard Henderson
2012-03-28 1:47 ` Jia Liu
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 09/12] Add helper functions for MIPS DSP Compare-Pick instructions Jia Liu
2012-03-27 17:42 ` Richard Henderson
2012-03-28 1:52 ` Jia Liu
2012-03-27 9:24 ` Jia Liu [this message]
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 11/12] Handle MIPS DSP instructions in target-mips/translate.c Jia Liu
2012-03-27 17:48 ` Richard Henderson
2012-03-28 1:36 ` Jia Liu
2012-03-29 13:20 ` Richard Henderson
2012-03-27 9:24 ` [Qemu-devel] [PATCH V3 12/12] add MIPS DSP testcases Jia Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1332840290-24553-11-git-send-email-proljc@gmail.com \
--to=proljc@gmail.com \
--cc=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).