diff options
author | Richard Henderson <rth@twiddle.net> | 2012-08-22 09:15:19 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-01-05 12:18:38 -0800 |
commit | cbe24bfa91d21766f2953c2da92c1e3dd13d8387 (patch) | |
tree | d8ccab5a23c7bb496563bcfeb3f0ed7dd2146916 /target-s390x/cc_helper.c | |
parent | 972e35b9665db113c3d4df7d394ee8cbbf7446ee (diff) | |
download | qemu-cbe24bfa91d21766f2953c2da92c1e3dd13d8387.zip qemu-cbe24bfa91d21766f2953c2da92c1e3dd13d8387.tar.gz qemu-cbe24bfa91d21766f2953c2da92c1e3dd13d8387.tar.bz2 |
target-s390: Convert SHIFT, ROTATE SINGLE
Note that we were missing the 32-bit SLA.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-s390x/cc_helper.c')
-rw-r--r-- | target-s390x/cc_helper.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c index 575f7c3..be4202a 100644 --- a/target-s390x/cc_helper.c +++ b/target-s390x/cc_helper.c @@ -345,34 +345,59 @@ static uint32_t cc_calc_icm(uint64_t mask, uint64_t val) } } -static uint32_t cc_calc_slag(uint64_t src, uint64_t shift) +static uint32_t cc_calc_sla_32(uint32_t src, int shift) { - uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift); - uint64_t match, r; + uint32_t mask = ((1U << shift) - 1U) << (32 - shift); + uint32_t sign = 1U << 31; + uint32_t match; + int32_t r; - /* check if the sign bit stays the same */ - if (src & (1ULL << 63)) { + /* Check if the sign bit stays the same. */ + if (src & sign) { match = mask; } else { match = 0; } - if ((src & mask) != match) { - /* overflow */ + /* Overflow. */ return 3; } - r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63)); - - if ((int64_t)r == 0) { + r = ((src << shift) & ~sign) | (src & sign); + if (r == 0) { return 0; - } else if ((int64_t)r < 0) { + } else if (r < 0) { return 1; } - return 2; } +static uint32_t cc_calc_sla_64(uint64_t src, int shift) +{ + uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift); + uint64_t sign = 1ULL << 63; + uint64_t match; + int64_t r; + + /* Check if the sign bit stays the same. */ + if (src & sign) { + match = mask; + } else { + match = 0; + } + if ((src & mask) != match) { + /* Overflow. */ + return 3; + } + + r = ((src << shift) & ~sign) | (src & sign); + if (r == 0) { + return 0; + } else if (r < 0) { + return 1; + } + return 2; +} static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst, uint64_t vr) @@ -473,8 +498,11 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, case CC_OP_ICM: r = cc_calc_icm(src, dst); break; - case CC_OP_SLAG: - r = cc_calc_slag(src, dst); + case CC_OP_SLA_32: + r = cc_calc_sla_32(src, dst); + break; + case CC_OP_SLA_64: + r = cc_calc_sla_64(src, dst); break; case CC_OP_LTGT_F32: |