xref: /openbmc/qemu/target/s390x/tcg/mem_helper.c (revision 5b5968c4)
1 /*
2  *  S/390 memory access helper routines
3  *
4  *  Copyright (c) 2009 Ulrich Hecht
5  *  Copyright (c) 2009 Alexander Graf
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "qemu/log.h"
23 #include "cpu.h"
24 #include "s390x-internal.h"
25 #include "tcg_s390x.h"
26 #include "exec/helper-proto.h"
27 #include "exec/exec-all.h"
28 #include "exec/cpu_ldst.h"
29 #include "qemu/int128.h"
30 #include "qemu/atomic128.h"
31 #include "trace.h"
32 
33 #if !defined(CONFIG_USER_ONLY)
34 #include "hw/s390x/storage-keys.h"
35 #include "hw/boards.h"
36 #endif
37 
38 #ifdef CONFIG_USER_ONLY
39 # define user_or_likely(X)    true
40 #else
41 # define user_or_likely(X)    likely(X)
42 #endif
43 
44 /*****************************************************************************/
45 /* Softmmu support */
46 
47 /* #define DEBUG_HELPER */
48 #ifdef DEBUG_HELPER
49 #define HELPER_LOG(x...) qemu_log(x)
50 #else
51 #define HELPER_LOG(x...)
52 #endif
53 
54 static inline bool psw_key_valid(CPUS390XState *env, uint8_t psw_key)
55 {
56     uint16_t pkm = env->cregs[3] >> 16;
57 
58     if (env->psw.mask & PSW_MASK_PSTATE) {
59         /* PSW key has range 0..15, it is valid if the bit is 1 in the PKM */
60         return pkm & (0x8000 >> psw_key);
61     }
62     return true;
63 }
64 
65 static bool is_destructive_overlap(CPUS390XState *env, uint64_t dest,
66                                    uint64_t src, uint32_t len)
67 {
68     if (!len || src == dest) {
69         return false;
70     }
71     /* Take care of wrapping at the end of address space. */
72     if (unlikely(wrap_address(env, src + len - 1) < src)) {
73         return dest > src || dest <= wrap_address(env, src + len - 1);
74     }
75     return dest > src && dest <= src + len - 1;
76 }
77 
78 /* Trigger a SPECIFICATION exception if an address or a length is not
79    naturally aligned.  */
80 static inline void check_alignment(CPUS390XState *env, uint64_t v,
81                                    int wordsize, uintptr_t ra)
82 {
83     if (v % wordsize) {
84         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
85     }
86 }
87 
88 /* Load a value from memory according to its size.  */
89 static inline uint64_t cpu_ldusize_data_ra(CPUS390XState *env, uint64_t addr,
90                                            int wordsize, uintptr_t ra)
91 {
92     switch (wordsize) {
93     case 1:
94         return cpu_ldub_data_ra(env, addr, ra);
95     case 2:
96         return cpu_lduw_data_ra(env, addr, ra);
97     default:
98         abort();
99     }
100 }
101 
102 /* Store a to memory according to its size.  */
103 static inline void cpu_stsize_data_ra(CPUS390XState *env, uint64_t addr,
104                                       uint64_t value, int wordsize,
105                                       uintptr_t ra)
106 {
107     switch (wordsize) {
108     case 1:
109         cpu_stb_data_ra(env, addr, value, ra);
110         break;
111     case 2:
112         cpu_stw_data_ra(env, addr, value, ra);
113         break;
114     default:
115         abort();
116     }
117 }
118 
119 /* An access covers at most 4096 bytes and therefore at most two pages. */
120 typedef struct S390Access {
121     target_ulong vaddr1;
122     target_ulong vaddr2;
123     void *haddr1;
124     void *haddr2;
125     uint16_t size1;
126     uint16_t size2;
127     /*
128      * If we can't access the host page directly, we'll have to do I/O access
129      * via ld/st helpers. These are internal details, so we store the
130      * mmu idx to do the access here instead of passing it around in the
131      * helpers.
132      */
133     int mmu_idx;
134 } S390Access;
135 
136 /*
137  * With nonfault=1, return the PGM_ exception that would have been injected
138  * into the guest; return 0 if no exception was detected.
139  *
140  * For !CONFIG_USER_ONLY, the TEC is stored stored to env->tlb_fill_tec.
141  * For CONFIG_USER_ONLY, the faulting address is stored to env->__excp_addr.
142  */
143 static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
144                                     int size, MMUAccessType access_type,
145                                     int mmu_idx, bool nonfault,
146                                     void **phost, uintptr_t ra)
147 {
148     int flags = probe_access_flags(env, addr, access_type, mmu_idx,
149                                    nonfault, phost, ra);
150 
151     if (unlikely(flags & TLB_INVALID_MASK)) {
152         assert(!nonfault);
153 #ifdef CONFIG_USER_ONLY
154         /* Address is in TEC in system mode; see s390_cpu_record_sigsegv. */
155         env->__excp_addr = addr & TARGET_PAGE_MASK;
156         return (page_get_flags(addr) & PAGE_VALID
157                 ? PGM_PROTECTION : PGM_ADDRESSING);
158 #else
159         return env->tlb_fill_exc;
160 #endif
161     }
162 
163 #ifndef CONFIG_USER_ONLY
164     if (unlikely(flags & TLB_WATCHPOINT)) {
165         /* S390 does not presently use transaction attributes. */
166         cpu_check_watchpoint(env_cpu(env), addr, size,
167                              MEMTXATTRS_UNSPECIFIED,
168                              (access_type == MMU_DATA_STORE
169                               ? BP_MEM_WRITE : BP_MEM_READ), ra);
170     }
171 #endif
172 
173     return 0;
174 }
175 
176 static int access_prepare_nf(S390Access *access, CPUS390XState *env,
177                              bool nonfault, vaddr vaddr1, int size,
178                              MMUAccessType access_type,
179                              int mmu_idx, uintptr_t ra)
180 {
181     int size1, size2, exc;
182 
183     assert(size > 0 && size <= 4096);
184 
185     size1 = MIN(size, -(vaddr1 | TARGET_PAGE_MASK)),
186     size2 = size - size1;
187 
188     memset(access, 0, sizeof(*access));
189     access->vaddr1 = vaddr1;
190     access->size1 = size1;
191     access->size2 = size2;
192     access->mmu_idx = mmu_idx;
193 
194     exc = s390_probe_access(env, vaddr1, size1, access_type, mmu_idx, nonfault,
195                             &access->haddr1, ra);
196     if (unlikely(exc)) {
197         return exc;
198     }
199     if (unlikely(size2)) {
200         /* The access crosses page boundaries. */
201         vaddr vaddr2 = wrap_address(env, vaddr1 + size1);
202 
203         access->vaddr2 = vaddr2;
204         exc = s390_probe_access(env, vaddr2, size2, access_type, mmu_idx,
205                                 nonfault, &access->haddr2, ra);
206         if (unlikely(exc)) {
207             return exc;
208         }
209     }
210     return 0;
211 }
212 
213 static inline void access_prepare(S390Access *ret, CPUS390XState *env,
214                                   vaddr vaddr, int size,
215                                   MMUAccessType access_type, int mmu_idx,
216                                   uintptr_t ra)
217 {
218     int exc = access_prepare_nf(ret, env, false, vaddr, size,
219                                 access_type, mmu_idx, ra);
220     assert(!exc);
221 }
222 
223 /* Helper to handle memset on a single page. */
224 static void do_access_memset(CPUS390XState *env, vaddr vaddr, char *haddr,
225                              uint8_t byte, uint16_t size, int mmu_idx,
226                              uintptr_t ra)
227 {
228 #ifdef CONFIG_USER_ONLY
229     memset(haddr, byte, size);
230 #else
231     if (likely(haddr)) {
232         memset(haddr, byte, size);
233     } else {
234         MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
235         for (int i = 0; i < size; i++) {
236             cpu_stb_mmu(env, vaddr + i, byte, oi, ra);
237         }
238     }
239 #endif
240 }
241 
242 static void access_memset(CPUS390XState *env, S390Access *desta,
243                           uint8_t byte, uintptr_t ra)
244 {
245 
246     do_access_memset(env, desta->vaddr1, desta->haddr1, byte, desta->size1,
247                      desta->mmu_idx, ra);
248     if (likely(!desta->size2)) {
249         return;
250     }
251     do_access_memset(env, desta->vaddr2, desta->haddr2, byte, desta->size2,
252                      desta->mmu_idx, ra);
253 }
254 
255 static uint8_t access_get_byte(CPUS390XState *env, S390Access *access,
256                                int offset, uintptr_t ra)
257 {
258     target_ulong vaddr = access->vaddr1;
259     void *haddr = access->haddr1;
260 
261     if (unlikely(offset >= access->size1)) {
262         offset -= access->size1;
263         vaddr = access->vaddr2;
264         haddr = access->haddr2;
265     }
266 
267     if (user_or_likely(haddr)) {
268         return ldub_p(haddr + offset);
269     } else {
270         MemOpIdx oi = make_memop_idx(MO_UB, access->mmu_idx);
271         return cpu_ldb_mmu(env, vaddr + offset, oi, ra);
272     }
273 }
274 
275 static void access_set_byte(CPUS390XState *env, S390Access *access,
276                             int offset, uint8_t byte, uintptr_t ra)
277 {
278     target_ulong vaddr = access->vaddr1;
279     void *haddr = access->haddr1;
280 
281     if (unlikely(offset >= access->size1)) {
282         offset -= access->size1;
283         vaddr = access->vaddr2;
284         haddr = access->haddr2;
285     }
286 
287     if (user_or_likely(haddr)) {
288         stb_p(haddr + offset, byte);
289     } else {
290         MemOpIdx oi = make_memop_idx(MO_UB, access->mmu_idx);
291         cpu_stb_mmu(env, vaddr + offset, byte, oi, ra);
292     }
293 }
294 
295 /*
296  * Move data with the same semantics as memmove() in case ranges don't overlap
297  * or src > dest. Undefined behavior on destructive overlaps.
298  */
299 static void access_memmove(CPUS390XState *env, S390Access *desta,
300                            S390Access *srca, uintptr_t ra)
301 {
302     int len = desta->size1 + desta->size2;
303     int diff;
304 
305     assert(len == srca->size1 + srca->size2);
306 
307     /* Fallback to slow access in case we don't have access to all host pages */
308     if (unlikely(!desta->haddr1 || (desta->size2 && !desta->haddr2) ||
309                  !srca->haddr1 || (srca->size2 && !srca->haddr2))) {
310         int i;
311 
312         for (i = 0; i < len; i++) {
313             uint8_t byte = access_get_byte(env, srca, i, ra);
314 
315             access_set_byte(env, desta, i, byte, ra);
316         }
317         return;
318     }
319 
320     diff = desta->size1 - srca->size1;
321     if (likely(diff == 0)) {
322         memmove(desta->haddr1, srca->haddr1, srca->size1);
323         if (unlikely(srca->size2)) {
324             memmove(desta->haddr2, srca->haddr2, srca->size2);
325         }
326     } else if (diff > 0) {
327         memmove(desta->haddr1, srca->haddr1, srca->size1);
328         memmove(desta->haddr1 + srca->size1, srca->haddr2, diff);
329         if (likely(desta->size2)) {
330             memmove(desta->haddr2, srca->haddr2 + diff, desta->size2);
331         }
332     } else {
333         diff = -diff;
334         memmove(desta->haddr1, srca->haddr1, desta->size1);
335         memmove(desta->haddr2, srca->haddr1 + desta->size1, diff);
336         if (likely(srca->size2)) {
337             memmove(desta->haddr2 + diff, srca->haddr2, srca->size2);
338         }
339     }
340 }
341 
342 static int mmu_idx_from_as(uint8_t as)
343 {
344     switch (as) {
345     case AS_PRIMARY:
346         return MMU_PRIMARY_IDX;
347     case AS_SECONDARY:
348         return MMU_SECONDARY_IDX;
349     case AS_HOME:
350         return MMU_HOME_IDX;
351     default:
352         /* FIXME AS_ACCREG */
353         g_assert_not_reached();
354     }
355 }
356 
357 /* and on array */
358 static uint32_t do_helper_nc(CPUS390XState *env, uint32_t l, uint64_t dest,
359                              uint64_t src, uintptr_t ra)
360 {
361     const int mmu_idx = cpu_mmu_index(env, false);
362     S390Access srca1, srca2, desta;
363     uint32_t i;
364     uint8_t c = 0;
365 
366     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
367                __func__, l, dest, src);
368 
369     /* NC always processes one more byte than specified - maximum is 256 */
370     l++;
371 
372     access_prepare(&srca1, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
373     access_prepare(&srca2, env, dest, l, MMU_DATA_LOAD, mmu_idx, ra);
374     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
375     for (i = 0; i < l; i++) {
376         const uint8_t x = access_get_byte(env, &srca1, i, ra) &
377                           access_get_byte(env, &srca2, i, ra);
378 
379         c |= x;
380         access_set_byte(env, &desta, i, x, ra);
381     }
382     return c != 0;
383 }
384 
385 uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest,
386                     uint64_t src)
387 {
388     return do_helper_nc(env, l, dest, src, GETPC());
389 }
390 
391 /* xor on array */
392 static uint32_t do_helper_xc(CPUS390XState *env, uint32_t l, uint64_t dest,
393                              uint64_t src, uintptr_t ra)
394 {
395     const int mmu_idx = cpu_mmu_index(env, false);
396     S390Access srca1, srca2, desta;
397     uint32_t i;
398     uint8_t c = 0;
399 
400     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
401                __func__, l, dest, src);
402 
403     /* XC always processes one more byte than specified - maximum is 256 */
404     l++;
405 
406     access_prepare(&srca1, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
407     access_prepare(&srca2, env, dest, l, MMU_DATA_LOAD, mmu_idx, ra);
408     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
409 
410     /* xor with itself is the same as memset(0) */
411     if (src == dest) {
412         access_memset(env, &desta, 0, ra);
413         return 0;
414     }
415 
416     for (i = 0; i < l; i++) {
417         const uint8_t x = access_get_byte(env, &srca1, i, ra) ^
418                           access_get_byte(env, &srca2, i, ra);
419 
420         c |= x;
421         access_set_byte(env, &desta, i, x, ra);
422     }
423     return c != 0;
424 }
425 
426 uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
427                     uint64_t src)
428 {
429     return do_helper_xc(env, l, dest, src, GETPC());
430 }
431 
432 /* or on array */
433 static uint32_t do_helper_oc(CPUS390XState *env, uint32_t l, uint64_t dest,
434                              uint64_t src, uintptr_t ra)
435 {
436     const int mmu_idx = cpu_mmu_index(env, false);
437     S390Access srca1, srca2, desta;
438     uint32_t i;
439     uint8_t c = 0;
440 
441     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
442                __func__, l, dest, src);
443 
444     /* OC always processes one more byte than specified - maximum is 256 */
445     l++;
446 
447     access_prepare(&srca1, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
448     access_prepare(&srca2, env, dest, l, MMU_DATA_LOAD, mmu_idx, ra);
449     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
450     for (i = 0; i < l; i++) {
451         const uint8_t x = access_get_byte(env, &srca1, i, ra) |
452                           access_get_byte(env, &srca2, i, ra);
453 
454         c |= x;
455         access_set_byte(env, &desta, i, x, ra);
456     }
457     return c != 0;
458 }
459 
460 uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest,
461                     uint64_t src)
462 {
463     return do_helper_oc(env, l, dest, src, GETPC());
464 }
465 
466 /* memmove */
467 static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest,
468                               uint64_t src, uintptr_t ra)
469 {
470     const int mmu_idx = cpu_mmu_index(env, false);
471     S390Access srca, desta;
472     uint32_t i;
473 
474     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
475                __func__, l, dest, src);
476 
477     /* MVC always copies one more byte than specified - maximum is 256 */
478     l++;
479 
480     access_prepare(&srca, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
481     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
482 
483     /*
484      * "When the operands overlap, the result is obtained as if the operands
485      * were processed one byte at a time". Only non-destructive overlaps
486      * behave like memmove().
487      */
488     if (dest == src + 1) {
489         access_memset(env, &desta, access_get_byte(env, &srca, 0, ra), ra);
490     } else if (!is_destructive_overlap(env, dest, src, l)) {
491         access_memmove(env, &desta, &srca, ra);
492     } else {
493         for (i = 0; i < l; i++) {
494             uint8_t byte = access_get_byte(env, &srca, i, ra);
495 
496             access_set_byte(env, &desta, i, byte, ra);
497         }
498     }
499 
500     return env->cc_op;
501 }
502 
503 void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
504 {
505     do_helper_mvc(env, l, dest, src, GETPC());
506 }
507 
508 /* move right to left */
509 void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src)
510 {
511     const int mmu_idx = cpu_mmu_index(env, false);
512     const uint64_t ra = GETPC();
513     S390Access srca, desta;
514     int32_t i;
515 
516     /* MVCRL always copies one more byte than specified - maximum is 256 */
517     l++;
518 
519     access_prepare(&srca, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
520     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
521 
522     for (i = l - 1; i >= 0; i--) {
523         uint8_t byte = access_get_byte(env, &srca, i, ra);
524         access_set_byte(env, &desta, i, byte, ra);
525     }
526 }
527 
528 /* move inverse  */
529 void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
530 {
531     const int mmu_idx = cpu_mmu_index(env, false);
532     S390Access srca, desta;
533     uintptr_t ra = GETPC();
534     int i;
535 
536     /* MVCIN always copies one more byte than specified - maximum is 256 */
537     l++;
538 
539     src = wrap_address(env, src - l + 1);
540     access_prepare(&srca, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
541     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
542     for (i = 0; i < l; i++) {
543         const uint8_t x = access_get_byte(env, &srca, l - i - 1, ra);
544 
545         access_set_byte(env, &desta, i, x, ra);
546     }
547 }
548 
549 /* move numerics  */
550 void HELPER(mvn)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
551 {
552     const int mmu_idx = cpu_mmu_index(env, false);
553     S390Access srca1, srca2, desta;
554     uintptr_t ra = GETPC();
555     int i;
556 
557     /* MVN always copies one more byte than specified - maximum is 256 */
558     l++;
559 
560     access_prepare(&srca1, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
561     access_prepare(&srca2, env, dest, l, MMU_DATA_LOAD, mmu_idx, ra);
562     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
563     for (i = 0; i < l; i++) {
564         const uint8_t x = (access_get_byte(env, &srca1, i, ra) & 0x0f) |
565                           (access_get_byte(env, &srca2, i, ra) & 0xf0);
566 
567         access_set_byte(env, &desta, i, x, ra);
568     }
569 }
570 
571 /* move with offset  */
572 void HELPER(mvo)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
573 {
574     const int mmu_idx = cpu_mmu_index(env, false);
575     /* MVO always processes one more byte than specified - maximum is 16 */
576     const int len_dest = (l >> 4) + 1;
577     const int len_src = (l & 0xf) + 1;
578     uintptr_t ra = GETPC();
579     uint8_t byte_dest, byte_src;
580     S390Access srca, desta;
581     int i, j;
582 
583     access_prepare(&srca, env, src, len_src, MMU_DATA_LOAD, mmu_idx, ra);
584     access_prepare(&desta, env, dest, len_dest, MMU_DATA_STORE, mmu_idx, ra);
585 
586     /* Handle rightmost byte */
587     byte_dest = cpu_ldub_data_ra(env, dest + len_dest - 1, ra);
588     byte_src = access_get_byte(env, &srca, len_src - 1, ra);
589     byte_dest = (byte_dest & 0x0f) | (byte_src << 4);
590     access_set_byte(env, &desta, len_dest - 1, byte_dest, ra);
591 
592     /* Process remaining bytes from right to left */
593     for (i = len_dest - 2, j = len_src - 2; i >= 0; i--, j--) {
594         byte_dest = byte_src >> 4;
595         if (j >= 0) {
596             byte_src = access_get_byte(env, &srca, j, ra);
597         } else {
598             byte_src = 0;
599         }
600         byte_dest |= byte_src << 4;
601         access_set_byte(env, &desta, i, byte_dest, ra);
602     }
603 }
604 
605 /* move zones  */
606 void HELPER(mvz)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
607 {
608     const int mmu_idx = cpu_mmu_index(env, false);
609     S390Access srca1, srca2, desta;
610     uintptr_t ra = GETPC();
611     int i;
612 
613     /* MVZ always copies one more byte than specified - maximum is 256 */
614     l++;
615 
616     access_prepare(&srca1, env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
617     access_prepare(&srca2, env, dest, l, MMU_DATA_LOAD, mmu_idx, ra);
618     access_prepare(&desta, env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
619     for (i = 0; i < l; i++) {
620         const uint8_t x = (access_get_byte(env, &srca1, i, ra) & 0xf0) |
621                           (access_get_byte(env, &srca2, i, ra) & 0x0f);
622 
623         access_set_byte(env, &desta, i, x, ra);
624     }
625 }
626 
627 /* compare unsigned byte arrays */
628 static uint32_t do_helper_clc(CPUS390XState *env, uint32_t l, uint64_t s1,
629                               uint64_t s2, uintptr_t ra)
630 {
631     uint32_t i;
632     uint32_t cc = 0;
633 
634     HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
635                __func__, l, s1, s2);
636 
637     for (i = 0; i <= l; i++) {
638         uint8_t x = cpu_ldub_data_ra(env, s1 + i, ra);
639         uint8_t y = cpu_ldub_data_ra(env, s2 + i, ra);
640         HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
641         if (x < y) {
642             cc = 1;
643             break;
644         } else if (x > y) {
645             cc = 2;
646             break;
647         }
648     }
649 
650     HELPER_LOG("\n");
651     return cc;
652 }
653 
654 uint32_t HELPER(clc)(CPUS390XState *env, uint32_t l, uint64_t s1, uint64_t s2)
655 {
656     return do_helper_clc(env, l, s1, s2, GETPC());
657 }
658 
659 /* compare logical under mask */
660 uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
661                      uint64_t addr)
662 {
663     uintptr_t ra = GETPC();
664     uint32_t cc = 0;
665 
666     HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
667                mask, addr);
668 
669     while (mask) {
670         if (mask & 8) {
671             uint8_t d = cpu_ldub_data_ra(env, addr, ra);
672             uint8_t r = extract32(r1, 24, 8);
673             HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
674                        addr);
675             if (r < d) {
676                 cc = 1;
677                 break;
678             } else if (r > d) {
679                 cc = 2;
680                 break;
681             }
682             addr++;
683         }
684         mask = (mask << 1) & 0xf;
685         r1 <<= 8;
686     }
687 
688     HELPER_LOG("\n");
689     return cc;
690 }
691 
692 static inline uint64_t get_address(CPUS390XState *env, int reg)
693 {
694     return wrap_address(env, env->regs[reg]);
695 }
696 
697 /*
698  * Store the address to the given register, zeroing out unused leftmost
699  * bits in bit positions 32-63 (24-bit and 31-bit mode only).
700  */
701 static inline void set_address_zero(CPUS390XState *env, int reg,
702                                     uint64_t address)
703 {
704     if (env->psw.mask & PSW_MASK_64) {
705         env->regs[reg] = address;
706     } else {
707         if (!(env->psw.mask & PSW_MASK_32)) {
708             address &= 0x00ffffff;
709         } else {
710             address &= 0x7fffffff;
711         }
712         env->regs[reg] = deposit64(env->regs[reg], 0, 32, address);
713     }
714 }
715 
716 static inline void set_address(CPUS390XState *env, int reg, uint64_t address)
717 {
718     if (env->psw.mask & PSW_MASK_64) {
719         /* 64-Bit mode */
720         env->regs[reg] = address;
721     } else {
722         if (!(env->psw.mask & PSW_MASK_32)) {
723             /* 24-Bit mode. According to the PoO it is implementation
724             dependent if bits 32-39 remain unchanged or are set to
725             zeros.  Choose the former so that the function can also be
726             used for TRT.  */
727             env->regs[reg] = deposit64(env->regs[reg], 0, 24, address);
728         } else {
729             /* 31-Bit mode. According to the PoO it is implementation
730             dependent if bit 32 remains unchanged or is set to zero.
731             Choose the latter so that the function can also be used for
732             TRT.  */
733             address &= 0x7fffffff;
734             env->regs[reg] = deposit64(env->regs[reg], 0, 32, address);
735         }
736     }
737 }
738 
739 static inline uint64_t wrap_length32(CPUS390XState *env, uint64_t length)
740 {
741     if (!(env->psw.mask & PSW_MASK_64)) {
742         return (uint32_t)length;
743     }
744     return length;
745 }
746 
747 static inline uint64_t wrap_length31(CPUS390XState *env, uint64_t length)
748 {
749     if (!(env->psw.mask & PSW_MASK_64)) {
750         /* 24-Bit and 31-Bit mode */
751         length &= 0x7fffffff;
752     }
753     return length;
754 }
755 
756 static inline uint64_t get_length(CPUS390XState *env, int reg)
757 {
758     return wrap_length31(env, env->regs[reg]);
759 }
760 
761 static inline void set_length(CPUS390XState *env, int reg, uint64_t length)
762 {
763     if (env->psw.mask & PSW_MASK_64) {
764         /* 64-Bit mode */
765         env->regs[reg] = length;
766     } else {
767         /* 24-Bit and 31-Bit mode */
768         env->regs[reg] = deposit64(env->regs[reg], 0, 32, length);
769     }
770 }
771 
772 /* search string (c is byte to search, r2 is string, r1 end of string) */
773 void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
774 {
775     uintptr_t ra = GETPC();
776     uint64_t end, str;
777     uint32_t len;
778     uint8_t v, c = env->regs[0];
779 
780     /* Bits 32-55 must contain all 0.  */
781     if (env->regs[0] & 0xffffff00u) {
782         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
783     }
784 
785     str = get_address(env, r2);
786     end = get_address(env, r1);
787 
788     /* Lest we fail to service interrupts in a timely manner, limit the
789        amount of work we're willing to do.  For now, let's cap at 8k.  */
790     for (len = 0; len < 0x2000; ++len) {
791         if (str + len == end) {
792             /* Character not found.  R1 & R2 are unmodified.  */
793             env->cc_op = 2;
794             return;
795         }
796         v = cpu_ldub_data_ra(env, str + len, ra);
797         if (v == c) {
798             /* Character found.  Set R1 to the location; R2 is unmodified.  */
799             env->cc_op = 1;
800             set_address(env, r1, str + len);
801             return;
802         }
803     }
804 
805     /* CPU-determined bytes processed.  Advance R2 to next byte to process.  */
806     env->cc_op = 3;
807     set_address(env, r2, str + len);
808 }
809 
810 void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2)
811 {
812     uintptr_t ra = GETPC();
813     uint32_t len;
814     uint16_t v, c = env->regs[0];
815     uint64_t end, str, adj_end;
816 
817     /* Bits 32-47 of R0 must be zero.  */
818     if (env->regs[0] & 0xffff0000u) {
819         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
820     }
821 
822     str = get_address(env, r2);
823     end = get_address(env, r1);
824 
825     /* If the LSB of the two addresses differ, use one extra byte.  */
826     adj_end = end + ((str ^ end) & 1);
827 
828     /* Lest we fail to service interrupts in a timely manner, limit the
829        amount of work we're willing to do.  For now, let's cap at 8k.  */
830     for (len = 0; len < 0x2000; len += 2) {
831         if (str + len == adj_end) {
832             /* End of input found.  */
833             env->cc_op = 2;
834             return;
835         }
836         v = cpu_lduw_data_ra(env, str + len, ra);
837         if (v == c) {
838             /* Character found.  Set R1 to the location; R2 is unmodified.  */
839             env->cc_op = 1;
840             set_address(env, r1, str + len);
841             return;
842         }
843     }
844 
845     /* CPU-determined bytes processed.  Advance R2 to next byte to process.  */
846     env->cc_op = 3;
847     set_address(env, r2, str + len);
848 }
849 
850 /* unsigned string compare (c is string terminator) */
851 Int128 HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2)
852 {
853     uintptr_t ra = GETPC();
854     uint32_t len;
855 
856     c = c & 0xff;
857     s1 = wrap_address(env, s1);
858     s2 = wrap_address(env, s2);
859 
860     /* Lest we fail to service interrupts in a timely manner, limit the
861        amount of work we're willing to do.  For now, let's cap at 8k.  */
862     for (len = 0; len < 0x2000; ++len) {
863         uint8_t v1 = cpu_ldub_data_ra(env, s1 + len, ra);
864         uint8_t v2 = cpu_ldub_data_ra(env, s2 + len, ra);
865         if (v1 == v2) {
866             if (v1 == c) {
867                 /* Equal.  CC=0, and don't advance the registers.  */
868                 env->cc_op = 0;
869                 return int128_make128(s2, s1);
870             }
871         } else {
872             /* Unequal.  CC={1,2}, and advance the registers.  Note that
873                the terminator need not be zero, but the string that contains
874                the terminator is by definition "low".  */
875             env->cc_op = (v1 == c ? 1 : v2 == c ? 2 : v1 < v2 ? 1 : 2);
876             return int128_make128(s2 + len, s1 + len);
877         }
878     }
879 
880     /* CPU-determined bytes equal; advance the registers.  */
881     env->cc_op = 3;
882     return int128_make128(s2 + len, s1 + len);
883 }
884 
885 /* move page */
886 uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint32_t r1, uint32_t r2)
887 {
888     const uint64_t src = get_address(env, r2) & TARGET_PAGE_MASK;
889     const uint64_t dst = get_address(env, r1) & TARGET_PAGE_MASK;
890     const int mmu_idx = cpu_mmu_index(env, false);
891     const bool f = extract64(r0, 11, 1);
892     const bool s = extract64(r0, 10, 1);
893     const bool cco = extract64(r0, 8, 1);
894     uintptr_t ra = GETPC();
895     S390Access srca, desta;
896     int exc;
897 
898     if ((f && s) || extract64(r0, 12, 4)) {
899         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
900     }
901 
902     /*
903      * We always manually handle exceptions such that we can properly store
904      * r1/r2 to the lowcore on page-translation exceptions.
905      *
906      * TODO: Access key handling
907      */
908     exc = access_prepare_nf(&srca, env, true, src, TARGET_PAGE_SIZE,
909                             MMU_DATA_LOAD, mmu_idx, ra);
910     if (exc) {
911         if (cco) {
912             return 2;
913         }
914         goto inject_exc;
915     }
916     exc = access_prepare_nf(&desta, env, true, dst, TARGET_PAGE_SIZE,
917                             MMU_DATA_STORE, mmu_idx, ra);
918     if (exc) {
919         if (cco && exc != PGM_PROTECTION) {
920             return 1;
921         }
922         goto inject_exc;
923     }
924     access_memmove(env, &desta, &srca, ra);
925     return 0; /* data moved */
926 inject_exc:
927 #if !defined(CONFIG_USER_ONLY)
928     if (exc != PGM_ADDRESSING) {
929         stq_phys(env_cpu(env)->as, env->psa + offsetof(LowCore, trans_exc_code),
930                  env->tlb_fill_tec);
931     }
932     if (exc == PGM_PAGE_TRANS) {
933         stb_phys(env_cpu(env)->as, env->psa + offsetof(LowCore, op_access_id),
934                  r1 << 4 | r2);
935     }
936 #endif
937     tcg_s390_program_interrupt(env, exc, ra);
938 }
939 
940 /* string copy */
941 uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
942 {
943     const int mmu_idx = cpu_mmu_index(env, false);
944     const uint64_t d = get_address(env, r1);
945     const uint64_t s = get_address(env, r2);
946     const uint8_t c = env->regs[0];
947     const int len = MIN(-(d | TARGET_PAGE_MASK), -(s | TARGET_PAGE_MASK));
948     S390Access srca, desta;
949     uintptr_t ra = GETPC();
950     int i;
951 
952     if (env->regs[0] & 0xffffff00ull) {
953         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
954     }
955 
956     /*
957      * Our access should not exceed single pages, as we must not report access
958      * exceptions exceeding the actually copied range (which we don't know at
959      * this point). We might over-indicate watchpoints within the pages
960      * (if we ever care, we have to limit processing to a single byte).
961      */
962     access_prepare(&srca, env, s, len, MMU_DATA_LOAD, mmu_idx, ra);
963     access_prepare(&desta, env, d, len, MMU_DATA_STORE, mmu_idx, ra);
964     for (i = 0; i < len; i++) {
965         const uint8_t v = access_get_byte(env, &srca, i, ra);
966 
967         access_set_byte(env, &desta, i, v, ra);
968         if (v == c) {
969             set_address_zero(env, r1, d + i);
970             return 1;
971         }
972     }
973     set_address_zero(env, r1, d + len);
974     set_address_zero(env, r2, s + len);
975     return 3;
976 }
977 
978 /* load access registers r1 to r3 from memory at a2 */
979 void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
980 {
981     uintptr_t ra = GETPC();
982     int i;
983 
984     if (a2 & 0x3) {
985         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
986     }
987 
988     for (i = r1;; i = (i + 1) % 16) {
989         env->aregs[i] = cpu_ldl_data_ra(env, a2, ra);
990         a2 += 4;
991 
992         if (i == r3) {
993             break;
994         }
995     }
996 }
997 
998 /* store access registers r1 to r3 in memory at a2 */
999 void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
1000 {
1001     uintptr_t ra = GETPC();
1002     int i;
1003 
1004     if (a2 & 0x3) {
1005         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1006     }
1007 
1008     for (i = r1;; i = (i + 1) % 16) {
1009         cpu_stl_data_ra(env, a2, env->aregs[i], ra);
1010         a2 += 4;
1011 
1012         if (i == r3) {
1013             break;
1014         }
1015     }
1016 }
1017 
1018 /* move long helper */
1019 static inline uint32_t do_mvcl(CPUS390XState *env,
1020                                uint64_t *dest, uint64_t *destlen,
1021                                uint64_t *src, uint64_t *srclen,
1022                                uint16_t pad, int wordsize, uintptr_t ra)
1023 {
1024     const int mmu_idx = cpu_mmu_index(env, false);
1025     int len = MIN(*destlen, -(*dest | TARGET_PAGE_MASK));
1026     S390Access srca, desta;
1027     int i, cc;
1028 
1029     if (*destlen == *srclen) {
1030         cc = 0;
1031     } else if (*destlen < *srclen) {
1032         cc = 1;
1033     } else {
1034         cc = 2;
1035     }
1036 
1037     if (!*destlen) {
1038         return cc;
1039     }
1040 
1041     /*
1042      * Only perform one type of type of operation (move/pad) at a time.
1043      * Stay within single pages.
1044      */
1045     if (*srclen) {
1046         /* Copy the src array */
1047         len = MIN(MIN(*srclen, -(*src | TARGET_PAGE_MASK)), len);
1048         *destlen -= len;
1049         *srclen -= len;
1050         access_prepare(&srca, env, *src, len, MMU_DATA_LOAD, mmu_idx, ra);
1051         access_prepare(&desta, env, *dest, len, MMU_DATA_STORE, mmu_idx, ra);
1052         access_memmove(env, &desta, &srca, ra);
1053         *src = wrap_address(env, *src + len);
1054         *dest = wrap_address(env, *dest + len);
1055     } else if (wordsize == 1) {
1056         /* Pad the remaining area */
1057         *destlen -= len;
1058         access_prepare(&desta, env, *dest, len, MMU_DATA_STORE, mmu_idx, ra);
1059         access_memset(env, &desta, pad, ra);
1060         *dest = wrap_address(env, *dest + len);
1061     } else {
1062         access_prepare(&desta, env, *dest, len, MMU_DATA_STORE, mmu_idx, ra);
1063 
1064         /* The remaining length selects the padding byte. */
1065         for (i = 0; i < len; (*destlen)--, i++) {
1066             if (*destlen & 1) {
1067                 access_set_byte(env, &desta, i, pad, ra);
1068             } else {
1069                 access_set_byte(env, &desta, i, pad >> 8, ra);
1070             }
1071         }
1072         *dest = wrap_address(env, *dest + len);
1073     }
1074 
1075     return *destlen ? 3 : cc;
1076 }
1077 
1078 /* move long */
1079 uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2)
1080 {
1081     const int mmu_idx = cpu_mmu_index(env, false);
1082     uintptr_t ra = GETPC();
1083     uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
1084     uint64_t dest = get_address(env, r1);
1085     uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
1086     uint64_t src = get_address(env, r2);
1087     uint8_t pad = env->regs[r2 + 1] >> 24;
1088     CPUState *cs = env_cpu(env);
1089     S390Access srca, desta;
1090     uint32_t cc, cur_len;
1091 
1092     if (is_destructive_overlap(env, dest, src, MIN(srclen, destlen))) {
1093         cc = 3;
1094     } else if (srclen == destlen) {
1095         cc = 0;
1096     } else if (destlen < srclen) {
1097         cc = 1;
1098     } else {
1099         cc = 2;
1100     }
1101 
1102     /* We might have to zero-out some bits even if there was no action. */
1103     if (unlikely(!destlen || cc == 3)) {
1104         set_address_zero(env, r2, src);
1105         set_address_zero(env, r1, dest);
1106         return cc;
1107     } else if (!srclen) {
1108         set_address_zero(env, r2, src);
1109     }
1110 
1111     /*
1112      * Only perform one type of type of operation (move/pad) in one step.
1113      * Stay within single pages.
1114      */
1115     while (destlen) {
1116         cur_len = MIN(destlen, -(dest | TARGET_PAGE_MASK));
1117         if (!srclen) {
1118             access_prepare(&desta, env, dest, cur_len,
1119                            MMU_DATA_STORE, mmu_idx, ra);
1120             access_memset(env, &desta, pad, ra);
1121         } else {
1122             cur_len = MIN(MIN(srclen, -(src | TARGET_PAGE_MASK)), cur_len);
1123 
1124             access_prepare(&srca, env, src, cur_len,
1125                            MMU_DATA_LOAD, mmu_idx, ra);
1126             access_prepare(&desta, env, dest, cur_len,
1127                            MMU_DATA_STORE, mmu_idx, ra);
1128             access_memmove(env, &desta, &srca, ra);
1129             src = wrap_address(env, src + cur_len);
1130             srclen -= cur_len;
1131             env->regs[r2 + 1] = deposit64(env->regs[r2 + 1], 0, 24, srclen);
1132             set_address_zero(env, r2, src);
1133         }
1134         dest = wrap_address(env, dest + cur_len);
1135         destlen -= cur_len;
1136         env->regs[r1 + 1] = deposit64(env->regs[r1 + 1], 0, 24, destlen);
1137         set_address_zero(env, r1, dest);
1138 
1139         /*
1140          * MVCL is interruptible. Return to the main loop if requested after
1141          * writing back all state to registers. If no interrupt will get
1142          * injected, we'll end up back in this handler and continue processing
1143          * the remaining parts.
1144          */
1145         if (destlen && unlikely(cpu_loop_exit_requested(cs))) {
1146             cpu_loop_exit_restore(cs, ra);
1147         }
1148     }
1149     return cc;
1150 }
1151 
1152 /* move long extended */
1153 uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
1154                        uint32_t r3)
1155 {
1156     uintptr_t ra = GETPC();
1157     uint64_t destlen = get_length(env, r1 + 1);
1158     uint64_t dest = get_address(env, r1);
1159     uint64_t srclen = get_length(env, r3 + 1);
1160     uint64_t src = get_address(env, r3);
1161     uint8_t pad = a2;
1162     uint32_t cc;
1163 
1164     cc = do_mvcl(env, &dest, &destlen, &src, &srclen, pad, 1, ra);
1165 
1166     set_length(env, r1 + 1, destlen);
1167     set_length(env, r3 + 1, srclen);
1168     set_address(env, r1, dest);
1169     set_address(env, r3, src);
1170 
1171     return cc;
1172 }
1173 
1174 /* move long unicode */
1175 uint32_t HELPER(mvclu)(CPUS390XState *env, uint32_t r1, uint64_t a2,
1176                        uint32_t r3)
1177 {
1178     uintptr_t ra = GETPC();
1179     uint64_t destlen = get_length(env, r1 + 1);
1180     uint64_t dest = get_address(env, r1);
1181     uint64_t srclen = get_length(env, r3 + 1);
1182     uint64_t src = get_address(env, r3);
1183     uint16_t pad = a2;
1184     uint32_t cc;
1185 
1186     cc = do_mvcl(env, &dest, &destlen, &src, &srclen, pad, 2, ra);
1187 
1188     set_length(env, r1 + 1, destlen);
1189     set_length(env, r3 + 1, srclen);
1190     set_address(env, r1, dest);
1191     set_address(env, r3, src);
1192 
1193     return cc;
1194 }
1195 
1196 /* compare logical long helper */
1197 static inline uint32_t do_clcl(CPUS390XState *env,
1198                                uint64_t *src1, uint64_t *src1len,
1199                                uint64_t *src3, uint64_t *src3len,
1200                                uint16_t pad, uint64_t limit,
1201                                int wordsize, uintptr_t ra)
1202 {
1203     uint64_t len = MAX(*src1len, *src3len);
1204     uint32_t cc = 0;
1205 
1206     check_alignment(env, *src1len | *src3len, wordsize, ra);
1207 
1208     if (!len) {
1209         return cc;
1210     }
1211 
1212     /* Lest we fail to service interrupts in a timely manner, limit the
1213        amount of work we're willing to do.  */
1214     if (len > limit) {
1215         len = limit;
1216         cc = 3;
1217     }
1218 
1219     for (; len; len -= wordsize) {
1220         uint16_t v1 = pad;
1221         uint16_t v3 = pad;
1222 
1223         if (*src1len) {
1224             v1 = cpu_ldusize_data_ra(env, *src1, wordsize, ra);
1225         }
1226         if (*src3len) {
1227             v3 = cpu_ldusize_data_ra(env, *src3, wordsize, ra);
1228         }
1229 
1230         if (v1 != v3) {
1231             cc = (v1 < v3) ? 1 : 2;
1232             break;
1233         }
1234 
1235         if (*src1len) {
1236             *src1 += wordsize;
1237             *src1len -= wordsize;
1238         }
1239         if (*src3len) {
1240             *src3 += wordsize;
1241             *src3len -= wordsize;
1242         }
1243     }
1244 
1245     return cc;
1246 }
1247 
1248 
1249 /* compare logical long */
1250 uint32_t HELPER(clcl)(CPUS390XState *env, uint32_t r1, uint32_t r2)
1251 {
1252     uintptr_t ra = GETPC();
1253     uint64_t src1len = extract64(env->regs[r1 + 1], 0, 24);
1254     uint64_t src1 = get_address(env, r1);
1255     uint64_t src3len = extract64(env->regs[r2 + 1], 0, 24);
1256     uint64_t src3 = get_address(env, r2);
1257     uint8_t pad = env->regs[r2 + 1] >> 24;
1258     uint32_t cc;
1259 
1260     cc = do_clcl(env, &src1, &src1len, &src3, &src3len, pad, -1, 1, ra);
1261 
1262     env->regs[r1 + 1] = deposit64(env->regs[r1 + 1], 0, 24, src1len);
1263     env->regs[r2 + 1] = deposit64(env->regs[r2 + 1], 0, 24, src3len);
1264     set_address(env, r1, src1);
1265     set_address(env, r2, src3);
1266 
1267     return cc;
1268 }
1269 
1270 /* compare logical long extended memcompare insn with padding */
1271 uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
1272                        uint32_t r3)
1273 {
1274     uintptr_t ra = GETPC();
1275     uint64_t src1len = get_length(env, r1 + 1);
1276     uint64_t src1 = get_address(env, r1);
1277     uint64_t src3len = get_length(env, r3 + 1);
1278     uint64_t src3 = get_address(env, r3);
1279     uint8_t pad = a2;
1280     uint32_t cc;
1281 
1282     cc = do_clcl(env, &src1, &src1len, &src3, &src3len, pad, 0x2000, 1, ra);
1283 
1284     set_length(env, r1 + 1, src1len);
1285     set_length(env, r3 + 1, src3len);
1286     set_address(env, r1, src1);
1287     set_address(env, r3, src3);
1288 
1289     return cc;
1290 }
1291 
1292 /* compare logical long unicode memcompare insn with padding */
1293 uint32_t HELPER(clclu)(CPUS390XState *env, uint32_t r1, uint64_t a2,
1294                        uint32_t r3)
1295 {
1296     uintptr_t ra = GETPC();
1297     uint64_t src1len = get_length(env, r1 + 1);
1298     uint64_t src1 = get_address(env, r1);
1299     uint64_t src3len = get_length(env, r3 + 1);
1300     uint64_t src3 = get_address(env, r3);
1301     uint16_t pad = a2;
1302     uint32_t cc = 0;
1303 
1304     cc = do_clcl(env, &src1, &src1len, &src3, &src3len, pad, 0x1000, 2, ra);
1305 
1306     set_length(env, r1 + 1, src1len);
1307     set_length(env, r3 + 1, src3len);
1308     set_address(env, r1, src1);
1309     set_address(env, r3, src3);
1310 
1311     return cc;
1312 }
1313 
1314 /* checksum */
1315 Int128 HELPER(cksm)(CPUS390XState *env, uint64_t r1,
1316                     uint64_t src, uint64_t src_len)
1317 {
1318     uintptr_t ra = GETPC();
1319     uint64_t max_len, len;
1320     uint64_t cksm = (uint32_t)r1;
1321 
1322     /* Lest we fail to service interrupts in a timely manner, limit the
1323        amount of work we're willing to do.  For now, let's cap at 8k.  */
1324     max_len = (src_len > 0x2000 ? 0x2000 : src_len);
1325 
1326     /* Process full words as available.  */
1327     for (len = 0; len + 4 <= max_len; len += 4, src += 4) {
1328         cksm += (uint32_t)cpu_ldl_data_ra(env, src, ra);
1329     }
1330 
1331     switch (max_len - len) {
1332     case 1:
1333         cksm += cpu_ldub_data_ra(env, src, ra) << 24;
1334         len += 1;
1335         break;
1336     case 2:
1337         cksm += cpu_lduw_data_ra(env, src, ra) << 16;
1338         len += 2;
1339         break;
1340     case 3:
1341         cksm += cpu_lduw_data_ra(env, src, ra) << 16;
1342         cksm += cpu_ldub_data_ra(env, src + 2, ra) << 8;
1343         len += 3;
1344         break;
1345     }
1346 
1347     /* Fold the carry from the checksum.  Note that we can see carry-out
1348        during folding more than once (but probably not more than twice).  */
1349     while (cksm > 0xffffffffull) {
1350         cksm = (uint32_t)cksm + (cksm >> 32);
1351     }
1352 
1353     /* Indicate whether or not we've processed everything.  */
1354     env->cc_op = (len == src_len ? 0 : 3);
1355 
1356     /* Return both cksm and processed length.  */
1357     return int128_make128(cksm, len);
1358 }
1359 
1360 void HELPER(pack)(CPUS390XState *env, uint32_t len, uint64_t dest, uint64_t src)
1361 {
1362     uintptr_t ra = GETPC();
1363     int len_dest = len >> 4;
1364     int len_src = len & 0xf;
1365     uint8_t b;
1366 
1367     dest += len_dest;
1368     src += len_src;
1369 
1370     /* last byte is special, it only flips the nibbles */
1371     b = cpu_ldub_data_ra(env, src, ra);
1372     cpu_stb_data_ra(env, dest, (b << 4) | (b >> 4), ra);
1373     src--;
1374     len_src--;
1375 
1376     /* now pack every value */
1377     while (len_dest > 0) {
1378         b = 0;
1379 
1380         if (len_src >= 0) {
1381             b = cpu_ldub_data_ra(env, src, ra) & 0x0f;
1382             src--;
1383             len_src--;
1384         }
1385         if (len_src >= 0) {
1386             b |= cpu_ldub_data_ra(env, src, ra) << 4;
1387             src--;
1388             len_src--;
1389         }
1390 
1391         len_dest--;
1392         dest--;
1393         cpu_stb_data_ra(env, dest, b, ra);
1394     }
1395 }
1396 
1397 static inline void do_pkau(CPUS390XState *env, uint64_t dest, uint64_t src,
1398                            uint32_t srclen, int ssize, uintptr_t ra)
1399 {
1400     int i;
1401     /* The destination operand is always 16 bytes long.  */
1402     const int destlen = 16;
1403 
1404     /* The operands are processed from right to left.  */
1405     src += srclen - 1;
1406     dest += destlen - 1;
1407 
1408     for (i = 0; i < destlen; i++) {
1409         uint8_t b = 0;
1410 
1411         /* Start with a positive sign */
1412         if (i == 0) {
1413             b = 0xc;
1414         } else if (srclen > ssize) {
1415             b = cpu_ldub_data_ra(env, src, ra) & 0x0f;
1416             src -= ssize;
1417             srclen -= ssize;
1418         }
1419 
1420         if (srclen > ssize) {
1421             b |= cpu_ldub_data_ra(env, src, ra) << 4;
1422             src -= ssize;
1423             srclen -= ssize;
1424         }
1425 
1426         cpu_stb_data_ra(env, dest, b, ra);
1427         dest--;
1428     }
1429 }
1430 
1431 
1432 void HELPER(pka)(CPUS390XState *env, uint64_t dest, uint64_t src,
1433                  uint32_t srclen)
1434 {
1435     do_pkau(env, dest, src, srclen, 1, GETPC());
1436 }
1437 
1438 void HELPER(pku)(CPUS390XState *env, uint64_t dest, uint64_t src,
1439                  uint32_t srclen)
1440 {
1441     do_pkau(env, dest, src, srclen, 2, GETPC());
1442 }
1443 
1444 void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest,
1445                   uint64_t src)
1446 {
1447     uintptr_t ra = GETPC();
1448     int len_dest = len >> 4;
1449     int len_src = len & 0xf;
1450     uint8_t b;
1451     int second_nibble = 0;
1452 
1453     dest += len_dest;
1454     src += len_src;
1455 
1456     /* last byte is special, it only flips the nibbles */
1457     b = cpu_ldub_data_ra(env, src, ra);
1458     cpu_stb_data_ra(env, dest, (b << 4) | (b >> 4), ra);
1459     src--;
1460     len_src--;
1461 
1462     /* now pad every nibble with 0xf0 */
1463 
1464     while (len_dest > 0) {
1465         uint8_t cur_byte = 0;
1466 
1467         if (len_src > 0) {
1468             cur_byte = cpu_ldub_data_ra(env, src, ra);
1469         }
1470 
1471         len_dest--;
1472         dest--;
1473 
1474         /* only advance one nibble at a time */
1475         if (second_nibble) {
1476             cur_byte >>= 4;
1477             len_src--;
1478             src--;
1479         }
1480         second_nibble = !second_nibble;
1481 
1482         /* digit */
1483         cur_byte = (cur_byte & 0xf);
1484         /* zone bits */
1485         cur_byte |= 0xf0;
1486 
1487         cpu_stb_data_ra(env, dest, cur_byte, ra);
1488     }
1489 }
1490 
1491 static inline uint32_t do_unpkau(CPUS390XState *env, uint64_t dest,
1492                                  uint32_t destlen, int dsize, uint64_t src,
1493                                  uintptr_t ra)
1494 {
1495     int i;
1496     uint32_t cc;
1497     uint8_t b;
1498     /* The source operand is always 16 bytes long.  */
1499     const int srclen = 16;
1500 
1501     /* The operands are processed from right to left.  */
1502     src += srclen - 1;
1503     dest += destlen - dsize;
1504 
1505     /* Check for the sign.  */
1506     b = cpu_ldub_data_ra(env, src, ra);
1507     src--;
1508     switch (b & 0xf) {
1509     case 0xa:
1510     case 0xc:
1511     case 0xe ... 0xf:
1512         cc = 0;  /* plus */
1513         break;
1514     case 0xb:
1515     case 0xd:
1516         cc = 1;  /* minus */
1517         break;
1518     default:
1519     case 0x0 ... 0x9:
1520         cc = 3;  /* invalid */
1521         break;
1522     }
1523 
1524     /* Now pad every nibble with 0x30, advancing one nibble at a time. */
1525     for (i = 0; i < destlen; i += dsize) {
1526         if (i == (31 * dsize)) {
1527             /* If length is 32/64 bytes, the leftmost byte is 0. */
1528             b = 0;
1529         } else if (i % (2 * dsize)) {
1530             b = cpu_ldub_data_ra(env, src, ra);
1531             src--;
1532         } else {
1533             b >>= 4;
1534         }
1535         cpu_stsize_data_ra(env, dest, 0x30 + (b & 0xf), dsize, ra);
1536         dest -= dsize;
1537     }
1538 
1539     return cc;
1540 }
1541 
1542 uint32_t HELPER(unpka)(CPUS390XState *env, uint64_t dest, uint32_t destlen,
1543                        uint64_t src)
1544 {
1545     return do_unpkau(env, dest, destlen, 1, src, GETPC());
1546 }
1547 
1548 uint32_t HELPER(unpku)(CPUS390XState *env, uint64_t dest, uint32_t destlen,
1549                        uint64_t src)
1550 {
1551     return do_unpkau(env, dest, destlen, 2, src, GETPC());
1552 }
1553 
1554 uint32_t HELPER(tp)(CPUS390XState *env, uint64_t dest, uint32_t destlen)
1555 {
1556     uintptr_t ra = GETPC();
1557     uint32_t cc = 0;
1558     int i;
1559 
1560     for (i = 0; i < destlen; i++) {
1561         uint8_t b = cpu_ldub_data_ra(env, dest + i, ra);
1562         /* digit */
1563         cc |= (b & 0xf0) > 0x90 ? 2 : 0;
1564 
1565         if (i == (destlen - 1)) {
1566             /* sign */
1567             cc |= (b & 0xf) < 0xa ? 1 : 0;
1568         } else {
1569             /* digit */
1570             cc |= (b & 0xf) > 0x9 ? 2 : 0;
1571         }
1572     }
1573 
1574     return cc;
1575 }
1576 
1577 static uint32_t do_helper_tr(CPUS390XState *env, uint32_t len, uint64_t array,
1578                              uint64_t trans, uintptr_t ra)
1579 {
1580     uint32_t i;
1581 
1582     for (i = 0; i <= len; i++) {
1583         uint8_t byte = cpu_ldub_data_ra(env, array + i, ra);
1584         uint8_t new_byte = cpu_ldub_data_ra(env, trans + byte, ra);
1585         cpu_stb_data_ra(env, array + i, new_byte, ra);
1586     }
1587 
1588     return env->cc_op;
1589 }
1590 
1591 void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array,
1592                 uint64_t trans)
1593 {
1594     do_helper_tr(env, len, array, trans, GETPC());
1595 }
1596 
1597 Int128 HELPER(tre)(CPUS390XState *env, uint64_t array,
1598                    uint64_t len, uint64_t trans)
1599 {
1600     uintptr_t ra = GETPC();
1601     uint8_t end = env->regs[0] & 0xff;
1602     uint64_t l = len;
1603     uint64_t i;
1604     uint32_t cc = 0;
1605 
1606     if (!(env->psw.mask & PSW_MASK_64)) {
1607         array &= 0x7fffffff;
1608         l = (uint32_t)l;
1609     }
1610 
1611     /* Lest we fail to service interrupts in a timely manner, limit the
1612        amount of work we're willing to do.  For now, let's cap at 8k.  */
1613     if (l > 0x2000) {
1614         l = 0x2000;
1615         cc = 3;
1616     }
1617 
1618     for (i = 0; i < l; i++) {
1619         uint8_t byte, new_byte;
1620 
1621         byte = cpu_ldub_data_ra(env, array + i, ra);
1622 
1623         if (byte == end) {
1624             cc = 1;
1625             break;
1626         }
1627 
1628         new_byte = cpu_ldub_data_ra(env, trans + byte, ra);
1629         cpu_stb_data_ra(env, array + i, new_byte, ra);
1630     }
1631 
1632     env->cc_op = cc;
1633     return int128_make128(len - i, array + i);
1634 }
1635 
1636 static inline uint32_t do_helper_trt(CPUS390XState *env, int len,
1637                                      uint64_t array, uint64_t trans,
1638                                      int inc, uintptr_t ra)
1639 {
1640     int i;
1641 
1642     for (i = 0; i <= len; i++) {
1643         uint8_t byte = cpu_ldub_data_ra(env, array + i * inc, ra);
1644         uint8_t sbyte = cpu_ldub_data_ra(env, trans + byte, ra);
1645 
1646         if (sbyte != 0) {
1647             set_address(env, 1, array + i * inc);
1648             env->regs[2] = deposit64(env->regs[2], 0, 8, sbyte);
1649             return (i == len) ? 2 : 1;
1650         }
1651     }
1652 
1653     return 0;
1654 }
1655 
1656 static uint32_t do_helper_trt_fwd(CPUS390XState *env, uint32_t len,
1657                                   uint64_t array, uint64_t trans,
1658                                   uintptr_t ra)
1659 {
1660     return do_helper_trt(env, len, array, trans, 1, ra);
1661 }
1662 
1663 uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array,
1664                      uint64_t trans)
1665 {
1666     return do_helper_trt(env, len, array, trans, 1, GETPC());
1667 }
1668 
1669 static uint32_t do_helper_trt_bkwd(CPUS390XState *env, uint32_t len,
1670                                    uint64_t array, uint64_t trans,
1671                                    uintptr_t ra)
1672 {
1673     return do_helper_trt(env, len, array, trans, -1, ra);
1674 }
1675 
1676 uint32_t HELPER(trtr)(CPUS390XState *env, uint32_t len, uint64_t array,
1677                       uint64_t trans)
1678 {
1679     return do_helper_trt(env, len, array, trans, -1, GETPC());
1680 }
1681 
1682 /* Translate one/two to one/two */
1683 uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, uint32_t r2,
1684                       uint32_t tst, uint32_t sizes)
1685 {
1686     uintptr_t ra = GETPC();
1687     int dsize = (sizes & 1) ? 1 : 2;
1688     int ssize = (sizes & 2) ? 1 : 2;
1689     uint64_t tbl = get_address(env, 1);
1690     uint64_t dst = get_address(env, r1);
1691     uint64_t len = get_length(env, r1 + 1);
1692     uint64_t src = get_address(env, r2);
1693     uint32_t cc = 3;
1694     int i;
1695 
1696     /* The lower address bits of TBL are ignored.  For TROO, TROT, it's
1697        the low 3 bits (double-word aligned).  For TRTO, TRTT, it's either
1698        the low 12 bits (4K, without ETF2-ENH) or 3 bits (with ETF2-ENH).  */
1699     if (ssize == 2 && !s390_has_feat(S390_FEAT_ETF2_ENH)) {
1700         tbl &= -4096;
1701     } else {
1702         tbl &= -8;
1703     }
1704 
1705     check_alignment(env, len, ssize, ra);
1706 
1707     /* Lest we fail to service interrupts in a timely manner, */
1708     /* limit the amount of work we're willing to do.   */
1709     for (i = 0; i < 0x2000; i++) {
1710         uint16_t sval = cpu_ldusize_data_ra(env, src, ssize, ra);
1711         uint64_t tble = tbl + (sval * dsize);
1712         uint16_t dval = cpu_ldusize_data_ra(env, tble, dsize, ra);
1713         if (dval == tst) {
1714             cc = 1;
1715             break;
1716         }
1717         cpu_stsize_data_ra(env, dst, dval, dsize, ra);
1718 
1719         len -= ssize;
1720         src += ssize;
1721         dst += dsize;
1722 
1723         if (len == 0) {
1724             cc = 0;
1725             break;
1726         }
1727     }
1728 
1729     set_address(env, r1, dst);
1730     set_length(env, r1 + 1, len);
1731     set_address(env, r2, src);
1732 
1733     return cc;
1734 }
1735 
1736 static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
1737                         uint64_t a2, bool parallel)
1738 {
1739     uint32_t mem_idx = cpu_mmu_index(env, false);
1740     uintptr_t ra = GETPC();
1741     uint32_t fc = extract32(env->regs[0], 0, 8);
1742     uint32_t sc = extract32(env->regs[0], 8, 8);
1743     uint64_t pl = get_address(env, 1) & -16;
1744     uint64_t svh, svl;
1745     uint32_t cc;
1746 
1747     /* Sanity check the function code and storage characteristic.  */
1748     if (fc > 1 || sc > 3) {
1749         if (!s390_has_feat(S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2)) {
1750             goto spec_exception;
1751         }
1752         if (fc > 2 || sc > 4 || (fc == 2 && (r3 & 1))) {
1753             goto spec_exception;
1754         }
1755     }
1756 
1757     /* Sanity check the alignments.  */
1758     if (extract32(a1, 0, fc + 2) || extract32(a2, 0, sc)) {
1759         goto spec_exception;
1760     }
1761 
1762     /* Sanity check writability of the store address.  */
1763     probe_write(env, a2, 1 << sc, mem_idx, ra);
1764 
1765     /*
1766      * Note that the compare-and-swap is atomic, and the store is atomic,
1767      * but the complete operation is not.  Therefore we do not need to
1768      * assert serial context in order to implement this.  That said,
1769      * restart early if we can't support either operation that is supposed
1770      * to be atomic.
1771      */
1772     if (parallel) {
1773         uint32_t max = 2;
1774 #ifdef CONFIG_ATOMIC64
1775         max = 3;
1776 #endif
1777         if ((HAVE_CMPXCHG128 ? 0 : fc + 2 > max) ||
1778             (HAVE_ATOMIC128  ? 0 : sc > max)) {
1779             cpu_loop_exit_atomic(env_cpu(env), ra);
1780         }
1781     }
1782 
1783     /* All loads happen before all stores.  For simplicity, load the entire
1784        store value area from the parameter list.  */
1785     svh = cpu_ldq_data_ra(env, pl + 16, ra);
1786     svl = cpu_ldq_data_ra(env, pl + 24, ra);
1787 
1788     switch (fc) {
1789     case 0:
1790         {
1791             uint32_t nv = cpu_ldl_data_ra(env, pl, ra);
1792             uint32_t cv = env->regs[r3];
1793             uint32_t ov;
1794 
1795             if (parallel) {
1796 #ifdef CONFIG_USER_ONLY
1797                 uint32_t *haddr = g2h(env_cpu(env), a1);
1798                 ov = qatomic_cmpxchg__nocheck(haddr, cv, nv);
1799 #else
1800                 MemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mem_idx);
1801                 ov = cpu_atomic_cmpxchgl_be_mmu(env, a1, cv, nv, oi, ra);
1802 #endif
1803             } else {
1804                 ov = cpu_ldl_data_ra(env, a1, ra);
1805                 cpu_stl_data_ra(env, a1, (ov == cv ? nv : ov), ra);
1806             }
1807             cc = (ov != cv);
1808             env->regs[r3] = deposit64(env->regs[r3], 32, 32, ov);
1809         }
1810         break;
1811 
1812     case 1:
1813         {
1814             uint64_t nv = cpu_ldq_data_ra(env, pl, ra);
1815             uint64_t cv = env->regs[r3];
1816             uint64_t ov;
1817 
1818             if (parallel) {
1819 #ifdef CONFIG_ATOMIC64
1820                 MemOpIdx oi = make_memop_idx(MO_TEUQ | MO_ALIGN, mem_idx);
1821                 ov = cpu_atomic_cmpxchgq_be_mmu(env, a1, cv, nv, oi, ra);
1822 #else
1823                 /* Note that we asserted !parallel above.  */
1824                 g_assert_not_reached();
1825 #endif
1826             } else {
1827                 ov = cpu_ldq_data_ra(env, a1, ra);
1828                 cpu_stq_data_ra(env, a1, (ov == cv ? nv : ov), ra);
1829             }
1830             cc = (ov != cv);
1831             env->regs[r3] = ov;
1832         }
1833         break;
1834 
1835     case 2:
1836         {
1837             uint64_t nvh = cpu_ldq_data_ra(env, pl, ra);
1838             uint64_t nvl = cpu_ldq_data_ra(env, pl + 8, ra);
1839             Int128 nv = int128_make128(nvl, nvh);
1840             Int128 cv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
1841             Int128 ov;
1842 
1843             if (!parallel) {
1844                 uint64_t oh = cpu_ldq_data_ra(env, a1 + 0, ra);
1845                 uint64_t ol = cpu_ldq_data_ra(env, a1 + 8, ra);
1846 
1847                 ov = int128_make128(ol, oh);
1848                 cc = !int128_eq(ov, cv);
1849                 if (cc) {
1850                     nv = ov;
1851                 }
1852 
1853                 cpu_stq_data_ra(env, a1 + 0, int128_gethi(nv), ra);
1854                 cpu_stq_data_ra(env, a1 + 8, int128_getlo(nv), ra);
1855             } else if (HAVE_CMPXCHG128) {
1856                 MemOpIdx oi = make_memop_idx(MO_TE | MO_128 | MO_ALIGN, mem_idx);
1857                 ov = cpu_atomic_cmpxchgo_be_mmu(env, a1, cv, nv, oi, ra);
1858                 cc = !int128_eq(ov, cv);
1859             } else {
1860                 /* Note that we asserted !parallel above.  */
1861                 g_assert_not_reached();
1862             }
1863 
1864             env->regs[r3 + 0] = int128_gethi(ov);
1865             env->regs[r3 + 1] = int128_getlo(ov);
1866         }
1867         break;
1868 
1869     default:
1870         g_assert_not_reached();
1871     }
1872 
1873     /* Store only if the comparison succeeded.  Note that above we use a pair
1874        of 64-bit big-endian loads, so for sc < 3 we must extract the value
1875        from the most-significant bits of svh.  */
1876     if (cc == 0) {
1877         switch (sc) {
1878         case 0:
1879             cpu_stb_data_ra(env, a2, svh >> 56, ra);
1880             break;
1881         case 1:
1882             cpu_stw_data_ra(env, a2, svh >> 48, ra);
1883             break;
1884         case 2:
1885             cpu_stl_data_ra(env, a2, svh >> 32, ra);
1886             break;
1887         case 3:
1888             cpu_stq_data_ra(env, a2, svh, ra);
1889             break;
1890         case 4:
1891             if (!parallel) {
1892                 cpu_stq_data_ra(env, a2 + 0, svh, ra);
1893                 cpu_stq_data_ra(env, a2 + 8, svl, ra);
1894             } else if (HAVE_ATOMIC128) {
1895                 MemOpIdx oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx);
1896                 Int128 sv = int128_make128(svl, svh);
1897                 cpu_atomic_sto_be_mmu(env, a2, sv, oi, ra);
1898             } else {
1899                 /* Note that we asserted !parallel above.  */
1900                 g_assert_not_reached();
1901             }
1902             break;
1903         default:
1904             g_assert_not_reached();
1905         }
1906     }
1907 
1908     return cc;
1909 
1910  spec_exception:
1911     tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1912 }
1913 
1914 uint32_t HELPER(csst)(CPUS390XState *env, uint32_t r3, uint64_t a1, uint64_t a2)
1915 {
1916     return do_csst(env, r3, a1, a2, false);
1917 }
1918 
1919 uint32_t HELPER(csst_parallel)(CPUS390XState *env, uint32_t r3, uint64_t a1,
1920                                uint64_t a2)
1921 {
1922     return do_csst(env, r3, a1, a2, true);
1923 }
1924 
1925 #if !defined(CONFIG_USER_ONLY)
1926 void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
1927 {
1928     uintptr_t ra = GETPC();
1929     bool PERchanged = false;
1930     uint64_t src = a2;
1931     uint32_t i;
1932 
1933     if (src & 0x7) {
1934         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1935     }
1936 
1937     for (i = r1;; i = (i + 1) % 16) {
1938         uint64_t val = cpu_ldq_data_ra(env, src, ra);
1939         if (env->cregs[i] != val && i >= 9 && i <= 11) {
1940             PERchanged = true;
1941         }
1942         env->cregs[i] = val;
1943         HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
1944                    i, src, val);
1945         src += sizeof(uint64_t);
1946 
1947         if (i == r3) {
1948             break;
1949         }
1950     }
1951 
1952     if (PERchanged && env->psw.mask & PSW_MASK_PER) {
1953         s390_cpu_recompute_watchpoints(env_cpu(env));
1954     }
1955 
1956     tlb_flush(env_cpu(env));
1957 }
1958 
1959 void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
1960 {
1961     uintptr_t ra = GETPC();
1962     bool PERchanged = false;
1963     uint64_t src = a2;
1964     uint32_t i;
1965 
1966     if (src & 0x3) {
1967         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1968     }
1969 
1970     for (i = r1;; i = (i + 1) % 16) {
1971         uint32_t val = cpu_ldl_data_ra(env, src, ra);
1972         if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) {
1973             PERchanged = true;
1974         }
1975         env->cregs[i] = deposit64(env->cregs[i], 0, 32, val);
1976         HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%x\n", i, src, val);
1977         src += sizeof(uint32_t);
1978 
1979         if (i == r3) {
1980             break;
1981         }
1982     }
1983 
1984     if (PERchanged && env->psw.mask & PSW_MASK_PER) {
1985         s390_cpu_recompute_watchpoints(env_cpu(env));
1986     }
1987 
1988     tlb_flush(env_cpu(env));
1989 }
1990 
1991 void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
1992 {
1993     uintptr_t ra = GETPC();
1994     uint64_t dest = a2;
1995     uint32_t i;
1996 
1997     if (dest & 0x7) {
1998         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1999     }
2000 
2001     for (i = r1;; i = (i + 1) % 16) {
2002         cpu_stq_data_ra(env, dest, env->cregs[i], ra);
2003         dest += sizeof(uint64_t);
2004 
2005         if (i == r3) {
2006             break;
2007         }
2008     }
2009 }
2010 
2011 void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
2012 {
2013     uintptr_t ra = GETPC();
2014     uint64_t dest = a2;
2015     uint32_t i;
2016 
2017     if (dest & 0x3) {
2018         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
2019     }
2020 
2021     for (i = r1;; i = (i + 1) % 16) {
2022         cpu_stl_data_ra(env, dest, env->cregs[i], ra);
2023         dest += sizeof(uint32_t);
2024 
2025         if (i == r3) {
2026             break;
2027         }
2028     }
2029 }
2030 
2031 uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr)
2032 {
2033     uintptr_t ra = GETPC();
2034     int i;
2035 
2036     real_addr = wrap_address(env, real_addr) & TARGET_PAGE_MASK;
2037 
2038     for (i = 0; i < TARGET_PAGE_SIZE; i += 8) {
2039         cpu_stq_mmuidx_ra(env, real_addr + i, 0, MMU_REAL_IDX, ra);
2040     }
2041 
2042     return 0;
2043 }
2044 
2045 uint32_t HELPER(tprot)(CPUS390XState *env, uint64_t a1, uint64_t a2)
2046 {
2047     S390CPU *cpu = env_archcpu(env);
2048     CPUState *cs = env_cpu(env);
2049 
2050     /*
2051      * TODO: we currently don't handle all access protection types
2052      * (including access-list and key-controlled) as well as AR mode.
2053      */
2054     if (!s390_cpu_virt_mem_check_write(cpu, a1, 0, 1)) {
2055         /* Fetching permitted; storing permitted */
2056         return 0;
2057     }
2058 
2059     if (env->int_pgm_code == PGM_PROTECTION) {
2060         /* retry if reading is possible */
2061         cs->exception_index = -1;
2062         if (!s390_cpu_virt_mem_check_read(cpu, a1, 0, 1)) {
2063             /* Fetching permitted; storing not permitted */
2064             return 1;
2065         }
2066     }
2067 
2068     switch (env->int_pgm_code) {
2069     case PGM_PROTECTION:
2070         /* Fetching not permitted; storing not permitted */
2071         cs->exception_index = -1;
2072         return 2;
2073     case PGM_ADDRESSING:
2074     case PGM_TRANS_SPEC:
2075         /* exceptions forwarded to the guest */
2076         s390_cpu_virt_mem_handle_exc(cpu, GETPC());
2077         return 0;
2078     }
2079 
2080     /* Translation not available */
2081     cs->exception_index = -1;
2082     return 3;
2083 }
2084 
2085 /* insert storage key extended */
2086 uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
2087 {
2088     static S390SKeysState *ss;
2089     static S390SKeysClass *skeyclass;
2090     uint64_t addr = wrap_address(env, r2);
2091     uint8_t key;
2092     int rc;
2093 
2094     addr = mmu_real2abs(env, addr);
2095     if (!mmu_absolute_addr_valid(addr, false)) {
2096         tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
2097     }
2098 
2099     if (unlikely(!ss)) {
2100         ss = s390_get_skeys_device();
2101         skeyclass = S390_SKEYS_GET_CLASS(ss);
2102         if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
2103             tlb_flush_all_cpus_synced(env_cpu(env));
2104         }
2105     }
2106 
2107     rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
2108     if (rc) {
2109         trace_get_skeys_nonzero(rc);
2110         return 0;
2111     }
2112     return key;
2113 }
2114 
2115 /* set storage key extended */
2116 void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
2117 {
2118     static S390SKeysState *ss;
2119     static S390SKeysClass *skeyclass;
2120     uint64_t addr = wrap_address(env, r2);
2121     uint8_t key;
2122     int rc;
2123 
2124     addr = mmu_real2abs(env, addr);
2125     if (!mmu_absolute_addr_valid(addr, false)) {
2126         tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
2127     }
2128 
2129     if (unlikely(!ss)) {
2130         ss = s390_get_skeys_device();
2131         skeyclass = S390_SKEYS_GET_CLASS(ss);
2132         if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
2133             tlb_flush_all_cpus_synced(env_cpu(env));
2134         }
2135     }
2136 
2137     key = r1 & 0xfe;
2138     rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
2139     if (rc) {
2140         trace_set_skeys_nonzero(rc);
2141     }
2142    /*
2143     * As we can only flush by virtual address and not all the entries
2144     * that point to a physical address we have to flush the whole TLB.
2145     */
2146     tlb_flush_all_cpus_synced(env_cpu(env));
2147 }
2148 
2149 /* reset reference bit extended */
2150 uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
2151 {
2152     uint64_t addr = wrap_address(env, r2);
2153     static S390SKeysState *ss;
2154     static S390SKeysClass *skeyclass;
2155     uint8_t re, key;
2156     int rc;
2157 
2158     addr = mmu_real2abs(env, addr);
2159     if (!mmu_absolute_addr_valid(addr, false)) {
2160         tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
2161     }
2162 
2163     if (unlikely(!ss)) {
2164         ss = s390_get_skeys_device();
2165         skeyclass = S390_SKEYS_GET_CLASS(ss);
2166         if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
2167             tlb_flush_all_cpus_synced(env_cpu(env));
2168         }
2169     }
2170 
2171     rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
2172     if (rc) {
2173         trace_get_skeys_nonzero(rc);
2174         return 0;
2175     }
2176 
2177     re = key & (SK_R | SK_C);
2178     key &= ~SK_R;
2179 
2180     rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
2181     if (rc) {
2182         trace_set_skeys_nonzero(rc);
2183         return 0;
2184     }
2185    /*
2186     * As we can only flush by virtual address and not all the entries
2187     * that point to a physical address we have to flush the whole TLB.
2188     */
2189     tlb_flush_all_cpus_synced(env_cpu(env));
2190 
2191     /*
2192      * cc
2193      *
2194      * 0  Reference bit zero; change bit zero
2195      * 1  Reference bit zero; change bit one
2196      * 2  Reference bit one; change bit zero
2197      * 3  Reference bit one; change bit one
2198      */
2199 
2200     return re >> 1;
2201 }
2202 
2203 uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2,
2204                       uint64_t key)
2205 {
2206     const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
2207     S390Access srca, desta;
2208     uintptr_t ra = GETPC();
2209     int cc = 0;
2210 
2211     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2212                __func__, l, a1, a2);
2213 
2214     if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
2215         psw_as == AS_HOME || psw_as == AS_ACCREG) {
2216         s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
2217     }
2218 
2219     if (!psw_key_valid(env, (key >> 4) & 0xf)) {
2220         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
2221     }
2222 
2223     l = wrap_length32(env, l);
2224     if (l > 256) {
2225         /* max 256 */
2226         l = 256;
2227         cc = 3;
2228     } else if (!l) {
2229         return cc;
2230     }
2231 
2232     access_prepare(&srca, env, a2, l, MMU_DATA_LOAD, MMU_PRIMARY_IDX, ra);
2233     access_prepare(&desta, env, a1, l, MMU_DATA_STORE, MMU_SECONDARY_IDX, ra);
2234     access_memmove(env, &desta, &srca, ra);
2235     return cc;
2236 }
2237 
2238 uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2,
2239                       uint64_t key)
2240 {
2241     const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
2242     S390Access srca, desta;
2243     uintptr_t ra = GETPC();
2244     int cc = 0;
2245 
2246     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2247                __func__, l, a1, a2);
2248 
2249     if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
2250         psw_as == AS_HOME || psw_as == AS_ACCREG) {
2251         s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
2252     }
2253 
2254     if (!psw_key_valid(env, (key >> 4) & 0xf)) {
2255         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
2256     }
2257 
2258     l = wrap_length32(env, l);
2259     if (l > 256) {
2260         /* max 256 */
2261         l = 256;
2262         cc = 3;
2263     } else if (!l) {
2264         return cc;
2265     }
2266     access_prepare(&srca, env, a2, l, MMU_DATA_LOAD, MMU_SECONDARY_IDX, ra);
2267     access_prepare(&desta, env, a1, l, MMU_DATA_STORE, MMU_PRIMARY_IDX, ra);
2268     access_memmove(env, &desta, &srca, ra);
2269     return cc;
2270 }
2271 
2272 void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
2273 {
2274     CPUState *cs = env_cpu(env);
2275     const uintptr_t ra = GETPC();
2276     uint64_t table, entry, raddr;
2277     uint16_t entries, i, index = 0;
2278 
2279     if (r2 & 0xff000) {
2280         tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
2281     }
2282 
2283     if (!(r2 & 0x800)) {
2284         /* invalidation-and-clearing operation */
2285         table = r1 & ASCE_ORIGIN;
2286         entries = (r2 & 0x7ff) + 1;
2287 
2288         switch (r1 & ASCE_TYPE_MASK) {
2289         case ASCE_TYPE_REGION1:
2290             index = (r2 >> 53) & 0x7ff;
2291             break;
2292         case ASCE_TYPE_REGION2:
2293             index = (r2 >> 42) & 0x7ff;
2294             break;
2295         case ASCE_TYPE_REGION3:
2296             index = (r2 >> 31) & 0x7ff;
2297             break;
2298         case ASCE_TYPE_SEGMENT:
2299             index = (r2 >> 20) & 0x7ff;
2300             break;
2301         }
2302         for (i = 0; i < entries; i++) {
2303             /* addresses are not wrapped in 24/31bit mode but table index is */
2304             raddr = table + ((index + i) & 0x7ff) * sizeof(entry);
2305             entry = cpu_ldq_mmuidx_ra(env, raddr, MMU_REAL_IDX, ra);
2306             if (!(entry & REGION_ENTRY_I)) {
2307                 /* we are allowed to not store if already invalid */
2308                 entry |= REGION_ENTRY_I;
2309                 cpu_stq_mmuidx_ra(env, raddr, entry, MMU_REAL_IDX, ra);
2310             }
2311         }
2312     }
2313 
2314     /* We simply flush the complete tlb, therefore we can ignore r3. */
2315     if (m4 & 1) {
2316         tlb_flush(cs);
2317     } else {
2318         tlb_flush_all_cpus_synced(cs);
2319     }
2320 }
2321 
2322 /* invalidate pte */
2323 void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr,
2324                   uint32_t m4)
2325 {
2326     CPUState *cs = env_cpu(env);
2327     const uintptr_t ra = GETPC();
2328     uint64_t page = vaddr & TARGET_PAGE_MASK;
2329     uint64_t pte_addr, pte;
2330 
2331     /* Compute the page table entry address */
2332     pte_addr = (pto & SEGMENT_ENTRY_ORIGIN);
2333     pte_addr += VADDR_PAGE_TX(vaddr) * 8;
2334 
2335     /* Mark the page table entry as invalid */
2336     pte = cpu_ldq_mmuidx_ra(env, pte_addr, MMU_REAL_IDX, ra);
2337     pte |= PAGE_ENTRY_I;
2338     cpu_stq_mmuidx_ra(env, pte_addr, pte, MMU_REAL_IDX, ra);
2339 
2340     /* XXX we exploit the fact that Linux passes the exact virtual
2341        address here - it's not obliged to! */
2342     if (m4 & 1) {
2343         if (vaddr & ~VADDR_PAGE_TX_MASK) {
2344             tlb_flush_page(cs, page);
2345             /* XXX 31-bit hack */
2346             tlb_flush_page(cs, page ^ 0x80000000);
2347         } else {
2348             /* looks like we don't have a valid virtual address */
2349             tlb_flush(cs);
2350         }
2351     } else {
2352         if (vaddr & ~VADDR_PAGE_TX_MASK) {
2353             tlb_flush_page_all_cpus_synced(cs, page);
2354             /* XXX 31-bit hack */
2355             tlb_flush_page_all_cpus_synced(cs, page ^ 0x80000000);
2356         } else {
2357             /* looks like we don't have a valid virtual address */
2358             tlb_flush_all_cpus_synced(cs);
2359         }
2360     }
2361 }
2362 
2363 /* flush local tlb */
2364 void HELPER(ptlb)(CPUS390XState *env)
2365 {
2366     tlb_flush(env_cpu(env));
2367 }
2368 
2369 /* flush global tlb */
2370 void HELPER(purge)(CPUS390XState *env)
2371 {
2372     tlb_flush_all_cpus_synced(env_cpu(env));
2373 }
2374 
2375 /* load real address */
2376 uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
2377 {
2378     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
2379     uint64_t ret, tec;
2380     int flags, exc, cc;
2381 
2382     /* XXX incomplete - has more corner cases */
2383     if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
2384         tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
2385     }
2386 
2387     exc = mmu_translate(env, addr, MMU_S390_LRA, asc, &ret, &flags, &tec);
2388     if (exc) {
2389         cc = 3;
2390         ret = exc | 0x80000000;
2391     } else {
2392         cc = 0;
2393         ret |= addr & ~TARGET_PAGE_MASK;
2394     }
2395 
2396     env->cc_op = cc;
2397     return ret;
2398 }
2399 #endif
2400 
2401 /* load pair from quadword */
2402 uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
2403 {
2404     uintptr_t ra = GETPC();
2405     uint64_t hi, lo;
2406 
2407     check_alignment(env, addr, 16, ra);
2408     hi = cpu_ldq_data_ra(env, addr + 0, ra);
2409     lo = cpu_ldq_data_ra(env, addr + 8, ra);
2410 
2411     env->retxl = lo;
2412     return hi;
2413 }
2414 
2415 uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
2416 {
2417     uintptr_t ra = GETPC();
2418     uint64_t hi, lo;
2419     int mem_idx;
2420     MemOpIdx oi;
2421     Int128 v;
2422 
2423     assert(HAVE_ATOMIC128);
2424 
2425     mem_idx = cpu_mmu_index(env, false);
2426     oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx);
2427     v = cpu_atomic_ldo_be_mmu(env, addr, oi, ra);
2428     hi = int128_gethi(v);
2429     lo = int128_getlo(v);
2430 
2431     env->retxl = lo;
2432     return hi;
2433 }
2434 
2435 /* store pair to quadword */
2436 void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
2437                   uint64_t low, uint64_t high)
2438 {
2439     uintptr_t ra = GETPC();
2440 
2441     check_alignment(env, addr, 16, ra);
2442     cpu_stq_data_ra(env, addr + 0, high, ra);
2443     cpu_stq_data_ra(env, addr + 8, low, ra);
2444 }
2445 
2446 void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
2447                            uint64_t low, uint64_t high)
2448 {
2449     uintptr_t ra = GETPC();
2450     int mem_idx;
2451     MemOpIdx oi;
2452     Int128 v;
2453 
2454     assert(HAVE_ATOMIC128);
2455 
2456     mem_idx = cpu_mmu_index(env, false);
2457     oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx);
2458     v = int128_make128(low, high);
2459     cpu_atomic_sto_be_mmu(env, addr, v, oi, ra);
2460 }
2461 
2462 /* Execute instruction.  This instruction executes an insn modified with
2463    the contents of r1.  It does not change the executed instruction in memory;
2464    it does not change the program counter.
2465 
2466    Perform this by recording the modified instruction in env->ex_value.
2467    This will be noticed by cpu_get_tb_cpu_state and thus tb translation.
2468 */
2469 void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
2470 {
2471     uint64_t insn = cpu_lduw_code(env, addr);
2472     uint8_t opc = insn >> 8;
2473 
2474     /* Or in the contents of R1[56:63].  */
2475     insn |= r1 & 0xff;
2476 
2477     /* Load the rest of the instruction.  */
2478     insn <<= 48;
2479     switch (get_ilen(opc)) {
2480     case 2:
2481         break;
2482     case 4:
2483         insn |= (uint64_t)cpu_lduw_code(env, addr + 2) << 32;
2484         break;
2485     case 6:
2486         insn |= (uint64_t)(uint32_t)cpu_ldl_code(env, addr + 2) << 16;
2487         break;
2488     default:
2489         g_assert_not_reached();
2490     }
2491 
2492     /* The very most common cases can be sped up by avoiding a new TB.  */
2493     if ((opc & 0xf0) == 0xd0) {
2494         typedef uint32_t (*dx_helper)(CPUS390XState *, uint32_t, uint64_t,
2495                                       uint64_t, uintptr_t);
2496         static const dx_helper dx[16] = {
2497             [0x0] = do_helper_trt_bkwd,
2498             [0x2] = do_helper_mvc,
2499             [0x4] = do_helper_nc,
2500             [0x5] = do_helper_clc,
2501             [0x6] = do_helper_oc,
2502             [0x7] = do_helper_xc,
2503             [0xc] = do_helper_tr,
2504             [0xd] = do_helper_trt_fwd,
2505         };
2506         dx_helper helper = dx[opc & 0xf];
2507 
2508         if (helper) {
2509             uint32_t l = extract64(insn, 48, 8);
2510             uint32_t b1 = extract64(insn, 44, 4);
2511             uint32_t d1 = extract64(insn, 32, 12);
2512             uint32_t b2 = extract64(insn, 28, 4);
2513             uint32_t d2 = extract64(insn, 16, 12);
2514             uint64_t a1 = wrap_address(env, (b1 ? env->regs[b1] : 0) + d1);
2515             uint64_t a2 = wrap_address(env, (b2 ? env->regs[b2] : 0) + d2);
2516 
2517             env->cc_op = helper(env, l, a1, a2, 0);
2518             env->psw.addr += ilen;
2519             return;
2520         }
2521     } else if (opc == 0x0a) {
2522         env->int_svc_code = extract64(insn, 48, 8);
2523         env->int_svc_ilen = ilen;
2524         helper_exception(env, EXCP_SVC);
2525         g_assert_not_reached();
2526     }
2527 
2528     /* Record the insn we want to execute as well as the ilen to use
2529        during the execution of the target insn.  This will also ensure
2530        that ex_value is non-zero, which flags that we are in a state
2531        that requires such execution.  */
2532     env->ex_value = insn | ilen;
2533 }
2534 
2535 uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
2536                        uint64_t len)
2537 {
2538     const uint8_t psw_key = (env->psw.mask & PSW_MASK_KEY) >> PSW_SHIFT_KEY;
2539     const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
2540     const uint64_t r0 = env->regs[0];
2541     const uintptr_t ra = GETPC();
2542     uint8_t dest_key, dest_as, dest_k, dest_a;
2543     uint8_t src_key, src_as, src_k, src_a;
2544     uint64_t val;
2545     int cc = 0;
2546 
2547     HELPER_LOG("%s dest %" PRIx64 ", src %" PRIx64 ", len %" PRIx64 "\n",
2548                __func__, dest, src, len);
2549 
2550     if (!(env->psw.mask & PSW_MASK_DAT)) {
2551         tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
2552     }
2553 
2554     /* OAC (operand access control) for the first operand -> dest */
2555     val = (r0 & 0xffff0000ULL) >> 16;
2556     dest_key = (val >> 12) & 0xf;
2557     dest_as = (val >> 6) & 0x3;
2558     dest_k = (val >> 1) & 0x1;
2559     dest_a = val & 0x1;
2560 
2561     /* OAC (operand access control) for the second operand -> src */
2562     val = (r0 & 0x0000ffffULL);
2563     src_key = (val >> 12) & 0xf;
2564     src_as = (val >> 6) & 0x3;
2565     src_k = (val >> 1) & 0x1;
2566     src_a = val & 0x1;
2567 
2568     if (!dest_k) {
2569         dest_key = psw_key;
2570     }
2571     if (!src_k) {
2572         src_key = psw_key;
2573     }
2574     if (!dest_a) {
2575         dest_as = psw_as;
2576     }
2577     if (!src_a) {
2578         src_as = psw_as;
2579     }
2580 
2581     if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {
2582         tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
2583     }
2584     if (!(env->cregs[0] & CR0_SECONDARY) &&
2585         (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {
2586         tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
2587     }
2588     if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {
2589         tcg_s390_program_interrupt(env, PGM_PRIVILEGED, ra);
2590     }
2591 
2592     len = wrap_length32(env, len);
2593     if (len > 4096) {
2594         cc = 3;
2595         len = 4096;
2596     }
2597 
2598     /* FIXME: AR-mode and proper problem state mode (using PSW keys) missing */
2599     if (src_as == AS_ACCREG || dest_as == AS_ACCREG ||
2600         (env->psw.mask & PSW_MASK_PSTATE)) {
2601         qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",
2602                       __func__);
2603         tcg_s390_program_interrupt(env, PGM_ADDRESSING, ra);
2604     }
2605 
2606     /* FIXME: Access using correct keys and AR-mode */
2607     if (len) {
2608         S390Access srca, desta;
2609 
2610         access_prepare(&srca, env, src, len, MMU_DATA_LOAD,
2611                        mmu_idx_from_as(src_as), ra);
2612         access_prepare(&desta, env, dest, len, MMU_DATA_STORE,
2613                        mmu_idx_from_as(dest_as), ra);
2614 
2615         access_memmove(env, &desta, &srca, ra);
2616     }
2617 
2618     return cc;
2619 }
2620 
2621 /* Decode a Unicode character.  A return value < 0 indicates success, storing
2622    the UTF-32 result into OCHAR and the input length into OLEN.  A return
2623    value >= 0 indicates failure, and the CC value to be returned.  */
2624 typedef int (*decode_unicode_fn)(CPUS390XState *env, uint64_t addr,
2625                                  uint64_t ilen, bool enh_check, uintptr_t ra,
2626                                  uint32_t *ochar, uint32_t *olen);
2627 
2628 /* Encode a Unicode character.  A return value < 0 indicates success, storing
2629    the bytes into ADDR and the output length into OLEN.  A return value >= 0
2630    indicates failure, and the CC value to be returned.  */
2631 typedef int (*encode_unicode_fn)(CPUS390XState *env, uint64_t addr,
2632                                  uint64_t ilen, uintptr_t ra, uint32_t c,
2633                                  uint32_t *olen);
2634 
2635 static int decode_utf8(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2636                        bool enh_check, uintptr_t ra,
2637                        uint32_t *ochar, uint32_t *olen)
2638 {
2639     uint8_t s0, s1, s2, s3;
2640     uint32_t c, l;
2641 
2642     if (ilen < 1) {
2643         return 0;
2644     }
2645     s0 = cpu_ldub_data_ra(env, addr, ra);
2646     if (s0 <= 0x7f) {
2647         /* one byte character */
2648         l = 1;
2649         c = s0;
2650     } else if (s0 <= (enh_check ? 0xc1 : 0xbf)) {
2651         /* invalid character */
2652         return 2;
2653     } else if (s0 <= 0xdf) {
2654         /* two byte character */
2655         l = 2;
2656         if (ilen < 2) {
2657             return 0;
2658         }
2659         s1 = cpu_ldub_data_ra(env, addr + 1, ra);
2660         c = s0 & 0x1f;
2661         c = (c << 6) | (s1 & 0x3f);
2662         if (enh_check && (s1 & 0xc0) != 0x80) {
2663             return 2;
2664         }
2665     } else if (s0 <= 0xef) {
2666         /* three byte character */
2667         l = 3;
2668         if (ilen < 3) {
2669             return 0;
2670         }
2671         s1 = cpu_ldub_data_ra(env, addr + 1, ra);
2672         s2 = cpu_ldub_data_ra(env, addr + 2, ra);
2673         c = s0 & 0x0f;
2674         c = (c << 6) | (s1 & 0x3f);
2675         c = (c << 6) | (s2 & 0x3f);
2676         /* Fold the byte-by-byte range descriptions in the PoO into
2677            tests against the complete value.  It disallows encodings
2678            that could be smaller, and the UTF-16 surrogates.  */
2679         if (enh_check
2680             && ((s1 & 0xc0) != 0x80
2681                 || (s2 & 0xc0) != 0x80
2682                 || c < 0x1000
2683                 || (c >= 0xd800 && c <= 0xdfff))) {
2684             return 2;
2685         }
2686     } else if (s0 <= (enh_check ? 0xf4 : 0xf7)) {
2687         /* four byte character */
2688         l = 4;
2689         if (ilen < 4) {
2690             return 0;
2691         }
2692         s1 = cpu_ldub_data_ra(env, addr + 1, ra);
2693         s2 = cpu_ldub_data_ra(env, addr + 2, ra);
2694         s3 = cpu_ldub_data_ra(env, addr + 3, ra);
2695         c = s0 & 0x07;
2696         c = (c << 6) | (s1 & 0x3f);
2697         c = (c << 6) | (s2 & 0x3f);
2698         c = (c << 6) | (s3 & 0x3f);
2699         /* See above.  */
2700         if (enh_check
2701             && ((s1 & 0xc0) != 0x80
2702                 || (s2 & 0xc0) != 0x80
2703                 || (s3 & 0xc0) != 0x80
2704                 || c < 0x010000
2705                 || c > 0x10ffff)) {
2706             return 2;
2707         }
2708     } else {
2709         /* invalid character */
2710         return 2;
2711     }
2712 
2713     *ochar = c;
2714     *olen = l;
2715     return -1;
2716 }
2717 
2718 static int decode_utf16(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2719                         bool enh_check, uintptr_t ra,
2720                         uint32_t *ochar, uint32_t *olen)
2721 {
2722     uint16_t s0, s1;
2723     uint32_t c, l;
2724 
2725     if (ilen < 2) {
2726         return 0;
2727     }
2728     s0 = cpu_lduw_data_ra(env, addr, ra);
2729     if ((s0 & 0xfc00) != 0xd800) {
2730         /* one word character */
2731         l = 2;
2732         c = s0;
2733     } else {
2734         /* two word character */
2735         l = 4;
2736         if (ilen < 4) {
2737             return 0;
2738         }
2739         s1 = cpu_lduw_data_ra(env, addr + 2, ra);
2740         c = extract32(s0, 6, 4) + 1;
2741         c = (c << 6) | (s0 & 0x3f);
2742         c = (c << 10) | (s1 & 0x3ff);
2743         if (enh_check && (s1 & 0xfc00) != 0xdc00) {
2744             /* invalid surrogate character */
2745             return 2;
2746         }
2747     }
2748 
2749     *ochar = c;
2750     *olen = l;
2751     return -1;
2752 }
2753 
2754 static int decode_utf32(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2755                         bool enh_check, uintptr_t ra,
2756                         uint32_t *ochar, uint32_t *olen)
2757 {
2758     uint32_t c;
2759 
2760     if (ilen < 4) {
2761         return 0;
2762     }
2763     c = cpu_ldl_data_ra(env, addr, ra);
2764     if ((c >= 0xd800 && c <= 0xdbff) || c > 0x10ffff) {
2765         /* invalid unicode character */
2766         return 2;
2767     }
2768 
2769     *ochar = c;
2770     *olen = 4;
2771     return -1;
2772 }
2773 
2774 static int encode_utf8(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2775                        uintptr_t ra, uint32_t c, uint32_t *olen)
2776 {
2777     uint8_t d[4];
2778     uint32_t l, i;
2779 
2780     if (c <= 0x7f) {
2781         /* one byte character */
2782         l = 1;
2783         d[0] = c;
2784     } else if (c <= 0x7ff) {
2785         /* two byte character */
2786         l = 2;
2787         d[1] = 0x80 | extract32(c, 0, 6);
2788         d[0] = 0xc0 | extract32(c, 6, 5);
2789     } else if (c <= 0xffff) {
2790         /* three byte character */
2791         l = 3;
2792         d[2] = 0x80 | extract32(c, 0, 6);
2793         d[1] = 0x80 | extract32(c, 6, 6);
2794         d[0] = 0xe0 | extract32(c, 12, 4);
2795     } else {
2796         /* four byte character */
2797         l = 4;
2798         d[3] = 0x80 | extract32(c, 0, 6);
2799         d[2] = 0x80 | extract32(c, 6, 6);
2800         d[1] = 0x80 | extract32(c, 12, 6);
2801         d[0] = 0xf0 | extract32(c, 18, 3);
2802     }
2803 
2804     if (ilen < l) {
2805         return 1;
2806     }
2807     for (i = 0; i < l; ++i) {
2808         cpu_stb_data_ra(env, addr + i, d[i], ra);
2809     }
2810 
2811     *olen = l;
2812     return -1;
2813 }
2814 
2815 static int encode_utf16(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2816                         uintptr_t ra, uint32_t c, uint32_t *olen)
2817 {
2818     uint16_t d0, d1;
2819 
2820     if (c <= 0xffff) {
2821         /* one word character */
2822         if (ilen < 2) {
2823             return 1;
2824         }
2825         cpu_stw_data_ra(env, addr, c, ra);
2826         *olen = 2;
2827     } else {
2828         /* two word character */
2829         if (ilen < 4) {
2830             return 1;
2831         }
2832         d1 = 0xdc00 | extract32(c, 0, 10);
2833         d0 = 0xd800 | extract32(c, 10, 6);
2834         d0 = deposit32(d0, 6, 4, extract32(c, 16, 5) - 1);
2835         cpu_stw_data_ra(env, addr + 0, d0, ra);
2836         cpu_stw_data_ra(env, addr + 2, d1, ra);
2837         *olen = 4;
2838     }
2839 
2840     return -1;
2841 }
2842 
2843 static int encode_utf32(CPUS390XState *env, uint64_t addr, uint64_t ilen,
2844                         uintptr_t ra, uint32_t c, uint32_t *olen)
2845 {
2846     if (ilen < 4) {
2847         return 1;
2848     }
2849     cpu_stl_data_ra(env, addr, c, ra);
2850     *olen = 4;
2851     return -1;
2852 }
2853 
2854 static inline uint32_t convert_unicode(CPUS390XState *env, uint32_t r1,
2855                                        uint32_t r2, uint32_t m3, uintptr_t ra,
2856                                        decode_unicode_fn decode,
2857                                        encode_unicode_fn encode)
2858 {
2859     uint64_t dst = get_address(env, r1);
2860     uint64_t dlen = get_length(env, r1 + 1);
2861     uint64_t src = get_address(env, r2);
2862     uint64_t slen = get_length(env, r2 + 1);
2863     bool enh_check = m3 & 1;
2864     int cc, i;
2865 
2866     /* Lest we fail to service interrupts in a timely manner, limit the
2867        amount of work we're willing to do.  For now, let's cap at 256.  */
2868     for (i = 0; i < 256; ++i) {
2869         uint32_t c, ilen, olen;
2870 
2871         cc = decode(env, src, slen, enh_check, ra, &c, &ilen);
2872         if (unlikely(cc >= 0)) {
2873             break;
2874         }
2875         cc = encode(env, dst, dlen, ra, c, &olen);
2876         if (unlikely(cc >= 0)) {
2877             break;
2878         }
2879 
2880         src += ilen;
2881         slen -= ilen;
2882         dst += olen;
2883         dlen -= olen;
2884         cc = 3;
2885     }
2886 
2887     set_address(env, r1, dst);
2888     set_length(env, r1 + 1, dlen);
2889     set_address(env, r2, src);
2890     set_length(env, r2 + 1, slen);
2891 
2892     return cc;
2893 }
2894 
2895 uint32_t HELPER(cu12)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2896 {
2897     return convert_unicode(env, r1, r2, m3, GETPC(),
2898                            decode_utf8, encode_utf16);
2899 }
2900 
2901 uint32_t HELPER(cu14)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2902 {
2903     return convert_unicode(env, r1, r2, m3, GETPC(),
2904                            decode_utf8, encode_utf32);
2905 }
2906 
2907 uint32_t HELPER(cu21)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2908 {
2909     return convert_unicode(env, r1, r2, m3, GETPC(),
2910                            decode_utf16, encode_utf8);
2911 }
2912 
2913 uint32_t HELPER(cu24)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2914 {
2915     return convert_unicode(env, r1, r2, m3, GETPC(),
2916                            decode_utf16, encode_utf32);
2917 }
2918 
2919 uint32_t HELPER(cu41)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2920 {
2921     return convert_unicode(env, r1, r2, m3, GETPC(),
2922                            decode_utf32, encode_utf8);
2923 }
2924 
2925 uint32_t HELPER(cu42)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
2926 {
2927     return convert_unicode(env, r1, r2, m3, GETPC(),
2928                            decode_utf32, encode_utf16);
2929 }
2930 
2931 void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
2932                         uintptr_t ra)
2933 {
2934     /* test the actual access, not just any access to the page due to LAP */
2935     while (len) {
2936         const uint64_t pagelen = -(addr | TARGET_PAGE_MASK);
2937         const uint64_t curlen = MIN(pagelen, len);
2938 
2939         probe_write(env, addr, curlen, cpu_mmu_index(env, false), ra);
2940         addr = wrap_address(env, addr + curlen);
2941         len -= curlen;
2942     }
2943 }
2944 
2945 void HELPER(probe_write_access)(CPUS390XState *env, uint64_t addr, uint64_t len)
2946 {
2947     probe_write_access(env, addr, len, GETPC());
2948 }
2949