target/s390x: Fix EXECUTE of relative long instructions
The code uses the wrong base for relative addressing: it should use the target instruction address and not the EXECUTE's address. Fix by storing the target instruction address in the new CPUS390XState member and loading it from the code generated by gen_ri2(). Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: David Hildenbrand <david@redhat.com> Message-Id: <20230316210751.302423-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
04fce706bd
commit
703d03a4aa
@ -87,6 +87,7 @@ struct CPUArchState {
|
|||||||
uint64_t cc_vr;
|
uint64_t cc_vr;
|
||||||
|
|
||||||
uint64_t ex_value;
|
uint64_t ex_value;
|
||||||
|
uint64_t ex_target;
|
||||||
|
|
||||||
uint64_t __excp_addr;
|
uint64_t __excp_addr;
|
||||||
uint64_t psa;
|
uint64_t psa;
|
||||||
|
@ -2530,6 +2530,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
|
|||||||
that ex_value is non-zero, which flags that we are in a state
|
that ex_value is non-zero, which flags that we are in a state
|
||||||
that requires such execution. */
|
that requires such execution. */
|
||||||
env->ex_value = insn | ilen;
|
env->ex_value = insn | ilen;
|
||||||
|
env->ex_target = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
|
uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
|
||||||
|
@ -5769,7 +5769,18 @@ static void in2_a2(DisasContext *s, DisasOps *o)
|
|||||||
|
|
||||||
static TCGv gen_ri2(DisasContext *s)
|
static TCGv gen_ri2(DisasContext *s)
|
||||||
{
|
{
|
||||||
return tcg_constant_i64(s->base.pc_next + (int64_t)get_field(s, i2) * 2);
|
int64_t delta = (int64_t)get_field(s, i2) * 2;
|
||||||
|
TCGv ri2;
|
||||||
|
|
||||||
|
if (unlikely(s->ex_value)) {
|
||||||
|
ri2 = tcg_temp_new_i64();
|
||||||
|
tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
|
||||||
|
tcg_gen_addi_i64(ri2, ri2, delta);
|
||||||
|
} else {
|
||||||
|
ri2 = tcg_constant_i64(s->base.pc_next + delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ri2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void in2_ri2(DisasContext *s, DisasOps *o)
|
static void in2_ri2(DisasContext *s, DisasOps *o)
|
||||||
|
Loading…
Reference in New Issue
Block a user