[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 54/70] target/s390x: fix COMPARE LOGICAL LONG EXTE
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PULL v2 54/70] target/s390x: fix COMPARE LOGICAL LONG EXTENDED |
Date: |
Tue, 6 Jun 2017 17:31:03 -0700 |
From: Aurelien Jarno <address@hidden>
There are multiple issues with the COMPARE LOGICAL LONG EXTENDED
instruction:
- The test between the two operands is inverted, leading to an inversion
of the cc values 1 and 2.
- The address and length of an operand continue to be decreased after
reaching the end of this operand. These values are then wrong write
back to the registers.
- We should limit the amount of bytes to process, so that interrupts can
be served correctly.
At the same time rename dest into src1 and src into src3 to match the
operand names and make the code less confusing.
Reviewed-by: Richard Henderson <address@hidden>
Signed-off-by: Aurelien Jarno <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
target/s390x/mem_helper.c | 54 ++++++++++++++++++++++++++++++++---------------
target/s390x/translate.c | 20 +++++++++++++-----
2 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 83c32c4..e30020c 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -666,35 +666,55 @@ uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1,
uint64_t a2,
uint32_t r3)
{
uintptr_t ra = GETPC();
- uint64_t destlen = get_length(env, r1 + 1);
- uint64_t dest = get_address(env, r1);
- uint64_t srclen = get_length(env, r3 + 1);
- uint64_t src = get_address(env, r3);
+ uint64_t src1len = get_length(env, r1 + 1);
+ uint64_t src1 = get_address(env, r1);
+ uint64_t src3len = get_length(env, r3 + 1);
+ uint64_t src3 = get_address(env, r3);
uint8_t pad = a2 & 0xff;
+ uint64_t len = MAX(src1len, src3len);
uint32_t cc = 0;
- if (!(destlen || srclen)) {
+ if (!len) {
return cc;
}
- if (srclen > destlen) {
- srclen = destlen;
+ /* Lest we fail to service interrupts in a timely manner, limit the
+ amount of work we're willing to do. For now, let's cap at 8k. */
+ if (len > 0x2000) {
+ len = 0x2000;
+ cc = 3;
}
- for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
- uint8_t v1 = srclen ? cpu_ldub_data_ra(env, src, ra) : pad;
- uint8_t v2 = destlen ? cpu_ldub_data_ra(env, dest, ra) : pad;
- if (v1 != v2) {
- cc = (v1 < v2) ? 1 : 2;
+ for (; len; len--) {
+ uint8_t v1 = pad;
+ uint8_t v3 = pad;
+
+ if (src1len) {
+ v1 = cpu_ldub_data_ra(env, src1, ra);
+ }
+ if (src3len) {
+ v3 = cpu_ldub_data_ra(env, src3, ra);
+ }
+
+ if (v1 != v3) {
+ cc = (v1 < v3) ? 1 : 2;
break;
}
+
+ if (src1len) {
+ src1++;
+ src1len--;
+ }
+ if (src3len) {
+ src3++;
+ src3len--;
+ }
}
- set_length(env, r1 + 1, destlen);
- /* can't use srclen here, we trunc'ed it */
- set_length(env, r3 + 1, env->regs[r3 + 1] - src - env->regs[r3]);
- set_address(env, r1, dest);
- set_address(env, r3, src);
+ set_length(env, r1 + 1, src1len);
+ set_length(env, r3 + 1, src3len);
+ set_address(env, r1, src1);
+ set_address(env, r3, src3);
return cc;
}
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index a21de09..ecd0a91 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1922,11 +1922,21 @@ static ExitStatus op_clc(DisasContext *s, DisasOps *o)
static ExitStatus op_clcle(DisasContext *s, DisasOps *o)
{
- TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
- TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
- gen_helper_clcle(cc_op, cpu_env, r1, o->in2, r3);
- tcg_temp_free_i32(r1);
- tcg_temp_free_i32(r3);
+ int r1 = get_field(s->fields, r1);
+ int r3 = get_field(s->fields, r3);
+ TCGv_i32 t1, t3;
+
+ /* r1 and r3 must be even. */
+ if (r1 & 1 || r3 & 1) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return EXIT_NORETURN;
+ }
+
+ t1 = tcg_const_i32(r1);
+ t3 = tcg_const_i32(r3);
+ gen_helper_clcle(cc_op, cpu_env, t1, o->in2, t3);
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(t3);
set_cc_static(s);
return NO_EXIT;
}
--
2.9.4
- [Qemu-devel] [PULL v2 43/70] target/s390x: implement TEST AND SET, (continued)
- [Qemu-devel] [PULL v2 43/70] target/s390x: implement TEST AND SET, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 42/70] target/s390x: implement local-TLB-clearing in IPTE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 44/70] target/s390x: implement TEST ADDRESSING MODE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 45/70] target/s390x: implement PACK, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 46/70] target/s390x: implement COMPARE AND SIGNAL, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 48/70] target/s390x: implement MOVE NUMERICS, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 47/70] target/s390x: implement MOVE INVERSE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 49/70] target/s390x: implement MOVE WITH OFFSET, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 50/70] target/s390x: implement MOVE ZONES, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 51/70] target/s390x: improve 24-bit and 31-bit addresses read, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 54/70] target/s390x: fix COMPARE LOGICAL LONG EXTENDED,
Richard Henderson <=
- [Qemu-devel] [PULL v2 52/70] target/s390x: improve 24-bit and 31-bit addresses write, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 53/70] target/s390x: improve 24-bit and 31-bit lengths read/write, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 55/70] target/s390x: implement COMPARE LOGICAL LONG, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 56/70] target/s390x: fix adj_len_to_page, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 59/70] target/s390x: implement MOVE LONG UNICODE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 58/70] target/s390x: implement COMPARE LOGICAL LONG UNICODE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 57/70] target/s390x: improve MOVE LONG and MOVE LONG EXTENDED, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 60/70] target/s390x: implement PACK ASCII, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 61/70] target/s390x: implement PACK UNICODE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 62/70] target/s390x: implement UNPACK ASCII, Richard Henderson, 2017/06/06