Skip to content

Commit

Permalink
target/s390x: Fix the "ignored match" case in VSTRS
Browse files Browse the repository at this point in the history
Currently the emulation of VSTRS recognizes partial matches in presence
of \0 in the haystack, which, according to PoP, is not correct:

    If the ZS flag is one and a zero byte was detected
    in the second operand, then there can not be a
    partial match ...

Add a check for this. While at it, fold a number of explicitly handled
special cases into the generic logic.

Cc: qemu-stable@nongnu.org
Reported-by: Claudio Fontana <cfontana@suse.de>
Closes: https://lists.gnu.org/archive/html/qemu-devel/2023-08/msg00633.html
Fixes: 1d706f3 ("target/s390x: vxeh2: vector string search")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230804233748.218935-3-iii@linux.ibm.com>
Tested-by: Claudio Fontana <cfontana@suse.de>
Acked-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 791b2b6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
  • Loading branch information
iii-i authored and Michael Tokarev committed Sep 10, 2023
1 parent b4b3aac commit 179a379
Showing 1 changed file with 17 additions and 37 deletions.
54 changes: 17 additions & 37 deletions target/s390x/tcg/vec_string_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,9 @@ 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 substr_elen, i, j, k, cc;
int nelem = 16 >> es;
bool eos = false;
int str_leftmost_0;

substr_elen = s390_vec_read_element8(v4, 7) >> es;

Expand All @@ -498,57 +498,37 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
}

/* If ZS, look for eos in the searched string. */
str_leftmost_0 = nelem;
if (zs) {
for (k = 0; k < nelem; k++) {
if (s390_vec_read_element(v2, k, es) == 0) {
eos = true;
str_leftmost_0 = k;
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;
}

cc = str_leftmost_0 == nelem ? 0 : 1; /* No match. */
for (k = 0; k < nelem; k++) {
i = MIN(nelem, k + substr_elen);
for (j = k + 1; j < i; j++) {
for (j = k; 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;
/* All elements matched. */
if (k > str_leftmost_0) {
cc = 1; /* Ignored match. */
k = nelem;
} else if (i - k == substr_elen) {
cc = 2; /* Full match. */
} else {
cc = 3; /* Partial match. */
}
break;
}
}

Expand Down

0 comments on commit 179a379

Please sign in to comment.