Merge "Change requested in launchpad bug #1288352" into 5.0
[packages/centos6/qemu.git] / 0009-target-s390x-split-memory-access-helpers.patch
1 From a44aee2570031bfcf99098d278c53ab39a582ba6 Mon Sep 17 00:00:00 2001
2 From: Blue Swirl <blauwirbel@gmail.com>
3 Date: Sun, 2 Sep 2012 07:33:34 +0000
4 Subject: [PATCH] target-s390x: split memory access helpers
5
6 Move memory access helpers to mem_helper.c.
7
8 Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
9 [agraf: fold softmmu include ifdefs together]
10 Signed-off-by: Alexander Graf <agraf@suse.de>
11
12 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
13 ---
14  target-s390x/Makefile.objs |    3 +-
15  target-s390x/mem_helper.c  | 1190 ++++++++++++++++++++++++++++++++++++++++++++
16  target-s390x/op_helper.c   | 1159 +-----------------------------------------
17  3 files changed, 1193 insertions(+), 1159 deletions(-)
18  create mode 100644 target-s390x/mem_helper.c
19
20 diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
21 index e8f66e9..b9b3061 100644
22 --- a/target-s390x/Makefile.objs
23 +++ b/target-s390x/Makefile.objs
24 @@ -1,5 +1,5 @@
25  obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
26 -obj-y += int_helper.o fpu_helper.o cc_helper.o
27 +obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
28  obj-$(CONFIG_SOFTMMU) += machine.o
29  obj-$(CONFIG_KVM) += kvm.o
30  
31 @@ -7,3 +7,4 @@ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
32  $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
33  $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
34  $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
35 +$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
36 diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
37 new file mode 100644
38 index 0000000..ba05e65
39 --- /dev/null
40 +++ b/target-s390x/mem_helper.c
41 @@ -0,0 +1,1190 @@
42 +/*
43 + *  S/390 memory access helper routines
44 + *
45 + *  Copyright (c) 2009 Ulrich Hecht
46 + *  Copyright (c) 2009 Alexander Graf
47 + *
48 + * This library is free software; you can redistribute it and/or
49 + * modify it under the terms of the GNU Lesser General Public
50 + * License as published by the Free Software Foundation; either
51 + * version 2 of the License, or (at your option) any later version.
52 + *
53 + * This library is distributed in the hope that it will be useful,
54 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
55 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
56 + * Lesser General Public License for more details.
57 + *
58 + * You should have received a copy of the GNU Lesser General Public
59 + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
60 + */
61 +
62 +#include "cpu.h"
63 +#include "dyngen-exec.h"
64 +#include "helper.h"
65 +
66 +/*****************************************************************************/
67 +/* Softmmu support */
68 +#if !defined(CONFIG_USER_ONLY)
69 +#include "softmmu_exec.h"
70 +
71 +#define MMUSUFFIX _mmu
72 +
73 +#define SHIFT 0
74 +#include "softmmu_template.h"
75 +
76 +#define SHIFT 1
77 +#include "softmmu_template.h"
78 +
79 +#define SHIFT 2
80 +#include "softmmu_template.h"
81 +
82 +#define SHIFT 3
83 +#include "softmmu_template.h"
84 +
85 +/* try to fill the TLB and return an exception if error. If retaddr is
86 +   NULL, it means that the function was called in C code (i.e. not
87 +   from generated code or from helper.c) */
88 +/* XXX: fix it to restore all registers */
89 +void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
90 +              uintptr_t retaddr)
91 +{
92 +    TranslationBlock *tb;
93 +    CPUS390XState *saved_env;
94 +    int ret;
95 +
96 +    saved_env = env;
97 +    env = env1;
98 +    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
99 +    if (unlikely(ret != 0)) {
100 +        if (likely(retaddr)) {
101 +            /* now we have a real cpu fault */
102 +            tb = tb_find_pc(retaddr);
103 +            if (likely(tb)) {
104 +                /* the PC is inside the translated code. It means that we have
105 +                   a virtual CPU fault */
106 +                cpu_restore_state(tb, env, retaddr);
107 +            }
108 +        }
109 +        cpu_loop_exit(env);
110 +    }
111 +    env = saved_env;
112 +}
113 +
114 +#endif
115 +
116 +/* #define DEBUG_HELPER */
117 +#ifdef DEBUG_HELPER
118 +#define HELPER_LOG(x...) qemu_log(x)
119 +#else
120 +#define HELPER_LOG(x...)
121 +#endif
122 +
123 +#ifndef CONFIG_USER_ONLY
124 +static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
125 +                            uint8_t byte)
126 +{
127 +    target_phys_addr_t dest_phys;
128 +    target_phys_addr_t len = l;
129 +    void *dest_p;
130 +    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
131 +    int flags;
132 +
133 +    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
134 +        stb(dest, byte);
135 +        cpu_abort(env, "should never reach here");
136 +    }
137 +    dest_phys |= dest & ~TARGET_PAGE_MASK;
138 +
139 +    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
140 +
141 +    memset(dest_p, byte, len);
142 +
143 +    cpu_physical_memory_unmap(dest_p, 1, len, len);
144 +}
145 +
146 +static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
147 +                             uint64_t src)
148 +{
149 +    target_phys_addr_t dest_phys;
150 +    target_phys_addr_t src_phys;
151 +    target_phys_addr_t len = l;
152 +    void *dest_p;
153 +    void *src_p;
154 +    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
155 +    int flags;
156 +
157 +    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
158 +        stb(dest, 0);
159 +        cpu_abort(env, "should never reach here");
160 +    }
161 +    dest_phys |= dest & ~TARGET_PAGE_MASK;
162 +
163 +    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
164 +        ldub(src);
165 +        cpu_abort(env, "should never reach here");
166 +    }
167 +    src_phys |= src & ~TARGET_PAGE_MASK;
168 +
169 +    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
170 +    src_p = cpu_physical_memory_map(src_phys, &len, 0);
171 +
172 +    memmove(dest_p, src_p, len);
173 +
174 +    cpu_physical_memory_unmap(dest_p, 1, len, len);
175 +    cpu_physical_memory_unmap(src_p, 0, len, len);
176 +}
177 +#endif
178 +
179 +/* and on array */
180 +uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
181 +{
182 +    int i;
183 +    unsigned char x;
184 +    uint32_t cc = 0;
185 +
186 +    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
187 +               __func__, l, dest, src);
188 +    for (i = 0; i <= l; i++) {
189 +        x = ldub(dest + i) & ldub(src + i);
190 +        if (x) {
191 +            cc = 1;
192 +        }
193 +        stb(dest + i, x);
194 +    }
195 +    return cc;
196 +}
197 +
198 +/* xor on array */
199 +uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
200 +{
201 +    int i;
202 +    unsigned char x;
203 +    uint32_t cc = 0;
204 +
205 +    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
206 +               __func__, l, dest, src);
207 +
208 +#ifndef CONFIG_USER_ONLY
209 +    /* xor with itself is the same as memset(0) */
210 +    if ((l > 32) && (src == dest) &&
211 +        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
212 +        mvc_fast_memset(env, l + 1, dest, 0);
213 +        return 0;
214 +    }
215 +#else
216 +    if (src == dest) {
217 +        memset(g2h(dest), 0, l + 1);
218 +        return 0;
219 +    }
220 +#endif
221 +
222 +    for (i = 0; i <= l; i++) {
223 +        x = ldub(dest + i) ^ ldub(src + i);
224 +        if (x) {
225 +            cc = 1;
226 +        }
227 +        stb(dest + i, x);
228 +    }
229 +    return cc;
230 +}
231 +
232 +/* or on array */
233 +uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
234 +{
235 +    int i;
236 +    unsigned char x;
237 +    uint32_t cc = 0;
238 +
239 +    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
240 +               __func__, l, dest, src);
241 +    for (i = 0; i <= l; i++) {
242 +        x = ldub(dest + i) | ldub(src + i);
243 +        if (x) {
244 +            cc = 1;
245 +        }
246 +        stb(dest + i, x);
247 +    }
248 +    return cc;
249 +}
250 +
251 +/* memmove */
252 +void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
253 +{
254 +    int i = 0;
255 +    int x = 0;
256 +    uint32_t l_64 = (l + 1) / 8;
257 +
258 +    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
259 +               __func__, l, dest, src);
260 +
261 +#ifndef CONFIG_USER_ONLY
262 +    if ((l > 32) &&
263 +        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
264 +        (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
265 +        if (dest == (src + 1)) {
266 +            mvc_fast_memset(env, l + 1, dest, ldub(src));
267 +            return;
268 +        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
269 +            mvc_fast_memmove(env, l + 1, dest, src);
270 +            return;
271 +        }
272 +    }
273 +#else
274 +    if (dest == (src + 1)) {
275 +        memset(g2h(dest), ldub(src), l + 1);
276 +        return;
277 +    } else {
278 +        memmove(g2h(dest), g2h(src), l + 1);
279 +        return;
280 +    }
281 +#endif
282 +
283 +    /* handle the parts that fit into 8-byte loads/stores */
284 +    if (dest != (src + 1)) {
285 +        for (i = 0; i < l_64; i++) {
286 +            stq(dest + x, ldq(src + x));
287 +            x += 8;
288 +        }
289 +    }
290 +
291 +    /* slow version crossing pages with byte accesses */
292 +    for (i = x; i <= l; i++) {
293 +        stb(dest + i, ldub(src + i));
294 +    }
295 +}
296 +
297 +/* compare unsigned byte arrays */
298 +uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
299 +{
300 +    int i;
301 +    unsigned char x, y;
302 +    uint32_t cc;
303 +
304 +    HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
305 +               __func__, l, s1, s2);
306 +    for (i = 0; i <= l; i++) {
307 +        x = ldub(s1 + i);
308 +        y = ldub(s2 + i);
309 +        HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
310 +        if (x < y) {
311 +            cc = 1;
312 +            goto done;
313 +        } else if (x > y) {
314 +            cc = 2;
315 +            goto done;
316 +        }
317 +    }
318 +    cc = 0;
319 + done:
320 +    HELPER_LOG("\n");
321 +    return cc;
322 +}
323 +
324 +/* compare logical under mask */
325 +uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
326 +{
327 +    uint8_t r, d;
328 +    uint32_t cc;
329 +
330 +    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
331 +               mask, addr);
332 +    cc = 0;
333 +    while (mask) {
334 +        if (mask & 8) {
335 +            d = ldub(addr);
336 +            r = (r1 & 0xff000000UL) >> 24;
337 +            HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
338 +                       addr);
339 +            if (r < d) {
340 +                cc = 1;
341 +                break;
342 +            } else if (r > d) {
343 +                cc = 2;
344 +                break;
345 +            }
346 +            addr++;
347 +        }
348 +        mask = (mask << 1) & 0xf;
349 +        r1 <<= 8;
350 +    }
351 +    HELPER_LOG("\n");
352 +    return cc;
353 +}
354 +
355 +/* store character under mask */
356 +void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
357 +{
358 +    uint8_t r;
359 +
360 +    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
361 +               addr);
362 +    while (mask) {
363 +        if (mask & 8) {
364 +            r = (r1 & 0xff000000UL) >> 24;
365 +            stb(addr, r);
366 +            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
367 +            addr++;
368 +        }
369 +        mask = (mask << 1) & 0xf;
370 +        r1 <<= 8;
371 +    }
372 +    HELPER_LOG("\n");
373 +}
374 +
375 +static inline uint64_t get_address(int x2, int b2, int d2)
376 +{
377 +    uint64_t r = d2;
378 +
379 +    if (x2) {
380 +        r += env->regs[x2];
381 +    }
382 +
383 +    if (b2) {
384 +        r += env->regs[b2];
385 +    }
386 +
387 +    /* 31-Bit mode */
388 +    if (!(env->psw.mask & PSW_MASK_64)) {
389 +        r &= 0x7fffffff;
390 +    }
391 +
392 +    return r;
393 +}
394 +
395 +static inline uint64_t get_address_31fix(int reg)
396 +{
397 +    uint64_t r = env->regs[reg];
398 +
399 +    /* 31-Bit mode */
400 +    if (!(env->psw.mask & PSW_MASK_64)) {
401 +        r &= 0x7fffffff;
402 +    }
403 +
404 +    return r;
405 +}
406 +
407 +/* search string (c is byte to search, r2 is string, r1 end of string) */
408 +uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
409 +{
410 +    uint64_t i;
411 +    uint32_t cc = 2;
412 +    uint64_t str = get_address_31fix(r2);
413 +    uint64_t end = get_address_31fix(r1);
414 +
415 +    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
416 +               c, env->regs[r1], env->regs[r2]);
417 +
418 +    for (i = str; i != end; i++) {
419 +        if (ldub(i) == c) {
420 +            env->regs[r1] = i;
421 +            cc = 1;
422 +            break;
423 +        }
424 +    }
425 +
426 +    return cc;
427 +}
428 +
429 +/* unsigned string compare (c is string terminator) */
430 +uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
431 +{
432 +    uint64_t s1 = get_address_31fix(r1);
433 +    uint64_t s2 = get_address_31fix(r2);
434 +    uint8_t v1, v2;
435 +    uint32_t cc;
436 +
437 +    c = c & 0xff;
438 +#ifdef CONFIG_USER_ONLY
439 +    if (!c) {
440 +        HELPER_LOG("%s: comparing '%s' and '%s'\n",
441 +                   __func__, (char *)g2h(s1), (char *)g2h(s2));
442 +    }
443 +#endif
444 +    for (;;) {
445 +        v1 = ldub(s1);
446 +        v2 = ldub(s2);
447 +        if ((v1 == c || v2 == c) || (v1 != v2)) {
448 +            break;
449 +        }
450 +        s1++;
451 +        s2++;
452 +    }
453 +
454 +    if (v1 == v2) {
455 +        cc = 0;
456 +    } else {
457 +        cc = (v1 < v2) ? 1 : 2;
458 +        /* FIXME: 31-bit mode! */
459 +        env->regs[r1] = s1;
460 +        env->regs[r2] = s2;
461 +    }
462 +    return cc;
463 +}
464 +
465 +/* move page */
466 +void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
467 +{
468 +    /* XXX missing r0 handling */
469 +#ifdef CONFIG_USER_ONLY
470 +    int i;
471 +
472 +    for (i = 0; i < TARGET_PAGE_SIZE; i++) {
473 +        stb(r1 + i, ldub(r2 + i));
474 +    }
475 +#else
476 +    mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
477 +#endif
478 +}
479 +
480 +/* string copy (c is string terminator) */
481 +void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
482 +{
483 +    uint64_t dest = get_address_31fix(r1);
484 +    uint64_t src = get_address_31fix(r2);
485 +    uint8_t v;
486 +
487 +    c = c & 0xff;
488 +#ifdef CONFIG_USER_ONLY
489 +    if (!c) {
490 +        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
491 +                   dest);
492 +    }
493 +#endif
494 +    for (;;) {
495 +        v = ldub(src);
496 +        stb(dest, v);
497 +        if (v == c) {
498 +            break;
499 +        }
500 +        src++;
501 +        dest++;
502 +    }
503 +    env->regs[r1] = dest; /* FIXME: 31-bit mode! */
504 +}
505 +
506 +/* compare and swap 64-bit */
507 +uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
508 +{
509 +    /* FIXME: locking? */
510 +    uint32_t cc;
511 +    uint64_t v2 = ldq(a2);
512 +
513 +    if (env->regs[r1] == v2) {
514 +        cc = 0;
515 +        stq(a2, env->regs[r3]);
516 +    } else {
517 +        cc = 1;
518 +        env->regs[r1] = v2;
519 +    }
520 +    return cc;
521 +}
522 +
523 +/* compare double and swap 64-bit */
524 +uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
525 +{
526 +    /* FIXME: locking? */
527 +    uint32_t cc;
528 +    uint64_t v2_hi = ldq(a2);
529 +    uint64_t v2_lo = ldq(a2 + 8);
530 +    uint64_t v1_hi = env->regs[r1];
531 +    uint64_t v1_lo = env->regs[r1 + 1];
532 +
533 +    if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
534 +        cc = 0;
535 +        stq(a2, env->regs[r3]);
536 +        stq(a2 + 8, env->regs[r3 + 1]);
537 +    } else {
538 +        cc = 1;
539 +        env->regs[r1] = v2_hi;
540 +        env->regs[r1 + 1] = v2_lo;
541 +    }
542 +
543 +    return cc;
544 +}
545 +
546 +/* compare and swap 32-bit */
547 +uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
548 +{
549 +    /* FIXME: locking? */
550 +    uint32_t cc;
551 +    uint32_t v2 = ldl(a2);
552 +
553 +    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
554 +    if (((uint32_t)env->regs[r1]) == v2) {
555 +        cc = 0;
556 +        stl(a2, (uint32_t)env->regs[r3]);
557 +    } else {
558 +        cc = 1;
559 +        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
560 +    }
561 +    return cc;
562 +}
563 +
564 +static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
565 +{
566 +    int pos = 24; /* top of the lower half of r1 */
567 +    uint64_t rmask = 0xff000000ULL;
568 +    uint8_t val = 0;
569 +    int ccd = 0;
570 +    uint32_t cc = 0;
571 +
572 +    while (mask) {
573 +        if (mask & 8) {
574 +            env->regs[r1] &= ~rmask;
575 +            val = ldub(address);
576 +            if ((val & 0x80) && !ccd) {
577 +                cc = 1;
578 +            }
579 +            ccd = 1;
580 +            if (val && cc == 0) {
581 +                cc = 2;
582 +            }
583 +            env->regs[r1] |= (uint64_t)val << pos;
584 +            address++;
585 +        }
586 +        mask = (mask << 1) & 0xf;
587 +        pos -= 8;
588 +        rmask >>= 8;
589 +    }
590 +
591 +    return cc;
592 +}
593 +
594 +/* execute instruction
595 +   this instruction executes an insn modified with the contents of r1
596 +   it does not change the executed instruction in memory
597 +   it does not change the program counter
598 +   in other words: tricky...
599 +   currently implemented by interpreting the cases it is most commonly used in
600 +*/
601 +uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
602 +{
603 +    uint16_t insn = lduw_code(addr);
604 +
605 +    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
606 +               insn);
607 +    if ((insn & 0xf0ff) == 0xd000) {
608 +        uint32_t l, insn2, b1, b2, d1, d2;
609 +
610 +        l = v1 & 0xff;
611 +        insn2 = ldl_code(addr + 2);
612 +        b1 = (insn2 >> 28) & 0xf;
613 +        b2 = (insn2 >> 12) & 0xf;
614 +        d1 = (insn2 >> 16) & 0xfff;
615 +        d2 = insn2 & 0xfff;
616 +        switch (insn & 0xf00) {
617 +        case 0x200:
618 +            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
619 +            break;
620 +        case 0x500:
621 +            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
622 +            break;
623 +        case 0x700:
624 +            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
625 +            break;
626 +        case 0xc00:
627 +            helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
628 +            break;
629 +        default:
630 +            goto abort;
631 +            break;
632 +        }
633 +    } else if ((insn & 0xff00) == 0x0a00) {
634 +        /* supervisor call */
635 +        HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
636 +        env->psw.addr = ret - 4;
637 +        env->int_svc_code = (insn | v1) & 0xff;
638 +        env->int_svc_ilc = 4;
639 +        helper_exception(EXCP_SVC);
640 +    } else if ((insn & 0xff00) == 0xbf00) {
641 +        uint32_t insn2, r1, r3, b2, d2;
642 +
643 +        insn2 = ldl_code(addr + 2);
644 +        r1 = (insn2 >> 20) & 0xf;
645 +        r3 = (insn2 >> 16) & 0xf;
646 +        b2 = (insn2 >> 12) & 0xf;
647 +        d2 = insn2 & 0xfff;
648 +        cc = helper_icm(r1, get_address(0, b2, d2), r3);
649 +    } else {
650 +    abort:
651 +        cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
652 +                  insn);
653 +    }
654 +    return cc;
655 +}
656 +
657 +/* store character under mask high operates on the upper half of r1 */
658 +void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
659 +{
660 +    int pos = 56; /* top of the upper half of r1 */
661 +
662 +    while (mask) {
663 +        if (mask & 8) {
664 +            stb(address, (env->regs[r1] >> pos) & 0xff);
665 +            address++;
666 +        }
667 +        mask = (mask << 1) & 0xf;
668 +        pos -= 8;
669 +    }
670 +}
671 +
672 +/* insert character under mask high; same as icm, but operates on the
673 +   upper half of r1 */
674 +uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
675 +{
676 +    int pos = 56; /* top of the upper half of r1 */
677 +    uint64_t rmask = 0xff00000000000000ULL;
678 +    uint8_t val = 0;
679 +    int ccd = 0;
680 +    uint32_t cc = 0;
681 +
682 +    while (mask) {
683 +        if (mask & 8) {
684 +            env->regs[r1] &= ~rmask;
685 +            val = ldub(address);
686 +            if ((val & 0x80) && !ccd) {
687 +                cc = 1;
688 +            }
689 +            ccd = 1;
690 +            if (val && cc == 0) {
691 +                cc = 2;
692 +            }
693 +            env->regs[r1] |= (uint64_t)val << pos;
694 +            address++;
695 +        }
696 +        mask = (mask << 1) & 0xf;
697 +        pos -= 8;
698 +        rmask >>= 8;
699 +    }
700 +
701 +    return cc;
702 +}
703 +
704 +/* load access registers r1 to r3 from memory at a2 */
705 +void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
706 +{
707 +    int i;
708 +
709 +    for (i = r1;; i = (i + 1) % 16) {
710 +        env->aregs[i] = ldl(a2);
711 +        a2 += 4;
712 +
713 +        if (i == r3) {
714 +            break;
715 +        }
716 +    }
717 +}
718 +
719 +/* store access registers r1 to r3 in memory at a2 */
720 +void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
721 +{
722 +    int i;
723 +
724 +    for (i = r1;; i = (i + 1) % 16) {
725 +        stl(a2, env->aregs[i]);
726 +        a2 += 4;
727 +
728 +        if (i == r3) {
729 +            break;
730 +        }
731 +    }
732 +}
733 +
734 +/* move long */
735 +uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
736 +{
737 +    uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
738 +    uint64_t dest = get_address_31fix(r1);
739 +    uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
740 +    uint64_t src = get_address_31fix(r2);
741 +    uint8_t pad = src >> 24;
742 +    uint8_t v;
743 +    uint32_t cc;
744 +
745 +    if (destlen == srclen) {
746 +        cc = 0;
747 +    } else if (destlen < srclen) {
748 +        cc = 1;
749 +    } else {
750 +        cc = 2;
751 +    }
752 +
753 +    if (srclen > destlen) {
754 +        srclen = destlen;
755 +    }
756 +
757 +    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
758 +        v = ldub(src);
759 +        stb(dest, v);
760 +    }
761 +
762 +    for (; destlen; dest++, destlen--) {
763 +        stb(dest, pad);
764 +    }
765 +
766 +    env->regs[r1 + 1] = destlen;
767 +    /* can't use srclen here, we trunc'ed it */
768 +    env->regs[r2 + 1] -= src - env->regs[r2];
769 +    env->regs[r1] = dest;
770 +    env->regs[r2] = src;
771 +
772 +    return cc;
773 +}
774 +
775 +/* move long extended another memcopy insn with more bells and whistles */
776 +uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
777 +{
778 +    uint64_t destlen = env->regs[r1 + 1];
779 +    uint64_t dest = env->regs[r1];
780 +    uint64_t srclen = env->regs[r3 + 1];
781 +    uint64_t src = env->regs[r3];
782 +    uint8_t pad = a2 & 0xff;
783 +    uint8_t v;
784 +    uint32_t cc;
785 +
786 +    if (!(env->psw.mask & PSW_MASK_64)) {
787 +        destlen = (uint32_t)destlen;
788 +        srclen = (uint32_t)srclen;
789 +        dest &= 0x7fffffff;
790 +        src &= 0x7fffffff;
791 +    }
792 +
793 +    if (destlen == srclen) {
794 +        cc = 0;
795 +    } else if (destlen < srclen) {
796 +        cc = 1;
797 +    } else {
798 +        cc = 2;
799 +    }
800 +
801 +    if (srclen > destlen) {
802 +        srclen = destlen;
803 +    }
804 +
805 +    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
806 +        v = ldub(src);
807 +        stb(dest, v);
808 +    }
809 +
810 +    for (; destlen; dest++, destlen--) {
811 +        stb(dest, pad);
812 +    }
813 +
814 +    env->regs[r1 + 1] = destlen;
815 +    /* can't use srclen here, we trunc'ed it */
816 +    /* FIXME: 31-bit mode! */
817 +    env->regs[r3 + 1] -= src - env->regs[r3];
818 +    env->regs[r1] = dest;
819 +    env->regs[r3] = src;
820 +
821 +    return cc;
822 +}
823 +
824 +/* compare logical long extended memcompare insn with padding */
825 +uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
826 +{
827 +    uint64_t destlen = env->regs[r1 + 1];
828 +    uint64_t dest = get_address_31fix(r1);
829 +    uint64_t srclen = env->regs[r3 + 1];
830 +    uint64_t src = get_address_31fix(r3);
831 +    uint8_t pad = a2 & 0xff;
832 +    uint8_t v1 = 0, v2 = 0;
833 +    uint32_t cc = 0;
834 +
835 +    if (!(destlen || srclen)) {
836 +        return cc;
837 +    }
838 +
839 +    if (srclen > destlen) {
840 +        srclen = destlen;
841 +    }
842 +
843 +    for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
844 +        v1 = srclen ? ldub(src) : pad;
845 +        v2 = destlen ? ldub(dest) : pad;
846 +        if (v1 != v2) {
847 +            cc = (v1 < v2) ? 1 : 2;
848 +            break;
849 +        }
850 +    }
851 +
852 +    env->regs[r1 + 1] = destlen;
853 +    /* can't use srclen here, we trunc'ed it */
854 +    env->regs[r3 + 1] -= src - env->regs[r3];
855 +    env->regs[r1] = dest;
856 +    env->regs[r3] = src;
857 +
858 +    return cc;
859 +}
860 +
861 +/* checksum */
862 +void HELPER(cksm)(uint32_t r1, uint32_t r2)
863 +{
864 +    uint64_t src = get_address_31fix(r2);
865 +    uint64_t src_len = env->regs[(r2 + 1) & 15];
866 +    uint64_t cksm = (uint32_t)env->regs[r1];
867 +
868 +    while (src_len >= 4) {
869 +        cksm += ldl(src);
870 +
871 +        /* move to next word */
872 +        src_len -= 4;
873 +        src += 4;
874 +    }
875 +
876 +    switch (src_len) {
877 +    case 0:
878 +        break;
879 +    case 1:
880 +        cksm += ldub(src) << 24;
881 +        break;
882 +    case 2:
883 +        cksm += lduw(src) << 16;
884 +        break;
885 +    case 3:
886 +        cksm += lduw(src) << 16;
887 +        cksm += ldub(src + 2) << 8;
888 +        break;
889 +    }
890 +
891 +    /* indicate we've processed everything */
892 +    env->regs[r2] = src + src_len;
893 +    env->regs[(r2 + 1) & 15] = 0;
894 +
895 +    /* store result */
896 +    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
897 +        ((uint32_t)cksm + (cksm >> 32));
898 +}
899 +
900 +void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
901 +{
902 +    int len_dest = len >> 4;
903 +    int len_src = len & 0xf;
904 +    uint8_t b;
905 +    int second_nibble = 0;
906 +
907 +    dest += len_dest;
908 +    src += len_src;
909 +
910 +    /* last byte is special, it only flips the nibbles */
911 +    b = ldub(src);
912 +    stb(dest, (b << 4) | (b >> 4));
913 +    src--;
914 +    len_src--;
915 +
916 +    /* now pad every nibble with 0xf0 */
917 +
918 +    while (len_dest > 0) {
919 +        uint8_t cur_byte = 0;
920 +
921 +        if (len_src > 0) {
922 +            cur_byte = ldub(src);
923 +        }
924 +
925 +        len_dest--;
926 +        dest--;
927 +
928 +        /* only advance one nibble at a time */
929 +        if (second_nibble) {
930 +            cur_byte >>= 4;
931 +            len_src--;
932 +            src--;
933 +        }
934 +        second_nibble = !second_nibble;
935 +
936 +        /* digit */
937 +        cur_byte = (cur_byte & 0xf);
938 +        /* zone bits */
939 +        cur_byte |= 0xf0;
940 +
941 +        stb(dest, cur_byte);
942 +    }
943 +}
944 +
945 +void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
946 +{
947 +    int i;
948 +
949 +    for (i = 0; i <= len; i++) {
950 +        uint8_t byte = ldub(array + i);
951 +        uint8_t new_byte = ldub(trans + byte);
952 +
953 +        stb(array + i, new_byte);
954 +    }
955 +}
956 +
957 +#if !defined(CONFIG_USER_ONLY)
958 +void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
959 +{
960 +    int i;
961 +    uint64_t src = a2;
962 +
963 +    for (i = r1;; i = (i + 1) % 16) {
964 +        env->cregs[i] = ldq(src);
965 +        HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
966 +                   i, src, env->cregs[i]);
967 +        src += sizeof(uint64_t);
968 +
969 +        if (i == r3) {
970 +            break;
971 +        }
972 +    }
973 +
974 +    tlb_flush(env, 1);
975 +}
976 +
977 +void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
978 +{
979 +    int i;
980 +    uint64_t src = a2;
981 +
982 +    for (i = r1;; i = (i + 1) % 16) {
983 +        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
984 +        src += sizeof(uint32_t);
985 +
986 +        if (i == r3) {
987 +            break;
988 +        }
989 +    }
990 +
991 +    tlb_flush(env, 1);
992 +}
993 +
994 +void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
995 +{
996 +    int i;
997 +    uint64_t dest = a2;
998 +
999 +    for (i = r1;; i = (i + 1) % 16) {
1000 +        stq(dest, env->cregs[i]);
1001 +        dest += sizeof(uint64_t);
1002 +
1003 +        if (i == r3) {
1004 +            break;
1005 +        }
1006 +    }
1007 +}
1008 +
1009 +void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
1010 +{
1011 +    int i;
1012 +    uint64_t dest = a2;
1013 +
1014 +    for (i = r1;; i = (i + 1) % 16) {
1015 +        stl(dest, env->cregs[i]);
1016 +        dest += sizeof(uint32_t);
1017 +
1018 +        if (i == r3) {
1019 +            break;
1020 +        }
1021 +    }
1022 +}
1023 +
1024 +uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
1025 +{
1026 +    /* XXX implement */
1027 +
1028 +    return 0;
1029 +}
1030 +
1031 +/* insert storage key extended */
1032 +uint64_t HELPER(iske)(uint64_t r2)
1033 +{
1034 +    uint64_t addr = get_address(0, 0, r2);
1035 +
1036 +    if (addr > ram_size) {
1037 +        return 0;
1038 +    }
1039 +
1040 +    return env->storage_keys[addr / TARGET_PAGE_SIZE];
1041 +}
1042 +
1043 +/* set storage key extended */
1044 +void HELPER(sske)(uint32_t r1, uint64_t r2)
1045 +{
1046 +    uint64_t addr = get_address(0, 0, r2);
1047 +
1048 +    if (addr > ram_size) {
1049 +        return;
1050 +    }
1051 +
1052 +    env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
1053 +}
1054 +
1055 +/* reset reference bit extended */
1056 +uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
1057 +{
1058 +    uint8_t re;
1059 +    uint8_t key;
1060 +
1061 +    if (r2 > ram_size) {
1062 +        return 0;
1063 +    }
1064 +
1065 +    key = env->storage_keys[r2 / TARGET_PAGE_SIZE];
1066 +    re = key & (SK_R | SK_C);
1067 +    env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R);
1068 +
1069 +    /*
1070 +     * cc
1071 +     *
1072 +     * 0  Reference bit zero; change bit zero
1073 +     * 1  Reference bit zero; change bit one
1074 +     * 2  Reference bit one; change bit zero
1075 +     * 3  Reference bit one; change bit one
1076 +     */
1077 +
1078 +    return re >> 1;
1079 +}
1080 +
1081 +/* compare and swap and purge */
1082 +uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
1083 +{
1084 +    uint32_t cc;
1085 +    uint32_t o1 = env->regs[r1];
1086 +    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
1087 +    uint32_t o2 = ldl(a2);
1088 +
1089 +    if (o1 == o2) {
1090 +        stl(a2, env->regs[(r1 + 1) & 15]);
1091 +        if (env->regs[r2] & 0x3) {
1092 +            /* flush TLB / ALB */
1093 +            tlb_flush(env, 1);
1094 +        }
1095 +        cc = 0;
1096 +    } else {
1097 +        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
1098 +        cc = 1;
1099 +    }
1100 +
1101 +    return cc;
1102 +}
1103 +
1104 +static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
1105 +                        uint64_t mode2)
1106 +{
1107 +    target_ulong src, dest;
1108 +    int flags, cc = 0, i;
1109 +
1110 +    if (!l) {
1111 +        return 0;
1112 +    } else if (l > 256) {
1113 +        /* max 256 */
1114 +        l = 256;
1115 +        cc = 3;
1116 +    }
1117 +
1118 +    if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
1119 +        cpu_loop_exit(env);
1120 +    }
1121 +    dest |= a1 & ~TARGET_PAGE_MASK;
1122 +
1123 +    if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
1124 +        cpu_loop_exit(env);
1125 +    }
1126 +    src |= a2 & ~TARGET_PAGE_MASK;
1127 +
1128 +    /* XXX replace w/ memcpy */
1129 +    for (i = 0; i < l; i++) {
1130 +        /* XXX be more clever */
1131 +        if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
1132 +            (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
1133 +            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
1134 +            break;
1135 +        }
1136 +        stb_phys(dest + i, ldub_phys(src + i));
1137 +    }
1138 +
1139 +    return cc;
1140 +}
1141 +
1142 +uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
1143 +{
1144 +    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
1145 +               __func__, l, a1, a2);
1146 +
1147 +    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
1148 +}
1149 +
1150 +uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
1151 +{
1152 +    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
1153 +               __func__, l, a1, a2);
1154 +
1155 +    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
1156 +}
1157 +
1158 +/* invalidate pte */
1159 +void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
1160 +{
1161 +    uint64_t page = vaddr & TARGET_PAGE_MASK;
1162 +    uint64_t pte = 0;
1163 +
1164 +    /* XXX broadcast to other CPUs */
1165 +
1166 +    /* XXX Linux is nice enough to give us the exact pte address.
1167 +       According to spec we'd have to find it out ourselves */
1168 +    /* XXX Linux is fine with overwriting the pte, the spec requires
1169 +       us to only set the invalid bit */
1170 +    stq_phys(pte_addr, pte | _PAGE_INVALID);
1171 +
1172 +    /* XXX we exploit the fact that Linux passes the exact virtual
1173 +       address here - it's not obliged to! */
1174 +    tlb_flush_page(env, page);
1175 +
1176 +    /* XXX 31-bit hack */
1177 +    if (page & 0x80000000) {
1178 +        tlb_flush_page(env, page & ~0x80000000);
1179 +    } else {
1180 +        tlb_flush_page(env, page | 0x80000000);
1181 +    }
1182 +}
1183 +
1184 +/* flush local tlb */
1185 +void HELPER(ptlb)(void)
1186 +{
1187 +    tlb_flush(env, 1);
1188 +}
1189 +
1190 +/* store using real address */
1191 +void HELPER(stura)(uint64_t addr, uint32_t v1)
1192 +{
1193 +    stw_phys(get_address(0, 0, addr), v1);
1194 +}
1195 +
1196 +/* load real address */
1197 +uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
1198 +{
1199 +    uint32_t cc = 0;
1200 +    int old_exc = env->exception_index;
1201 +    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
1202 +    uint64_t ret;
1203 +    int flags;
1204 +
1205 +    /* XXX incomplete - has more corner cases */
1206 +    if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
1207 +        program_interrupt(env, PGM_SPECIAL_OP, 2);
1208 +    }
1209 +
1210 +    env->exception_index = old_exc;
1211 +    if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
1212 +        cc = 3;
1213 +    }
1214 +    if (env->exception_index == EXCP_PGM) {
1215 +        ret = env->int_pgm_code | 0x80000000;
1216 +    } else {
1217 +        ret |= addr & ~TARGET_PAGE_MASK;
1218 +    }
1219 +    env->exception_index = old_exc;
1220 +
1221 +    if (!(env->psw.mask & PSW_MASK_64)) {
1222 +        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
1223 +            (ret & 0xffffffffULL);
1224 +    } else {
1225 +        env->regs[r1] = ret;
1226 +    }
1227 +
1228 +    return cc;
1229 +}
1230 +
1231 +#endif
1232 diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
1233 index 3b8b997..bb8dbf5 100644
1234 --- a/target-s390x/op_helper.c
1235 +++ b/target-s390x/op_helper.c
1236 @@ -32,57 +32,8 @@
1237  #endif
1238  
1239  #if !defined(CONFIG_USER_ONLY)
1240 -#include "sysemu.h"
1241 -#endif
1242 -
1243 -/*****************************************************************************/
1244 -/* Softmmu support */
1245 -#if !defined(CONFIG_USER_ONLY)
1246  #include "softmmu_exec.h"
1247 -
1248 -#define MMUSUFFIX _mmu
1249 -
1250 -#define SHIFT 0
1251 -#include "softmmu_template.h"
1252 -
1253 -#define SHIFT 1
1254 -#include "softmmu_template.h"
1255 -
1256 -#define SHIFT 2
1257 -#include "softmmu_template.h"
1258 -
1259 -#define SHIFT 3
1260 -#include "softmmu_template.h"
1261 -
1262 -/* try to fill the TLB and return an exception if error. If retaddr is
1263 -   NULL, it means that the function was called in C code (i.e. not
1264 -   from generated code or from helper.c) */
1265 -/* XXX: fix it to restore all registers */
1266 -void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
1267 -              uintptr_t retaddr)
1268 -{
1269 -    TranslationBlock *tb;
1270 -    CPUS390XState *saved_env;
1271 -    int ret;
1272 -
1273 -    saved_env = env;
1274 -    env = env1;
1275 -    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
1276 -    if (unlikely(ret != 0)) {
1277 -        if (likely(retaddr)) {
1278 -            /* now we have a real cpu fault */
1279 -            tb = tb_find_pc(retaddr);
1280 -            if (likely(tb)) {
1281 -                /* the PC is inside the translated code. It means that we have
1282 -                   a virtual CPU fault */
1283 -                cpu_restore_state(tb, env, retaddr);
1284 -            }
1285 -        }
1286 -        cpu_loop_exit(env);
1287 -    }
1288 -    env = saved_env;
1289 -}
1290 -
1291 +#include "sysemu.h"
1292  #endif
1293  
1294  /* #define DEBUG_HELPER */
1295 @@ -101,840 +52,6 @@ void HELPER(exception)(uint32_t excp)
1296  }
1297  
1298  #ifndef CONFIG_USER_ONLY
1299 -static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
1300 -                            uint8_t byte)
1301 -{
1302 -    target_phys_addr_t dest_phys;
1303 -    target_phys_addr_t len = l;
1304 -    void *dest_p;
1305 -    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
1306 -    int flags;
1307 -
1308 -    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
1309 -        stb(dest, byte);
1310 -        cpu_abort(env, "should never reach here");
1311 -    }
1312 -    dest_phys |= dest & ~TARGET_PAGE_MASK;
1313 -
1314 -    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
1315 -
1316 -    memset(dest_p, byte, len);
1317 -
1318 -    cpu_physical_memory_unmap(dest_p, 1, len, len);
1319 -}
1320 -
1321 -static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
1322 -                             uint64_t src)
1323 -{
1324 -    target_phys_addr_t dest_phys;
1325 -    target_phys_addr_t src_phys;
1326 -    target_phys_addr_t len = l;
1327 -    void *dest_p;
1328 -    void *src_p;
1329 -    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
1330 -    int flags;
1331 -
1332 -    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
1333 -        stb(dest, 0);
1334 -        cpu_abort(env, "should never reach here");
1335 -    }
1336 -    dest_phys |= dest & ~TARGET_PAGE_MASK;
1337 -
1338 -    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
1339 -        ldub(src);
1340 -        cpu_abort(env, "should never reach here");
1341 -    }
1342 -    src_phys |= src & ~TARGET_PAGE_MASK;
1343 -
1344 -    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
1345 -    src_p = cpu_physical_memory_map(src_phys, &len, 0);
1346 -
1347 -    memmove(dest_p, src_p, len);
1348 -
1349 -    cpu_physical_memory_unmap(dest_p, 1, len, len);
1350 -    cpu_physical_memory_unmap(src_p, 0, len, len);
1351 -}
1352 -#endif
1353 -
1354 -/* and on array */
1355 -uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
1356 -{
1357 -    int i;
1358 -    unsigned char x;
1359 -    uint32_t cc = 0;
1360 -
1361 -    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
1362 -               __func__, l, dest, src);
1363 -    for (i = 0; i <= l; i++) {
1364 -        x = ldub(dest + i) & ldub(src + i);
1365 -        if (x) {
1366 -            cc = 1;
1367 -        }
1368 -        stb(dest + i, x);
1369 -    }
1370 -    return cc;
1371 -}
1372 -
1373 -/* xor on array */
1374 -uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
1375 -{
1376 -    int i;
1377 -    unsigned char x;
1378 -    uint32_t cc = 0;
1379 -
1380 -    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
1381 -               __func__, l, dest, src);
1382 -
1383 -#ifndef CONFIG_USER_ONLY
1384 -    /* xor with itself is the same as memset(0) */
1385 -    if ((l > 32) && (src == dest) &&
1386 -        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
1387 -        mvc_fast_memset(env, l + 1, dest, 0);
1388 -        return 0;
1389 -    }
1390 -#else
1391 -    if (src == dest) {
1392 -        memset(g2h(dest), 0, l + 1);
1393 -        return 0;
1394 -    }
1395 -#endif
1396 -
1397 -    for (i = 0; i <= l; i++) {
1398 -        x = ldub(dest + i) ^ ldub(src + i);
1399 -        if (x) {
1400 -            cc = 1;
1401 -        }
1402 -        stb(dest + i, x);
1403 -    }
1404 -    return cc;
1405 -}
1406 -
1407 -/* or on array */
1408 -uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
1409 -{
1410 -    int i;
1411 -    unsigned char x;
1412 -    uint32_t cc = 0;
1413 -
1414 -    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
1415 -               __func__, l, dest, src);
1416 -    for (i = 0; i <= l; i++) {
1417 -        x = ldub(dest + i) | ldub(src + i);
1418 -        if (x) {
1419 -            cc = 1;
1420 -        }
1421 -        stb(dest + i, x);
1422 -    }
1423 -    return cc;
1424 -}
1425 -
1426 -/* memmove */
1427 -void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
1428 -{
1429 -    int i = 0;
1430 -    int x = 0;
1431 -    uint32_t l_64 = (l + 1) / 8;
1432 -
1433 -    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
1434 -               __func__, l, dest, src);
1435 -
1436 -#ifndef CONFIG_USER_ONLY
1437 -    if ((l > 32) &&
1438 -        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
1439 -        (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
1440 -        if (dest == (src + 1)) {
1441 -            mvc_fast_memset(env, l + 1, dest, ldub(src));
1442 -            return;
1443 -        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
1444 -            mvc_fast_memmove(env, l + 1, dest, src);
1445 -            return;
1446 -        }
1447 -    }
1448 -#else
1449 -    if (dest == (src + 1)) {
1450 -        memset(g2h(dest), ldub(src), l + 1);
1451 -        return;
1452 -    } else {
1453 -        memmove(g2h(dest), g2h(src), l + 1);
1454 -        return;
1455 -    }
1456 -#endif
1457 -
1458 -    /* handle the parts that fit into 8-byte loads/stores */
1459 -    if (dest != (src + 1)) {
1460 -        for (i = 0; i < l_64; i++) {
1461 -            stq(dest + x, ldq(src + x));
1462 -            x += 8;
1463 -        }
1464 -    }
1465 -
1466 -    /* slow version crossing pages with byte accesses */
1467 -    for (i = x; i <= l; i++) {
1468 -        stb(dest + i, ldub(src + i));
1469 -    }
1470 -}
1471 -
1472 -/* compare unsigned byte arrays */
1473 -uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
1474 -{
1475 -    int i;
1476 -    unsigned char x, y;
1477 -    uint32_t cc;
1478 -
1479 -    HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
1480 -               __func__, l, s1, s2);
1481 -    for (i = 0; i <= l; i++) {
1482 -        x = ldub(s1 + i);
1483 -        y = ldub(s2 + i);
1484 -        HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
1485 -        if (x < y) {
1486 -            cc = 1;
1487 -            goto done;
1488 -        } else if (x > y) {
1489 -            cc = 2;
1490 -            goto done;
1491 -        }
1492 -    }
1493 -    cc = 0;
1494 - done:
1495 -    HELPER_LOG("\n");
1496 -    return cc;
1497 -}
1498 -
1499 -/* compare logical under mask */
1500 -uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
1501 -{
1502 -    uint8_t r, d;
1503 -    uint32_t cc;
1504 -
1505 -    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
1506 -               mask, addr);
1507 -    cc = 0;
1508 -    while (mask) {
1509 -        if (mask & 8) {
1510 -            d = ldub(addr);
1511 -            r = (r1 & 0xff000000UL) >> 24;
1512 -            HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
1513 -                       addr);
1514 -            if (r < d) {
1515 -                cc = 1;
1516 -                break;
1517 -            } else if (r > d) {
1518 -                cc = 2;
1519 -                break;
1520 -            }
1521 -            addr++;
1522 -        }
1523 -        mask = (mask << 1) & 0xf;
1524 -        r1 <<= 8;
1525 -    }
1526 -    HELPER_LOG("\n");
1527 -    return cc;
1528 -}
1529 -
1530 -/* store character under mask */
1531 -void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
1532 -{
1533 -    uint8_t r;
1534 -
1535 -    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
1536 -               addr);
1537 -    while (mask) {
1538 -        if (mask & 8) {
1539 -            r = (r1 & 0xff000000UL) >> 24;
1540 -            stb(addr, r);
1541 -            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
1542 -            addr++;
1543 -        }
1544 -        mask = (mask << 1) & 0xf;
1545 -        r1 <<= 8;
1546 -    }
1547 -    HELPER_LOG("\n");
1548 -}
1549 -
1550 -static inline uint64_t get_address(int x2, int b2, int d2)
1551 -{
1552 -    uint64_t r = d2;
1553 -
1554 -    if (x2) {
1555 -        r += env->regs[x2];
1556 -    }
1557 -
1558 -    if (b2) {
1559 -        r += env->regs[b2];
1560 -    }
1561 -
1562 -    /* 31-Bit mode */
1563 -    if (!(env->psw.mask & PSW_MASK_64)) {
1564 -        r &= 0x7fffffff;
1565 -    }
1566 -
1567 -    return r;
1568 -}
1569 -
1570 -static inline uint64_t get_address_31fix(int reg)
1571 -{
1572 -    uint64_t r = env->regs[reg];
1573 -
1574 -    /* 31-Bit mode */
1575 -    if (!(env->psw.mask & PSW_MASK_64)) {
1576 -        r &= 0x7fffffff;
1577 -    }
1578 -
1579 -    return r;
1580 -}
1581 -
1582 -/* search string (c is byte to search, r2 is string, r1 end of string) */
1583 -uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
1584 -{
1585 -    uint64_t i;
1586 -    uint32_t cc = 2;
1587 -    uint64_t str = get_address_31fix(r2);
1588 -    uint64_t end = get_address_31fix(r1);
1589 -
1590 -    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
1591 -               c, env->regs[r1], env->regs[r2]);
1592 -
1593 -    for (i = str; i != end; i++) {
1594 -        if (ldub(i) == c) {
1595 -            env->regs[r1] = i;
1596 -            cc = 1;
1597 -            break;
1598 -        }
1599 -    }
1600 -
1601 -    return cc;
1602 -}
1603 -
1604 -/* unsigned string compare (c is string terminator) */
1605 -uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
1606 -{
1607 -    uint64_t s1 = get_address_31fix(r1);
1608 -    uint64_t s2 = get_address_31fix(r2);
1609 -    uint8_t v1, v2;
1610 -    uint32_t cc;
1611 -
1612 -    c = c & 0xff;
1613 -#ifdef CONFIG_USER_ONLY
1614 -    if (!c) {
1615 -        HELPER_LOG("%s: comparing '%s' and '%s'\n",
1616 -                   __func__, (char *)g2h(s1), (char *)g2h(s2));
1617 -    }
1618 -#endif
1619 -    for (;;) {
1620 -        v1 = ldub(s1);
1621 -        v2 = ldub(s2);
1622 -        if ((v1 == c || v2 == c) || (v1 != v2)) {
1623 -            break;
1624 -        }
1625 -        s1++;
1626 -        s2++;
1627 -    }
1628 -
1629 -    if (v1 == v2) {
1630 -        cc = 0;
1631 -    } else {
1632 -        cc = (v1 < v2) ? 1 : 2;
1633 -        /* FIXME: 31-bit mode! */
1634 -        env->regs[r1] = s1;
1635 -        env->regs[r2] = s2;
1636 -    }
1637 -    return cc;
1638 -}
1639 -
1640 -/* move page */
1641 -void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
1642 -{
1643 -    /* XXX missing r0 handling */
1644 -#ifdef CONFIG_USER_ONLY
1645 -    int i;
1646 -
1647 -    for (i = 0; i < TARGET_PAGE_SIZE; i++) {
1648 -        stb(r1 + i, ldub(r2 + i));
1649 -    }
1650 -#else
1651 -    mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
1652 -#endif
1653 -}
1654 -
1655 -/* string copy (c is string terminator) */
1656 -void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
1657 -{
1658 -    uint64_t dest = get_address_31fix(r1);
1659 -    uint64_t src = get_address_31fix(r2);
1660 -    uint8_t v;
1661 -
1662 -    c = c & 0xff;
1663 -#ifdef CONFIG_USER_ONLY
1664 -    if (!c) {
1665 -        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
1666 -                   dest);
1667 -    }
1668 -#endif
1669 -    for (;;) {
1670 -        v = ldub(src);
1671 -        stb(dest, v);
1672 -        if (v == c) {
1673 -            break;
1674 -        }
1675 -        src++;
1676 -        dest++;
1677 -    }
1678 -    env->regs[r1] = dest; /* FIXME: 31-bit mode! */
1679 -}
1680 -
1681 -/* compare and swap 64-bit */
1682 -uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
1683 -{
1684 -    /* FIXME: locking? */
1685 -    uint32_t cc;
1686 -    uint64_t v2 = ldq(a2);
1687 -
1688 -    if (env->regs[r1] == v2) {
1689 -        cc = 0;
1690 -        stq(a2, env->regs[r3]);
1691 -    } else {
1692 -        cc = 1;
1693 -        env->regs[r1] = v2;
1694 -    }
1695 -    return cc;
1696 -}
1697 -
1698 -/* compare double and swap 64-bit */
1699 -uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
1700 -{
1701 -    /* FIXME: locking? */
1702 -    uint32_t cc;
1703 -    uint64_t v2_hi = ldq(a2);
1704 -    uint64_t v2_lo = ldq(a2 + 8);
1705 -    uint64_t v1_hi = env->regs[r1];
1706 -    uint64_t v1_lo = env->regs[r1 + 1];
1707 -
1708 -    if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
1709 -        cc = 0;
1710 -        stq(a2, env->regs[r3]);
1711 -        stq(a2 + 8, env->regs[r3 + 1]);
1712 -    } else {
1713 -        cc = 1;
1714 -        env->regs[r1] = v2_hi;
1715 -        env->regs[r1 + 1] = v2_lo;
1716 -    }
1717 -
1718 -    return cc;
1719 -}
1720 -
1721 -/* compare and swap 32-bit */
1722 -uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
1723 -{
1724 -    /* FIXME: locking? */
1725 -    uint32_t cc;
1726 -    uint32_t v2 = ldl(a2);
1727 -
1728 -    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
1729 -    if (((uint32_t)env->regs[r1]) == v2) {
1730 -        cc = 0;
1731 -        stl(a2, (uint32_t)env->regs[r3]);
1732 -    } else {
1733 -        cc = 1;
1734 -        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
1735 -    }
1736 -    return cc;
1737 -}
1738 -
1739 -static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
1740 -{
1741 -    int pos = 24; /* top of the lower half of r1 */
1742 -    uint64_t rmask = 0xff000000ULL;
1743 -    uint8_t val = 0;
1744 -    int ccd = 0;
1745 -    uint32_t cc = 0;
1746 -
1747 -    while (mask) {
1748 -        if (mask & 8) {
1749 -            env->regs[r1] &= ~rmask;
1750 -            val = ldub(address);
1751 -            if ((val & 0x80) && !ccd) {
1752 -                cc = 1;
1753 -            }
1754 -            ccd = 1;
1755 -            if (val && cc == 0) {
1756 -                cc = 2;
1757 -            }
1758 -            env->regs[r1] |= (uint64_t)val << pos;
1759 -            address++;
1760 -        }
1761 -        mask = (mask << 1) & 0xf;
1762 -        pos -= 8;
1763 -        rmask >>= 8;
1764 -    }
1765 -
1766 -    return cc;
1767 -}
1768 -
1769 -/* execute instruction
1770 -   this instruction executes an insn modified with the contents of r1
1771 -   it does not change the executed instruction in memory
1772 -   it does not change the program counter
1773 -   in other words: tricky...
1774 -   currently implemented by interpreting the cases it is most commonly used in
1775 -*/
1776 -uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
1777 -{
1778 -    uint16_t insn = lduw_code(addr);
1779 -
1780 -    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
1781 -               insn);
1782 -    if ((insn & 0xf0ff) == 0xd000) {
1783 -        uint32_t l, insn2, b1, b2, d1, d2;
1784 -
1785 -        l = v1 & 0xff;
1786 -        insn2 = ldl_code(addr + 2);
1787 -        b1 = (insn2 >> 28) & 0xf;
1788 -        b2 = (insn2 >> 12) & 0xf;
1789 -        d1 = (insn2 >> 16) & 0xfff;
1790 -        d2 = insn2 & 0xfff;
1791 -        switch (insn & 0xf00) {
1792 -        case 0x200:
1793 -            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
1794 -            break;
1795 -        case 0x500:
1796 -            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
1797 -            break;
1798 -        case 0x700:
1799 -            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
1800 -            break;
1801 -        case 0xc00:
1802 -            helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
1803 -            break;
1804 -        default:
1805 -            goto abort;
1806 -            break;
1807 -        }
1808 -    } else if ((insn & 0xff00) == 0x0a00) {
1809 -        /* supervisor call */
1810 -        HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
1811 -        env->psw.addr = ret - 4;
1812 -        env->int_svc_code = (insn | v1) & 0xff;
1813 -        env->int_svc_ilc = 4;
1814 -        helper_exception(EXCP_SVC);
1815 -    } else if ((insn & 0xff00) == 0xbf00) {
1816 -        uint32_t insn2, r1, r3, b2, d2;
1817 -
1818 -        insn2 = ldl_code(addr + 2);
1819 -        r1 = (insn2 >> 20) & 0xf;
1820 -        r3 = (insn2 >> 16) & 0xf;
1821 -        b2 = (insn2 >> 12) & 0xf;
1822 -        d2 = insn2 & 0xfff;
1823 -        cc = helper_icm(r1, get_address(0, b2, d2), r3);
1824 -    } else {
1825 -    abort:
1826 -        cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
1827 -                  insn);
1828 -    }
1829 -    return cc;
1830 -}
1831 -
1832 -/* store character under mask high operates on the upper half of r1 */
1833 -void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
1834 -{
1835 -    int pos = 56; /* top of the upper half of r1 */
1836 -
1837 -    while (mask) {
1838 -        if (mask & 8) {
1839 -            stb(address, (env->regs[r1] >> pos) & 0xff);
1840 -            address++;
1841 -        }
1842 -        mask = (mask << 1) & 0xf;
1843 -        pos -= 8;
1844 -    }
1845 -}
1846 -
1847 -/* insert character under mask high; same as icm, but operates on the
1848 -   upper half of r1 */
1849 -uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
1850 -{
1851 -    int pos = 56; /* top of the upper half of r1 */
1852 -    uint64_t rmask = 0xff00000000000000ULL;
1853 -    uint8_t val = 0;
1854 -    int ccd = 0;
1855 -    uint32_t cc = 0;
1856 -
1857 -    while (mask) {
1858 -        if (mask & 8) {
1859 -            env->regs[r1] &= ~rmask;
1860 -            val = ldub(address);
1861 -            if ((val & 0x80) && !ccd) {
1862 -                cc = 1;
1863 -            }
1864 -            ccd = 1;
1865 -            if (val && cc == 0) {
1866 -                cc = 2;
1867 -            }
1868 -            env->regs[r1] |= (uint64_t)val << pos;
1869 -            address++;
1870 -        }
1871 -        mask = (mask << 1) & 0xf;
1872 -        pos -= 8;
1873 -        rmask >>= 8;
1874 -    }
1875 -
1876 -    return cc;
1877 -}
1878 -
1879 -/* load access registers r1 to r3 from memory at a2 */
1880 -void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
1881 -{
1882 -    int i;
1883 -
1884 -    for (i = r1;; i = (i + 1) % 16) {
1885 -        env->aregs[i] = ldl(a2);
1886 -        a2 += 4;
1887 -
1888 -        if (i == r3) {
1889 -            break;
1890 -        }
1891 -    }
1892 -}
1893 -
1894 -/* store access registers r1 to r3 in memory at a2 */
1895 -void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
1896 -{
1897 -    int i;
1898 -
1899 -    for (i = r1;; i = (i + 1) % 16) {
1900 -        stl(a2, env->aregs[i]);
1901 -        a2 += 4;
1902 -
1903 -        if (i == r3) {
1904 -            break;
1905 -        }
1906 -    }
1907 -}
1908 -
1909 -/* move long */
1910 -uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
1911 -{
1912 -    uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
1913 -    uint64_t dest = get_address_31fix(r1);
1914 -    uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
1915 -    uint64_t src = get_address_31fix(r2);
1916 -    uint8_t pad = src >> 24;
1917 -    uint8_t v;
1918 -    uint32_t cc;
1919 -
1920 -    if (destlen == srclen) {
1921 -        cc = 0;
1922 -    } else if (destlen < srclen) {
1923 -        cc = 1;
1924 -    } else {
1925 -        cc = 2;
1926 -    }
1927 -
1928 -    if (srclen > destlen) {
1929 -        srclen = destlen;
1930 -    }
1931 -
1932 -    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
1933 -        v = ldub(src);
1934 -        stb(dest, v);
1935 -    }
1936 -
1937 -    for (; destlen; dest++, destlen--) {
1938 -        stb(dest, pad);
1939 -    }
1940 -
1941 -    env->regs[r1 + 1] = destlen;
1942 -    /* can't use srclen here, we trunc'ed it */
1943 -    env->regs[r2 + 1] -= src - env->regs[r2];
1944 -    env->regs[r1] = dest;
1945 -    env->regs[r2] = src;
1946 -
1947 -    return cc;
1948 -}
1949 -
1950 -/* move long extended another memcopy insn with more bells and whistles */
1951 -uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
1952 -{
1953 -    uint64_t destlen = env->regs[r1 + 1];
1954 -    uint64_t dest = env->regs[r1];
1955 -    uint64_t srclen = env->regs[r3 + 1];
1956 -    uint64_t src = env->regs[r3];
1957 -    uint8_t pad = a2 & 0xff;
1958 -    uint8_t v;
1959 -    uint32_t cc;
1960 -
1961 -    if (!(env->psw.mask & PSW_MASK_64)) {
1962 -        destlen = (uint32_t)destlen;
1963 -        srclen = (uint32_t)srclen;
1964 -        dest &= 0x7fffffff;
1965 -        src &= 0x7fffffff;
1966 -    }
1967 -
1968 -    if (destlen == srclen) {
1969 -        cc = 0;
1970 -    } else if (destlen < srclen) {
1971 -        cc = 1;
1972 -    } else {
1973 -        cc = 2;
1974 -    }
1975 -
1976 -    if (srclen > destlen) {
1977 -        srclen = destlen;
1978 -    }
1979 -
1980 -    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
1981 -        v = ldub(src);
1982 -        stb(dest, v);
1983 -    }
1984 -
1985 -    for (; destlen; dest++, destlen--) {
1986 -        stb(dest, pad);
1987 -    }
1988 -
1989 -    env->regs[r1 + 1] = destlen;
1990 -    /* can't use srclen here, we trunc'ed it */
1991 -    /* FIXME: 31-bit mode! */
1992 -    env->regs[r3 + 1] -= src - env->regs[r3];
1993 -    env->regs[r1] = dest;
1994 -    env->regs[r3] = src;
1995 -
1996 -    return cc;
1997 -}
1998 -
1999 -/* compare logical long extended memcompare insn with padding */
2000 -uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
2001 -{
2002 -    uint64_t destlen = env->regs[r1 + 1];
2003 -    uint64_t dest = get_address_31fix(r1);
2004 -    uint64_t srclen = env->regs[r3 + 1];
2005 -    uint64_t src = get_address_31fix(r3);
2006 -    uint8_t pad = a2 & 0xff;
2007 -    uint8_t v1 = 0, v2 = 0;
2008 -    uint32_t cc = 0;
2009 -
2010 -    if (!(destlen || srclen)) {
2011 -        return cc;
2012 -    }
2013 -
2014 -    if (srclen > destlen) {
2015 -        srclen = destlen;
2016 -    }
2017 -
2018 -    for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
2019 -        v1 = srclen ? ldub(src) : pad;
2020 -        v2 = destlen ? ldub(dest) : pad;
2021 -        if (v1 != v2) {
2022 -            cc = (v1 < v2) ? 1 : 2;
2023 -            break;
2024 -        }
2025 -    }
2026 -
2027 -    env->regs[r1 + 1] = destlen;
2028 -    /* can't use srclen here, we trunc'ed it */
2029 -    env->regs[r3 + 1] -= src - env->regs[r3];
2030 -    env->regs[r1] = dest;
2031 -    env->regs[r3] = src;
2032 -
2033 -    return cc;
2034 -}
2035 -
2036 -/* checksum */
2037 -void HELPER(cksm)(uint32_t r1, uint32_t r2)
2038 -{
2039 -    uint64_t src = get_address_31fix(r2);
2040 -    uint64_t src_len = env->regs[(r2 + 1) & 15];
2041 -    uint64_t cksm = (uint32_t)env->regs[r1];
2042 -
2043 -    while (src_len >= 4) {
2044 -        cksm += ldl(src);
2045 -
2046 -        /* move to next word */
2047 -        src_len -= 4;
2048 -        src += 4;
2049 -    }
2050 -
2051 -    switch (src_len) {
2052 -    case 0:
2053 -        break;
2054 -    case 1:
2055 -        cksm += ldub(src) << 24;
2056 -        break;
2057 -    case 2:
2058 -        cksm += lduw(src) << 16;
2059 -        break;
2060 -    case 3:
2061 -        cksm += lduw(src) << 16;
2062 -        cksm += ldub(src + 2) << 8;
2063 -        break;
2064 -    }
2065 -
2066 -    /* indicate we've processed everything */
2067 -    env->regs[r2] = src + src_len;
2068 -    env->regs[(r2 + 1) & 15] = 0;
2069 -
2070 -    /* store result */
2071 -    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
2072 -        ((uint32_t)cksm + (cksm >> 32));
2073 -}
2074 -
2075 -void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
2076 -{
2077 -    int len_dest = len >> 4;
2078 -    int len_src = len & 0xf;
2079 -    uint8_t b;
2080 -    int second_nibble = 0;
2081 -
2082 -    dest += len_dest;
2083 -    src += len_src;
2084 -
2085 -    /* last byte is special, it only flips the nibbles */
2086 -    b = ldub(src);
2087 -    stb(dest, (b << 4) | (b >> 4));
2088 -    src--;
2089 -    len_src--;
2090 -
2091 -    /* now pad every nibble with 0xf0 */
2092 -
2093 -    while (len_dest > 0) {
2094 -        uint8_t cur_byte = 0;
2095 -
2096 -        if (len_src > 0) {
2097 -            cur_byte = ldub(src);
2098 -        }
2099 -
2100 -        len_dest--;
2101 -        dest--;
2102 -
2103 -        /* only advance one nibble at a time */
2104 -        if (second_nibble) {
2105 -            cur_byte >>= 4;
2106 -            len_src--;
2107 -            src--;
2108 -        }
2109 -        second_nibble = !second_nibble;
2110 -
2111 -        /* digit */
2112 -        cur_byte = (cur_byte & 0xf);
2113 -        /* zone bits */
2114 -        cur_byte |= 0xf0;
2115 -
2116 -        stb(dest, cur_byte);
2117 -    }
2118 -}
2119 -
2120 -void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
2121 -{
2122 -    int i;
2123 -
2124 -    for (i = 0; i <= len; i++) {
2125 -        uint8_t byte = ldub(array + i);
2126 -        uint8_t new_byte = ldub(trans + byte);
2127 -
2128 -        stb(array + i, new_byte);
2129 -    }
2130 -}
2131 -
2132 -#ifndef CONFIG_USER_ONLY
2133  void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
2134  {
2135      qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
2136 @@ -1267,206 +384,6 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
2137      return cc;
2138  }
2139  
2140 -void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
2141 -{
2142 -    int i;
2143 -    uint64_t src = a2;
2144 -
2145 -    for (i = r1;; i = (i + 1) % 16) {
2146 -        env->cregs[i] = ldq(src);
2147 -        HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
2148 -                   i, src, env->cregs[i]);
2149 -        src += sizeof(uint64_t);
2150 -
2151 -        if (i == r3) {
2152 -            break;
2153 -        }
2154 -    }
2155 -
2156 -    tlb_flush(env, 1);
2157 -}
2158 -
2159 -void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
2160 -{
2161 -    int i;
2162 -    uint64_t src = a2;
2163 -
2164 -    for (i = r1;; i = (i + 1) % 16) {
2165 -        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
2166 -        src += sizeof(uint32_t);
2167 -
2168 -        if (i == r3) {
2169 -            break;
2170 -        }
2171 -    }
2172 -
2173 -    tlb_flush(env, 1);
2174 -}
2175 -
2176 -void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
2177 -{
2178 -    int i;
2179 -    uint64_t dest = a2;
2180 -
2181 -    for (i = r1;; i = (i + 1) % 16) {
2182 -        stq(dest, env->cregs[i]);
2183 -        dest += sizeof(uint64_t);
2184 -
2185 -        if (i == r3) {
2186 -            break;
2187 -        }
2188 -    }
2189 -}
2190 -
2191 -void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
2192 -{
2193 -    int i;
2194 -    uint64_t dest = a2;
2195 -
2196 -    for (i = r1;; i = (i + 1) % 16) {
2197 -        stl(dest, env->cregs[i]);
2198 -        dest += sizeof(uint32_t);
2199 -
2200 -        if (i == r3) {
2201 -            break;
2202 -        }
2203 -    }
2204 -}
2205 -
2206 -uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
2207 -{
2208 -    /* XXX implement */
2209 -
2210 -    return 0;
2211 -}
2212 -
2213 -/* insert storage key extended */
2214 -uint64_t HELPER(iske)(uint64_t r2)
2215 -{
2216 -    uint64_t addr = get_address(0, 0, r2);
2217 -
2218 -    if (addr > ram_size) {
2219 -        return 0;
2220 -    }
2221 -
2222 -    return env->storage_keys[addr / TARGET_PAGE_SIZE];
2223 -}
2224 -
2225 -/* set storage key extended */
2226 -void HELPER(sske)(uint32_t r1, uint64_t r2)
2227 -{
2228 -    uint64_t addr = get_address(0, 0, r2);
2229 -
2230 -    if (addr > ram_size) {
2231 -        return;
2232 -    }
2233 -
2234 -    env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
2235 -}
2236 -
2237 -/* reset reference bit extended */
2238 -uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
2239 -{
2240 -    uint8_t re;
2241 -    uint8_t key;
2242 -
2243 -    if (r2 > ram_size) {
2244 -        return 0;
2245 -    }
2246 -
2247 -    key = env->storage_keys[r2 / TARGET_PAGE_SIZE];
2248 -    re = key & (SK_R | SK_C);
2249 -    env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R);
2250 -
2251 -    /*
2252 -     * cc
2253 -     *
2254 -     * 0  Reference bit zero; change bit zero
2255 -     * 1  Reference bit zero; change bit one
2256 -     * 2  Reference bit one; change bit zero
2257 -     * 3  Reference bit one; change bit one
2258 -     */
2259 -
2260 -    return re >> 1;
2261 -}
2262 -
2263 -/* compare and swap and purge */
2264 -uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
2265 -{
2266 -    uint32_t cc;
2267 -    uint32_t o1 = env->regs[r1];
2268 -    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
2269 -    uint32_t o2 = ldl(a2);
2270 -
2271 -    if (o1 == o2) {
2272 -        stl(a2, env->regs[(r1 + 1) & 15]);
2273 -        if (env->regs[r2] & 0x3) {
2274 -            /* flush TLB / ALB */
2275 -            tlb_flush(env, 1);
2276 -        }
2277 -        cc = 0;
2278 -    } else {
2279 -        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
2280 -        cc = 1;
2281 -    }
2282 -
2283 -    return cc;
2284 -}
2285 -
2286 -static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
2287 -                        uint64_t mode2)
2288 -{
2289 -    target_ulong src, dest;
2290 -    int flags, cc = 0, i;
2291 -
2292 -    if (!l) {
2293 -        return 0;
2294 -    } else if (l > 256) {
2295 -        /* max 256 */
2296 -        l = 256;
2297 -        cc = 3;
2298 -    }
2299 -
2300 -    if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
2301 -        cpu_loop_exit(env);
2302 -    }
2303 -    dest |= a1 & ~TARGET_PAGE_MASK;
2304 -
2305 -    if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
2306 -        cpu_loop_exit(env);
2307 -    }
2308 -    src |= a2 & ~TARGET_PAGE_MASK;
2309 -
2310 -    /* XXX replace w/ memcpy */
2311 -    for (i = 0; i < l; i++) {
2312 -        /* XXX be more clever */
2313 -        if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
2314 -            (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
2315 -            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
2316 -            break;
2317 -        }
2318 -        stb_phys(dest + i, ldub_phys(src + i));
2319 -    }
2320 -
2321 -    return cc;
2322 -}
2323 -
2324 -uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
2325 -{
2326 -    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2327 -               __func__, l, a1, a2);
2328 -
2329 -    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
2330 -}
2331 -
2332 -uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
2333 -{
2334 -    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2335 -               __func__, l, a1, a2);
2336 -
2337 -    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
2338 -}
2339 -
2340  uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
2341  {
2342      int cc = 0;
2343 @@ -1508,78 +425,4 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
2344  
2345      return cc;
2346  }
2347 -
2348 -/* invalidate pte */
2349 -void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
2350 -{
2351 -    uint64_t page = vaddr & TARGET_PAGE_MASK;
2352 -    uint64_t pte = 0;
2353 -
2354 -    /* XXX broadcast to other CPUs */
2355 -
2356 -    /* XXX Linux is nice enough to give us the exact pte address.
2357 -       According to spec we'd have to find it out ourselves */
2358 -    /* XXX Linux is fine with overwriting the pte, the spec requires
2359 -       us to only set the invalid bit */
2360 -    stq_phys(pte_addr, pte | _PAGE_INVALID);
2361 -
2362 -    /* XXX we exploit the fact that Linux passes the exact virtual
2363 -       address here - it's not obliged to! */
2364 -    tlb_flush_page(env, page);
2365 -
2366 -    /* XXX 31-bit hack */
2367 -    if (page & 0x80000000) {
2368 -        tlb_flush_page(env, page & ~0x80000000);
2369 -    } else {
2370 -        tlb_flush_page(env, page | 0x80000000);
2371 -    }
2372 -}
2373 -
2374 -/* flush local tlb */
2375 -void HELPER(ptlb)(void)
2376 -{
2377 -    tlb_flush(env, 1);
2378 -}
2379 -
2380 -/* store using real address */
2381 -void HELPER(stura)(uint64_t addr, uint32_t v1)
2382 -{
2383 -    stw_phys(get_address(0, 0, addr), v1);
2384 -}
2385 -
2386 -/* load real address */
2387 -uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
2388 -{
2389 -    uint32_t cc = 0;
2390 -    int old_exc = env->exception_index;
2391 -    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
2392 -    uint64_t ret;
2393 -    int flags;
2394 -
2395 -    /* XXX incomplete - has more corner cases */
2396 -    if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
2397 -        program_interrupt(env, PGM_SPECIAL_OP, 2);
2398 -    }
2399 -
2400 -    env->exception_index = old_exc;
2401 -    if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
2402 -        cc = 3;
2403 -    }
2404 -    if (env->exception_index == EXCP_PGM) {
2405 -        ret = env->int_pgm_code | 0x80000000;
2406 -    } else {
2407 -        ret |= addr & ~TARGET_PAGE_MASK;
2408 -    }
2409 -    env->exception_index = old_exc;
2410 -
2411 -    if (!(env->psw.mask & PSW_MASK_64)) {
2412 -        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
2413 -            (ret & 0xffffffffULL);
2414 -    } else {
2415 -        env->regs[r1] = ret;
2416 -    }
2417 -
2418 -    return cc;
2419 -}
2420 -
2421  #endif
2422 -- 
2423 1.7.12.1
2424