summaryrefslogtreecommitdiffstats
path: root/target-tricore/op_helper.c
diff options
context:
space:
mode:
authorBastian Koppelmann2014-11-28 18:07:26 +0100
committerBastian Koppelmann2014-12-21 19:34:48 +0100
commit0b79a78169d813d11ad32f103e7a2c64c32bd705 (patch)
tree82576e305f416ea3d6b8e643f8f4c088a8c2450d /target-tricore/op_helper.c
parenttarget-tricore: Add instructions of RR opcode format, that have 0xb as the fi... (diff)
downloadqemu-0b79a78169d813d11ad32f103e7a2c64c32bd705.tar.gz
qemu-0b79a78169d813d11ad32f103e7a2c64c32bd705.tar.xz
qemu-0b79a78169d813d11ad32f103e7a2c64c32bd705.zip
target-tricore: Add instructions of RR opcode format, that have 0xf as the first opcode
Add instructions of RR opcode format, that have 0xf as the first opcode. Add helper functions: * clo/z/s: Counts leading ones/zeros/signs. * clo/z/s_h: Count leading ones/zeros/signs in two haflwords. * sh/_h: Shifts one/two word/hwords. * sha/_h: Shifts one/two word/hwords arithmeticly. Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-tricore/op_helper.c')
-rw-r--r--target-tricore/op_helper.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 26e01ed1b9..98f28d5623 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -873,6 +873,166 @@ EXTREMA_H_B(min, <)
#undef EXTREMA_H_B
+uint32_t helper_clo(target_ulong r1)
+{
+ return clo32(r1);
+}
+
+uint32_t helper_clo_h(target_ulong r1)
+{
+ uint32_t ret_hw0 = extract32(r1, 0, 16);
+ uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+ ret_hw0 = clo32(ret_hw0 << 16);
+ ret_hw1 = clo32(ret_hw1 << 16);
+
+ if (ret_hw0 > 16) {
+ ret_hw0 = 16;
+ }
+ if (ret_hw1 > 16) {
+ ret_hw1 = 16;
+ }
+
+ return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_clz(target_ulong r1)
+{
+ return clz32(r1);
+}
+
+uint32_t helper_clz_h(target_ulong r1)
+{
+ uint32_t ret_hw0 = extract32(r1, 0, 16);
+ uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+ ret_hw0 = clz32(ret_hw0 << 16);
+ ret_hw1 = clz32(ret_hw1 << 16);
+
+ if (ret_hw0 > 16) {
+ ret_hw0 = 16;
+ }
+ if (ret_hw1 > 16) {
+ ret_hw1 = 16;
+ }
+
+ return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_cls(target_ulong r1)
+{
+ return clrsb32(r1);
+}
+
+uint32_t helper_cls_h(target_ulong r1)
+{
+ uint32_t ret_hw0 = extract32(r1, 0, 16);
+ uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+ ret_hw0 = clrsb32(ret_hw0 << 16);
+ ret_hw1 = clrsb32(ret_hw1 << 16);
+
+ if (ret_hw0 > 15) {
+ ret_hw0 = 15;
+ }
+ if (ret_hw1 > 15) {
+ ret_hw1 = 15;
+ }
+
+ return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_sh(target_ulong r1, target_ulong r2)
+{
+ int32_t shift_count = sextract32(r2, 0, 6);
+
+ if (shift_count == -32) {
+ return 0;
+ } else if (shift_count < 0) {
+ return r1 >> -shift_count;
+ } else {
+ return r1 << shift_count;
+ }
+}
+
+uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
+{
+ int32_t ret_hw0, ret_hw1;
+ int32_t shift_count;
+
+ shift_count = sextract32(r2, 0, 5);
+
+ if (shift_count == -16) {
+ return 0;
+ } else if (shift_count < 0) {
+ ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
+ ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
+ return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+ } else {
+ ret_hw0 = extract32(r1, 0, 16) << shift_count;
+ ret_hw1 = extract32(r1, 16, 16) << shift_count;
+ return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+ }
+}
+
+uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
+{
+ int32_t shift_count;
+ int64_t result, t1;
+ uint32_t ret;
+
+ shift_count = sextract32(r2, 0, 6);
+ t1 = sextract32(r1, 0, 32);
+
+ if (shift_count == 0) {
+ env->PSW_USB_C = env->PSW_USB_V = 0;
+ ret = r1;
+ } else if (shift_count == -32) {
+ env->PSW_USB_C = r1;
+ env->PSW_USB_V = 0;
+ ret = t1 >> 31;
+ } else if (shift_count > 0) {
+ result = t1 << shift_count;
+ /* calc carry */
+ env->PSW_USB_C = ((result & 0xffffffff00000000) != 0);
+ /* calc v */
+ env->PSW_USB_V = (((result > 0x7fffffffLL) ||
+ (result < -0x80000000LL)) << 31);
+ /* calc sv */
+ env->PSW_USB_SV |= env->PSW_USB_V;
+ ret = (uint32_t)result;
+ } else {
+ env->PSW_USB_V = 0;
+ env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
+ ret = t1 >> -shift_count;
+ }
+
+ env->PSW_USB_AV = ret ^ ret * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+ return ret;
+}
+
+uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
+{
+ int32_t shift_count;
+ int32_t ret_hw0, ret_hw1;
+
+ shift_count = sextract32(r2, 0, 5);
+
+ if (shift_count == 0) {
+ return r1;
+ } else if (shift_count < 0) {
+ ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
+ ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
+ return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+ } else {
+ ret_hw0 = sextract32(r1, 0, 16) << shift_count;
+ ret_hw1 = sextract32(r1, 16, 16) << shift_count;
+ return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+ }
+}
+
/* context save area (CSA) related helpers */
static int cdc_increment(target_ulong *psw)