* Mark Nios II as orphan
* Many s390x emulation fixes * Disable flaky complete_in_standby blockjob unit test * White space cleanups in various files -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQYVEoRHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbWu/A//QdVG7wS66lhdkPPu/GN+eDNaNsTzPPZd YwH0bpy2YoopInwa1ggZ1zPatmbSOVUcKjUfNYLcQzUBQnmeFtpuAF+4IGDhYfa+ agkjWvmrCrIww4Wn+OLdLReW1+GtRlKZKu7xbYKkeLyqr9SHUD2lNUZ5RXj2t9Lw BXkPDXkMFqfVDzHtAxyXL7Z7yk3UTnZKBjDxiwE3tZ4S+N4r7m/TvNHiopI2bTVg JeDTxN40ylbOlBfOLC/qhlLUVnyBsDalIfKffIdLZ5Qn+FnKfZhkt9km4i7OL+ZX 1wKnTh/J8OCYqHOyhJdZGT8QxZH79qDm12/nKXzIQkxtJoKuz6Fm5FY3ZJNrb+IJ ybxSpAFBJB/8sUjbzl8ZjGxbZecIyEBKT518+oBoqjNcy3n8/m2BhBFr6f6F4cJC kdTnRS0XYKGLbJLz0+VBARE7hoHNckYsup/DGscppyYKNA6rFXbq/MI3+oMGAnPw Ua/+gXU/hwq8TPg97A7O0hS4TKSKMtdZFEDmAGzkejVHvm/3BvcYrVoKDljnUAQV SaERp/Elefbt3EufkuZp77AwLU8RcEFscitEIACmLbmwm3aKpqS+R2u1EJ4ZcoFT dHUBkokXW1/i+FtNRmjEKV9z398cNYXGEDLPfMnFbknHwbS53pqeQqqlvUidltGk LWviyiqKihk= =tYCc -----END PGP SIGNATURE----- Merge tag 'pull-request-2023-03-20' of https://gitlab.com/thuth/qemu into staging * Mark Nios II as orphan * Many s390x emulation fixes * Disable flaky complete_in_standby blockjob unit test * White space cleanups in various files # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQYVEoRHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbWu/A//QdVG7wS66lhdkPPu/GN+eDNaNsTzPPZd # YwH0bpy2YoopInwa1ggZ1zPatmbSOVUcKjUfNYLcQzUBQnmeFtpuAF+4IGDhYfa+ # agkjWvmrCrIww4Wn+OLdLReW1+GtRlKZKu7xbYKkeLyqr9SHUD2lNUZ5RXj2t9Lw # BXkPDXkMFqfVDzHtAxyXL7Z7yk3UTnZKBjDxiwE3tZ4S+N4r7m/TvNHiopI2bTVg # JeDTxN40ylbOlBfOLC/qhlLUVnyBsDalIfKffIdLZ5Qn+FnKfZhkt9km4i7OL+ZX # 1wKnTh/J8OCYqHOyhJdZGT8QxZH79qDm12/nKXzIQkxtJoKuz6Fm5FY3ZJNrb+IJ # ybxSpAFBJB/8sUjbzl8ZjGxbZecIyEBKT518+oBoqjNcy3n8/m2BhBFr6f6F4cJC # kdTnRS0XYKGLbJLz0+VBARE7hoHNckYsup/DGscppyYKNA6rFXbq/MI3+oMGAnPw # Ua/+gXU/hwq8TPg97A7O0hS4TKSKMtdZFEDmAGzkejVHvm/3BvcYrVoKDljnUAQV # SaERp/Elefbt3EufkuZp77AwLU8RcEFscitEIACmLbmwm3aKpqS+R2u1EJ4ZcoFT # dHUBkokXW1/i+FtNRmjEKV9z398cNYXGEDLPfMnFbknHwbS53pqeQqqlvUidltGk # LWviyiqKihk= # =tYCc # -----END PGP SIGNATURE----- # gpg: Signature made Mon 20 Mar 2023 12:40:42 GMT # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2023-03-20' of https://gitlab.com/thuth/qemu: (24 commits) replace TABs with spaces qemu/osdep: Switch position of "extern" and "G_NORETURN" tests/unit/test-blockjob: Disable complete_in_standby test target/s390x/tcg/mem_helper: Remove bad assert() statement tests/tcg/s390x: Test unaligned accesses target/s390x: Update do_unaligned_access() comment target/s390x: Handle STGRL to non-aligned addresses target/s390x: Handle STRL to non-aligned addresses target/s390x: Handle CLRL and CLGFRL with non-aligned addresses target/s390x: Handle CGRL and CLGRL with non-aligned addresses target/s390x: Handle CRL and CGFRL with non-aligned addresses target/s390x: Handle LLGFRL from non-aligned addresses target/s390x: Handle LRL and LGFRL from non-aligned addresses target/s390x: Handle LGRL from non-aligned addresses target/s390x: Handle EXECUTE of odd addresses target/s390x: Handle branching to odd addresses tests/tcg/s390x: Add ex-relative-long.c target/s390x: Fix EXECUTE of relative long instructions tests/tcg/s390x: Add rxsbg.c target/s390x: Fix R[NOX]SBG with T=1 ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4c6f44644d
@ -257,9 +257,9 @@ F: docs/system/cpu-models-mips.rst.inc
|
|||||||
F: tests/tcg/mips/
|
F: tests/tcg/mips/
|
||||||
|
|
||||||
NiosII TCG CPUs
|
NiosII TCG CPUs
|
||||||
M: Chris Wulff <crwulff@gmail.com>
|
R: Chris Wulff <crwulff@gmail.com>
|
||||||
M: Marek Vasut <marex@denx.de>
|
R: Marek Vasut <marex@denx.de>
|
||||||
S: Maintained
|
S: Orphan
|
||||||
F: target/nios2/
|
F: target/nios2/
|
||||||
F: hw/nios2/
|
F: hw/nios2/
|
||||||
F: disas/nios2.c
|
F: disas/nios2.c
|
||||||
|
@ -237,7 +237,7 @@ extern "C" {
|
|||||||
* supports QEMU_ERROR, this will be reported at compile time; otherwise
|
* supports QEMU_ERROR, this will be reported at compile time; otherwise
|
||||||
* this will be reported at link time due to the missing symbol.
|
* this will be reported at link time due to the missing symbol.
|
||||||
*/
|
*/
|
||||||
extern G_NORETURN
|
G_NORETURN extern
|
||||||
void QEMU_ERROR("code path is reachable")
|
void QEMU_ERROR("code path is reachable")
|
||||||
qemu_build_not_reached_always(void);
|
qemu_build_not_reached_always(void);
|
||||||
#if defined(__OPTIMIZE__) && !defined(__NO_INLINE__)
|
#if defined(__OPTIMIZE__) && !defined(__NO_INLINE__)
|
||||||
|
@ -122,7 +122,7 @@
|
|||||||
read_fw var ## _SIZE; \
|
read_fw var ## _SIZE; \
|
||||||
mov %eax, %ecx; \
|
mov %eax, %ecx; \
|
||||||
read_fw var ## _ADDR; \
|
read_fw var ## _ADDR; \
|
||||||
mov %eax, %edi ;\
|
mov %eax, %edi ; \
|
||||||
read_fw_dma var ## _DATA, %ecx, %edi
|
read_fw_dma var ## _DATA, %ecx, %edi
|
||||||
#else
|
#else
|
||||||
#define read_fw_blob_dma(var) read_fw_blob(var)
|
#define read_fw_blob_dma(var) read_fw_blob(var)
|
||||||
|
@ -41,6 +41,26 @@
|
|||||||
#define CR0_RESET 0xE0UL
|
#define CR0_RESET 0xE0UL
|
||||||
#define CR14_RESET 0xC2000000UL;
|
#define CR14_RESET 0xC2000000UL;
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
static bool is_early_exception_psw(uint64_t mask, uint64_t addr)
|
||||||
|
{
|
||||||
|
if (mask & PSW_MASK_RESERVED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mask & (PSW_MASK_32 | PSW_MASK_64)) {
|
||||||
|
case 0:
|
||||||
|
return addr & ~0xffffffULL;
|
||||||
|
case PSW_MASK_32:
|
||||||
|
return addr & ~0x7fffffffULL;
|
||||||
|
case PSW_MASK_32 | PSW_MASK_64:
|
||||||
|
return false;
|
||||||
|
default: /* PSW_MASK_64 */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
@ -57,6 +77,12 @@ void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
|||||||
env->cc_op = (mask >> 44) & 3;
|
env->cc_op = (mask >> 44) & 3;
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
if (is_early_exception_psw(mask, addr)) {
|
||||||
|
env->int_pgm_ilen = 0;
|
||||||
|
trigger_pgm_exception(env, PGM_SPECIFICATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((old_mask ^ mask) & PSW_MASK_PER) {
|
if ((old_mask ^ mask) & PSW_MASK_PER) {
|
||||||
s390_cpu_recompute_watchpoints(env_cpu(env));
|
s390_cpu_recompute_watchpoints(env_cpu(env));
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "cpu_models.h"
|
#include "cpu_models.h"
|
||||||
#include "exec/cpu-defs.h"
|
#include "exec/cpu-defs.h"
|
||||||
#include "qemu/cpu-float.h"
|
#include "qemu/cpu-float.h"
|
||||||
|
#include "tcg/tcg_s390x.h"
|
||||||
|
|
||||||
#define ELF_MACHINE_UNAME "S390X"
|
#define ELF_MACHINE_UNAME "S390X"
|
||||||
|
|
||||||
@ -87,6 +88,7 @@ struct CPUArchState {
|
|||||||
uint64_t cc_vr;
|
uint64_t cc_vr;
|
||||||
|
|
||||||
uint64_t ex_value;
|
uint64_t ex_value;
|
||||||
|
uint64_t ex_target;
|
||||||
|
|
||||||
uint64_t __excp_addr;
|
uint64_t __excp_addr;
|
||||||
uint64_t psa;
|
uint64_t psa;
|
||||||
@ -292,6 +294,7 @@ extern const VMStateDescription vmstate_s390_cpu;
|
|||||||
#define PSW_MASK_32 0x0000000080000000ULL
|
#define PSW_MASK_32 0x0000000080000000ULL
|
||||||
#define PSW_MASK_SHORT_ADDR 0x000000007fffffffULL
|
#define PSW_MASK_SHORT_ADDR 0x000000007fffffffULL
|
||||||
#define PSW_MASK_SHORT_CTRL 0xffffffff80000000ULL
|
#define PSW_MASK_SHORT_CTRL 0xffffffff80000000ULL
|
||||||
|
#define PSW_MASK_RESERVED 0xb80800fe7fffffffULL
|
||||||
|
|
||||||
#undef PSW_ASC_PRIMARY
|
#undef PSW_ASC_PRIMARY
|
||||||
#undef PSW_ASC_ACCREG
|
#undef PSW_ASC_ACCREG
|
||||||
@ -381,6 +384,14 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
|
|||||||
static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
|
||||||
target_ulong *cs_base, uint32_t *flags)
|
target_ulong *cs_base, uint32_t *flags)
|
||||||
{
|
{
|
||||||
|
if (env->psw.addr & 1) {
|
||||||
|
/*
|
||||||
|
* Instructions must be at even addresses.
|
||||||
|
* This needs to be checked before address translation.
|
||||||
|
*/
|
||||||
|
env->int_pgm_ilen = 2; /* see s390_cpu_tlb_fill() */
|
||||||
|
tcg_s390_program_interrupt(env, PGM_SPECIFICATION, 0);
|
||||||
|
}
|
||||||
*pc = env->psw.addr;
|
*pc = env->psw.addr;
|
||||||
*cs_base = env->ex_value;
|
*cs_base = env->ex_value;
|
||||||
*flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
|
*flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
|
||||||
|
@ -85,8 +85,8 @@ void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Unaligned accesses are only diagnosed with MO_ALIGN. At the moment,
|
* Unaligned accesses are only diagnosed with MO_ALIGN. At the moment,
|
||||||
* this is only for the atomic operations, for which we want to raise a
|
* this is only for the atomic and relative long operations, for which we want
|
||||||
* specification exception.
|
* to raise a specification exception.
|
||||||
*/
|
*/
|
||||||
static G_NORETURN
|
static G_NORETURN
|
||||||
void do_unaligned_access(CPUState *cs, uintptr_t retaddr)
|
void do_unaligned_access(CPUState *cs, uintptr_t retaddr)
|
||||||
@ -212,7 +212,8 @@ static void do_program_interrupt(CPUS390XState *env)
|
|||||||
LowCore *lowcore;
|
LowCore *lowcore;
|
||||||
int ilen = env->int_pgm_ilen;
|
int ilen = env->int_pgm_ilen;
|
||||||
|
|
||||||
assert(ilen == 2 || ilen == 4 || ilen == 6);
|
assert((env->int_pgm_code == PGM_SPECIFICATION && ilen == 0) ||
|
||||||
|
ilen == 2 || ilen == 4 || ilen == 6);
|
||||||
|
|
||||||
switch (env->int_pgm_code) {
|
switch (env->int_pgm_code) {
|
||||||
case PGM_PER:
|
case PGM_PER:
|
||||||
|
@ -410,12 +410,12 @@
|
|||||||
|
|
||||||
/* LOAD */
|
/* LOAD */
|
||||||
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0)
|
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0)
|
||||||
C(0x5800, L, RX_a, Z, 0, a2, new, r1_32, ld32s, 0)
|
D(0x5800, L, RX_a, Z, 0, a2, new, r1_32, ld32s, 0, 0)
|
||||||
C(0xe358, LY, RXY_a, LD, 0, a2, new, r1_32, ld32s, 0)
|
D(0xe358, LY, RXY_a, LD, 0, a2, new, r1_32, ld32s, 0, 0)
|
||||||
C(0xb904, LGR, RRE, Z, 0, r2_o, 0, r1, mov2, 0)
|
C(0xb904, LGR, RRE, Z, 0, r2_o, 0, r1, mov2, 0)
|
||||||
C(0xb914, LGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, 0)
|
C(0xb914, LGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, 0)
|
||||||
C(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0)
|
D(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0, 0)
|
||||||
C(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0)
|
D(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0, 0)
|
||||||
F(0x2800, LDR, RR_a, Z, 0, f2, 0, f1, mov2, 0, IF_AFP1 | IF_AFP2)
|
F(0x2800, LDR, RR_a, Z, 0, f2, 0, f1, mov2, 0, IF_AFP1 | IF_AFP2)
|
||||||
F(0x6800, LD, RX_a, Z, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
F(0x6800, LD, RX_a, Z, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
||||||
F(0xed65, LDY, RXY_a, LD, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
F(0xed65, LDY, RXY_a, LD, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
||||||
@ -426,9 +426,9 @@
|
|||||||
/* LOAD IMMEDIATE */
|
/* LOAD IMMEDIATE */
|
||||||
C(0xc001, LGFI, RIL_a, EI, 0, i2, 0, r1, mov2, 0)
|
C(0xc001, LGFI, RIL_a, EI, 0, i2, 0, r1, mov2, 0)
|
||||||
/* LOAD RELATIVE LONG */
|
/* LOAD RELATIVE LONG */
|
||||||
C(0xc40d, LRL, RIL_b, GIE, 0, ri2, new, r1_32, ld32s, 0)
|
D(0xc40d, LRL, RIL_b, GIE, 0, ri2, new, r1_32, ld32s, 0, MO_ALIGN)
|
||||||
C(0xc408, LGRL, RIL_b, GIE, 0, ri2, r1, 0, ld64, 0)
|
D(0xc408, LGRL, RIL_b, GIE, 0, ri2, r1, 0, ld64, 0, MO_ALIGN)
|
||||||
C(0xc40c, LGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32s, 0)
|
D(0xc40c, LGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32s, 0, MO_ALIGN)
|
||||||
/* LOAD ADDRESS */
|
/* LOAD ADDRESS */
|
||||||
C(0x4100, LA, RX_a, Z, 0, a2, 0, r1, mov2, 0)
|
C(0x4100, LA, RX_a, Z, 0, a2, 0, r1, mov2, 0)
|
||||||
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
|
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
|
||||||
@ -456,9 +456,9 @@
|
|||||||
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
|
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
|
||||||
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
|
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
|
||||||
C(0xb912, LTGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, s64)
|
C(0xb912, LTGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, s64)
|
||||||
C(0xe312, LT, RXY_a, EI, 0, a2, new, r1_32, ld32s, s64)
|
D(0xe312, LT, RXY_a, EI, 0, a2, new, r1_32, ld32s, s64, 0)
|
||||||
C(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64)
|
D(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64, 0)
|
||||||
C(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64)
|
D(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64, 0)
|
||||||
F(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32, IF_BFP)
|
F(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32, IF_BFP)
|
||||||
F(0xb312, LTDBR, RRE, Z, 0, f2, 0, f1, mov2, f64, IF_BFP)
|
F(0xb312, LTDBR, RRE, Z, 0, f2, 0, f1, mov2, f64, IF_BFP)
|
||||||
F(0xb342, LTXBR, RRE, Z, x2h, x2l, 0, x1_P, movx, f128, IF_BFP)
|
F(0xb342, LTXBR, RRE, Z, x2h, x2l, 0, x1_P, movx, f128, IF_BFP)
|
||||||
@ -502,16 +502,16 @@
|
|||||||
C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0)
|
C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0)
|
||||||
C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0)
|
C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0)
|
||||||
/* LOAD HIGH */
|
/* LOAD HIGH */
|
||||||
C(0xe3ca, LFH, RXY_a, HW, 0, a2, new, r1_32h, ld32u, 0)
|
D(0xe3ca, LFH, RXY_a, HW, 0, a2, new, r1_32h, ld32u, 0, 0)
|
||||||
/* LOAG HIGH AND TRAP */
|
/* LOAG HIGH AND TRAP */
|
||||||
C(0xe3c8, LFHAT, RXY_a, LAT, 0, m2_32u, r1, 0, lfhat, 0)
|
C(0xe3c8, LFHAT, RXY_a, LAT, 0, m2_32u, r1, 0, lfhat, 0)
|
||||||
/* LOAD LOGICAL */
|
/* LOAD LOGICAL */
|
||||||
C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0)
|
C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0)
|
||||||
C(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0)
|
D(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0, 0)
|
||||||
/* LOAD LOGICAL AND TRAP */
|
/* LOAD LOGICAL AND TRAP */
|
||||||
C(0xe39d, LLGFAT, RXY_a, LAT, 0, a2, r1, 0, llgfat, 0)
|
C(0xe39d, LLGFAT, RXY_a, LAT, 0, a2, r1, 0, llgfat, 0)
|
||||||
/* LOAD LOGICAL RELATIVE LONG */
|
/* LOAD LOGICAL RELATIVE LONG */
|
||||||
C(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0)
|
D(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0, MO_ALIGN)
|
||||||
/* LOAD LOGICAL CHARACTER */
|
/* LOAD LOGICAL CHARACTER */
|
||||||
C(0xb994, LLCR, RRE, EI, 0, r2_8u, 0, r1_32, mov2, 0)
|
C(0xb994, LLCR, RRE, EI, 0, r2_8u, 0, r1_32, mov2, 0)
|
||||||
C(0xb984, LLGCR, RRE, EI, 0, r2_8u, 0, r1, mov2, 0)
|
C(0xb984, LLGCR, RRE, EI, 0, r2_8u, 0, r1, mov2, 0)
|
||||||
@ -840,16 +840,16 @@
|
|||||||
F(0xed15, SQDB, RXE, Z, 0, m2_64, new, f1, sqdb, 0, IF_BFP)
|
F(0xed15, SQDB, RXE, Z, 0, m2_64, new, f1, sqdb, 0, IF_BFP)
|
||||||
|
|
||||||
/* STORE */
|
/* STORE */
|
||||||
C(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0)
|
D(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0, 0)
|
||||||
C(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0)
|
D(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0, 0)
|
||||||
C(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0)
|
D(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0, 0)
|
||||||
F(0x6000, STD, RX_a, Z, f1, a2, 0, 0, st64, 0, IF_AFP1)
|
E(0x6000, STD, RX_a, Z, f1, a2, 0, 0, st64, 0, 0, IF_AFP1)
|
||||||
F(0xed67, STDY, RXY_a, LD, f1, a2, 0, 0, st64, 0, IF_AFP1)
|
E(0xed67, STDY, RXY_a, LD, f1, a2, 0, 0, st64, 0, 0, IF_AFP1)
|
||||||
F(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0, IF_AFP1)
|
E(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0, 0, IF_AFP1)
|
||||||
F(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0, IF_AFP1)
|
E(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0, 0, IF_AFP1)
|
||||||
/* STORE RELATIVE LONG */
|
/* STORE RELATIVE LONG */
|
||||||
C(0xc40f, STRL, RIL_b, GIE, r1_o, ri2, 0, 0, st32, 0)
|
D(0xc40f, STRL, RIL_b, GIE, r1_o, ri2, 0, 0, st32, 0, MO_ALIGN)
|
||||||
C(0xc40b, STGRL, RIL_b, GIE, r1_o, ri2, 0, 0, st64, 0)
|
D(0xc40b, STGRL, RIL_b, GIE, r1_o, ri2, 0, 0, st64, 0, MO_ALIGN)
|
||||||
/* STORE CHARACTER */
|
/* STORE CHARACTER */
|
||||||
C(0x4200, STC, RX_a, Z, r1_o, a2, 0, 0, st8, 0)
|
C(0x4200, STC, RX_a, Z, r1_o, a2, 0, 0, st8, 0)
|
||||||
C(0xe372, STCY, RXY_a, LD, r1_o, a2, 0, 0, st8, 0)
|
C(0xe372, STCY, RXY_a, LD, r1_o, a2, 0, 0, st8, 0)
|
||||||
@ -867,7 +867,7 @@
|
|||||||
/* STORE HALFWORD RELATIVE LONG */
|
/* STORE HALFWORD RELATIVE LONG */
|
||||||
C(0xc407, STHRL, RIL_b, GIE, r1_o, ri2, 0, 0, st16, 0)
|
C(0xc407, STHRL, RIL_b, GIE, r1_o, ri2, 0, 0, st16, 0)
|
||||||
/* STORE HIGH */
|
/* STORE HIGH */
|
||||||
C(0xe3cb, STFH, RXY_a, HW, r1_sr32, a2, 0, 0, st32, 0)
|
D(0xe3cb, STFH, RXY_a, HW, r1_sr32, a2, 0, 0, st32, 0, 0)
|
||||||
/* STORE ON CONDITION */
|
/* STORE ON CONDITION */
|
||||||
D(0xebf3, STOC, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0)
|
D(0xebf3, STOC, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0)
|
||||||
D(0xebe3, STOCG, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1)
|
D(0xebe3, STOCG, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1)
|
||||||
|
@ -149,7 +149,6 @@ static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
|
|||||||
nonfault, phost, ra);
|
nonfault, phost, ra);
|
||||||
|
|
||||||
if (unlikely(flags & TLB_INVALID_MASK)) {
|
if (unlikely(flags & TLB_INVALID_MASK)) {
|
||||||
assert(!nonfault);
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
/* Address is in TEC in system mode; see s390_cpu_record_sigsegv. */
|
/* Address is in TEC in system mode; see s390_cpu_record_sigsegv. */
|
||||||
env->__excp_addr = addr & TARGET_PAGE_MASK;
|
env->__excp_addr = addr & TARGET_PAGE_MASK;
|
||||||
@ -2468,8 +2467,16 @@ void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
|
|||||||
*/
|
*/
|
||||||
void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
|
void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
|
||||||
{
|
{
|
||||||
uint64_t insn = cpu_lduw_code(env, addr);
|
uint64_t insn;
|
||||||
uint8_t opc = insn >> 8;
|
uint8_t opc;
|
||||||
|
|
||||||
|
/* EXECUTE targets must be at even addresses. */
|
||||||
|
if (addr & 1) {
|
||||||
|
tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
|
||||||
|
}
|
||||||
|
|
||||||
|
insn = cpu_lduw_code(env, addr);
|
||||||
|
opc = insn >> 8;
|
||||||
|
|
||||||
/* Or in the contents of R1[56:63]. */
|
/* Or in the contents of R1[56:63]. */
|
||||||
insn |= r1 & 0xff;
|
insn |= r1 & 0xff;
|
||||||
@ -2530,6 +2537,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
|
|||||||
that ex_value is non-zero, which flags that we are in a state
|
that ex_value is non-zero, which flags that we are in a state
|
||||||
that requires such execution. */
|
that requires such execution. */
|
||||||
env->ex_value = insn | ilen;
|
env->ex_value = insn | ilen;
|
||||||
|
env->ex_target = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
|
uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
|
||||||
|
@ -2770,19 +2770,22 @@ static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o)
|
|||||||
|
|
||||||
static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
|
tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
|
||||||
|
MO_TESL | s->insn->data);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
|
tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
|
||||||
|
MO_TEUL | s->insn->data);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
|
tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
|
||||||
|
MO_TEUQ | s->insn->data);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2910,19 +2913,21 @@ static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
|
|||||||
|
|
||||||
static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
TCGv_i64 t1, t2;
|
TCGv_i64 mask, addr;
|
||||||
|
|
||||||
per_breaking_event(s);
|
per_breaking_event(s);
|
||||||
|
|
||||||
t1 = tcg_temp_new_i64();
|
/*
|
||||||
t2 = tcg_temp_new_i64();
|
* Convert the short PSW into the normal PSW, similar to what
|
||||||
tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
|
* s390_cpu_load_normal() does.
|
||||||
MO_TEUL | MO_ALIGN_8);
|
*/
|
||||||
tcg_gen_addi_i64(o->in2, o->in2, 4);
|
mask = tcg_temp_new_i64();
|
||||||
tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
|
addr = tcg_temp_new_i64();
|
||||||
/* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
|
tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN_8);
|
||||||
tcg_gen_shli_i64(t1, t1, 32);
|
tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
|
||||||
gen_helper_load_psw(cpu_env, t1, t2);
|
tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
|
||||||
|
tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
|
||||||
|
gen_helper_load_psw(cpu_env, mask, addr);
|
||||||
return DISAS_NORETURN;
|
return DISAS_NORETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3695,11 +3700,15 @@ static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
|
|||||||
int i3 = get_field(s, i3);
|
int i3 = get_field(s, i3);
|
||||||
int i4 = get_field(s, i4);
|
int i4 = get_field(s, i4);
|
||||||
int i5 = get_field(s, i5);
|
int i5 = get_field(s, i5);
|
||||||
|
TCGv_i64 orig_out;
|
||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
|
|
||||||
/* If this is a test-only form, arrange to discard the result. */
|
/* If this is a test-only form, arrange to discard the result. */
|
||||||
if (i3 & 0x80) {
|
if (i3 & 0x80) {
|
||||||
|
tcg_debug_assert(o->out != NULL);
|
||||||
|
orig_out = o->out;
|
||||||
o->out = tcg_temp_new_i64();
|
o->out = tcg_temp_new_i64();
|
||||||
|
tcg_gen_mov_i64(o->out, orig_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
i3 &= 63;
|
i3 &= 63;
|
||||||
@ -4066,9 +4075,23 @@ static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
|
|||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_check_psw_mask(DisasContext *s)
|
||||||
|
{
|
||||||
|
TCGv_i64 reserved = tcg_temp_new_i64();
|
||||||
|
TCGLabel *ok = gen_new_label();
|
||||||
|
|
||||||
|
tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
|
||||||
|
tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
|
||||||
|
gen_program_exception(s, PGM_SPECIFICATION);
|
||||||
|
gen_set_label(ok);
|
||||||
|
}
|
||||||
|
|
||||||
static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
|
tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
|
||||||
|
|
||||||
|
gen_check_psw_mask(s);
|
||||||
|
|
||||||
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
|
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
|
||||||
s->exit_to_mainloop = true;
|
s->exit_to_mainloop = true;
|
||||||
return DISAS_TOO_MANY;
|
return DISAS_TOO_MANY;
|
||||||
@ -4329,6 +4352,8 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
|
|||||||
tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
|
tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_check_psw_mask(s);
|
||||||
|
|
||||||
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
|
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
|
||||||
s->exit_to_mainloop = true;
|
s->exit_to_mainloop = true;
|
||||||
return DISAS_TOO_MANY;
|
return DISAS_TOO_MANY;
|
||||||
@ -4367,13 +4392,15 @@ static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
|
|||||||
|
|
||||||
static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
|
tcg_gen_qemu_st_tl(o->in1, o->in2, get_mem_index(s),
|
||||||
|
MO_TEUL | s->insn->data);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
|
tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s),
|
||||||
|
MO_TEUQ | s->insn->data);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5747,7 +5774,18 @@ static void in2_a2(DisasContext *s, DisasOps *o)
|
|||||||
|
|
||||||
static TCGv gen_ri2(DisasContext *s)
|
static TCGv gen_ri2(DisasContext *s)
|
||||||
{
|
{
|
||||||
return tcg_constant_i64(s->base.pc_next + (int64_t)get_field(s, i2) * 2);
|
int64_t delta = (int64_t)get_field(s, i2) * 2;
|
||||||
|
TCGv ri2;
|
||||||
|
|
||||||
|
if (unlikely(s->ex_value)) {
|
||||||
|
ri2 = tcg_temp_new_i64();
|
||||||
|
tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
|
||||||
|
tcg_gen_addi_i64(ri2, ri2, delta);
|
||||||
|
} else {
|
||||||
|
ri2 = tcg_constant_i64(s->base.pc_next + delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ri2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void in2_ri2(DisasContext *s, DisasOps *o)
|
static void in2_ri2(DisasContext *s, DisasOps *o)
|
||||||
@ -5855,21 +5893,24 @@ static void in2_mri2_16u(DisasContext *s, DisasOps *o)
|
|||||||
static void in2_mri2_32s(DisasContext *s, DisasOps *o)
|
static void in2_mri2_32s(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in2 = tcg_temp_new_i64();
|
o->in2 = tcg_temp_new_i64();
|
||||||
tcg_gen_qemu_ld32s(o->in2, gen_ri2(s), get_mem_index(s));
|
tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
|
||||||
|
MO_TESL | MO_ALIGN);
|
||||||
}
|
}
|
||||||
#define SPEC_in2_mri2_32s 0
|
#define SPEC_in2_mri2_32s 0
|
||||||
|
|
||||||
static void in2_mri2_32u(DisasContext *s, DisasOps *o)
|
static void in2_mri2_32u(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in2 = tcg_temp_new_i64();
|
o->in2 = tcg_temp_new_i64();
|
||||||
tcg_gen_qemu_ld32u(o->in2, gen_ri2(s), get_mem_index(s));
|
tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
|
||||||
|
MO_TEUL | MO_ALIGN);
|
||||||
}
|
}
|
||||||
#define SPEC_in2_mri2_32u 0
|
#define SPEC_in2_mri2_32u 0
|
||||||
|
|
||||||
static void in2_mri2_64(DisasContext *s, DisasOps *o)
|
static void in2_mri2_64(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in2 = tcg_temp_new_i64();
|
o->in2 = tcg_temp_new_i64();
|
||||||
tcg_gen_qemu_ld64(o->in2, gen_ri2(s), get_mem_index(s));
|
tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s),
|
||||||
|
MO_TEUQ | MO_ALIGN);
|
||||||
}
|
}
|
||||||
#define SPEC_in2_mri2_64 0
|
#define SPEC_in2_mri2_64 0
|
||||||
|
|
||||||
|
@ -1,11 +1,25 @@
|
|||||||
S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
|
S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
|
||||||
VPATH+=$(S390X_SRC)
|
VPATH+=$(S390X_SRC)
|
||||||
QEMU_OPTS=-action panic=exit-failure -kernel
|
QEMU_OPTS=-action panic=exit-failure -kernel
|
||||||
|
LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
|
||||||
|
LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
|
||||||
|
|
||||||
%: %.S
|
%.o: %.S
|
||||||
$(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
|
$(CC) -march=z13 -m64 -c $< -o $@
|
||||||
-Wl,--build-id=none $< -o $@
|
|
||||||
|
%: %.o $(LINK_SCRIPT)
|
||||||
|
$(CC) $< -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
TESTS += unaligned-lowcore
|
TESTS += unaligned-lowcore
|
||||||
TESTS += bal
|
TESTS += bal
|
||||||
TESTS += sam
|
TESTS += sam
|
||||||
|
TESTS += lpsw
|
||||||
|
TESTS += lpswe-early
|
||||||
|
TESTS += ssm-early
|
||||||
|
TESTS += stosm-early
|
||||||
|
TESTS += exrl-ssm-early
|
||||||
|
|
||||||
|
include $(S390X_SRC)/pgm-specification.mak
|
||||||
|
$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
|
||||||
|
$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
|
||||||
|
TESTS += $(PGM_SPECIFICATION_TESTS)
|
||||||
|
@ -2,6 +2,9 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
|
|||||||
VPATH+=$(S390X_SRC)
|
VPATH+=$(S390X_SRC)
|
||||||
CFLAGS+=-march=zEC12 -m64
|
CFLAGS+=-march=zEC12 -m64
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
config-cc.mak: Makefile
|
config-cc.mak: Makefile
|
||||||
$(quiet-@)( \
|
$(quiet-@)( \
|
||||||
$(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
|
$(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
|
||||||
@ -29,10 +32,19 @@ TESTS+=clst
|
|||||||
TESTS+=long-double
|
TESTS+=long-double
|
||||||
TESTS+=cdsg
|
TESTS+=cdsg
|
||||||
TESTS+=chrl
|
TESTS+=chrl
|
||||||
|
TESTS+=rxsbg
|
||||||
|
TESTS+=ex-relative-long
|
||||||
|
|
||||||
cdsg: CFLAGS+=-pthread
|
cdsg: CFLAGS+=-pthread
|
||||||
cdsg: LDFLAGS+=-pthread
|
cdsg: LDFLAGS+=-pthread
|
||||||
|
|
||||||
|
rxsbg: CFLAGS+=-O2
|
||||||
|
|
||||||
|
include $(S390X_SRC)/pgm-specification.mak
|
||||||
|
$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
|
||||||
|
$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
|
||||||
|
TESTS += $(PGM_SPECIFICATION_TESTS)
|
||||||
|
|
||||||
Z13_TESTS=vistr
|
Z13_TESTS=vistr
|
||||||
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
|
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
|
||||||
TESTS+=$(Z13_TESTS)
|
TESTS+=$(Z13_TESTS)
|
||||||
|
16
tests/tcg/s390x/br-odd.S
Normal file
16
tests/tcg/s390x/br-odd.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test BRanching to a non-mapped odd address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
lgrl %r1,odd_addr
|
||||||
|
br %r1
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
odd_addr:
|
||||||
|
.quad 0xDDDDDDDDDDDDDDDD
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,0xDDDDDDDDDDDDDDDD
|
16
tests/tcg/s390x/cgrl-unaligned.S
Normal file
16
tests/tcg/s390x/cgrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test CGRL with a non-doubleword aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
cgrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.long 0
|
||||||
|
unaligned:
|
||||||
|
.quad 0
|
16
tests/tcg/s390x/clrl-unaligned.S
Normal file
16
tests/tcg/s390x/clrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test CLRL with a non-word aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
clrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.short 0
|
||||||
|
unaligned:
|
||||||
|
.long 0
|
16
tests/tcg/s390x/crl-unaligned.S
Normal file
16
tests/tcg/s390x/crl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test CRL with a non-word aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
crl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.short 0
|
||||||
|
unaligned:
|
||||||
|
.long 0
|
17
tests/tcg/s390x/ex-odd.S
Normal file
17
tests/tcg/s390x/ex-odd.S
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Test EXECUTing a non-mapped odd address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
lgrl %r1,odd_addr
|
||||||
|
fail:
|
||||||
|
ex 0,0(%r1)
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
odd_addr:
|
||||||
|
.quad 0xDDDDDDDDDDDDDDDD
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,fail
|
156
tests/tcg/s390x/ex-relative-long.c
Normal file
156
tests/tcg/s390x/ex-relative-long.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* Check EXECUTE with relative long instructions as targets. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct test {
|
||||||
|
const char *name;
|
||||||
|
long (*func)(long reg, long *cc);
|
||||||
|
long exp_reg;
|
||||||
|
long exp_mem;
|
||||||
|
long exp_cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each test sets the MEM_IDXth element of the mem array to MEM and uses a
|
||||||
|
* single relative long instruction on it. The other elements remain zero.
|
||||||
|
* This is in order to prevent stumbling upon MEM in random memory in case
|
||||||
|
* there is an off-by-a-small-value bug.
|
||||||
|
*
|
||||||
|
* Note that while gcc supports the ZL constraint for relative long operands,
|
||||||
|
* clang doesn't, so the assembly code accesses mem[MEM_IDX] using MEM_ASM.
|
||||||
|
*/
|
||||||
|
static long mem[0x1000];
|
||||||
|
#define MEM_IDX 0x800
|
||||||
|
#define MEM_ASM "mem+0x800*8"
|
||||||
|
|
||||||
|
/* Initial %r2 value. */
|
||||||
|
#define REG 0x1234567887654321
|
||||||
|
|
||||||
|
/* Initial mem[MEM_IDX] value. */
|
||||||
|
#define MEM 0xfedcba9889abcdef
|
||||||
|
|
||||||
|
/* Initial cc value. */
|
||||||
|
#define CC 0
|
||||||
|
|
||||||
|
/* Relative long instructions and their expected effects. */
|
||||||
|
#define FOR_EACH_INSN(F) \
|
||||||
|
F(cgfrl, REG, MEM, 2) \
|
||||||
|
F(cghrl, REG, MEM, 2) \
|
||||||
|
F(cgrl, REG, MEM, 2) \
|
||||||
|
F(chrl, REG, MEM, 1) \
|
||||||
|
F(clgfrl, REG, MEM, 2) \
|
||||||
|
F(clghrl, REG, MEM, 2) \
|
||||||
|
F(clgrl, REG, MEM, 1) \
|
||||||
|
F(clhrl, REG, MEM, 2) \
|
||||||
|
F(clrl, REG, MEM, 1) \
|
||||||
|
F(crl, REG, MEM, 1) \
|
||||||
|
F(larl, (long)&mem[MEM_IDX], MEM, CC) \
|
||||||
|
F(lgfrl, 0xfffffffffedcba98, MEM, CC) \
|
||||||
|
F(lghrl, 0xfffffffffffffedc, MEM, CC) \
|
||||||
|
F(lgrl, MEM, MEM, CC) \
|
||||||
|
F(lhrl, 0x12345678fffffedc, MEM, CC) \
|
||||||
|
F(llghrl, 0x000000000000fedc, MEM, CC) \
|
||||||
|
F(llhrl, 0x123456780000fedc, MEM, CC) \
|
||||||
|
F(lrl, 0x12345678fedcba98, MEM, CC) \
|
||||||
|
F(stgrl, REG, REG, CC) \
|
||||||
|
F(sthrl, REG, 0x4321ba9889abcdef, CC) \
|
||||||
|
F(strl, REG, 0x8765432189abcdef, CC)
|
||||||
|
|
||||||
|
/* Test functions. */
|
||||||
|
#define DEFINE_EX_TEST(insn, exp_reg, exp_mem, exp_cc) \
|
||||||
|
static long test_ex_ ## insn(long reg, long *cc) \
|
||||||
|
{ \
|
||||||
|
register long r2 asm("r2"); \
|
||||||
|
char mask = 0x20; /* make target use %r2 */ \
|
||||||
|
long pm, target; \
|
||||||
|
\
|
||||||
|
r2 = reg; \
|
||||||
|
asm("larl %[target],0f\n" \
|
||||||
|
"cr %%r0,%%r0\n" /* initial cc */ \
|
||||||
|
"ex %[mask],0(%[target])\n" \
|
||||||
|
"jg 1f\n" \
|
||||||
|
"0: " #insn " %%r0," MEM_ASM "\n" \
|
||||||
|
"1: ipm %[pm]\n" \
|
||||||
|
: [target] "=&a" (target), [r2] "+r" (r2), [pm] "=r" (pm) \
|
||||||
|
: [mask] "a" (mask) \
|
||||||
|
: "cc", "memory"); \
|
||||||
|
reg = r2; \
|
||||||
|
*cc = (pm >> 28) & 3; \
|
||||||
|
\
|
||||||
|
return reg; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_EXRL_TEST(insn, exp_reg, exp_mem, exp_cc) \
|
||||||
|
static long test_exrl_ ## insn(long reg, long *cc) \
|
||||||
|
{ \
|
||||||
|
register long r2 asm("r2"); \
|
||||||
|
char mask = 0x20; /* make target use %r2 */ \
|
||||||
|
long pm; \
|
||||||
|
\
|
||||||
|
r2 = reg; \
|
||||||
|
asm("cr %%r0,%%r0\n" /* initial cc */ \
|
||||||
|
"exrl %[mask],0f\n" \
|
||||||
|
"jg 1f\n" \
|
||||||
|
"0: " #insn " %%r0," MEM_ASM "\n" \
|
||||||
|
"1: ipm %[pm]\n" \
|
||||||
|
: [r2] "+r" (r2), [pm] "=r" (pm) \
|
||||||
|
: [mask] "a" (mask) \
|
||||||
|
: "cc", "memory"); \
|
||||||
|
reg = r2; \
|
||||||
|
*cc = (pm >> 28) & 3; \
|
||||||
|
\
|
||||||
|
return reg; \
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_EACH_INSN(DEFINE_EX_TEST)
|
||||||
|
FOR_EACH_INSN(DEFINE_EXRL_TEST)
|
||||||
|
|
||||||
|
/* Test definitions. */
|
||||||
|
#define REGISTER_EX_EXRL_TEST(ex_insn, insn, _exp_reg, _exp_mem, _exp_cc) \
|
||||||
|
{ \
|
||||||
|
.name = #ex_insn " " #insn, \
|
||||||
|
.func = test_ ## ex_insn ## _ ## insn, \
|
||||||
|
.exp_reg = (_exp_reg), \
|
||||||
|
.exp_mem = (_exp_mem), \
|
||||||
|
.exp_cc = (_exp_cc), \
|
||||||
|
},
|
||||||
|
|
||||||
|
#define REGISTER_EX_TEST(insn, exp_reg, exp_mem, exp_cc) \
|
||||||
|
REGISTER_EX_EXRL_TEST(ex, insn, exp_reg, exp_mem, exp_cc)
|
||||||
|
|
||||||
|
#define REGISTER_EXRL_TEST(insn, exp_reg, exp_mem, exp_cc) \
|
||||||
|
REGISTER_EX_EXRL_TEST(exrl, insn, exp_reg, exp_mem, exp_cc)
|
||||||
|
|
||||||
|
static const struct test tests[] = {
|
||||||
|
FOR_EACH_INSN(REGISTER_EX_TEST)
|
||||||
|
FOR_EACH_INSN(REGISTER_EXRL_TEST)
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Loop over all tests and run them. */
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
const struct test *test;
|
||||||
|
int ret = EXIT_SUCCESS;
|
||||||
|
long reg, cc;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
|
||||||
|
test = &tests[i];
|
||||||
|
mem[MEM_IDX] = MEM;
|
||||||
|
cc = -1;
|
||||||
|
reg = test->func(REG, &cc);
|
||||||
|
#define ASSERT_EQ(expected, actual) do { \
|
||||||
|
if (expected != actual) { \
|
||||||
|
fprintf(stderr, "%s: " #expected " (0x%lx) != " #actual " (0x%lx)\n", \
|
||||||
|
test->name, expected, actual); \
|
||||||
|
ret = EXIT_FAILURE; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
ASSERT_EQ(test->exp_reg, reg);
|
||||||
|
ASSERT_EQ(test->exp_mem, mem[MEM_IDX]);
|
||||||
|
ASSERT_EQ(test->exp_cc, cc);
|
||||||
|
#undef ASSERT_EQ
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
43
tests/tcg/s390x/exrl-ssm-early.S
Normal file
43
tests/tcg/s390x/exrl-ssm-early.S
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Test early exception recognition using EXRL + SSM.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.org 0x8d
|
||||||
|
ilc:
|
||||||
|
.org 0x8e
|
||||||
|
program_interruption_code:
|
||||||
|
.org 0x150
|
||||||
|
program_old_psw:
|
||||||
|
.org 0x1D0 /* program new PSW */
|
||||||
|
.quad 0,pgm
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
exrl %r0,ssm
|
||||||
|
expected_pswa:
|
||||||
|
j failure
|
||||||
|
ssm:
|
||||||
|
ssm ssm_op
|
||||||
|
|
||||||
|
pgm:
|
||||||
|
chhsi program_interruption_code,0x6 /* specification exception? */
|
||||||
|
jne failure
|
||||||
|
cli ilc,6 /* ilc for EXRL? */
|
||||||
|
jne failure
|
||||||
|
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
ssm_op:
|
||||||
|
.byte 0x08 /* bit 4 set */
|
||||||
|
.align 8
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x0800000180000000,expected_pswa /* bit 2 set */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000000000000,0 /* disabled wait */
|
16
tests/tcg/s390x/lgrl-unaligned.S
Normal file
16
tests/tcg/s390x/lgrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test LGRL from a non-doubleword aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
lgrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.long 0
|
||||||
|
unaligned:
|
||||||
|
.quad 0
|
16
tests/tcg/s390x/llgfrl-unaligned.S
Normal file
16
tests/tcg/s390x/llgfrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test LLGFRL from a non-word aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
llgfrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.short 0
|
||||||
|
unaligned:
|
||||||
|
.long 0
|
36
tests/tcg/s390x/lpsw.S
Normal file
36
tests/tcg/s390x/lpsw.S
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Test the LPSW instruction.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.org 0x140
|
||||||
|
svc_old_psw:
|
||||||
|
.org 0x1c0 /* supervisor call new PSW */
|
||||||
|
.quad 0x80000000,svc /* 31-bit mode */
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
lpsw short_psw
|
||||||
|
lpsw_target:
|
||||||
|
svc 0
|
||||||
|
expected_pswa:
|
||||||
|
j failure
|
||||||
|
|
||||||
|
svc:
|
||||||
|
clc svc_old_psw(16),expected_psw /* correct full PSW? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
short_psw:
|
||||||
|
.long 0x90001,0x80000000+lpsw_target /* problem state,
|
||||||
|
64-bit mode */
|
||||||
|
expected_psw:
|
||||||
|
.quad 0x1000180000000,expected_pswa /* corresponds to short_psw */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000000000000,0 /* disabled wait */
|
38
tests/tcg/s390x/lpswe-early.S
Normal file
38
tests/tcg/s390x/lpswe-early.S
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Test early exception recognition using LPSWE.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.org 0x8d
|
||||||
|
ilc:
|
||||||
|
.org 0x8e
|
||||||
|
program_interruption_code:
|
||||||
|
.org 0x150
|
||||||
|
program_old_psw:
|
||||||
|
.org 0x1D0 /* program new PSW */
|
||||||
|
.quad 0,pgm
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
lpswe bad_psw
|
||||||
|
j failure
|
||||||
|
|
||||||
|
pgm:
|
||||||
|
chhsi program_interruption_code,0x6 /* specification exception? */
|
||||||
|
jne failure
|
||||||
|
cli ilc,0 /* ilc zero? */
|
||||||
|
jne failure
|
||||||
|
clc program_old_psw(16),bad_psw /* correct old PSW? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
bad_psw:
|
||||||
|
.quad 0x8000000000000000,0xfedcba9876543210 /* bit 0 set */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000000000000,0 /* disabled wait */
|
18
tests/tcg/s390x/lpswe-unaligned.S
Normal file
18
tests/tcg/s390x/lpswe-unaligned.S
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Test LPSWE from a non-doubleword aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
larl %r1,unaligned
|
||||||
|
fail:
|
||||||
|
lpswe 0(%r1)
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,fail
|
||||||
|
.long 0
|
||||||
|
unaligned:
|
||||||
|
.quad 0
|
16
tests/tcg/s390x/lrl-unaligned.S
Normal file
16
tests/tcg/s390x/lrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test LRL from a non-word aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
lrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.short 0
|
||||||
|
unaligned:
|
||||||
|
.long 0
|
40
tests/tcg/s390x/pgm-specification-softmmu.S
Normal file
40
tests/tcg/s390x/pgm-specification-softmmu.S
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Common softmmu code for specification exception testing.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.section .head
|
||||||
|
.org 0x8d
|
||||||
|
ilc:
|
||||||
|
.org 0x8e
|
||||||
|
program_interruption_code:
|
||||||
|
.org 0x150
|
||||||
|
program_old_psw:
|
||||||
|
.org 0x1D0 /* program new PSW */
|
||||||
|
.quad 0x180000000,pgm /* 64-bit mode */
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
lpswe test_psw
|
||||||
|
|
||||||
|
pgm:
|
||||||
|
chhsi program_interruption_code,0x6 /* PGM_SPECIFICATION? */
|
||||||
|
jne failure
|
||||||
|
lg %r0,expected_old_psw+8 /* ilc adjustment */
|
||||||
|
llgc %r1,ilc
|
||||||
|
agr %r0,%r1
|
||||||
|
stg %r0,expected_old_psw+8
|
||||||
|
clc expected_old_psw(16),program_old_psw /* correct location? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
test_psw:
|
||||||
|
.quad 0x180000000,test /* 64-bit mode */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000180000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000180000000,0 /* disabled wait */
|
37
tests/tcg/s390x/pgm-specification-user.c
Normal file
37
tests/tcg/s390x/pgm-specification-user.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Common user code for specification exception testing.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern void test(void);
|
||||||
|
extern long expected_old_psw[2];
|
||||||
|
|
||||||
|
static void handle_sigill(int sig, siginfo_t *info, void *ucontext)
|
||||||
|
{
|
||||||
|
if ((long)info->si_addr != expected_old_psw[1]) {
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
memset(&act, 0, sizeof(act));
|
||||||
|
act.sa_sigaction = handle_sigill;
|
||||||
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
err = sigaction(SIGILL, &act, NULL);
|
||||||
|
assert(err == 0);
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
15
tests/tcg/s390x/pgm-specification.mak
Normal file
15
tests/tcg/s390x/pgm-specification.mak
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
# List of specification exception tests.
|
||||||
|
# Shared between the softmmu and the user makefiles.
|
||||||
|
PGM_SPECIFICATION_TESTS = \
|
||||||
|
br-odd \
|
||||||
|
cgrl-unaligned \
|
||||||
|
clrl-unaligned \
|
||||||
|
crl-unaligned \
|
||||||
|
ex-odd \
|
||||||
|
lgrl-unaligned \
|
||||||
|
llgfrl-unaligned \
|
||||||
|
lpswe-unaligned \
|
||||||
|
lrl-unaligned \
|
||||||
|
stgrl-unaligned \
|
||||||
|
strl-unaligned
|
46
tests/tcg/s390x/rxsbg.c
Normal file
46
tests/tcg/s390x/rxsbg.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Test the RXSBG instruction.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static inline __attribute__((__always_inline__)) void
|
||||||
|
rxsbg(unsigned long *r1, unsigned long r2, int i3, int i4, int i5, int *cc)
|
||||||
|
{
|
||||||
|
asm("rxsbg %[r1],%[r2],%[i3],%[i4],%[i5]\n"
|
||||||
|
"ipm %[cc]"
|
||||||
|
: [r1] "+r" (*r1), [cc] "=r" (*cc)
|
||||||
|
: [r2] "r" (r2) , [i3] "i" (i3) , [i4] "i" (i4) , [i5] "i" (i5)
|
||||||
|
: "cc");
|
||||||
|
*cc = (*cc >> 28) & 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_cc0(void)
|
||||||
|
{
|
||||||
|
unsigned long r1 = 6;
|
||||||
|
int cc;
|
||||||
|
|
||||||
|
rxsbg(&r1, 3, 61 | 0x80, 62, 1, &cc);
|
||||||
|
assert(r1 == 6);
|
||||||
|
assert(cc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_cc1(void)
|
||||||
|
{
|
||||||
|
unsigned long r1 = 2;
|
||||||
|
int cc;
|
||||||
|
|
||||||
|
rxsbg(&r1, 3, 61 | 0x80, 62, 1, &cc);
|
||||||
|
assert(r1 == 2);
|
||||||
|
assert(cc == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_cc0();
|
||||||
|
test_cc1();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
20
tests/tcg/s390x/softmmu.ld
Normal file
20
tests/tcg/s390x/softmmu.ld
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Linker script for the softmmu test kernels.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.head)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(*)
|
||||||
|
}
|
||||||
|
}
|
41
tests/tcg/s390x/ssm-early.S
Normal file
41
tests/tcg/s390x/ssm-early.S
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Test early exception recognition using SSM.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.org 0x8d
|
||||||
|
ilc:
|
||||||
|
.org 0x8e
|
||||||
|
program_interruption_code:
|
||||||
|
.org 0x150
|
||||||
|
program_old_psw:
|
||||||
|
.org 0x1D0 /* program new PSW */
|
||||||
|
.quad 0,pgm
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
ssm ssm_op
|
||||||
|
expected_pswa:
|
||||||
|
j failure
|
||||||
|
|
||||||
|
pgm:
|
||||||
|
chhsi program_interruption_code,0x6 /* specification exception? */
|
||||||
|
jne failure
|
||||||
|
cli ilc,4 /* ilc for SSM? */
|
||||||
|
jne failure
|
||||||
|
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
ssm_op:
|
||||||
|
.byte 0x20 /* bit 2 set */
|
||||||
|
.align 8
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x2000000180000000,expected_pswa /* bit 2 set */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000000000000,0 /* disabled wait */
|
16
tests/tcg/s390x/stgrl-unaligned.S
Normal file
16
tests/tcg/s390x/stgrl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test STGRL to a non-doubleword aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
stgrl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.long 0
|
||||||
|
unaligned:
|
||||||
|
.quad 0
|
41
tests/tcg/s390x/stosm-early.S
Normal file
41
tests/tcg/s390x/stosm-early.S
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Test early exception recognition using STOSM.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.org 0x8d
|
||||||
|
ilc:
|
||||||
|
.org 0x8e
|
||||||
|
program_interruption_code:
|
||||||
|
.org 0x150
|
||||||
|
program_old_psw:
|
||||||
|
.org 0x1D0 /* program new PSW */
|
||||||
|
.quad 0,pgm
|
||||||
|
.org 0x200 /* lowcore padding */
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
stosm ssm_op,0x10 /* bit 3 set */
|
||||||
|
expected_pswa:
|
||||||
|
j failure
|
||||||
|
|
||||||
|
pgm:
|
||||||
|
chhsi program_interruption_code,0x6 /* specification exception? */
|
||||||
|
jne failure
|
||||||
|
cli ilc,4 /* ilc for STOSM? */
|
||||||
|
jne failure
|
||||||
|
clc program_old_psw(16),expected_old_psw /* correct old PSW? */
|
||||||
|
jne failure
|
||||||
|
lpswe success_psw
|
||||||
|
failure:
|
||||||
|
lpswe failure_psw
|
||||||
|
|
||||||
|
ssm_op:
|
||||||
|
.byte 0
|
||||||
|
.align 8
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x1000000180000000,expected_pswa /* bit 3 set */
|
||||||
|
success_psw:
|
||||||
|
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
|
||||||
|
failure_psw:
|
||||||
|
.quad 0x2000000000000,0 /* disabled wait */
|
16
tests/tcg/s390x/strl-unaligned.S
Normal file
16
tests/tcg/s390x/strl-unaligned.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Test STRL to a non-word aligned address.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
.globl test
|
||||||
|
test:
|
||||||
|
strl %r1,unaligned
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.globl expected_old_psw
|
||||||
|
expected_old_psw:
|
||||||
|
.quad 0x180000000,test
|
||||||
|
.short 0
|
||||||
|
unaligned:
|
||||||
|
.long 0
|
@ -531,6 +531,13 @@ int main(int argc, char **argv)
|
|||||||
g_test_add_func("/blockjob/cancel/standby", test_cancel_standby);
|
g_test_add_func("/blockjob/cancel/standby", test_cancel_standby);
|
||||||
g_test_add_func("/blockjob/cancel/pending", test_cancel_pending);
|
g_test_add_func("/blockjob/cancel/pending", test_cancel_pending);
|
||||||
g_test_add_func("/blockjob/cancel/concluded", test_cancel_concluded);
|
g_test_add_func("/blockjob/cancel/concluded", test_cancel_concluded);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test is flaky and sometimes fails in CI and otherwise:
|
||||||
|
* don't run unless user opts in via environment variable.
|
||||||
|
*/
|
||||||
|
if (getenv("QEMU_TEST_FLAKY_TESTS")) {
|
||||||
g_test_add_func("/blockjob/complete_in_standby", test_complete_in_standby);
|
g_test_add_func("/blockjob/complete_in_standby", test_complete_in_standby);
|
||||||
|
}
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user