2 * S/390 memory access helper routines
4 * Copyright (c) 2009 Ulrich Hecht
5 * Copyright (c) 2009 Alexander Graf
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.
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.
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/>.
21 #include "qemu/osdep.h"
24 #include "tcg_s390x.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 #include "qemu/atomic128.h"
32 #if !defined(CONFIG_USER_ONLY)
33 #include "hw/s390x/storage-keys.h"
36 /*****************************************************************************/
39 /* #define DEBUG_HELPER */
41 #define HELPER_LOG(x...) qemu_log(x)
43 #define HELPER_LOG(x...)
46 static inline bool psw_key_valid(CPUS390XState
*env
, uint8_t psw_key
)
48 uint16_t pkm
= env
->cregs
[3] >> 16;
50 if (env
->psw
.mask
& PSW_MASK_PSTATE
) {
51 /* PSW key has range 0..15, it is valid if the bit is 1 in the PKM */
52 return pkm
& (0x80 >> psw_key
);
57 static bool is_destructive_overlap(CPUS390XState
*env
, uint64_t dest
,
58 uint64_t src
, uint32_t len
)
60 if (!len
|| src
== dest
) {
63 /* Take care of wrapping at the end of address space. */
64 if (unlikely(wrap_address(env
, src
+ len
- 1) < src
)) {
65 return dest
> src
|| dest
<= wrap_address(env
, src
+ len
- 1);
67 return dest
> src
&& dest
<= src
+ len
- 1;
70 /* Trigger a SPECIFICATION exception if an address or a length is not
72 static inline void check_alignment(CPUS390XState
*env
, uint64_t v
,
73 int wordsize
, uintptr_t ra
)
76 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
80 /* Load a value from memory according to its size. */
81 static inline uint64_t cpu_ldusize_data_ra(CPUS390XState
*env
, uint64_t addr
,
82 int wordsize
, uintptr_t ra
)
86 return cpu_ldub_data_ra(env
, addr
, ra
);
88 return cpu_lduw_data_ra(env
, addr
, ra
);
94 /* Store a to memory according to its size. */
95 static inline void cpu_stsize_data_ra(CPUS390XState
*env
, uint64_t addr
,
96 uint64_t value
, int wordsize
,
101 cpu_stb_data_ra(env
, addr
, value
, ra
);
104 cpu_stw_data_ra(env
, addr
, value
, ra
);
111 /* An access covers at most 4096 bytes and therefore at most two pages. */
112 typedef struct S390Access
{
120 * If we can't access the host page directly, we'll have to do I/O access
121 * via ld/st helpers. These are internal details, so we store the
122 * mmu idx to do the access here instead of passing it around in the
123 * helpers. Maybe, one day we can get rid of ld/st access - once we can
124 * handle TLB_NOTDIRTY differently. We don't expect these special accesses
125 * to trigger exceptions - only if we would have TLB_NOTDIRTY on LAP
126 * pages, we might trigger a new MMU translation - very unlikely that
127 * the mapping changes in between and we would trigger a fault.
132 static S390Access
access_prepare(CPUS390XState
*env
, vaddr vaddr
, int size
,
133 MMUAccessType access_type
, int mmu_idx
,
136 S390Access access
= {
138 .size1
= MIN(size
, -(vaddr
| TARGET_PAGE_MASK
)),
142 g_assert(size
> 0 && size
<= 4096);
143 access
.haddr1
= probe_access(env
, access
.vaddr1
, access
.size1
, access_type
,
146 if (unlikely(access
.size1
!= size
)) {
147 /* The access crosses page boundaries. */
148 access
.vaddr2
= wrap_address(env
, vaddr
+ access
.size1
);
149 access
.size2
= size
- access
.size1
;
150 access
.haddr2
= probe_access(env
, access
.vaddr2
, access
.size2
,
151 access_type
, mmu_idx
, ra
);
156 /* Helper to handle memset on a single page. */
157 static void do_access_memset(CPUS390XState
*env
, vaddr vaddr
, char *haddr
,
158 uint8_t byte
, uint16_t size
, int mmu_idx
,
161 #ifdef CONFIG_USER_ONLY
163 memset(haddr
, byte
, size
);
165 TCGMemOpIdx oi
= make_memop_idx(MO_UB
, mmu_idx
);
169 memset(haddr
, byte
, size
);
172 * Do a single access and test if we can then get access to the
173 * page. This is especially relevant to speed up TLB_NOTDIRTY.
176 helper_ret_stb_mmu(env
, vaddr
, byte
, oi
, ra
);
177 haddr
= tlb_vaddr_to_host(env
, vaddr
, MMU_DATA_STORE
, mmu_idx
);
179 memset(haddr
+ 1, byte
, size
- 1);
181 for (i
= 1; i
< size
; i
++) {
182 helper_ret_stb_mmu(env
, vaddr
+ i
, byte
, oi
, ra
);
189 static void access_memset(CPUS390XState
*env
, S390Access
*desta
,
190 uint8_t byte
, uintptr_t ra
)
193 do_access_memset(env
, desta
->vaddr1
, desta
->haddr1
, byte
, desta
->size1
,
195 if (likely(!desta
->size2
)) {
198 do_access_memset(env
, desta
->vaddr2
, desta
->haddr2
, byte
, desta
->size2
,
202 static uint8_t do_access_get_byte(CPUS390XState
*env
, vaddr vaddr
, char **haddr
,
203 int offset
, int mmu_idx
, uintptr_t ra
)
205 #ifdef CONFIG_USER_ONLY
206 return ldub_p(*haddr
+ offset
);
208 TCGMemOpIdx oi
= make_memop_idx(MO_UB
, mmu_idx
);
211 if (likely(*haddr
)) {
212 return ldub_p(*haddr
+ offset
);
215 * Do a single access and test if we can then get access to the
216 * page. This is especially relevant to speed up TLB_NOTDIRTY.
218 byte
= helper_ret_ldub_mmu(env
, vaddr
+ offset
, oi
, ra
);
219 *haddr
= tlb_vaddr_to_host(env
, vaddr
, MMU_DATA_LOAD
, mmu_idx
);
224 static uint8_t access_get_byte(CPUS390XState
*env
, S390Access
*access
,
225 int offset
, uintptr_t ra
)
227 if (offset
< access
->size1
) {
228 return do_access_get_byte(env
, access
->vaddr1
, &access
->haddr1
,
229 offset
, access
->mmu_idx
, ra
);
231 return do_access_get_byte(env
, access
->vaddr2
, &access
->haddr2
,
232 offset
- access
->size1
, access
->mmu_idx
, ra
);
235 static void do_access_set_byte(CPUS390XState
*env
, vaddr vaddr
, char **haddr
,
236 int offset
, uint8_t byte
, int mmu_idx
,
239 #ifdef CONFIG_USER_ONLY
240 stb_p(*haddr
+ offset
, byte
);
242 TCGMemOpIdx oi
= make_memop_idx(MO_UB
, mmu_idx
);
244 if (likely(*haddr
)) {
245 stb_p(*haddr
+ offset
, byte
);
249 * Do a single access and test if we can then get access to the
250 * page. This is especially relevant to speed up TLB_NOTDIRTY.
252 helper_ret_stb_mmu(env
, vaddr
+ offset
, byte
, oi
, ra
);
253 *haddr
= tlb_vaddr_to_host(env
, vaddr
, MMU_DATA_STORE
, mmu_idx
);
257 static void access_set_byte(CPUS390XState
*env
, S390Access
*access
,
258 int offset
, uint8_t byte
, uintptr_t ra
)
260 if (offset
< access
->size1
) {
261 do_access_set_byte(env
, access
->vaddr1
, &access
->haddr1
, offset
, byte
,
262 access
->mmu_idx
, ra
);
264 do_access_set_byte(env
, access
->vaddr2
, &access
->haddr2
,
265 offset
- access
->size1
, byte
, access
->mmu_idx
, ra
);
270 * Move data with the same semantics as memmove() in case ranges don't overlap
271 * or src > dest. Undefined behavior on destructive overlaps.
273 static void access_memmove(CPUS390XState
*env
, S390Access
*desta
,
274 S390Access
*srca
, uintptr_t ra
)
278 g_assert(desta
->size1
+ desta
->size2
== srca
->size1
+ srca
->size2
);
280 /* Fallback to slow access in case we don't have access to all host pages */
281 if (unlikely(!desta
->haddr1
|| (desta
->size2
&& !desta
->haddr2
) ||
282 !srca
->haddr1
|| (srca
->size2
&& !srca
->haddr2
))) {
285 for (i
= 0; i
< desta
->size1
+ desta
->size2
; i
++) {
286 uint8_t byte
= access_get_byte(env
, srca
, i
, ra
);
288 access_set_byte(env
, desta
, i
, byte
, ra
);
293 if (srca
->size1
== desta
->size1
) {
294 memmove(desta
->haddr1
, srca
->haddr1
, srca
->size1
);
295 if (unlikely(srca
->size2
)) {
296 memmove(desta
->haddr2
, srca
->haddr2
, srca
->size2
);
298 } else if (srca
->size1
< desta
->size1
) {
299 diff
= desta
->size1
- srca
->size1
;
300 memmove(desta
->haddr1
, srca
->haddr1
, srca
->size1
);
301 memmove(desta
->haddr1
+ srca
->size1
, srca
->haddr2
, diff
);
302 if (likely(desta
->size2
)) {
303 memmove(desta
->haddr2
, srca
->haddr2
+ diff
, desta
->size2
);
306 diff
= srca
->size1
- desta
->size1
;
307 memmove(desta
->haddr1
, srca
->haddr1
, desta
->size1
);
308 memmove(desta
->haddr2
, srca
->haddr1
+ desta
->size1
, diff
);
309 if (likely(srca
->size2
)) {
310 memmove(desta
->haddr2
+ diff
, srca
->haddr2
, srca
->size2
);
315 static int mmu_idx_from_as(uint8_t as
)
319 return MMU_PRIMARY_IDX
;
321 return MMU_SECONDARY_IDX
;
325 /* FIXME AS_ACCREG */
326 g_assert_not_reached();
331 static uint32_t do_helper_nc(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
332 uint64_t src
, uintptr_t ra
)
334 const int mmu_idx
= cpu_mmu_index(env
, false);
335 S390Access srca1
, srca2
, desta
;
339 HELPER_LOG("%s l %d dest %" PRIx64
" src %" PRIx64
"\n",
340 __func__
, l
, dest
, src
);
342 /* NC always processes one more byte than specified - maximum is 256 */
345 srca1
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
346 srca2
= access_prepare(env
, dest
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
347 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
348 for (i
= 0; i
< l
; i
++) {
349 const uint8_t x
= access_get_byte(env
, &srca1
, i
, ra
) &
350 access_get_byte(env
, &srca2
, i
, ra
);
353 access_set_byte(env
, &desta
, i
, x
, ra
);
358 uint32_t HELPER(nc
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
361 return do_helper_nc(env
, l
, dest
, src
, GETPC());
365 static uint32_t do_helper_xc(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
366 uint64_t src
, uintptr_t ra
)
368 const int mmu_idx
= cpu_mmu_index(env
, false);
369 S390Access srca1
, srca2
, desta
;
373 HELPER_LOG("%s l %d dest %" PRIx64
" src %" PRIx64
"\n",
374 __func__
, l
, dest
, src
);
376 /* XC always processes one more byte than specified - maximum is 256 */
379 srca1
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
380 srca2
= access_prepare(env
, dest
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
381 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
383 /* xor with itself is the same as memset(0) */
385 access_memset(env
, &desta
, 0, ra
);
389 for (i
= 0; i
< l
; i
++) {
390 const uint8_t x
= access_get_byte(env
, &srca1
, i
, ra
) ^
391 access_get_byte(env
, &srca2
, i
, ra
);
394 access_set_byte(env
, &desta
, i
, x
, ra
);
399 uint32_t HELPER(xc
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
402 return do_helper_xc(env
, l
, dest
, src
, GETPC());
406 static uint32_t do_helper_oc(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
407 uint64_t src
, uintptr_t ra
)
409 const int mmu_idx
= cpu_mmu_index(env
, false);
410 S390Access srca1
, srca2
, desta
;
414 HELPER_LOG("%s l %d dest %" PRIx64
" src %" PRIx64
"\n",
415 __func__
, l
, dest
, src
);
417 /* OC always processes one more byte than specified - maximum is 256 */
420 srca1
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
421 srca2
= access_prepare(env
, dest
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
422 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
423 for (i
= 0; i
< l
; i
++) {
424 const uint8_t x
= access_get_byte(env
, &srca1
, i
, ra
) |
425 access_get_byte(env
, &srca2
, i
, ra
);
428 access_set_byte(env
, &desta
, i
, x
, ra
);
433 uint32_t HELPER(oc
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
436 return do_helper_oc(env
, l
, dest
, src
, GETPC());
440 static uint32_t do_helper_mvc(CPUS390XState
*env
, uint32_t l
, uint64_t dest
,
441 uint64_t src
, uintptr_t ra
)
443 const int mmu_idx
= cpu_mmu_index(env
, false);
444 S390Access srca
, desta
;
447 HELPER_LOG("%s l %d dest %" PRIx64
" src %" PRIx64
"\n",
448 __func__
, l
, dest
, src
);
450 /* MVC always copies one more byte than specified - maximum is 256 */
453 srca
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
454 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
457 * "When the operands overlap, the result is obtained as if the operands
458 * were processed one byte at a time". Only non-destructive overlaps
459 * behave like memmove().
461 if (dest
== src
+ 1) {
462 access_memset(env
, &desta
, access_get_byte(env
, &srca
, 0, ra
), ra
);
463 } else if (!is_destructive_overlap(env
, dest
, src
, l
)) {
464 access_memmove(env
, &desta
, &srca
, ra
);
466 for (i
= 0; i
< l
; i
++) {
467 uint8_t byte
= access_get_byte(env
, &srca
, i
, ra
);
469 access_set_byte(env
, &desta
, i
, byte
, ra
);
476 void HELPER(mvc
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
, uint64_t src
)
478 do_helper_mvc(env
, l
, dest
, src
, GETPC());
482 void HELPER(mvcin
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
, uint64_t src
)
484 const int mmu_idx
= cpu_mmu_index(env
, false);
485 S390Access srca
, desta
;
486 uintptr_t ra
= GETPC();
489 /* MVCIN always copies one more byte than specified - maximum is 256 */
492 src
= wrap_address(env
, src
- l
+ 1);
493 srca
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
494 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
495 for (i
= 0; i
< l
; i
++) {
496 const uint8_t x
= access_get_byte(env
, &srca
, l
- i
- 1, ra
);
498 access_set_byte(env
, &desta
, i
, x
, ra
);
503 void HELPER(mvn
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
, uint64_t src
)
505 const int mmu_idx
= cpu_mmu_index(env
, false);
506 S390Access srca1
, srca2
, desta
;
507 uintptr_t ra
= GETPC();
510 /* MVN always copies one more byte than specified - maximum is 256 */
513 srca1
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
514 srca2
= access_prepare(env
, dest
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
515 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
516 for (i
= 0; i
< l
; i
++) {
517 const uint8_t x
= (access_get_byte(env
, &srca1
, i
, ra
) & 0x0f) |
518 (access_get_byte(env
, &srca2
, i
, ra
) & 0xf0);
520 access_set_byte(env
, &desta
, i
, x
, ra
);
524 /* move with offset */
525 void HELPER(mvo
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
, uint64_t src
)
527 const int mmu_idx
= cpu_mmu_index(env
, false);
528 /* MVO always processes one more byte than specified - maximum is 16 */
529 const int len_dest
= (l
>> 4) + 1;
530 const int len_src
= (l
& 0xf) + 1;
531 uintptr_t ra
= GETPC();
532 uint8_t byte_dest
, byte_src
;
533 S390Access srca
, desta
;
536 srca
= access_prepare(env
, src
, len_src
, MMU_DATA_LOAD
, mmu_idx
, ra
);
537 desta
= access_prepare(env
, dest
, len_dest
, MMU_DATA_STORE
, mmu_idx
, ra
);
539 /* Handle rightmost byte */
540 byte_dest
= cpu_ldub_data_ra(env
, dest
+ len_dest
- 1, ra
);
541 byte_src
= access_get_byte(env
, &srca
, len_src
- 1, ra
);
542 byte_dest
= (byte_dest
& 0x0f) | (byte_src
<< 4);
543 access_set_byte(env
, &desta
, len_dest
- 1, byte_dest
, ra
);
545 /* Process remaining bytes from right to left */
546 for (i
= len_dest
- 2, j
= len_src
- 2; i
>= 0; i
--, j
--) {
547 byte_dest
= byte_src
>> 4;
549 byte_src
= access_get_byte(env
, &srca
, j
, ra
);
553 byte_dest
|= byte_src
<< 4;
554 access_set_byte(env
, &desta
, i
, byte_dest
, ra
);
559 void HELPER(mvz
)(CPUS390XState
*env
, uint32_t l
, uint64_t dest
, uint64_t src
)
561 const int mmu_idx
= cpu_mmu_index(env
, false);
562 S390Access srca1
, srca2
, desta
;
563 uintptr_t ra
= GETPC();
566 /* MVZ always copies one more byte than specified - maximum is 256 */
569 srca1
= access_prepare(env
, src
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
570 srca2
= access_prepare(env
, dest
, l
, MMU_DATA_LOAD
, mmu_idx
, ra
);
571 desta
= access_prepare(env
, dest
, l
, MMU_DATA_STORE
, mmu_idx
, ra
);
572 for (i
= 0; i
< l
; i
++) {
573 const uint8_t x
= (access_get_byte(env
, &srca1
, i
, ra
) & 0xf0) |
574 (access_get_byte(env
, &srca2
, i
, ra
) & 0x0f);
576 access_set_byte(env
, &desta
, i
, x
, ra
);
580 /* compare unsigned byte arrays */
581 static uint32_t do_helper_clc(CPUS390XState
*env
, uint32_t l
, uint64_t s1
,
582 uint64_t s2
, uintptr_t ra
)
587 HELPER_LOG("%s l %d s1 %" PRIx64
" s2 %" PRIx64
"\n",
588 __func__
, l
, s1
, s2
);
590 for (i
= 0; i
<= l
; i
++) {
591 uint8_t x
= cpu_ldub_data_ra(env
, s1
+ i
, ra
);
592 uint8_t y
= cpu_ldub_data_ra(env
, s2
+ i
, ra
);
593 HELPER_LOG("%02x (%c)/%02x (%c) ", x
, x
, y
, y
);
607 uint32_t HELPER(clc
)(CPUS390XState
*env
, uint32_t l
, uint64_t s1
, uint64_t s2
)
609 return do_helper_clc(env
, l
, s1
, s2
, GETPC());
612 /* compare logical under mask */
613 uint32_t HELPER(clm
)(CPUS390XState
*env
, uint32_t r1
, uint32_t mask
,
616 uintptr_t ra
= GETPC();
619 HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64
"\n", __func__
, r1
,
624 uint8_t d
= cpu_ldub_data_ra(env
, addr
, ra
);
625 uint8_t r
= extract32(r1
, 24, 8);
626 HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64
") ", mask
, r
, d
,
637 mask
= (mask
<< 1) & 0xf;
645 static inline uint64_t get_address(CPUS390XState
*env
, int reg
)
647 return wrap_address(env
, env
->regs
[reg
]);
651 * Store the address to the given register, zeroing out unused leftmost
652 * bits in bit positions 32-63 (24-bit and 31-bit mode only).
654 static inline void set_address_zero(CPUS390XState
*env
, int reg
,
657 if (env
->psw
.mask
& PSW_MASK_64
) {
658 env
->regs
[reg
] = address
;
660 if (!(env
->psw
.mask
& PSW_MASK_32
)) {
661 address
&= 0x00ffffff;
663 address
&= 0x7fffffff;
665 env
->regs
[reg
] = deposit64(env
->regs
[reg
], 0, 32, address
);
669 static inline void set_address(CPUS390XState
*env
, int reg
, uint64_t address
)
671 if (env
->psw
.mask
& PSW_MASK_64
) {
673 env
->regs
[reg
] = address
;
675 if (!(env
->psw
.mask
& PSW_MASK_32
)) {
676 /* 24-Bit mode. According to the PoO it is implementation
677 dependent if bits 32-39 remain unchanged or are set to
678 zeros. Choose the former so that the function can also be
680 env
->regs
[reg
] = deposit64(env
->regs
[reg
], 0, 24, address
);
682 /* 31-Bit mode. According to the PoO it is implementation
683 dependent if bit 32 remains unchanged or is set to zero.
684 Choose the latter so that the function can also be used for
686 address
&= 0x7fffffff;
687 env
->regs
[reg
] = deposit64(env
->regs
[reg
], 0, 32, address
);
692 static inline uint64_t wrap_length32(CPUS390XState
*env
, uint64_t length
)
694 if (!(env
->psw
.mask
& PSW_MASK_64
)) {
695 return (uint32_t)length
;
700 static inline uint64_t wrap_length31(CPUS390XState
*env
, uint64_t length
)
702 if (!(env
->psw
.mask
& PSW_MASK_64
)) {
703 /* 24-Bit and 31-Bit mode */
704 length
&= 0x7fffffff;
709 static inline uint64_t get_length(CPUS390XState
*env
, int reg
)
711 return wrap_length31(env
, env
->regs
[reg
]);
714 static inline void set_length(CPUS390XState
*env
, int reg
, uint64_t length
)
716 if (env
->psw
.mask
& PSW_MASK_64
) {
718 env
->regs
[reg
] = length
;
720 /* 24-Bit and 31-Bit mode */
721 env
->regs
[reg
] = deposit64(env
->regs
[reg
], 0, 32, length
);
725 /* search string (c is byte to search, r2 is string, r1 end of string) */
726 void HELPER(srst
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
)
728 uintptr_t ra
= GETPC();
731 uint8_t v
, c
= env
->regs
[0];
733 /* Bits 32-55 must contain all 0. */
734 if (env
->regs
[0] & 0xffffff00u
) {
735 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
738 str
= get_address(env
, r2
);
739 end
= get_address(env
, r1
);
741 /* Lest we fail to service interrupts in a timely manner, limit the
742 amount of work we're willing to do. For now, let's cap at 8k. */
743 for (len
= 0; len
< 0x2000; ++len
) {
744 if (str
+ len
== end
) {
745 /* Character not found. R1 & R2 are unmodified. */
749 v
= cpu_ldub_data_ra(env
, str
+ len
, ra
);
751 /* Character found. Set R1 to the location; R2 is unmodified. */
753 set_address(env
, r1
, str
+ len
);
758 /* CPU-determined bytes processed. Advance R2 to next byte to process. */
760 set_address(env
, r2
, str
+ len
);
763 void HELPER(srstu
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
)
765 uintptr_t ra
= GETPC();
767 uint16_t v
, c
= env
->regs
[0];
768 uint64_t end
, str
, adj_end
;
770 /* Bits 32-47 of R0 must be zero. */
771 if (env
->regs
[0] & 0xffff0000u
) {
772 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
775 str
= get_address(env
, r2
);
776 end
= get_address(env
, r1
);
778 /* If the LSB of the two addresses differ, use one extra byte. */
779 adj_end
= end
+ ((str
^ end
) & 1);
781 /* Lest we fail to service interrupts in a timely manner, limit the
782 amount of work we're willing to do. For now, let's cap at 8k. */
783 for (len
= 0; len
< 0x2000; len
+= 2) {
784 if (str
+ len
== adj_end
) {
785 /* End of input found. */
789 v
= cpu_lduw_data_ra(env
, str
+ len
, ra
);
791 /* Character found. Set R1 to the location; R2 is unmodified. */
793 set_address(env
, r1
, str
+ len
);
798 /* CPU-determined bytes processed. Advance R2 to next byte to process. */
800 set_address(env
, r2
, str
+ len
);
803 /* unsigned string compare (c is string terminator) */
804 uint64_t HELPER(clst
)(CPUS390XState
*env
, uint64_t c
, uint64_t s1
, uint64_t s2
)
806 uintptr_t ra
= GETPC();
810 s1
= wrap_address(env
, s1
);
811 s2
= wrap_address(env
, s2
);
813 /* Lest we fail to service interrupts in a timely manner, limit the
814 amount of work we're willing to do. For now, let's cap at 8k. */
815 for (len
= 0; len
< 0x2000; ++len
) {
816 uint8_t v1
= cpu_ldub_data_ra(env
, s1
+ len
, ra
);
817 uint8_t v2
= cpu_ldub_data_ra(env
, s2
+ len
, ra
);
820 /* Equal. CC=0, and don't advance the registers. */
826 /* Unequal. CC={1,2}, and advance the registers. Note that
827 the terminator need not be zero, but the string that contains
828 the terminator is by definition "low". */
829 env
->cc_op
= (v1
== c
? 1 : v2
== c
? 2 : v1
< v2
? 1 : 2);
830 env
->retxl
= s2
+ len
;
835 /* CPU-determined bytes equal; advance the registers. */
837 env
->retxl
= s2
+ len
;
842 uint32_t HELPER(mvpg
)(CPUS390XState
*env
, uint64_t r0
, uint64_t r1
, uint64_t r2
)
844 const int mmu_idx
= cpu_mmu_index(env
, false);
845 const bool f
= extract64(r0
, 11, 1);
846 const bool s
= extract64(r0
, 10, 1);
847 uintptr_t ra
= GETPC();
848 S390Access srca
, desta
;
850 if ((f
&& s
) || extract64(r0
, 12, 4)) {
851 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, GETPC());
854 r1
= wrap_address(env
, r1
& TARGET_PAGE_MASK
);
855 r2
= wrap_address(env
, r2
& TARGET_PAGE_MASK
);
859 * - Access key handling
860 * - CC-option with surpression of page-translation exceptions
861 * - Store r1/r2 register identifiers at real location 162
863 srca
= access_prepare(env
, r2
, TARGET_PAGE_SIZE
, MMU_DATA_LOAD
, mmu_idx
,
865 desta
= access_prepare(env
, r1
, TARGET_PAGE_SIZE
, MMU_DATA_STORE
, mmu_idx
,
867 access_memmove(env
, &desta
, &srca
, ra
);
868 return 0; /* data moved */
872 uint32_t HELPER(mvst
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
)
874 const int mmu_idx
= cpu_mmu_index(env
, false);
875 const uint64_t d
= get_address(env
, r1
);
876 const uint64_t s
= get_address(env
, r2
);
877 const uint8_t c
= env
->regs
[0];
878 const int len
= MIN(-(d
| TARGET_PAGE_MASK
), -(s
| TARGET_PAGE_MASK
));
879 S390Access srca
, desta
;
880 uintptr_t ra
= GETPC();
883 if (env
->regs
[0] & 0xffffff00ull
) {
884 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
888 * Our access should not exceed single pages, as we must not report access
889 * exceptions exceeding the actually copied range (which we don't know at
890 * this point). We might over-indicate watchpoints within the pages
891 * (if we ever care, we have to limit processing to a single byte).
893 srca
= access_prepare(env
, s
, len
, MMU_DATA_LOAD
, mmu_idx
, ra
);
894 desta
= access_prepare(env
, d
, len
, MMU_DATA_STORE
, mmu_idx
, ra
);
895 for (i
= 0; i
< len
; i
++) {
896 const uint8_t v
= access_get_byte(env
, &srca
, i
, ra
);
898 access_set_byte(env
, &desta
, i
, v
, ra
);
900 set_address_zero(env
, r1
, d
+ i
);
904 set_address_zero(env
, r1
, d
+ len
);
905 set_address_zero(env
, r2
, s
+ len
);
909 /* load access registers r1 to r3 from memory at a2 */
910 void HELPER(lam
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
912 uintptr_t ra
= GETPC();
916 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
919 for (i
= r1
;; i
= (i
+ 1) % 16) {
920 env
->aregs
[i
] = cpu_ldl_data_ra(env
, a2
, ra
);
929 /* store access registers r1 to r3 in memory at a2 */
930 void HELPER(stam
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
932 uintptr_t ra
= GETPC();
936 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
939 for (i
= r1
;; i
= (i
+ 1) % 16) {
940 cpu_stl_data_ra(env
, a2
, env
->aregs
[i
], ra
);
949 /* move long helper */
950 static inline uint32_t do_mvcl(CPUS390XState
*env
,
951 uint64_t *dest
, uint64_t *destlen
,
952 uint64_t *src
, uint64_t *srclen
,
953 uint16_t pad
, int wordsize
, uintptr_t ra
)
955 const int mmu_idx
= cpu_mmu_index(env
, false);
956 int len
= MIN(*destlen
, -(*dest
| TARGET_PAGE_MASK
));
957 S390Access srca
, desta
;
960 if (*destlen
== *srclen
) {
962 } else if (*destlen
< *srclen
) {
973 * Only perform one type of type of operation (move/pad) at a time.
974 * Stay within single pages.
977 /* Copy the src array */
978 len
= MIN(MIN(*srclen
, -(*src
| TARGET_PAGE_MASK
)), len
);
981 srca
= access_prepare(env
, *src
, len
, MMU_DATA_LOAD
, mmu_idx
, ra
);
982 desta
= access_prepare(env
, *dest
, len
, MMU_DATA_STORE
, mmu_idx
, ra
);
983 access_memmove(env
, &desta
, &srca
, ra
);
984 *src
= wrap_address(env
, *src
+ len
);
985 *dest
= wrap_address(env
, *dest
+ len
);
986 } else if (wordsize
== 1) {
987 /* Pad the remaining area */
989 desta
= access_prepare(env
, *dest
, len
, MMU_DATA_STORE
, mmu_idx
, ra
);
990 access_memset(env
, &desta
, pad
, ra
);
991 *dest
= wrap_address(env
, *dest
+ len
);
993 desta
= access_prepare(env
, *dest
, len
, MMU_DATA_STORE
, mmu_idx
, ra
);
995 /* The remaining length selects the padding byte. */
996 for (i
= 0; i
< len
; (*destlen
)--, i
++) {
998 access_set_byte(env
, &desta
, i
, pad
, ra
);
1000 access_set_byte(env
, &desta
, i
, pad
>> 8, ra
);
1003 *dest
= wrap_address(env
, *dest
+ len
);
1006 return *destlen
? 3 : cc
;
1010 uint32_t HELPER(mvcl
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
)
1012 const int mmu_idx
= cpu_mmu_index(env
, false);
1013 uintptr_t ra
= GETPC();
1014 uint64_t destlen
= env
->regs
[r1
+ 1] & 0xffffff;
1015 uint64_t dest
= get_address(env
, r1
);
1016 uint64_t srclen
= env
->regs
[r2
+ 1] & 0xffffff;
1017 uint64_t src
= get_address(env
, r2
);
1018 uint8_t pad
= env
->regs
[r2
+ 1] >> 24;
1019 CPUState
*cs
= env_cpu(env
);
1020 S390Access srca
, desta
;
1021 uint32_t cc
, cur_len
;
1023 if (is_destructive_overlap(env
, dest
, src
, MIN(srclen
, destlen
))) {
1025 } else if (srclen
== destlen
) {
1027 } else if (destlen
< srclen
) {
1033 /* We might have to zero-out some bits even if there was no action. */
1034 if (unlikely(!destlen
|| cc
== 3)) {
1035 set_address_zero(env
, r2
, src
);
1036 set_address_zero(env
, r1
, dest
);
1038 } else if (!srclen
) {
1039 set_address_zero(env
, r2
, src
);
1043 * Only perform one type of type of operation (move/pad) in one step.
1044 * Stay within single pages.
1047 cur_len
= MIN(destlen
, -(dest
| TARGET_PAGE_MASK
));
1049 desta
= access_prepare(env
, dest
, cur_len
, MMU_DATA_STORE
, mmu_idx
,
1051 access_memset(env
, &desta
, pad
, ra
);
1053 cur_len
= MIN(MIN(srclen
, -(src
| TARGET_PAGE_MASK
)), cur_len
);
1055 srca
= access_prepare(env
, src
, cur_len
, MMU_DATA_LOAD
, mmu_idx
,
1057 desta
= access_prepare(env
, dest
, cur_len
, MMU_DATA_STORE
, mmu_idx
,
1059 access_memmove(env
, &desta
, &srca
, ra
);
1060 src
= wrap_address(env
, src
+ cur_len
);
1062 env
->regs
[r2
+ 1] = deposit64(env
->regs
[r2
+ 1], 0, 24, srclen
);
1063 set_address_zero(env
, r2
, src
);
1065 dest
= wrap_address(env
, dest
+ cur_len
);
1067 env
->regs
[r1
+ 1] = deposit64(env
->regs
[r1
+ 1], 0, 24, destlen
);
1068 set_address_zero(env
, r1
, dest
);
1071 * MVCL is interruptible. Return to the main loop if requested after
1072 * writing back all state to registers. If no interrupt will get
1073 * injected, we'll end up back in this handler and continue processing
1074 * the remaining parts.
1076 if (destlen
&& unlikely(cpu_loop_exit_requested(cs
))) {
1077 cpu_loop_exit_restore(cs
, ra
);
1083 /* move long extended */
1084 uint32_t HELPER(mvcle
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
,
1087 uintptr_t ra
= GETPC();
1088 uint64_t destlen
= get_length(env
, r1
+ 1);
1089 uint64_t dest
= get_address(env
, r1
);
1090 uint64_t srclen
= get_length(env
, r3
+ 1);
1091 uint64_t src
= get_address(env
, r3
);
1095 cc
= do_mvcl(env
, &dest
, &destlen
, &src
, &srclen
, pad
, 1, ra
);
1097 set_length(env
, r1
+ 1, destlen
);
1098 set_length(env
, r3
+ 1, srclen
);
1099 set_address(env
, r1
, dest
);
1100 set_address(env
, r3
, src
);
1105 /* move long unicode */
1106 uint32_t HELPER(mvclu
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
,
1109 uintptr_t ra
= GETPC();
1110 uint64_t destlen
= get_length(env
, r1
+ 1);
1111 uint64_t dest
= get_address(env
, r1
);
1112 uint64_t srclen
= get_length(env
, r3
+ 1);
1113 uint64_t src
= get_address(env
, r3
);
1117 cc
= do_mvcl(env
, &dest
, &destlen
, &src
, &srclen
, pad
, 2, ra
);
1119 set_length(env
, r1
+ 1, destlen
);
1120 set_length(env
, r3
+ 1, srclen
);
1121 set_address(env
, r1
, dest
);
1122 set_address(env
, r3
, src
);
1127 /* compare logical long helper */
1128 static inline uint32_t do_clcl(CPUS390XState
*env
,
1129 uint64_t *src1
, uint64_t *src1len
,
1130 uint64_t *src3
, uint64_t *src3len
,
1131 uint16_t pad
, uint64_t limit
,
1132 int wordsize
, uintptr_t ra
)
1134 uint64_t len
= MAX(*src1len
, *src3len
);
1137 check_alignment(env
, *src1len
| *src3len
, wordsize
, ra
);
1143 /* Lest we fail to service interrupts in a timely manner, limit the
1144 amount of work we're willing to do. */
1150 for (; len
; len
-= wordsize
) {
1155 v1
= cpu_ldusize_data_ra(env
, *src1
, wordsize
, ra
);
1158 v3
= cpu_ldusize_data_ra(env
, *src3
, wordsize
, ra
);
1162 cc
= (v1
< v3
) ? 1 : 2;
1168 *src1len
-= wordsize
;
1172 *src3len
-= wordsize
;
1180 /* compare logical long */
1181 uint32_t HELPER(clcl
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
)
1183 uintptr_t ra
= GETPC();
1184 uint64_t src1len
= extract64(env
->regs
[r1
+ 1], 0, 24);
1185 uint64_t src1
= get_address(env
, r1
);
1186 uint64_t src3len
= extract64(env
->regs
[r2
+ 1], 0, 24);
1187 uint64_t src3
= get_address(env
, r2
);
1188 uint8_t pad
= env
->regs
[r2
+ 1] >> 24;
1191 cc
= do_clcl(env
, &src1
, &src1len
, &src3
, &src3len
, pad
, -1, 1, ra
);
1193 env
->regs
[r1
+ 1] = deposit64(env
->regs
[r1
+ 1], 0, 24, src1len
);
1194 env
->regs
[r2
+ 1] = deposit64(env
->regs
[r2
+ 1], 0, 24, src3len
);
1195 set_address(env
, r1
, src1
);
1196 set_address(env
, r2
, src3
);
1201 /* compare logical long extended memcompare insn with padding */
1202 uint32_t HELPER(clcle
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
,
1205 uintptr_t ra
= GETPC();
1206 uint64_t src1len
= get_length(env
, r1
+ 1);
1207 uint64_t src1
= get_address(env
, r1
);
1208 uint64_t src3len
= get_length(env
, r3
+ 1);
1209 uint64_t src3
= get_address(env
, r3
);
1213 cc
= do_clcl(env
, &src1
, &src1len
, &src3
, &src3len
, pad
, 0x2000, 1, ra
);
1215 set_length(env
, r1
+ 1, src1len
);
1216 set_length(env
, r3
+ 1, src3len
);
1217 set_address(env
, r1
, src1
);
1218 set_address(env
, r3
, src3
);
1223 /* compare logical long unicode memcompare insn with padding */
1224 uint32_t HELPER(clclu
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
,
1227 uintptr_t ra
= GETPC();
1228 uint64_t src1len
= get_length(env
, r1
+ 1);
1229 uint64_t src1
= get_address(env
, r1
);
1230 uint64_t src3len
= get_length(env
, r3
+ 1);
1231 uint64_t src3
= get_address(env
, r3
);
1235 cc
= do_clcl(env
, &src1
, &src1len
, &src3
, &src3len
, pad
, 0x1000, 2, ra
);
1237 set_length(env
, r1
+ 1, src1len
);
1238 set_length(env
, r3
+ 1, src3len
);
1239 set_address(env
, r1
, src1
);
1240 set_address(env
, r3
, src3
);
1246 uint64_t HELPER(cksm
)(CPUS390XState
*env
, uint64_t r1
,
1247 uint64_t src
, uint64_t src_len
)
1249 uintptr_t ra
= GETPC();
1250 uint64_t max_len
, len
;
1251 uint64_t cksm
= (uint32_t)r1
;
1253 /* Lest we fail to service interrupts in a timely manner, limit the
1254 amount of work we're willing to do. For now, let's cap at 8k. */
1255 max_len
= (src_len
> 0x2000 ? 0x2000 : src_len
);
1257 /* Process full words as available. */
1258 for (len
= 0; len
+ 4 <= max_len
; len
+= 4, src
+= 4) {
1259 cksm
+= (uint32_t)cpu_ldl_data_ra(env
, src
, ra
);
1262 switch (max_len
- len
) {
1264 cksm
+= cpu_ldub_data_ra(env
, src
, ra
) << 24;
1268 cksm
+= cpu_lduw_data_ra(env
, src
, ra
) << 16;
1272 cksm
+= cpu_lduw_data_ra(env
, src
, ra
) << 16;
1273 cksm
+= cpu_ldub_data_ra(env
, src
+ 2, ra
) << 8;
1278 /* Fold the carry from the checksum. Note that we can see carry-out
1279 during folding more than once (but probably not more than twice). */
1280 while (cksm
> 0xffffffffull
) {
1281 cksm
= (uint32_t)cksm
+ (cksm
>> 32);
1284 /* Indicate whether or not we've processed everything. */
1285 env
->cc_op
= (len
== src_len
? 0 : 3);
1287 /* Return both cksm and processed length. */
1292 void HELPER(pack
)(CPUS390XState
*env
, uint32_t len
, uint64_t dest
, uint64_t src
)
1294 uintptr_t ra
= GETPC();
1295 int len_dest
= len
>> 4;
1296 int len_src
= len
& 0xf;
1302 /* last byte is special, it only flips the nibbles */
1303 b
= cpu_ldub_data_ra(env
, src
, ra
);
1304 cpu_stb_data_ra(env
, dest
, (b
<< 4) | (b
>> 4), ra
);
1308 /* now pack every value */
1309 while (len_dest
> 0) {
1313 b
= cpu_ldub_data_ra(env
, src
, ra
) & 0x0f;
1318 b
|= cpu_ldub_data_ra(env
, src
, ra
) << 4;
1325 cpu_stb_data_ra(env
, dest
, b
, ra
);
1329 static inline void do_pkau(CPUS390XState
*env
, uint64_t dest
, uint64_t src
,
1330 uint32_t srclen
, int ssize
, uintptr_t ra
)
1333 /* The destination operand is always 16 bytes long. */
1334 const int destlen
= 16;
1336 /* The operands are processed from right to left. */
1338 dest
+= destlen
- 1;
1340 for (i
= 0; i
< destlen
; i
++) {
1343 /* Start with a positive sign */
1346 } else if (srclen
> ssize
) {
1347 b
= cpu_ldub_data_ra(env
, src
, ra
) & 0x0f;
1352 if (srclen
> ssize
) {
1353 b
|= cpu_ldub_data_ra(env
, src
, ra
) << 4;
1358 cpu_stb_data_ra(env
, dest
, b
, ra
);
1364 void HELPER(pka
)(CPUS390XState
*env
, uint64_t dest
, uint64_t src
,
1367 do_pkau(env
, dest
, src
, srclen
, 1, GETPC());
1370 void HELPER(pku
)(CPUS390XState
*env
, uint64_t dest
, uint64_t src
,
1373 do_pkau(env
, dest
, src
, srclen
, 2, GETPC());
1376 void HELPER(unpk
)(CPUS390XState
*env
, uint32_t len
, uint64_t dest
,
1379 uintptr_t ra
= GETPC();
1380 int len_dest
= len
>> 4;
1381 int len_src
= len
& 0xf;
1383 int second_nibble
= 0;
1388 /* last byte is special, it only flips the nibbles */
1389 b
= cpu_ldub_data_ra(env
, src
, ra
);
1390 cpu_stb_data_ra(env
, dest
, (b
<< 4) | (b
>> 4), ra
);
1394 /* now pad every nibble with 0xf0 */
1396 while (len_dest
> 0) {
1397 uint8_t cur_byte
= 0;
1400 cur_byte
= cpu_ldub_data_ra(env
, src
, ra
);
1406 /* only advance one nibble at a time */
1407 if (second_nibble
) {
1412 second_nibble
= !second_nibble
;
1415 cur_byte
= (cur_byte
& 0xf);
1419 cpu_stb_data_ra(env
, dest
, cur_byte
, ra
);
1423 static inline uint32_t do_unpkau(CPUS390XState
*env
, uint64_t dest
,
1424 uint32_t destlen
, int dsize
, uint64_t src
,
1430 /* The source operand is always 16 bytes long. */
1431 const int srclen
= 16;
1433 /* The operands are processed from right to left. */
1435 dest
+= destlen
- dsize
;
1437 /* Check for the sign. */
1438 b
= cpu_ldub_data_ra(env
, src
, ra
);
1452 cc
= 3; /* invalid */
1456 /* Now pad every nibble with 0x30, advancing one nibble at a time. */
1457 for (i
= 0; i
< destlen
; i
+= dsize
) {
1458 if (i
== (31 * dsize
)) {
1459 /* If length is 32/64 bytes, the leftmost byte is 0. */
1461 } else if (i
% (2 * dsize
)) {
1462 b
= cpu_ldub_data_ra(env
, src
, ra
);
1467 cpu_stsize_data_ra(env
, dest
, 0x30 + (b
& 0xf), dsize
, ra
);
1474 uint32_t HELPER(unpka
)(CPUS390XState
*env
, uint64_t dest
, uint32_t destlen
,
1477 return do_unpkau(env
, dest
, destlen
, 1, src
, GETPC());
1480 uint32_t HELPER(unpku
)(CPUS390XState
*env
, uint64_t dest
, uint32_t destlen
,
1483 return do_unpkau(env
, dest
, destlen
, 2, src
, GETPC());
1486 uint32_t HELPER(tp
)(CPUS390XState
*env
, uint64_t dest
, uint32_t destlen
)
1488 uintptr_t ra
= GETPC();
1492 for (i
= 0; i
< destlen
; i
++) {
1493 uint8_t b
= cpu_ldub_data_ra(env
, dest
+ i
, ra
);
1495 cc
|= (b
& 0xf0) > 0x90 ? 2 : 0;
1497 if (i
== (destlen
- 1)) {
1499 cc
|= (b
& 0xf) < 0xa ? 1 : 0;
1502 cc
|= (b
& 0xf) > 0x9 ? 2 : 0;
1509 static uint32_t do_helper_tr(CPUS390XState
*env
, uint32_t len
, uint64_t array
,
1510 uint64_t trans
, uintptr_t ra
)
1514 for (i
= 0; i
<= len
; i
++) {
1515 uint8_t byte
= cpu_ldub_data_ra(env
, array
+ i
, ra
);
1516 uint8_t new_byte
= cpu_ldub_data_ra(env
, trans
+ byte
, ra
);
1517 cpu_stb_data_ra(env
, array
+ i
, new_byte
, ra
);
1523 void HELPER(tr
)(CPUS390XState
*env
, uint32_t len
, uint64_t array
,
1526 do_helper_tr(env
, len
, array
, trans
, GETPC());
1529 uint64_t HELPER(tre
)(CPUS390XState
*env
, uint64_t array
,
1530 uint64_t len
, uint64_t trans
)
1532 uintptr_t ra
= GETPC();
1533 uint8_t end
= env
->regs
[0] & 0xff;
1538 if (!(env
->psw
.mask
& PSW_MASK_64
)) {
1539 array
&= 0x7fffffff;
1543 /* Lest we fail to service interrupts in a timely manner, limit the
1544 amount of work we're willing to do. For now, let's cap at 8k. */
1550 for (i
= 0; i
< l
; i
++) {
1551 uint8_t byte
, new_byte
;
1553 byte
= cpu_ldub_data_ra(env
, array
+ i
, ra
);
1560 new_byte
= cpu_ldub_data_ra(env
, trans
+ byte
, ra
);
1561 cpu_stb_data_ra(env
, array
+ i
, new_byte
, ra
);
1565 env
->retxl
= len
- i
;
1569 static inline uint32_t do_helper_trt(CPUS390XState
*env
, int len
,
1570 uint64_t array
, uint64_t trans
,
1571 int inc
, uintptr_t ra
)
1575 for (i
= 0; i
<= len
; i
++) {
1576 uint8_t byte
= cpu_ldub_data_ra(env
, array
+ i
* inc
, ra
);
1577 uint8_t sbyte
= cpu_ldub_data_ra(env
, trans
+ byte
, ra
);
1580 set_address(env
, 1, array
+ i
* inc
);
1581 env
->regs
[2] = deposit64(env
->regs
[2], 0, 8, sbyte
);
1582 return (i
== len
) ? 2 : 1;
1589 static uint32_t do_helper_trt_fwd(CPUS390XState
*env
, uint32_t len
,
1590 uint64_t array
, uint64_t trans
,
1593 return do_helper_trt(env
, len
, array
, trans
, 1, ra
);
1596 uint32_t HELPER(trt
)(CPUS390XState
*env
, uint32_t len
, uint64_t array
,
1599 return do_helper_trt(env
, len
, array
, trans
, 1, GETPC());
1602 static uint32_t do_helper_trt_bkwd(CPUS390XState
*env
, uint32_t len
,
1603 uint64_t array
, uint64_t trans
,
1606 return do_helper_trt(env
, len
, array
, trans
, -1, ra
);
1609 uint32_t HELPER(trtr
)(CPUS390XState
*env
, uint32_t len
, uint64_t array
,
1612 return do_helper_trt(env
, len
, array
, trans
, -1, GETPC());
1615 /* Translate one/two to one/two */
1616 uint32_t HELPER(trXX
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
,
1617 uint32_t tst
, uint32_t sizes
)
1619 uintptr_t ra
= GETPC();
1620 int dsize
= (sizes
& 1) ? 1 : 2;
1621 int ssize
= (sizes
& 2) ? 1 : 2;
1622 uint64_t tbl
= get_address(env
, 1);
1623 uint64_t dst
= get_address(env
, r1
);
1624 uint64_t len
= get_length(env
, r1
+ 1);
1625 uint64_t src
= get_address(env
, r2
);
1629 /* The lower address bits of TBL are ignored. For TROO, TROT, it's
1630 the low 3 bits (double-word aligned). For TRTO, TRTT, it's either
1631 the low 12 bits (4K, without ETF2-ENH) or 3 bits (with ETF2-ENH). */
1632 if (ssize
== 2 && !s390_has_feat(S390_FEAT_ETF2_ENH
)) {
1638 check_alignment(env
, len
, ssize
, ra
);
1640 /* Lest we fail to service interrupts in a timely manner, */
1641 /* limit the amount of work we're willing to do. */
1642 for (i
= 0; i
< 0x2000; i
++) {
1643 uint16_t sval
= cpu_ldusize_data_ra(env
, src
, ssize
, ra
);
1644 uint64_t tble
= tbl
+ (sval
* dsize
);
1645 uint16_t dval
= cpu_ldusize_data_ra(env
, tble
, dsize
, ra
);
1650 cpu_stsize_data_ra(env
, dst
, dval
, dsize
, ra
);
1662 set_address(env
, r1
, dst
);
1663 set_length(env
, r1
+ 1, len
);
1664 set_address(env
, r2
, src
);
1669 void HELPER(cdsg
)(CPUS390XState
*env
, uint64_t addr
,
1670 uint32_t r1
, uint32_t r3
)
1672 uintptr_t ra
= GETPC();
1673 Int128 cmpv
= int128_make128(env
->regs
[r1
+ 1], env
->regs
[r1
]);
1674 Int128 newv
= int128_make128(env
->regs
[r3
+ 1], env
->regs
[r3
]);
1676 uint64_t oldh
, oldl
;
1679 check_alignment(env
, addr
, 16, ra
);
1681 oldh
= cpu_ldq_data_ra(env
, addr
+ 0, ra
);
1682 oldl
= cpu_ldq_data_ra(env
, addr
+ 8, ra
);
1684 oldv
= int128_make128(oldl
, oldh
);
1685 fail
= !int128_eq(oldv
, cmpv
);
1690 cpu_stq_data_ra(env
, addr
+ 0, int128_gethi(newv
), ra
);
1691 cpu_stq_data_ra(env
, addr
+ 8, int128_getlo(newv
), ra
);
1694 env
->regs
[r1
] = int128_gethi(oldv
);
1695 env
->regs
[r1
+ 1] = int128_getlo(oldv
);
1698 void HELPER(cdsg_parallel
)(CPUS390XState
*env
, uint64_t addr
,
1699 uint32_t r1
, uint32_t r3
)
1701 uintptr_t ra
= GETPC();
1702 Int128 cmpv
= int128_make128(env
->regs
[r1
+ 1], env
->regs
[r1
]);
1703 Int128 newv
= int128_make128(env
->regs
[r3
+ 1], env
->regs
[r3
]);
1709 assert(HAVE_CMPXCHG128
);
1711 mem_idx
= cpu_mmu_index(env
, false);
1712 oi
= make_memop_idx(MO_TEQ
| MO_ALIGN_16
, mem_idx
);
1713 oldv
= helper_atomic_cmpxchgo_be_mmu(env
, addr
, cmpv
, newv
, oi
, ra
);
1714 fail
= !int128_eq(oldv
, cmpv
);
1717 env
->regs
[r1
] = int128_gethi(oldv
);
1718 env
->regs
[r1
+ 1] = int128_getlo(oldv
);
1721 static uint32_t do_csst(CPUS390XState
*env
, uint32_t r3
, uint64_t a1
,
1722 uint64_t a2
, bool parallel
)
1724 uint32_t mem_idx
= cpu_mmu_index(env
, false);
1725 uintptr_t ra
= GETPC();
1726 uint32_t fc
= extract32(env
->regs
[0], 0, 8);
1727 uint32_t sc
= extract32(env
->regs
[0], 8, 8);
1728 uint64_t pl
= get_address(env
, 1) & -16;
1732 /* Sanity check the function code and storage characteristic. */
1733 if (fc
> 1 || sc
> 3) {
1734 if (!s390_has_feat(S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2
)) {
1735 goto spec_exception
;
1737 if (fc
> 2 || sc
> 4 || (fc
== 2 && (r3
& 1))) {
1738 goto spec_exception
;
1742 /* Sanity check the alignments. */
1743 if (extract32(a1
, 0, fc
+ 2) || extract32(a2
, 0, sc
)) {
1744 goto spec_exception
;
1747 /* Sanity check writability of the store address. */
1748 probe_write(env
, a2
, 1 << sc
, mem_idx
, ra
);
1751 * Note that the compare-and-swap is atomic, and the store is atomic,
1752 * but the complete operation is not. Therefore we do not need to
1753 * assert serial context in order to implement this. That said,
1754 * restart early if we can't support either operation that is supposed
1759 #ifdef CONFIG_ATOMIC64
1762 if ((HAVE_CMPXCHG128
? 0 : fc
+ 2 > max
) ||
1763 (HAVE_ATOMIC128
? 0 : sc
> max
)) {
1764 cpu_loop_exit_atomic(env_cpu(env
), ra
);
1768 /* All loads happen before all stores. For simplicity, load the entire
1769 store value area from the parameter list. */
1770 svh
= cpu_ldq_data_ra(env
, pl
+ 16, ra
);
1771 svl
= cpu_ldq_data_ra(env
, pl
+ 24, ra
);
1776 uint32_t nv
= cpu_ldl_data_ra(env
, pl
, ra
);
1777 uint32_t cv
= env
->regs
[r3
];
1781 #ifdef CONFIG_USER_ONLY
1782 uint32_t *haddr
= g2h(a1
);
1783 ov
= atomic_cmpxchg__nocheck(haddr
, cv
, nv
);
1785 TCGMemOpIdx oi
= make_memop_idx(MO_TEUL
| MO_ALIGN
, mem_idx
);
1786 ov
= helper_atomic_cmpxchgl_be_mmu(env
, a1
, cv
, nv
, oi
, ra
);
1789 ov
= cpu_ldl_data_ra(env
, a1
, ra
);
1790 cpu_stl_data_ra(env
, a1
, (ov
== cv
? nv
: ov
), ra
);
1793 env
->regs
[r3
] = deposit64(env
->regs
[r3
], 32, 32, ov
);
1799 uint64_t nv
= cpu_ldq_data_ra(env
, pl
, ra
);
1800 uint64_t cv
= env
->regs
[r3
];
1804 #ifdef CONFIG_ATOMIC64
1805 # ifdef CONFIG_USER_ONLY
1806 uint64_t *haddr
= g2h(a1
);
1807 ov
= atomic_cmpxchg__nocheck(haddr
, cv
, nv
);
1809 TCGMemOpIdx oi
= make_memop_idx(MO_TEQ
| MO_ALIGN
, mem_idx
);
1810 ov
= helper_atomic_cmpxchgq_be_mmu(env
, a1
, cv
, nv
, oi
, ra
);
1813 /* Note that we asserted !parallel above. */
1814 g_assert_not_reached();
1817 ov
= cpu_ldq_data_ra(env
, a1
, ra
);
1818 cpu_stq_data_ra(env
, a1
, (ov
== cv
? nv
: ov
), ra
);
1827 uint64_t nvh
= cpu_ldq_data_ra(env
, pl
, ra
);
1828 uint64_t nvl
= cpu_ldq_data_ra(env
, pl
+ 8, ra
);
1829 Int128 nv
= int128_make128(nvl
, nvh
);
1830 Int128 cv
= int128_make128(env
->regs
[r3
+ 1], env
->regs
[r3
]);
1834 uint64_t oh
= cpu_ldq_data_ra(env
, a1
+ 0, ra
);
1835 uint64_t ol
= cpu_ldq_data_ra(env
, a1
+ 8, ra
);
1837 ov
= int128_make128(ol
, oh
);
1838 cc
= !int128_eq(ov
, cv
);
1843 cpu_stq_data_ra(env
, a1
+ 0, int128_gethi(nv
), ra
);
1844 cpu_stq_data_ra(env
, a1
+ 8, int128_getlo(nv
), ra
);
1845 } else if (HAVE_CMPXCHG128
) {
1846 TCGMemOpIdx oi
= make_memop_idx(MO_TEQ
| MO_ALIGN_16
, mem_idx
);
1847 ov
= helper_atomic_cmpxchgo_be_mmu(env
, a1
, cv
, nv
, oi
, ra
);
1848 cc
= !int128_eq(ov
, cv
);
1850 /* Note that we asserted !parallel above. */
1851 g_assert_not_reached();
1854 env
->regs
[r3
+ 0] = int128_gethi(ov
);
1855 env
->regs
[r3
+ 1] = int128_getlo(ov
);
1860 g_assert_not_reached();
1863 /* Store only if the comparison succeeded. Note that above we use a pair
1864 of 64-bit big-endian loads, so for sc < 3 we must extract the value
1865 from the most-significant bits of svh. */
1869 cpu_stb_data_ra(env
, a2
, svh
>> 56, ra
);
1872 cpu_stw_data_ra(env
, a2
, svh
>> 48, ra
);
1875 cpu_stl_data_ra(env
, a2
, svh
>> 32, ra
);
1878 cpu_stq_data_ra(env
, a2
, svh
, ra
);
1882 cpu_stq_data_ra(env
, a2
+ 0, svh
, ra
);
1883 cpu_stq_data_ra(env
, a2
+ 8, svl
, ra
);
1884 } else if (HAVE_ATOMIC128
) {
1885 TCGMemOpIdx oi
= make_memop_idx(MO_TEQ
| MO_ALIGN_16
, mem_idx
);
1886 Int128 sv
= int128_make128(svl
, svh
);
1887 helper_atomic_sto_be_mmu(env
, a2
, sv
, oi
, ra
);
1889 /* Note that we asserted !parallel above. */
1890 g_assert_not_reached();
1894 g_assert_not_reached();
1901 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
1904 uint32_t HELPER(csst
)(CPUS390XState
*env
, uint32_t r3
, uint64_t a1
, uint64_t a2
)
1906 return do_csst(env
, r3
, a1
, a2
, false);
1909 uint32_t HELPER(csst_parallel
)(CPUS390XState
*env
, uint32_t r3
, uint64_t a1
,
1912 return do_csst(env
, r3
, a1
, a2
, true);
1915 #if !defined(CONFIG_USER_ONLY)
1916 void HELPER(lctlg
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
1918 uintptr_t ra
= GETPC();
1919 bool PERchanged
= false;
1924 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
1927 for (i
= r1
;; i
= (i
+ 1) % 16) {
1928 uint64_t val
= cpu_ldq_data_ra(env
, src
, ra
);
1929 if (env
->cregs
[i
] != val
&& i
>= 9 && i
<= 11) {
1932 env
->cregs
[i
] = val
;
1933 HELPER_LOG("load ctl %d from 0x%" PRIx64
" == 0x%" PRIx64
"\n",
1935 src
+= sizeof(uint64_t);
1942 if (PERchanged
&& env
->psw
.mask
& PSW_MASK_PER
) {
1943 s390_cpu_recompute_watchpoints(env_cpu(env
));
1946 tlb_flush(env_cpu(env
));
1949 void HELPER(lctl
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
1951 uintptr_t ra
= GETPC();
1952 bool PERchanged
= false;
1957 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
1960 for (i
= r1
;; i
= (i
+ 1) % 16) {
1961 uint32_t val
= cpu_ldl_data_ra(env
, src
, ra
);
1962 if ((uint32_t)env
->cregs
[i
] != val
&& i
>= 9 && i
<= 11) {
1965 env
->cregs
[i
] = deposit64(env
->cregs
[i
], 0, 32, val
);
1966 HELPER_LOG("load ctl %d from 0x%" PRIx64
" == 0x%x\n", i
, src
, val
);
1967 src
+= sizeof(uint32_t);
1974 if (PERchanged
&& env
->psw
.mask
& PSW_MASK_PER
) {
1975 s390_cpu_recompute_watchpoints(env_cpu(env
));
1978 tlb_flush(env_cpu(env
));
1981 void HELPER(stctg
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
1983 uintptr_t ra
= GETPC();
1988 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
1991 for (i
= r1
;; i
= (i
+ 1) % 16) {
1992 cpu_stq_data_ra(env
, dest
, env
->cregs
[i
], ra
);
1993 dest
+= sizeof(uint64_t);
2001 void HELPER(stctl
)(CPUS390XState
*env
, uint32_t r1
, uint64_t a2
, uint32_t r3
)
2003 uintptr_t ra
= GETPC();
2008 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
2011 for (i
= r1
;; i
= (i
+ 1) % 16) {
2012 cpu_stl_data_ra(env
, dest
, env
->cregs
[i
], ra
);
2013 dest
+= sizeof(uint32_t);
2021 uint32_t HELPER(testblock
)(CPUS390XState
*env
, uint64_t real_addr
)
2023 uintptr_t ra
= GETPC();
2026 real_addr
= wrap_address(env
, real_addr
) & TARGET_PAGE_MASK
;
2028 for (i
= 0; i
< TARGET_PAGE_SIZE
; i
+= 8) {
2029 cpu_stq_mmuidx_ra(env
, real_addr
+ i
, 0, MMU_REAL_IDX
, ra
);
2035 uint32_t HELPER(tprot
)(CPUS390XState
*env
, uint64_t a1
, uint64_t a2
)
2037 S390CPU
*cpu
= env_archcpu(env
);
2038 CPUState
*cs
= env_cpu(env
);
2041 * TODO: we currently don't handle all access protection types
2042 * (including access-list and key-controlled) as well as AR mode.
2044 if (!s390_cpu_virt_mem_check_write(cpu
, a1
, 0, 1)) {
2045 /* Fetching permitted; storing permitted */
2049 if (env
->int_pgm_code
== PGM_PROTECTION
) {
2050 /* retry if reading is possible */
2051 cs
->exception_index
= -1;
2052 if (!s390_cpu_virt_mem_check_read(cpu
, a1
, 0, 1)) {
2053 /* Fetching permitted; storing not permitted */
2058 switch (env
->int_pgm_code
) {
2059 case PGM_PROTECTION
:
2060 /* Fetching not permitted; storing not permitted */
2061 cs
->exception_index
= -1;
2063 case PGM_ADDRESSING
:
2064 case PGM_TRANS_SPEC
:
2065 /* exceptions forwarded to the guest */
2066 s390_cpu_virt_mem_handle_exc(cpu
, GETPC());
2070 /* Translation not available */
2071 cs
->exception_index
= -1;
2075 /* insert storage key extended */
2076 uint64_t HELPER(iske
)(CPUS390XState
*env
, uint64_t r2
)
2078 static S390SKeysState
*ss
;
2079 static S390SKeysClass
*skeyclass
;
2080 uint64_t addr
= wrap_address(env
, r2
);
2083 if (addr
> ram_size
) {
2087 if (unlikely(!ss
)) {
2088 ss
= s390_get_skeys_device();
2089 skeyclass
= S390_SKEYS_GET_CLASS(ss
);
2092 if (skeyclass
->get_skeys(ss
, addr
/ TARGET_PAGE_SIZE
, 1, &key
)) {
2098 /* set storage key extended */
2099 void HELPER(sske
)(CPUS390XState
*env
, uint64_t r1
, uint64_t r2
)
2101 static S390SKeysState
*ss
;
2102 static S390SKeysClass
*skeyclass
;
2103 uint64_t addr
= wrap_address(env
, r2
);
2106 if (addr
> ram_size
) {
2110 if (unlikely(!ss
)) {
2111 ss
= s390_get_skeys_device();
2112 skeyclass
= S390_SKEYS_GET_CLASS(ss
);
2116 skeyclass
->set_skeys(ss
, addr
/ TARGET_PAGE_SIZE
, 1, &key
);
2118 * As we can only flush by virtual address and not all the entries
2119 * that point to a physical address we have to flush the whole TLB.
2121 tlb_flush_all_cpus_synced(env_cpu(env
));
2124 /* reset reference bit extended */
2125 uint32_t HELPER(rrbe
)(CPUS390XState
*env
, uint64_t r2
)
2127 static S390SKeysState
*ss
;
2128 static S390SKeysClass
*skeyclass
;
2131 if (r2
> ram_size
) {
2135 if (unlikely(!ss
)) {
2136 ss
= s390_get_skeys_device();
2137 skeyclass
= S390_SKEYS_GET_CLASS(ss
);
2140 if (skeyclass
->get_skeys(ss
, r2
/ TARGET_PAGE_SIZE
, 1, &key
)) {
2144 re
= key
& (SK_R
| SK_C
);
2147 if (skeyclass
->set_skeys(ss
, r2
/ TARGET_PAGE_SIZE
, 1, &key
)) {
2151 * As we can only flush by virtual address and not all the entries
2152 * that point to a physical address we have to flush the whole TLB.
2154 tlb_flush_all_cpus_synced(env_cpu(env
));
2159 * 0 Reference bit zero; change bit zero
2160 * 1 Reference bit zero; change bit one
2161 * 2 Reference bit one; change bit zero
2162 * 3 Reference bit one; change bit one
2168 uint32_t HELPER(mvcs
)(CPUS390XState
*env
, uint64_t l
, uint64_t a1
, uint64_t a2
)
2170 const uint8_t psw_as
= (env
->psw
.mask
& PSW_MASK_ASC
) >> PSW_SHIFT_ASC
;
2171 S390Access srca
, desta
;
2172 uintptr_t ra
= GETPC();
2175 HELPER_LOG("%s: %16" PRIx64
" %16" PRIx64
" %16" PRIx64
"\n",
2176 __func__
, l
, a1
, a2
);
2178 if (!(env
->psw
.mask
& PSW_MASK_DAT
) || !(env
->cregs
[0] & CR0_SECONDARY
) ||
2179 psw_as
== AS_HOME
|| psw_as
== AS_ACCREG
) {
2180 s390_program_interrupt(env
, PGM_SPECIAL_OP
, ra
);
2183 l
= wrap_length32(env
, l
);
2192 /* TODO: Access key handling */
2193 srca
= access_prepare(env
, a2
, l
, MMU_DATA_LOAD
, MMU_PRIMARY_IDX
, ra
);
2194 desta
= access_prepare(env
, a1
, l
, MMU_DATA_STORE
, MMU_SECONDARY_IDX
, ra
);
2195 access_memmove(env
, &desta
, &srca
, ra
);
2199 uint32_t HELPER(mvcp
)(CPUS390XState
*env
, uint64_t l
, uint64_t a1
, uint64_t a2
)
2201 const uint8_t psw_as
= (env
->psw
.mask
& PSW_MASK_ASC
) >> PSW_SHIFT_ASC
;
2202 S390Access srca
, desta
;
2203 uintptr_t ra
= GETPC();
2206 HELPER_LOG("%s: %16" PRIx64
" %16" PRIx64
" %16" PRIx64
"\n",
2207 __func__
, l
, a1
, a2
);
2209 if (!(env
->psw
.mask
& PSW_MASK_DAT
) || !(env
->cregs
[0] & CR0_SECONDARY
) ||
2210 psw_as
== AS_HOME
|| psw_as
== AS_ACCREG
) {
2211 s390_program_interrupt(env
, PGM_SPECIAL_OP
, ra
);
2214 l
= wrap_length32(env
, l
);
2223 /* TODO: Access key handling */
2224 srca
= access_prepare(env
, a2
, l
, MMU_DATA_LOAD
, MMU_SECONDARY_IDX
, ra
);
2225 desta
= access_prepare(env
, a1
, l
, MMU_DATA_STORE
, MMU_PRIMARY_IDX
, ra
);
2226 access_memmove(env
, &desta
, &srca
, ra
);
2230 void HELPER(idte
)(CPUS390XState
*env
, uint64_t r1
, uint64_t r2
, uint32_t m4
)
2232 CPUState
*cs
= env_cpu(env
);
2233 const uintptr_t ra
= GETPC();
2234 uint64_t table
, entry
, raddr
;
2235 uint16_t entries
, i
, index
= 0;
2238 tcg_s390_program_interrupt(env
, PGM_SPECIFICATION
, ra
);
2241 if (!(r2
& 0x800)) {
2242 /* invalidation-and-clearing operation */
2243 table
= r1
& ASCE_ORIGIN
;
2244 entries
= (r2
& 0x7ff) + 1;
2246 switch (r1
& ASCE_TYPE_MASK
) {
2247 case ASCE_TYPE_REGION1
:
2248 index
= (r2
>> 53) & 0x7ff;
2250 case ASCE_TYPE_REGION2
:
2251 index
= (r2
>> 42) & 0x7ff;
2253 case ASCE_TYPE_REGION3
:
2254 index
= (r2
>> 31) & 0x7ff;
2256 case ASCE_TYPE_SEGMENT
:
2257 index
= (r2
>> 20) & 0x7ff;
2260 for (i
= 0; i
< entries
; i
++) {
2261 /* addresses are not wrapped in 24/31bit mode but table index is */
2262 raddr
= table
+ ((index
+ i
) & 0x7ff) * sizeof(entry
);
2263 entry
= cpu_ldq_mmuidx_ra(env
, raddr
, MMU_REAL_IDX
, ra
);
2264 if (!(entry
& REGION_ENTRY_I
)) {
2265 /* we are allowed to not store if already invalid */
2266 entry
|= REGION_ENTRY_I
;
2267 cpu_stq_mmuidx_ra(env
, raddr
, entry
, MMU_REAL_IDX
, ra
);
2272 /* We simply flush the complete tlb, therefore we can ignore r3. */
2276 tlb_flush_all_cpus_synced(cs
);
2280 /* invalidate pte */
2281 void HELPER(ipte
)(CPUS390XState
*env
, uint64_t pto
, uint64_t vaddr
,
2284 CPUState
*cs
= env_cpu(env
);
2285 const uintptr_t ra
= GETPC();
2286 uint64_t page
= vaddr
& TARGET_PAGE_MASK
;
2287 uint64_t pte_addr
, pte
;
2289 /* Compute the page table entry address */
2290 pte_addr
= (pto
& SEGMENT_ENTRY_ORIGIN
);
2291 pte_addr
+= VADDR_PAGE_TX(vaddr
) * 8;
2293 /* Mark the page table entry as invalid */
2294 pte
= cpu_ldq_mmuidx_ra(env
, pte_addr
, MMU_REAL_IDX
, ra
);
2295 pte
|= PAGE_ENTRY_I
;
2296 cpu_stq_mmuidx_ra(env
, pte_addr
, pte
, MMU_REAL_IDX
, ra
);
2298 /* XXX we exploit the fact that Linux passes the exact virtual
2299 address here - it's not obliged to! */
2301 if (vaddr
& ~VADDR_PAGE_TX_MASK
) {
2302 tlb_flush_page(cs
, page
);
2303 /* XXX 31-bit hack */
2304 tlb_flush_page(cs
, page
^ 0x80000000);
2306 /* looks like we don't have a valid virtual address */
2310 if (vaddr
& ~VADDR_PAGE_TX_MASK
) {
2311 tlb_flush_page_all_cpus_synced(cs
, page
);
2312 /* XXX 31-bit hack */
2313 tlb_flush_page_all_cpus_synced(cs
, page
^ 0x80000000);
2315 /* looks like we don't have a valid virtual address */
2316 tlb_flush_all_cpus_synced(cs
);
2321 /* flush local tlb */
2322 void HELPER(ptlb
)(CPUS390XState
*env
)
2324 tlb_flush(env_cpu(env
));
2327 /* flush global tlb */
2328 void HELPER(purge
)(CPUS390XState
*env
)
2330 tlb_flush_all_cpus_synced(env_cpu(env
));
2333 /* load real address */
2334 uint64_t HELPER(lra
)(CPUS390XState
*env
, uint64_t addr
)
2336 uint64_t asc
= env
->psw
.mask
& PSW_MASK_ASC
;
2340 /* XXX incomplete - has more corner cases */
2341 if (!(env
->psw
.mask
& PSW_MASK_64
) && (addr
>> 32)) {
2342 tcg_s390_program_interrupt(env
, PGM_SPECIAL_OP
, GETPC());
2345 exc
= mmu_translate(env
, addr
, 0, asc
, &ret
, &flags
, &tec
);
2348 ret
= exc
| 0x80000000;
2351 ret
|= addr
& ~TARGET_PAGE_MASK
;
2359 /* load pair from quadword */
2360 uint64_t HELPER(lpq
)(CPUS390XState
*env
, uint64_t addr
)
2362 uintptr_t ra
= GETPC();
2365 check_alignment(env
, addr
, 16, ra
);
2366 hi
= cpu_ldq_data_ra(env
, addr
+ 0, ra
);
2367 lo
= cpu_ldq_data_ra(env
, addr
+ 8, ra
);
2373 uint64_t HELPER(lpq_parallel
)(CPUS390XState
*env
, uint64_t addr
)
2375 uintptr_t ra
= GETPC();
2381 assert(HAVE_ATOMIC128
);
2383 mem_idx
= cpu_mmu_index(env
, false);
2384 oi
= make_memop_idx(MO_TEQ
| MO_ALIGN_16
, mem_idx
);
2385 v
= helper_atomic_ldo_be_mmu(env
, addr
, oi
, ra
);
2386 hi
= int128_gethi(v
);
2387 lo
= int128_getlo(v
);
2393 /* store pair to quadword */
2394 void HELPER(stpq
)(CPUS390XState
*env
, uint64_t addr
,
2395 uint64_t low
, uint64_t high
)
2397 uintptr_t ra
= GETPC();
2399 check_alignment(env
, addr
, 16, ra
);
2400 cpu_stq_data_ra(env
, addr
+ 0, high
, ra
);
2401 cpu_stq_data_ra(env
, addr
+ 8, low
, ra
);
2404 void HELPER(stpq_parallel
)(CPUS390XState
*env
, uint64_t addr
,
2405 uint64_t low
, uint64_t high
)
2407 uintptr_t ra
= GETPC();
2412 assert(HAVE_ATOMIC128
);
2414 mem_idx
= cpu_mmu_index(env
, false);
2415 oi
= make_memop_idx(MO_TEQ
| MO_ALIGN_16
, mem_idx
);
2416 v
= int128_make128(low
, high
);
2417 helper_atomic_sto_be_mmu(env
, addr
, v
, oi
, ra
);
2420 /* Execute instruction. This instruction executes an insn modified with
2421 the contents of r1. It does not change the executed instruction in memory;
2422 it does not change the program counter.
2424 Perform this by recording the modified instruction in env->ex_value.
2425 This will be noticed by cpu_get_tb_cpu_state and thus tb translation.
2427 void HELPER(ex
)(CPUS390XState
*env
, uint32_t ilen
, uint64_t r1
, uint64_t addr
)
2429 uint64_t insn
= cpu_lduw_code(env
, addr
);
2430 uint8_t opc
= insn
>> 8;
2432 /* Or in the contents of R1[56:63]. */
2435 /* Load the rest of the instruction. */
2437 switch (get_ilen(opc
)) {
2441 insn
|= (uint64_t)cpu_lduw_code(env
, addr
+ 2) << 32;
2444 insn
|= (uint64_t)(uint32_t)cpu_ldl_code(env
, addr
+ 2) << 16;
2447 g_assert_not_reached();
2450 /* The very most common cases can be sped up by avoiding a new TB. */
2451 if ((opc
& 0xf0) == 0xd0) {
2452 typedef uint32_t (*dx_helper
)(CPUS390XState
*, uint32_t, uint64_t,
2453 uint64_t, uintptr_t);
2454 static const dx_helper dx
[16] = {
2455 [0x0] = do_helper_trt_bkwd
,
2456 [0x2] = do_helper_mvc
,
2457 [0x4] = do_helper_nc
,
2458 [0x5] = do_helper_clc
,
2459 [0x6] = do_helper_oc
,
2460 [0x7] = do_helper_xc
,
2461 [0xc] = do_helper_tr
,
2462 [0xd] = do_helper_trt_fwd
,
2464 dx_helper helper
= dx
[opc
& 0xf];
2467 uint32_t l
= extract64(insn
, 48, 8);
2468 uint32_t b1
= extract64(insn
, 44, 4);
2469 uint32_t d1
= extract64(insn
, 32, 12);
2470 uint32_t b2
= extract64(insn
, 28, 4);
2471 uint32_t d2
= extract64(insn
, 16, 12);
2472 uint64_t a1
= wrap_address(env
, env
->regs
[b1
] + d1
);
2473 uint64_t a2
= wrap_address(env
, env
->regs
[b2
] + d2
);
2475 env
->cc_op
= helper(env
, l
, a1
, a2
, 0);
2476 env
->psw
.addr
+= ilen
;
2479 } else if (opc
== 0x0a) {
2480 env
->int_svc_code
= extract64(insn
, 48, 8);
2481 env
->int_svc_ilen
= ilen
;
2482 helper_exception(env
, EXCP_SVC
);
2483 g_assert_not_reached();
2486 /* Record the insn we want to execute as well as the ilen to use
2487 during the execution of the target insn. This will also ensure
2488 that ex_value is non-zero, which flags that we are in a state
2489 that requires such execution. */
2490 env
->ex_value
= insn
| ilen
;
2493 uint32_t HELPER(mvcos
)(CPUS390XState
*env
, uint64_t dest
, uint64_t src
,
2496 const uint8_t psw_key
= (env
->psw
.mask
& PSW_MASK_KEY
) >> PSW_SHIFT_KEY
;
2497 const uint8_t psw_as
= (env
->psw
.mask
& PSW_MASK_ASC
) >> PSW_SHIFT_ASC
;
2498 const uint64_t r0
= env
->regs
[0];
2499 const uintptr_t ra
= GETPC();
2500 uint8_t dest_key
, dest_as
, dest_k
, dest_a
;
2501 uint8_t src_key
, src_as
, src_k
, src_a
;
2505 HELPER_LOG("%s dest %" PRIx64
", src %" PRIx64
", len %" PRIx64
"\n",
2506 __func__
, dest
, src
, len
);
2508 if (!(env
->psw
.mask
& PSW_MASK_DAT
)) {
2509 tcg_s390_program_interrupt(env
, PGM_SPECIAL_OP
, ra
);
2512 /* OAC (operand access control) for the first operand -> dest */
2513 val
= (r0
& 0xffff0000ULL
) >> 16;
2514 dest_key
= (val
>> 12) & 0xf;
2515 dest_as
= (val
>> 6) & 0x3;
2516 dest_k
= (val
>> 1) & 0x1;
2519 /* OAC (operand access control) for the second operand -> src */
2520 val
= (r0
& 0x0000ffffULL
);
2521 src_key
= (val
>> 12) & 0xf;
2522 src_as
= (val
>> 6) & 0x3;
2523 src_k
= (val
>> 1) & 0x1;
2539 if (dest_a
&& dest_as
== AS_HOME
&& (env
->psw
.mask
& PSW_MASK_PSTATE
)) {
2540 tcg_s390_program_interrupt(env
, PGM_SPECIAL_OP
, ra
);
2542 if (!(env
->cregs
[0] & CR0_SECONDARY
) &&
2543 (dest_as
== AS_SECONDARY
|| src_as
== AS_SECONDARY
)) {
2544 tcg_s390_program_interrupt(env
, PGM_SPECIAL_OP
, ra
);
2546 if (!psw_key_valid(env
, dest_key
) || !psw_key_valid(env
, src_key
)) {
2547 tcg_s390_program_interrupt(env
, PGM_PRIVILEGED
, ra
);
2550 len
= wrap_length32(env
, len
);
2556 /* FIXME: AR-mode and proper problem state mode (using PSW keys) missing */
2557 if (src_as
== AS_ACCREG
|| dest_as
== AS_ACCREG
||
2558 (env
->psw
.mask
& PSW_MASK_PSTATE
)) {
2559 qemu_log_mask(LOG_UNIMP
, "%s: AR-mode and PSTATE support missing\n",
2561 tcg_s390_program_interrupt(env
, PGM_ADDRESSING
, ra
);
2564 /* FIXME: Access using correct keys and AR-mode */
2566 S390Access srca
= access_prepare(env
, src
, len
, MMU_DATA_LOAD
,
2567 mmu_idx_from_as(src_as
), ra
);
2568 S390Access desta
= access_prepare(env
, dest
, len
, MMU_DATA_STORE
,
2569 mmu_idx_from_as(dest_as
), ra
);
2571 access_memmove(env
, &desta
, &srca
, ra
);
2577 /* Decode a Unicode character. A return value < 0 indicates success, storing
2578 the UTF-32 result into OCHAR and the input length into OLEN. A return
2579 value >= 0 indicates failure, and the CC value to be returned. */
2580 typedef int (*decode_unicode_fn
)(CPUS390XState
*env
, uint64_t addr
,
2581 uint64_t ilen
, bool enh_check
, uintptr_t ra
,
2582 uint32_t *ochar
, uint32_t *olen
);
2584 /* Encode a Unicode character. A return value < 0 indicates success, storing
2585 the bytes into ADDR and the output length into OLEN. A return value >= 0
2586 indicates failure, and the CC value to be returned. */
2587 typedef int (*encode_unicode_fn
)(CPUS390XState
*env
, uint64_t addr
,
2588 uint64_t ilen
, uintptr_t ra
, uint32_t c
,
2591 static int decode_utf8(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2592 bool enh_check
, uintptr_t ra
,
2593 uint32_t *ochar
, uint32_t *olen
)
2595 uint8_t s0
, s1
, s2
, s3
;
2601 s0
= cpu_ldub_data_ra(env
, addr
, ra
);
2603 /* one byte character */
2606 } else if (s0
<= (enh_check
? 0xc1 : 0xbf)) {
2607 /* invalid character */
2609 } else if (s0
<= 0xdf) {
2610 /* two byte character */
2615 s1
= cpu_ldub_data_ra(env
, addr
+ 1, ra
);
2617 c
= (c
<< 6) | (s1
& 0x3f);
2618 if (enh_check
&& (s1
& 0xc0) != 0x80) {
2621 } else if (s0
<= 0xef) {
2622 /* three byte character */
2627 s1
= cpu_ldub_data_ra(env
, addr
+ 1, ra
);
2628 s2
= cpu_ldub_data_ra(env
, addr
+ 2, ra
);
2630 c
= (c
<< 6) | (s1
& 0x3f);
2631 c
= (c
<< 6) | (s2
& 0x3f);
2632 /* Fold the byte-by-byte range descriptions in the PoO into
2633 tests against the complete value. It disallows encodings
2634 that could be smaller, and the UTF-16 surrogates. */
2636 && ((s1
& 0xc0) != 0x80
2637 || (s2
& 0xc0) != 0x80
2639 || (c
>= 0xd800 && c
<= 0xdfff))) {
2642 } else if (s0
<= (enh_check
? 0xf4 : 0xf7)) {
2643 /* four byte character */
2648 s1
= cpu_ldub_data_ra(env
, addr
+ 1, ra
);
2649 s2
= cpu_ldub_data_ra(env
, addr
+ 2, ra
);
2650 s3
= cpu_ldub_data_ra(env
, addr
+ 3, ra
);
2652 c
= (c
<< 6) | (s1
& 0x3f);
2653 c
= (c
<< 6) | (s2
& 0x3f);
2654 c
= (c
<< 6) | (s3
& 0x3f);
2657 && ((s1
& 0xc0) != 0x80
2658 || (s2
& 0xc0) != 0x80
2659 || (s3
& 0xc0) != 0x80
2665 /* invalid character */
2674 static int decode_utf16(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2675 bool enh_check
, uintptr_t ra
,
2676 uint32_t *ochar
, uint32_t *olen
)
2684 s0
= cpu_lduw_data_ra(env
, addr
, ra
);
2685 if ((s0
& 0xfc00) != 0xd800) {
2686 /* one word character */
2690 /* two word character */
2695 s1
= cpu_lduw_data_ra(env
, addr
+ 2, ra
);
2696 c
= extract32(s0
, 6, 4) + 1;
2697 c
= (c
<< 6) | (s0
& 0x3f);
2698 c
= (c
<< 10) | (s1
& 0x3ff);
2699 if (enh_check
&& (s1
& 0xfc00) != 0xdc00) {
2700 /* invalid surrogate character */
2710 static int decode_utf32(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2711 bool enh_check
, uintptr_t ra
,
2712 uint32_t *ochar
, uint32_t *olen
)
2719 c
= cpu_ldl_data_ra(env
, addr
, ra
);
2720 if ((c
>= 0xd800 && c
<= 0xdbff) || c
> 0x10ffff) {
2721 /* invalid unicode character */
2730 static int encode_utf8(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2731 uintptr_t ra
, uint32_t c
, uint32_t *olen
)
2737 /* one byte character */
2740 } else if (c
<= 0x7ff) {
2741 /* two byte character */
2743 d
[1] = 0x80 | extract32(c
, 0, 6);
2744 d
[0] = 0xc0 | extract32(c
, 6, 5);
2745 } else if (c
<= 0xffff) {
2746 /* three byte character */
2748 d
[2] = 0x80 | extract32(c
, 0, 6);
2749 d
[1] = 0x80 | extract32(c
, 6, 6);
2750 d
[0] = 0xe0 | extract32(c
, 12, 4);
2752 /* four byte character */
2754 d
[3] = 0x80 | extract32(c
, 0, 6);
2755 d
[2] = 0x80 | extract32(c
, 6, 6);
2756 d
[1] = 0x80 | extract32(c
, 12, 6);
2757 d
[0] = 0xf0 | extract32(c
, 18, 3);
2763 for (i
= 0; i
< l
; ++i
) {
2764 cpu_stb_data_ra(env
, addr
+ i
, d
[i
], ra
);
2771 static int encode_utf16(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2772 uintptr_t ra
, uint32_t c
, uint32_t *olen
)
2777 /* one word character */
2781 cpu_stw_data_ra(env
, addr
, c
, ra
);
2784 /* two word character */
2788 d1
= 0xdc00 | extract32(c
, 0, 10);
2789 d0
= 0xd800 | extract32(c
, 10, 6);
2790 d0
= deposit32(d0
, 6, 4, extract32(c
, 16, 5) - 1);
2791 cpu_stw_data_ra(env
, addr
+ 0, d0
, ra
);
2792 cpu_stw_data_ra(env
, addr
+ 2, d1
, ra
);
2799 static int encode_utf32(CPUS390XState
*env
, uint64_t addr
, uint64_t ilen
,
2800 uintptr_t ra
, uint32_t c
, uint32_t *olen
)
2805 cpu_stl_data_ra(env
, addr
, c
, ra
);
2810 static inline uint32_t convert_unicode(CPUS390XState
*env
, uint32_t r1
,
2811 uint32_t r2
, uint32_t m3
, uintptr_t ra
,
2812 decode_unicode_fn decode
,
2813 encode_unicode_fn encode
)
2815 uint64_t dst
= get_address(env
, r1
);
2816 uint64_t dlen
= get_length(env
, r1
+ 1);
2817 uint64_t src
= get_address(env
, r2
);
2818 uint64_t slen
= get_length(env
, r2
+ 1);
2819 bool enh_check
= m3
& 1;
2822 /* Lest we fail to service interrupts in a timely manner, limit the
2823 amount of work we're willing to do. For now, let's cap at 256. */
2824 for (i
= 0; i
< 256; ++i
) {
2825 uint32_t c
, ilen
, olen
;
2827 cc
= decode(env
, src
, slen
, enh_check
, ra
, &c
, &ilen
);
2828 if (unlikely(cc
>= 0)) {
2831 cc
= encode(env
, dst
, dlen
, ra
, c
, &olen
);
2832 if (unlikely(cc
>= 0)) {
2843 set_address(env
, r1
, dst
);
2844 set_length(env
, r1
+ 1, dlen
);
2845 set_address(env
, r2
, src
);
2846 set_length(env
, r2
+ 1, slen
);
2851 uint32_t HELPER(cu12
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2853 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2854 decode_utf8
, encode_utf16
);
2857 uint32_t HELPER(cu14
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2859 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2860 decode_utf8
, encode_utf32
);
2863 uint32_t HELPER(cu21
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2865 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2866 decode_utf16
, encode_utf8
);
2869 uint32_t HELPER(cu24
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2871 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2872 decode_utf16
, encode_utf32
);
2875 uint32_t HELPER(cu41
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2877 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2878 decode_utf32
, encode_utf8
);
2881 uint32_t HELPER(cu42
)(CPUS390XState
*env
, uint32_t r1
, uint32_t r2
, uint32_t m3
)
2883 return convert_unicode(env
, r1
, r2
, m3
, GETPC(),
2884 decode_utf32
, encode_utf16
);
2887 void probe_write_access(CPUS390XState
*env
, uint64_t addr
, uint64_t len
,
2890 /* test the actual access, not just any access to the page due to LAP */
2892 const uint64_t pagelen
= -(addr
| TARGET_PAGE_MASK
);
2893 const uint64_t curlen
= MIN(pagelen
, len
);
2895 probe_write(env
, addr
, curlen
, cpu_mmu_index(env
, false), ra
);
2896 addr
= wrap_address(env
, addr
+ curlen
);
2901 void HELPER(probe_write_access
)(CPUS390XState
*env
, uint64_t addr
, uint64_t len
)
2903 probe_write_access(env
, addr
, len
, GETPC());