target/s390x: vxeh2: vector string search
Signed-off-by: David Miller <dmiller423@gmail.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com> Tested-by: Thomas Huth <thuth@redhat.com> Reviewed-by: David Hildenbrand <david@redhat.com> Message-Id: <20220428094708.84835-7-david@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
acc2d3a406
commit
1d706f3141
@ -246,6 +246,12 @@ DEF_HELPER_6(gvec_vstrc_cc32, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrc_cc_rt8, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrc_cc_rt16, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_8, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_16, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_32, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_zs8, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_zs16, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
DEF_HELPER_6(gvec_vstrs_zs32, void, ptr, cptr, cptr, cptr, env, i32)
|
||||
|
||||
/* === Vector Floating-Point Instructions */
|
||||
DEF_HELPER_FLAGS_5(gvec_vfa32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
|
||||
|
@ -1246,6 +1246,8 @@
|
||||
F(0xe75c, VISTR, VRR_a, V, 0, 0, 0, 0, vistr, 0, IF_VEC)
|
||||
/* VECTOR STRING RANGE COMPARE */
|
||||
F(0xe78a, VSTRC, VRR_d, V, 0, 0, 0, 0, vstrc, 0, IF_VEC)
|
||||
/* VECTOR STRING SEARCH */
|
||||
F(0xe78b, VSTRS, VRR_d, VE2, 0, 0, 0, 0, vstrs, 0, IF_VEC)
|
||||
|
||||
/* === Vector Floating-Point Instructions */
|
||||
|
||||
|
@ -6222,7 +6222,8 @@ enum DisasInsnEnum {
|
||||
#define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */
|
||||
#define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION
|
||||
#define FAC_V S390_FEAT_VECTOR /* vector facility */
|
||||
#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
|
||||
#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
|
||||
#define FAC_VE2 S390_FEAT_VECTOR_ENH2 /* vector enhancements facility 2 */
|
||||
#define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
|
||||
#define FAC_MIE3 S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */
|
||||
|
||||
|
@ -2497,6 +2497,31 @@ static DisasJumpType op_vstrc(DisasContext *s, DisasOps *o)
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_vstrs(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
typedef void (*helper_vstrs)(TCGv_ptr, TCGv_ptr, TCGv_ptr,
|
||||
TCGv_ptr, TCGv_ptr, TCGv_i32);
|
||||
static const helper_vstrs fns[3][2] = {
|
||||
{ gen_helper_gvec_vstrs_8, gen_helper_gvec_vstrs_zs8 },
|
||||
{ gen_helper_gvec_vstrs_16, gen_helper_gvec_vstrs_zs16 },
|
||||
{ gen_helper_gvec_vstrs_32, gen_helper_gvec_vstrs_zs32 },
|
||||
};
|
||||
const uint8_t es = get_field(s, m5);
|
||||
const uint8_t m6 = get_field(s, m6);
|
||||
const bool zs = extract32(m6, 1, 1);
|
||||
|
||||
if (es > ES_32 || m6 & ~2) {
|
||||
gen_program_exception(s, PGM_SPECIFICATION);
|
||||
return DISAS_NORETURN;
|
||||
}
|
||||
|
||||
gen_gvec_4_ptr(get_field(s, v1), get_field(s, v2),
|
||||
get_field(s, v3), get_field(s, v4),
|
||||
cpu_env, 0, fns[es][zs]);
|
||||
set_cc_static(s);
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
const uint8_t fpf = get_field(s, m4);
|
||||
|
@ -470,3 +470,102 @@ void HELPER(gvec_vstrc_cc_rt##BITS)(void *v1, const void *v2, const void *v3, \
|
||||
DEF_VSTRC_CC_RT_HELPER(8)
|
||||
DEF_VSTRC_CC_RT_HELPER(16)
|
||||
DEF_VSTRC_CC_RT_HELPER(32)
|
||||
|
||||
static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
|
||||
const S390Vector *v4, uint8_t es, bool zs)
|
||||
{
|
||||
int substr_elen, substr_0, str_elen, i, j, k, cc;
|
||||
int nelem = 16 >> es;
|
||||
bool eos = false;
|
||||
|
||||
substr_elen = s390_vec_read_element8(v4, 7) >> es;
|
||||
|
||||
/* If ZS, bound substr length by min(nelem, strlen(v3)). */
|
||||
if (zs) {
|
||||
substr_elen = MIN(substr_elen, nelem);
|
||||
for (i = 0; i < substr_elen; i++) {
|
||||
if (s390_vec_read_element(v3, i, es) == 0) {
|
||||
substr_elen = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (substr_elen == 0) {
|
||||
cc = 2; /* full match for degenerate case of empty substr */
|
||||
k = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If ZS, look for eos in the searched string. */
|
||||
if (zs) {
|
||||
for (k = 0; k < nelem; k++) {
|
||||
if (s390_vec_read_element(v2, k, es) == 0) {
|
||||
eos = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str_elen = k;
|
||||
} else {
|
||||
str_elen = nelem;
|
||||
}
|
||||
|
||||
substr_0 = s390_vec_read_element(v3, 0, es);
|
||||
|
||||
for (k = 0; ; k++) {
|
||||
for (; k < str_elen; k++) {
|
||||
if (s390_vec_read_element(v2, k, es) == substr_0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we reached the end of the string, no match. */
|
||||
if (k == str_elen) {
|
||||
cc = eos; /* no match (with or without zero char) */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the substring is only one char, match. */
|
||||
if (substr_elen == 1) {
|
||||
cc = 2; /* full match */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the match begins at the last char, we have a partial match. */
|
||||
if (k == str_elen - 1) {
|
||||
cc = 3; /* partial match */
|
||||
goto done;
|
||||
}
|
||||
|
||||
i = MIN(nelem, k + substr_elen);
|
||||
for (j = k + 1; j < i; j++) {
|
||||
uint32_t e2 = s390_vec_read_element(v2, j, es);
|
||||
uint32_t e3 = s390_vec_read_element(v3, j - k, es);
|
||||
if (e2 != e3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == i) {
|
||||
/* Matched up until "end". */
|
||||
cc = i - k == substr_elen ? 2 : 3; /* full or partial match */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
s390_vec_write_element64(v1, 0, k << es);
|
||||
s390_vec_write_element64(v1, 1, 0);
|
||||
return cc;
|
||||
}
|
||||
|
||||
#define DEF_VSTRS_HELPER(BITS) \
|
||||
void QEMU_FLATTEN HELPER(gvec_vstrs_##BITS)(void *v1, const void *v2, \
|
||||
const void *v3, const void *v4, CPUS390XState *env, uint32_t desc) \
|
||||
{ env->cc_op = vstrs(v1, v2, v3, v4, MO_##BITS, false); } \
|
||||
void QEMU_FLATTEN HELPER(gvec_vstrs_zs##BITS)(void *v1, const void *v2, \
|
||||
const void *v3, const void *v4, CPUS390XState *env, uint32_t desc) \
|
||||
{ env->cc_op = vstrs(v1, v2, v3, v4, MO_##BITS, true); }
|
||||
|
||||
DEF_VSTRS_HELPER(8)
|
||||
DEF_VSTRS_HELPER(16)
|
||||
DEF_VSTRS_HELPER(32)
|
||||
|
Loading…
Reference in New Issue
Block a user