[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 04/30] s390x/tcg: MVCL: Process max 4k bytes at a time
From: |
David Hildenbrand |
Subject: |
[PULL 04/30] s390x/tcg: MVCL: Process max 4k bytes at a time |
Date: |
Mon, 23 Sep 2019 10:06:46 +0200 |
Process max 4k bytes at a time, writing back registers between the
accesses. The instruction is interruptible.
"For operands longer than 2K bytes, access exceptions are not
recognized for locations more than 2K bytes beyond the current location
being processed."
Note that on z/Architecture, 2k vs. 4k access cannot get differentiated as
long as pages are not crossed. This seems to be a leftover from ESA/390.
Simply stay within single pages.
MVCL handling is quite different than MVCLE/MVCLU handling, so split up
the handlers.
Defer interrupt handling, as that will require more thought, add a TODO
for that.
Reviewed-by: Richard Henderson <address@hidden>
Signed-off-by: David Hildenbrand <address@hidden>
---
target/s390x/mem_helper.c | 44 +++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 223312a4b1..58ab2e48e3 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -798,19 +798,51 @@ uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1,
uint32_t r2)
uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
uint64_t src = get_address(env, r2);
uint8_t pad = env->regs[r2 + 1] >> 24;
- uint32_t cc;
+ uint32_t cc, cur_len;
if (is_destructive_overlap(env, dest, src, MIN(srclen, destlen))) {
cc = 3;
+ } else if (srclen == destlen) {
+ cc = 0;
+ } else if (destlen < srclen) {
+ cc = 1;
} else {
- cc = do_mvcl(env, &dest, &destlen, &src, &srclen, pad, 1, ra);
+ cc = 2;
}
- env->regs[r1 + 1] = deposit64(env->regs[r1 + 1], 0, 24, destlen);
- env->regs[r2 + 1] = deposit64(env->regs[r2 + 1], 0, 24, srclen);
- set_address_zero(env, r1, dest);
- set_address_zero(env, r2, src);
+ /* We might have to zero-out some bits even if there was no action. */
+ if (unlikely(!destlen || cc == 3)) {
+ set_address_zero(env, r2, src);
+ set_address_zero(env, r1, dest);
+ return cc;
+ } else if (!srclen) {
+ set_address_zero(env, r2, src);
+ }
+ /*
+ * Only perform one type of type of operation (move/pad) in one step.
+ * Stay within single pages.
+ */
+ while (destlen) {
+ cur_len = MIN(destlen, -(dest | TARGET_PAGE_MASK));
+ if (!srclen) {
+ fast_memset(env, dest, pad, cur_len, ra);
+ } else {
+ cur_len = MIN(MIN(srclen, -(src | TARGET_PAGE_MASK)), cur_len);
+
+ fast_memmove(env, dest, src, cur_len, ra);
+ src = wrap_address(env, src + cur_len);
+ srclen -= cur_len;
+ env->regs[r2 + 1] = deposit64(env->regs[r2 + 1], 0, 24, srclen);
+ set_address_zero(env, r2, src);
+ }
+ dest = wrap_address(env, dest + cur_len);
+ destlen -= cur_len;
+ env->regs[r1 + 1] = deposit64(env->regs[r1 + 1], 0, 24, destlen);
+ set_address_zero(env, r1, dest);
+
+ /* TODO: Deliver interrupts. */
+ }
return cc;
}
--
2.21.0
- [PULL 00/30] s390x/tcg update, David Hildenbrand, 2019/09/23
- [PULL 01/30] s390x/tcg: Reset exception_index to -1 instead of 0, David Hildenbrand, 2019/09/23
- [PULL 02/30] s390x/tcg: MVCL: Zero out unused bits of address, David Hildenbrand, 2019/09/23
- [PULL 03/30] s390x/tcg: MVCL: Detect destructive overlaps, David Hildenbrand, 2019/09/23
- [PULL 04/30] s390x/tcg: MVCL: Process max 4k bytes at a time,
David Hildenbrand <=
- [PULL 05/30] s390x/tcg: MVC: Increment the length once, David Hildenbrand, 2019/09/23
- [PULL 06/30] s390x/tcg: MVC: Use is_destructive_overlap(), David Hildenbrand, 2019/09/23
- [PULL 07/30] s390x/tcg: MVPG: Check for specification exceptions, David Hildenbrand, 2019/09/23
- [PULL 08/30] s390x/tcg: MVPG: Properly wrap the addresses, David Hildenbrand, 2019/09/23
- [PULL 09/30] s390x/tcg: MVCLU/MVCLE: Process max 4k bytes at a time, David Hildenbrand, 2019/09/23
- [PULL 10/30] s390x/tcg: MVCS/MVCP: Check for special operation exceptions, David Hildenbrand, 2019/09/23
- [PULL 11/30] s390x/tcg: MVCOS: Lengths are 32 bit in 24/31-bit mode, David Hildenbrand, 2019/09/23
- [PULL 12/30] s390x/tcg: MVCS/MVCP: Properly wrap the length, David Hildenbrand, 2019/09/23
- [PULL 13/30] s390x/tcg: MVST: Check for specification exceptions, David Hildenbrand, 2019/09/23
- [PULL 14/30] s390x/tcg: MVST: Fix storing back the addresses to registers, David Hildenbrand, 2019/09/23