aboutsummaryrefslogtreecommitdiff
path: root/target-mips/dsp_helper.c
diff options
context:
space:
mode:
authorJia Liu <proljc@gmail.com>2012-10-24 22:17:09 +0800
committerAurelien Jarno <aurelien@aurel32.net>2012-10-31 21:37:18 +0100
commit1cb6686cf926e0efc2056405a0a76dd41eb65d89 (patch)
tree7b3bb92fe62144e9ce3cbff72d17c46a02aaadb1 /target-mips/dsp_helper.c
parenta22260ae380fa6abb546479cfc2962ba4c40382d (diff)
target-mips: Add ASE DSP bit/manipulation instructions
Add MIPS ASE DSP Bit/Manipulation instructions. Signed-off-by: Jia Liu <proljc@gmail.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-mips/dsp_helper.c')
-rw-r--r--target-mips/dsp_helper.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 86c27ec0e8..919ff299f6 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3112,6 +3112,61 @@ DM_OPERATE(dmsubu, mul_u32_u32, 0, 0);
#undef DM_OPERATE
#endif
+/** DSP Bit/Manipulation Sub-class insns **/
+target_ulong helper_bitrev(target_ulong rt)
+{
+ int32_t temp;
+ uint32_t rd;
+ int i;
+
+ temp = rt & MIPSDSP_LO;
+ rd = 0;
+ for (i = 0; i < 16; i++) {
+ rd = (rd << 1) | (temp & 1);
+ temp = temp >> 1;
+ }
+
+ return (target_ulong)rd;
+}
+
+#define BIT_INSV(name, posfilter, sizefilter, ret_type) \
+target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
+ target_ulong rt) \
+{ \
+ uint32_t pos, size, msb, lsb; \
+ target_ulong filter; \
+ target_ulong temp, temprs, temprt; \
+ target_ulong dspc; \
+ \
+ dspc = env->active_tc.DSPControl; \
+ \
+ pos = dspc & posfilter; \
+ size = (dspc >> 7) & sizefilter; \
+ \
+ msb = pos + size - 1; \
+ lsb = pos; \
+ \
+ if (lsb > msb || (msb > TARGET_LONG_BITS)) { \
+ return rt; \
+ } \
+ \
+ filter = ((int32_t)0x01 << size) - 1; \
+ filter = filter << pos; \
+ temprs = rs & filter; \
+ temprt = rt & ~filter; \
+ temp = temprs | temprt; \
+ \
+ return (target_long)(ret_type)temp; \
+}
+
+BIT_INSV(insv, 0x1F, 0x1F, int32_t);
+#ifdef TARGET_MIPS64
+BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
+#endif
+
+#undef BIT_INSV
+
+
#undef MIPSDSP_LHI
#undef MIPSDSP_LLO
#undef MIPSDSP_HI