aboutsummaryrefslogtreecommitdiff
path: root/target-tilegx/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-tilegx/helper.c')
-rw-r--r--target-tilegx/helper.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/target-tilegx/helper.c b/target-tilegx/helper.c
index a01bb8d513..dda821f5cb 100644
--- a/target-tilegx/helper.c
+++ b/target-tilegx/helper.c
@@ -21,6 +21,8 @@
#include "cpu.h"
#include "qemu-common.h"
#include "exec/helper-proto.h"
+#include <zlib.h> /* For crc32 */
+#include "syscall_defs.h"
void helper_exception(CPUTLGState *env, uint32_t excp)
{
@@ -30,6 +32,27 @@ void helper_exception(CPUTLGState *env, uint32_t excp)
cpu_loop_exit(cs);
}
+void helper_ext01_ics(CPUTLGState *env)
+{
+ uint64_t val = env->spregs[TILEGX_SPR_EX_CONTEXT_0_1];
+
+ switch (val) {
+ case 0:
+ case 1:
+ env->spregs[TILEGX_SPR_CRITICAL_SEC] = val;
+ break;
+ default:
+#if defined(CONFIG_USER_ONLY)
+ env->signo = TARGET_SIGILL;
+ env->sigcode = TARGET_ILL_ILLOPC;
+ helper_exception(env, TILEGX_EXCP_SIGNAL);
+#else
+ helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED);
+#endif
+ break;
+ }
+}
+
uint64_t helper_cntlz(uint64_t arg)
{
return clz64(arg);
@@ -78,3 +101,61 @@ uint64_t helper_shufflebytes(uint64_t dest, uint64_t srca, uint64_t srcb)
return vdst;
}
+
+uint64_t helper_crc32_8(uint64_t accum, uint64_t input)
+{
+ uint8_t buf = input;
+
+ /* zlib crc32 converts the accumulator and output to one's complement. */
+ return crc32(accum ^ 0xffffffff, &buf, 1) ^ 0xffffffff;
+}
+
+uint64_t helper_crc32_32(uint64_t accum, uint64_t input)
+{
+ uint8_t buf[4];
+
+ stl_le_p(buf, input);
+
+ /* zlib crc32 converts the accumulator and output to one's complement. */
+ return crc32(accum ^ 0xffffffff, buf, 4) ^ 0xffffffff;
+}
+
+uint64_t helper_cmula(uint64_t srcd, uint64_t srca, uint64_t srcb)
+{
+ uint32_t reala = (int16_t)srca;
+ uint32_t imaga = (int16_t)(srca >> 16);
+ uint32_t realb = (int16_t)srcb;
+ uint32_t imagb = (int16_t)(srcb >> 16);
+ uint32_t reald = srcd;
+ uint32_t imagd = srcd >> 32;
+ uint32_t realr = reala * realb - imaga * imagb + reald;
+ uint32_t imagr = reala * imagb + imaga * realb + imagd;
+
+ return deposit64(realr, 32, 32, imagr);
+}
+
+uint64_t helper_cmulaf(uint64_t srcd, uint64_t srca, uint64_t srcb)
+{
+ uint32_t reala = (int16_t)srca;
+ uint32_t imaga = (int16_t)(srca >> 16);
+ uint32_t realb = (int16_t)srcb;
+ uint32_t imagb = (int16_t)(srcb >> 16);
+ uint32_t reald = (int16_t)srcd;
+ uint32_t imagd = (int16_t)(srcd >> 16);
+ int32_t realr = reala * realb - imaga * imagb;
+ int32_t imagr = reala * imagb + imaga * realb;
+
+ return deposit32((realr >> 15) + reald, 16, 16, (imagr >> 15) + imagd);
+}
+
+uint64_t helper_cmul2(uint64_t srca, uint64_t srcb, int shift, int round)
+{
+ uint32_t reala = (int16_t)srca;
+ uint32_t imaga = (int16_t)(srca >> 16);
+ uint32_t realb = (int16_t)srcb;
+ uint32_t imagb = (int16_t)(srcb >> 16);
+ int32_t realr = reala * realb - imaga * imagb + round;
+ int32_t imagr = reala * imagb + imaga * realb + round;
+
+ return deposit32(realr >> shift, 16, 16, imagr >> shift);
+}