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