Skip to content

Commit

Permalink
s390x/tcg: Implement VECTOR STORE WITH LENGTH
Browse files Browse the repository at this point in the history
Very similar to VECTOR LOAD WITH LENGTH, just the opposite direction.
Properly probe write access before modifying memory.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190307121539.12842-32-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
  • Loading branch information
davidhildenbrand authored and cohuck committed Mar 11, 2019
1 parent 29b8bcf commit 0e0a5b4
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions target/s390x/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ DEF_HELPER_5(gvec_vpkls_cc16, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vpkls_cc32, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vpkls_cc64, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vperm, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(vstl, TCG_CALL_NO_WG, void, env, cptr, i64, i64)

#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
Expand Down
2 changes: 2 additions & 0 deletions target/s390x/insn-data.def
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,8 @@
E(0xe70a, VSTEG, VRX, V, la2, 0, 0, 0, vste, 0, ES_64, IF_VEC)
/* VECTOR STORE MULTIPLE */
F(0xe73e, VSTM, VRS_a, V, la2, 0, 0, 0, vstm, 0, IF_VEC)
/* VECTOR STORE WITH LENGTH */
F(0xe73f, VSTL, VRS_b, V, la2, r3_32u, 0, 0, vstl, 0, IF_VEC)

#ifndef CONFIG_USER_ONLY
/* COMPARE AND SWAP AND PURGE */
Expand Down
13 changes: 13 additions & 0 deletions target/s390x/translate_vx.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,3 +882,16 @@ static DisasJumpType op_vstm(DisasContext *s, DisasOps *o)
tcg_temp_free_i64(tmp);
return DISAS_NEXT;
}

static DisasJumpType op_vstl(DisasContext *s, DisasOps *o)
{
const int v1_offs = vec_full_reg_offset(get_field(s->fields, v1));
TCGv_ptr a0 = tcg_temp_new_ptr();

/* convert highest index into an actual length */
tcg_gen_addi_i64(o->in2, o->in2, 1);
tcg_gen_addi_ptr(a0, cpu_env, v1_offs);
gen_helper_vstl(cpu_env, a0, o->addr1, o->in2);
tcg_temp_free_ptr(a0);
return DISAS_NEXT;
}
24 changes: 24 additions & 0 deletions target/s390x/vec_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,27 @@ void HELPER(gvec_vperm)(void *v1, const void *v2, const void *v3,
}
*(S390Vector *)v1 = tmp;
}

void HELPER(vstl)(CPUS390XState *env, const void *v1, uint64_t addr,
uint64_t bytes)
{
/* Probe write access before actually modifying memory */
probe_write_access(env, addr, bytes, GETPC());

if (likely(bytes >= 16)) {
cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 0), GETPC());
addr = wrap_address(env, addr + 8);
cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 1), GETPC());
} else {
S390Vector tmp = {};
int i;

for (i = 0; i < bytes; i++) {
uint8_t byte = s390_vec_read_element8(v1, i);

cpu_stb_data_ra(env, addr, byte, GETPC());
addr = wrap_address(env, addr + 1);
}
*(S390Vector *)v1 = tmp;
}
}

0 comments on commit 0e0a5b4

Please sign in to comment.