diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2015-06-03 23:09:47 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2015-06-05 01:37:59 +0200 |
commit | 54f007750978ffbb98ce933077e0d1741e0202b0 (patch) | |
tree | 3b4cfd1d974255f0ffe2a200e2402b7567d060d0 /target-s390x/mem_helper.c | |
parent | ed0bcecec105137567f461e5b57834e72c851855 (diff) |
target-s390x: implement TRANSLATE AND TEST instruction
It is part of the basic zArchitecture instructions. Allow it to be call
from EXECUTE.
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-s390x/mem_helper.c')
-rw-r--r-- | target-s390x/mem_helper.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index 0e8cd0f489..e19e1aa961 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -509,6 +509,9 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1, case 0xc00: helper_tr(env, l, get_address(env, 0, b1, d1), get_address(env, 0, b2, d2)); + case 0xd00: + cc = helper_trt(env, l, get_address(env, 0, b1, d1), + get_address(env, 0, b2, d2)); break; default: goto abort; @@ -801,6 +804,27 @@ void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array, } } +uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array, + uint64_t trans) +{ + uint32_t cc = 0; + int i; + + for (i = 0; i <= len; i++) { + uint8_t byte = cpu_ldub_data(env, array + i); + uint8_t sbyte = cpu_ldub_data(env, trans + byte); + + if (sbyte != 0) { + env->regs[1] = array + i; + env->regs[2] = (env->regs[2] & ~0xff) | sbyte; + cc = (i == len) ? 2 : 1; + break; + } + } + + return cc; +} + #if !defined(CONFIG_USER_ONLY) void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) { |