s390x/tcg: MVCLU/MVCLE: Process max 4k bytes at a time
Let's stay within single pages. ... and indicate cc=3 in case there is work remaining. Keep unicode padding simple. While reworking, properly wrap the addresses. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com>
This commit is contained in:
parent
a3910396ba
commit
86678418b2
@ -768,8 +768,8 @@ static inline uint32_t do_mvcl(CPUS390XState *env,
|
|||||||
uint64_t *src, uint64_t *srclen,
|
uint64_t *src, uint64_t *srclen,
|
||||||
uint16_t pad, int wordsize, uintptr_t ra)
|
uint16_t pad, int wordsize, uintptr_t ra)
|
||||||
{
|
{
|
||||||
uint64_t len = MIN(*srclen, *destlen);
|
int len = MIN(*destlen, -(*dest | TARGET_PAGE_MASK));
|
||||||
uint32_t cc;
|
int i, cc;
|
||||||
|
|
||||||
if (*destlen == *srclen) {
|
if (*destlen == *srclen) {
|
||||||
cc = 0;
|
cc = 0;
|
||||||
@ -779,32 +779,40 @@ static inline uint32_t do_mvcl(CPUS390XState *env,
|
|||||||
cc = 2;
|
cc = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the src array */
|
if (!*destlen) {
|
||||||
fast_memmove(env, *dest, *src, len, ra);
|
return cc;
|
||||||
*src += len;
|
}
|
||||||
*srclen -= len;
|
|
||||||
*dest += len;
|
|
||||||
*destlen -= len;
|
|
||||||
|
|
||||||
/* Pad the remaining area */
|
/*
|
||||||
if (wordsize == 1) {
|
* Only perform one type of type of operation (move/pad) at a time.
|
||||||
fast_memset(env, *dest, pad, *destlen, ra);
|
* Stay within single pages.
|
||||||
*dest += *destlen;
|
*/
|
||||||
*destlen = 0;
|
if (*srclen) {
|
||||||
|
/* Copy the src array */
|
||||||
|
len = MIN(MIN(*srclen, -(*src | TARGET_PAGE_MASK)), len);
|
||||||
|
*destlen -= len;
|
||||||
|
*srclen -= len;
|
||||||
|
fast_memmove(env, *dest, *src, len, ra);
|
||||||
|
*src = wrap_address(env, *src + len);
|
||||||
|
*dest = wrap_address(env, *dest + len);
|
||||||
|
} else if (wordsize == 1) {
|
||||||
|
/* Pad the remaining area */
|
||||||
|
*destlen -= len;
|
||||||
|
fast_memset(env, *dest, pad, len, ra);
|
||||||
|
*dest = wrap_address(env, *dest + len);
|
||||||
} else {
|
} else {
|
||||||
/* If remaining length is odd, pad with odd byte first. */
|
/* The remaining length selects the padding byte. */
|
||||||
if (*destlen & 1) {
|
for (i = 0; i < len; (*destlen)--, i++) {
|
||||||
cpu_stb_data_ra(env, *dest, pad & 0xff, ra);
|
if (*destlen & 1) {
|
||||||
*dest += 1;
|
cpu_stb_data_ra(env, *dest, pad, ra);
|
||||||
*destlen -= 1;
|
} else {
|
||||||
}
|
cpu_stb_data_ra(env, *dest, pad >> 8, ra);
|
||||||
/* The remaining length is even, pad using words. */
|
}
|
||||||
for (; *destlen; *dest += 2, *destlen -= 2) {
|
*dest = wrap_address(env, *dest + 1);
|
||||||
cpu_stw_data_ra(env, *dest, pad, ra);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cc;
|
return *destlen ? 3 : cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move long */
|
/* move long */
|
||||||
|
Loading…
Reference in New Issue
Block a user