提交 2bb525e2 编写于 作者: D David Hildenbrand

s390x/tcg: MVST: Fix storing back the addresses to registers

24 and 31-bit address space handling is wrong when it comes to storing
back the addresses to the register.

While at it, read gprs 0 implicitly.
Reviewed-by: NRichard Henderson <richard.henderson@linaro.org>
Signed-off-by: NDavid Hildenbrand <david@redhat.com>
上级 087b8193
...@@ -20,7 +20,7 @@ DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64) ...@@ -20,7 +20,7 @@ DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(mvpg, TCG_CALL_NO_WG, i32, env, i64, i64, i64) DEF_HELPER_FLAGS_4(mvpg, TCG_CALL_NO_WG, i32, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mvz, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(mvz, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_4(mvst, i64, env, i64, i64, i64) DEF_HELPER_3(mvst, i32, env, i32, i32)
DEF_HELPER_4(ex, void, env, i32, i64, i64) DEF_HELPER_4(ex, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(lam, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_4(lam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
......
...@@ -637,7 +637,7 @@ ...@@ -637,7 +637,7 @@
/* MOVE PAGE */ /* MOVE PAGE */
C(0xb254, MVPG, RRE, Z, r1_o, r2_o, 0, 0, mvpg, 0) C(0xb254, MVPG, RRE, Z, r1_o, r2_o, 0, 0, mvpg, 0)
/* MOVE STRING */ /* MOVE STRING */
C(0xb255, MVST, RRE, Z, r1_o, r2_o, 0, 0, mvst, 0) C(0xb255, MVST, RRE, Z, 0, 0, 0, 0, mvst, 0)
/* MOVE WITH OPTIONAL SPECIFICATION */ /* MOVE WITH OPTIONAL SPECIFICATION */
C(0xc800, MVCOS, SSF, MVCOS, la1, a2, 0, 0, mvcos, 0) C(0xc800, MVCOS, SSF, MVCOS, la1, a2, 0, 0, mvcos, 0)
/* MOVE WITH OFFSET */ /* MOVE WITH OFFSET */
......
...@@ -700,18 +700,18 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2) ...@@ -700,18 +700,18 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
return 0; /* data moved */ return 0; /* data moved */
} }
/* string copy (c is string terminator) */ /* string copy */
uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s) uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{ {
const uint64_t d = get_address(env, r1);
const uint64_t s = get_address(env, r2);
const uint8_t c = env->regs[0];
uintptr_t ra = GETPC(); uintptr_t ra = GETPC();
uint32_t len; uint32_t len;
if (c & 0xffffff00ull) { if (env->regs[0] & 0xffffff00ull) {
s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra); s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
} }
c = c & 0xff;
d = wrap_address(env, d);
s = wrap_address(env, s);
/* Lest we fail to service interrupts in a timely manner, limit the /* 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. */ amount of work we're willing to do. For now, let's cap at 8k. */
...@@ -719,17 +719,13 @@ uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s) ...@@ -719,17 +719,13 @@ uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s)
uint8_t v = cpu_ldub_data_ra(env, s + len, ra); uint8_t v = cpu_ldub_data_ra(env, s + len, ra);
cpu_stb_data_ra(env, d + len, v, ra); cpu_stb_data_ra(env, d + len, v, ra);
if (v == c) { if (v == c) {
/* Complete. Set CC=1 and advance R1. */ set_address_zero(env, r1, d + len);
env->cc_op = 1; return 1;
env->retxl = s;
return d + len;
} }
} }
set_address_zero(env, r1, d + len);
/* Incomplete. Set CC=3 and signal to advance R1 and R2. */ set_address_zero(env, r2, s + len);
env->cc_op = 3; return 3;
env->retxl = s + len;
return d + len;
} }
/* load access registers r1 to r3 from memory at a2 */ /* load access registers r1 to r3 from memory at a2 */
......
...@@ -3488,9 +3488,13 @@ static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o) ...@@ -3488,9 +3488,13 @@ static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o)
static DisasJumpType op_mvst(DisasContext *s, DisasOps *o) static DisasJumpType op_mvst(DisasContext *s, DisasOps *o)
{ {
gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2); TCGv_i32 t1 = tcg_const_i32(get_field(s->fields, r1));
TCGv_i32 t2 = tcg_const_i32(get_field(s->fields, r2));
gen_helper_mvst(cc_op, cpu_env, t1, t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
set_cc_static(s); set_cc_static(s);
return_low128(o->in2);
return DISAS_NEXT; return DISAS_NEXT;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册