* Fix s390x CPU reconfiguration information in the SCLP facility map
* Fix condition code problem in the CLC and LAALG instruction * Fix ordering of the new s390x topology list entries * Add some more files to the MAINTAINERS file * Allow newer versions of Tesseract in the m68k nextcube test -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmVKgksRHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbWIHg//TM3JOpsMEqHKlUKqOJH02mFQrK6H7LG0 BC56FG7T+/mpYs1NTG92t8nCK03C2ZCweQWD7ZulRJAjPhZv+TF5bJEForivU7+k PKEshz9xKCWn2YGyNnf2LA06J1JkF215+KlReOoxwSgj1cPlHfBLQ0DtxmpJJZ1G h5p4d26BbSlwR58HrFWTlhgJMPenl59BETUGIK1FklBxunmZeeijddfniAhOT44y i0u9/H9KCg3tkwBROUy+42QV+ef32kz/yvi5RmYQI5W7PixO4sxH6MYduOjshsu9 wK70f8EOwiZV6lFxqmbV7vxFeNnp5IuaVU7PMBoAkwZqLw99mSFy1+1BabCuL5b+ 3iUTiD4UW48MYwE2Ua6Lit4kpfjhwcp/UYz6pIk6TCBQX6LfzO+nj+rod0GdIpyZ 4Lwm7jBtpTlYkGrsMvpA/qcidOtqPA1lmBTNlY1hFodQF6KWtyObn0w5AM80xeeU /mGxQDz97Bpz7LKZvhu+k38jaWvnJFnl3jF1zet88CYL9YL+YI/k1KjhFafCXb0V 38Xpt5JTWxyLSh2B3gx0OpokX5bftvW9GlLix0HqL7c23uYwR2Bq+Rd6I8SAlk4C uJq6gqP8IFBFHfgbmyqf/fyd/eHxm7J1voIdy9PZyxZ1JYT9A7yu56qV6SJYwCpr aARwui/Dm4o= =y+cC -----END PGP SIGNATURE----- Merge tag 'pull-request-2023-11-07' of https://gitlab.com/thuth/qemu into staging * Fix s390x CPU reconfiguration information in the SCLP facility map * Fix condition code problem in the CLC and LAALG instruction * Fix ordering of the new s390x topology list entries * Add some more files to the MAINTAINERS file * Allow newer versions of Tesseract in the m68k nextcube test # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmVKgksRHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbWIHg//TM3JOpsMEqHKlUKqOJH02mFQrK6H7LG0 # BC56FG7T+/mpYs1NTG92t8nCK03C2ZCweQWD7ZulRJAjPhZv+TF5bJEForivU7+k # PKEshz9xKCWn2YGyNnf2LA06J1JkF215+KlReOoxwSgj1cPlHfBLQ0DtxmpJJZ1G # h5p4d26BbSlwR58HrFWTlhgJMPenl59BETUGIK1FklBxunmZeeijddfniAhOT44y # i0u9/H9KCg3tkwBROUy+42QV+ef32kz/yvi5RmYQI5W7PixO4sxH6MYduOjshsu9 # wK70f8EOwiZV6lFxqmbV7vxFeNnp5IuaVU7PMBoAkwZqLw99mSFy1+1BabCuL5b+ # 3iUTiD4UW48MYwE2Ua6Lit4kpfjhwcp/UYz6pIk6TCBQX6LfzO+nj+rod0GdIpyZ # 4Lwm7jBtpTlYkGrsMvpA/qcidOtqPA1lmBTNlY1hFodQF6KWtyObn0w5AM80xeeU # /mGxQDz97Bpz7LKZvhu+k38jaWvnJFnl3jF1zet88CYL9YL+YI/k1KjhFafCXb0V # 38Xpt5JTWxyLSh2B3gx0OpokX5bftvW9GlLix0HqL7c23uYwR2Bq+Rd6I8SAlk4C # uJq6gqP8IFBFHfgbmyqf/fyd/eHxm7J1voIdy9PZyxZ1JYT9A7yu56qV6SJYwCpr # aARwui/Dm4o= # =y+cC # -----END PGP SIGNATURE----- # gpg: Signature made Wed 08 Nov 2023 02:30:35 HKT # 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-11-07' of https://gitlab.com/thuth/qemu: target/s390x/cpu topology: Fix ordering and creation of TLEs tests/tcg/s390x: Test ADD LOGICAL WITH CARRY tests/tcg/s390x: Test LAALG with negative cc_src target/s390x: Fix LAALG not updating cc_src tests/tcg/s390x: Test CLC with inaccessible second operand target/s390x: Fix CLC corrupting cc_src target/s390x/cpu_models: Use 'first_cpu' in s390_get_feat_block() s390/sclp: fix SCLP facility map tests/avocado: Allow newer versions of tesseract in the nextcube test MAINTAINERS: Add artist.c to the hppa machine section MAINTAINERS: Add the virtio-gpu documentation to the corresponding section Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
44ad47b758
@ -1194,6 +1194,7 @@ M: Richard Henderson <richard.henderson@linaro.org>
|
||||
R: Helge Deller <deller@gmx.de>
|
||||
S: Odd Fixes
|
||||
F: configs/devices/hppa-softmmu/default.mak
|
||||
F: hw/display/artist.c
|
||||
F: hw/hppa/
|
||||
F: hw/input/lasips2.c
|
||||
F: hw/net/*i82596*
|
||||
@ -2496,6 +2497,7 @@ S: Odd Fixes
|
||||
F: hw/display/virtio-gpu*
|
||||
F: hw/display/virtio-vga.*
|
||||
F: include/hw/virtio/virtio-gpu.h
|
||||
F: docs/system/devices/virtio-gpu.rst
|
||||
|
||||
vhost-user-blk
|
||||
M: Raphael Norwitz <raphael.norwitz@nutanix.com>
|
||||
|
@ -38,10 +38,8 @@
|
||||
#define MAX_STORAGE_INCREMENTS 1020
|
||||
|
||||
/* CPU hotplug SCLP codes */
|
||||
#define SCLP_HAS_CPU_INFO 0x0C00000000000000ULL
|
||||
#define SCLP_HAS_CPU_INFO 0x0800000000000000ULL
|
||||
#define SCLP_CMDW_READ_CPU_INFO 0x00010001
|
||||
#define SCLP_CMDW_CONFIGURE_CPU 0x00110001
|
||||
#define SCLP_CMDW_DECONFIGURE_CPU 0x00100001
|
||||
|
||||
/* SCLP PCI codes */
|
||||
#define SCLP_HAS_IOA_RECONFIG 0x0000000040000000ULL
|
||||
|
@ -196,11 +196,7 @@ uint32_t s390_get_ibc_val(void)
|
||||
|
||||
void s390_get_feat_block(S390FeatType type, uint8_t *data)
|
||||
{
|
||||
static S390CPU *cpu;
|
||||
|
||||
if (!cpu) {
|
||||
cpu = S390_CPU(qemu_get_cpu(0));
|
||||
}
|
||||
S390CPU *cpu = S390_CPU(first_cpu);
|
||||
|
||||
if (!cpu || !cpu->model) {
|
||||
return;
|
||||
|
@ -210,6 +210,9 @@ static S390TopologyId s390_topology_from_cpu(S390CPU *cpu)
|
||||
static int s390_topology_id_cmp(const S390TopologyId *l,
|
||||
const S390TopologyId *r)
|
||||
{
|
||||
int l_polarization = l->vertical ? l->entitlement : 0;
|
||||
int r_polarization = r->vertical ? r->entitlement : 0;
|
||||
|
||||
/*
|
||||
* lexical order, compare less significant values only if more significant
|
||||
* ones are equal
|
||||
@ -219,9 +222,8 @@ static int s390_topology_id_cmp(const S390TopologyId *l,
|
||||
l->book - r->book ?:
|
||||
l->socket - r->socket ?:
|
||||
l->type - r->type ?:
|
||||
/* logic is inverted for the next three */
|
||||
r->vertical - l->vertical ?:
|
||||
r->entitlement - l->entitlement ?:
|
||||
/* logic is inverted for the next two */
|
||||
r_polarization - l_polarization ?:
|
||||
r->dedicated - l->dedicated ?:
|
||||
l->origin - r->origin;
|
||||
}
|
||||
|
@ -442,7 +442,7 @@
|
||||
D(0xebe8, LAAG, RSY_a, ILA, r3, a2, new, in2_r1, laa, adds64, MO_TEUQ)
|
||||
/* LOAD AND ADD LOGICAL */
|
||||
D(0xebfa, LAAL, RSY_a, ILA, r3_32u, a2, new, in2_r1_32, laa, addu32, MO_TEUL)
|
||||
D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa, addu64, MO_TEUQ)
|
||||
D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa_addu64, addu64, MO_TEUQ)
|
||||
/* LOAD AND AND */
|
||||
D(0xebf4, LAN, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, lan, nz32, MO_TESL)
|
||||
D(0xebe4, LANG, RSY_a, ILA, r3, a2, new, in2_r1, lan, nz64, MO_TEUQ)
|
||||
|
@ -2007,6 +2007,7 @@ static DisasJumpType op_cksm(DisasContext *s, DisasOps *o)
|
||||
static DisasJumpType op_clc(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int l = get_field(s, l1);
|
||||
TCGv_i64 src;
|
||||
TCGv_i32 vl;
|
||||
MemOp mop;
|
||||
|
||||
@ -2016,9 +2017,11 @@ static DisasJumpType op_clc(DisasContext *s, DisasOps *o)
|
||||
case 4:
|
||||
case 8:
|
||||
mop = ctz32(l + 1) | MO_TE;
|
||||
tcg_gen_qemu_ld_tl(cc_src, o->addr1, get_mem_index(s), mop);
|
||||
/* Do not update cc_src yet: loading cc_dst may cause an exception. */
|
||||
src = tcg_temp_new_i64();
|
||||
tcg_gen_qemu_ld_tl(src, o->addr1, get_mem_index(s), mop);
|
||||
tcg_gen_qemu_ld_tl(cc_dst, o->in2, get_mem_index(s), mop);
|
||||
gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst);
|
||||
gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, src, cc_dst);
|
||||
return DISAS_NEXT;
|
||||
default:
|
||||
vl = tcg_constant_i32(l);
|
||||
@ -2674,17 +2677,32 @@ static DisasJumpType op_kxb(DisasContext *s, DisasOps *o)
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_laa(DisasContext *s, DisasOps *o)
|
||||
static DisasJumpType help_laa(DisasContext *s, DisasOps *o, bool addu64)
|
||||
{
|
||||
/* The real output is indeed the original value in memory;
|
||||
recompute the addition for the computation of CC. */
|
||||
tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s),
|
||||
s->insn->data | MO_ALIGN);
|
||||
/* However, we need to recompute the addition for setting CC. */
|
||||
tcg_gen_add_i64(o->out, o->in1, o->in2);
|
||||
if (addu64) {
|
||||
tcg_gen_movi_i64(cc_src, 0);
|
||||
tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
|
||||
} else {
|
||||
tcg_gen_add_i64(o->out, o->in1, o->in2);
|
||||
}
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_laa(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
return help_laa(s, o, false);
|
||||
}
|
||||
|
||||
static DisasJumpType op_laa_addu64(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
return help_laa(s, o, true);
|
||||
}
|
||||
|
||||
static DisasJumpType op_lan(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
/* The real output is indeed the original value in memory;
|
||||
|
@ -55,25 +55,16 @@ class NextCubeMachine(QemuSystemTest):
|
||||
self.assertEqual(width, 1120)
|
||||
self.assertEqual(height, 832)
|
||||
|
||||
@skipUnless(tesseract_available(3), 'tesseract v3 OCR tool not available')
|
||||
def test_bootrom_framebuffer_ocr_with_tesseract_v3(self):
|
||||
screenshot_path = os.path.join(self.workdir, "dump.ppm")
|
||||
self.check_bootrom_framebuffer(screenshot_path)
|
||||
lines = tesseract_ocr(screenshot_path, tesseract_version=3)
|
||||
text = '\n'.join(lines)
|
||||
self.assertIn('Backplane', text)
|
||||
self.assertIn('Ethernet address', text)
|
||||
|
||||
# Tesseract 4 adds a new OCR engine based on LSTM neural networks. The
|
||||
# new version is faster and more accurate than version 3. The drawback is
|
||||
# that it is still alpha-level software.
|
||||
@skipUnless(tesseract_available(4), 'tesseract v4 OCR tool not available')
|
||||
def test_bootrom_framebuffer_ocr_with_tesseract_v4(self):
|
||||
@skipUnless(tesseract_available(4), 'tesseract OCR tool not available')
|
||||
def test_bootrom_framebuffer_ocr_with_tesseract(self):
|
||||
screenshot_path = os.path.join(self.workdir, "dump.ppm")
|
||||
self.check_bootrom_framebuffer(screenshot_path)
|
||||
lines = tesseract_ocr(screenshot_path, tesseract_version=4)
|
||||
text = '\n'.join(lines)
|
||||
self.assertIn('Testing the FPU, SCC', text)
|
||||
self.assertIn('Testing the FPU', text)
|
||||
self.assertIn('System test failed. Error code', text)
|
||||
self.assertIn('Boot command', text)
|
||||
self.assertIn('Next>', text)
|
||||
|
@ -21,13 +21,13 @@ def tesseract_available(expected_version):
|
||||
version = res.stdout_text.split()[1]
|
||||
except IndexError:
|
||||
version = res.stderr_text.split()[1]
|
||||
return int(version.split('.')[0]) == expected_version
|
||||
return int(version.split('.')[0]) >= expected_version
|
||||
|
||||
match = re.match(r'tesseract\s(\d)', res)
|
||||
if match is None:
|
||||
return False
|
||||
# now this is guaranteed to be a digit
|
||||
return int(match.groups()[0]) == expected_version
|
||||
return int(match.groups()[0]) >= expected_version
|
||||
|
||||
|
||||
def tesseract_ocr(image_path, tesseract_args='', tesseract_version=3):
|
||||
|
@ -41,6 +41,9 @@ TESTS+=larl
|
||||
TESTS+=mdeb
|
||||
TESTS+=cgebra
|
||||
TESTS+=clgebr
|
||||
TESTS+=clc
|
||||
TESTS+=laalg
|
||||
TESTS+=add-logical-with-carry
|
||||
|
||||
cdsg: CFLAGS+=-pthread
|
||||
cdsg: LDFLAGS+=-pthread
|
||||
|
156
tests/tcg/s390x/add-logical-with-carry.c
Normal file
156
tests/tcg/s390x/add-logical-with-carry.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Test ADD LOGICAL WITH CARRY instructions.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const struct test {
|
||||
const char *name;
|
||||
unsigned long values[3];
|
||||
unsigned long exp_sum;
|
||||
int exp_cc;
|
||||
} tests[] = {
|
||||
/*
|
||||
* Each test starts with CC 0 and executes two chained ADD LOGICAL WITH
|
||||
* CARRY instructions on three input values. The values must be compatible
|
||||
* with both 32- and 64-bit test functions.
|
||||
*/
|
||||
|
||||
/* NAME VALUES EXP_SUM EXP_CC */
|
||||
{ "cc0->cc0", {0, 0, 0}, 0, 0, },
|
||||
{ "cc0->cc1", {0, 0, 42}, 42, 1, },
|
||||
/* cc0->cc2 is not possible */
|
||||
/* cc0->cc3 is not possible */
|
||||
/* cc1->cc0 is not possible */
|
||||
{ "cc1->cc1", {-3, 1, 1}, -1, 1, },
|
||||
{ "cc1->cc2", {-3, 1, 2}, 0, 2, },
|
||||
{ "cc1->cc3", {-3, 1, -1}, -3, 3, },
|
||||
/* cc2->cc0 is not possible */
|
||||
{ "cc2->cc1", {-1, 1, 1}, 2, 1, },
|
||||
{ "cc2->cc2", {-1, 1, -1}, 0, 2, },
|
||||
/* cc2->cc3 is not possible */
|
||||
/* cc3->cc0 is not possible */
|
||||
{ "cc3->cc1", {-1, 2, 1}, 3, 1, },
|
||||
{ "cc3->cc2", {-1, 2, -2}, 0, 2, },
|
||||
{ "cc3->cc3", {-1, 2, -1}, 1, 3, },
|
||||
};
|
||||
|
||||
/* Test ALCR (register variant) followed by ALC (memory variant). */
|
||||
static unsigned long test32rm(unsigned long a, unsigned long b,
|
||||
unsigned long c, int *cc)
|
||||
{
|
||||
unsigned int a32 = a, b32 = b, c32 = c;
|
||||
|
||||
asm("xr %[cc],%[cc]\n"
|
||||
"alcr %[a],%[b]\n"
|
||||
"alc %[a],%[c]\n"
|
||||
"ipm %[cc]"
|
||||
: [a] "+&r" (a32), [cc] "+&r" (*cc)
|
||||
: [b] "r" (b32), [c] "T" (c32)
|
||||
: "cc");
|
||||
*cc >>= 28;
|
||||
|
||||
return (int)a32;
|
||||
}
|
||||
|
||||
/* Test ALC (memory variant) followed by ALCR (register variant). */
|
||||
static unsigned long test32mr(unsigned long a, unsigned long b,
|
||||
unsigned long c, int *cc)
|
||||
{
|
||||
unsigned int a32 = a, b32 = b, c32 = c;
|
||||
|
||||
asm("xr %[cc],%[cc]\n"
|
||||
"alc %[a],%[b]\n"
|
||||
"alcr %[c],%[a]\n"
|
||||
"ipm %[cc]"
|
||||
: [a] "+&r" (a32), [c] "+&r" (c32), [cc] "+&r" (*cc)
|
||||
: [b] "T" (b32)
|
||||
: "cc");
|
||||
*cc >>= 28;
|
||||
|
||||
return (int)c32;
|
||||
}
|
||||
|
||||
/* Test ALCGR (register variant) followed by ALCG (memory variant). */
|
||||
static unsigned long test64rm(unsigned long a, unsigned long b,
|
||||
unsigned long c, int *cc)
|
||||
{
|
||||
asm("xr %[cc],%[cc]\n"
|
||||
"alcgr %[a],%[b]\n"
|
||||
"alcg %[a],%[c]\n"
|
||||
"ipm %[cc]"
|
||||
: [a] "+&r" (a), [cc] "+&r" (*cc)
|
||||
: [b] "r" (b), [c] "T" (c)
|
||||
: "cc");
|
||||
*cc >>= 28;
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Test ALCG (memory variant) followed by ALCGR (register variant). */
|
||||
static unsigned long test64mr(unsigned long a, unsigned long b,
|
||||
unsigned long c, int *cc)
|
||||
{
|
||||
asm("xr %[cc],%[cc]\n"
|
||||
"alcg %[a],%[b]\n"
|
||||
"alcgr %[c],%[a]\n"
|
||||
"ipm %[cc]"
|
||||
: [a] "+&r" (a), [c] "+&r" (c), [cc] "+&r" (*cc)
|
||||
: [b] "T" (b)
|
||||
: "cc");
|
||||
*cc >>= 28;
|
||||
return c;
|
||||
}
|
||||
|
||||
static const struct test_func {
|
||||
const char *name;
|
||||
unsigned long (*ptr)(unsigned long, unsigned long, unsigned long, int *);
|
||||
} test_funcs[] = {
|
||||
{ "test32rm", test32rm },
|
||||
{ "test32mr", test32mr },
|
||||
{ "test64rm", test64rm },
|
||||
{ "test64mr", test64mr },
|
||||
};
|
||||
|
||||
static const struct test_perm {
|
||||
const char *name;
|
||||
size_t a_idx, b_idx, c_idx;
|
||||
} test_perms[] = {
|
||||
{ "a, b, c", 0, 1, 2 },
|
||||
{ "b, a, c", 1, 0, 2 },
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned long a, b, c, sum;
|
||||
int result = EXIT_SUCCESS;
|
||||
const struct test_func *f;
|
||||
const struct test_perm *p;
|
||||
size_t i, j, k;
|
||||
const struct test *t;
|
||||
int cc;
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
|
||||
t = &tests[i];
|
||||
for (j = 0; j < sizeof(test_funcs) / sizeof(test_funcs[0]); j++) {
|
||||
f = &test_funcs[j];
|
||||
for (k = 0; k < sizeof(test_perms) / sizeof(test_perms[0]); k++) {
|
||||
p = &test_perms[k];
|
||||
a = t->values[p->a_idx];
|
||||
b = t->values[p->b_idx];
|
||||
c = t->values[p->c_idx];
|
||||
sum = f->ptr(a, b, c, &cc);
|
||||
if (sum != t->exp_sum || cc != t->exp_cc) {
|
||||
fprintf(stderr,
|
||||
"[ FAILED ] %s %s(0x%lx, 0x%lx, 0x%lx) returned 0x%lx cc %d, expected 0x%lx cc %d\n",
|
||||
t->name, f->name, a, b, c, sum, cc,
|
||||
t->exp_sum, t->exp_cc);
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
48
tests/tcg/s390x/clc.c
Normal file
48
tests/tcg/s390x/clc.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Test the CLC instruction.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void handle_sigsegv(int sig, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
mcontext_t *mcontext = &((ucontext_t *)ucontext)->uc_mcontext;
|
||||
if (mcontext->gregs[0] != 600) {
|
||||
write(STDERR_FILENO, "bad r0\n", 7);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
if (((mcontext->psw.mask >> 44) & 3) != 1) {
|
||||
write(STDERR_FILENO, "bad cc\n", 7);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register unsigned long r0 asm("r0");
|
||||
unsigned long mem = 42, rhs = 500;
|
||||
struct sigaction act;
|
||||
int err;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_sigaction = handle_sigsegv;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
err = sigaction(SIGSEGV, &act, NULL);
|
||||
assert(err == 0);
|
||||
|
||||
r0 = 100;
|
||||
asm("algr %[r0],%[rhs]\n"
|
||||
"clc 0(8,%[mem]),0(0)\n" /* The 2nd operand will cause a SEGV. */
|
||||
: [r0] "+r" (r0)
|
||||
: [mem] "r" (&mem)
|
||||
, [rhs] "r" (rhs)
|
||||
: "cc", "memory");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
27
tests/tcg/s390x/laalg.c
Normal file
27
tests/tcg/s390x/laalg.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Test the LAALG instruction.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned long cc = 0, op1, op2 = 40, op3 = 2;
|
||||
|
||||
asm("slgfi %[cc],1\n" /* Set cc_src = -1. */
|
||||
"laalg %[op1],%[op3],%[op2]\n"
|
||||
"ipm %[cc]"
|
||||
: [cc] "+r" (cc)
|
||||
, [op1] "=r" (op1)
|
||||
, [op2] "+T" (op2)
|
||||
: [op3] "r" (op3)
|
||||
: "cc");
|
||||
|
||||
assert(cc == 0xffffffff10ffffff);
|
||||
assert(op1 == 40);
|
||||
assert(op2 == 42);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user