summaryrefslogtreecommitdiff
path: root/target-tricore/op_helper.c
diff options
context:
space:
mode:
authorBastian Koppelmann <kbastian@mail.uni-paderborn.de>2014-09-26 20:36:09 +0100
committerBastian Koppelmann <kbastian@mail.uni-paderborn.de>2014-10-20 12:25:07 +0100
commit3a16ecb06355d0bfc8b547eba094ebaa44dce39f (patch)
tree12b8a1f2134b0e6cf4ce0ec71cf876a2cc38eadd /target-tricore/op_helper.c
parentb74f2b5bb3b7b806a896c97386a597205055bb9e (diff)
downloadqemu-3a16ecb06355d0bfc8b547eba094ebaa44dce39f.tar.gz
target-tricore: Add instructions of BO opcode format
Add instructions of BO opcode format. Add microcode generator functions gen_swap, gen_ldmst. Add microcode generator functions gen_st/ld_preincr, which write back the address after the memory access. Add helper for circular and bit reverse addr mode calculation. Add sign extended bitmask for BO_OFF10 field. 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.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 94b5d8e12e..a36988aa1b 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,42 @@
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
+/* Addressing mode helper */
+
+static uint16_t reverse16(uint16_t val)
+{
+ uint8_t high = (uint8_t)(val >> 8);
+ uint8_t low = (uint8_t)(val & 0xff);
+
+ uint16_t rh, rl;
+
+ rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+ rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+ return (rh << 8) | rl;
+}
+
+uint32_t helper_br_update(uint32_t reg)
+{
+ uint32_t index = reg & 0xffff;
+ uint32_t incr = reg >> 16;
+ uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
+ return reg - index + new_index;
+}
+
+uint32_t helper_circ_update(uint32_t reg, uint32_t off)
+{
+ uint32_t index = reg & 0xffff;
+ uint32_t length = reg >> 16;
+ int32_t new_index = index + off;
+ if (new_index < 0) {
+ new_index += length;
+ } else {
+ new_index %= length;
+ }
+ return reg - index + new_index;
+}
+
#define SSOV(env, ret, arg, len) do { \
int64_t max_pos = INT##len ##_MAX; \
int64_t max_neg = INT##len ##_MIN; \