From b5edcddda31b464e73cc0a79e88457e603c3b247 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 16 Jun 2015 22:57:47 +0200 Subject: [PATCH 1/4] target-s390x: fix MOVE LONG instruction The MOVE LONG instruction should pad the destination operand with the byte from bit positions 32-39 of the source length (r2 + 1), not with the same byte in the source address. Signed-off-by: Aurelien Jarno Reviewed-by: Richard Henderson Signed-off-by: Alexander Graf --- target-s390x/mem_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index 3ccbeb99e4..9f0eb1e32b 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -550,7 +550,7 @@ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) uint64_t dest = get_address_31fix(env, r1); uint64_t srclen = env->regs[r2 + 1] & 0xffffff; uint64_t src = get_address_31fix(env, r2); - uint8_t pad = src >> 24; + uint8_t pad = env->regs[r2 + 1] >> 24; uint8_t v; uint32_t cc; From c9c19b493286db7358f9ee26401b927bbbd21604 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 21 Jun 2015 18:51:08 +0200 Subject: [PATCH 2/4] target-s390x: fix EXECUTE instruction executing TRT A break is missing in the EXECUTE instruction, when executing the TRANSLATE AND TEST instruction. Reported-by: Paolo Bonzini Signed-off-by: Aurelien Jarno Reviewed-By: Richard Henderson Signed-off-by: Alexander Graf --- target-s390x/mem_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index 9f0eb1e32b..6f8bd796ad 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -482,6 +482,7 @@ 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)); + break; case 0xd00: cc = helper_trt(env, l, get_address(env, 0, b1, d1), get_address(env, 0, b2, d2)); From 92f2b4e71e988ad2751c71717e9fe3387753442a Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Thu, 25 Jun 2015 21:16:58 +0200 Subject: [PATCH 3/4] target-s390x: fix CONVERT TO BINARY (CVD, CVDY) current_number being shift left by more than 32 bits, we can't use a simple int. Similarly use an int64_t type for the input binary value, to not get the -2^31 case wrong. Finally don't initialize shift to 4, it's already done in the for loop. Signed-off-by: Aurelien Jarno Reviewed-by: Richard Henderson Signed-off-by: Alexander Graf --- target-s390x/int_helper.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c index 2c2b3f622c..a46c736d67 100644 --- a/target-s390x/int_helper.c +++ b/target-s390x/int_helper.c @@ -121,11 +121,12 @@ uint64_t HELPER(clz)(uint64_t v) return clz64(v); } -uint64_t HELPER(cvd)(int32_t bin) +uint64_t HELPER(cvd)(int32_t reg) { /* positive 0 */ uint64_t dec = 0x0c; - int shift = 4; + int64_t bin = reg; + int shift; if (bin < 0) { bin = -bin; @@ -133,9 +134,7 @@ uint64_t HELPER(cvd)(int32_t bin) } for (shift = 4; (shift < 64) && bin; shift += 4) { - int current_number = bin % 10; - - dec |= (current_number) << shift; + dec |= (bin % 10) << shift; bin /= 10; } From cd3b29b745b0ff393b2d37317837bc726b8dacc8 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 16 Jun 2015 07:11:41 +0200 Subject: [PATCH 4/4] tcg/s390: fix branch target change during code retranslation Make sure to not modify the branch target. This ensure that the branch target is not corrupted during partial retranslation. Signed-off-by: Aurelien Jarno Tested-by: Alexander Graf Reviewed-by: Richard Henderson Signed-off-by: Alexander Graf --- tcg/s390/tcg-target.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 669fafe24f..921991ebfa 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -1643,8 +1643,10 @@ static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1); - label_ptr = s->code_ptr + 1; - tcg_out_insn(s, RI, BRC, S390_CC_NE, 0); + /* We need to keep the offset unchanged for retranslation. */ + tcg_out16(s, RI_BRC | (S390_CC_NE << 4)); + label_ptr = s->code_ptr; + s->code_ptr += 1; tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0); @@ -1669,8 +1671,10 @@ static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0); - label_ptr = s->code_ptr + 1; - tcg_out_insn(s, RI, BRC, S390_CC_NE, 0); + /* We need to keep the offset unchanged for retranslation. */ + tcg_out16(s, RI_BRC | (S390_CC_NE << 4)); + label_ptr = s->code_ptr; + s->code_ptr += 1; tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);