mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-19 08:02:15 -06:00
* Fix emulation of the SET CLOCK instruction
* Fix the s390x avocado test with Fedora * Update the s390x Travis jobs to Focal (instead of Bionic) * Implement the z15 Misc Instruction Extension 3 Facility -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmIcpUcRHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbVKwxAAs3ImvYQR2EuyN4Zxfe37B3z2hhyplAS3 dVbBEJU5NlEqMHp4XODDeYL9aDXSvwgm9hOcBHwp77imSjPwz6JhpJOgsBNBboHT tDcGw75bcwidDcYCQqpCTYkaTwGmQ0mn3lG2XBYU1QiSCDYjsV/7HBY6M52Bvie8 rrMMNGhkD0lLN48gDXptF5Vo8YZTSk6lxkWa/6QfsFNfyLqobAQAs6ubngXsZARg m9RPiX+MVZ/yXU46k5cjIMAsXCdnwewMOC3WV7kSiBhpAO0vnr5J0CT1lHXKZ6lS chQ8L7G/Gmyos0ly8peHt14DUkNlDjV02XPL2eoXr4oapAZsSTSKRiYdwI59Taje 4D1fHn9mUc43iiqOa3QnosGvtsLVoozY03Fk6XKBFbQYGcR721cHmeUOBaxw+0rA T3eoryYVb08ukc5Jn5fW5i4BPskrUC8eTSTxaQUMD8vkRBH49DatRe0XQTHumR7F XD7hIcTq2SaIO9UE7XjBp/wpJ80vjBvgK4VheFdWW6z0bxNrGFF/I2EXl3cwiaUD mJoF9pFQyzhvflzuBn0FeJuNWGjClHqeb1e9Cmq/acONeWrXbwIO/6S4vo0B47e6 09OklxecdDqxM4pmPoXMWF2KZAzp1WLb6sfYtkV2lwDQwaisXYBN3ybKyScOpX9V rtQtKMb94+E= =lS9b -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2022-02-28' into staging * Fix emulation of the SET CLOCK instruction * Fix the s390x avocado test with Fedora * Update the s390x Travis jobs to Focal (instead of Bionic) * Implement the z15 Misc Instruction Extension 3 Facility # gpg: Signature made Mon 28 Feb 2022 10:34:47 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 * remotes/thuth-gitlab/tags/pull-request-2022-02-28: tests/tcg/s390x: Tests for Miscellaneous-Instruction-Extensions Facility 3 s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z15 GA1 s390x/tcg: Implement Miscellaneous-Instruction-Extensions Facility 3 for the s390x travis.yml: Update the s390x jobs to Ubuntu Focal tests/avocado/machine_s390_ccw_virtio: Adapt test to new default resolution s390x: sck: load into a temporary not into in1 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
99c53410bc
13 changed files with 241 additions and 20 deletions
12
.travis.yml
12
.travis.yml
|
@ -1,6 +1,3 @@
|
||||||
# The current Travis default is a VM based 16.04 Xenial on GCE
|
|
||||||
# Additional builds with specific requirements for a full VM need to
|
|
||||||
# be added as additional matrix: entries later on
|
|
||||||
os: linux
|
os: linux
|
||||||
dist: focal
|
dist: focal
|
||||||
language: c
|
language: c
|
||||||
|
@ -190,7 +187,7 @@ jobs:
|
||||||
|
|
||||||
- name: "[s390x] GCC check-tcg"
|
- name: "[s390x] GCC check-tcg"
|
||||||
arch: s390x
|
arch: s390x
|
||||||
dist: bionic
|
dist: focal
|
||||||
addons:
|
addons:
|
||||||
apt_packages:
|
apt_packages:
|
||||||
- libaio-dev
|
- libaio-dev
|
||||||
|
@ -233,7 +230,7 @@ jobs:
|
||||||
|
|
||||||
- name: "[s390x] GCC (other-softmmu)"
|
- name: "[s390x] GCC (other-softmmu)"
|
||||||
arch: s390x
|
arch: s390x
|
||||||
dist: bionic
|
dist: focal
|
||||||
addons:
|
addons:
|
||||||
apt_packages:
|
apt_packages:
|
||||||
- libaio-dev
|
- libaio-dev
|
||||||
|
@ -263,10 +260,11 @@ jobs:
|
||||||
|
|
||||||
- name: "[s390x] GCC (user)"
|
- name: "[s390x] GCC (user)"
|
||||||
arch: s390x
|
arch: s390x
|
||||||
dist: bionic
|
dist: focal
|
||||||
addons:
|
addons:
|
||||||
apt_packages:
|
apt_packages:
|
||||||
- libgcrypt20-dev
|
- libgcrypt20-dev
|
||||||
|
- libglib2.0-dev
|
||||||
- libgnutls28-dev
|
- libgnutls28-dev
|
||||||
- ninja-build
|
- ninja-build
|
||||||
env:
|
env:
|
||||||
|
@ -274,7 +272,7 @@ jobs:
|
||||||
|
|
||||||
- name: "[s390x] Clang (disable-tcg)"
|
- name: "[s390x] Clang (disable-tcg)"
|
||||||
arch: s390x
|
arch: s390x
|
||||||
dist: bionic
|
dist: focal
|
||||||
compiler: clang
|
compiler: clang
|
||||||
addons:
|
addons:
|
||||||
apt_packages:
|
apt_packages:
|
||||||
|
|
|
@ -802,7 +802,10 @@ DEFINE_CCW_MACHINE(7_0, "7.0", true);
|
||||||
|
|
||||||
static void ccw_machine_6_2_instance_options(MachineState *machine)
|
static void ccw_machine_6_2_instance_options(MachineState *machine)
|
||||||
{
|
{
|
||||||
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
|
||||||
|
|
||||||
ccw_machine_7_0_instance_options(machine);
|
ccw_machine_7_0_instance_options(machine);
|
||||||
|
s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccw_machine_6_2_class_options(MachineClass *mc)
|
static void ccw_machine_6_2_class_options(MachineClass *mc)
|
||||||
|
|
|
@ -86,9 +86,9 @@ static S390CPUDef s390_cpu_defs[] = {
|
||||||
CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"),
|
CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QEMU_MAX_CPU_TYPE 0x3906
|
#define QEMU_MAX_CPU_TYPE 0x8561
|
||||||
#define QEMU_MAX_CPU_GEN 14
|
#define QEMU_MAX_CPU_GEN 15
|
||||||
#define QEMU_MAX_CPU_EC_GA 2
|
#define QEMU_MAX_CPU_EC_GA 1
|
||||||
static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
|
static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
|
||||||
static S390FeatBitmap qemu_max_cpu_feat;
|
static S390FeatBitmap qemu_max_cpu_feat;
|
||||||
|
|
||||||
|
|
|
@ -731,13 +731,16 @@ static uint16_t qemu_V6_0[] = {
|
||||||
S390_FEAT_ESOP,
|
S390_FEAT_ESOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint16_t qemu_LATEST[] = {
|
static uint16_t qemu_V6_2[] = {
|
||||||
S390_FEAT_INSTRUCTION_EXEC_PROT,
|
S390_FEAT_INSTRUCTION_EXEC_PROT,
|
||||||
S390_FEAT_MISC_INSTRUCTION_EXT2,
|
S390_FEAT_MISC_INSTRUCTION_EXT2,
|
||||||
S390_FEAT_MSA_EXT_8,
|
S390_FEAT_MSA_EXT_8,
|
||||||
S390_FEAT_VECTOR_ENH,
|
S390_FEAT_VECTOR_ENH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint16_t qemu_LATEST[] = {
|
||||||
|
S390_FEAT_MISC_INSTRUCTION_EXT3,
|
||||||
|
};
|
||||||
/* add all new definitions before this point */
|
/* add all new definitions before this point */
|
||||||
static uint16_t qemu_MAX[] = {
|
static uint16_t qemu_MAX[] = {
|
||||||
/* generates a dependency warning, leave it out for now */
|
/* generates a dependency warning, leave it out for now */
|
||||||
|
@ -862,6 +865,7 @@ static FeatGroupDefSpec QemuFeatDef[] = {
|
||||||
QEMU_FEAT_INITIALIZER(V4_0),
|
QEMU_FEAT_INITIALIZER(V4_0),
|
||||||
QEMU_FEAT_INITIALIZER(V4_1),
|
QEMU_FEAT_INITIALIZER(V4_1),
|
||||||
QEMU_FEAT_INITIALIZER(V6_0),
|
QEMU_FEAT_INITIALIZER(V6_0),
|
||||||
|
QEMU_FEAT_INITIALIZER(V6_2),
|
||||||
QEMU_FEAT_INITIALIZER(LATEST),
|
QEMU_FEAT_INITIALIZER(LATEST),
|
||||||
QEMU_FEAT_INITIALIZER(MAX),
|
QEMU_FEAT_INITIALIZER(MAX),
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@ DEF_HELPER_FLAGS_4(nc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
||||||
DEF_HELPER_FLAGS_4(oc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
DEF_HELPER_FLAGS_4(oc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
||||||
DEF_HELPER_FLAGS_4(xc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
DEF_HELPER_FLAGS_4(xc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
||||||
DEF_HELPER_FLAGS_4(mvc, TCG_CALL_NO_WG, void, env, i32, i64, i64)
|
DEF_HELPER_FLAGS_4(mvc, TCG_CALL_NO_WG, void, env, i32, i64, i64)
|
||||||
|
DEF_HELPER_FLAGS_4(mvcrl, TCG_CALL_NO_WG, void, env, i64, i64, i64)
|
||||||
DEF_HELPER_FLAGS_4(mvcin, TCG_CALL_NO_WG, void, env, i32, i64, i64)
|
DEF_HELPER_FLAGS_4(mvcin, TCG_CALL_NO_WG, void, env, i32, i64, i64)
|
||||||
DEF_HELPER_FLAGS_4(clc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
DEF_HELPER_FLAGS_4(clc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
|
||||||
DEF_HELPER_3(mvcl, i32, env, i32, i32)
|
DEF_HELPER_3(mvcl, i32, env, i32, i32)
|
||||||
|
|
|
@ -105,6 +105,9 @@
|
||||||
D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000)
|
D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000)
|
||||||
D(0x9400, NI, SI, Z, la1, i2_8u, new, 0, ni, nz64, MO_UB)
|
D(0x9400, NI, SI, Z, la1, i2_8u, new, 0, ni, nz64, MO_UB)
|
||||||
D(0xeb54, NIY, SIY, LD, la1, i2_8u, new, 0, ni, nz64, MO_UB)
|
D(0xeb54, NIY, SIY, LD, la1, i2_8u, new, 0, ni, nz64, MO_UB)
|
||||||
|
/* AND WITH COMPLEMENT */
|
||||||
|
C(0xb9f5, NCRK, RRF_a, MIE3, r2, r3, new, r1_32, andc, nz32)
|
||||||
|
C(0xb9e5, NCGRK, RRF_a, MIE3, r2, r3, r1, 0, andc, nz64)
|
||||||
|
|
||||||
/* BRANCH AND LINK */
|
/* BRANCH AND LINK */
|
||||||
C(0x0500, BALR, RR_a, Z, 0, r2_nz, r1, 0, bal, 0)
|
C(0x0500, BALR, RR_a, Z, 0, r2_nz, r1, 0, bal, 0)
|
||||||
|
@ -640,6 +643,8 @@
|
||||||
C(0xeb8e, MVCLU, RSY_a, E2, 0, a2, 0, 0, mvclu, 0)
|
C(0xeb8e, MVCLU, RSY_a, E2, 0, a2, 0, 0, mvclu, 0)
|
||||||
/* MOVE NUMERICS */
|
/* MOVE NUMERICS */
|
||||||
C(0xd100, MVN, SS_a, Z, la1, a2, 0, 0, mvn, 0)
|
C(0xd100, MVN, SS_a, Z, la1, a2, 0, 0, mvn, 0)
|
||||||
|
/* MOVE RIGHT TO LEFT */
|
||||||
|
C(0xe50a, MVCRL, SSE, MIE3, la1, a2, 0, 0, mvcrl, 0)
|
||||||
/* MOVE PAGE */
|
/* MOVE PAGE */
|
||||||
C(0xb254, MVPG, RRE, Z, 0, 0, 0, 0, mvpg, 0)
|
C(0xb254, MVPG, RRE, Z, 0, 0, 0, 0, mvpg, 0)
|
||||||
/* MOVE STRING */
|
/* MOVE STRING */
|
||||||
|
@ -707,6 +712,16 @@
|
||||||
F(0xed0f, MSEB, RXF, Z, e1, m2_32u, new, e1, mseb, 0, IF_BFP)
|
F(0xed0f, MSEB, RXF, Z, e1, m2_32u, new, e1, mseb, 0, IF_BFP)
|
||||||
F(0xed1f, MSDB, RXF, Z, f1, m2_64, new, f1, msdb, 0, IF_BFP)
|
F(0xed1f, MSDB, RXF, Z, f1, m2_64, new, f1, msdb, 0, IF_BFP)
|
||||||
|
|
||||||
|
/* NAND */
|
||||||
|
C(0xb974, NNRK, RRF_a, MIE3, r2, r3, new, r1_32, nand, nz32)
|
||||||
|
C(0xb964, NNGRK, RRF_a, MIE3, r2, r3, r1, 0, nand, nz64)
|
||||||
|
/* NOR */
|
||||||
|
C(0xb976, NORK, RRF_a, MIE3, r2, r3, new, r1_32, nor, nz32)
|
||||||
|
C(0xb966, NOGRK, RRF_a, MIE3, r2, r3, r1, 0, nor, nz64)
|
||||||
|
/* NOT EXCLUSIVE OR */
|
||||||
|
C(0xb977, NXRK, RRF_a, MIE3, r2, r3, new, r1_32, nxor, nz32)
|
||||||
|
C(0xb967, NXGRK, RRF_a, MIE3, r2, r3, r1, 0, nxor, nz64)
|
||||||
|
|
||||||
/* OR */
|
/* OR */
|
||||||
C(0x1600, OR, RR_a, Z, r1, r2, new, r1_32, or, nz32)
|
C(0x1600, OR, RR_a, Z, r1, r2, new, r1_32, or, nz32)
|
||||||
C(0xb9f6, ORK, RRF_a, DO, r2, r3, new, r1_32, or, nz32)
|
C(0xb9f6, ORK, RRF_a, DO, r2, r3, new, r1_32, or, nz32)
|
||||||
|
@ -725,6 +740,9 @@
|
||||||
D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000)
|
D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000)
|
||||||
D(0x9600, OI, SI, Z, la1, i2_8u, new, 0, oi, nz64, MO_UB)
|
D(0x9600, OI, SI, Z, la1, i2_8u, new, 0, oi, nz64, MO_UB)
|
||||||
D(0xeb56, OIY, SIY, LD, la1, i2_8u, new, 0, oi, nz64, MO_UB)
|
D(0xeb56, OIY, SIY, LD, la1, i2_8u, new, 0, oi, nz64, MO_UB)
|
||||||
|
/* OR WITH COMPLEMENT */
|
||||||
|
C(0xb975, OCRK, RRF_a, MIE3, r2, r3, new, r1_32, orc, nz32)
|
||||||
|
C(0xb965, OCGRK, RRF_a, MIE3, r2, r3, r1, 0, orc, nz64)
|
||||||
|
|
||||||
/* PACK */
|
/* PACK */
|
||||||
/* Really format SS_b, but we pack both lengths into one argument
|
/* Really format SS_b, but we pack both lengths into one argument
|
||||||
|
@ -735,6 +753,9 @@
|
||||||
/* PACK UNICODE */
|
/* PACK UNICODE */
|
||||||
C(0xe100, PKU, SS_f, E2, la1, a2, 0, 0, pku, 0)
|
C(0xe100, PKU, SS_f, E2, la1, a2, 0, 0, pku, 0)
|
||||||
|
|
||||||
|
/* POPULATION COUNT */
|
||||||
|
C(0xb9e1, POPCNT, RRF_c, PC, 0, r2_o, r1, 0, popcnt, nz64)
|
||||||
|
|
||||||
/* PREFETCH */
|
/* PREFETCH */
|
||||||
/* Implemented as nops of course. */
|
/* Implemented as nops of course. */
|
||||||
C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0)
|
C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0)
|
||||||
|
@ -743,9 +764,6 @@
|
||||||
/* Implemented as nop of course. */
|
/* Implemented as nop of course. */
|
||||||
C(0xb2e8, PPA, RRF_c, PPA, 0, 0, 0, 0, 0, 0)
|
C(0xb2e8, PPA, RRF_c, PPA, 0, 0, 0, 0, 0, 0)
|
||||||
|
|
||||||
/* POPULATION COUNT */
|
|
||||||
C(0xb9e1, POPCNT, RRE, PC, 0, r2_o, r1, 0, popcnt, nz64)
|
|
||||||
|
|
||||||
/* ROTATE LEFT SINGLE LOGICAL */
|
/* ROTATE LEFT SINGLE LOGICAL */
|
||||||
C(0xeb1d, RLL, RSY_a, Z, r3_o, sh, new, r1_32, rll32, 0)
|
C(0xeb1d, RLL, RSY_a, Z, r3_o, sh, new, r1_32, rll32, 0)
|
||||||
C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh, r1, 0, rll64, 0)
|
C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh, r1, 0, rll64, 0)
|
||||||
|
@ -765,6 +783,12 @@
|
||||||
/* SEARCH STRING UNICODE */
|
/* SEARCH STRING UNICODE */
|
||||||
C(0xb9be, SRSTU, RRE, ETF3, 0, 0, 0, 0, srstu, 0)
|
C(0xb9be, SRSTU, RRE, ETF3, 0, 0, 0, 0, srstu, 0)
|
||||||
|
|
||||||
|
/* SELECT */
|
||||||
|
C(0xb9f0, SELR, RRF_a, MIE3, r3, r2, new, r1_32, loc, 0)
|
||||||
|
C(0xb9e3, SELGR, RRF_a, MIE3, r3, r2, r1, 0, loc, 0)
|
||||||
|
/* SELECT HIGH */
|
||||||
|
C(0xb9c0, SELFHR, RRF_a, MIE3, r3_sr32, r2_sr32, new, r1_32h, loc, 0)
|
||||||
|
|
||||||
/* SET ACCESS */
|
/* SET ACCESS */
|
||||||
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
|
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
|
||||||
/* SET ADDRESSING MODE */
|
/* SET ADDRESSING MODE */
|
||||||
|
@ -1317,7 +1341,7 @@
|
||||||
/* SET ADDRESS SPACE CONTROL FAST */
|
/* SET ADDRESS SPACE CONTROL FAST */
|
||||||
F(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0, IF_PRIV)
|
F(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0, IF_PRIV)
|
||||||
/* SET CLOCK */
|
/* SET CLOCK */
|
||||||
F(0xb204, SCK, S, Z, la2, 0, 0, 0, sck, 0, IF_PRIV | IF_IO)
|
F(0xb204, SCK, S, Z, 0, m2_64a, 0, 0, sck, 0, IF_PRIV | IF_IO)
|
||||||
/* SET CLOCK COMPARATOR */
|
/* SET CLOCK COMPARATOR */
|
||||||
F(0xb206, SCKC, S, Z, 0, m2_64a, 0, 0, sckc, 0, IF_PRIV | IF_IO)
|
F(0xb206, SCKC, S, Z, 0, m2_64a, 0, 0, sckc, 0, IF_PRIV | IF_IO)
|
||||||
/* SET CLOCK PROGRAMMABLE FIELD */
|
/* SET CLOCK PROGRAMMABLE FIELD */
|
||||||
|
|
|
@ -547,6 +547,26 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||||
do_helper_mvc(env, l, dest, src, GETPC());
|
do_helper_mvc(env, l, dest, src, GETPC());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* move right to left */
|
||||||
|
void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src)
|
||||||
|
{
|
||||||
|
const int mmu_idx = cpu_mmu_index(env, false);
|
||||||
|
const uint64_t ra = GETPC();
|
||||||
|
S390Access srca, desta;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
/* MVCRL always copies one more byte than specified - maximum is 256 */
|
||||||
|
l++;
|
||||||
|
|
||||||
|
srca = access_prepare(env, src, l, MMU_DATA_LOAD, mmu_idx, ra);
|
||||||
|
desta = access_prepare(env, dest, l, MMU_DATA_STORE, mmu_idx, ra);
|
||||||
|
|
||||||
|
for (i = l - 1; i >= 0; i--) {
|
||||||
|
uint8_t byte = access_get_byte(env, &srca, i, ra);
|
||||||
|
access_set_byte(env, &desta, i, byte, ra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* move inverse */
|
/* move inverse */
|
||||||
void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1498,6 +1498,36 @@ static DisasJumpType op_andi(DisasContext *s, DisasOps *o)
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_andc(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
tcg_gen_andc_i64(o->out, o->in1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_orc(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
tcg_gen_orc_i64(o->out, o->in1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_nand(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
tcg_gen_nand_i64(o->out, o->in1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_nor(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
tcg_gen_nor_i64(o->out, o->in1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_nxor(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
tcg_gen_eqv_i64(o->out, o->in1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in1 = tcg_temp_new_i64();
|
o->in1 = tcg_temp_new_i64();
|
||||||
|
@ -2958,7 +2988,13 @@ static DisasJumpType op_loc(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
DisasCompare c;
|
DisasCompare c;
|
||||||
|
|
||||||
disas_jcc(s, &c, get_field(s, m3));
|
if (have_field(s, m3)) {
|
||||||
|
/* LOAD * ON CONDITION */
|
||||||
|
disas_jcc(s, &c, get_field(s, m3));
|
||||||
|
} else {
|
||||||
|
/* SELECT */
|
||||||
|
disas_jcc(s, &c, get_field(s, m4));
|
||||||
|
}
|
||||||
|
|
||||||
if (c.is_64) {
|
if (c.is_64) {
|
||||||
tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
|
tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
|
||||||
|
@ -3358,6 +3394,12 @@ static DisasJumpType op_mvc(DisasContext *s, DisasOps *o)
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DisasJumpType op_mvcrl(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
gen_helper_mvcrl(cpu_env, regs[0], o->addr1, o->in2);
|
||||||
|
return DISAS_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
TCGv_i32 l = tcg_const_i32(get_field(s, l1));
|
TCGv_i32 l = tcg_const_i32(get_field(s, l1));
|
||||||
|
@ -3744,7 +3786,13 @@ static DisasJumpType op_pku(DisasContext *s, DisasOps *o)
|
||||||
|
|
||||||
static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
gen_helper_popcnt(o->out, o->in2);
|
const uint8_t m3 = get_field(s, m3);
|
||||||
|
|
||||||
|
if ((m3 & 8) && s390_has_feat(S390_FEAT_MISC_INSTRUCTION_EXT3)) {
|
||||||
|
tcg_gen_ctpop_i64(o->out, o->in2);
|
||||||
|
} else {
|
||||||
|
gen_helper_popcnt(o->out, o->in2);
|
||||||
|
}
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4290,8 +4338,7 @@ static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEUQ | MO_ALIGN);
|
gen_helper_sck(cc_op, cpu_env, o->in2);
|
||||||
gen_helper_sck(cc_op, cpu_env, o->in1);
|
|
||||||
set_cc_static(s);
|
set_cc_static(s);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
@ -5668,6 +5715,13 @@ static void in1_r3_D32(DisasContext *s, DisasOps *o)
|
||||||
}
|
}
|
||||||
#define SPEC_in1_r3_D32 SPEC_r3_even
|
#define SPEC_in1_r3_D32 SPEC_r3_even
|
||||||
|
|
||||||
|
static void in1_r3_sr32(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
o->in1 = tcg_temp_new_i64();
|
||||||
|
tcg_gen_shri_i64(o->in1, regs[get_field(s, r3)], 32);
|
||||||
|
}
|
||||||
|
#define SPEC_in1_r3_sr32 0
|
||||||
|
|
||||||
static void in1_e1(DisasContext *s, DisasOps *o)
|
static void in1_e1(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in1 = load_freg32_i64(get_field(s, r1));
|
o->in1 = load_freg32_i64(get_field(s, r1));
|
||||||
|
@ -6170,6 +6224,7 @@ enum DisasInsnEnum {
|
||||||
#define FAC_V S390_FEAT_VECTOR /* vector facility */
|
#define FAC_V S390_FEAT_VECTOR /* vector facility */
|
||||||
#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
|
#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
|
||||||
#define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
|
#define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
|
||||||
|
#define FAC_MIE3 S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */
|
||||||
|
|
||||||
static const DisasInsn insn_info[] = {
|
static const DisasInsn insn_info[] = {
|
||||||
#include "insn-data.def"
|
#include "insn-data.def"
|
||||||
|
|
|
@ -248,7 +248,7 @@ class S390CCWVirtioMachine(QemuSystemTest):
|
||||||
line = ppmfile.readline()
|
line = ppmfile.readline()
|
||||||
self.assertEqual(line, b"P6\n")
|
self.assertEqual(line, b"P6\n")
|
||||||
line = ppmfile.readline()
|
line = ppmfile.readline()
|
||||||
self.assertEqual(line, b"1024 768\n")
|
self.assertEqual(line, b"1280 800\n")
|
||||||
line = ppmfile.readline()
|
line = ppmfile.readline()
|
||||||
self.assertEqual(line, b"255\n")
|
self.assertEqual(line, b"255\n")
|
||||||
line = ppmfile.readline(256)
|
line = ppmfile.readline(256)
|
||||||
|
|
|
@ -7,6 +7,9 @@ TESTS+=ipm
|
||||||
TESTS+=exrl-trt
|
TESTS+=exrl-trt
|
||||||
TESTS+=exrl-trtr
|
TESTS+=exrl-trtr
|
||||||
TESTS+=pack
|
TESTS+=pack
|
||||||
|
TESTS+=mie3-compl
|
||||||
|
TESTS+=mie3-mvcrl
|
||||||
|
TESTS+=mie3-sel
|
||||||
TESTS+=mvo
|
TESTS+=mvo
|
||||||
TESTS+=mvc
|
TESTS+=mvc
|
||||||
TESTS+=shift
|
TESTS+=shift
|
||||||
|
|
48
tests/tcg/s390x/mie3-compl.c
Normal file
48
tests/tcg/s390x/mie3-compl.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
|
||||||
|
{ \
|
||||||
|
uint64_t res = 0; \
|
||||||
|
asm ("llihf %[res],801\n" ASM \
|
||||||
|
: [res]"=&r"(res) : [a]"r"(a), [b]"r"(b) : "cc"); \
|
||||||
|
return res; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AND WITH COMPLEMENT */
|
||||||
|
FbinOp(_ncrk, ".insn rrf, 0xB9F50000, %[res], %[b], %[a], 0\n")
|
||||||
|
FbinOp(_ncgrk, ".insn rrf, 0xB9E50000, %[res], %[b], %[a], 0\n")
|
||||||
|
|
||||||
|
/* NAND */
|
||||||
|
FbinOp(_nnrk, ".insn rrf, 0xB9740000, %[res], %[b], %[a], 0\n")
|
||||||
|
FbinOp(_nngrk, ".insn rrf, 0xB9640000, %[res], %[b], %[a], 0\n")
|
||||||
|
|
||||||
|
/* NOT XOR */
|
||||||
|
FbinOp(_nxrk, ".insn rrf, 0xB9770000, %[res], %[b], %[a], 0\n")
|
||||||
|
FbinOp(_nxgrk, ".insn rrf, 0xB9670000, %[res], %[b], %[a], 0\n")
|
||||||
|
|
||||||
|
/* NOR */
|
||||||
|
FbinOp(_nork, ".insn rrf, 0xB9760000, %[res], %[b], %[a], 0\n")
|
||||||
|
FbinOp(_nogrk, ".insn rrf, 0xB9660000, %[res], %[b], %[a], 0\n")
|
||||||
|
|
||||||
|
/* OR WITH COMPLEMENT */
|
||||||
|
FbinOp(_ocrk, ".insn rrf, 0xB9750000, %[res], %[b], %[a], 0\n")
|
||||||
|
FbinOp(_ocgrk, ".insn rrf, 0xB9650000, %[res], %[b], %[a], 0\n")
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (_ncrk(0xFF88, 0xAA11) != 0x0000032100000011ull ||
|
||||||
|
_nnrk(0xFF88, 0xAA11) != 0x00000321FFFF55FFull ||
|
||||||
|
_nork(0xFF88, 0xAA11) != 0x00000321FFFF0066ull ||
|
||||||
|
_nxrk(0xFF88, 0xAA11) != 0x00000321FFFFAA66ull ||
|
||||||
|
_ocrk(0xFF88, 0xAA11) != 0x00000321FFFFAA77ull ||
|
||||||
|
_ncgrk(0xFF88, 0xAA11) != 0x0000000000000011ull ||
|
||||||
|
_nngrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFF55FFull ||
|
||||||
|
_nogrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFF0066ull ||
|
||||||
|
_nxgrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFFAA66ull ||
|
||||||
|
_ocgrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFFAA77ull)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
27
tests/tcg/s390x/mie3-mvcrl.c
Normal file
27
tests/tcg/s390x/mie3-mvcrl.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static inline void mvcrl_8(const char *dst, const char *src)
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"llill %%r0, 8\n"
|
||||||
|
".insn sse, 0xE50A00000000, 0(%[dst]), 0(%[src])"
|
||||||
|
: : [dst] "d" (dst), [src] "d" (src)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *alpha = "abcdefghijklmnop";
|
||||||
|
|
||||||
|
/* array missing 'i' */
|
||||||
|
char tstr[17] = "abcdefghjklmnop\0" ;
|
||||||
|
|
||||||
|
/* mvcrl reference use: 'open a hole in an array' */
|
||||||
|
mvcrl_8(tstr + 9, tstr + 8);
|
||||||
|
|
||||||
|
/* place missing 'i' */
|
||||||
|
tstr[8] = 'i';
|
||||||
|
|
||||||
|
return strncmp(alpha, tstr, 16ul);
|
||||||
|
}
|
38
tests/tcg/s390x/mie3-sel.c
Normal file
38
tests/tcg/s390x/mie3-sel.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
|
||||||
|
{ \
|
||||||
|
uint64_t res = 0; \
|
||||||
|
asm ( \
|
||||||
|
"lg %%r2, %[a]\n" \
|
||||||
|
"lg %%r3, %[b]\n" \
|
||||||
|
"lg %%r0, %[c]\n" \
|
||||||
|
"ltgr %%r0, %%r0\n" \
|
||||||
|
ASM \
|
||||||
|
"stg %%r0, %[res] " \
|
||||||
|
: [res] "=m" (res) \
|
||||||
|
: [a] "m" (a), \
|
||||||
|
[b] "m" (b), \
|
||||||
|
[c] "m" (c) \
|
||||||
|
: "r0", "r2", \
|
||||||
|
"r3", "r4" \
|
||||||
|
); \
|
||||||
|
return res; \
|
||||||
|
}
|
||||||
|
|
||||||
|
Fi3 (_selre, ".insn rrf, 0xB9F00000, %%r0, %%r3, %%r2, 8\n")
|
||||||
|
Fi3 (_selgrz, ".insn rrf, 0xB9E30000, %%r0, %%r3, %%r2, 8\n")
|
||||||
|
Fi3 (_selfhrnz, ".insn rrf, 0xB9C00000, %%r0, %%r3, %%r2, 7\n")
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
uint64_t a = ~0, b = ~0, c = ~0;
|
||||||
|
a = _selre(0x066600000066ull, 0x066600000006ull, a);
|
||||||
|
b = _selgrz(0xF00D00000005ull, 0xF00D00000055ull, b);
|
||||||
|
c = _selfhrnz(0x043200000044ull, 0x065400000004ull, c);
|
||||||
|
|
||||||
|
return (int) (
|
||||||
|
(0xFFFFFFFF00000066ull != a) ||
|
||||||
|
(0x0000F00D00000005ull != b) ||
|
||||||
|
(0x00000654FFFFFFFFull != c));
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue