From 964a622739c13e774d2fd08a66eb22ec336d5ee96ec743f3860d6d5f9fb1813f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Wed, 16 Feb 2011 19:30:51 +0000 Subject: [PATCH] Accepting request 60601 from home:uli_suse:branches:Virtualization OBS-URL: https://build.opensuse.org/request/show/60601 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=7 --- 0001-qemu-0.7.0-amd64.patch | 12 +- 0002-qemu-0.9.0.cvs-binfmt.patch | 45 +- 0003-qemu-cvs-alsa_bitfield.patch | 6 +- 0004-qemu-cvs-alsa_ioctl.patch | 16 +- 0005-qemu-cvs-alsa_mmap.patch | 14 +- 0006-qemu-cvs-gettimeofday.patch | 10 +- 0007-qemu-cvs-ioctl_debug.patch | 10 +- 0008-qemu-cvs-ioctl_nodirection.patch | 12 +- 0009-qemu-cvs-newpath.patch | 235 - ...h => 0009-qemu-cvs-sched_getaffinity.patch | 16 +- ...64.patch => 0010-qemu-cvs-mmap-amd64.patch | 12 +- 0011-qemu-img-vmdk-scsi.patch | 116 + 0012-qemu-cvs-pthread.patch | 28 - ...rn.patch => 0012-qemu-nonvoid_return.patch | 12 +- ...=> 0013-i386-linux-user-NPTL-support.patch | 16 +- 0013-qemu-img-vmdk-scsi.patch | 142 - ...ch => 0014-qemu-0.11-git-ioctl_mount.patch | 10 +- ...mulation.patch => 0015-S-390-support.patch | 3808 +++++++++++++---- 0015-pcap-network-emulation.patch | 205 - 0016-fix-mipsn32-linux-user-builds.patch | 58 + 0017-S-390-build-fix.patch | 129 + ...mu-0.11-git-user-linux-ppc-uid16_fix.patch | 116 - ...ind_vma-to-work-fine-on-64-bit-hosts.patch | 125 - 0020-TCG-sync-op-32-bit-targets-fixed.patch | 82 - ...390-host-target-build-system-support.patch | 127 - 0023-S-390-host-support-for-TCG.patch | 1486 ------- ...inux-user-S-390-64-bit-s390x-support.patch | 1350 ------ ...t-do-locking-in-single-threaded-proc.patch | 96 - 0026-linux-user-dup3-fallocate-syscalls.patch | 80 - 0027-linux-user-fcntl-fixes-for-LTP.patch | 171 - ...r-enable-getdents-for-32-bit-systems.patch | 41 - ...ne-a-couple-of-syscalls-for-non-uid1.patch | 271 -- 0030-linux-user-getpriority-errno-fix.patch | 28 - ...-linux-user-fadvise64-implementation.patch | 46 - ...-fstat-buffer-to-initialize-nsec-fie.patch | 31 - 0033-dup3-check-fallocate-check-fixed.patch | 76 - qemu-0.11.0.tar.bz2 | 3 - qemu-0.14.0-rc1.tar.bz2 | 3 + qemu.changes | 16 + qemu.spec | 78 +- 40 files changed, 3351 insertions(+), 5787 deletions(-) delete mode 100644 0009-qemu-cvs-newpath.patch rename 0010-qemu-cvs-sched_getaffinity.patch => 0009-qemu-cvs-sched_getaffinity.patch (80%) rename 0011-qemu-cvs-mmap-amd64.patch => 0010-qemu-cvs-mmap-amd64.patch (80%) create mode 100644 0011-qemu-img-vmdk-scsi.patch delete mode 100644 0012-qemu-cvs-pthread.patch rename 0014-qemu-nonvoid_return.patch => 0012-qemu-nonvoid_return.patch (78%) rename 0016-i386-linux-user-NPTL-support.patch => 0013-i386-linux-user-NPTL-support.patch (83%) delete mode 100644 0013-qemu-img-vmdk-scsi.patch rename 0017-qemu-0.11-git-ioctl_mount.patch => 0014-qemu-0.11-git-ioctl_mount.patch (80%) rename 0021-S-390-CPU-emulation.patch => 0015-S-390-support.patch (55%) delete mode 100644 0015-pcap-network-emulation.patch create mode 100644 0016-fix-mipsn32-linux-user-builds.patch create mode 100644 0017-S-390-build-fix.patch delete mode 100644 0018-qemu-0.11-git-user-linux-ppc-uid16_fix.patch delete mode 100644 0019-Rewrite-mmap_find_vma-to-work-fine-on-64-bit-hosts.patch delete mode 100644 0020-TCG-sync-op-32-bit-targets-fixed.patch delete mode 100644 0022-S-390-host-target-build-system-support.patch delete mode 100644 0023-S-390-host-support-for-TCG.patch delete mode 100644 0024-linux-user-S-390-64-bit-s390x-support.patch delete mode 100644 0025-linux-user-don-t-do-locking-in-single-threaded-proc.patch delete mode 100644 0026-linux-user-dup3-fallocate-syscalls.patch delete mode 100644 0027-linux-user-fcntl-fixes-for-LTP.patch delete mode 100644 0028-linux-user-enable-getdents-for-32-bit-systems.patch delete mode 100644 0029-linux-user-define-a-couple-of-syscalls-for-non-uid1.patch delete mode 100644 0030-linux-user-getpriority-errno-fix.patch delete mode 100644 0031-linux-user-fadvise64-implementation.patch delete mode 100644 0032-linux-user-zero-fstat-buffer-to-initialize-nsec-fie.patch delete mode 100644 0033-dup3-check-fallocate-check-fixed.patch delete mode 100644 qemu-0.11.0.tar.bz2 create mode 100644 qemu-0.14.0-rc1.tar.bz2 diff --git a/0001-qemu-0.7.0-amd64.patch b/0001-qemu-0.7.0-amd64.patch index a4b348a1..b52de353 100644 --- a/0001-qemu-0.7.0-amd64.patch +++ b/0001-qemu-0.7.0-amd64.patch @@ -1,7 +1,7 @@ -From 827af866df5674253ef563bd244277d31a93ba32 Mon Sep 17 00:00:00 2001 +From 4af9300d36f0975213b0fb967131629ad6b4c550 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:17:39 +0200 -Subject: [PATCH 01/33] qemu-0.7.0-amd64 +Subject: [PATCH 01/17] qemu-0.7.0-amd64 No clue why this is necessary or useful, nothing found in any changelogs. --- @@ -9,10 +9,10 @@ No clue why this is necessary or useful, nothing found in any changelogs. 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x86_64.ld b/x86_64.ld -index 878dafb..142e641 100644 +index 46d8d4d..cce0a17 100644 --- a/x86_64.ld +++ b/x86_64.ld -@@ -59,8 +59,6 @@ SECTIONS +@@ -70,8 +70,6 @@ SECTIONS .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .eh_frame_hdr : { *(.eh_frame_hdr) } @@ -21,7 +21,7 @@ index 878dafb..142e641 100644 /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000); -@@ -86,8 +84,8 @@ SECTIONS +@@ -97,8 +95,8 @@ SECTIONS .data1 : { *(.data1) } .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } @@ -33,5 +33,5 @@ index 878dafb..142e641 100644 .ctors : { -- -1.6.2.1 +1.7.1 diff --git a/0002-qemu-0.9.0.cvs-binfmt.patch b/0002-qemu-0.9.0.cvs-binfmt.patch index ec88e3d2..0fba9ef6 100644 --- a/0002-qemu-0.9.0.cvs-binfmt.patch +++ b/0002-qemu-0.9.0.cvs-binfmt.patch @@ -1,7 +1,7 @@ -From 496da9d6ffd6f42570cbed52adba37fea769d2ab Mon Sep 17 00:00:00 2001 +From 8f16efecc00d3ee4615dcd2d5381b23df4465698 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:18:44 +0200 -Subject: [PATCH 02/33] qemu-0.9.0.cvs-binfmt +Subject: [PATCH 02/17] qemu-0.9.0.cvs-binfmt Fixes binfmt_misc setup script: - x86_64 is i386-compatible @@ -10,28 +10,15 @@ Fixes binfmt_misc setup script: Signed-off-by: Ulrich Hecht --- - qemu-binfmt-conf.sh | 33 ++++++++++++++++++--------------- - 1 files changed, 18 insertions(+), 15 deletions(-) + scripts/qemu-binfmt-conf.sh | 35 +++++++++++++++++++---------------- + 1 files changed, 19 insertions(+), 16 deletions(-) -diff --git a/qemu-binfmt-conf.sh b/qemu-binfmt-conf.sh -index 941f0cf..67d6728 100644 ---- a/qemu-binfmt-conf.sh -+++ b/qemu-binfmt-conf.sh -@@ -12,7 +12,7 @@ fi - # probe cpu type - cpu=`uname -m` - case "$cpu" in -- i386|i486|i586|i686|i86pc|BePC) -+ i386|i486|i586|i686|i86pc|BePC|x86_64) - cpu="i386" - ;; - m68k) -@@ -24,36 +24,39 @@ case "$cpu" in - "Power Macintosh"|ppc|ppc64) - cpu="ppc" - ;; -- armv4l) -+ armv[4-9]*l) +diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh +index c50beb7..335ab05 100644 +--- a/scripts/qemu-binfmt-conf.sh ++++ b/scripts/qemu-binfmt-conf.sh +@@ -27,40 +27,43 @@ case "$cpu" in + armv[4-9]*) cpu="arm" ;; + sparc*) @@ -45,6 +32,10 @@ index 941f0cf..67d6728 100644 - echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register + echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register + echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "alpha" ] ; then +- echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register ++ echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register fi if [ $cpu != "arm" ] ; then - echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register @@ -80,6 +71,12 @@ index 941f0cf..67d6728 100644 + echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register + echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register fi + if [ $cpu != "sh" ] ; then +- echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register +- echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register ++ echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register + fi -- -1.6.2.1 +1.7.1 diff --git a/0003-qemu-cvs-alsa_bitfield.patch b/0003-qemu-cvs-alsa_bitfield.patch index a4ecc7b2..ca81f6c8 100644 --- a/0003-qemu-cvs-alsa_bitfield.patch +++ b/0003-qemu-cvs-alsa_bitfield.patch @@ -1,7 +1,7 @@ -From 4675ae349f0d4e489f1298f1cbf246dfa7124d79 Mon Sep 17 00:00:00 2001 +From 8a88b86cc9a3ad0bb6da52fb0f938fe5a085c027 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:20:50 +0200 -Subject: [PATCH 03/33] qemu-cvs-alsa_bitfield +Subject: [PATCH 03/17] qemu-cvs-alsa_bitfield Implements TYPE_INTBITFIELD partially. (required for ALSA support) @@ -79,5 +79,5 @@ index 109c541..55890f3 100644 case TYPE_LONGLONG: case TYPE_ULONGLONG: -- -1.6.2.1 +1.7.1 diff --git a/0004-qemu-cvs-alsa_ioctl.patch b/0004-qemu-cvs-alsa_ioctl.patch index 805ee83e..b55d06f1 100644 --- a/0004-qemu-cvs-alsa_ioctl.patch +++ b/0004-qemu-cvs-alsa_ioctl.patch @@ -1,7 +1,7 @@ -From ab27a247cbab3c5f780e14a3ad822a5e12955d8f Mon Sep 17 00:00:00 2001 +From c5b614579d85877cfa39dfea8989040e43f9ba56 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:23:27 +0200 -Subject: [PATCH 04/33] qemu-cvs-alsa_ioctl +Subject: [PATCH 04/17] qemu-cvs-alsa_ioctl Implements ALSA ioctls on PPC hosts. @@ -19,10 +19,10 @@ Signed-off-by: Ulrich Hecht create mode 100644 linux-user/syscall_types_alsa.h diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h -index 685cc71..aee5a88 100644 +index acff781..13ff54f 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h -@@ -301,6 +301,11 @@ +@@ -308,6 +308,11 @@ IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) @@ -2254,16 +2254,16 @@ index 0000000..3de8614 + unsigned char *code; +}; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index ac5dbc5..78c6488 100644 +index d02a9bf..be612ce 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h -@@ -2138,3 +2138,4 @@ struct target_mq_attr { +@@ -2205,3 +2205,4 @@ struct target_mq_attr { #define FUTEX_CLOCK_REALTIME 256 #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) +#include "ioctls_alsa_structs.h" diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h -index d3f3df9..1fa48d0 100644 +index 0e67cd8..635fdef 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -80,6 +80,11 @@ STRUCT(count_info, @@ -3622,5 +3622,5 @@ index 0000000..6dbc964 +) + -- -1.6.2.1 +1.7.1 diff --git a/0005-qemu-cvs-alsa_mmap.patch b/0005-qemu-cvs-alsa_mmap.patch index aa4080af..c10345f5 100644 --- a/0005-qemu-cvs-alsa_mmap.patch +++ b/0005-qemu-cvs-alsa_mmap.patch @@ -1,7 +1,7 @@ -From ed5099e1cc655c77344863855abe5c20c1b6eb0b Mon Sep 17 00:00:00 2001 +From 3848cba4ed22ebef70e59cbb542e71a37fe74d1d Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:24:15 +0200 -Subject: [PATCH 05/33] qemu-cvs-alsa_mmap +Subject: [PATCH 05/17] qemu-cvs-alsa_mmap Hack to prevent ALSA from using mmap() interface to simplify emulation. @@ -11,11 +11,11 @@ Signed-off-by: Ulrich Hecht 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c -index e05caa0..c33e5fe 100644 +index abf21f6..e18c228 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c -@@ -321,6 +321,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) - return addr; +@@ -360,6 +360,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) + } } +#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000 @@ -24,7 +24,7 @@ index e05caa0..c33e5fe 100644 /* NOTE: all the constants are the HOST ones */ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, int flags, int fd, abi_ulong offset) -@@ -356,6 +359,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, +@@ -395,6 +398,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } #endif @@ -43,5 +43,5 @@ index e05caa0..c33e5fe 100644 errno = EINVAL; goto fail; -- -1.6.2.1 +1.7.1 diff --git a/0006-qemu-cvs-gettimeofday.patch b/0006-qemu-cvs-gettimeofday.patch index c4dcf38b..6deb743c 100644 --- a/0006-qemu-cvs-gettimeofday.patch +++ b/0006-qemu-cvs-gettimeofday.patch @@ -1,7 +1,7 @@ -From 69aca2fcdf61fbd4a5c0123a7e64cf99862076ff Mon Sep 17 00:00:00 2001 +From da6cdca6cdbfccb4936f5df5e297a87fe1e4baa8 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:25:41 +0200 -Subject: [PATCH 06/33] qemu-cvs-gettimeofday +Subject: [PATCH 06/17] qemu-cvs-gettimeofday No clue what this is for. --- @@ -9,10 +9,10 @@ No clue what this is for. 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 7b57323..70d3b2d 100644 +index 499c4d7..92f2aa6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c -@@ -5063,6 +5063,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, +@@ -5399,6 +5399,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_gettimeofday: { struct timeval tv; @@ -22,5 +22,5 @@ index 7b57323..70d3b2d 100644 if (!is_error(ret)) { if (copy_to_user_timeval(arg1, &tv)) -- -1.6.2.1 +1.7.1 diff --git a/0007-qemu-cvs-ioctl_debug.patch b/0007-qemu-cvs-ioctl_debug.patch index d4aaecae..6c322862 100644 --- a/0007-qemu-cvs-ioctl_debug.patch +++ b/0007-qemu-cvs-ioctl_debug.patch @@ -1,7 +1,7 @@ -From 4ec256fd6d555ec61f0a1bd530ff66860937b232 Mon Sep 17 00:00:00 2001 +From 1a883714ac7e953bab2bbdeba651d0696f49dd81 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:26:33 +0200 -Subject: [PATCH 07/33] qemu-cvs-ioctl_debug +Subject: [PATCH 07/17] qemu-cvs-ioctl_debug Extends unsupported ioctl debug output. @@ -11,10 +11,10 @@ Signed-off-by: Ulrich Hecht 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 70d3b2d..ce5283c 100644 +index 92f2aa6..04f77ef 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c -@@ -2890,7 +2890,12 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) +@@ -3100,7 +3100,12 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) ie = ioctl_entries; for(;;) { if (ie->target_cmd == 0) { @@ -29,5 +29,5 @@ index 70d3b2d..ce5283c 100644 } if (ie->target_cmd == cmd) -- -1.6.2.1 +1.7.1 diff --git a/0008-qemu-cvs-ioctl_nodirection.patch b/0008-qemu-cvs-ioctl_nodirection.patch index 3cdacf68..cee2bb0e 100644 --- a/0008-qemu-cvs-ioctl_nodirection.patch +++ b/0008-qemu-cvs-ioctl_nodirection.patch @@ -1,7 +1,7 @@ -From 5a0ba0e95920618c8ae38f4842d9dd56943f4343 Mon Sep 17 00:00:00 2001 +From d03d586aabc9000cabc56de7e327c5b5640f3179 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:27:36 +0200 -Subject: [PATCH 08/33] qemu-cvs-ioctl_nodirection +Subject: [PATCH 08/17] qemu-cvs-ioctl_nodirection the direction given in the ioctl should be correct so we can assume the communication is uni-directional. The alsa developers did not like this @@ -14,10 +14,10 @@ Signed-off-by: Ulrich Hecht 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index ce5283c..b7230c7 100644 +index 04f77ef..b51634b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c -@@ -2920,6 +2920,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) +@@ -3134,6 +3134,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) arg_type++; target_size = thunk_type_size(arg_type, 0); switch(ie->access) { @@ -29,7 +29,7 @@ index ce5283c..b7230c7 100644 case IOC_R: ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); if (!is_error(ret)) { -@@ -2938,6 +2943,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) +@@ -3152,6 +3157,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) unlock_user(argptr, arg, 0); ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); break; @@ -38,5 +38,5 @@ index ce5283c..b7230c7 100644 case IOC_RW: argptr = lock_user(VERIFY_READ, arg, target_size, 1); -- -1.6.2.1 +1.7.1 diff --git a/0009-qemu-cvs-newpath.patch b/0009-qemu-cvs-newpath.patch deleted file mode 100644 index 5fc1023a..00000000 --- a/0009-qemu-cvs-newpath.patch +++ /dev/null @@ -1,235 +0,0 @@ -From bc376b5848fef44ed9a56ec2e0e9bfd22aa1b24d Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Tue, 14 Apr 2009 16:28:45 +0200 -Subject: [PATCH 09/33] qemu-cvs-newpath - -fast path mangling patch by Kirill A. Shutemov - -Signed-off-by: Ulrich Hecht ---- - linux-user/path.c | 190 ++++++++++++++++------------------------------------- - 1 files changed, 56 insertions(+), 134 deletions(-) - -diff --git a/linux-user/path.c b/linux-user/path.c -index 06b1f5f..aedff50 100644 ---- a/linux-user/path.c -+++ b/linux-user/path.c -@@ -1,159 +1,81 @@ - /* Code to mangle pathnames into those matching a given prefix. - eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so"); -- -- The assumption is that this area does not change. - */ - #include --#include -+#include - #include --#include - #include --#include - #include - #include "qemu.h" - --struct pathelem --{ -- /* Name of this, eg. lib */ -- char *name; -- /* Full path name, eg. /usr/gnemul/x86-linux/lib. */ -- char *pathname; -- struct pathelem *parent; -- /* Children */ -- unsigned int num_entries; -- struct pathelem *entries[0]; -+struct path_list_head { -+ struct path_list_head *next; -+ char* path; - }; - --static struct pathelem *base; -- --/* First N chars of S1 match S2, and S2 is N chars long. */ --static int strneq(const char *s1, unsigned int n, const char *s2) --{ -- unsigned int i; -- -- for (i = 0; i < n; i++) -- if (s1[i] != s2[i]) -- return 0; -- return s2[i] == 0; --} -- --static struct pathelem *add_entry(struct pathelem *root, const char *name); -- --static struct pathelem *new_entry(const char *root, -- struct pathelem *parent, -- const char *name) --{ -- struct pathelem *new = malloc(sizeof(*new)); -- new->name = strdup(name); -- asprintf(&new->pathname, "%s/%s", root, name); -- new->num_entries = 0; -- return new; --} -- --#define streq(a,b) (strcmp((a), (b)) == 0) -- --static struct pathelem *add_dir_maybe(struct pathelem *path) --{ -- DIR *dir; -- -- if ((dir = opendir(path->pathname)) != NULL) { -- struct dirent *dirent; -- -- while ((dirent = readdir(dir)) != NULL) { -- if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ -- path = add_entry(path, dirent->d_name); -- } -- } -- closedir(dir); -- } -- return path; --} -- --static struct pathelem *add_entry(struct pathelem *root, const char *name) --{ -- root->num_entries++; -- -- root = realloc(root, sizeof(*root) -- + sizeof(root->entries[0])*root->num_entries); -- -- root->entries[root->num_entries-1] = new_entry(root->pathname, root, name); -- root->entries[root->num_entries-1] -- = add_dir_maybe(root->entries[root->num_entries-1]); -- return root; --} -- --/* This needs to be done after tree is stabilized (ie. no more reallocs!). */ --static void set_parents(struct pathelem *child, struct pathelem *parent) --{ -- unsigned int i; -- -- child->parent = parent; -- for (i = 0; i < child->num_entries; i++) -- set_parents(child->entries[i], child); --} -- --/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */ --static const char * --follow_path(const struct pathelem *cursor, const char *name) --{ -- unsigned int i, namelen; -- -- name += strspn(name, "/"); -- namelen = strcspn(name, "/"); -- -- if (namelen == 0) -- return cursor->pathname; -- -- if (strneq(name, namelen, "..")) -- return follow_path(cursor->parent, name + namelen); -- -- if (strneq(name, namelen, ".")) -- return follow_path(cursor, name + namelen); -- -- for (i = 0; i < cursor->num_entries; i++) -- if (strneq(name, namelen, cursor->entries[i]->name)) -- return follow_path(cursor->entries[i], name + namelen); -- -- /* Not found */ -- return NULL; --} -+static struct path_list_head* list_head; - - void init_paths(const char *prefix) - { -- char pref_buf[PATH_MAX]; -- -- if (prefix[0] == '\0' || -- !strcmp(prefix, "/")) -+ if (prefix[0] != '/' || -+ prefix[0] == '\0' || -+ !strcmp(prefix, "/")) - return; - -- if (prefix[0] != '/') { -- char *cwd = get_current_dir_name(); -- if (!cwd) -- abort(); -- strcpy(pref_buf, cwd); -- strcat(pref_buf, "/"); -- strcat(pref_buf, prefix); -- free(cwd); -- } else -- strcpy(pref_buf,prefix + 1); -+ list_head = malloc(sizeof(struct path_list_head)); - -- base = new_entry("", NULL, pref_buf); -- base = add_dir_maybe(base); -- if (base->num_entries == 0) { -- free (base); -- base = NULL; -- } else { -- set_parents(base, base); -- } -+ /* first element of list is prefix */ -+ list_head->path = strdup(prefix); -+ list_head->next = NULL; - } - - /* Look for path in emulation dir, otherwise return name. */ - const char *path(const char *name) - { -+ struct path_list_head *list = list_head; -+ int path_length = strlen(list_head->path) + strlen(name) + 1; -+ char *newname = malloc(path_length); -+ struct stat buf; -+ const char * result = name; -+ - /* Only do absolute paths: quick and dirty, but should mostly be OK. - Could do relative by tracking cwd. */ -- if (!base || !name || name[0] != '/') -- return name; -- -- return follow_path(base, name) ?: name; -+ if (!list_head || result[0] != '/') -+ goto exit; -+ -+ strncpy(newname, list_head->path, path_length); -+ strncat(newname, name, path_length); -+ -+ /* look for place where path should be present */ -+ while ( list->next && (strcmp(list->next->path, newname) < 0) ) -+ list = list->next; -+ -+ /* if there is no path in list */ -+ if ( !list->next || strcmp(list->next->path, newname) ) { -+ /* add element to list if path exist in emulation dir */ -+ if ( !stat(newname, &buf) ) -+ { -+ struct path_list_head *new; -+ -+ new = malloc(sizeof(struct path_list_head)); -+ new->path = strdup(newname); -+ new->next = list->next; -+ list->next = new; -+ result = new->path; -+ } -+ -+ } else if ( stat(list->next->path, &buf) ) { -+ /* remove element from list if path doesn't exist in emulation dir */ -+ struct path_list_head* tmp; -+ -+ tmp = list->next; -+ list->next = tmp->next; -+ free(tmp->path); -+ free(tmp); -+ } else -+ result = list->next->path; -+ -+exit: -+ free(newname); -+ return result; - } --- -1.6.2.1 - diff --git a/0010-qemu-cvs-sched_getaffinity.patch b/0009-qemu-cvs-sched_getaffinity.patch similarity index 80% rename from 0010-qemu-cvs-sched_getaffinity.patch rename to 0009-qemu-cvs-sched_getaffinity.patch index ac86e0f3..68ebf984 100644 --- a/0010-qemu-cvs-sched_getaffinity.patch +++ b/0009-qemu-cvs-sched_getaffinity.patch @@ -1,7 +1,7 @@ -From 72e306e63740a51a1c82f39cabb65df65ce2c215 Mon Sep 17 00:00:00 2001 +From 026ee1029cfeb6c802ee715372992fb3c847bd27 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:30:16 +0200 -Subject: [PATCH 10/33] qemu-cvs-sched_getaffinity +Subject: [PATCH 09/17] qemu-cvs-sched_getaffinity Implements sched_getaffinity syscall. @@ -11,10 +11,10 @@ Signed-off-by: Ulrich Hecht 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index b7230c7..faf41b1 100644 +index b51634b..81bf1f0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c -@@ -152,6 +152,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ +@@ -164,6 +164,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ } @@ -22,7 +22,7 @@ index b7230c7..faf41b1 100644 #define __NR_sys_uname __NR_uname #define __NR_sys_faccessat __NR_faccessat #define __NR_sys_fchmodat __NR_fchmodat -@@ -213,6 +214,9 @@ _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) +@@ -223,6 +224,9 @@ _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) #if defined(TARGET_NR_tkill) && defined(__NR_tkill) _syscall2(int,sys_tkill,int,tid,int,sig) #endif @@ -32,10 +32,10 @@ index b7230c7..faf41b1 100644 #ifdef __NR_exit_group _syscall1(int,exit_group,int,error_code) #endif -@@ -6979,6 +6983,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, +@@ -7505,6 +7509,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif - #endif /* CONFIG_SPLICE */ + #endif + +#ifdef TARGET_NR_sched_getaffinity + case TARGET_NR_sched_getaffinity: @@ -52,5 +52,5 @@ index b7230c7..faf41b1 100644 unimplemented: gemu_log("qemu: Unsupported syscall: %d\n", num); -- -1.6.2.1 +1.7.1 diff --git a/0011-qemu-cvs-mmap-amd64.patch b/0010-qemu-cvs-mmap-amd64.patch similarity index 80% rename from 0011-qemu-cvs-mmap-amd64.patch rename to 0010-qemu-cvs-mmap-amd64.patch index 2579fc44..410d9937 100644 --- a/0011-qemu-cvs-mmap-amd64.patch +++ b/0010-qemu-cvs-mmap-amd64.patch @@ -1,7 +1,7 @@ -From 5c8849d886cafd1626c1d36c572c3ccee5c88d5d Mon Sep 17 00:00:00 2001 +From 2013ec7c2d1b5a71d73701da746363b69d4c992c Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:34:05 +0200 -Subject: [PATCH 11/33] qemu-cvs-mmap-amd64 +Subject: [PATCH 10/17] qemu-cvs-mmap-amd64 Map stuff to address space < 4GB on AMD64. This patch got continually smaller as most cases were this was an issue were dealt with in other ways. May @@ -13,7 +13,7 @@ Signed-off-by: Ulrich Hecht 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c -index c33e5fe..9ca8f6f 100644 +index e18c228..de8abe9 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -31,6 +31,10 @@ @@ -26,8 +26,8 @@ index c33e5fe..9ca8f6f 100644 + //#define DEBUG_MMAP - #if defined(USE_NPTL) -@@ -230,7 +234,7 @@ static int mmap_frag(abi_ulong real_start, + #if defined(CONFIG_USE_NPTL) +@@ -169,7 +173,7 @@ static int mmap_frag(abi_ulong real_start, if (prot1 == 0) { /* no page was there, so we allocate one */ void *p = mmap(host_start, qemu_host_page_size, prot, @@ -37,5 +37,5 @@ index c33e5fe..9ca8f6f 100644 return -1; prot1 = prot; -- -1.6.2.1 +1.7.1 diff --git a/0011-qemu-img-vmdk-scsi.patch b/0011-qemu-img-vmdk-scsi.patch new file mode 100644 index 00000000..7525395d --- /dev/null +++ b/0011-qemu-img-vmdk-scsi.patch @@ -0,0 +1,116 @@ +From 09686f619707ec98e073bf671b0334a2f65934ad Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Tue, 14 Apr 2009 16:37:42 +0200 +Subject: [PATCH 11/17] qemu-img-vmdk-scsi + +Support creation of SCSI VMDK images in qemu-img. + +Signed-off-by: Ulrich Hecht +--- + block.c | 5 ++++- + block/vmdk.c | 7 +++++-- + block_int.h | 2 ++ + qemu-img.c | 8 +++++++- + 4 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/block.c b/block.c +index b476479..b77f09b 100644 +--- a/block.c ++++ b/block.c +@@ -2792,7 +2792,7 @@ int bdrv_img_create(const char *filename, const char *fmt, + char *options, uint64_t img_size, int flags) + { + QEMUOptionParameter *param = NULL, *create_options = NULL; +- QEMUOptionParameter *backing_fmt, *backing_file; ++ QEMUOptionParameter *backing_fmt, *backing_file, *scsi; + BlockDriverState *bs = NULL; + BlockDriver *drv, *proto_drv; + BlockDriver *backing_drv = NULL; +@@ -2901,6 +2901,9 @@ int bdrv_img_create(const char *filename, const char *fmt, + + printf("Formatting '%s', fmt=%s ", filename, fmt); + print_option_parameters(param); ++ scsi = get_option_parameter(param, BLOCK_OPT_SCSI); ++ if (scsi && scsi->value.n) ++ printf(", SCSI"); + puts(""); + + ret = bdrv_create(drv, filename, param); +diff --git a/block/vmdk.c b/block/vmdk.c +index 8fc9d67..8944173 100644 +--- a/block/vmdk.c ++++ b/block/vmdk.c +@@ -685,7 +685,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + "ddb.geometry.cylinders = \"%" PRId64 "\"\n" + "ddb.geometry.heads = \"16\"\n" + "ddb.geometry.sectors = \"63\"\n" +- "ddb.adapterType = \"ide\"\n"; ++ "ddb.adapterType = \"%s\"\n"; + char desc[1024]; + const char *real_filename, *temp_str; + int64_t total_size = 0; +@@ -701,6 +701,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + backing_file = options->value.s; + } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { + flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0; ++ } else if (!strcmp(options->name, BLOCK_OPT_SCSI)) { ++ flags |= options->value.n ? BLOCK_FLAG_SCSI: 0; + } + options++; + } +@@ -798,7 +800,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) + snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL), + total_size, real_filename, + (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), +- total_size / (int64_t)(63 * 16)); ++ total_size / (int64_t)(63 * 16), ++ flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide"); + + /* write the descriptor */ + lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET); +diff --git a/block_int.h b/block_int.h +index 545ad11..771fd91 100644 +--- a/block_int.h ++++ b/block_int.h +@@ -30,10 +30,12 @@ + + #define BLOCK_FLAG_ENCRYPT 1 + #define BLOCK_FLAG_COMPAT6 4 ++#define BLOCK_FLAG_SCSI 8 + + #define BLOCK_OPT_SIZE "size" + #define BLOCK_OPT_ENCRYPT "encryption" + #define BLOCK_OPT_COMPAT6 "compat6" ++#define BLOCK_OPT_SCSI "scsi" + #define BLOCK_OPT_BACKING_FILE "backing_file" + #define BLOCK_OPT_BACKING_FMT "backing_fmt" + #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" +diff --git a/qemu-img.c b/qemu-img.c +index 4a37358..ed8cc08 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -572,7 +572,7 @@ static int img_convert(int argc, char **argv) + const uint8_t *buf1; + BlockDriverInfo bdi; + QEMUOptionParameter *param = NULL, *create_options = NULL; +- QEMUOptionParameter *out_baseimg_param; ++ QEMUOptionParameter *out_baseimg_param, *scsi; + char *options = NULL; + const char *snapshot_name = NULL; + +@@ -727,6 +727,12 @@ static int img_convert(int argc, char **argv) + } + } + ++ if ((scsi = get_option_parameter(param, BLOCK_OPT_SCSI)) && scsi->value.n && strcmp(drv->format_name, "vmdk")) { ++ error_report("SCSI devices not supported for this file format"); ++ ret = -1; ++ goto out; ++ } ++ + /* Create the new image */ + ret = bdrv_create(drv, out_filename, param); + if (ret < 0) { +-- +1.7.1 + diff --git a/0012-qemu-cvs-pthread.patch b/0012-qemu-cvs-pthread.patch deleted file mode 100644 index 4f43936b..00000000 --- a/0012-qemu-cvs-pthread.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9e89bde7061d46a60dfe895450053360427a32f0 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Tue, 14 Apr 2009 16:34:36 +0200 -Subject: [PATCH 12/33] qemu-cvs-pthread - -Link with libpthread. Not sure if still necessary. - -Signed-off-by: Ulrich Hecht ---- - Makefile | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/Makefile b/Makefile -index e4f9498..be55d3d 100644 ---- a/Makefile -+++ b/Makefile -@@ -19,7 +19,7 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw - CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP -MT $@ - CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE - CPPFLAGS += -U_FORTIFY_SOURCE --LIBS= -+LIBS=-lpthread - ifdef CONFIG_STATIC - LDFLAGS += -static - endif --- -1.6.2.1 - diff --git a/0014-qemu-nonvoid_return.patch b/0012-qemu-nonvoid_return.patch similarity index 78% rename from 0014-qemu-nonvoid_return.patch rename to 0012-qemu-nonvoid_return.patch index a5a1da92..69f32979 100644 --- a/0014-qemu-nonvoid_return.patch +++ b/0012-qemu-nonvoid_return.patch @@ -1,7 +1,7 @@ -From 29b517b3811d8745eb73e95fe18552eb1f0153af Mon Sep 17 00:00:00 2001 +From 75c51f45c127ebe4f549041aae98f510480429ae Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Tue, 14 Apr 2009 16:38:20 +0200 -Subject: [PATCH 14/33] qemu-nonvoid_return +Subject: [PATCH 12/17] qemu-nonvoid_return Squelches GCC warnings about undefined return values. @@ -12,10 +12,10 @@ Signed-off-by: Ulrich Hecht 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/mpcore.c b/hw/mpcore.c -index 907bd99..a682695 100644 +index fc05215..7bdb495 100644 --- a/hw/mpcore.c +++ b/hw/mpcore.c -@@ -108,6 +108,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset) +@@ -104,6 +104,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset) default: return 0; } @@ -24,7 +24,7 @@ index 907bd99..a682695 100644 static void mpcore_timer_write(mpcore_timer_state *s, int offset, diff --git a/target-m68k/translate.c b/target-m68k/translate.c -index b37578b..feaa155 100644 +index 6f72a2b..7d9492b 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -440,6 +440,7 @@ static inline int opsize_bytes(int opsize) @@ -36,5 +36,5 @@ index b37578b..feaa155 100644 /* Assign value to a register. If the width is less than the register width -- -1.6.2.1 +1.7.1 diff --git a/0016-i386-linux-user-NPTL-support.patch b/0013-i386-linux-user-NPTL-support.patch similarity index 83% rename from 0016-i386-linux-user-NPTL-support.patch rename to 0013-i386-linux-user-NPTL-support.patch index 39c6e78f..c52fe858 100644 --- a/0016-i386-linux-user-NPTL-support.patch +++ b/0013-i386-linux-user-NPTL-support.patch @@ -1,7 +1,7 @@ -From e770ff83915791d048ca88da6c3877cb54bf063e Mon Sep 17 00:00:00 2001 +From f44ecd4fcdb8e02e6bd58201a81f047d1e109508 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 16 Apr 2009 15:14:12 +0200 -Subject: [PATCH 16/33] i386-linux-user NPTL support +Subject: [PATCH 13/17] i386-linux-user NPTL support Makes NPTL binaries run by implementing TLS. @@ -12,10 +12,10 @@ Signed-off-by: Ulrich Hecht 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/configure b/configure -index 4ce7bc1..4f79498 100755 +index 598e8e1..95de763 100755 --- a/configure +++ b/configure -@@ -1904,6 +1904,7 @@ TARGET_ABI_DIR="" +@@ -2910,6 +2910,7 @@ TARGET_ABI_DIR="" case "$target_arch2" in i386) target_phys_bits=32 @@ -24,10 +24,10 @@ index 4ce7bc1..4f79498 100755 x86_64) TARGET_BASE_ARCH=i386 diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index faf41b1..87ceac7 100644 +index 81bf1f0..1a98433 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c -@@ -3575,8 +3575,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, +@@ -3792,8 +3792,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, ts->child_tidptr = child_tidptr; } @@ -43,7 +43,7 @@ index faf41b1..87ceac7 100644 /* Grab a mutex so that thread setup appears atomic. */ pthread_mutex_lock(&clone_lock); -@@ -3648,8 +3654,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, +@@ -3867,8 +3873,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, if (flags & CLONE_PARENT_SETTID) put_user_u32(gettid(), parent_tidptr); ts = (TaskState *)env->opaque; @@ -60,5 +60,5 @@ index faf41b1..87ceac7 100644 ts->child_tidptr = child_tidptr; #endif -- -1.6.2.1 +1.7.1 diff --git a/0013-qemu-img-vmdk-scsi.patch b/0013-qemu-img-vmdk-scsi.patch deleted file mode 100644 index f97f045a..00000000 --- a/0013-qemu-img-vmdk-scsi.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 75e8da1c5ca1b61a9a97fcc385eb5c6b9f83130f Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Tue, 14 Apr 2009 16:37:42 +0200 -Subject: [PATCH 13/33] qemu-img-vmdk-scsi - -Support creation of SCSI VMDK images in qemu-img. - -Signed-off-by: Ulrich Hecht ---- - block/vmdk.c | 5 +++-- - block_int.h | 1 + - qemu-img-cmds.hx | 8 ++++---- - qemu-img.c | 15 +++++++++++++-- - 4 files changed, 21 insertions(+), 8 deletions(-) - -diff --git a/block/vmdk.c b/block/vmdk.c -index 4e48622..b7a15c7 100644 ---- a/block/vmdk.c -+++ b/block/vmdk.c -@@ -710,7 +710,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) - "ddb.geometry.cylinders = \"%" PRId64 "\"\n" - "ddb.geometry.heads = \"16\"\n" - "ddb.geometry.sectors = \"63\"\n" -- "ddb.adapterType = \"ide\"\n"; -+ "ddb.adapterType = \"%s\"\n"; - char desc[1024]; - const char *real_filename, *temp_str; - int64_t total_size = 0; -@@ -800,7 +800,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) - snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL), - total_size, real_filename, - (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), -- total_size / (int64_t)(63 * 16)); -+ total_size / (int64_t)(63 * 16), -+ flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide"); - - /* write the descriptor */ - lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET); -diff --git a/block_int.h b/block_int.h -index 8898d91..d482050 100644 ---- a/block_int.h -+++ b/block_int.h -@@ -30,6 +30,7 @@ - #define BLOCK_FLAG_ENCRYPT 1 - #define BLOCK_FLAG_COMPRESS 2 - #define BLOCK_FLAG_COMPAT6 4 -+#define BLOCK_FLAG_SCSI 8 - - #define BLOCK_OPT_SIZE "size" - #define BLOCK_OPT_ENCRYPT "encryption" -diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx -index ddb86f0..be94d22 100644 ---- a/qemu-img-cmds.hx -+++ b/qemu-img-cmds.hx -@@ -16,9 +16,9 @@ STEXI - ETEXI - - DEF("create", img_create, -- "create [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]") -+ "create [-s] [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]") - STEXI --@item create [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] -+@item create [-s] [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] - ETEXI - - DEF("commit", img_commit, -@@ -28,9 +28,9 @@ STEXI - ETEXI - - DEF("convert", img_convert, -- "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename") -+ "convert [-c] [-s] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename") - STEXI --@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename} -+@item convert [-c] [-s] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename} - ETEXI - - DEF("info", img_info, -diff --git a/qemu-img.c b/qemu-img.c -index 070fe2e..2adeb56 100644 ---- a/qemu-img.c -+++ b/qemu-img.c -@@ -259,7 +259,7 @@ static int img_create(int argc, char **argv) - - flags = 0; - for(;;) { -- c = getopt(argc, argv, "F:b:f:he6o:"); -+ c = getopt(argc, argv, "F:b:f:hes6o:"); - if (c == -1) - break; - switch(c) { -@@ -278,6 +278,9 @@ static int img_create(int argc, char **argv) - case 'e': - flags |= BLOCK_FLAG_ENCRYPT; - break; -+ case 's': -+ flags |= BLOCK_FLAG_SCSI; -+ break; - case '6': - flags |= BLOCK_FLAG_COMPAT6; - break; -@@ -357,6 +360,8 @@ static int img_create(int argc, char **argv) - - printf("Formatting '%s', fmt=%s ", filename, fmt); - print_option_parameters(param); -+ if (flags & BLOCK_FLAG_SCSI) -+ printf(", SCSI"); - puts(""); - - ret = bdrv_create(drv, filename, param); -@@ -551,7 +556,7 @@ static int img_convert(int argc, char **argv) - out_baseimg = NULL; - flags = 0; - for(;;) { -- c = getopt(argc, argv, "f:O:B:hce6o:"); -+ c = getopt(argc, argv, "f:O:B:hces6o:"); - if (c == -1) - break; - switch(c) { -@@ -573,6 +578,9 @@ static int img_convert(int argc, char **argv) - case 'e': - flags |= BLOCK_FLAG_ENCRYPT; - break; -+ case 's': -+ flags |= BLOCK_FLAG_SCSI; -+ break; - case '6': - flags |= BLOCK_FLAG_COMPAT6; - break; -@@ -639,6 +647,9 @@ static int img_convert(int argc, char **argv) - } - } - -+ if (flags & BLOCK_FLAG_SCSI && strcmp(drv->format_name, "vmdk")) -+ error("SCSI devices not supported for this file format"); -+ - /* Create the new image */ - ret = bdrv_create(drv, out_filename, param); - free_option_parameters(param); --- -1.6.2.1 - diff --git a/0017-qemu-0.11-git-ioctl_mount.patch b/0014-qemu-0.11-git-ioctl_mount.patch similarity index 80% rename from 0017-qemu-0.11-git-ioctl_mount.patch rename to 0014-qemu-0.11-git-ioctl_mount.patch index 3d0b1798..32384664 100644 --- a/0017-qemu-0.11-git-ioctl_mount.patch +++ b/0014-qemu-0.11-git-ioctl_mount.patch @@ -1,17 +1,17 @@ -From df6df89350799107b3395665943c4df7eeba87e0 Mon Sep 17 00:00:00 2001 +From 3f23daf11dab4206ef87839bb513c4f97609f112 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Wed, 17 Jun 2009 14:54:48 +0200 -Subject: [PATCH 17/33] qemu-0.11-git-ioctl_mount +Subject: [PATCH 14/17] qemu-0.11-git-ioctl_mount --- linux-user/ioctls.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h -index aee5a88..a0fb052 100644 +index 13ff54f..2442040 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h -@@ -310,7 +310,7 @@ +@@ -317,7 +317,7 @@ IOCTL(LOOP_CLR_FD, 0, TYPE_INT) IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info))) IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info))) @@ -21,5 +21,5 @@ index aee5a88..a0fb052 100644 IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) #endif -- -1.6.2.1 +1.7.1 diff --git a/0021-S-390-CPU-emulation.patch b/0015-S-390-support.patch similarity index 55% rename from 0021-S-390-CPU-emulation.patch rename to 0015-S-390-support.patch index e8d1c93f..d4c031e0 100644 --- a/0021-S-390-CPU-emulation.patch +++ b/0015-S-390-support.patch @@ -1,303 +1,2044 @@ -From 5567f8f0512bc4fa8a31b4691d9fce49eaf40bb9 Mon Sep 17 00:00:00 2001 +From c0218c03294d692613596cdf361badaa63a700d6 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht -Date: Fri, 24 Jul 2009 16:58:54 +0200 -Subject: [PATCH 21/33] S/390 CPU emulation +Date: Tue, 24 Aug 2010 13:23:23 +0200 +Subject: [PATCH 15/17] S/390 support -Currently only does userspace with 64-bit addressing, but it's quite good -at that. - -Signed-off-by: Ulrich Hecht --- - cpu-exec.c | 42 + - disas.c | 3 + - s390-dis.c | 4 +- - target-s390x/cpu.h | 131 +++ - target-s390x/exec.h | 51 + - target-s390x/helper.c | 81 ++ - target-s390x/helpers.h | 128 +++ - target-s390x/op_helper.c | 1719 ++++++++++++++++++++++++++++++++ - target-s390x/translate.c | 2479 ++++++++++++++++++++++++++++++++++++++++++++++ - 9 files changed, 4636 insertions(+), 2 deletions(-) - create mode 100644 target-s390x/cpu.h - create mode 100644 target-s390x/exec.h - create mode 100644 target-s390x/helper.c + configure | 2 + + cpu-all.h | 2 +- + cpu-defs.h | 8 + + cpu-exec.c | 14 +- + default-configs/s390x-linux-user.mak | 1 + + disas.c | 3 + + linux-user/elfload.c | 18 + + linux-user/main.c | 89 ++ + linux-user/s390x/syscall.h | 25 + + linux-user/s390x/syscall_nr.h | 348 +++++ + linux-user/s390x/target_signal.h | 26 + + linux-user/s390x/termbits.h | 283 ++++ + linux-user/signal.c | 314 ++++ + linux-user/syscall.c | 144 ++- + linux-user/syscall_defs.h | 56 +- + s390x.ld | 194 +++ + scripts/qemu-binfmt-conf.sh | 5 +- + target-s390x/cpu.h | 29 +- + target-s390x/exec.h | 8 + + target-s390x/helper.c | 25 +- + target-s390x/helpers.h | 127 ++ + target-s390x/op_helper.c | 1607 +++++++++++++++++++ + target-s390x/translate.c | 2795 ++++++++++++++++++++++++++++++++++ + tcg/tcg-op.h | 12 + + tcg/tcg-opc.h | 2 + + tcg/tcg.c | 6 + + 26 files changed, 6102 insertions(+), 41 deletions(-) + create mode 100644 default-configs/s390x-linux-user.mak + create mode 100644 linux-user/s390x/syscall.h + create mode 100644 linux-user/s390x/syscall_nr.h + create mode 100644 linux-user/s390x/target_signal.h + create mode 100644 linux-user/s390x/termbits.h + create mode 100644 s390x.ld create mode 100644 target-s390x/helpers.h - create mode 100644 target-s390x/op_helper.c - create mode 100644 target-s390x/translate.c +diff --git a/configure b/configure +index 95de763..bd1484b 100755 +--- a/configure ++++ b/configure +@@ -1018,6 +1018,7 @@ sh4eb-linux-user \ + sparc-linux-user \ + sparc64-linux-user \ + sparc32plus-linux-user \ ++s390x-linux-user \ + " + fi + # the following are Darwin specific +@@ -3006,6 +3007,7 @@ case "$target_arch2" in + target_phys_bits=64 + ;; + s390x) ++ target_nptl="yes" + target_phys_bits=64 + ;; + *) +diff --git a/cpu-all.h b/cpu-all.h +index ffbd6a4..3713bce 100644 +--- a/cpu-all.h ++++ b/cpu-all.h +@@ -138,7 +138,7 @@ typedef union { + uint64_t ll; + } CPU_DoubleU; + +-#ifdef TARGET_SPARC ++#if defined(TARGET_SPARC) || defined(TARGET_S390X) + typedef union { + float128 q; + #if defined(HOST_WORDS_BIGENDIAN) \ +diff --git a/cpu-defs.h b/cpu-defs.h +index 8d4bf86..1d489c5 100644 +--- a/cpu-defs.h ++++ b/cpu-defs.h +@@ -148,6 +148,13 @@ typedef struct CPUWatchpoint { + } CPUWatchpoint; + + #define CPU_TEMP_BUF_NLONGS 128 ++ ++#ifdef CONFIG_USER_ONLY ++#define MULTITHREAD uint32_t multithreaded; ++#else ++#define MULTITHREAD ++#endif ++ + #define CPU_COMMON \ + struct TranslationBlock *current_tb; /* currently executing TB */ \ + /* soft mmu support */ \ +@@ -160,6 +167,7 @@ typedef struct CPUWatchpoint { + memory was accessed */ \ + uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ + uint32_t interrupt_request; \ ++ MULTITHREAD /* needs locking when accessing TBs */ \ + volatile sig_atomic_t exit_request; \ + CPU_COMMON_TLB \ + struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \ diff --git a/cpu-exec.c b/cpu-exec.c -index 2385d56..855ea3e 100644 +index 8c9fb8b..38ce4c0 100644 --- a/cpu-exec.c +++ b/cpu-exec.c -@@ -249,6 +249,7 @@ int cpu_exec(CPUState *env1) - #elif defined(TARGET_MIPS) - #elif defined(TARGET_SH4) - #elif defined(TARGET_CRIS) -+#elif defined(TARGET_S390X) - /* XXXXX */ - #else - #error unsupported target CPU -@@ -712,6 +713,7 @@ int cpu_exec(CPUState *env1) - #elif defined(TARGET_SH4) - #elif defined(TARGET_ALPHA) - #elif defined(TARGET_CRIS) -+#elif defined(TARGET_S390X) - /* XXXXX */ - #else - #error unsupported target CPU -@@ -1234,6 +1236,46 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - return 1; - } - -+#elif defined (TARGET_S390X) -+static inline int handle_cpu_signal(unsigned long pc, unsigned long address, -+ int is_write, sigset_t *old_set, -+ void *puc) -+{ -+ TranslationBlock *tb; -+ int ret; -+ -+ if (cpu_single_env) -+ env = cpu_single_env; /* XXX: find a correct solution for multithread */ -+#if defined(DEBUG_SIGNAL) -+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", -+ pc, address, is_write, *(unsigned long *)old_set); +@@ -229,6 +229,9 @@ int cpu_exec(CPUState *env1) + TranslationBlock *tb; + uint8_t *tc_ptr; + unsigned long next_tb; ++#ifdef CONFIG_USER_ONLY ++ uint32_t multithreaded; +#endif -+ /* XXX: locking issue */ -+ if (is_write && page_unprotect(h2g(address), pc, puc)) { -+ return 1; -+ } -+ -+ /* see if it is an MMU fault */ -+ ret = cpu_s390x_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); -+ if (ret < 0) -+ return 0; /* not an MMU fault */ -+ if (ret == 0) -+ return 1; /* the MMU fault was handled without causing real CPU fault */ -+ -+ /* now we have a real cpu fault */ -+ tb = tb_find_pc(pc); -+ if (tb) { -+ /* the PC is inside the translated code. It means that we have -+ a virtual CPU fault */ -+ cpu_restore_state(tb, env, pc, puc); -+ } -+ /* we restore the process signal mask as the sigreturn should -+ do it (XXX: use sigsetjmp) */ -+ sigprocmask(SIG_SETMASK, old_set, NULL); -+ cpu_loop_exit(); -+ /* never comes here */ -+ return 1; -+} - #else - #error unsupported target CPU + + if (cpu_halted(env1) == EXCP_HALTED) + return EXCP_HALTED; +@@ -573,7 +576,11 @@ int cpu_exec(CPUState *env1) #endif + } + #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */ +- spin_lock(&tb_lock); ++#ifdef CONFIG_USER_ONLY ++ multithreaded = env->multithreaded; ++ if (multithreaded) ++#endif ++ spin_lock(&tb_lock); + tb = tb_find_fast(); + /* Note: we do it here to avoid a gcc bug on Mac OS X when + doing it in tb_find_slow */ +@@ -595,7 +602,10 @@ int cpu_exec(CPUState *env1) + if (next_tb != 0 && tb->page_addr[1] == -1) { + tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); + } +- spin_unlock(&tb_lock); ++#ifdef CONFIG_USER_ONLY ++ if (multithreaded) ++#endif ++ spin_unlock(&tb_lock); + + /* cpu_interrupt might be called while translating the + TB, but before it is linked into a potentially +diff --git a/default-configs/s390x-linux-user.mak b/default-configs/s390x-linux-user.mak +new file mode 100644 +index 0000000..a243c99 +--- /dev/null ++++ b/default-configs/s390x-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for s390x-linux-user diff --git a/disas.c b/disas.c -index af5a9ea..da5b1a5 100644 +index c76f36f..dbc1d0a 100644 --- a/disas.c +++ b/disas.c -@@ -195,6 +195,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) - #elif defined(TARGET_CRIS) - disasm_info.mach = bfd_mach_cris_v32; - print_insn = print_insn_crisv32; +@@ -215,6 +215,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) + disasm_info.mach = bfd_mach_cris_v32; + print_insn = print_insn_crisv32; + } +#elif defined(TARGET_S390X) + disasm_info.mach = bfd_mach_s390_64; + print_insn = print_insn_s390; #elif defined(TARGET_MICROBLAZE) disasm_info.mach = bfd_arch_microblaze; print_insn = print_insn_microblaze; -diff --git a/s390-dis.c b/s390-dis.c -index 86dd84f..9a73a57 100644 ---- a/s390-dis.c -+++ b/s390-dis.c -@@ -191,10 +191,10 @@ init_disasm (struct disassemble_info *info) - // switch (info->mach) - // { - // case bfd_mach_s390_31: -- current_arch_mask = 1 << S390_OPCODE_ESA; -+// current_arch_mask = 1 << S390_OPCODE_ESA; - // break; - // case bfd_mach_s390_64: --// current_arch_mask = 1 << S390_OPCODE_ZARCH; -+ current_arch_mask = 1 << S390_OPCODE_ZARCH; - // break; - // default: - // abort (); -diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h -new file mode 100644 -index 0000000..3505df4 ---- /dev/null -+++ b/target-s390x/cpu.h -@@ -0,0 +1,131 @@ -+/* -+ * S/390 virtual CPU header -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -+ */ -+#ifndef CPU_S390X_H -+#define CPU_S390X_H +diff --git a/linux-user/elfload.c b/linux-user/elfload.c +index 33d776d..8554a04 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -793,6 +793,24 @@ static inline void init_thread(struct target_pt_regs *regs, + + #endif /* TARGET_ALPHA */ + ++#ifdef TARGET_S390X + -+#define TARGET_LONG_BITS 64 ++#define ELF_START_MMAP (0x20000000000ULL) + -+#define ELF_MACHINE EM_S390 ++#define elf_check_arch(x) ( (x) == ELF_ARCH ) + -+#define CPUState struct CPUS390XState ++#define ELF_CLASS ELFCLASS64 ++#define ELF_DATA ELFDATA2MSB ++#define ELF_ARCH EM_S390 + -+#include "cpu-defs.h" -+ -+#include "softfloat.h" -+ -+#define NB_MMU_MODES 2 // guess -+#define MMU_USER_IDX 0 // guess -+ -+typedef union FPReg { -+ struct { -+#ifdef WORDS_BIGENDIAN -+ float32 e; -+ int32_t __pad; -+#else -+ int32_t __pad; -+ float32 e; -+#endif -+ }; -+ float64 d; -+ uint64_t i; -+} FPReg; -+ -+typedef struct CPUS390XState { -+ uint64_t regs[16]; /* GP registers */ -+ -+ uint32_t aregs[16]; /* access registers */ -+ -+ uint32_t fpc; /* floating-point control register */ -+ FPReg fregs[16]; /* FP registers */ -+ float_status fpu_status; /* passed to softfloat lib */ -+ -+ struct { -+ uint64_t mask; -+ uint64_t addr; -+ } psw; -+ -+ int cc; /* condition code (0-3) */ -+ -+ uint64_t __excp_addr; -+ -+ CPU_COMMON -+} CPUS390XState; -+ -+#if defined(CONFIG_USER_ONLY) -+static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) ++static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ -+ if (newsp) -+ env->regs[15] = newsp; -+ env->regs[0] = 0; ++ regs->psw.addr = infop->entry; ++ regs->gprs[15] = infop->start_stack; +} ++ ++#endif /* TARGET_S390X */ ++ + #ifndef ELF_PLATFORM + #define ELF_PLATFORM (NULL) + #endif +diff --git a/linux-user/main.c b/linux-user/main.c +index 0d627d6..812efda 100644 +--- a/linux-user/main.c ++++ b/linux-user/main.c +@@ -2624,6 +2624,86 @@ void cpu_loop (CPUState *env) + } + #endif /* TARGET_ALPHA */ + ++#ifdef TARGET_S390X ++void cpu_loop(CPUS390XState *env) ++{ ++ int trapnr; ++ target_siginfo_t info; ++ ++ while (1) { ++ trapnr = cpu_s390x_exec (env); ++ ++ if ((trapnr & 0xffff0000) == EXCP_EXECUTE_SVC) { ++ int n = trapnr & 0xffff; ++ env->regs[2] = do_syscall(env, n, ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5], ++ env->regs[6], ++ env->regs[7]); ++ } ++ else switch (trapnr) { ++ case EXCP_INTERRUPT: ++ /* just indicate that signals should be handled asap */ ++ break; ++ case EXCP_DEBUG: ++ { ++ int sig; ++ ++ sig = gdb_handlesig (env, TARGET_SIGTRAP); ++ if (sig) { ++ info.si_signo = sig; ++ info.si_errno = 0; ++ info.si_code = TARGET_TRAP_BRKPT; ++ queue_signal(env, info.si_signo, &info); ++ } ++ } ++ break; ++ case EXCP_SVC: ++ { ++ int n = ldub(env->psw.addr - 1); ++ if (!n) n = env->regs[1]; /* syscalls > 255 */ ++ env->regs[2] = do_syscall(env, n, ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5], ++ env->regs[6], ++ env->regs[7]); ++ } ++ break; ++ case EXCP_ADDR: ++ { ++ info.si_signo = SIGSEGV; ++ info.si_errno = 0; ++ /* XXX: check env->error_code */ ++ info.si_code = TARGET_SEGV_MAPERR; ++ info._sifields._sigfault._addr = env->__excp_addr; ++ queue_signal(env, info.si_signo, &info); ++ } ++ break; ++ case EXCP_SPEC: ++ { ++ fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4)); ++ info.si_signo = SIGILL; ++ info.si_errno = 0; ++ info.si_code = TARGET_ILL_ILLOPC; ++ info._sifields._sigfault._addr = env->__excp_addr; ++ queue_signal(env, info.si_signo, &info); ++ } ++ break; ++ default: ++ printf ("Unhandled trap: 0x%x\n", trapnr); ++ cpu_dump_state(env, stderr, fprintf, 0); ++ exit (1); ++ } ++ process_pending_signals (env); ++ } ++} ++ ++#endif /* TARGET_S390X */ ++ + static void usage(void) + { + printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n" +@@ -3354,6 +3434,15 @@ int main(int argc, char **argv, char **envp) + env->regs[15] = regs->acr; + env->pc = regs->erp; + } ++#elif defined(TARGET_S390X) ++ { ++ int i; ++ for (i = 0; i < 16; i++) { ++ env->regs[i] = regs->gprs[i]; ++ } ++ env->psw.mask = regs->psw.mask; ++ env->psw.addr = regs->psw.addr; ++ } + #else + #error unsupported target CPU + #endif +diff --git a/linux-user/s390x/syscall.h b/linux-user/s390x/syscall.h +new file mode 100644 +index 0000000..a3812a8 +--- /dev/null ++++ b/linux-user/s390x/syscall.h +@@ -0,0 +1,25 @@ ++/* this typedef defines how a Program Status Word looks like */ ++typedef struct ++{ ++ abi_ulong mask; ++ abi_ulong addr; ++} __attribute__ ((aligned(8))) target_psw_t; ++ ++/* ++ * The pt_regs struct defines the way the registers are stored on ++ * the stack during a system call. ++ */ ++ ++#define TARGET_NUM_GPRS 16 ++ ++struct target_pt_regs ++{ ++ abi_ulong args[1]; ++ target_psw_t psw; ++ abi_ulong gprs[TARGET_NUM_GPRS]; ++ abi_ulong orig_gpr2; ++ unsigned short ilc; ++ unsigned short trap; ++}; ++ ++#define UNAME_MACHINE "s390x" +diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h +new file mode 100644 +index 0000000..4a60b9a +--- /dev/null ++++ b/linux-user/s390x/syscall_nr.h +@@ -0,0 +1,348 @@ ++/* ++ * This file contains the system call numbers. ++ */ ++ ++#define TARGET_NR_exit 1 ++#define TARGET_NR_fork 2 ++#define TARGET_NR_read 3 ++#define TARGET_NR_write 4 ++#define TARGET_NR_open 5 ++#define TARGET_NR_close 6 ++#define TARGET_NR_restart_syscall 7 ++#define TARGET_NR_creat 8 ++#define TARGET_NR_link 9 ++#define TARGET_NR_unlink 10 ++#define TARGET_NR_execve 11 ++#define TARGET_NR_chdir 12 ++#define TARGET_NR_mknod 14 ++#define TARGET_NR_chmod 15 ++#define TARGET_NR_lseek 19 ++#define TARGET_NR_getpid 20 ++#define TARGET_NR_mount 21 ++#define TARGET_NR_umount 22 ++#define TARGET_NR_ptrace 26 ++#define TARGET_NR_alarm 27 ++#define TARGET_NR_pause 29 ++#define TARGET_NR_utime 30 ++#define TARGET_NR_access 33 ++#define TARGET_NR_nice 34 ++#define TARGET_NR_sync 36 ++#define TARGET_NR_kill 37 ++#define TARGET_NR_rename 38 ++#define TARGET_NR_mkdir 39 ++#define TARGET_NR_rmdir 40 ++#define TARGET_NR_dup 41 ++#define TARGET_NR_pipe 42 ++#define TARGET_NR_times 43 ++#define TARGET_NR_brk 45 ++#define TARGET_NR_signal 48 ++#define TARGET_NR_acct 51 ++#define TARGET_NR_umount2 52 ++#define TARGET_NR_ioctl 54 ++#define TARGET_NR_fcntl 55 ++#define TARGET_NR_setpgid 57 ++#define TARGET_NR_umask 60 ++#define TARGET_NR_chroot 61 ++#define TARGET_NR_ustat 62 ++#define TARGET_NR_dup2 63 ++#define TARGET_NR_getppid 64 ++#define TARGET_NR_getpgrp 65 ++#define TARGET_NR_setsid 66 ++#define TARGET_NR_sigaction 67 ++#define TARGET_NR_sigsuspend 72 ++#define TARGET_NR_sigpending 73 ++#define TARGET_NR_sethostname 74 ++#define TARGET_NR_setrlimit 75 ++#define TARGET_NR_getrusage 77 ++#define TARGET_NR_gettimeofday 78 ++#define TARGET_NR_settimeofday 79 ++#define TARGET_NR_symlink 83 ++#define TARGET_NR_readlink 85 ++#define TARGET_NR_uselib 86 ++#define TARGET_NR_swapon 87 ++#define TARGET_NR_reboot 88 ++#define TARGET_NR_readdir 89 ++#define TARGET_NR_mmap 90 ++#define TARGET_NR_munmap 91 ++#define TARGET_NR_truncate 92 ++#define TARGET_NR_ftruncate 93 ++#define TARGET_NR_fchmod 94 ++#define TARGET_NR_getpriority 96 ++#define TARGET_NR_setpriority 97 ++#define TARGET_NR_statfs 99 ++#define TARGET_NR_fstatfs 100 ++#define TARGET_NR_socketcall 102 ++#define TARGET_NR_syslog 103 ++#define TARGET_NR_setitimer 104 ++#define TARGET_NR_getitimer 105 ++#define TARGET_NR_stat 106 ++#define TARGET_NR_lstat 107 ++#define TARGET_NR_fstat 108 ++#define TARGET_NR_lookup_dcookie 110 ++#define TARGET_NR_vhangup 111 ++#define TARGET_NR_idle 112 ++#define TARGET_NR_wait4 114 ++#define TARGET_NR_swapoff 115 ++#define TARGET_NR_sysinfo 116 ++#define TARGET_NR_ipc 117 ++#define TARGET_NR_fsync 118 ++#define TARGET_NR_sigreturn 119 ++#define TARGET_NR_clone 120 ++#define TARGET_NR_setdomainname 121 ++#define TARGET_NR_uname 122 ++#define TARGET_NR_adjtimex 124 ++#define TARGET_NR_mprotect 125 ++#define TARGET_NR_sigprocmask 126 ++#define TARGET_NR_create_module 127 ++#define TARGET_NR_init_module 128 ++#define TARGET_NR_delete_module 129 ++#define TARGET_NR_get_kernel_syms 130 ++#define TARGET_NR_quotactl 131 ++#define TARGET_NR_getpgid 132 ++#define TARGET_NR_fchdir 133 ++#define TARGET_NR_bdflush 134 ++#define TARGET_NR_sysfs 135 ++#define TARGET_NR_personality 136 ++#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ ++#define TARGET_NR_getdents 141 ++#define TARGET_NR_flock 143 ++#define TARGET_NR_msync 144 ++#define TARGET_NR_readv 145 ++#define TARGET_NR_writev 146 ++#define TARGET_NR_getsid 147 ++#define TARGET_NR_fdatasync 148 ++#define TARGET_NR__sysctl 149 ++#define TARGET_NR_mlock 150 ++#define TARGET_NR_munlock 151 ++#define TARGET_NR_mlockall 152 ++#define TARGET_NR_munlockall 153 ++#define TARGET_NR_sched_setparam 154 ++#define TARGET_NR_sched_getparam 155 ++#define TARGET_NR_sched_setscheduler 156 ++#define TARGET_NR_sched_getscheduler 157 ++#define TARGET_NR_sched_yield 158 ++#define TARGET_NR_sched_get_priority_max 159 ++#define TARGET_NR_sched_get_priority_min 160 ++#define TARGET_NR_sched_rr_get_interval 161 ++#define TARGET_NR_nanosleep 162 ++#define TARGET_NR_mremap 163 ++#define TARGET_NR_query_module 167 ++#define TARGET_NR_poll 168 ++#define TARGET_NR_nfsservctl 169 ++#define TARGET_NR_prctl 172 ++#define TARGET_NR_rt_sigreturn 173 ++#define TARGET_NR_rt_sigaction 174 ++#define TARGET_NR_rt_sigprocmask 175 ++#define TARGET_NR_rt_sigpending 176 ++#define TARGET_NR_rt_sigtimedwait 177 ++#define TARGET_NR_rt_sigqueueinfo 178 ++#define TARGET_NR_rt_sigsuspend 179 ++#define TARGET_NR_pread64 180 ++#define TARGET_NR_pwrite64 181 ++#define TARGET_NR_getcwd 183 ++#define TARGET_NR_capget 184 ++#define TARGET_NR_capset 185 ++#define TARGET_NR_sigaltstack 186 ++#define TARGET_NR_sendfile 187 ++#define TARGET_NR_getpmsg 188 ++#define TARGET_NR_putpmsg 189 ++#define TARGET_NR_vfork 190 ++#define TARGET_NR_pivot_root 217 ++#define TARGET_NR_mincore 218 ++#define TARGET_NR_madvise 219 ++#define TARGET_NR_getdents64 220 ++#define TARGET_NR_readahead 222 ++#define TARGET_NR_setxattr 224 ++#define TARGET_NR_lsetxattr 225 ++#define TARGET_NR_fsetxattr 226 ++#define TARGET_NR_getxattr 227 ++#define TARGET_NR_lgetxattr 228 ++#define TARGET_NR_fgetxattr 229 ++#define TARGET_NR_listxattr 230 ++#define TARGET_NR_llistxattr 231 ++#define TARGET_NR_flistxattr 232 ++#define TARGET_NR_removexattr 233 ++#define TARGET_NR_lremovexattr 234 ++#define TARGET_NR_fremovexattr 235 ++#define TARGET_NR_gettid 236 ++#define TARGET_NR_tkill 237 ++#define TARGET_NR_futex 238 ++#define TARGET_NR_sched_setaffinity 239 ++#define TARGET_NR_sched_getaffinity 240 ++#define TARGET_NR_tgkill 241 ++/* Number 242 is reserved for tux */ ++#define TARGET_NR_io_setup 243 ++#define TARGET_NR_io_destroy 244 ++#define TARGET_NR_io_getevents 245 ++#define TARGET_NR_io_submit 246 ++#define TARGET_NR_io_cancel 247 ++#define TARGET_NR_exit_group 248 ++#define TARGET_NR_epoll_create 249 ++#define TARGET_NR_epoll_ctl 250 ++#define TARGET_NR_epoll_wait 251 ++#define TARGET_NR_set_tid_address 252 ++#define TARGET_NR_fadvise64 253 ++#define TARGET_NR_timer_create 254 ++#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1) ++#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2) ++#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3) ++#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4) ++#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5) ++#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6) ++#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) ++#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) ++/* Number 263 is reserved for vserver */ ++#define TARGET_NR_statfs64 265 ++#define TARGET_NR_fstatfs64 266 ++#define TARGET_NR_remap_file_pages 267 ++/* Number 268 is reserved for new sys_mbind */ ++/* Number 269 is reserved for new sys_get_mempolicy */ ++/* Number 270 is reserved for new sys_set_mempolicy */ ++#define TARGET_NR_mq_open 271 ++#define TARGET_NR_mq_unlink 272 ++#define TARGET_NR_mq_timedsend 273 ++#define TARGET_NR_mq_timedreceive 274 ++#define TARGET_NR_mq_notify 275 ++#define TARGET_NR_mq_getsetattr 276 ++#define TARGET_NR_kexec_load 277 ++#define TARGET_NR_add_key 278 ++#define TARGET_NR_request_key 279 ++#define TARGET_NR_keyctl 280 ++#define TARGET_NR_waitid 281 ++#define TARGET_NR_ioprio_set 282 ++#define TARGET_NR_ioprio_get 283 ++#define TARGET_NR_inotify_init 284 ++#define TARGET_NR_inotify_add_watch 285 ++#define TARGET_NR_inotify_rm_watch 286 ++/* Number 287 is reserved for new sys_migrate_pages */ ++#define TARGET_NR_openat 288 ++#define TARGET_NR_mkdirat 289 ++#define TARGET_NR_mknodat 290 ++#define TARGET_NR_fchownat 291 ++#define TARGET_NR_futimesat 292 ++#define TARGET_NR_unlinkat 294 ++#define TARGET_NR_renameat 295 ++#define TARGET_NR_linkat 296 ++#define TARGET_NR_symlinkat 297 ++#define TARGET_NR_readlinkat 298 ++#define TARGET_NR_fchmodat 299 ++#define TARGET_NR_faccessat 300 ++#define TARGET_NR_pselect6 301 ++#define TARGET_NR_ppoll 302 ++#define TARGET_NR_unshare 303 ++#define TARGET_NR_set_robust_list 304 ++#define TARGET_NR_get_robust_list 305 ++#define TARGET_NR_splice 306 ++#define TARGET_NR_sync_file_range 307 ++#define TARGET_NR_tee 308 ++#define TARGET_NR_vmsplice 309 ++/* Number 310 is reserved for new sys_move_pages */ ++#define TARGET_NR_getcpu 311 ++#define TARGET_NR_epoll_pwait 312 ++#define TARGET_NR_utimes 313 ++#define TARGET_NR_fallocate 314 ++#define TARGET_NR_utimensat 315 ++#define TARGET_NR_signalfd 316 ++#define TARGET_NR_timerfd 317 ++#define TARGET_NR_eventfd 318 ++#define TARGET_NR_timerfd_create 319 ++#define TARGET_NR_timerfd_settime 320 ++#define TARGET_NR_timerfd_gettime 321 ++#define TARGET_NR_signalfd4 322 ++#define TARGET_NR_eventfd2 323 ++#define TARGET_NR_inotify_init1 324 ++#define TARGET_NR_pipe2 325 ++#define TARGET_NR_dup3 326 ++#define TARGET_NR_epoll_create1 327 ++#define NR_syscalls 328 ++ ++/* ++ * There are some system calls that are not present on 64 bit, some ++ * have a different name although they do the same (e.g. TARGET_NR_chown32 ++ * is TARGET_NR_chown on 64 bit). ++ */ ++#ifndef TARGET_S390X ++ ++#define TARGET_NR_time 13 ++#define TARGET_NR_lchown 16 ++#define TARGET_NR_setuid 23 ++#define TARGET_NR_getuid 24 ++#define TARGET_NR_stime 25 ++#define TARGET_NR_setgid 46 ++#define TARGET_NR_getgid 47 ++#define TARGET_NR_geteuid 49 ++#define TARGET_NR_getegid 50 ++#define TARGET_NR_setreuid 70 ++#define TARGET_NR_setregid 71 ++#define TARGET_NR_getrlimit 76 ++#define TARGET_NR_getgroups 80 ++#define TARGET_NR_setgroups 81 ++#define TARGET_NR_fchown 95 ++#define TARGET_NR_ioperm 101 ++#define TARGET_NR_setfsuid 138 ++#define TARGET_NR_setfsgid 139 ++#define TARGET_NR__llseek 140 ++#define TARGET_NR__newselect 142 ++#define TARGET_NR_setresuid 164 ++#define TARGET_NR_getresuid 165 ++#define TARGET_NR_setresgid 170 ++#define TARGET_NR_getresgid 171 ++#define TARGET_NR_chown 182 ++#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ ++#define TARGET_NR_mmap2 192 ++#define TARGET_NR_truncate64 193 ++#define TARGET_NR_ftruncate64 194 ++#define TARGET_NR_stat64 195 ++#define TARGET_NR_lstat64 196 ++#define TARGET_NR_fstat64 197 ++#define TARGET_NR_lchown32 198 ++#define TARGET_NR_getuid32 199 ++#define TARGET_NR_getgid32 200 ++#define TARGET_NR_geteuid32 201 ++#define TARGET_NR_getegid32 202 ++#define TARGET_NR_setreuid32 203 ++#define TARGET_NR_setregid32 204 ++#define TARGET_NR_getgroups32 205 ++#define TARGET_NR_setgroups32 206 ++#define TARGET_NR_fchown32 207 ++#define TARGET_NR_setresuid32 208 ++#define TARGET_NR_getresuid32 209 ++#define TARGET_NR_setresgid32 210 ++#define TARGET_NR_getresgid32 211 ++#define TARGET_NR_chown32 212 ++#define TARGET_NR_setuid32 213 ++#define TARGET_NR_setgid32 214 ++#define TARGET_NR_setfsuid32 215 ++#define TARGET_NR_setfsgid32 216 ++#define TARGET_NR_fcntl64 221 ++#define TARGET_NR_sendfile64 223 ++#define TARGET_NR_fadvise64_64 264 ++#define TARGET_NR_fstatat64 293 ++ ++#else ++ ++#define TARGET_NR_select 142 ++#define TARGET_NR_getrlimit 191 /* SuS compliant getrlimit */ ++#define TARGET_NR_lchown 198 ++#define TARGET_NR_getuid 199 ++#define TARGET_NR_getgid 200 ++#define TARGET_NR_geteuid 201 ++#define TARGET_NR_getegid 202 ++#define TARGET_NR_setreuid 203 ++#define TARGET_NR_setregid 204 ++#define TARGET_NR_getgroups 205 ++#define TARGET_NR_setgroups 206 ++#define TARGET_NR_fchown 207 ++#define TARGET_NR_setresuid 208 ++#define TARGET_NR_getresuid 209 ++#define TARGET_NR_setresgid 210 ++#define TARGET_NR_getresgid 211 ++#define TARGET_NR_chown 212 ++#define TARGET_NR_setuid 213 ++#define TARGET_NR_setgid 214 ++#define TARGET_NR_setfsuid 215 ++#define TARGET_NR_setfsgid 216 ++#define TARGET_NR_newfstatat 293 ++ +#endif + -+CPUS390XState *cpu_s390x_init(const char *cpu_model); +diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h +new file mode 100644 +index 0000000..b4816b0 +--- /dev/null ++++ b/linux-user/s390x/target_signal.h +@@ -0,0 +1,26 @@ ++#ifndef TARGET_SIGNAL_H ++#define TARGET_SIGNAL_H ++ ++#include "cpu.h" ++ ++typedef struct target_sigaltstack { ++ abi_ulong ss_sp; ++ int ss_flags; ++ abi_ulong ss_size; ++} target_stack_t; ++ ++/* ++ * sigaltstack controls ++ */ ++#define TARGET_SS_ONSTACK 1 ++#define TARGET_SS_DISABLE 2 ++ ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_SIGSTKSZ 8192 ++ ++static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state) ++{ ++ return state->regs[15]; ++} ++ ++#endif /* TARGET_SIGNAL_H */ +diff --git a/linux-user/s390x/termbits.h b/linux-user/s390x/termbits.h +new file mode 100644 +index 0000000..2a78a05 +--- /dev/null ++++ b/linux-user/s390x/termbits.h +@@ -0,0 +1,283 @@ ++/* ++ * include/asm-s390/termbits.h ++ * ++ * S390 version ++ * ++ * Derived from "include/asm-i386/termbits.h" ++ */ ++ ++#define TARGET_NCCS 19 ++struct target_termios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++}; ++ ++struct target_termios2 { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++ unsigned int c_ispeed; /* input speed */ ++ unsigned int c_ospeed; /* output speed */ ++}; ++ ++struct target_ktermios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++ unsigned int c_ispeed; /* input speed */ ++ unsigned int c_ospeed; /* output speed */ ++}; ++ ++/* c_cc characters */ ++#define TARGET_VINTR 0 ++#define TARGET_VQUIT 1 ++#define TARGET_VERASE 2 ++#define TARGET_VKILL 3 ++#define TARGET_VEOF 4 ++#define TARGET_VTIME 5 ++#define TARGET_VMIN 6 ++#define TARGET_VSWTC 7 ++#define TARGET_VSTART 8 ++#define TARGET_VSTOP 9 ++#define TARGET_VSUSP 10 ++#define TARGET_VEOL 11 ++#define TARGET_VREPRINT 12 ++#define TARGET_VDISCARD 13 ++#define TARGET_VWERASE 14 ++#define TARGET_VLNEXT 15 ++#define TARGET_VEOL2 16 ++ ++/* c_iflag bits */ ++#define TARGET_IGNBRK 0000001 ++#define TARGET_BRKINT 0000002 ++#define TARGET_IGNPAR 0000004 ++#define TARGET_PARMRK 0000010 ++#define TARGET_INPCK 0000020 ++#define TARGET_ISTRIP 0000040 ++#define TARGET_INLCR 0000100 ++#define TARGET_IGNCR 0000200 ++#define TARGET_ICRNL 0000400 ++#define TARGET_IUCLC 0001000 ++#define TARGET_IXON 0002000 ++#define TARGET_IXANY 0004000 ++#define TARGET_IXOFF 0010000 ++#define TARGET_IMAXBEL 0020000 ++#define TARGET_IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define TARGET_OPOST 0000001 ++#define TARGET_OLCUC 0000002 ++#define TARGET_ONLCR 0000004 ++#define TARGET_OCRNL 0000010 ++#define TARGET_ONOCR 0000020 ++#define TARGET_ONLRET 0000040 ++#define TARGET_OFILL 0000100 ++#define TARGET_OFDEL 0000200 ++#define TARGET_NLDLY 0000400 ++#define TARGET_NL0 0000000 ++#define TARGET_NL1 0000400 ++#define TARGET_CRDLY 0003000 ++#define TARGET_CR0 0000000 ++#define TARGET_CR1 0001000 ++#define TARGET_CR2 0002000 ++#define TARGET_CR3 0003000 ++#define TARGET_TABDLY 0014000 ++#define TARGET_TAB0 0000000 ++#define TARGET_TAB1 0004000 ++#define TARGET_TAB2 0010000 ++#define TARGET_TAB3 0014000 ++#define TARGET_XTABS 0014000 ++#define TARGET_BSDLY 0020000 ++#define TARGET_BS0 0000000 ++#define TARGET_BS1 0020000 ++#define TARGET_VTDLY 0040000 ++#define TARGET_VT0 0000000 ++#define TARGET_VT1 0040000 ++#define TARGET_FFDLY 0100000 ++#define TARGET_FF0 0000000 ++#define TARGET_FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define TARGET_CBAUD 0010017 ++#define TARGET_B0 0000000 /* hang up */ ++#define TARGET_B50 0000001 ++#define TARGET_B75 0000002 ++#define TARGET_B110 0000003 ++#define TARGET_B134 0000004 ++#define TARGET_B150 0000005 ++#define TARGET_B200 0000006 ++#define TARGET_B300 0000007 ++#define TARGET_B600 0000010 ++#define TARGET_B1200 0000011 ++#define TARGET_B1800 0000012 ++#define TARGET_B2400 0000013 ++#define TARGET_B4800 0000014 ++#define TARGET_B9600 0000015 ++#define TARGET_B19200 0000016 ++#define TARGET_B38400 0000017 ++#define TARGET_EXTA B19200 ++#define TARGET_EXTB B38400 ++#define TARGET_CSIZE 0000060 ++#define TARGET_CS5 0000000 ++#define TARGET_CS6 0000020 ++#define TARGET_CS7 0000040 ++#define TARGET_CS8 0000060 ++#define TARGET_CSTOPB 0000100 ++#define TARGET_CREAD 0000200 ++#define TARGET_PARENB 0000400 ++#define TARGET_PARODD 0001000 ++#define TARGET_HUPCL 0002000 ++#define TARGET_CLOCAL 0004000 ++#define TARGET_CBAUDEX 0010000 ++#define TARGET_BOTHER 0010000 ++#define TARGET_B57600 0010001 ++#define TARGET_B115200 0010002 ++#define TARGET_B230400 0010003 ++#define TARGET_B460800 0010004 ++#define TARGET_B500000 0010005 ++#define TARGET_B576000 0010006 ++#define TARGET_B921600 0010007 ++#define TARGET_B1000000 0010010 ++#define TARGET_B1152000 0010011 ++#define TARGET_B1500000 0010012 ++#define TARGET_B2000000 0010013 ++#define TARGET_B2500000 0010014 ++#define TARGET_B3000000 0010015 ++#define TARGET_B3500000 0010016 ++#define TARGET_B4000000 0010017 ++#define TARGET_CIBAUD 002003600000 /* input baud rate */ ++#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define TARGET_CRTSCTS 020000000000 /* flow control */ ++ ++#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ ++ ++/* c_lflag bits */ ++#define TARGET_ISIG 0000001 ++#define TARGET_ICANON 0000002 ++#define TARGET_XCASE 0000004 ++#define TARGET_ECHO 0000010 ++#define TARGET_ECHOE 0000020 ++#define TARGET_ECHOK 0000040 ++#define TARGET_ECHONL 0000100 ++#define TARGET_NOFLSH 0000200 ++#define TARGET_TOSTOP 0000400 ++#define TARGET_ECHOCTL 0001000 ++#define TARGET_ECHOPRT 0002000 ++#define TARGET_ECHOKE 0004000 ++#define TARGET_FLUSHO 0010000 ++#define TARGET_PENDIN 0040000 ++#define TARGET_IEXTEN 0100000 ++ ++/* tcflow() and TCXONC use these */ ++#define TARGET_TCOOFF 0 ++#define TARGET_TCOON 1 ++#define TARGET_TCIOFF 2 ++#define TARGET_TCION 3 ++ ++/* tcflush() and TCFLSH use these */ ++#define TARGET_TCIFLUSH 0 ++#define TARGET_TCOFLUSH 1 ++#define TARGET_TCIOFLUSH 2 ++ ++/* tcsetattr uses these */ ++#define TARGET_TCSANOW 0 ++#define TARGET_TCSADRAIN 1 ++#define TARGET_TCSAFLUSH 2 ++ ++/* ++ * include/asm-s390/ioctls.h ++ * ++ * S390 version ++ * ++ * Derived from "include/asm-i386/ioctls.h" ++ */ ++ ++/* 0x54 is just a magic number to make these relatively unique ('T') */ ++ ++#define TARGET_TCGETS 0x5401 ++#define TARGET_TCSETS 0x5402 ++#define TARGET_TCSETSW 0x5403 ++#define TARGET_TCSETSF 0x5404 ++#define TARGET_TCGETA 0x5405 ++#define TARGET_TCSETA 0x5406 ++#define TARGET_TCSETAW 0x5407 ++#define TARGET_TCSETAF 0x5408 ++#define TARGET_TCSBRK 0x5409 ++#define TARGET_TCXONC 0x540A ++#define TARGET_TCFLSH 0x540B ++#define TARGET_TIOCEXCL 0x540C ++#define TARGET_TIOCNXCL 0x540D ++#define TARGET_TIOCSCTTY 0x540E ++#define TARGET_TIOCGPGRP 0x540F ++#define TARGET_TIOCSPGRP 0x5410 ++#define TARGET_TIOCOUTQ 0x5411 ++#define TARGET_TIOCSTI 0x5412 ++#define TARGET_TIOCGWINSZ 0x5413 ++#define TARGET_TIOCSWINSZ 0x5414 ++#define TARGET_TIOCMGET 0x5415 ++#define TARGET_TIOCMBIS 0x5416 ++#define TARGET_TIOCMBIC 0x5417 ++#define TARGET_TIOCMSET 0x5418 ++#define TARGET_TIOCGSOFTCAR 0x5419 ++#define TARGET_TIOCSSOFTCAR 0x541A ++#define TARGET_FIONREAD 0x541B ++#define TARGET_TIOCINQ FIONREAD ++#define TARGET_TIOCLINUX 0x541C ++#define TARGET_TIOCCONS 0x541D ++#define TARGET_TIOCGSERIAL 0x541E ++#define TARGET_TIOCSSERIAL 0x541F ++#define TARGET_TIOCPKT 0x5420 ++#define TARGET_FIONBIO 0x5421 ++#define TARGET_TIOCNOTTY 0x5422 ++#define TARGET_TIOCSETD 0x5423 ++#define TARGET_TIOCGETD 0x5424 ++#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ ++#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ ++#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ ++#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ ++#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2) ++#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2) ++#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2) ++#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2) ++#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ ++#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ ++#define TARGET_TIOCGDEV _IOR('T',0x32, unsigned int) /* Get real dev no below /dev/console */ ++ ++#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ ++#define TARGET_FIOCLEX 0x5451 ++#define TARGET_FIOASYNC 0x5452 ++#define TARGET_TIOCSERCONFIG 0x5453 ++#define TARGET_TIOCSERGWILD 0x5454 ++#define TARGET_TIOCSERSWILD 0x5455 ++#define TARGET_TIOCGLCKTRMIOS 0x5456 ++#define TARGET_TIOCSLCKTRMIOS 0x5457 ++#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ ++#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ ++#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ ++#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ ++ ++#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ ++#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ ++#define TARGET_FIOQSIZE 0x545E ++ ++/* Used for packet mode */ ++#define TARGET_TIOCPKT_DATA 0 ++#define TARGET_TIOCPKT_FLUSHREAD 1 ++#define TARGET_TIOCPKT_FLUSHWRITE 2 ++#define TARGET_TIOCPKT_STOP 4 ++#define TARGET_TIOCPKT_START 8 ++#define TARGET_TIOCPKT_NOSTOP 16 ++#define TARGET_TIOCPKT_DOSTOP 32 ++ ++#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ ++ +diff --git a/linux-user/signal.c b/linux-user/signal.c +index b01bd64..8b02b32 100644 +--- a/linux-user/signal.c ++++ b/linux-user/signal.c +@@ -3614,6 +3614,320 @@ long do_rt_sigreturn(CPUState *env) + return -TARGET_ENOSYS; + } + ++#elif defined(TARGET_S390X) ++ ++#define __NUM_GPRS 16 ++#define __NUM_FPRS 16 ++#define __NUM_ACRS 16 ++ ++#define S390_SYSCALL_SIZE 2 ++#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */ ++ ++#define _SIGCONTEXT_NSIG 64 ++#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ ++#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) ++#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) ++#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */ ++#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) ++ ++typedef struct ++{ ++ target_psw_t psw; ++ target_ulong gprs[__NUM_GPRS]; ++ unsigned int acrs[__NUM_ACRS]; ++} target_s390_regs_common; ++ ++typedef struct ++{ ++ unsigned int fpc; ++ double fprs[__NUM_FPRS]; ++} target_s390_fp_regs; ++ ++typedef struct ++{ ++ target_s390_regs_common regs; ++ target_s390_fp_regs fpregs; ++} target_sigregs; ++ ++struct target_sigcontext ++{ ++ target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; ++ target_sigregs *sregs; ++}; ++ ++typedef struct ++{ ++ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; ++ struct target_sigcontext sc; ++ target_sigregs sregs; ++ int signo; ++ uint8_t retcode[S390_SYSCALL_SIZE]; ++} sigframe; ++ ++struct target_ucontext { ++ target_ulong uc_flags; ++ struct target_ucontext *uc_link; ++ target_stack_t uc_stack; ++ target_sigregs uc_mcontext; ++ target_sigset_t uc_sigmask; /* mask last for extensibility */ ++}; ++ ++typedef struct ++{ ++ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; ++ uint8_t retcode[S390_SYSCALL_SIZE]; ++ struct target_siginfo info; ++ struct target_ucontext uc; ++} rt_sigframe; ++ ++static inline abi_ulong ++get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size) ++{ ++ abi_ulong sp; ++ ++ /* Default to using normal stack */ ++ sp = env->regs[15]; ++ ++ /* This is the X/Open sanctioned signal stack switching. */ ++ if (ka->sa_flags & TARGET_SA_ONSTACK) { ++ if (! sas_ss_flags(sp)) ++ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; ++ } ++ ++ /* This is the legacy signal stack switching. */ ++ else if (/* FIXME !user_mode(regs) */ 0 && ++ !(ka->sa_flags & TARGET_SA_RESTORER) && ++ ka->sa_restorer) { ++ sp = (abi_ulong) ka->sa_restorer; ++ } ++ ++ return (sp - frame_size) & -8ul; ++} ++ ++static void save_sigregs(CPUState *env, target_sigregs *sregs) ++{ ++ int i; ++ //save_access_regs(current->thread.acrs); FIXME ++ ++ /* Copy a 'clean' PSW mask to the user to avoid leaking ++ information about whether PER is currently on. */ ++ __put_user(env->psw.mask, &sregs->regs.psw.mask); ++ __put_user(env->psw.addr, &sregs->regs.psw.addr); ++ for (i = 0; i < 16; i++) ++ __put_user(env->regs[i], &sregs->regs.gprs[i]); ++ for (i = 0; i < 16; i++) ++ __put_user(env->aregs[i], &sregs->regs.acrs[i]); ++ /* ++ * We have to store the fp registers to current->thread.fp_regs ++ * to merge them with the emulated registers. ++ */ ++ //save_fp_regs(¤t->thread.fp_regs); FIXME ++ for (i = 0; i < 16; i++) ++ __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]); ++} ++ ++static void setup_frame(int sig, struct target_sigaction *ka, ++ target_sigset_t *set, CPUState *env) ++{ ++ sigframe *frame; ++ abi_ulong frame_addr; ++ ++ frame_addr = get_sigframe(ka, env, sizeof *frame); ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) ++ goto give_sigsegv; ++ ++ qemu_log("%s: 1\n", __FUNCTION__); ++ if (__put_user(set->sig[0], &frame->sc.oldmask[0])) ++ goto give_sigsegv; ++ ++ save_sigregs(env, &frame->sregs); ++ ++ __put_user((abi_ulong)&frame->sregs, (abi_ulong *)&frame->sc.sregs); ++ ++ /* Set up to return from userspace. If provided, use a stub ++ already in userspace. */ ++ if (ka->sa_flags & TARGET_SA_RESTORER) { ++ env->regs[14] = (unsigned long) ++ ka->sa_restorer | PSW_ADDR_AMODE; ++ } else { ++ env->regs[14] = (unsigned long) ++ frame->retcode | PSW_ADDR_AMODE; ++ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, ++ (uint16_t *)(frame->retcode))) ++ goto give_sigsegv; ++ } ++ ++ /* Set up backchain. */ ++ if (__put_user(env->regs[15], (abi_ulong *) frame)) ++ goto give_sigsegv; ++ ++ /* Set up registers for signal handler */ ++ env->regs[15] = (target_ulong) frame; ++ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; ++ ++ env->regs[2] = sig; //map_signal(sig); ++ env->regs[3] = (target_ulong) &frame->sc; ++ ++ /* We forgot to include these in the sigcontext. ++ To avoid breaking binary compatibility, they are passed as args. */ ++ env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; ++ env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; ++ ++ /* Place signal number on stack to allow backtrace from handler. */ ++ if (__put_user(env->regs[2], (int *) &frame->signo)) ++ goto give_sigsegv; ++ unlock_user_struct(frame, frame_addr, 1); ++ return; ++ ++give_sigsegv: ++ qemu_log("%s: give_sigsegv\n", __FUNCTION__); ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sig(TARGET_SIGSEGV); ++} ++ ++static void setup_rt_frame(int sig, struct target_sigaction *ka, ++ target_siginfo_t *info, ++ target_sigset_t *set, CPUState *env) ++{ ++ int i; ++ rt_sigframe *frame; ++ abi_ulong frame_addr; ++ ++ frame_addr = get_sigframe(ka, env, sizeof *frame); ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) ++ goto give_sigsegv; ++ ++ qemu_log("%s: 1\n", __FUNCTION__); ++ if (copy_siginfo_to_user(&frame->info, info)) ++ goto give_sigsegv; ++ ++ /* Create the ucontext. */ ++ __put_user(0, &frame->uc.uc_flags); ++ __put_user((abi_ulong)NULL, (abi_ulong*)&frame->uc.uc_link); ++ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp); ++ __put_user(sas_ss_flags(get_sp_from_cpustate(env)), ++ &frame->uc.uc_stack.ss_flags); ++ __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size); ++ save_sigregs(env, &frame->uc.uc_mcontext); ++ for(i = 0; i < TARGET_NSIG_WORDS; i++) { ++ __put_user((abi_ulong)set->sig[i], (abi_ulong*)&frame->uc.uc_sigmask.sig[i]); ++ } ++ ++ /* Set up to return from userspace. If provided, use a stub ++ already in userspace. */ ++ if (ka->sa_flags & TARGET_SA_RESTORER) { ++ env->regs[14] = (unsigned long) ++ ka->sa_restorer | PSW_ADDR_AMODE; ++ } else { ++ env->regs[14] = (unsigned long) ++ frame->retcode | PSW_ADDR_AMODE; ++ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, ++ (uint16_t *)(frame->retcode))) ++ goto give_sigsegv; ++ } ++ ++ /* Set up backchain. */ ++ if (__put_user(env->regs[15], (abi_ulong *) frame)) ++ goto give_sigsegv; ++ ++ /* Set up registers for signal handler */ ++ env->regs[15] = (target_ulong) frame; ++ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; ++ ++ env->regs[2] = sig; //map_signal(sig); ++ env->regs[3] = (target_ulong) &frame->info; ++ env->regs[4] = (target_ulong) &frame->uc; ++ return; ++ ++give_sigsegv: ++ qemu_log("%s: give_sigsegv\n", __FUNCTION__); ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sig(TARGET_SIGSEGV); ++} ++ ++static int ++restore_sigregs(CPUState *env, target_sigregs *sc) ++{ ++ int err = 0; ++ int i; ++ ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->regs[i], &sc->regs.gprs[i]); ++ } ++ ++ err |= __get_user(env->psw.mask, &sc->regs.psw.mask); ++ qemu_log("%s: sc->regs.psw.addr 0x%lx env->psw.addr 0x%lx\n", __FUNCTION__, sc->regs.psw.addr, env->psw.addr); ++ err |= __get_user(env->psw.addr, &sc->regs.psw.addr); ++ /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ ++ ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->aregs[i], &sc->regs.acrs[i]); ++ } ++ for (i = 0; i < 16; i++) { ++ err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]); ++ } ++ ++ return err; ++} ++ ++long do_sigreturn(CPUState *env) ++{ ++ sigframe *frame; ++ abi_ulong frame_addr = env->regs[15]; ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ target_sigset_t target_set; ++ sigset_t set; ++ ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) ++ goto badframe; ++ if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) ++ goto badframe; ++ ++ target_to_host_sigset_internal(&set, &target_set); ++ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ ++ ++ if (restore_sigregs(env, &frame->sregs)) ++ goto badframe; ++ ++ unlock_user_struct(frame, frame_addr, 0); ++ return env->regs[2]; ++ ++badframe: ++ unlock_user_struct(frame, frame_addr, 0); ++ force_sig(TARGET_SIGSEGV); ++ return 0; ++} ++ ++long do_rt_sigreturn(CPUState *env) ++{ ++ rt_sigframe *frame; ++ abi_ulong frame_addr = env->regs[15]; ++ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); ++ sigset_t set; ++ ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) ++ goto badframe; ++ target_to_host_sigset(&set, &frame->uc.uc_sigmask); ++ ++ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ ++ ++ if (restore_sigregs(env, &frame->uc.uc_mcontext)) ++ goto badframe; ++ ++ if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0, ++ get_sp_from_cpustate(env)) == -EFAULT) ++ goto badframe; ++ unlock_user_struct(frame, frame_addr, 0); ++ return env->regs[2]; ++ ++badframe: ++ unlock_user_struct(frame, frame_addr, 0); ++ force_sig(TARGET_SIGSEGV); ++ return 0; ++} ++ + #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) + + /* FIXME: Many of the structures are defined for both PPC and PPC64, but +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 1a98433..fe8fb1e 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -194,7 +194,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ + #define __NR_sys_inotify_add_watch __NR_inotify_add_watch + #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch + +-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) ++#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || defined(__s390x__) + #define __NR__llseek __NR_lseek + #endif + +@@ -321,7 +321,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode) + return (fchmodat(dirfd, pathname, mode, 0)); + } + #endif +-#if defined(TARGET_NR_fchownat) && defined(USE_UID16) ++#if defined(TARGET_NR_fchownat) + static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, + gid_t group, int flags) + { +@@ -430,7 +430,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode) + #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) + _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) + #endif +-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16) ++#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) + _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, + uid_t,owner,gid_t,group,int,flags) + #endif +@@ -3774,6 +3774,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, + #endif + ts = qemu_mallocz(sizeof(TaskState)); + init_task_state(ts); ++ env->multithreaded = 1; + /* we create a new CPU instance. */ + new_env = cpu_copy(env); + #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) +@@ -5443,7 +5444,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + ret = get_errno(settimeofday(&tv, NULL)); + } + break; +-#ifdef TARGET_NR_select ++#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390) + case TARGET_NR_select: + { + struct target_sel_arg_struct *sel; +@@ -5554,7 +5555,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + #endif + #ifdef TARGET_NR_mmap + case TARGET_NR_mmap: +-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) ++#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \ ++ defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \ ++ || defined(TARGET_S390X) + { + abi_ulong *v; + abi_ulong v1, v2, v3, v4, v5, v6; +@@ -6050,6 +6053,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); + #elif defined(TARGET_CRIS) + ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5)); ++#elif defined(TARGET_S390X) ++ ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); + #else + ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); + #endif +@@ -6254,8 +6259,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + break; + #endif /* TARGET_NR_getdents64 */ +-#ifdef TARGET_NR__newselect ++#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) ++#ifdef TARGET_S390X ++ case TARGET_NR_select: ++#else + case TARGET_NR__newselect: ++#endif + ret = do_select(arg1, arg2, arg3, arg4, arg5); + break; + #endif +@@ -6480,7 +6489,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + case TARGET_NR_sigaltstack: + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \ + defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \ +- defined(TARGET_M68K) ++ defined(TARGET_M68K) || defined(TARGET_S390X) + ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env)); + break; + #else +@@ -6713,18 +6722,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + case TARGET_NR_setfsgid: + ret = get_errno(setfsgid(arg1)); + break; ++#else /* USE_UID16 */ ++#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) ++ case TARGET_NR_fchownat: ++ if (!(p = lock_user_string(arg2))) ++ goto efault; ++ ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5)); ++ unlock_user(p, arg2, 0); ++ break; ++#endif + #endif /* USE_UID16 */ + +-#ifdef TARGET_NR_lchown32 ++#if defined(TARGET_NR_lchown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_lchown32) + case TARGET_NR_lchown32: ++#else ++ case TARGET_NR_lchown: ++#endif + if (!(p = lock_user_string(arg1))) + goto efault; + ret = get_errno(lchown(p, arg2, arg3)); + unlock_user(p, arg1, 0); + break; + #endif +-#ifdef TARGET_NR_getuid32 ++#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getuid32) + case TARGET_NR_getuid32: ++#else ++ case TARGET_NR_getuid: ++#endif + ret = get_errno(getuid()); + break; + #endif +@@ -6869,33 +6895,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + break; + #endif + +-#ifdef TARGET_NR_getgid32 ++#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getgid32) + case TARGET_NR_getgid32: ++#else ++ case TARGET_NR_getgid: ++#endif + ret = get_errno(getgid()); + break; + #endif +-#ifdef TARGET_NR_geteuid32 ++#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_geteuid32) + case TARGET_NR_geteuid32: ++#else ++ case TARGET_NR_geteuid: ++#endif + ret = get_errno(geteuid()); + break; + #endif +-#ifdef TARGET_NR_getegid32 ++#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && !defined(USE_UID16)) ++#if defined(TARGET_NR_getegid32) + case TARGET_NR_getegid32: ++#else ++ case TARGET_NR_getegid: ++#endif + ret = get_errno(getegid()); + break; + #endif +-#ifdef TARGET_NR_setreuid32 ++#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setreuid32) + case TARGET_NR_setreuid32: ++#else ++ case TARGET_NR_setreuid: ++#endif + ret = get_errno(setreuid(arg1, arg2)); + break; + #endif +-#ifdef TARGET_NR_setregid32 ++#if defined(TARGET_NR_setregid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setregid32) + case TARGET_NR_setregid32: ++#else ++ case TARGET_NR_setregid: ++#endif + ret = get_errno(setregid(arg1, arg2)); + break; + #endif +-#ifdef TARGET_NR_getgroups32 ++#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16) ++#if defined(TARGET_NR_getgroups32) + case TARGET_NR_getgroups32: ++#else ++ case TARGET_NR_getgroups: ++#endif + { + int gidsetsize = arg1; + uint32_t *target_grouplist; +@@ -6919,8 +6969,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + break; + #endif +-#ifdef TARGET_NR_setgroups32 ++#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setgroups32) + case TARGET_NR_setgroups32: ++#else ++ case TARGET_NR_setgroups: ++#endif + { + int gidsetsize = arg1; + uint32_t *target_grouplist; +@@ -6940,18 +6994,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + break; + #endif +-#ifdef TARGET_NR_fchown32 ++#if defined(TARGET_NR_fchown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_fchown32) + case TARGET_NR_fchown32: ++#else ++ case TARGET_NR_fchown: ++#endif + ret = get_errno(fchown(arg1, arg2, arg3)); + break; + #endif +-#ifdef TARGET_NR_setresuid32 ++#if defined(TARGET_NR_setresuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setresuid32) + case TARGET_NR_setresuid32: ++#else ++ case TARGET_NR_setresuid: ++#endif + ret = get_errno(setresuid(arg1, arg2, arg3)); + break; + #endif +-#ifdef TARGET_NR_getresuid32 ++#if defined(TARGET_NR_getresuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_getresuid32) + case TARGET_NR_getresuid32: ++#else ++ case TARGET_NR_getresuid: ++#endif + { + uid_t ruid, euid, suid; + ret = get_errno(getresuid(&ruid, &euid, &suid)); +@@ -6964,13 +7030,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + break; + #endif +-#ifdef TARGET_NR_setresgid32 ++#if defined(TARGET_NR_setresgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setresgid32) + case TARGET_NR_setresgid32: ++#else ++ case TARGET_NR_setresgid: ++#endif + ret = get_errno(setresgid(arg1, arg2, arg3)); + break; + #endif ++#if defined(TARGET_NR_getresgid32) || !defined(USE_UID16) + #ifdef TARGET_NR_getresgid32 + case TARGET_NR_getresgid32: ++#else ++ case TARGET_NR_getresgid: ++#endif + { + gid_t rgid, egid, sgid; + ret = get_errno(getresgid(&rgid, &egid, &sgid)); +@@ -6983,31 +7057,51 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + break; + #endif +-#ifdef TARGET_NR_chown32 ++#if defined(TARGET_NR_chown32) || !defined(USE_UID16) ++#if defined(TARGET_NR_chown32) + case TARGET_NR_chown32: ++#else ++ case TARGET_NR_chown: ++#endif + if (!(p = lock_user_string(arg1))) + goto efault; + ret = get_errno(chown(p, arg2, arg3)); + unlock_user(p, arg1, 0); + break; + #endif +-#ifdef TARGET_NR_setuid32 ++#if defined(TARGET_NR_setuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setuid32) + case TARGET_NR_setuid32: ++#else ++ case TARGET_NR_setuid: ++#endif + ret = get_errno(setuid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setgid32 ++#if defined(TARGET_NR_setgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setgid32) + case TARGET_NR_setgid32: ++#else ++ case TARGET_NR_setgid: ++#endif + ret = get_errno(setgid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setfsuid32 ++#if defined(TARGET_NR_setfsuid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setfsuid32) + case TARGET_NR_setfsuid32: ++#else ++ case TARGET_NR_setfsuid: ++#endif + ret = get_errno(setfsuid(arg1)); + break; + #endif +-#ifdef TARGET_NR_setfsgid32 ++#if defined(TARGET_NR_setfsgid32) || !defined(USE_UID16) ++#if defined(TARGET_NR_setfsgid32) + case TARGET_NR_setfsgid32: ++#else ++ case TARGET_NR_setfsgid: ++#endif + ret = get_errno(setfsgid(arg1)); + break; + #endif +diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h +index be612ce..c17bfc9 100644 +--- a/linux-user/syscall_defs.h ++++ b/linux-user/syscall_defs.h +@@ -55,7 +55,7 @@ + #endif + + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ +- || defined(TARGET_M68K) || defined(TARGET_CRIS) ++ || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_S390X) + + #define TARGET_IOC_SIZEBITS 14 + #define TARGET_IOC_DIRBITS 2 +@@ -315,7 +315,10 @@ struct target_sigaction; + int do_sigaction(int sig, const struct target_sigaction *act, + struct target_sigaction *oact); + +-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) ++#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || \ ++ defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || \ ++ defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ ++ defined(TARGET_MICROBLAZE) || defined(TARGET_S390X) + + #if defined(TARGET_SPARC) + #define TARGET_SA_NOCLDSTOP 8u +@@ -1677,6 +1680,27 @@ struct target_stat { + + abi_long __unused[3]; + }; ++#elif defined(TARGET_S390X) ++struct target_stat { ++ abi_ulong st_dev; ++ abi_ulong st_ino; ++ abi_ulong st_nlink; ++ unsigned int st_mode; ++ unsigned int st_uid; ++ unsigned int st_gid; ++ unsigned int __pad1; ++ abi_ulong st_rdev; ++ abi_ulong st_size; ++ abi_ulong target_st_atime; ++ abi_ulong target_st_atime_nsec; ++ abi_ulong target_st_mtime; ++ abi_ulong target_st_mtime_nsec; ++ abi_ulong target_st_ctime; ++ abi_ulong target_st_ctime_nsec; ++ abi_ulong st_blksize; ++ abi_long st_blocks; ++ abi_ulong __unused[3]; ++}; + #else + #error unsupported CPU + #endif +@@ -1763,6 +1787,34 @@ struct target_statfs64 { + abi_long f_frsize; + abi_long f_spare[5]; + }; ++#elif defined(TARGET_S390X) ++struct target_statfs { ++ int32_t f_type; ++ int32_t f_bsize; ++ abi_long f_blocks; ++ abi_long f_bfree; ++ abi_long f_bavail; ++ abi_long f_files; ++ abi_long f_ffree; ++ kernel_fsid_t f_fsid; ++ int32_t f_namelen; ++ int32_t f_frsize; ++ int32_t f_spare[5]; ++}; ++ ++struct target_statfs64 { ++ int32_t f_type; ++ int32_t f_bsize; ++ abi_long f_blocks; ++ abi_long f_bfree; ++ abi_long f_bavail; ++ abi_long f_files; ++ abi_long f_ffree; ++ kernel_fsid_t f_fsid; ++ int32_t f_namelen; ++ int32_t f_frsize; ++ int32_t f_spare[5]; ++}; + #else + struct target_statfs { + uint32_t f_type; +diff --git a/s390x.ld b/s390x.ld +new file mode 100644 +index 0000000..7d1f2b7 +--- /dev/null ++++ b/s390x.ld +@@ -0,0 +1,194 @@ ++/* Default linker script, for normal executables */ ++OUTPUT_FORMAT("elf64-s390", "elf64-s390", ++ "elf64-s390") ++OUTPUT_ARCH(s390:64-bit) ++ENTRY(_start) ++SEARCH_DIR("/usr/s390x-suse-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/s390x-suse-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; ++ .interp : { *(.interp) } ++ .note.gnu.build-id : { *(.note.gnu.build-id) } ++ .hash : { *(.hash) } ++ .gnu.hash : { *(.gnu.hash) } ++ .dynsym : { *(.dynsym) } ++ .dynstr : { *(.dynstr) } ++ .gnu.version : { *(.gnu.version) } ++ .gnu.version_d : { *(.gnu.version_d) } ++ .gnu.version_r : { *(.gnu.version_r) } ++ .rel.init : { *(.rel.init) } ++ .rela.init : { *(.rela.init) } ++ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } ++ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } ++ .rel.fini : { *(.rel.fini) } ++ .rela.fini : { *(.rela.fini) } ++ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } ++ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } ++ .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } ++ .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } ++ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } ++ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } ++ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } ++ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } ++ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } ++ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } ++ .rel.ctors : { *(.rel.ctors) } ++ .rela.ctors : { *(.rela.ctors) } ++ .rel.dtors : { *(.rel.dtors) } ++ .rela.dtors : { *(.rela.dtors) } ++ .rel.got : { *(.rel.got) } ++ .rela.got : { *(.rela.got) } ++ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } ++ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } ++ .rel.plt : { *(.rel.plt) } ++ .rela.plt : { *(.rela.plt) } ++ .init : ++ { ++ KEEP (*(.init)) ++ } =0x07070707 ++ .plt : { *(.plt) } ++ .text : ++ { ++ *(.text .stub .text.* .gnu.linkonce.t.*) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0x07070707 ++ .fini : ++ { ++ KEEP (*(.fini)) ++ } =0x07070707 ++ PROVIDE (__etext = .); ++ PROVIDE (_etext = .); ++ PROVIDE (etext = .); ++ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } ++ .rodata1 : { *(.rodata1) } ++ .eh_frame_hdr : { *(.eh_frame_hdr) } ++ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } ++ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. */ ++ . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); ++ /* Exception handling */ ++ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } ++ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } ++ /* Thread Local Storage sections */ ++ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } ++ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } ++ .preinit_array : ++ { ++ PROVIDE_HIDDEN (__preinit_array_start = .); ++ KEEP (*(.preinit_array)) ++ PROVIDE_HIDDEN (__preinit_array_end = .); ++ } ++ .init_array : ++ { ++ PROVIDE_HIDDEN (__init_array_start = .); ++ KEEP (*(SORT(.init_array.*))) ++ KEEP (*(.init_array)) ++ PROVIDE_HIDDEN (__init_array_end = .); ++ } ++ .fini_array : ++ { ++ PROVIDE_HIDDEN (__fini_array_start = .); ++ KEEP (*(.fini_array)) ++ KEEP (*(SORT(.fini_array.*))) ++ PROVIDE_HIDDEN (__fini_array_end = .); ++ } ++ .ctors : ++ { ++ /* gcc uses crtbegin.o to find the start of ++ the constructors, so we make sure it is ++ first. Because this is a wildcard, it ++ doesn't matter if the user does not ++ actually link against crtbegin.o; the ++ linker won't look for a file to match a ++ wildcard. The wildcard also means that it ++ doesn't matter which directory crtbegin.o ++ is in. */ ++ KEEP (*crtbegin.o(.ctors)) ++ KEEP (*crtbegin?.o(.ctors)) ++ /* We don't want to include the .ctor section from ++ the crtend.o file until after the sorted ctors. ++ The .ctor section from the crtend file contains the ++ end of ctors marker and it must be last */ ++ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) ++ KEEP (*(SORT(.ctors.*))) ++ KEEP (*(.ctors)) ++ } ++ .dtors : ++ { ++ KEEP (*crtbegin.o(.dtors)) ++ KEEP (*crtbegin?.o(.dtors)) ++ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) ++ KEEP (*(SORT(.dtors.*))) ++ KEEP (*(.dtors)) ++ } ++ .jcr : { KEEP (*(.jcr)) } ++ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } ++ .dynamic : { *(.dynamic) } ++ . = DATA_SEGMENT_RELRO_END (0, .); ++ .got : { *(.got.plt) *(.got) } ++ .data : ++ { ++ *(.data .data.* .gnu.linkonce.d.*) ++ SORT(CONSTRUCTORS) ++ } ++ .data1 : { *(.data1) } ++ _edata = .; PROVIDE (edata = .); ++ __bss_start = .; ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss .bss.* .gnu.linkonce.b.*) ++ *(COMMON) ++ /* Align here to ensure that the .bss section occupies space up to ++ _end. Align after .bss to ensure correct alignment even if the ++ .bss section disappears because there are no input sections. ++ FIXME: Why do we need it? When there is no .bss section, we don't ++ pad the .data section. */ ++ . = ALIGN(. != 0 ? 64 / 8 : 1); ++ } ++ . = ALIGN(64 / 8); ++ . = ALIGN(64 / 8); ++ _end = .; PROVIDE (end = .); ++ . = DATA_SEGMENT_END (.); ++ /* Stabs debugging sections. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ .stab.excl 0 : { *(.stab.excl) } ++ .stab.exclstr 0 : { *(.stab.exclstr) } ++ .stab.index 0 : { *(.stab.index) } ++ .stab.indexstr 0 : { *(.stab.indexstr) } ++ .comment 0 : { *(.comment) } ++ /* DWARF debug sections. ++ Symbols in the DWARF debugging sections are relative to the beginning ++ of the section so we begin them at 0. */ ++ /* DWARF 1 */ ++ .debug 0 : { *(.debug) } ++ .line 0 : { *(.line) } ++ /* GNU DWARF 1 extensions */ ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ /* DWARF 1.1 and DWARF 2 */ ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ /* DWARF 2 */ ++ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } ++ .debug_abbrev 0 : { *(.debug_abbrev) } ++ .debug_line 0 : { *(.debug_line) } ++ .debug_frame 0 : { *(.debug_frame) } ++ .debug_str 0 : { *(.debug_str) } ++ .debug_loc 0 : { *(.debug_loc) } ++ .debug_macinfo 0 : { *(.debug_macinfo) } ++ /* SGI/MIPS DWARF 2 extensions */ ++ .debug_weaknames 0 : { *(.debug_weaknames) } ++ .debug_funcnames 0 : { *(.debug_funcnames) } ++ .debug_typenames 0 : { *(.debug_typenames) } ++ .debug_varnames 0 : { *(.debug_varnames) } ++ /* DWARF 3 */ ++ .debug_pubtypes 0 : { *(.debug_pubtypes) } ++ .debug_ranges 0 : { *(.debug_ranges) } ++ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } ++ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) } ++} +diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh +index 335ab05..7aa4a4a 100644 +--- a/scripts/qemu-binfmt-conf.sh ++++ b/scripts/qemu-binfmt-conf.sh +@@ -1,5 +1,5 @@ + #!/bin/sh +-# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC program execution by the kernel ++# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel + + # load the binfmt_misc module + if [ ! -d /proc/sys/fs/binfmt_misc ]; then +@@ -67,3 +67,6 @@ if [ $cpu != "sh" ] ; then + echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register + echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register + fi ++if [ $cpu != "s390x" ] ; then ++ echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register ++fi +diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h +index e47c372..49a919e 100644 +--- a/target-s390x/cpu.h ++++ b/target-s390x/cpu.h +@@ -26,6 +26,14 @@ + #define CPUState struct CPUS390XState + + #include "cpu-defs.h" ++#define TARGET_PAGE_BITS 12 ++ ++/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM ++ emulation actually works, this is good enough for a placeholder. */ ++#define TARGET_PHYS_ADDR_SPACE_BITS 64 ++#define TARGET_VIRT_ADDR_SPACE_BITS 64 ++ ++#include "cpu-all.h" + + #include "softfloat.h" + +@@ -51,7 +59,7 @@ typedef struct CPUS390XState { + uint32_t aregs[16]; /* access registers */ + + uint32_t fpc; /* floating-point control register */ +- FPReg fregs[16]; /* FP registers */ ++ CPU_DoubleU fregs[16]; /* FP registers */ + float_status fpu_status; /* passed to softfloat lib */ + + struct { +@@ -85,8 +93,10 @@ static inline int cpu_mmu_index (CPUState *env) + } + + CPUS390XState *cpu_s390x_init(const char *cpu_model); +void s390x_translate_init(void); -+int cpu_s390x_exec(CPUS390XState *s); -+void cpu_s390x_close(CPUS390XState *s); + int cpu_s390x_exec(CPUS390XState *s); + void cpu_s390x_close(CPUS390XState *s); +void do_interrupt (CPUState *env); -+ -+/* you can call this signal handler from your SIGBUS and SIGSEGV -+ signal handlers to inform the virtual CPU of exceptions. non zero -+ is returned if the signal was handled by the virtual CPU. */ -+int cpu_s390x_signal_handler(int host_signum, void *pinfo, -+ void *puc); -+int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, -+ int mmu_idx, int is_softmuu); -+ + + /* you can call this signal handler from your SIGBUS and SIGSEGV + signal handlers to inform the virtual CPU of exceptions. non zero +@@ -97,29 +107,32 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw + int mmu_idx, int is_softmuu); + #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault + +-#define TARGET_PAGE_BITS 12 +- +-/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM +- emulation actually works, this is good enough for a placeholder. */ +-#define TARGET_PHYS_ADDR_SPACE_BITS 32 +-#define TARGET_VIRT_ADDR_SPACE_BITS 32 + + #ifndef CONFIG_USER_ONLY + int s390_virtio_hypercall(CPUState *env); + void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token); + CPUState *s390_cpu_addr2state(uint16_t cpu_addr); + #endif +void cpu_lock(void); +void cpu_unlock(void); -+ + +static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) +{ + env->aregs[0] = newtls >> 32; + env->aregs[1] = newtls & 0xffffffffULL; +} -+ -+#define TARGET_PAGE_BITS 12 // guess -+ -+#define cpu_init cpu_s390x_init -+#define cpu_exec cpu_s390x_exec -+#define cpu_gen_code cpu_s390x_gen_code + + #define cpu_init cpu_s390x_init + #define cpu_exec cpu_s390x_exec + #define cpu_gen_code cpu_s390x_gen_code +#define cpu_signal_handler cpu_s390x_signal_handler -+//#define cpu_list s390x_cpu_list -+ -+#include "cpu-all.h" + +-#include "cpu-all.h" +#include "exec-all.h" -+ -+#define EXCP_OPEX 1 /* operation exception (sigill) */ -+#define EXCP_SVC 2 /* supervisor call (syscall) */ -+#define EXCP_ADDR 5 /* addressing exception */ -+#define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */ -+ -+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb) -+{ -+ env->psw.addr = tb->pc; -+} -+ -+static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, -+ target_ulong *cs_base, int *flags) -+{ -+ *pc = env->psw.addr; -+ *cs_base = 0; -+ *flags = env->psw.mask; // guess -+} -+#endif + + #define EXCP_OPEX 1 /* operation exception (sigill) */ + #define EXCP_SVC 2 /* supervisor call (syscall) */ + #define EXCP_ADDR 5 /* addressing exception */ ++#define EXCP_SPEC 6 /* specification exception */ + #define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */ + + static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, diff --git a/target-s390x/exec.h b/target-s390x/exec.h -new file mode 100644 -index 0000000..5198359 ---- /dev/null +index bf3f264..6fe64a6 100644 +--- a/target-s390x/exec.h +++ b/target-s390x/exec.h -@@ -0,0 +1,51 @@ -+/* -+ * S/390 execution defines -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -+ */ -+ -+#include "dyngen-exec.h" -+ -+register struct CPUS390XState *env asm(AREG0); -+ -+#include "cpu.h" -+#include "exec-all.h" -+ -+static inline int cpu_has_work(CPUState *env) -+{ -+ return env->interrupt_request & CPU_INTERRUPT_HARD; // guess -+} -+ +@@ -34,6 +34,14 @@ static inline int cpu_has_work(CPUState *env) + return env->interrupt_request & CPU_INTERRUPT_HARD; // guess + } + +static inline void regs_to_env(void) +{ +} @@ -306,70 +2047,36 @@ index 0000000..5198359 +{ +} + -+static inline int cpu_halted(CPUState *env) -+{ -+ if (!env->halted) { -+ return 0; -+ } -+ if (cpu_has_work(env)) { -+ env->halted = 0; -+ return 0; -+ } -+ return EXCP_HALTED; -+} + static inline int cpu_halted(CPUState *env) + { + if (!env->halted) { diff --git a/target-s390x/helper.c b/target-s390x/helper.c -new file mode 100644 -index 0000000..5407c62 ---- /dev/null +index 4a5297b..6085e58 100644 +--- a/target-s390x/helper.c +++ b/target-s390x/helper.c -@@ -0,0 +1,81 @@ -+/* -+ * S/390 helpers -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+ -+#include "cpu.h" -+#include "exec-all.h" -+#include "gdbstub.h" -+#include "qemu-common.h" -+ -+CPUS390XState *cpu_s390x_init(const char *cpu_model) -+{ -+ CPUS390XState *env; -+ static int inited = 0; -+ -+ env = qemu_mallocz(sizeof(CPUS390XState)); -+ cpu_exec_init(env); -+ if (!inited) { -+ inited = 1; +@@ -26,8 +26,10 @@ + #include "gdbstub.h" + #include "qemu-common.h" + ++#if !defined(CONFIG_USER_ONLY) + #include + #include "kvm.h" ++#endif + + CPUS390XState *cpu_s390x_init(const char *cpu_model) + { +@@ -38,6 +40,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) + cpu_exec_init(env); + if (!inited) { + inited = 1; + s390x_translate_init(); -+ } -+ -+ env->cpu_model_str = cpu_model; -+ cpu_reset(env); -+ qemu_init_vcpu(env); -+ return env; -+} -+ + } + + env->cpu_model_str = cpu_model; +@@ -46,6 +49,24 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) + return env; + } + +#if defined(CONFIG_USER_ONLY) + +void do_interrupt (CPUState *env) @@ -380,36 +2087,39 @@ index 0000000..5407c62 +int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int mmu_idx, int is_softmmu) +{ -+ //fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d is_softmmu %d\n", __FUNCTION__, address, rw, mmu_idx, is_softmmu); ++ /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d is_softmmu %d\n", __FUNCTION__, address, rw, mmu_idx, is_softmmu); */ + env->exception_index = EXCP_ADDR; + env->__excp_addr = address; /* FIXME: find out how this works on a real machine */ + return 1; +} + -+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -+{ -+ return addr; -+} -+ +#endif /* CONFIG_USER_ONLY */ + -+void cpu_reset(CPUS390XState *env) -+{ -+ if (qemu_loglevel_mask(CPU_LOG_RESET)) { -+ qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); -+ log_cpu_state(env, 0); -+ } -+ -+ memset(env, 0, offsetof(CPUS390XState, breakpoints)); -+ /* FIXME: reset vector? */ -+ tlb_flush(env, 1); -+} + void cpu_reset(CPUS390XState *env) + { + if (qemu_loglevel_mask(CPU_LOG_RESET)) { +@@ -58,13 +79,13 @@ void cpu_reset(CPUS390XState *env) + tlb_flush(env, 1); + } + ++#ifndef CONFIG_USER_ONLY ++ + target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) + { + return 0; + } + +-#ifndef CONFIG_USER_ONLY +- + int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int mmu_idx, int is_softmmu) + { diff --git a/target-s390x/helpers.h b/target-s390x/helpers.h new file mode 100644 -index 0000000..0ba2086 +index 0000000..6009312 --- /dev/null +++ b/target-s390x/helpers.h -@@ -0,0 +1,128 @@ +@@ -0,0 +1,127 @@ +#include "def-helper.h" + +DEF_HELPER_1(exception, void, i32) @@ -427,7 +2137,6 @@ index 0000000..0ba2086 +DEF_HELPER_FLAGS_1(set_cc_nz_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32) +DEF_HELPER_FLAGS_1(set_cc_nz_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64) +DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32) -+DEF_HELPER_4(brc, void, i32, i32, i64, s32) +DEF_HELPER_3(brctg, void, i64, i64, s32) +DEF_HELPER_3(brct, void, i32, i64, s32) +DEF_HELPER_4(brcl, void, i32, i32, i64, s64) @@ -500,13 +2209,13 @@ index 0000000..0ba2086 +DEF_HELPER_2(lcebr, i32, i32, i32) +DEF_HELPER_2(lcdbr, i32, i32, i32) +DEF_HELPER_2(lcxbr, i32, i32, i32) -+DEF_HELPER_2(ceb, i32, i32, i64) -+DEF_HELPER_2(aeb, i32, i32, i64) -+DEF_HELPER_2(deb, void, i32, i64) -+DEF_HELPER_2(meeb, void, i32, i64) ++DEF_HELPER_2(ceb, i32, i32, i32) ++DEF_HELPER_2(aeb, i32, i32, i32) ++DEF_HELPER_2(deb, void, i32, i32) ++DEF_HELPER_2(meeb, void, i32, i32) +DEF_HELPER_2(cdb, i32, i32, i64) +DEF_HELPER_2(adb, i32, i32, i64) -+DEF_HELPER_2(seb, i32, i32, i64) ++DEF_HELPER_2(seb, i32, i32, i32) +DEF_HELPER_2(sdb, i32, i32, i64) +DEF_HELPER_2(mdb, void, i32, i64) +DEF_HELPER_2(ddb, void, i32, i64) @@ -539,36 +2248,31 @@ index 0000000..0ba2086 + +#include "def-helper.h" diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c -new file mode 100644 -index 0000000..5de4d08 ---- /dev/null +index 402df2d..20c83c5 100644 +--- a/target-s390x/op_helper.c +++ b/target-s390x/op_helper.c -@@ -0,0 +1,1719 @@ -+/* -+ * S/390 helper routines -+ * +@@ -1,6 +1,7 @@ + /* + * S/390 helper routines + * + * Copyright (c) 2009 Ulrich Hecht -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -+ */ -+ -+#include "exec.h" + * Copyright (c) 2009 Alexander Graf + * + * This library is free software; you can redistribute it and/or +@@ -18,6 +19,8 @@ + */ + + #include "exec.h" +#include "helpers.h" +#include -+ -+//#define DEBUG_HELPER + + /*****************************************************************************/ + /* Softmmu support */ +@@ -71,3 +74,1607 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) + } + + #endif ++/* #define DEBUG_HELPER */ +#ifdef DEBUG_HELPER +#define HELPER_LOG(x...) qemu_log(x) +#else @@ -662,8 +2366,7 @@ index 0000000..5de4d08 + if (x < y) { + cc = 1; + goto done; -+ } -+ else if (x > y) { ++ } else if (x > y) { + cc = 2; + goto done; + } @@ -765,17 +2468,6 @@ index 0000000..5de4d08 + return cc; +} + -+/* relative conditional branch */ -+void HELPER(brc)(uint32_t cc, uint32_t mask, uint64_t pc, int32_t offset) -+{ -+ if ( mask & ( 1 << (3 - cc) ) ) { -+ env->psw.addr = pc + offset; -+ } -+ else { -+ env->psw.addr = pc + 4; -+ } -+} -+ +/* branch relative on 64-bit count (condition is computed inline, this only + does the branch */ +void HELPER(brctg)(uint64_t flag, uint64_t pc, int32_t offset) @@ -924,15 +2616,20 @@ index 0000000..5de4d08 +/* 64/64 -> 128 unsigned multiplication */ +void HELPER(mlg)(uint32_t r1, uint64_t v2) +{ ++#if TARGET_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ + __uint128_t res = (__uint128_t)env->regs[r1 + 1]; + res *= (__uint128_t)v2; + env->regs[r1] = (uint64_t)(res >> 64); + env->regs[r1 + 1] = (uint64_t)res; ++#else ++ mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2); ++#endif +} + +/* 128 -> 64/64 unsigned division */ +void HELPER(dlg)(uint32_t r1, uint64_t v2) +{ ++#if TARGET_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ + __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) | + (env->regs[r1+1]); + uint64_t divisor = v2; @@ -941,8 +2638,11 @@ index 0000000..5de4d08 + __uint128_t remainder = dividend % divisor; + env->regs[r1] = remainder; + HELPER_LOG("%s: dividend 0x%016lx%016lx divisor 0x%lx quotient 0x%lx rem 0x%lx\n", -+ __FUNCTION__, (uint64_t)(dividend >> 64), (uint64_t)dividend, divisor, (uint64_t)quotient, -+ (uint64_t)remainder); ++ __FUNCTION__, (uint64_t)(dividend >> 64), (uint64_t)dividend, ++ divisor, (uint64_t)quotient, (uint64_t)remainder); ++#else ++ cpu_abort(env, "128 -> 64/64 division not implemented on this system\n"); ++#endif +} + +/* set condition code for 64-bit signed addition */ @@ -950,8 +2650,7 @@ index 0000000..5de4d08 +{ + if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { + return 3; /* overflow */ -+ } -+ else { ++ } else { + if (ar < 0) return 1; + else if (ar > 0) return 2; + else return 0; @@ -964,12 +2663,10 @@ index 0000000..5de4d08 + if (ar == 0) { + if (a1) return 2; + else return 0; -+ } -+ else { ++ } else { + if (ar < a1 || ar < a2) { + return 3; -+ } -+ else { ++ } else { + return 1; + } + } @@ -980,8 +2677,7 @@ index 0000000..5de4d08 +{ + if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { + return 3; /* overflow */ -+ } -+ else { ++ } else { + if (ar < 0) return 1; + else if (ar > 0) return 2; + else return 0; @@ -994,12 +2690,10 @@ index 0000000..5de4d08 + if (ar == 0) { + if (a1) return 2; + else return 0; -+ } -+ else { ++ } else { + if (ar < a1 || ar < a2) { + return 3; -+ } -+ else { ++ } else { + return 1; + } + } @@ -1010,8 +2704,7 @@ index 0000000..5de4d08 +{ + if ((s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) { + return 3; /* overflow */ -+ } -+ else { ++ } else { + if (sr < 0) return 1; + else if (sr > 0) return 2; + else return 0; @@ -1023,8 +2716,7 @@ index 0000000..5de4d08 +{ + if ((s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) { + return 3; /* overflow */ -+ } -+ else { ++ } else { + if (sr < 0) return 1; + else if (sr > 0) return 2; + else return 0; @@ -1132,8 +2824,7 @@ index 0000000..5de4d08 + if (env->regs[r1] == v2) { + cc = 0; + stq(a2, env->regs[r3]); -+ } -+ else { ++ } else { + cc = 1; + env->regs[r1] = v2; + } @@ -1151,8 +2842,7 @@ index 0000000..5de4d08 + cc = 0; + stq(a2, env->regs[r3]); + stq(a2 + 8, env->regs[r3 + 1]); -+ } -+ else { ++ } else { + cc = 1; + env->regs[r1] = v2 >> 64; + env->regs[r1 + 1] = v2 & 0xffffffffffffffffULL; @@ -1170,8 +2860,7 @@ index 0000000..5de4d08 + if (((uint32_t)env->regs[r1]) == v2) { + cc = 0; + stl(a2, (uint32_t)env->regs[r3]); -+ } -+ else { ++ } else { + cc = 1; + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2; + } @@ -1193,7 +2882,7 @@ index 0000000..5de4d08 + if ((insn & 0xf0ff) == 0xd000) { + uint32_t l, insn2, b, d1, d2; + l = v1 & 0xff; -+ insn2 = ldl(addr + 2); ++ insn2 = ldl_code(addr + 2); + b = (((insn2 >> 28) & 0xf) << 4) | ((insn2 >> 12) & 0xf); + d1 = (insn2 >> 16) & 0xfff; + d2 = insn2 & 0xfff; @@ -1201,7 +2890,7 @@ index 0000000..5de4d08 + case 0x200: helper_mvc(l, b, d1, d2); return cc; break; + case 0x500: return helper_clc(l, b, d1, d2); break; + case 0x700: return helper_xc(l, b, d1, d2); break; -+ default: helper_exception(23); break; ++ default: goto abort; break; + } + } + else if ((insn & 0xff00) == 0x0a00) { /* supervisor call */ @@ -1210,7 +2899,8 @@ index 0000000..5de4d08 + helper_exception(EXCP_EXECUTE_SVC + ((insn | v1) & 0xff)); + } + else { -+ helper_exception(23); ++abort: ++ cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n", insn); + } + return cc; +} @@ -1252,8 +2942,7 @@ index 0000000..5de4d08 + + if (val < 0) { + env->regs[reg] = -val; -+ } -+ else { ++ } else { + env->regs[reg] = val; + } + return cc; @@ -1268,8 +2957,7 @@ index 0000000..5de4d08 + + if (val < 0) { + env->regs[reg] = (env->regs[reg] & 0xffffffff00000000ULL) | val; -+ } -+ else { ++ } else { + env->regs[reg] = (env->regs[reg] & 0xffffffff00000000ULL) | ((uint32_t)-val); + } + return cc; @@ -1285,8 +2973,7 @@ index 0000000..5de4d08 + + if (val < 0) { + env->regs[reg] = -val; -+ } -+ else { ++ } else { + env->regs[reg] = val; + } + return cc; @@ -1301,8 +2988,7 @@ index 0000000..5de4d08 + + if (val < 0) { + env->regs[reg] = val; -+ } -+ else { ++ } else { + env->regs[reg] = -val; + } + return cc; @@ -1319,12 +3005,12 @@ index 0000000..5de4d08 + if (res == 0) { + if (v1) cc = 2; + else cc = 0; -+ } -+ else { -+ if (res < v1 || res < v2) ++ } else { ++ if (res < v1 || res < v2) { + cc = 3; -+ else ++ } else { + cc = 1; ++ } + } + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res; + return cc; @@ -1337,12 +3023,10 @@ index 0000000..5de4d08 + if (res == 0) { + if (v1) cc = 2; + else cc = 0; -+ } -+ else { ++ } else { + if (res < v1 || res < v2) { + cc = 3; -+ } -+ else { ++ } else { + cc = 1; + } + } @@ -1487,8 +3171,7 @@ index 0000000..5de4d08 + if (cc & 2) { /* borrow */ + if (v1) return 1; + else return 0; -+ } -+ else { ++ } else { + if (v1) return 3; + else return 2; + } @@ -1502,27 +3185,12 @@ index 0000000..5de4d08 + if (cc & 2) { /* borrow */ + if (v1) return 1; + else return 0; -+ } -+ else { ++ } else { + if (v1) return 3; + else return 2; + } +} + -+/* union used for splitting/joining 128-bit floats to/from 64-bit FP regs */ -+typedef union { -+ struct { -+#ifdef WORDS_BIGENDIAN -+ uint64_t h; -+ uint64_t l; -+#else -+ uint64_t l; -+ uint64_t h; -+#endif -+ }; -+ float128 x; -+} FP128; -+ +/* condition codes for binary FP ops */ +static uint32_t set_cc_f32(float32 v1, float32 v2) +{ @@ -1575,17 +3243,17 @@ index 0000000..5de4d08 +/* convert 32-bit int to 128-bit float */ +void HELPER(cxfbr)(uint32_t f1, int32_t v2) +{ -+ FP128 v1; -+ v1.x = int32_to_float128(v2, &env->fpu_status); -+ env->fregs[f1].i = v1.h; -+ env->fregs[f1 + 2].i = v1.l; ++ CPU_QuadU v1; ++ v1.q = int32_to_float128(v2, &env->fpu_status); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; +} + +/* convert 64-bit int to 32-bit float */ +void HELPER(cegbr)(uint32_t f1, int64_t v2) +{ + HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1); -+ env->fregs[f1].e = int64_to_float32(v2, &env->fpu_status); ++ env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status); +} + +/* convert 64-bit int to 64-bit float */ @@ -1598,26 +3266,26 @@ index 0000000..5de4d08 +/* convert 64-bit int to 128-bit float */ +void HELPER(cxgbr)(uint32_t f1, int64_t v2) +{ -+ FP128 x1; -+ x1.x = int64_to_float128(v2, &env->fpu_status); -+ HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2, x1.h, x1.l); -+ env->fregs[f1].i = x1.h; -+ env->fregs[f1 + 2].i = x1.l; ++ CPU_QuadU x1; ++ x1.q = int64_to_float128(v2, &env->fpu_status); ++ HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2, x1.ll.upper, x1.l); ++ env->fregs[f1].ll = x1.ll.upper; ++ env->fregs[f1 + 2].ll = x1.ll.lower; +} + +/* convert 32-bit int to 32-bit float */ +void HELPER(cefbr)(uint32_t f1, int32_t v2) +{ -+ env->fregs[f1].e = int32_to_float32(v2, &env->fpu_status); -+ HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2, env->fregs[f1].e, f1); ++ env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status); ++ HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2, env->fregs[f1].l.upper, f1); +} + +/* 32-bit FP addition RR */ +uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = float32_add(env->fregs[f1].e, env->fregs[f2].e, &env->fpu_status); -+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].e, env->fregs[f1].e, f1); -+ return set_cc_nz_f32(env->fregs[f1].e); ++ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* 64-bit FP addition RR */ @@ -1631,9 +3299,9 @@ index 0000000..5de4d08 +/* 32-bit FP subtraction RR */ +uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = float32_sub(env->fregs[f1].e, env->fregs[f2].e, &env->fpu_status); -+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].e, env->fregs[f1].e, f1); -+ return set_cc_nz_f32(env->fregs[f1].e); ++ env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); ++ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* 64-bit FP subtraction RR */ @@ -1647,22 +3315,22 @@ index 0000000..5de4d08 +/* 32-bit FP division RR */ +void HELPER(debr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = float32_div(env->fregs[f1].e, env->fregs[f2].e, &env->fpu_status); ++ env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); +} + +/* 128-bit FP division RR */ +void HELPER(dxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ FP128 res; -+ res.x = float128_div(v1.x, v2.x, &env->fpu_status); -+ env->fregs[f1].i = res.h; -+ env->fregs[f1 + 2].i = res.l; ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_div(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* 64-bit FP multiplication RR */ @@ -1674,61 +3342,58 @@ index 0000000..5de4d08 +/* 128-bit FP multiplication RR */ +void HELPER(mxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ FP128 res; -+ res.x = float128_mul(v1.x, v2.x, &env->fpu_status); -+ //HELPER_LOG("%s: 0x%ld * 0x%ld = 0x%ld\n", __FUNCTION__, v1.x, v2.x, res.x); -+ env->fregs[f1].i = res.h; -+ env->fregs[f1 + 2].i = res.l; ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_mul(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* convert 32-bit float to 64-bit float */ +void HELPER(ldebr)(uint32_t r1, uint32_t r2) +{ -+ env->fregs[r1].d = float32_to_float64(env->fregs[r2].e, &env->fpu_status); ++ env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper, &env->fpu_status); +} + +/* convert 128-bit float to 64-bit float */ +void HELPER(ldxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 x2; -+ x2.h = env->fregs[f2].i; -+ x2.l = env->fregs[f2 + 2].i; -+ //HELPER_LOG("%s: converted %llf ", __FUNCTION__, x2.x); -+ env->fregs[f1].d = float128_to_float64(x2.x, &env->fpu_status); ++ CPU_QuadU x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status); + HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d); +} + +/* convert 64-bit float to 128-bit float */ +void HELPER(lxdbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 res; -+ res.x = float64_to_float128(env->fregs[f2].d, &env->fpu_status); -+ env->fregs[f1].i = res.h; -+ env->fregs[f1 + 2].i = res.l; ++ CPU_QuadU res; ++ res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* convert 64-bit float to 32-bit float */ +void HELPER(ledbr)(uint32_t f1, uint32_t f2) +{ + float64 d2 = env->fregs[f2].d; -+ env->fregs[f1].e = float64_to_float32(d2, &env->fpu_status); ++ env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status); +} + +/* convert 128-bit float to 32-bit float */ +void HELPER(lexbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 x2; -+ x2.h = env->fregs[f2].i; -+ x2.l = env->fregs[f2 + 2].i; -+ //HELPER_LOG("%s: converted %llf ", __FUNCTION__, x2.x); -+ env->fregs[f1].e = float128_to_float32(x2.x, &env->fpu_status); -+ HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].e); ++ CPU_QuadU x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status); ++ HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper); +} + +/* absolute value of 32-bit float */ @@ -1736,12 +3401,7 @@ index 0000000..5de4d08 +{ + float32 v1; + float32 v2 = env->fregs[f2].d; -+ if (float32_is_neg(v2)) { -+ v1 = float32_abs(v2); -+ } -+ else { -+ v1 = v2; -+ } ++ v1 = float32_abs(v2); + env->fregs[f1].d = v1; + return set_cc_nz_f32(v1); +} @@ -1751,12 +3411,7 @@ index 0000000..5de4d08 +{ + float64 v1; + float64 v2 = env->fregs[f2].d; -+ if (float64_is_neg(v2)) { -+ v1 = float64_abs(v2); -+ } -+ else { -+ v1 = v2; -+ } ++ v1 = float64_abs(v2); + env->fregs[f1].d = v1; + return set_cc_nz_f64(v1); +} @@ -1764,19 +3419,14 @@ index 0000000..5de4d08 +/* absolute value of 128-bit float */ +uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ if (float128_is_neg(v2.x)) { -+ v1.x = float128_abs(v2.x); -+ } -+ else { -+ v1 = v2; -+ } -+ env->fregs[f1].i = v1.h; -+ env->fregs[f1 + 2].i = v1.l; -+ return set_cc_nz_f128(v1.x); ++ CPU_QuadU v1; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ v1.q = float128_abs(v2.q); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; ++ return set_cc_nz_f128(v1.q); +} + +/* load and test 64-bit float */ @@ -1789,26 +3439,26 @@ index 0000000..5de4d08 +/* load and test 32-bit float */ +uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = env->fregs[f2].e; -+ return set_cc_nz_f32(env->fregs[f1].e); ++ env->fregs[f1].l.upper = env->fregs[f2].l.upper; ++ return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* load and test 128-bit float */ +uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 x; -+ x.h = env->fregs[f2].i; -+ x.l = env->fregs[f2 + 2].i; -+ env->fregs[f1].i = x.h; -+ env->fregs[f1 + 2].i = x.l; -+ return set_cc_nz_f128(x.x); ++ CPU_QuadU x; ++ x.ll.upper = env->fregs[f2].ll; ++ x.ll.lower = env->fregs[f2 + 2].ll; ++ env->fregs[f1].ll = x.ll.upper; ++ env->fregs[f1 + 2].ll = x.ll.lower; ++ return set_cc_nz_f128(x.q); +} + +/* negative absolute of 32-bit float */ +uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = float32_sub(float32_zero, env->fregs[f2].e, &env->fpu_status); -+ return set_cc_nz_f32(env->fregs[f1].e); ++ env->fregs[f1].l.upper = float32_sub(float32_zero, env->fregs[f2].l.upper, &env->fpu_status); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* negative absolute of 64-bit float */ @@ -1821,73 +3471,61 @@ index 0000000..5de4d08 +/* convert 64-bit float to 128-bit float */ +uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 x1, x2; -+ x2.h = env->fregs[f2].i; -+ x2.l = env->fregs[f2 + 2].i; -+ x1.x = float128_sub(float64_to_float128(float64_zero, &env->fpu_status), x2.x, &env->fpu_status); -+ env->fregs[f1].i = x1.h; -+ env->fregs[f1 + 2].i = x1.l; -+ return set_cc_nz_f128(x1.x); ++ CPU_QuadU x1, x2; ++ x2.ll.upper = env->fregs[f2].ll; ++ x2.ll.lower = env->fregs[f2 + 2].ll; ++ x1.q = float128_sub(float64_to_float128(float64_zero, &env->fpu_status), x2.q, &env->fpu_status); ++ env->fregs[f1].ll = x1.ll.upper; ++ env->fregs[f1 + 2].ll = x1.ll.lower; ++ return set_cc_nz_f128(x1.q); +} + +/* 32-bit FP compare RM */ -+uint32_t HELPER(ceb)(uint32_t f1, uint64_t a2) ++uint32_t HELPER(ceb)(uint32_t f1, uint32_t val) +{ -+ float32 v1 = env->fregs[f1].e; -+ union { -+ float32 e; -+ uint32_t i; -+ } v2; -+ v2.i = ldl(a2); -+ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.e); -+ return set_cc_f32(v1, v2.e); ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ return set_cc_f32(v1, v2.f); +} + +/* 32-bit FP addition RM */ -+uint32_t HELPER(aeb)(uint32_t f1, uint64_t a2) ++uint32_t HELPER(aeb)(uint32_t f1, uint32_t val) +{ -+ float32 v1 = env->fregs[f1].e; -+ union { -+ float32 e; -+ uint32_t i; -+ } v2; -+ v2.i = ldl(a2); -+ HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.e); -+ env->fregs[f1].e = float32_add(v1, v2.e, &env->fpu_status); -+ return set_cc_nz_f32(env->fregs[f1].e); ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status); ++ return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* 32-bit FP division RM */ -+void HELPER(deb)(uint32_t f1, uint64_t a2) ++void HELPER(deb)(uint32_t f1, uint32_t val) +{ -+ float32 v1 = env->fregs[f1].e; -+ union { -+ float32 e; -+ uint32_t i; -+ } v2; -+ v2.i = ldl(a2); -+ HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__, v1, f1, v2.e); -+ env->fregs[f1].e = float32_div(v1, v2.e, &env->fpu_status); ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status); +} + +/* 32-bit FP multiplication RM */ -+void HELPER(meeb)(uint32_t f1, uint64_t a2) ++void HELPER(meeb)(uint32_t f1, uint32_t val) +{ -+ float32 v1 = env->fregs[f1].e; -+ union { -+ float32 e; -+ uint32_t i; -+ } v2; -+ v2.i = ldl(a2); -+ HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.e); -+ env->fregs[f1].e = float32_mul(v1, v2.e, &env->fpu_status); ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2.f); ++ env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status); +} + +/* 32-bit FP compare RR */ +uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2) +{ -+ float32 v1 = env->fregs[f1].e; -+ float32 v2 = env->fregs[f2].e;; ++ float32 v1 = env->fregs[f1].l.upper; ++ float32 v2 = env->fregs[f2].l.upper;; + HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, v1, f1, v2); + return set_cc_f32(v1, v2); +} @@ -1904,16 +3542,15 @@ index 0000000..5de4d08 +/* 128-bit FP compare RR */ +uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ //HELPER_LOG("%s: comparing %llf from f%d and %llf\n", __FUNCTION__, v1.x, f1, v2.x); -+ if (float128_is_nan(v1.x) || float128_is_nan(v2.x)) return 3; -+ else if (float128_eq(v1.x, v2.x, &env->fpu_status)) return 0; -+ else if (float128_lt(v1.x, v2.x, &env->fpu_status)) return 1; ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ if (float128_is_nan(v1.q) || float128_is_nan(v2.q)) return 3; ++ else if (float128_eq(v1.q, v2.q, &env->fpu_status)) return 0; ++ else if (float128_lt(v1.q, v2.q, &env->fpu_status)) return 1; + else return 2; +} + @@ -1921,11 +3558,8 @@ index 0000000..5de4d08 +uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1, f1, v2.d); + return set_cc_f64(v1, v2.d); +} @@ -1934,26 +3568,20 @@ index 0000000..5de4d08 +uint32_t HELPER(adb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__, v1, f1, v2.d); + env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status); + return set_cc_nz_f64(v1); +} + +/* 32-bit FP subtraction RM */ -+uint32_t HELPER(seb)(uint32_t f1, uint64_t a2) ++uint32_t HELPER(seb)(uint32_t f1, uint32_t val) +{ -+ float32 v1 = env->fregs[f1].e; -+ union { -+ float32 e; -+ uint32_t i; -+ } v2; -+ v2.i = ldl(a2); -+ env->fregs[f1].e = v1 = float32_sub(v1, v2.e, &env->fpu_status); ++ float32 v1 = env->fregs[f1].l.upper; ++ CPU_FloatU v2; ++ v2.l = val; ++ env->fregs[f1].l.upper = v1 = float32_sub(v1, v2.f, &env->fpu_status); + return set_cc_nz_f32(v1); +} + @@ -1961,11 +3589,8 @@ index 0000000..5de4d08 +uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status); + return set_cc_nz_f64(v1); +} @@ -1974,11 +3599,8 @@ index 0000000..5de4d08 +void HELPER(mdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__, v1, f1, v2.d); + env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status); +} @@ -1987,11 +3609,8 @@ index 0000000..5de4d08 +void HELPER(ddb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__, v1, f1, v2.d); + env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status); +} @@ -2019,7 +3638,7 @@ index 0000000..5de4d08 +/* convert 32-bit float to 64-bit int */ +uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ -+ float32 v2 = env->fregs[f2].e; ++ float32 v2 = env->fregs[f2].l.upper; + set_round_mode(m3); + env->regs[r1] = float32_to_int64(v2, &env->fpu_status); + return set_cc_nz_f32(v2); @@ -2037,21 +3656,21 @@ index 0000000..5de4d08 +/* convert 128-bit float to 64-bit int */ +uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; + set_round_mode(m3); -+ env->regs[r1] = float128_to_int64(v2.x, &env->fpu_status); -+ if (float128_is_nan(v2.x)) return 3; -+ else if (float128_is_zero(v2.x)) return 0; -+ else if (float128_is_neg(v2.x)) return 1; ++ env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); ++ if (float128_is_nan(v2.q)) return 3; ++ else if (float128_is_zero(v2.q)) return 0; ++ else if (float128_is_neg(v2.q)) return 1; + else return 2; +} + +/* convert 32-bit float to 32-bit int */ +uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ -+ float32 v2 = env->fregs[f2].e; ++ float32 v2 = env->fregs[f2].l.upper; + set_round_mode(m3); + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float32_to_int32(v2, &env->fpu_status); + return set_cc_nz_f32(v2); @@ -2069,17 +3688,17 @@ index 0000000..5de4d08 +/* convert 128-bit float to 32-bit int */ +uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float128_to_int32(v2.x, &env->fpu_status); -+ return set_cc_nz_f128(v2.x); ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | float128_to_int32(v2.q, &env->fpu_status); ++ return set_cc_nz_f128(v2.q); +} + +/* load 32-bit FP zero */ +void HELPER(lzer)(uint32_t f1) +{ -+ env->fregs[f1].e = float32_zero; ++ env->fregs[f1].l.upper = float32_zero; +} + +/* load 64-bit FP zero */ @@ -2091,48 +3710,48 @@ index 0000000..5de4d08 +/* load 128-bit FP zero */ +void HELPER(lzxr)(uint32_t f1) +{ -+ FP128 x; -+ x.x = float64_to_float128(float64_zero, &env->fpu_status); -+ env->fregs[f1].i = x.h; -+ env->fregs[f1 + 1].i = x.l; ++ CPU_QuadU x; ++ x.q = float64_to_float128(float64_zero, &env->fpu_status); ++ env->fregs[f1].ll = x.ll.upper; ++ env->fregs[f1 + 1].ll = x.ll.lower; +} + +/* 128-bit FP subtraction RR */ +uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ FP128 res; -+ res.x = float128_sub(v1.x, v2.x, &env->fpu_status); -+ env->fregs[f1].i = res.h; -+ env->fregs[f1 + 2].i = res.l; -+ return set_cc_nz_f128(res.x); ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_sub(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++ return set_cc_nz_f128(res.q); +} + +/* 128-bit FP addition RR */ +uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2) +{ -+ FP128 v1; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; -+ FP128 v2; -+ v2.h = env->fregs[f2].i; -+ v2.l = env->fregs[f2 + 2].i; -+ FP128 res; -+ res.x = float128_add(v1.x, v2.x, &env->fpu_status); -+ env->fregs[f1].i = res.h; -+ env->fregs[f1 + 2].i = res.l; -+ return set_cc_nz_f128(res.x); ++ CPU_QuadU v1; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; ++ CPU_QuadU v2; ++ v2.ll.upper = env->fregs[f2].ll; ++ v2.ll.lower = env->fregs[f2 + 2].ll; ++ CPU_QuadU res; ++ res.q = float128_add(v1.q, v2.q, &env->fpu_status); ++ env->fregs[f1].ll = res.ll.upper; ++ env->fregs[f1 + 2].ll = res.ll.lower; ++ return set_cc_nz_f128(res.q); +} + +/* 32-bit FP multiplication RR */ +void HELPER(meebr)(uint32_t f1, uint32_t f2) +{ -+ env->fregs[f1].e = float32_mul(env->fregs[f1].e, env->fregs[f2].e, &env->fpu_status); ++ env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper, env->fregs[f2].l.upper, &env->fpu_status); +} + +/* 64-bit FP division RR */ @@ -2145,11 +3764,8 @@ index 0000000..5de4d08 +void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3) +{ + HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3); -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); + env->fregs[f1].d = float64_add(env->fregs[f1].d, float64_mul(v2.d, env->fregs[f3].d, &env->fpu_status), &env->fpu_status); +} + @@ -2170,27 +3786,24 @@ index 0000000..5de4d08 +/* 32-bit FP multiply and add RR */ +void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2) +{ -+ env->fregs[f1].e = float32_add(env->fregs[f1].e, float32_mul(env->fregs[f2].e, env->fregs[f3].e, &env->fpu_status), &env->fpu_status); ++ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, float32_mul(env->fregs[f2].l.upper, env->fregs[f3].l.upper, &env->fpu_status), &env->fpu_status); +} + +/* convert 64-bit float to 128-bit float */ +void HELPER(lxdb)(uint32_t f1, uint64_t a2) +{ -+ union { -+ float64 d; -+ uint64_t i; -+ } v2; -+ v2.i = ldq(a2); -+ FP128 v1; -+ v1.x = float64_to_float128(v2.d, &env->fpu_status); -+ env->fregs[f1].i = v1.h; -+ env->fregs[f1 + 2].i = v1.l; ++ CPU_DoubleU v2; ++ v2.ll = ldq(a2); ++ CPU_QuadU v1; ++ v1.q = float64_to_float128(v2.d, &env->fpu_status); ++ env->fregs[f1].ll = v1.ll.upper; ++ env->fregs[f1 + 2].ll = v1.ll.lower; +} + +/* test data class 32-bit */ +uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2) +{ -+ float32 v1 = env->fregs[f1].e; ++ float32 v1 = env->fregs[f1].l.upper; + int neg = float32_is_neg(v1); + uint32_t cc = 0; + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); @@ -2222,16 +3835,16 @@ index 0000000..5de4d08 +/* test data class 128-bit */ +uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2) +{ -+ FP128 v1; ++ CPU_QuadU v1; + uint32_t cc = 0; -+ v1.h = env->fregs[f1].i; -+ v1.l = env->fregs[f1 + 2].i; ++ v1.ll.upper = env->fregs[f1].ll; ++ v1.ll.lower = env->fregs[f1 + 2].ll; + -+ int neg = float128_is_neg(v1.x); -+ if (float128_is_zero(v1.x) && (m2 & (1 << (11-neg)))) cc = 1; -+ else if (float128_is_infinity(v1.x) && (m2 & (1 << (5-neg)))) cc = 1; -+ else if (float128_is_nan(v1.x) && (m2 & (1 << (3-neg)))) cc = 1; -+ else if (float128_is_signaling_nan(v1.x) && (m2 & (1 << (1-neg)))) cc = 1; ++ int neg = float128_is_neg(v1.q); ++ if (float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) cc = 1; ++ else if (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) cc = 1; ++ else if (float128_is_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ + return cc; @@ -2264,30 +3877,13 @@ index 0000000..5de4d08 + env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status); +} diff --git a/target-s390x/translate.c b/target-s390x/translate.c -new file mode 100644 -index 0000000..e477389 ---- /dev/null +index d33bfb1..e08dcf4 100644 +--- a/target-s390x/translate.c +++ b/target-s390x/translate.c -@@ -0,0 +1,2479 @@ -+/* -+ * S/390 translation -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -+ */ +@@ -16,6 +16,18 @@ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include +#include +#include @@ -2300,13 +3896,13 @@ index 0000000..e477389 +#else +# define LOG_DISAS(...) do { } while (0) +#endif -+ -+#include "cpu.h" -+#include "exec-all.h" -+#include "disas.h" -+#include "tcg-op.h" -+#include "qemu-log.h" -+ + + #include "cpu.h" + #include "exec-all.h" +@@ -23,6 +35,25 @@ + #include "tcg-op.h" + #include "qemu-log.h" + +/* global register indexes */ +static TCGv_ptr cpu_env; + @@ -2320,36 +3916,26 @@ index 0000000..e477389 + uint64_t pc; + int is_jmp; + CPUS390XState *env; ++ struct TranslationBlock *tb; +}; + +#define DISAS_EXCP 4 +#define DISAS_SVC 5 + -+void cpu_dump_state(CPUState *env, FILE *f, -+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...), -+ int flags) -+{ -+ int i; -+ for (i = 0; i < 16; i++) { -+ cpu_fprintf(f, "R%02d=%016lx", i, env->regs[i]); -+ if ((i % 4) == 3) cpu_fprintf(f, "\n"); -+ else cpu_fprintf(f, " "); -+ } -+ for (i = 0; i < 16; i++) { -+ cpu_fprintf(f, "F%02d=%016lx", i, env->fregs[i]); -+ if ((i % 4) == 3) cpu_fprintf(f, "\n"); -+ else cpu_fprintf(f, " "); -+ } -+ cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc); -+} -+ + void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, + int flags) + { +@@ -46,12 +77,2776 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, + cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc); + } + +#define TCGREGS + +static TCGv global_cc; +#ifdef TCGREGS +/* registers stored in TCG variables enhance performance */ -+static TCGv tcgregs[16]; -+static TCGv tcgregs32[16]; ++static TCGv_i64 tcgregs[16]; ++static TCGv_i32 tcgregs32[16]; +#endif +static TCGv cc; +static TCGv psw_addr; @@ -2366,7 +3952,7 @@ index 0000000..e477389 + tcgregs[i] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, regs[i]), strdup(rn)); + sprintf(rn, "r%d", i); + tcgregs32[i] = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, regs[i]) -+#ifdef WORDS_BIGENDIAN ++#ifdef HOST_WORDS_BIGENDIAN + + 4 +#endif + , strdup(rn)); @@ -2406,20 +3992,20 @@ index 0000000..e477389 + return r; +} + -+static TCGv load_freg32(int reg) ++static TCGv_i32 load_freg32(int reg) +{ -+ TCGv r = tcg_temp_new_i32(); -+ tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].e)); ++ TCGv_i32 r = tcg_temp_new_i32(); ++ tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); + return r; +} + -+static void load_reg32_var(TCGv r, int reg) ++static void load_reg32_var(TCGv_i32 r, int reg) +{ +#ifdef TCGREGS + sync_reg64(reg); + tcg_gen_mov_i32(r, tcgregs32[reg]); +#else -+#ifdef WORDS_BIGENDIAN ++#ifdef HOST_WORDS_BIGENDIAN + tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, regs[reg]) + 4); +#else + tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, regs[reg])); @@ -2427,9 +4013,9 @@ index 0000000..e477389 +#endif +} + -+static TCGv load_reg32(int reg) ++static TCGv_i32 load_reg32(int reg) +{ -+ TCGv r = tcg_temp_new_i32(); ++ TCGv_i32 r = tcg_temp_new_i32(); + load_reg32_var(r, reg); + return r; +} @@ -2449,13 +4035,13 @@ index 0000000..e477389 + tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, fregs[reg].d)); +} + -+static void store_reg32(int reg, TCGv v) ++static void store_reg32(int reg, TCGv_i32 v) +{ +#ifdef TCGREGS + sync_reg64(reg); + tcg_gen_mov_i32(tcgregs32[reg], v); +#else -+#ifdef WORDS_BIGENDIAN ++#ifdef HOST_WORDS_BIGENDIAN + tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, regs[reg]) + 4); +#else + tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, regs[reg])); @@ -2463,16 +4049,16 @@ index 0000000..e477389 +#endif +} + -+static void store_reg8(int reg, TCGv v) ++static void store_reg8(int reg, TCGv_i32 v) +{ +#ifdef TCGREGS -+ TCGv tmp = tcg_temp_new_i32(); ++ TCGv_i32 tmp = tcg_temp_new_i32(); + sync_reg64(reg); + tcg_gen_andi_i32(tmp, tcgregs32[reg], 0xffffff00UL); + tcg_gen_or_i32(tcgregs32[reg], tmp, v); + tcg_temp_free(tmp); +#else -+#ifdef WORDS_BIGENDIAN ++#ifdef HOST_WORDS_BIGENDIAN + tcg_gen_st8_i32(v, cpu_env, offsetof(CPUState, regs[reg]) + 7); +#else + tcg_gen_st8_i32(v, cpu_env, offsetof(CPUState, regs[reg])); @@ -2482,14 +4068,14 @@ index 0000000..e477389 + +static void store_freg32(int reg, TCGv v) +{ -+ tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].e)); ++ tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); +} + +static void gen_illegal_opcode(DisasContext *s) +{ -+ TCGv tmp = tcg_temp_new_i64(); -+ tcg_gen_movi_i64(tmp, 42); ++ TCGv tmp = tcg_const_i64(EXCP_SPEC); + gen_helper_exception(tmp); ++ tcg_temp_free(tmp); + s->is_jmp = DISAS_EXCP; +} + @@ -2497,7 +4083,7 @@ index 0000000..e477389 + +static TCGv get_address(int x2, int b2, int d2) +{ -+ TCGv tmp = 0,tmp2 = 0; ++ TCGv tmp = 0, tmp2; + if (d2) tmp = tcg_const_i64(d2); + if (x2) { + if (d2) { @@ -2558,11 +4144,15 @@ index 0000000..e477389 +/* this is a hysterical raisin */ +static inline void cmp_s32c(TCGv v1, int32_t v2) +{ -+ gen_helper_cmp_s32(cc, v1, tcg_const_i32(v2)); ++ TCGv_i32 tmp = tcg_const_i32(v2); ++ gen_helper_cmp_s32(cc, v1, tmp); ++ tcg_temp_free(tmp); +} +static inline void cmp_u32c(TCGv v1, uint32_t v2) +{ -+ gen_helper_cmp_u32(cc, v1, tcg_const_i32(v2)); ++ TCGv_i32 tmp = tcg_const_i32(v2); ++ gen_helper_cmp_u32(cc, v1, tmp); ++ tcg_temp_free(tmp); +} + + @@ -2579,34 +4169,84 @@ index 0000000..e477389 +/* see cmp_[su]32c() */ +static inline void cmp_s64c(TCGv v1, int64_t v2) +{ -+ gen_helper_cmp_s64(cc, v1, tcg_const_i64(v2)); ++ TCGv_i32 tmp = tcg_const_i64(v2); ++ gen_helper_cmp_s64(cc, v1, tmp); ++ tcg_temp_free(tmp); +} +static inline void cmp_u64c(TCGv v1, uint64_t v2) +{ -+ gen_helper_cmp_u64(cc, v1, tcg_const_i64(v2)); ++ TCGv_i32 tmp = tcg_const_i64(v2); ++ gen_helper_cmp_u64(cc, v1, tmp); ++ tcg_temp_free(tmp); +} + +static void gen_bcr(uint32_t mask, int tr, uint64_t offset) +{ -+ TCGv target; ++ TCGv target, o; ++ TCGv_i32 m; + if (mask == 0xf) { /* unconditional */ + target = load_reg(tr); + tcg_gen_mov_i64(psw_addr, target); + } + else { -+ gen_helper_bcr(cc, tcg_const_i32(mask), (target = load_reg(tr)), tcg_const_i64(offset)); ++ m = tcg_const_i32(mask); ++ o = tcg_const_i64(offset); ++ gen_helper_bcr(cc, m, (target = load_reg(tr)), o); ++ tcg_temp_free(m); ++ tcg_temp_free(o); + } + tcg_temp_free(target); +} + -+static void gen_brc(uint32_t mask, uint64_t pc, int32_t offset) ++static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc) +{ ++ TranslationBlock *tb; ++ ++ tb = s->tb; ++ /* NOTE: we handle the case where the TB spans two pages here */ ++ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || ++ (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { ++ /* jump to same page: we can use a direct jump */ ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_gen_goto_tb(tb_num); ++ tcg_gen_movi_i64(psw_addr, pc); ++ tcg_gen_exit_tb((long)tb + tb_num); ++ } else { ++ /* jump to another page: currently not optimized */ ++ tcg_gen_movi_i64(psw_addr, pc); ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_gen_exit_tb(0); ++ } ++} ++ ++static void gen_brc(uint32_t mask, DisasContext *s, int32_t offset) ++{ ++ TCGv_i32 r; ++ TCGv_i32 tmp, tmp2; ++ int skip; ++ + if (mask == 0xf) { /* unconditional */ -+ tcg_gen_movi_i64(psw_addr, pc + offset); ++ //tcg_gen_movi_i64(psw_addr, s->pc + offset); ++ gen_goto_tb(s, 0, s->pc + offset); + } + else { -+ gen_helper_brc(cc, tcg_const_i32(mask), tcg_const_i64(pc), tcg_const_i32(offset)); ++ tmp = tcg_const_i32(3); ++ tcg_gen_sub_i32(tmp, tmp, cc); /* 3 - cc */ ++ tmp2 = tcg_const_i32(1); ++ tcg_gen_shl_i32(tmp2, tmp2, tmp); /* 1 << (3 - cc) */ ++ r = tcg_const_i32(mask); ++ tcg_gen_and_i32(r, r, tmp2); /* mask & (1 << (3 - cc)) */ ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ skip = gen_new_label(); ++ tcg_gen_brcondi_i32(TCG_COND_EQ, r, 0, skip); ++ gen_goto_tb(s, 0, s->pc + offset); ++ gen_set_label(skip); ++ gen_goto_tb(s, 1, s->pc + 4); ++ //tcg_gen_mov_i32(global_cc, cc); ++ tcg_temp_free(r); + } ++ s->is_jmp = DISAS_TB_JUMP; +} + +static void gen_set_cc_add64(TCGv v1, TCGv v2, TCGv vr) @@ -2616,7 +4256,7 @@ index 0000000..e477389 + +static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + + LOG_DISAS("disas_e3: op 0x%x r1 %d x2 %d b2 %d d2 %d\n", op, r1, x2, b2, d2); + tmp = get_address(x2, b2, d2); @@ -2627,12 +4267,14 @@ index 0000000..e477389 + tcg_gen_qemu_ld64(tmp2, tmp, 1); + store_reg(r1, tmp2); + if (op == 0x2) set_cc_s64(tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x12: /* LT R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, tmp, 1); + store_reg32(r1, tmp2); + set_cc_s32(tmp2); ++ tcg_temp_free(tmp2); + break; + case 0xc: /* MSG R1,D2(X2,B2) [RXY] */ + case 0x1c: /* MSGF R1,D2(X2,B2) [RXY] */ @@ -2642,47 +4284,49 @@ index 0000000..e477389 + } + else { + tcg_gen_qemu_ld32s(tmp2, tmp, 1); -+ tcg_gen_ext32s_i64(tmp2, tmp2); + } ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + tcg_gen_mul_i64(tmp, tmp, tmp2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp2); + break; + case 0xd: /* DSG R1,D2(X2,B2) [RXY] */ + case 0x1d: /* DSGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + if (op == 0x1d) { + tcg_gen_qemu_ld32s(tmp2, tmp, 1); -+ tcg_gen_ext32s_i64(tmp2, tmp2); + } + else { + tcg_gen_qemu_ld64(tmp2, tmp, 1); + } ++ tcg_temp_free(tmp); + tmp = load_reg(r1 + 1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_div_i64(tmp3, tmp, tmp2); + store_reg(r1 + 1, tmp3); + tcg_gen_rem_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x8: /* AG R1,D2(X2,B2) [RXY] */ + case 0xa: /* ALG R1,D2(X2,B2) [RXY] */ + case 0x18: /* AGF R1,D2(X2,B2) [RXY] */ + case 0x1a: /* ALGF R1,D2(X2,B2) [RXY] */ + if (op == 0x1a) { -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); -+ tcg_gen_ext32u_i64(tmp2, tmp2); + } + else if (op == 0x18) { -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, tmp, 1); -+ tcg_gen_ext32s_i64(tmp2, tmp2); + } + else { + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); + } ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_add_i64(tmp3, tmp, tmp2); @@ -2692,25 +4336,24 @@ index 0000000..e477389 + case 0xa: case 0x1a: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x9: /* SG R1,D2(X2,B2) [RXY] */ + case 0xb: /* SLG R1,D2(X2,B2) [RXY] */ + case 0x19: /* SGF R1,D2(X2,B2) [RXY] */ + case 0x1b: /* SLGF R1,D2(X2,B2) [RXY] */ ++ tmp2 = tcg_temp_new_i64(); + if (op == 0x19) { -+ tmp2 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32s(tmp2, tmp, 1); -+ tcg_gen_ext32s_i64(tmp2, tmp2); + } + else if (op == 0x1b) { -+ tmp2 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); -+ tcg_gen_ext32u_i64(tmp2, tmp2); + } + else { -+ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); + } ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_sub_i64(tmp3, tmp, tmp2); @@ -2720,6 +4363,8 @@ index 0000000..e477389 + case 0xb: case 0x1b: gen_helper_set_cc_subu64(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x14: /* LGF R1,D2(X2,B2) [RXY] */ + case 0x16: /* LLGF R1,D2(X2,B2) [RXY] */ @@ -2727,29 +4372,31 @@ index 0000000..e477389 + tcg_gen_qemu_ld32u(tmp2, tmp, 1); + switch (op) { + case 0x14: tcg_gen_ext32s_i64(tmp2, tmp2); break; -+ case 0x16: tcg_gen_ext32u_i64(tmp2, tmp2); break; ++ case 0x16: break; + default: tcg_abort(); + } + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x15: /* LGH R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, 1); -+ tcg_gen_ext16s_i64(tmp2, tmp2); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x17: /* LLGT R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); -+ tcg_gen_ext32u_i64(tmp2, tmp2); + tcg_gen_andi_i64(tmp2, tmp2, 0x7fffffffULL); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x1e: /* LRV R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); -+ tcg_gen_bswap32_i32(tmp2, tmp2); -+ store_reg(r1, tmp2); ++ tcg_gen_bswap32_i64(tmp2, tmp2); ++ store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x20: /* CG R1,D2(X2,B2) [RXY] */ + case 0x21: /* CLG R1,D2(X2,B2) */ @@ -2763,52 +4410,58 @@ index 0000000..e477389 + break; + case 0x30: + tcg_gen_qemu_ld32s(tmp2, tmp, 1); -+ tcg_gen_ext32s_i64(tmp2, tmp2); + break; + case 0x31: + tcg_gen_qemu_ld32u(tmp2, tmp, 1); -+ tcg_gen_ext32u_i64(tmp2, tmp2); + break; + default: + tcg_abort(); + } ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + switch (op) { + case 0x20: case 0x30: cmp_s64(tmp, tmp2); break; + case 0x21: case 0x31: cmp_u64(tmp, tmp2); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp2); + break; + case 0x24: /* stg r1, d2(x2,b2) */ + tmp2 = load_reg(r1); + tcg_gen_qemu_st64(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); + break; + case 0x3e: /* STRV R1,D2(X2,B2) [RXY] */ + tmp2 = load_reg32(r1); + tcg_gen_bswap32_i32(tmp2, tmp2); + tcg_gen_qemu_st32(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); + break; + case 0x50: /* STY R1,D2(X2,B2) [RXY] */ + tmp2 = load_reg32(r1); + tcg_gen_qemu_st32(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); + break; + case 0x57: /* XY R1,D2(X2,B2) [RXY] */ + tmp2 = load_reg32(r1); -+ tmp3 = tcg_temp_new_i32(); ++ tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp3, tmp, 1); + tcg_gen_xor_i32(tmp, tmp2, tmp3); + store_reg32(r1, tmp); + set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x58: /* LY R1,D2(X2,B2) [RXY] */ -+ tmp3 = tcg_temp_new_i32(); ++ tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp3, tmp, 1); + store_reg32(r1, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0x5a: /* AY R1,D2(X2,B2) [RXY] */ + case 0x5b: /* SY R1,D2(X2,B2) [RXY] */ + tmp2 = load_reg32(r1); -+ tmp3 = tcg_temp_new_i32(); ++ tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp3, tmp, 1); + switch (op) { + case 0x5a: tcg_gen_add_i32(tmp, tmp2, tmp3); break; @@ -2821,6 +4474,8 @@ index 0000000..e477389 + case 0x5b: gen_helper_set_cc_sub32(cc, tmp2, tmp3, tmp); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x71: /* LAY R1,D2(X2,B2) [RXY] */ + store_reg(r1, tmp); @@ -2828,11 +4483,13 @@ index 0000000..e477389 + case 0x72: /* STCY R1,D2(X2,B2) [RXY] */ + tmp2 = load_reg32(r1); + tcg_gen_qemu_st8(tmp2, tmp, 1); ++ tcg_temp_free(tmp2); + break; + case 0x73: /* ICY R1,D2(X2,B2) [RXY] */ -+ tmp3 = tcg_temp_new_i32(); ++ tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp3, tmp, 1); + store_reg8(r1, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0x76: /* LB R1,D2(X2,B2) [RXY] */ + case 0x77: /* LGB R1,D2(X2,B2) [RXY] */ @@ -2840,7 +4497,7 @@ index 0000000..e477389 + tcg_gen_qemu_ld8s(tmp2, tmp, 1); + switch (op) { + case 0x76: -+ tcg_gen_ext8s_i32(tmp2, tmp2); ++ tcg_gen_ext8s_i64(tmp2, tmp2); + store_reg32(r1, tmp2); + break; + case 0x77: @@ -2849,12 +4506,13 @@ index 0000000..e477389 + break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp2); + break; + case 0x78: /* LHY R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, 1); -+ tcg_gen_ext16s_i32(tmp2, tmp2); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x80: /* NG R1,D2(X2,B2) [RXY] */ + case 0x81: /* OG R1,D2(X2,B2) [RXY] */ @@ -2870,22 +4528,29 @@ index 0000000..e477389 + } + store_reg(r1, tmp); + set_cc_nz_u64(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x86: /* MLG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32(r1); + gen_helper_mlg(tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x87: /* DLG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32(r1); + gen_helper_dlg(tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x88: /* ALCG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_shri_i64(tmp3, cc, 1); @@ -2894,46 +4559,60 @@ index 0000000..e477389 + tcg_gen_add_i64(tmp3, tmp, tmp3); + store_reg(r1, tmp3); + gen_helper_set_cc_addc_u64(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x89: /* SLBG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = load_reg(r1); + tmp3 = tcg_const_i32(r1); + gen_helper_slbg(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x90: /* LLGC R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x91: /* LLGH R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16u(tmp2, tmp, 1); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x94: /* LLC R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x95: /* LLH R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16u(tmp2, tmp, 1); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x98: /* ALC R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32(r1); + gen_helper_addc_u32(cc, cc, tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x99: /* SLB R1,D2(X2,B2) [RXY] */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = load_reg32(r1); + tmp3 = tcg_const_i32(r1); + gen_helper_slb(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal e3 operation 0x%x\n", op); @@ -2941,13 +4620,11 @@ index 0000000..e477389 + break; + } + tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + +static void disas_eb(DisasContext *s, int op, int r1, int r3, int b2, int d2) +{ -+ TCGv tmp = 0,tmp2 = 0,tmp3 = 0,tmp4 = 0; ++ TCGv tmp, tmp2, tmp3, tmp4; + int i; + + LOG_DISAS("disas_eb: op 0x%x r1 %d r3 %d b2 %d d2 0x%x\n", op, r1, r3, b2, d2); @@ -2959,8 +4636,9 @@ index 0000000..e477389 + if (b2) { + tmp = get_address(0, b2, d2); + tcg_gen_andi_i64(tmp, tmp, 0x3f); ++ } else { ++ tmp = tcg_const_i64(d2 & 0x3f); + } -+ else tmp = tcg_const_i32(d2 & 0x3f); + tmp2 = load_reg(r3); + tmp3 = tcg_temp_new_i64(); + switch (op) { @@ -2972,13 +4650,17 @@ index 0000000..e477389 + } + store_reg(r1, tmp3); + if (op == 0xa) set_cc_s64(tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x1d: /* RLL R1,R3,D2(B2) [RSY] */ + if (b2) { + tmp = get_address(0, b2, d2); + tcg_gen_andi_i64(tmp, tmp, 0x3f); ++ } else { ++ tmp = tcg_const_i64(d2 & 0x3f); + } -+ else tmp = tcg_const_i32(d2 & 0x3f); + tmp2 = load_reg32(r3); + tmp3 = tcg_temp_new_i32(); + switch (op) { @@ -2986,6 +4668,9 @@ index 0000000..e477389 + default: tcg_abort(); break; + } + store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x4: /* LMG R1,R3,D2(B2) [RSY] */ + case 0x24: /* stmg */ @@ -3011,7 +4696,6 @@ index 0000000..e477389 + } + tcg_gen_addi_i64(tmp, tmp, 8); + } -+ tmp2 = 0; + } + else { + tmp = tcg_const_i32(r1); @@ -3020,64 +4704,84 @@ index 0000000..e477389 + tmp4 = tcg_const_i32(d2); + if (op == 0x4) gen_helper_lmg(tmp, tmp2, tmp3, tmp4); + else gen_helper_stmg(tmp, tmp2, tmp3, tmp4); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); ++ tcg_temp_free(tmp4); + } ++ tcg_temp_free(tmp); + break; + case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */ + tmp2 = get_address(0, b2, d2); + tmp = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r3); + gen_helper_stcmh(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x30: /* CSG R1,R3,D2(B2) [RSY] */ + tmp2 = get_address(0, b2, d2); + tmp = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r3); + gen_helper_csg(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x3e: /* CDSG R1,R3,D2(B2) [RSY] */ + tmp2 = get_address(0, b2, d2); + tmp = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r3); + gen_helper_cdsg(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x51: /* TMY D1(B1),I2 [SIY] */ + tmp = get_address(0, b2, d2); /* SIY -> this is the destination */ -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32((r1 << 4) | r3); + gen_helper_tm(cc, tmp2, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x52: /* MVIY D1(B1),I2 [SIY] */ + tmp2 = tcg_const_i32((r1 << 4) | r3); + tmp = get_address(0, b2, d2); /* SIY -> this is the destination */ + tcg_gen_qemu_st8(tmp2, tmp, 1); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x55: /* CLIY D1(B1),I2 [SIY] */ + tmp3 = get_address(0, b2, d2); /* SIY -> this is the 1st operand */ -+ tmp = tcg_temp_new_i32(); ++ tmp = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp, tmp3, 1); + cmp_u32c(tmp, (r1 << 4) | r3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp3); + break; + case 0x80: /* ICMH R1,M3,D2(B2) [RSY] */ + tmp2 = get_address(0, b2, d2); + tmp = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r3); + gen_helper_icmh(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal eb operation 0x%x\n", op); + gen_illegal_opcode(s); + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); -+ if (tmp4) tcg_temp_free(tmp4); +} + +static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2, int r1b) +{ -+ TCGv tmp, tmp2, tmp3 = 0; ++ TCGv_i32 tmp; ++ TCGv tmp2, tmp3; + tmp2 = get_address(x2, b2, d2); + tmp = tcg_const_i32(r1); + switch (op) { @@ -3085,16 +4789,28 @@ index 0000000..e477389 + gen_helper_lxdb(tmp, tmp2); + break; + case 0x9: /* CEB R1,D2(X2,B2) [RXE] */ -+ gen_helper_ceb(cc, tmp, tmp2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_ceb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0xa: /* AEB R1,D2(X2,B2) [RXE] */ -+ gen_helper_aeb(cc, tmp, tmp2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_aeb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0xb: /* SEB R1,D2(X2,B2) [RXE] */ -+ gen_helper_seb(cc, tmp, tmp2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_seb(cc, tmp, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0xd: /* DEB R1,D2(X2,B2) [RXE] */ -+ gen_helper_deb(tmp, tmp2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_deb(tmp, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0x10: /* TCEB R1,D2(X2,B2) [RXE] */ + gen_helper_tceb(cc, tmp, tmp2); @@ -3106,7 +4822,10 @@ index 0000000..e477389 + gen_helper_tcxb(cc, tmp, tmp2); + break; + case 0x17: /* MEEB R1,D2(X2,B2) [RXE] */ -+ gen_helper_meeb(tmp, tmp2); ++ tmp3 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld32u(tmp3, tmp2, 1); ++ gen_helper_meeb(tmp, tmp3); ++ tcg_temp_free(tmp3); + break; + case 0x19: /* CDB R1,D2(X2,B2) [RXE] */ + gen_helper_cdb(cc, tmp, tmp2); @@ -3127,11 +4846,12 @@ index 0000000..e477389 + /* for RXF insns, r1 is R3 and r1b is R1 */ + tmp3 = tcg_const_i32(r1b); + gen_helper_madb(tmp3, tmp2, tmp); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal ed operation 0x%x\n", op); + gen_illegal_opcode(s); -+ break; ++ return; + } + tcg_temp_free(tmp); + tcg_temp_free(tmp2); @@ -3139,7 +4859,7 @@ index 0000000..e477389 + +static void disas_a5(DisasContext *s, int op, int r1, int i2) +{ -+ TCGv tmp = 0,tmp2 = 0; ++ TCGv tmp, tmp2; + uint64_t vtmp; + LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); + switch (op) { @@ -3173,6 +4893,7 @@ index 0000000..e477389 + tcg_gen_shri_i64(tmp2, tmp, 48); + tcg_gen_trunc_i64_i32(tmp2, tmp2); + set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x5: /* NIHL R1,I2 [RI] */ + case 0x9: /* OIHL R1,I2 [RI] */ @@ -3193,6 +4914,7 @@ index 0000000..e477389 + tcg_gen_trunc_i64_i32(tmp2, tmp2); + tcg_gen_andi_i32(tmp2, tmp2, 0xffff); + set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x6: /* NILH R1,I2 [RI] */ + case 0xa: /* OILH R1,I2 [RI] */ @@ -3213,6 +4935,7 @@ index 0000000..e477389 + tcg_gen_trunc_i64_i32(tmp2, tmp2); + tcg_gen_andi_i32(tmp2, tmp2, 0xffff); + set_cc_nz_u32(tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x7: /* NILL R1,I2 [RI] */ + case 0xb: /* OILL R1,I2 [RI] */ @@ -3232,6 +4955,7 @@ index 0000000..e477389 + tcg_gen_trunc_i64_i32(tmp, tmp); + tcg_gen_andi_i32(tmp, tmp, 0xffff); + set_cc_nz_u32(tmp); /* signedness should not matter here */ ++ tcg_temp_free(tmp2); + break; + case 0xc: /* LLIHH R1,I2 [RI] */ + tmp = tcg_const_i64( ((uint64_t)i2) << 48 ); @@ -3252,15 +4976,14 @@ index 0000000..e477389 + default: + LOG_DISAS("illegal a5 operation 0x%x\n", op); + gen_illegal_opcode(s); -+ break; ++ return; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); ++ tcg_temp_free(tmp); +} + +static void disas_a7(DisasContext *s, int op, int r1, int i2) +{ -+ TCGv tmp = 0,tmp2 = 0,tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + LOG_DISAS("disas_a7: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); + switch (op) { + case 0x0: /* TMLH or TMH R1,I2 [RI] */ @@ -3268,32 +4991,35 @@ index 0000000..e477389 + tcg_gen_shri_i64(tmp, tmp, 16); + tmp2 = tcg_const_i32((uint16_t)i2); + gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x1: /* TMLL or TML R1,I2 [RI] */ + tmp = load_reg(r1); + tmp2 = tcg_const_i32((uint16_t)i2); + gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x2: /* TMHH R1,I2 [RI] */ + tmp = load_reg(r1); + tcg_gen_shri_i64(tmp, tmp, 48); + tmp2 = tcg_const_i32((uint16_t)i2); + gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x3: /* TMHL R1,I2 [RI] */ + tmp = load_reg(r1); + tcg_gen_shri_i64(tmp, tmp, 32); + tmp2 = tcg_const_i32((uint16_t)i2); + gen_helper_tmxx(cc, tmp, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x4: /* brc m1, i2 */ -+ /* FIXME: optimize m1 == 0xf (unconditional) case */ -+ gen_brc(r1, s->pc, i2 * 2); -+ s->is_jmp = DISAS_JUMP; -+ break; ++ gen_brc(r1, s, i2 * 2); ++ return; + case 0x5: /* BRAS R1,I2 [RI] */ + tmp = tcg_const_i64(s->pc + 4); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + tmp = tcg_const_i64(s->pc + i2 * 2); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); + s->is_jmp = DISAS_JUMP; @@ -3306,6 +5032,8 @@ index 0000000..e477389 + tmp3 = tcg_const_i32(i2 * 2); + gen_helper_brct(tmp, tmp2, tmp3); + s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x7: /* BRCTG R1,I2 [RI] */ + tmp = load_reg(r1); @@ -3315,6 +5043,8 @@ index 0000000..e477389 + tmp3 = tcg_const_i32(i2 * 2); + gen_helper_brctg(tmp, tmp2, tmp3); + s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x8: /* lhi r1, i2 */ + tmp = tcg_const_i32(i2); @@ -3331,6 +5061,8 @@ index 0000000..e477389 + store_reg32(r1, tmp3); + tmp2 = tcg_const_i32(i2); + gen_helper_set_cc_add32(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xb: /* aghi r1, i2 */ + tmp = load_reg(r1); @@ -3339,6 +5071,8 @@ index 0000000..e477389 + store_reg(r1, tmp3); + tmp2 = tcg_const_i64(i2); + gen_set_cc_add64(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xc: /* MHI R1,I2 [RI] */ + tmp = load_reg32(r1); @@ -3361,16 +5095,14 @@ index 0000000..e477389 + default: + LOG_DISAS("illegal a7 operation 0x%x\n", op); + gen_illegal_opcode(s); -+ break; ++ return; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); ++ tcg_temp_free(tmp); +} + +static void disas_b2(DisasContext *s, int op, int r1, int r2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv_i32 tmp, tmp2, tmp3; + LOG_DISAS("disas_b2: op 0x%x r1 %d r2 %d\n", op, r1, r2); + switch (op) { + case 0x22: /* IPM R1 [RRE] */ @@ -3391,47 +5123,57 @@ index 0000000..e477389 + tmp2 = load_reg32(r2); + tcg_gen_mul_i32(tmp, tmp, tmp2); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp2); + break; + case 0x55: /* MVST R1,R2 [RRE] */ + tmp = load_reg32(0); + tmp2 = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r2); + gen_helper_mvst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x5d: /* CLST R1,R2 [RRE] */ + tmp = load_reg32(0); + tmp2 = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r2); + gen_helper_clst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x5e: /* SRST R1,R2 [RRE] */ + tmp = load_reg32(0); + tmp2 = tcg_const_i32(r1); + tmp3 = tcg_const_i32(r2); + gen_helper_srst(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal b2 operation 0x%x\n", op); + gen_illegal_opcode(s); -+ break; ++ return; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); ++ tcg_temp_free(tmp); +} + +static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv_i32 tmp, tmp2, tmp3; + LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2); +#define FP_HELPER(i) \ + tmp = tcg_const_i32(r1); \ + tmp2 = tcg_const_i32(r2); \ -+ gen_helper_ ## i (tmp, tmp2); ++ gen_helper_ ## i (tmp, tmp2); \ ++ tcg_temp_free(tmp); \ ++ tcg_temp_free(tmp2); ++ +#define FP_HELPER_CC(i) \ + tmp = tcg_const_i32(r1); \ + tmp2 = tcg_const_i32(r2); \ -+ gen_helper_ ## i (cc, tmp, tmp2); ++ gen_helper_ ## i (cc, tmp, tmp2); \ ++ tcg_temp_free(tmp); \ ++ tcg_temp_free(tmp2); + + switch (op) { + case 0x0: /* LPEBR R1,R2 [RRE] */ @@ -3485,6 +5227,9 @@ index 0000000..e477389 + case 0x1f: gen_helper_msdbr(tmp, tmp3, tmp2); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x40: /* LPXBR R1,R2 [RRE] */ + FP_HELPER_CC(lpxbr); break; @@ -3511,29 +5256,36 @@ index 0000000..e477389 + case 0x65: /* LXR R1,R2 [RRE] */ + tmp = load_freg(r2); + store_freg(r1, tmp); ++ tcg_temp_free(tmp); + tmp = load_freg(r2 + 2); + store_freg(r1 + 2, tmp); ++ tcg_temp_free(tmp); + break; + case 0x74: /* LZER R1 [RRE] */ + tmp = tcg_const_i32(r1); + gen_helper_lzer(tmp); ++ tcg_temp_free(tmp); + break; + case 0x75: /* LZDR R1 [RRE] */ + tmp = tcg_const_i32(r1); + gen_helper_lzdr(tmp); ++ tcg_temp_free(tmp); + break; + case 0x76: /* LZXR R1 [RRE] */ + tmp = tcg_const_i32(r1); + gen_helper_lzxr(tmp); ++ tcg_temp_free(tmp); + break; + case 0x84: /* SFPC R1 [RRE] */ + tmp = load_reg32(r1); + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fpc)); ++ tcg_temp_free(tmp); + break; + case 0x8c: /* EFPC R1 [RRE] */ + tmp = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, fpc)); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x94: /* CEFBR R1,R2 [RRE] */ + case 0x95: /* CDFBR R1,R2 [RRE] */ @@ -3546,6 +5298,8 @@ index 0000000..e477389 + case 0x96: gen_helper_cxfbr(tmp, tmp2); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x98: /* CFEBR R1,R2 [RRE] */ + case 0x99: /* CFDBR R1,R2 [RRE] */ @@ -3559,6 +5313,9 @@ index 0000000..e477389 + case 0x9a: gen_helper_cfxbr(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xa4: /* CEGBR R1,R2 [RRE] */ + case 0xa5: /* CDGBR R1,R2 [RRE] */ @@ -3569,43 +5326,53 @@ index 0000000..e477389 + case 0xa5: gen_helper_cdgbr(tmp, tmp2); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0xa6: /* CXGBR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = load_reg(r2); + gen_helper_cxgbr(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0xa8: /* CGEBR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = tcg_const_i32(r2); + tmp3 = tcg_const_i32(m3); + gen_helper_cgebr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xa9: /* CGDBR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = tcg_const_i32(r2); + tmp3 = tcg_const_i32(m3); + gen_helper_cgdbr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xaa: /* CGXBR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = tcg_const_i32(r2); + tmp3 = tcg_const_i32(m3); + gen_helper_cgxbr(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal b3 operation 0x%x\n", op); + gen_illegal_opcode(s); + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + +static void disas_b9(DisasContext *s, int op, int r1, int r2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2); + switch (op) { + case 0: /* LPGR R1,R2 [RRE] */ @@ -3619,16 +5386,21 @@ index 0000000..e477389 + } + tmp = tcg_const_i32(r1); + gen_helper_abs_i64(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 1: /* LNGR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + tmp = tcg_const_i32(r1); + gen_helper_nabs_i64(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 2: /* LTGR R1,R2 [RRE] */ + tmp = load_reg(r2); + if (r1 != r2) store_reg(r1, tmp); + set_cc_s64(tmp); ++ tcg_temp_free(tmp); + break; + case 3: /* LCGR R1,R2 [RRE] */ + case 0x13: /* LCGFR R1,R2 [RRE] */ @@ -3642,15 +5414,18 @@ index 0000000..e477389 + tcg_gen_neg_i64(tmp, tmp); + store_reg(r1, tmp); + gen_helper_set_cc_comp_s64(cc, tmp); ++ tcg_temp_free(tmp); + break; + case 4: /* LGR R1,R2 [RRE] */ + tmp = load_reg(r2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x6: /* LGBR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + tcg_gen_ext8s_i64(tmp2, tmp2); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 8: /* AGR R1,R2 [RRE] */ + case 0xa: /* ALGR R1,R2 [RRE] */ @@ -3664,6 +5439,9 @@ index 0000000..e477389 + case 0xa: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 9: /* SGR R1,R2 [RRE] */ + case 0xb: /* SLGR R1,R2 [RRE] */ @@ -3688,6 +5466,9 @@ index 0000000..e477389 + case 0xb: case 0x1b: gen_helper_set_cc_subu64(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xc: /* MSGR R1,R2 [RRE] */ + case 0x1c: /* MSGFR R1,R2 [RRE] */ @@ -3696,6 +5477,8 @@ index 0000000..e477389 + if (op == 0x1c) tcg_gen_ext32s_i64(tmp2, tmp2); + tcg_gen_mul_i64(tmp, tmp, tmp2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0xd: /* DSGR R1,R2 [RRE] */ + case 0x1d: /* DSGFR R1,R2 [RRE] */ @@ -3712,23 +5495,30 @@ index 0000000..e477389 + store_reg(r1 + 1, tmp3); + tcg_gen_rem_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x14: /* LGFR R1,R2 [RRE] */ + tmp = load_reg32(r2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_ext32s_i64(tmp2, tmp); + store_reg(r1, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x16: /* LLGFR R1,R2 [RRE] */ + tmp = load_reg32(r2); + tcg_gen_ext32u_i64(tmp, tmp); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x17: /* LLGTR R1,R2 [RRE] */ + tmp = load_reg32(r2); -+ tcg_gen_andi_i32(tmp, tmp, 0x7fffffffUL); ++ tcg_gen_andi_i64(tmp, tmp, 0x7fffffffUL); + tcg_gen_ext32u_i64(tmp, tmp); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x18: /* AGFR R1,R2 [RRE] */ + case 0x1a: /* ALGFR R1,R2 [RRE] */ @@ -3747,6 +5537,9 @@ index 0000000..e477389 + case 0x1a: gen_helper_set_cc_addu64(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x20: /* CGR R1,R2 [RRE] */ + case 0x30: /* CGFR R1,R2 [RRE] */ @@ -3754,6 +5547,8 @@ index 0000000..e477389 + if (op == 0x30) tcg_gen_ext32s_i64(tmp2, tmp2); + tmp = load_reg(r1); + cmp_s64(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x21: /* CLGR R1,R2 [RRE] */ + case 0x31: /* CLGFR R1,R2 [RRE] */ @@ -3761,16 +5556,20 @@ index 0000000..e477389 + if (op == 0x31) tcg_gen_ext32u_i64(tmp2, tmp2); + tmp = load_reg(r1); + cmp_u64(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x26: /* LBR R1,R2 [RRE] */ + tmp2 = load_reg32(r2); + tcg_gen_ext8s_i32(tmp2, tmp2); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x27: /* LHR R1,R2 [RRE] */ + tmp2 = load_reg32(r2); + tcg_gen_ext16s_i32(tmp2, tmp2); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp2); + break; + case 0x80: /* NGR R1,R2 [RRE] */ + case 0x81: /* OGR R1,R2 [RRE] */ @@ -3785,26 +5584,34 @@ index 0000000..e477389 + } + store_reg(r1, tmp); + set_cc_nz_u64(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x83: /* FLOGR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + tmp = tcg_const_i32(r1); + gen_helper_flogr(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x84: /* LLGCR R1,R2 [RRE] */ + tmp = load_reg(r2); + tcg_gen_andi_i64(tmp, tmp, 0xff); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x85: /* LLGHR R1,R2 [RRE] */ + tmp = load_reg(r2); + tcg_gen_andi_i64(tmp, tmp, 0xffff); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x87: /* DLGR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = load_reg(r2); + gen_helper_dlg(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x88: /* ALCGR R1,R2 [RRE] */ + tmp = load_reg(r1); @@ -3816,47 +5623,57 @@ index 0000000..e477389 + tcg_gen_add_i64(tmp3, tmp, tmp3); + store_reg(r1, tmp3); + gen_helper_set_cc_addc_u64(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x89: /* SLBGR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + tmp3 = tcg_const_i32(r1); + gen_helper_slbg(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x94: /* LLCR R1,R2 [RRE] */ + tmp = load_reg32(r2); + tcg_gen_andi_i32(tmp, tmp, 0xff); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x95: /* LLHR R1,R2 [RRE] */ + tmp = load_reg32(r2); + tcg_gen_andi_i32(tmp, tmp, 0xffff); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x98: /* ALCR R1,R2 [RRE] */ + tmp = tcg_const_i32(r1); + tmp2 = load_reg32(r2); + gen_helper_addc_u32(cc, cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x99: /* SLBR R1,R2 [RRE] */ + tmp = load_reg32(r1); + tmp2 = load_reg32(r2); + tmp3 = tcg_const_i32(r1); + gen_helper_slb(cc, cc, tmp3, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + default: + LOG_DISAS("illegal b9 operation 0x%x\n", op); + gen_illegal_opcode(s); + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + +static void disas_c0(DisasContext *s, int op, int r1, int i2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + LOG_DISAS("disas_c0: op 0x%x r1 %d i2 %d\n", op, r1, i2); + uint64_t target = s->pc + i2 * 2; + /* FIXME: huh? */ target &= 0xffffffff; @@ -3864,10 +5681,12 @@ index 0000000..e477389 + case 0: /* larl r1, i2 */ + tmp = tcg_const_i64(target); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x1: /* LGFI R1,I2 [RIL] */ + tmp = tcg_const_i64((int64_t)i2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0x4: /* BRCL M1,I2 [RIL] */ + tmp = tcg_const_i32(r1); /* aka m1 */ @@ -3875,6 +5694,9 @@ index 0000000..e477389 + tmp3 = tcg_const_i64(i2 * 2); + gen_helper_brcl(cc, tmp, tmp2, tmp3); + s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x5: /* brasl r1, i2 */ + tmp = tcg_const_i64(s->pc + 6); @@ -3882,6 +5704,7 @@ index 0000000..e477389 + tmp = tcg_const_i64(target); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); + s->is_jmp = DISAS_JUMP; ++ tcg_temp_free(tmp); + break; + case 0x7: /* XILF R1,I2 [RIL] */ + case 0xb: /* NILF R1,I2 [RIL] */ @@ -3896,10 +5719,12 @@ index 0000000..e477389 + store_reg32(r1, tmp); + tcg_gen_trunc_i64_i32(tmp, tmp); + set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); + break; + case 0x9: /* IILF R1,I2 [RIL] */ + tmp = tcg_const_i32((uint32_t)i2); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0xa: /* NIHF R1,I2 [RIL] */ + tmp = load_reg(r1); @@ -3911,28 +5736,28 @@ index 0000000..e477389 + tcg_gen_shr_i64(tmp, tmp, 32); + tcg_gen_trunc_i64_i32(tmp, tmp); + set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); + break; + case 0xe: /* LLIHF R1,I2 [RIL] */ + tmp = tcg_const_i64(((uint64_t)(uint32_t)i2) << 32); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + case 0xf: /* LLILF R1,I2 [RIL] */ + tmp = tcg_const_i64((uint32_t)i2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); + break; + default: + LOG_DISAS("illegal c0 operation 0x%x\n", op); + gen_illegal_opcode(s); + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + +static void disas_c2(DisasContext *s, int op, int r1, int i2) +{ -+ TCGv tmp = 0, tmp2 = 0, tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + switch (op) { + case 0x4: /* SLGFI R1,I2 [RIL] */ + case 0xa: /* ALGFI R1,I2 [RIL] */ @@ -3951,6 +5776,9 @@ index 0000000..e477389 + default: tcg_abort(); + } + store_reg(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0x5: /* SLFI R1,I2 [RIL] */ + case 0xb: /* ALFI R1,I2 [RIL] */ @@ -3969,14 +5797,19 @@ index 0000000..e477389 + default: tcg_abort(); + } + store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + break; + case 0xc: /* CGFI R1,I2 [RIL] */ + tmp = load_reg(r1); + cmp_s64c(tmp, (int64_t)i2); ++ tcg_temp_free(tmp); + break; + case 0xe: /* CLGFI R1,I2 [RIL] */ + tmp = load_reg(r1); + cmp_u64c(tmp, (uint64_t)(uint32_t)i2); ++ tcg_temp_free(tmp); + break; + case 0xd: /* CFI R1,I2 [RIL] */ + case 0xf: /* CLFI R1,I2 [RIL] */ @@ -3986,19 +5819,25 @@ index 0000000..e477389 + case 0xf: cmp_u32c(tmp, i2); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); + break; + default: + LOG_DISAS("illegal c2 operation 0x%x\n", op); + gen_illegal_opcode(s); + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + -+static inline uint64_t ld_code2(uint64_t pc) { return (uint64_t)lduw_code(pc); } -+static inline uint64_t ld_code4(uint64_t pc) { return (uint64_t)ldl_code(pc); } ++static inline uint64_t ld_code2(uint64_t pc) ++{ ++ return (uint64_t)lduw_code(pc); ++} ++ ++static inline uint64_t ld_code4(uint64_t pc) ++{ ++ return (uint64_t)ldl_code(pc); ++} ++ +static inline uint64_t ld_code6(uint64_t pc) +{ + uint64_t opc; @@ -4009,7 +5848,7 @@ index 0000000..e477389 + +static void disas_s390_insn(CPUState *env, DisasContext *s) +{ -+ TCGv tmp = 0,tmp2 = 0,tmp3 = 0; ++ TCGv tmp, tmp2, tmp3; + unsigned char opc; + uint64_t insn; + int op, r1, r2, r3, d1, d2, x2, b1, b2, i, i2, r1b; @@ -4033,6 +5872,9 @@ index 0000000..e477389 + d2 = insn & 0xfff; \ + tmp = get_address(x2, b2, d2); + ++#define FREE_RX \ ++ tcg_temp_free(tmp); ++ +#define FETCH_DECODE_RS \ + insn = ld_code4(s->pc); \ + DEBUGINSN \ @@ -4048,6 +5890,9 @@ index 0000000..e477389 + d1 = insn & 0xfff; \ + tmp = get_address(0, b1, d1); + ++#define FREE_SI \ ++ tcg_temp_free(tmp); ++ + switch (opc) { + case 0x7: /* BCR M1,R2 [RR] */ + FETCH_DECODE_RR @@ -4066,6 +5911,7 @@ index 0000000..e477389 + i = insn & 0xff; + tmp = tcg_const_i64(s->pc); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, psw.addr)); ++ tcg_temp_free(tmp); + s->is_jmp = DISAS_SVC; + s->pc += 2; + break; @@ -4076,8 +5922,10 @@ index 0000000..e477389 + if (r2) { + tmp2 = load_reg(r2); + tcg_gen_st_i64(tmp2, cpu_env, offsetof(CPUState, psw.addr)); ++ tcg_temp_free(tmp2); + s->is_jmp = DISAS_JUMP; + } ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x10: /* LPR R1,R2 [RR] */ @@ -4085,6 +5933,8 @@ index 0000000..e477389 + tmp2 = load_reg32(r2); + tmp = tcg_const_i32(r1); + gen_helper_abs_i32(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 2; + break; + case 0x11: /* LNR R1,R2 [RR] */ @@ -4092,6 +5942,8 @@ index 0000000..e477389 + tmp2 = load_reg32(r2); + tmp = tcg_const_i32(r1); + gen_helper_nabs_i32(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 2; + break; + case 0x12: /* LTR R1,R2 [RR] */ @@ -4099,6 +5951,7 @@ index 0000000..e477389 + tmp = load_reg32(r2); + if (r1 != r2) store_reg32(r1, tmp); + set_cc_s32(tmp); ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x13: /* LCR R1,R2 [RR] */ @@ -4107,6 +5960,7 @@ index 0000000..e477389 + tcg_gen_neg_i32(tmp, tmp); + store_reg32(r1, tmp); + gen_helper_set_cc_comp_s32(cc, tmp); ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x14: /* NR R1,R2 [RR] */ @@ -4123,12 +5977,15 @@ index 0000000..e477389 + } + store_reg32(r1, tmp); + set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 2; + break; + case 0x18: /* LR R1,R2 [RR] */ + FETCH_DECODE_RR + tmp = load_reg32(r2); + store_reg32(r1, tmp); ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x15: /* CLR R1,R2 [RR] */ @@ -4142,6 +5999,8 @@ index 0000000..e477389 + default: tcg_abort(); + } + s->pc += 2; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x1a: /* AR R1,R2 [RR] */ + case 0x1e: /* ALR R1,R2 [RR] */ @@ -4156,6 +6015,9 @@ index 0000000..e477389 + case 0x1e: gen_helper_set_cc_addu32(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 2; + break; + case 0x1b: /* SR R1,R2 [RR] */ @@ -4171,42 +6033,54 @@ index 0000000..e477389 + case 0x1f: gen_helper_set_cc_subu32(cc, tmp, tmp2, tmp3); break; + default: tcg_abort(); + } ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 2; + break; + case 0x28: /* LDR R1,R2 [RR] */ + FETCH_DECODE_RR + tmp = load_freg(r2); + store_freg(r1, tmp); ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x38: /* LER R1,R2 [RR] */ + FETCH_DECODE_RR + tmp = load_freg32(r2); + store_freg32(r1, tmp); ++ tcg_temp_free(tmp); + s->pc += 2; + break; + case 0x40: /* STH R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX + tmp2 = load_reg32(r1); + tcg_gen_qemu_st16(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x41: /* la */ + FETCH_DECODE_RX + store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */ ++ FREE_RX + s->pc += 4; + break; + case 0x42: /* STC R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX + tmp2 = load_reg32(r1); + tcg_gen_qemu_st8(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x43: /* IC R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); + store_reg8(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x44: /* EX R1,D2(X2,B2) [RX] */ @@ -4214,6 +6088,9 @@ index 0000000..e477389 + tmp2 = load_reg(r1); + tmp3 = tcg_const_i64(s->pc + 4); + gen_helper_ex(cc, cc, tmp2, tmp, tmp3); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0x47: /* BC M1,D2(X2,B2) [RX] */ @@ -4222,30 +6099,39 @@ index 0000000..e477389 + tmp2 = tcg_const_i32(r1); /* aka m1 */ + tmp3 = tcg_const_i64(s->pc); + gen_helper_bc(cc, tmp2, tmp, tmp3); ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->is_jmp = DISAS_JUMP; + s->pc += 4; + break; + case 0x48: /* LH R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, 1); + store_reg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x49: /* CH R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg32(r1); + cmp_s32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x4a: /* AH R1,D2(X2,B2) [RX] */ + case 0x4b: /* SH R1,D2(X2,B2) [RX] */ + case 0x4c: /* MH R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg32(r1); + tmp3 = tcg_temp_new_i32(); + switch (opc) { @@ -4263,6 +6149,9 @@ index 0000000..e477389 + default: tcg_abort(); + } + store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0x50: /* st r1, d2(x2, b2) */ @@ -4270,21 +6159,27 @@ index 0000000..e477389 + tmp2 = load_reg32(r1); + tcg_gen_qemu_st32(tmp2, tmp, 1); + s->pc += 4; ++ FREE_RX ++ tcg_temp_free(tmp2); + break; + case 0x55: /* CL R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg32(r1); + cmp_u32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x54: /* N R1,D2(X2,B2) [RX] */ + case 0x56: /* O R1,D2(X2,B2) [RX] */ + case 0x57: /* X R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg32(r1); + switch (opc) { + case 0x54: tcg_gen_and_i32(tmp, tmp, tmp2); break; @@ -4294,21 +6189,28 @@ index 0000000..e477389 + } + store_reg32(r1, tmp); + set_cc_nz_u32(tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x58: /* l r1, d2(x2, b2) */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); + store_reg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x59: /* C R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg32(r1); + cmp_s32(tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x5a: /* A R1,D2(X2,B2) [RX] */ @@ -4332,12 +6234,17 @@ index 0000000..e477389 + case 0x5f: gen_helper_set_cc_subu32(cc, tmp2, tmp, tmp3); break; + default: tcg_abort(); + } ++ FREE_RX ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0x60: /* STD R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX + tmp2 = load_freg(r1); + tcg_gen_qemu_st64(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x68: /* LD R1,D2(X2,B2) [RX] */ @@ -4345,28 +6252,37 @@ index 0000000..e477389 + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, 1); + store_freg(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x70: /* STE R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX + tmp2 = load_freg32(r1); + tcg_gen_qemu_st32(tmp2, tmp, 1); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x71: /* MS R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, tmp, 1); ++ FREE_RX + tmp = load_reg(r1); + tcg_gen_mul_i32(tmp, tmp, tmp2); + store_reg(r1, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x78: /* LE R1,D2(X2,B2) [RX] */ + FETCH_DECODE_RX -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); + store_freg32(r1, tmp2); ++ FREE_RX ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x88: /* SRL R1,D2(B2) [RS] */ @@ -4385,26 +6301,33 @@ index 0000000..e477389 + store_reg32(r1, tmp2); + if (opc == 0x8a) set_cc_s32(tmp2); + s->pc += 4; ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + case 0x91: /* TM D1(B1),I2 [SI] */ + FETCH_DECODE_SI -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); ++ FREE_SI + tmp = tcg_const_i32(i2); + gen_helper_tm(cc, tmp2, tmp); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x92: /* MVI D1(B1),I2 [SI] */ + FETCH_DECODE_SI + tmp2 = tcg_const_i32(i2); + tcg_gen_qemu_st8(tmp2, tmp, 1); ++ FREE_SI ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x94: /* NI D1(B1),I2 [SI] */ + case 0x96: /* OI D1(B1),I2 [SI] */ + case 0x97: /* XI D1(B1),I2 [SI] */ + FETCH_DECODE_SI -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); + switch (opc) { + case 0x94: tcg_gen_andi_i32(tmp2, tmp2, i2); break; @@ -4414,13 +6337,17 @@ index 0000000..e477389 + } + tcg_gen_qemu_st8(tmp2, tmp, 1); + set_cc_nz_u32(tmp2); ++ FREE_SI ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x95: /* CLI D1(B1),I2 [SI] */ + FETCH_DECODE_SI -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, 1); + cmp_u32c(tmp2, i2); ++ FREE_SI ++ tcg_temp_free(tmp2); + s->pc += 4; + break; + case 0x9b: /* STAM R1,R3,D2(B2) [RS] */ @@ -4429,6 +6356,9 @@ index 0000000..e477389 + tmp2 = get_address(0, b2, d2); + tmp3 = tcg_const_i32(r3); + gen_helper_stam(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xa5: @@ -4453,6 +6383,9 @@ index 0000000..e477389 + tmp3 = tcg_const_i32(r3); + tmp2 = get_address(0, b2, d2); + gen_helper_mvcle(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xa9: /* CLCLE R1,R3,D2(B2) [RS] */ @@ -4461,6 +6394,9 @@ index 0000000..e477389 + tmp3 = tcg_const_i32(r3); + tmp2 = get_address(0, b2, d2); + gen_helper_clcle(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xb2: @@ -4474,6 +6410,8 @@ index 0000000..e477389 + tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, fpc)); + tmp2 = get_address(0, b2, d2); + tcg_gen_qemu_st32(tmp, tmp2, 1); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + break; + default: + r1 = (insn >> 4) & 0xf; @@ -4506,6 +6444,9 @@ index 0000000..e477389 + tmp2 = get_address(0, b2, d2); + tmp3 = tcg_const_i32(r3); + gen_helper_cs(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xbd: /* CLM R1,M3,D2(B2) [RS] */ @@ -4514,6 +6455,9 @@ index 0000000..e477389 + tmp2 = tcg_const_i32(r3); /* aka m3 */ + tmp = load_reg32(r1); + gen_helper_clm(cc, tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xbe: /* STCM R1,M3,D2(B2) [RS] */ @@ -4522,17 +6466,23 @@ index 0000000..e477389 + tmp2 = tcg_const_i32(r3); /* aka m3 */ + tmp = load_reg32(r1); + gen_helper_stcm(tmp, tmp2, tmp3); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + s->pc += 4; + break; + case 0xbf: /* ICM R1,M3,D2(B2) [RS] */ + FETCH_DECODE_RS + if (r3 == 15) { /* effectively a 32-bit load */ + tmp = get_address(0, b2, d2); -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, 1); + store_reg32(r1, tmp2); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32(r3); + gen_helper_set_cc_icm(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); + } + else if (r3) { + uint32_t mask = 0x00ffffffUL; @@ -4540,7 +6490,7 @@ index 0000000..e477389 + int m3 = r3; + tmp3 = load_reg32(r1); + tmp = get_address(0, b2, d2); -+ tmp2 = tcg_temp_new_i32(); ++ tmp2 = tcg_temp_new_i64(); + while (m3) { + if (m3 & 8) { + tcg_gen_qemu_ld8u(tmp2, tmp, 1); @@ -4554,12 +6504,17 @@ index 0000000..e477389 + shift -= 8; + } + store_reg32(r1, tmp3); ++ tcg_temp_free(tmp); + tmp = tcg_const_i32(r3); + gen_helper_set_cc_icm(cc, tmp, tmp2); ++ tcg_temp_free(tmp); ++ tcg_temp_free(tmp2); ++ tcg_temp_free(tmp3); + } + else { + tmp = tcg_const_i32(0); + gen_helper_set_cc_icm(cc, tmp, tmp); /* i.e. env->cc = 0 */ ++ tcg_temp_free(tmp); + } + s->pc += 4; + break; @@ -4634,12 +6589,9 @@ index 0000000..e477389 + s->pc += 6; + break; + } -+ if (tmp) tcg_temp_free(tmp); -+ if (tmp2) tcg_temp_free(tmp2); -+ if (tmp3) tcg_temp_free(tmp3); +} + -+static always_inline void gen_intermediate_code_internal (CPUState *env, ++static inline void gen_intermediate_code_internal (CPUState *env, + TranslationBlock *tb, + int search_pc) +{ @@ -4656,6 +6608,7 @@ index 0000000..e477389 + dc.env = env; + dc.pc = pc_start; + dc.is_jmp = DISAS_NEXT; ++ dc.tb = tb; + + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + @@ -4667,12 +6620,11 @@ index 0000000..e477389 + max_insns = CF_COUNT_MASK; + + gen_icount_start(); -+#if 1 ++ ++ /* using a temp for the condition code allows TCG to optimize away ++ any condition code calculations that are not actually used */ + cc = tcg_temp_local_new_i32(); + tcg_gen_mov_i32(cc, global_cc); -+#else -+ cc = global_cc; -+#endif + do { + if (search_pc) { + j = gen_opc_ptr - gen_opc_buf; @@ -4694,9 +6646,13 @@ index 0000000..e477389 + disas_s390_insn(env, &dc); + + num_insns++; -+ } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start && num_insns < max_insns); -+ tcg_gen_mov_i32(global_cc, cc); -+ tcg_temp_free(cc); ++ } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start ++ && num_insns < max_insns && !env->singlestep_enabled); ++ ++ if (dc.is_jmp != DISAS_TB_JUMP) { ++ tcg_gen_mov_i32(global_cc, cc); ++ tcg_temp_free(cc); ++ } + + if (!dc.is_jmp) { + tcg_gen_st_i64(tcg_const_i64(dc.pc), cpu_env, offsetof(CPUState, psw.addr)); @@ -4711,7 +6667,9 @@ index 0000000..e477389 + if (tb->cflags & CF_LAST_IO) + gen_io_end(); + /* Generate the return instruction */ -+ tcg_gen_exit_tb(0); ++ if (dc.is_jmp != DISAS_TB_JUMP) { ++ tcg_gen_exit_tb(0); ++ } + gen_icount_end(tb, num_insns); + *gen_opc_ptr = INDEX_op_end; + if (search_pc) { @@ -4733,21 +6691,77 @@ index 0000000..e477389 +#endif +} + -+void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) -+{ + void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) + { + gen_intermediate_code_internal(env, tb, 0); -+} -+ -+void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) -+{ + } + + void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) + { + gen_intermediate_code_internal(env, tb, 1); + } + + void gen_pc_load(CPUState *env, TranslationBlock *tb, +diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h +index 207a89f..f5de104 100644 +--- a/tcg/tcg-op.h ++++ b/tcg/tcg-op.h +@@ -366,6 +366,18 @@ static inline void tcg_gen_br(int label) + tcg_gen_op1i(INDEX_op_br, label); + } + ++static inline void tcg_gen_sync_i32(TCGv_i32 arg) ++{ ++ tcg_gen_op1_i32(INDEX_op_sync_i32, arg); +} + -+void gen_pc_load(CPUState *env, TranslationBlock *tb, -+ unsigned long searched_pc, int pc_pos, void *puc) ++#if TCG_TARGET_REG_BITS == 64 ++static inline void tcg_gen_sync_i64(TCGv_i64 arg) +{ -+ env->psw.addr = gen_opc_pc[pc_pos]; ++ tcg_gen_op1_i64(INDEX_op_sync_i64, arg); +} ++#endif ++ + static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg) + { + if (!TCGV_EQUAL_I32(ret, arg)) +diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h +index 2c7ca1a..938b1a0 100644 +--- a/tcg/tcg-opc.h ++++ b/tcg/tcg-opc.h +@@ -41,6 +41,7 @@ DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */ + DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) + DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) + ++DEF(sync_i32, 0, 1, 0, 0) + DEF(mov_i32, 1, 1, 0, 0) + DEF(movi_i32, 1, 0, 1, 0) + DEF(setcond_i32, 1, 2, 1, 0) +@@ -131,6 +132,7 @@ DEF(nor_i32, 1, 2, 0, 0) + #endif + + #if TCG_TARGET_REG_BITS == 64 ++DEF(sync_i64, 0, 1, 0, 0) + DEF(mov_i64, 1, 1, 0, 0) + DEF(movi_i64, 1, 0, 1, 0) + DEF(setcond_i64, 1, 2, 1, 0) +diff --git a/tcg/tcg.c b/tcg/tcg.c +index 5dd6a2c..a75772a 100644 +--- a/tcg/tcg.c ++++ b/tcg/tcg.c +@@ -2022,6 +2022,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, + // dump_regs(s); + #endif + switch(opc) { ++ case INDEX_op_sync_i32: ++#if TCG_TARGET_REG_BITS == 64 ++ case INDEX_op_sync_i64: ++#endif ++ temp_save(s, args[0], s->reserved_regs); ++ break; + case INDEX_op_mov_i32: + #if TCG_TARGET_REG_BITS == 64 + case INDEX_op_mov_i64: -- -1.6.2.1 +1.7.1 diff --git a/0015-pcap-network-emulation.patch b/0015-pcap-network-emulation.patch deleted file mode 100644 index a8eeb9f8..00000000 --- a/0015-pcap-network-emulation.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 99759e033ea960b86828657682f8382538c4ccb7 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Tue, 14 Apr 2009 16:52:51 +0200 -Subject: [PATCH 15/33] pcap network emulation - -Implements network emulation using libpcap; useful for direct Ethernet access. - -Signed-off-by: Ulrich Hecht ---- - Makefile.target | 3 ++ - configure | 7 ++++ - net.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - qemu-options.hx | 4 ++ - 4 files changed, 122 insertions(+), 0 deletions(-) - -diff --git a/Makefile.target b/Makefile.target -index f9cd42a..9c9304c 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -618,6 +618,9 @@ endif - ifdef CONFIG_SLIRP - CPPFLAGS+=-I$(SRC_PATH)/slirp - endif -+ifdef CONFIG_PCAP -+LIBS+=-lpcap -+endif - - # specific flags are needed for non soft mmu emulator - ifdef CONFIG_STATIC -diff --git a/configure b/configure -index cac4198..4ce7bc1 100755 ---- a/configure -+++ b/configure -@@ -169,6 +169,7 @@ mingw32="no" - EXESUF="" - slirp="yes" - vde="yes" -+pcap="yes" - fmod_lib="" - fmod_inc="" - oss_lib="" -@@ -432,6 +433,8 @@ for opt do - ;; - --disable-vde) vde="no" - ;; -+ --disable-pcap) pcap="no" -+ ;; - --disable-kqemu) kqemu="no" - ;; - --disable-xen) xen="no" -@@ -1598,6 +1601,10 @@ if test "$vde" = "yes" ; then - echo "#define CONFIG_VDE 1" >> $config_host_h - echo "VDE_LIBS=-lvdeplug" >> $config_host_mak - fi -+if test "$pcap" = "yes" ; then -+ echo "CONFIG_PCAP=yes" >> $config_host_mak -+ echo "#define CONFIG_PCAP 1" >> $config_host_h -+fi - for card in $audio_card_list; do - def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` - echo "$def=y" >> $config_host_mak -diff --git a/net.c b/net.c -index 3d3829d..595f7bc 100644 ---- a/net.c -+++ b/net.c -@@ -1264,6 +1264,105 @@ void do_info_usernet(Monitor *mon) - - #endif /* CONFIG_SLIRP */ - -+#if defined(CONFIG_PCAP) -+#include -+typedef struct PCAPState { -+ VLANClientState *vc; -+ pcap_t *handle; -+} PCAPState; -+ -+static ssize_t pcap_receive(VLANClientState *vc, const uint8_t *buf, size_t size) -+{ -+ PCAPState *s = (PCAPState *)(vc->opaque); -+ -+ pcap_sendpacket(s->handle, (u_char*)buf, size); -+ return size; -+} -+ -+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata) -+{ -+ VLANClientState *vc = (VLANClientState *)user; -+ -+ qemu_send_packet(vc, pdata, phdr->len); -+} -+ -+static void pcap_send(void *opaque) -+{ -+ PCAPState *s = (PCAPState *)opaque; -+ -+ pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_char *)s->vc); -+} -+ -+static int net_pcap_init(VLANState *vlan, const char *model, const char *name, char *ifname) -+{ -+ PCAPState *s; -+ char errbuf[PCAP_ERRBUF_SIZE]; -+ int fd; -+ -+ s = qemu_mallocz(sizeof(PCAPState)); -+ if (!s) -+ return -1; -+ -+ if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) { -+ fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf); -+ goto fail; -+ } -+ -+ /* Attempt to connect device. */ -+ s->handle = (void*)pcap_open_live(ifname, 65535, 1, 0, errbuf); -+ if (!s->handle) { -+ fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf); -+ goto fail; -+ } -+ -+ /* Check non-blocking mode. */ -+ if (pcap_setnonblock(s->handle, 1, errbuf) < 0) { -+ fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf); -+ goto fail; -+ } -+ -+#if defined(BIOCSHDRCMPLT) -+ /* -+ * Tell the kernel that the header is fully-formed when it gets it. -+ * This is required in order to fake the src address. -+ */ -+ { -+ unsigned int one = 1; -+ ioctl(pcap_fileno(s->handle), BIOCSHDRCMPLT, &one); -+ } -+#endif /* BIOCSHDRCMPLT */ -+ -+#if defined(BIOCIMMEDIATE) -+ /* -+ * Tell the kernel that the packet has to be processed immediately. -+ */ -+ { -+ unsigned int one = 1; -+ ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one); -+ } -+#endif /* BIOCIMMEDIATE */ -+ -+ s->vc = qemu_new_vlan_client(vlan, model, name, NULL, pcap_receive, NULL, NULL, s); -+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector"); -+ if ((fd = pcap_get_selectable_fd(s->handle)) < 0) { -+ fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n"); -+ goto fail; -+ } -+ qemu_set_fd_handler(fd, pcap_send, NULL, s); -+ -+ return 0; -+ -+fail: -+ if (s) { -+ if (s->handle) -+ pcap_close(s->handle); -+ qemu_free(s); -+ } -+ -+ return -1; -+} -+#endif /* CONFIG_PCAP */ -+ - #if !defined(_WIN32) - - typedef struct TAPState { -@@ -2631,6 +2730,15 @@ int net_client_init(Monitor *mon, const char *device, const char *p) - ret = 0; - } else - #endif -+#ifdef CONFIG_PCAP -+ if (!strcmp(device, "pcap")) { -+ char ifname[64]; -+ if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) -+ ret = net_pcap_init(vlan, device, name, NULL); -+ else -+ ret = net_pcap_init(vlan, device, name, ifname); -+ } else -+#endif - #ifdef _WIN32 - if (!strcmp(device, "tap")) { - static const char * const tap_params[] = { -diff --git a/qemu-options.hx b/qemu-options.hx -index a58287c..4d46d6c 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -801,6 +801,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, - " default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n" - #endif - #endif -+#ifdef CONFIG_PCAP -+ "-net pcap[,vlan=n][,ifname=name]\n" -+ " connect the host network interface using PCAP to VLAN 'n'\n" -+#endif - "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n" - " connect the vlan 'n' to another VLAN using a socket connection\n" - "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n" --- -1.6.2.1 - diff --git a/0016-fix-mipsn32-linux-user-builds.patch b/0016-fix-mipsn32-linux-user-builds.patch new file mode 100644 index 00000000..9398885e --- /dev/null +++ b/0016-fix-mipsn32-linux-user-builds.patch @@ -0,0 +1,58 @@ +From 4569b209989e09bdebcb6cce809b3fed0f94142c Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Wed, 25 Aug 2010 14:23:43 +0200 +Subject: [PATCH 16/17] fix mipsn32*-linux-user builds + +Signed-off-by: Ulrich Hecht +--- + configure | 2 ++ + default-configs/mipsn32-linux-user.mak | 1 + + default-configs/mipsn32el-linux-user.mak | 1 + + linux-user/mipsn32/syscall.h | 3 ++- + 4 files changed, 6 insertions(+), 1 deletions(-) + create mode 100644 default-configs/mipsn32-linux-user.mak + create mode 100644 default-configs/mipsn32el-linux-user.mak + +diff --git a/configure b/configure +index bd1484b..6513d91 100755 +--- a/configure ++++ b/configure +@@ -1010,6 +1010,8 @@ m68k-linux-user \ + microblaze-linux-user \ + mips-linux-user \ + mipsel-linux-user \ ++mipsn32-linux-user \ ++mipsn32el-linux-user \ + ppc-linux-user \ + ppc64-linux-user \ + ppc64abi32-linux-user \ +diff --git a/default-configs/mipsn32-linux-user.mak b/default-configs/mipsn32-linux-user.mak +new file mode 100644 +index 0000000..31df570 +--- /dev/null ++++ b/default-configs/mipsn32-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for mips-linux-user +diff --git a/default-configs/mipsn32el-linux-user.mak b/default-configs/mipsn32el-linux-user.mak +new file mode 100644 +index 0000000..4d0e4af +--- /dev/null ++++ b/default-configs/mipsn32el-linux-user.mak +@@ -0,0 +1 @@ ++# Default configuration for mipsel-linux-user +diff --git a/linux-user/mipsn32/syscall.h b/linux-user/mipsn32/syscall.h +index 4ec506c..beeeb3c 100644 +--- a/linux-user/mipsn32/syscall.h ++++ b/linux-user/mipsn32/syscall.h +@@ -216,6 +216,7 @@ struct target_pt_regs { + #undef TARGET_ENOTRECOVERABLE + #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */ + +- ++/* Nasty hack: define a fake errno value for use by sigreturn. */ ++#define TARGET_QEMU_ESIGRETURN 255 + + #define UNAME_MACHINE "mips64" +-- +1.7.1 + diff --git a/0017-S-390-build-fix.patch b/0017-S-390-build-fix.patch new file mode 100644 index 00000000..cc7f3935 --- /dev/null +++ b/0017-S-390-build-fix.patch @@ -0,0 +1,129 @@ +From 024f781ab4af31ba5e14882b5661d4586ae26988 Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht +Date: Wed, 9 Feb 2011 18:35:21 +0100 +Subject: [PATCH 17/17] S/390 build fix + +--- + target-s390x/op_helper.c | 22 +++++++++++----------- + target-s390x/translate.c | 2 +- + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c +index 20c83c5..46b71fc 100644 +--- a/target-s390x/op_helper.c ++++ b/target-s390x/op_helper.c +@@ -738,7 +738,7 @@ uint32_t HELPER(tmxx)(uint64_t val, uint32_t mask) + uint32_t HELPER(abs_i32)(uint32_t reg, int32_t val) + { + uint32_t cc; +- if (val == 0x80000000UL) cc = 3; ++ if ((uint32_t)val == 0x80000000UL) cc = 3; + else if (val) cc = 1; + else cc = 0; + +@@ -996,7 +996,7 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2) + /* condition codes for binary FP ops */ + static uint32_t set_cc_f32(float32 v1, float32 v2) + { +- if (float32_is_nan(v1) || float32_is_nan(v2)) return 3; ++ if (float32_is_any_nan(v1) || float32_is_any_nan(v2)) return 3; + else if (float32_eq(v1, v2, &env->fpu_status)) return 0; + else if (float32_lt(v1, v2, &env->fpu_status)) return 1; + else return 2; +@@ -1004,7 +1004,7 @@ static uint32_t set_cc_f32(float32 v1, float32 v2) + + static uint32_t set_cc_f64(float64 v1, float64 v2) + { +- if (float64_is_nan(v1) || float64_is_nan(v2)) return 3; ++ if (float64_is_any_nan(v1) || float64_is_any_nan(v2)) return 3; + else if (float64_eq(v1, v2, &env->fpu_status)) return 0; + else if (float64_lt(v1, v2, &env->fpu_status)) return 1; + else return 2; +@@ -1013,7 +1013,7 @@ static uint32_t set_cc_f64(float64 v1, float64 v2) + /* condition codes for unary FP ops */ + static uint32_t set_cc_nz_f32(float32 v) + { +- if (float32_is_nan(v)) return 3; ++ if (float32_is_any_nan(v)) return 3; + else if (float32_is_zero(v)) return 0; + else if (float32_is_neg(v)) return 1; + else return 2; +@@ -1021,7 +1021,7 @@ static uint32_t set_cc_nz_f32(float32 v) + + static uint32_t set_cc_nz_f64(float64 v) + { +- if (float64_is_nan(v)) return 3; ++ if (float64_is_any_nan(v)) return 3; + else if (float64_is_zero(v)) return 0; + else if (float64_is_neg(v)) return 1; + else return 2; +@@ -1029,7 +1029,7 @@ static uint32_t set_cc_nz_f64(float64 v) + + static uint32_t set_cc_nz_f128(float128 v) + { +- if (float128_is_nan(v)) return 3; ++ if (float128_is_any_nan(v)) return 3; + else if (float128_is_zero(v)) return 0; + else if (float128_is_neg(v)) return 1; + else return 2; +@@ -1350,7 +1350,7 @@ uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2) + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; +- if (float128_is_nan(v1.q) || float128_is_nan(v2.q)) return 3; ++ if (float128_is_any_nan(v1.q) || float128_is_any_nan(v2.q)) return 3; + else if (float128_eq(v1.q, v2.q, &env->fpu_status)) return 0; + else if (float128_lt(v1.q, v2.q, &env->fpu_status)) return 1; + else return 2; +@@ -1463,7 +1463,7 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3) + v2.ll.lower = env->fregs[f2 + 2].ll; + set_round_mode(m3); + env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); +- if (float128_is_nan(v2.q)) return 3; ++ if (float128_is_any_nan(v2.q)) return 3; + else if (float128_is_zero(v2.q)) return 0; + else if (float128_is_neg(v2.q)) return 1; + else return 2; +@@ -1611,7 +1611,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2) + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); + if (float32_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float32_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float32_is_quiet_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +@@ -1627,7 +1627,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2) + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); + if (float64_is_zero(v1) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float64_is_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float64_is_quiet_nan(v1) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +@@ -1645,7 +1645,7 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2) + int neg = float128_is_neg(v1.q); + if (float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) cc = 1; + else if (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) cc = 1; +- else if (float128_is_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; ++ else if (float128_is_quiet_nan(v1.q) && (m2 & (1 << (3-neg)))) cc = 1; + else if (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg)))) cc = 1; + else /* assume normalized number */ if (m2 & (1 << (9-neg))) cc = 1; + /* FIXME: denormalized? */ +diff --git a/target-s390x/translate.c b/target-s390x/translate.c +index e08dcf4..189a60b 100644 +--- a/target-s390x/translate.c ++++ b/target-s390x/translate.c +@@ -67,7 +67,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, + } + } + for (i = 0; i < 16; i++) { +- cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].i); ++ cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].ll); + if ((i % 4) == 3) { + cpu_fprintf(f, "\n"); + } else { +-- +1.7.1 + diff --git a/0018-qemu-0.11-git-user-linux-ppc-uid16_fix.patch b/0018-qemu-0.11-git-user-linux-ppc-uid16_fix.patch deleted file mode 100644 index c0be7ea9..00000000 --- a/0018-qemu-0.11-git-user-linux-ppc-uid16_fix.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 015bd9be8314b3ce6d97d1bc9614874aee9b0e52 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Wed, 17 Jun 2009 15:08:38 +0200 -Subject: [PATCH 18/33] qemu-0.11-git-user-linux-ppc-uid16_fix - ---- - linux-user/ppc/syscall_nr.h | 30 +++++++++++++++--------------- - linux-user/syscall_defs.h | 2 +- - 2 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h -index f54276b..cc84a4c 100644 ---- a/linux-user/ppc/syscall_nr.h -+++ b/linux-user/ppc/syscall_nr.h -@@ -17,15 +17,15 @@ - #define TARGET_NR_time 13 - #define TARGET_NR_mknod 14 - #define TARGET_NR_chmod 15 --#define TARGET_NR_lchown32 16 -+#define TARGET_NR_lchown 16 - #define TARGET_NR_break 17 - #define TARGET_NR_oldstat 18 - #define TARGET_NR_lseek 19 - #define TARGET_NR_getpid 20 - #define TARGET_NR_mount 21 - #define TARGET_NR_umount 22 --#define TARGET_NR_setuid32 23 --#define TARGET_NR_getuid32 24 -+#define TARGET_NR_setuid 23 -+#define TARGET_NR_getuid 24 - #define TARGET_NR_stime 25 - #define TARGET_NR_ptrace 26 - #define TARGET_NR_alarm 27 -@@ -47,11 +47,11 @@ - #define TARGET_NR_times 43 - #define TARGET_NR_prof 44 - #define TARGET_NR_brk 45 --#define TARGET_NR_setgid32 46 --#define TARGET_NR_getgid32 47 -+#define TARGET_NR_setgid 46 -+#define TARGET_NR_getgid 47 - #define TARGET_NR_signal 48 --#define TARGET_NR_geteuid32 49 --#define TARGET_NR_getegid32 50 -+#define TARGET_NR_geteuid 49 -+#define TARGET_NR_getegid 50 - #define TARGET_NR_acct 51 - #define TARGET_NR_umount2 52 - #define TARGET_NR_lock 53 -@@ -71,8 +71,8 @@ - #define TARGET_NR_sigaction 67 - #define TARGET_NR_sgetmask 68 - #define TARGET_NR_ssetmask 69 --#define TARGET_NR_setreuid32 70 --#define TARGET_NR_setregid32 71 -+#define TARGET_NR_setreuid 70 -+#define TARGET_NR_setregid 71 - #define TARGET_NR_sigsuspend 72 - #define TARGET_NR_sigpending 73 - #define TARGET_NR_sethostname 74 -@@ -81,8 +81,8 @@ - #define TARGET_NR_getrusage 77 - #define TARGET_NR_gettimeofday 78 - #define TARGET_NR_settimeofday 79 --#define TARGET_NR_getgroups32 80 --#define TARGET_NR_setgroups32 81 -+#define TARGET_NR_getgroups 80 -+#define TARGET_NR_setgroups 81 - #define TARGET_NR_select 82 - #define TARGET_NR_symlink 83 - #define TARGET_NR_oldlstat 84 -@@ -96,7 +96,7 @@ - #define TARGET_NR_truncate 92 - #define TARGET_NR_ftruncate 93 - #define TARGET_NR_fchmod 94 --#define TARGET_NR_fchown32 95 -+#define TARGET_NR_fchown 95 - #define TARGET_NR_getpriority 96 - #define TARGET_NR_setpriority 97 - #define TARGET_NR_profil 98 -@@ -139,8 +139,8 @@ - #define TARGET_NR_sysfs 135 - #define TARGET_NR_personality 136 - #define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ --#define TARGET_NR_setfsuid32 138 --#define TARGET_NR_setfsgid32 139 -+#define TARGET_NR_setfsuid 138 -+#define TARGET_NR_setfsgid 139 - #define TARGET_NR__llseek 140 - #define TARGET_NR_getdents 141 - #define TARGET_NR__newselect 142 -@@ -182,7 +182,7 @@ - #define TARGET_NR_rt_sigsuspend 178 - #define TARGET_NR_pread64 179 - #define TARGET_NR_pwrite64 180 --#define TARGET_NR_chown32 181 -+#define TARGET_NR_chown 181 - #define TARGET_NR_getcwd 182 - #define TARGET_NR_capget 183 - #define TARGET_NR_capset 184 -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 78c6488..0cbe396 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -49,7 +49,7 @@ - #define TARGET_IOC_TYPEBITS 8 - - #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ -- || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) -+ || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC) - /* 16 bit uid wrappers emulation */ - #define USE_UID16 - #endif --- -1.6.2.1 - diff --git a/0019-Rewrite-mmap_find_vma-to-work-fine-on-64-bit-hosts.patch b/0019-Rewrite-mmap_find_vma-to-work-fine-on-64-bit-hosts.patch deleted file mode 100644 index 1996efd3..00000000 --- a/0019-Rewrite-mmap_find_vma-to-work-fine-on-64-bit-hosts.patch +++ /dev/null @@ -1,125 +0,0 @@ -From d7f01e455acae19ef780e29417ffba50ca90ffde Mon Sep 17 00:00:00 2001 -From: Kirill A. Shutemov -Date: Wed, 17 Jun 2009 15:14:43 +0200 -Subject: [PATCH 19/33] Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets - -From: Kirill A. Shutemov - -qemu's page table can be incomple if /proc/self/maps is unavailable or -host allocating a memory with mmap(), so we can't use it to find free -memory area. - -New version mmap_find_vma() uses mmap() without MAP_FIXED to find free -memory. - -From: Kirill A. Shutemov - -Signed-off-by: Kirill A. Shutemov -Signed-off-by: Riku Voipio ---- - linux-user/mmap.c | 79 +++++++++++++++++++++++++++++------------------------ - 1 files changed, 43 insertions(+), 36 deletions(-) - -diff --git a/linux-user/mmap.c b/linux-user/mmap.c -index 9ca8f6f..8d94783 100644 ---- a/linux-user/mmap.c -+++ b/linux-user/mmap.c -@@ -277,52 +277,59 @@ static abi_ulong mmap_next_start = 0x40000000; - - unsigned long last_brk; - --/* find a free memory area of size 'size'. The search starts at -- 'start'. If 'start' == 0, then a default start address is used. -- Return -1 if error. --*/ --/* page_init() marks pages used by the host as reserved to be sure not -- to use them. */ -+/* -+ * Find and reserve a free memory area of size 'size'. The search -+ * starts at 'start'. -+ * It must be called with mmap_lock() held. -+ * Return -1 if error. -+ */ - abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) - { -- abi_ulong addr, addr1, addr_start; -- int prot; -- unsigned long new_brk; -- -- new_brk = (unsigned long)sbrk(0); -- if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) { -- /* This is a hack to catch the host allocating memory with brk(). -- If it uses mmap then we loose. -- FIXME: We really want to avoid the host allocating memory in -- the first place, and maybe leave some slack to avoid switching -- to mmap. */ -- page_set_flags(last_brk & TARGET_PAGE_MASK, -- TARGET_PAGE_ALIGN(new_brk), -- PAGE_RESERVED); -- } -- last_brk = new_brk; -+ void *ptr; -+ abi_ulong addr; - - size = HOST_PAGE_ALIGN(size); -- start = start & qemu_host_page_mask; -+ start &= qemu_host_page_mask; -+ -+ /* If 'start' == 0, then a default start address is used. */ -+ if (start == 0) -+ start = mmap_next_start; -+ - addr = start; -- if (addr == 0) -- addr = mmap_next_start; -- addr_start = addr; -+ - for(;;) { -- prot = 0; -- for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { -- prot |= page_get_flags(addr1); -- } -- if (prot == 0) -+ /* -+ * Reserve needed memory area to avoid a race. -+ * It should be discarded using: -+ * - mmap() with MAP_FIXED flag -+ * - mremap() with MREMAP_FIXED flag -+ * - shmat() with SHM_REMAP flag -+ */ -+ ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE, -+ MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); -+ -+ /* ENOMEM, if host address space has no memory */ -+ if (ptr == MAP_FAILED) -+ return (abi_ulong)-1; -+ -+ /* If address fits target address space we've found what we need */ -+ if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1) - break; -+ -+ /* Unmap and try again with new page */ -+ munmap(ptr, size); - addr += qemu_host_page_size; -- /* we found nothing */ -- if (addr == addr_start) -+ -+ /* ENOMEM if we check whole of target address space */ -+ if (addr == start) - return (abi_ulong)-1; - } -- if (start == 0) -- mmap_next_start = addr + size; -- return addr; -+ -+ /* Update default start address */ -+ if (start == mmap_next_start) -+ mmap_next_start = (unsigned long)ptr + size; -+ -+ return h2g(ptr); - } - - #define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000 --- -1.6.2.1 - diff --git a/0020-TCG-sync-op-32-bit-targets-fixed.patch b/0020-TCG-sync-op-32-bit-targets-fixed.patch deleted file mode 100644 index 7b5f3dd1..00000000 --- a/0020-TCG-sync-op-32-bit-targets-fixed.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ea0b70265614b950d1e2ed48a9581ecd5e63ac97 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Fri, 24 Jul 2009 17:25:37 +0200 -Subject: [PATCH 20/33] TCG "sync" op (32-bit targets fixed) - -sync allows concurrent accesses to locations in memory through different TCG -variables. This comes in handy when you are emulating CPU registers that can -be used as either 32 or 64 bit, as TCG doesn't know anything about aliases. -See the s390x target for an example. - -Fixed to not break 32-bit target builds. - -Signed-off-by: Ulrich Hecht ---- - tcg/tcg-op.h | 12 ++++++++++++ - tcg/tcg-opc.h | 2 ++ - tcg/tcg.c | 6 ++++++ - 3 files changed, 20 insertions(+), 0 deletions(-) - -diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h -index 7cb6934..cfd6160 100644 ---- a/tcg/tcg-op.h -+++ b/tcg/tcg-op.h -@@ -316,6 +316,18 @@ static inline void tcg_gen_br(int label) - tcg_gen_op1i(INDEX_op_br, label); - } - -+static inline void tcg_gen_sync_i32(TCGv_i32 arg) -+{ -+ tcg_gen_op1_i32(INDEX_op_sync_i32, arg); -+} -+ -+#if TCG_TARGET_REG_BITS == 64 -+static inline void tcg_gen_sync_i64(TCGv_i64 arg) -+{ -+ tcg_gen_op1_i64(INDEX_op_sync_i64, arg); -+} -+#endif -+ - static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg) - { - if (!TCGV_EQUAL_I32(ret, arg)) -diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h -index 3a095fc..654a45f 100644 ---- a/tcg/tcg-opc.h -+++ b/tcg/tcg-opc.h -@@ -40,6 +40,7 @@ DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */ - DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) - DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) - -+DEF2(sync_i32, 0, 1, 0, 0) - DEF2(mov_i32, 1, 1, 0, 0) - DEF2(movi_i32, 1, 0, 1, 0) - /* load/store */ -@@ -103,6 +104,7 @@ DEF2(neg_i32, 1, 1, 0, 0) - #endif - - #if TCG_TARGET_REG_BITS == 64 -+DEF2(sync_i64, 0, 1, 0, 0) - DEF2(mov_i64, 1, 1, 0, 0) - DEF2(movi_i64, 1, 0, 1, 0) - /* load/store */ -diff --git a/tcg/tcg.c b/tcg/tcg.c -index 299bff6..86e16fa 100644 ---- a/tcg/tcg.c -+++ b/tcg/tcg.c -@@ -1927,6 +1927,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, - // dump_regs(s); - #endif - switch(opc) { -+ case INDEX_op_sync_i32: -+#if TCG_TARGET_REG_BITS == 64 -+ case INDEX_op_sync_i64: -+#endif -+ temp_save(s, args[0], s->reserved_regs); -+ break; - case INDEX_op_mov_i32: - #if TCG_TARGET_REG_BITS == 64 - case INDEX_op_mov_i64: --- -1.6.2.1 - diff --git a/0022-S-390-host-target-build-system-support.patch b/0022-S-390-host-target-build-system-support.patch deleted file mode 100644 index 3baff1cd..00000000 --- a/0022-S-390-host-target-build-system-support.patch +++ /dev/null @@ -1,127 +0,0 @@ -From fba6b2002b323519c4bb03079479de5bc3819642 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Fri, 24 Jul 2009 17:03:48 +0200 -Subject: [PATCH 22/33] S/390 host/target build system support - -changes to configure and makefiles for S/390 host and target support, -fixed as suggested by Juan Quintela - -Signed-off-by: Ulrich Hecht ---- - Makefile.target | 9 +++++++++ - configure | 19 ++++++++++++++----- - 2 files changed, 23 insertions(+), 5 deletions(-) - -diff --git a/Makefile.target b/Makefile.target -index 9c9304c..1080bf0 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -84,6 +84,9 @@ CPPFLAGS+=-I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/$(ARCH) - ifeq ($(ARCH),sparc64) - CPPFLAGS+=-I$(SRC_PATH)/tcg/sparc - endif -+ifeq ($(ARCH),s390x) -+CPPFLAGS+=-I$(SRC_PATH)/tcg/s390 -+endif - ifdef CONFIG_SOFTFLOAT - libobj-y += fpu/softfloat.o - else -@@ -211,6 +214,9 @@ endif - ifeq ($(ARCH),s390) - LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld - endif -+ifeq ($(ARCH),s390x) -+LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -+endif - - ifeq ($(ARCH),sparc) - # -static is used to avoid g1/g3 usage by the dynamic linker -@@ -358,6 +364,9 @@ endif - ifeq ($(ARCH),s390) - LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld - endif -+ifeq ($(ARCH),s390x) -+LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -+endif - - ifeq ($(ARCH),sparc) - # -static is used to avoid g1/g3 usage by the dynamic linker -diff --git a/configure b/configure -index 4f79498..e0874b5 100755 ---- a/configure -+++ b/configure -@@ -146,9 +146,12 @@ case "$cpu" in - ppc64) - cpu="ppc64" - ;; -- s390*) -+ s390) - cpu="s390" - ;; -+ s390x) -+ cpu="s390x" -+ ;; - sparc|sun4[cdmuv]) - cpu="sparc" - ;; -@@ -745,6 +748,7 @@ sh4eb-linux-user \ - sparc-linux-user \ - sparc64-linux-user \ - sparc32plus-linux-user \ -+s390x-linux-user \ - " - fi - # the following are Darwin specific -@@ -809,6 +813,7 @@ hostlongbits="32" - if test "$cpu" = "x86_64" \ - -o "$cpu" = "alpha" \ - -o "$cpu" = "ia64" \ -+ -o "$cpu" = "s390x" \ - -o "$cpu" = "sparc64" \ - -o "$cpu" = "ppc64"; then - hostlongbits="64" -@@ -1499,10 +1504,10 @@ echo "EXESUF=$EXESUF" >> $config_host_mak - echo "PTHREADLIBS=$PTHREADLIBS" >> $config_host_mak - echo "CLOCKLIBS=$CLOCKLIBS" >> $config_host_mak - case "$cpu" in -- i386|x86_64|alpha|cris|hppa|ia64|m68k|microbaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64) -+ i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64) - ARCH=$cpu - ;; -- armv4b|arm4l) -+ armv4b|armv4l) - ARCH=arm - ;; - *) -@@ -1837,7 +1842,7 @@ config_h=$target_dir/config.h - target_arch2=`echo $target | cut -d '-' -f 1` - target_bigendian="no" - case "$target_arch2" in -- armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|sh4eb|sparc|sparc64|sparc32plus) -+ armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus) - target_bigendian=yes - ;; - esac -@@ -1997,6 +2002,10 @@ case "$target_arch2" in - echo "TARGET_ABI32=y" >> $config_mak - target_phys_bits=64 - ;; -+ s390x) -+ target_nptl="yes" -+ target_phys_bits=64 -+ ;; - *) - echo "Unsupported target CPU" - exit 1 -@@ -2065,7 +2074,7 @@ fi - echo "TARGET_XML_FILES=$list" >> $config_mak - - case "$target_arch2" in -- arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|sparc|sparc64|sparc32plus) -+ arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sparc|sparc64|sparc32plus) - echo "CONFIG_SOFTFLOAT=y" >> $config_mak - ;; - esac --- -1.6.2.1 - diff --git a/0023-S-390-host-support-for-TCG.patch b/0023-S-390-host-support-for-TCG.patch deleted file mode 100644 index 35028cb9..00000000 --- a/0023-S-390-host-support-for-TCG.patch +++ /dev/null @@ -1,1486 +0,0 @@ -From 3a42668021f934d0b36127c2c14479ae5cf62e8f Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Fri, 24 Jul 2009 17:00:17 +0200 -Subject: [PATCH 23/33] S/390 host support for TCG - -S/390 TCG code generator as posted before - -improvements since last time: -- don't use R0 (often means "zero", not "register zero") -- optimized add_i32 immediate -- formatted for better compliance with the QEMU coding style - -Signed-off-by: Ulrich Hecht ---- - dyngen-exec.h | 2 +- - linux-user/syscall.c | 2 +- - s390x.ld | 194 +++++++++ - tcg/s390/tcg-target.c | 1145 +++++++++++++++++++++++++++++++++++++++++++++++++ - tcg/s390/tcg-target.h | 76 ++++ - 5 files changed, 1417 insertions(+), 2 deletions(-) - create mode 100644 s390x.ld - create mode 100644 tcg/s390/tcg-target.c - create mode 100644 tcg/s390/tcg-target.h - -diff --git a/dyngen-exec.h b/dyngen-exec.h -index c007763..606ee11 100644 ---- a/dyngen-exec.h -+++ b/dyngen-exec.h -@@ -119,7 +119,7 @@ extern int printf(const char *, ...); - - /* The return address may point to the start of the next instruction. - Subtracting one gets us the call instruction itself. */ --#if defined(__s390__) -+#if defined(__s390__) && !defined(__s390x__) - # define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1)) - #elif defined(__arm__) - /* Thumb return addresses have the low bit set, so we need to subtract two. -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 87ceac7..548be54 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -182,7 +182,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ - #define __NR_sys_inotify_add_watch __NR_inotify_add_watch - #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch - --#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) -+#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || defined(__s390x__) - #define __NR__llseek __NR_lseek - #endif - -diff --git a/s390x.ld b/s390x.ld -new file mode 100644 -index 0000000..7d1f2b7 ---- /dev/null -+++ b/s390x.ld -@@ -0,0 +1,194 @@ -+/* Default linker script, for normal executables */ -+OUTPUT_FORMAT("elf64-s390", "elf64-s390", -+ "elf64-s390") -+OUTPUT_ARCH(s390:64-bit) -+ENTRY(_start) -+SEARCH_DIR("/usr/s390x-suse-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/s390x-suse-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); -+SECTIONS -+{ -+ /* Read-only sections, merged into text segment: */ -+ PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; -+ .interp : { *(.interp) } -+ .note.gnu.build-id : { *(.note.gnu.build-id) } -+ .hash : { *(.hash) } -+ .gnu.hash : { *(.gnu.hash) } -+ .dynsym : { *(.dynsym) } -+ .dynstr : { *(.dynstr) } -+ .gnu.version : { *(.gnu.version) } -+ .gnu.version_d : { *(.gnu.version_d) } -+ .gnu.version_r : { *(.gnu.version_r) } -+ .rel.init : { *(.rel.init) } -+ .rela.init : { *(.rela.init) } -+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -+ .rel.fini : { *(.rel.fini) } -+ .rela.fini : { *(.rela.fini) } -+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -+ .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } -+ .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } -+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -+ .rel.ctors : { *(.rel.ctors) } -+ .rela.ctors : { *(.rela.ctors) } -+ .rel.dtors : { *(.rel.dtors) } -+ .rela.dtors : { *(.rela.dtors) } -+ .rel.got : { *(.rel.got) } -+ .rela.got : { *(.rela.got) } -+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -+ .rel.plt : { *(.rel.plt) } -+ .rela.plt : { *(.rela.plt) } -+ .init : -+ { -+ KEEP (*(.init)) -+ } =0x07070707 -+ .plt : { *(.plt) } -+ .text : -+ { -+ *(.text .stub .text.* .gnu.linkonce.t.*) -+ /* .gnu.warning sections are handled specially by elf32.em. */ -+ *(.gnu.warning) -+ } =0x07070707 -+ .fini : -+ { -+ KEEP (*(.fini)) -+ } =0x07070707 -+ PROVIDE (__etext = .); -+ PROVIDE (_etext = .); -+ PROVIDE (etext = .); -+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -+ .rodata1 : { *(.rodata1) } -+ .eh_frame_hdr : { *(.eh_frame_hdr) } -+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } -+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } -+ /* Adjust the address for the data segment. We want to adjust up to -+ the same address within the page on the next page up. */ -+ . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); -+ /* Exception handling */ -+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } -+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } -+ /* Thread Local Storage sections */ -+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -+ .preinit_array : -+ { -+ PROVIDE_HIDDEN (__preinit_array_start = .); -+ KEEP (*(.preinit_array)) -+ PROVIDE_HIDDEN (__preinit_array_end = .); -+ } -+ .init_array : -+ { -+ PROVIDE_HIDDEN (__init_array_start = .); -+ KEEP (*(SORT(.init_array.*))) -+ KEEP (*(.init_array)) -+ PROVIDE_HIDDEN (__init_array_end = .); -+ } -+ .fini_array : -+ { -+ PROVIDE_HIDDEN (__fini_array_start = .); -+ KEEP (*(.fini_array)) -+ KEEP (*(SORT(.fini_array.*))) -+ PROVIDE_HIDDEN (__fini_array_end = .); -+ } -+ .ctors : -+ { -+ /* gcc uses crtbegin.o to find the start of -+ the constructors, so we make sure it is -+ first. Because this is a wildcard, it -+ doesn't matter if the user does not -+ actually link against crtbegin.o; the -+ linker won't look for a file to match a -+ wildcard. The wildcard also means that it -+ doesn't matter which directory crtbegin.o -+ is in. */ -+ KEEP (*crtbegin.o(.ctors)) -+ KEEP (*crtbegin?.o(.ctors)) -+ /* We don't want to include the .ctor section from -+ the crtend.o file until after the sorted ctors. -+ The .ctor section from the crtend file contains the -+ end of ctors marker and it must be last */ -+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) -+ KEEP (*(SORT(.ctors.*))) -+ KEEP (*(.ctors)) -+ } -+ .dtors : -+ { -+ KEEP (*crtbegin.o(.dtors)) -+ KEEP (*crtbegin?.o(.dtors)) -+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) -+ KEEP (*(SORT(.dtors.*))) -+ KEEP (*(.dtors)) -+ } -+ .jcr : { KEEP (*(.jcr)) } -+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } -+ .dynamic : { *(.dynamic) } -+ . = DATA_SEGMENT_RELRO_END (0, .); -+ .got : { *(.got.plt) *(.got) } -+ .data : -+ { -+ *(.data .data.* .gnu.linkonce.d.*) -+ SORT(CONSTRUCTORS) -+ } -+ .data1 : { *(.data1) } -+ _edata = .; PROVIDE (edata = .); -+ __bss_start = .; -+ .bss : -+ { -+ *(.dynbss) -+ *(.bss .bss.* .gnu.linkonce.b.*) -+ *(COMMON) -+ /* Align here to ensure that the .bss section occupies space up to -+ _end. Align after .bss to ensure correct alignment even if the -+ .bss section disappears because there are no input sections. -+ FIXME: Why do we need it? When there is no .bss section, we don't -+ pad the .data section. */ -+ . = ALIGN(. != 0 ? 64 / 8 : 1); -+ } -+ . = ALIGN(64 / 8); -+ . = ALIGN(64 / 8); -+ _end = .; PROVIDE (end = .); -+ . = DATA_SEGMENT_END (.); -+ /* Stabs debugging sections. */ -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ .stab.excl 0 : { *(.stab.excl) } -+ .stab.exclstr 0 : { *(.stab.exclstr) } -+ .stab.index 0 : { *(.stab.index) } -+ .stab.indexstr 0 : { *(.stab.indexstr) } -+ .comment 0 : { *(.comment) } -+ /* DWARF debug sections. -+ Symbols in the DWARF debugging sections are relative to the beginning -+ of the section so we begin them at 0. */ -+ /* DWARF 1 */ -+ .debug 0 : { *(.debug) } -+ .line 0 : { *(.line) } -+ /* GNU DWARF 1 extensions */ -+ .debug_srcinfo 0 : { *(.debug_srcinfo) } -+ .debug_sfnames 0 : { *(.debug_sfnames) } -+ /* DWARF 1.1 and DWARF 2 */ -+ .debug_aranges 0 : { *(.debug_aranges) } -+ .debug_pubnames 0 : { *(.debug_pubnames) } -+ /* DWARF 2 */ -+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -+ .debug_abbrev 0 : { *(.debug_abbrev) } -+ .debug_line 0 : { *(.debug_line) } -+ .debug_frame 0 : { *(.debug_frame) } -+ .debug_str 0 : { *(.debug_str) } -+ .debug_loc 0 : { *(.debug_loc) } -+ .debug_macinfo 0 : { *(.debug_macinfo) } -+ /* SGI/MIPS DWARF 2 extensions */ -+ .debug_weaknames 0 : { *(.debug_weaknames) } -+ .debug_funcnames 0 : { *(.debug_funcnames) } -+ .debug_typenames 0 : { *(.debug_typenames) } -+ .debug_varnames 0 : { *(.debug_varnames) } -+ /* DWARF 3 */ -+ .debug_pubtypes 0 : { *(.debug_pubtypes) } -+ .debug_ranges 0 : { *(.debug_ranges) } -+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } -+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) } -+} -diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c -new file mode 100644 -index 0000000..0b285cd ---- /dev/null -+++ b/tcg/s390/tcg-target.c -@@ -0,0 +1,1145 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+ -+#ifndef NDEBUG -+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { -+ "%r0", -+ "%r1", -+ "%r2", -+ "%r3", -+ "%r4", -+ "%r5", -+ "%r6", -+ "%r7", -+ "%r8", -+ "%r9", -+ "%r10", -+ "%r11", -+ "%r12", -+ "%r13", -+ "%r14", -+ "%r15" -+}; -+#endif -+ -+static const int tcg_target_reg_alloc_order[] = { -+ TCG_REG_R6, -+ TCG_REG_R7, -+ TCG_REG_R8, -+ TCG_REG_R9, -+ TCG_REG_R10, -+ TCG_REG_R11, -+ TCG_REG_R12, -+ TCG_REG_R13, -+ TCG_REG_R14, -+ /* TCG_REG_R0, many insns can't be used with R0, so we better avoid it for now */ -+ TCG_REG_R1, -+ TCG_REG_R2, -+ TCG_REG_R3, -+ TCG_REG_R4, -+ TCG_REG_R5, -+}; -+ -+static const int tcg_target_call_iarg_regs[4] = { -+ TCG_REG_R2, TCG_REG_R3, TCG_REG_R4, TCG_REG_R5 -+}; -+static const int tcg_target_call_oarg_regs[2] = { -+ TCG_REG_R2, TCG_REG_R3 -+}; -+ -+static void patch_reloc(uint8_t *code_ptr, int type, -+ tcg_target_long value, tcg_target_long addend) -+{ -+ switch (type) { -+ case R_390_PC32DBL: -+ *(uint32_t*)code_ptr = (value - ((tcg_target_long)code_ptr + addend)) >> 1; -+ break; -+ default: -+ tcg_abort(); -+ break; -+ } -+} -+ -+/* maximum number of register used for input function arguments */ -+static inline int tcg_target_get_call_iarg_regs_count(int flags) -+{ -+ return 4; -+} -+ -+#define TCG_CT_CONST_S16 0x100 -+#define TCG_CT_CONST_U12 0x200 -+ -+/* parse target specific constraints */ -+static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) -+{ -+ const char *ct_str; -+ -+ ct->ct |= TCG_CT_REG; -+ tcg_regset_set32(ct->u.regs, 0, 0xffff); -+ ct_str = *pct_str; -+ switch (ct_str[0]) { -+ case 'L': /* qemu_ld constraint */ -+ tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2); -+#ifdef CONFIG_SOFTMMU -+ tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3); -+#endif -+ break; -+ case 'S': /* qemu_st constraint */ -+ tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2); -+#ifdef CONFIG_SOFTMMU -+ tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3); -+ tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4); -+#endif -+ break; -+ case 'R': /* not R0 */ -+ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); -+ break; -+ case 'I': -+ ct->ct &= ~TCG_CT_REG; -+ ct->ct |= TCG_CT_CONST_S16; -+ break; -+ default: -+ break; -+ } -+ ct_str++; -+ *pct_str = ct_str; -+ -+ return 0; -+} -+ -+/* Test if a constant matches the constraint. */ -+static inline int tcg_target_const_match(tcg_target_long val, -+ const TCGArgConstraint *arg_ct) -+{ -+ int ct; -+ ct = arg_ct->ct; -+ if (ct & TCG_CT_CONST) -+ return 1; -+ if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) -+ return 1; -+ if ((ct & TCG_CT_CONST_U12) && val == (val & 0xfff)) -+ return 1; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SOFTMMU -+ -+#include "../../softmmu_defs.h" -+ -+static void *qemu_ld_helpers[4] = { -+ __ldb_mmu, -+ __ldw_mmu, -+ __ldl_mmu, -+ __ldq_mmu, -+}; -+ -+static void *qemu_st_helpers[4] = { -+ __stb_mmu, -+ __stw_mmu, -+ __stl_mmu, -+ __stq_mmu, -+}; -+#endif -+ -+static uint8_t *tb_ret_addr; -+ -+/* signed/unsigned is handled by using COMPARE and COMPARE LOGICAL, -+ respectively */ -+static const uint8_t tcg_cond_to_s390_cond[10] = { -+ [TCG_COND_EQ] = 8, -+ [TCG_COND_LT] = 4, -+ [TCG_COND_LTU] = 4, -+ [TCG_COND_LE] = 8 | 4, -+ [TCG_COND_LEU] = 8 | 4, -+ [TCG_COND_GT] = 2, -+ [TCG_COND_GTU] = 2, -+ [TCG_COND_GE] = 8 | 2, -+ [TCG_COND_GEU] = 8 | 2, -+ [TCG_COND_NE] = 4 | 2 | 1, -+}; -+ -+/* emit load/store (and then some) instructions (E3 prefix) */ -+static inline void tcg_out_e3(TCGContext* s, int op, int r1, int r2, int disp) -+{ -+ tcg_out16(s, 0xe300 | (r1 << 4)); -+ tcg_out32(s, op | (r2 << 28) | ((disp & 0xfff) << 16) | ((disp >> 12) << 8)); -+} -+#define E3_LG 0x04 -+#define E3_LRVG 0x0f -+#define E3_LGF 0x14 -+#define E3_LGH 0x15 -+#define E3_LLGF 0x16 -+#define E3_LRV 0x1e -+#define E3_LRVH 0x1f -+#define E3_CG 0x20 -+#define E3_STG 0x24 -+#define E3_STRVG 0x2f -+#define E3_STRV 0x3e -+#define E3_STRVH 0x3f -+#define E3_STHY 0x70 -+#define E3_STCY 0x72 -+#define E3_LGB 0x77 -+#define E3_LLGC 0x90 -+#define E3_LLGH 0x91 -+ -+/* emit 64-bit register/register insns (B9 prefix) */ -+static inline void tcg_out_b9(TCGContext* s, int op, int r1, int r2) -+{ -+ tcg_out32(s, 0xb9000000 | (op << 16) | (r1 << 4) | r2); -+} -+#define B9_LGR 0x04 -+#define B9_AGR 0x08 -+#define B9_SGR 0x09 -+#define B9_MSGR 0x0c -+#define B9_LGFR 0x14 -+#define B9_LLGFR 0x16 -+#define B9_CGR 0x20 -+#define B9_CLGR 0x21 -+#define B9_NGR 0x80 -+#define B9_OGR 0x81 -+#define B9_XGR 0x82 -+#define B9_DLGR 0x87 -+#define B9_DLR 0x97 -+ -+/* emit (mostly) 32-bit register/register insns */ -+static inline void tcg_out_rr(TCGContext* s, int op, int r1, int r2) -+{ -+ tcg_out16(s, (op << 8) | (r1 << 4) | r2); -+} -+#define RR_BASR 0x0d -+#define RR_NR 0x14 -+#define RR_CLR 0x15 -+#define RR_OR 0x16 -+#define RR_XR 0x17 -+#define RR_LR 0x18 -+#define RR_CR 0x19 -+#define RR_AR 0x1a -+#define RR_SR 0x1b -+ -+static inline void tcg_out_a7(TCGContext *s, int op, int r1, int16_t i2) -+{ -+ tcg_out32(s, 0xa7000000UL | (r1 << 20) | (op << 16) | ((uint16_t)i2)); -+} -+#define A7_AHI 0xa -+#define A7_AHGI 0xb -+ -+/* emit 64-bit shifts (EB prefix) */ -+static inline void tcg_out_sh64(TCGContext* s, int op, int r0, int r1, int r2, int imm) -+{ -+ tcg_out16(s, 0xeb00 | (r0 << 4) | r1); -+ tcg_out32(s, op | (r2 << 28) | ((imm & 0xfff) << 16) | ((imm >> 12) << 8)); -+} -+#define SH64_REG_NONE 0 /* use immediate only (not R0!) */ -+#define SH64_SRAG 0x0a -+#define SH64_SRLG 0x0c -+#define SH64_SLLG 0x0d -+ -+/* emit 32-bit shifts */ -+static inline void tcg_out_sh32(TCGContext* s, int op, int r0, int r1, int imm) -+{ -+ tcg_out32(s, 0x80000000 | (op << 24) | (r0 << 20) | (r1 << 12) | imm); -+} -+#define SH32_REG_NONE 0 /* use immediate only (not R0!) */ -+#define SH32_SRL 0x8 -+#define SH32_SLL 0x9 -+#define SH32_SRA 0xa -+ -+/* branch to relative address (long) */ -+static inline void tcg_out_brasl(TCGContext* s, int r, tcg_target_long raddr) -+{ -+ tcg_out16(s, 0xc005 | (r << 4)); -+ tcg_out32(s, raddr >> 1); -+} -+ -+/* store 8/16/32 bits */ -+static inline void tcg_out_store(TCGContext* s, int op, int r0, int r1, int off) -+{ -+ tcg_out32(s, (op << 24) | (r0 << 20) | (r1 << 12) | off); -+} -+#define ST_STH 0x40 -+#define ST_STC 0x42 -+#define ST_ST 0x50 -+ -+/* load a register with an immediate value */ -+static inline void tcg_out_movi(TCGContext *s, TCGType type, -+ int ret, tcg_target_long arg) -+{ -+ //fprintf(stderr,"tcg_out_movi ret 0x%x arg 0x%lx\n",ret,arg); -+ if (arg >= -0x8000 && arg < 0x8000) { /* signed immediate load */ -+ /* lghi %rret, arg */ -+ tcg_out32(s, 0xa7090000 | (ret << 20) | (arg & 0xffff)); -+ } -+ else if (!(arg & 0xffffffffffff0000UL)) { -+ /* llill %rret, arg */ -+ tcg_out32(s, 0xa50f0000 | (ret << 20) | arg); -+ } -+ else if (!(arg & 0xffffffff00000000UL) || type == TCG_TYPE_I32) { -+ /* llill %rret, arg */ -+ tcg_out32(s, 0xa50f0000 | (ret << 20) | (arg & 0xffff)); -+ /* iilh %rret, arg */ -+ tcg_out32(s, 0xa5020000 | (ret << 20) | ((arg & 0xffffffff) >> 16)); -+ } -+ else { -+ /* branch over constant and store its address in R13 */ -+ tcg_out_brasl(s, TCG_REG_R13, 14); -+ /* 64-bit constant */ -+ tcg_out32(s,arg >> 32); -+ tcg_out32(s,arg); -+ /* load constant to ret */ -+ tcg_out_e3(s, E3_LG, ret, TCG_REG_R13, 0); -+ } -+} -+ -+/* load data without address translation or endianness conversion */ -+static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg, -+ int arg1, tcg_target_long arg2) -+{ -+ int op; -+ //fprintf(stderr,"tcg_out_ld type %d arg %d arg1 %d arg2 %ld\n",type,arg,arg1,arg2); -+ -+ if (type == TCG_TYPE_I32) op = E3_LLGF; /* 32-bit zero-extended */ -+ else op = E3_LG; /* 64-bit */ -+ -+ if (arg2 < -0x80000 || arg2 > 0x7ffff) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, arg2); /* load the displacement */ -+ tcg_out_b9(s, B9_AGR, TCG_REG_R13, arg1); /* add the address */ -+ tcg_out_e3(s, op, arg, TCG_REG_R13, 0); /* load the data */ -+ } -+ else { -+ tcg_out_e3(s, op, arg, arg1, arg2); /* load the data */ -+ } -+} -+ -+/* load data with address translation (if applicable) and endianness conversion */ -+static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc) -+{ -+ int addr_reg, data_reg, mem_index, s_bits; -+#if defined(CONFIG_SOFTMMU) -+ uint16_t *label1_ptr, *label2_ptr; -+#endif -+ -+ data_reg = *args++; -+ addr_reg = *args++; -+ mem_index = *args; -+ -+ s_bits = opc & 3; -+ -+ int arg0 = TCG_REG_R2; -+#ifdef CONFIG_SOFTMMU -+ int arg1 = TCG_REG_R3; -+#endif -+ -+ /* fprintf(stderr,"tcg_out_qemu_ld opc %d data_reg %d addr_reg %d mem_index %d s_bits %d\n", -+ opc, data_reg, addr_reg, mem_index, s_bits); */ -+ -+#ifdef CONFIG_SOFTMMU -+ tcg_out_b9(s, B9_LGR, arg1, addr_reg); -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+ -+ tcg_out_sh64(s, SH64_SRLG, arg1, addr_reg, SH64_REG_NONE, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, TARGET_PAGE_MASK | ((1 << s_bits) - 1)); -+ tcg_out_b9(s, B9_NGR, arg0, TCG_REG_R13); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS); -+ tcg_out_b9(s, B9_NGR, arg1, TCG_REG_R13); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, offsetof(CPUState, tlb_table[mem_index][0].addr_read)); -+ tcg_out_b9(s, B9_AGR, arg1, TCG_REG_R13); -+ -+ tcg_out_b9(s, B9_AGR, arg1, TCG_AREG0); -+ -+ tcg_out_e3(s, E3_CG, arg0, arg1, 0); -+ -+ label1_ptr = (uint16_t*)s->code_ptr; -+ tcg_out32(s, 0xa7840000); /* je label1 (offset will be patched in later) */ -+ -+ /* call load helper */ -+#if TARGET_LONG_BITS == 32 -+ tcg_out_b9(s, B9_LLGFR, arg0, addr_reg); -+#else -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+#endif -+ tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (tcg_target_ulong)qemu_ld_helpers[s_bits]); -+ tcg_out_rr(s, RR_BASR, TCG_REG_R14, TCG_REG_R13); -+ -+ /* sign extension */ -+ switch (opc) { -+ case 0 | 4: -+ tcg_out_sh64(s, SH64_SLLG, data_reg, arg0, SH64_REG_NONE, 56); -+ tcg_out_sh64(s, SH64_SRAG, data_reg, data_reg, SH64_REG_NONE, 56); -+ break; -+ case 1 | 4: -+ tcg_out_sh64(s, SH64_SLLG, data_reg, arg0, SH64_REG_NONE, 48); -+ tcg_out_sh64(s, SH64_SRAG, data_reg, data_reg, SH64_REG_NONE, 48); -+ break; -+ case 2 | 4: -+ tcg_out_b9(s, B9_LGFR, data_reg, arg0); -+ break; -+ case 0: case 1: case 2: case 3: default: -+ /* unsigned -> just copy */ -+ tcg_out_b9(s, B9_LGR, data_reg, arg0); -+ break; -+ } -+ -+ /* jump to label2 (end) */ -+ label2_ptr = (uint16_t*)s->code_ptr; -+ tcg_out32(s, 0xa7d50000); /* bras %r13, label2 */ -+ -+ /* this is label1, patch branch */ -+ *(label1_ptr + 1) = ((unsigned long)s->code_ptr - (unsigned long)label1_ptr) >> 1; -+ -+ tcg_out_e3(s, E3_LG, arg1, arg1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read)); -+ -+#if TARGET_LONG_BITS == 32 -+ /* zero upper 32 bits */ -+ tcg_out_b9(s, B9_LLGFR, arg0, addr_reg); -+#else -+ /* just copy */ -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+#endif -+ tcg_out_b9(s, B9_AGR, arg0, arg1); -+ -+#else /* CONFIG_SOFTMMU */ -+ /* user mode, no address translation required */ -+ arg0 = addr_reg; -+#endif -+ -+ switch (opc) { -+ case 0: /* unsigned byte */ -+ tcg_out_e3(s, E3_LLGC, data_reg, arg0, 0); -+ break; -+ case 0 | 4: /* signed byte */ -+ tcg_out_e3(s, E3_LGB, data_reg, arg0, 0); -+ break; -+ case 1: /* unsigned short */ -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_LLGH, data_reg, arg0, 0); -+#else -+ /* swapped unsigned halfword load with upper bits zeroed */ -+ tcg_out_e3(s, E3_LRVH, data_reg, arg0, 0); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, 0xffffL); -+ tcg_out_b9(s, B9_NGR, data_reg, 13); -+#endif -+ break; -+ case 1 | 4: /* signed short */ -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_LGH, data_reg, arg0, 0); -+#else -+ /* swapped sign-extended halfword load */ -+ tcg_out_e3(s, E3_LRVH, data_reg, arg0, 0); -+ tcg_out_sh64(s, SH64_SLLG, data_reg, data_reg, SH64_REG_NONE, 48); -+ tcg_out_sh64(s, SH64_SRAG, data_reg, data_reg, SH64_REG_NONE, 48); -+#endif -+ break; -+ case 2: /* unsigned int */ -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_LLGF, data_reg, arg0, 0); -+#else -+ /* swapped unsigned int load with upper bits zeroed */ -+ tcg_out_e3(s, E3_LRV, data_reg, arg0, 0); -+ tcg_out_b9(s, B9_LLGFR, data_reg, data_reg); -+#endif -+ break; -+ case 2 | 4: /* signed int */ -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_LGF, data_reg, arg0, 0); -+#else -+ /* swapped sign-extended int load */ -+ tcg_out_e3(s, E3_LRV, data_reg, arg0, 0); -+ tcg_out_b9(s, B9_LGFR, data_reg, data_reg); -+#endif -+ break; -+ case 3: /* long (64 bit) */ -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_LG, data_reg, arg0, 0); -+#else -+ tcg_out_e3(s, E3_LRVG, data_reg, arg0, 0); -+#endif -+ break; -+ default: -+ tcg_abort(); -+ } -+ -+#ifdef CONFIG_SOFTMMU -+ /* this is label2, patch branch */ -+ *(label2_ptr + 1) = ((unsigned long)s->code_ptr - (unsigned long)label2_ptr) >> 1; -+#endif -+} -+ -+static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc) -+{ -+ int addr_reg, data_reg, mem_index, s_bits; -+#if defined(CONFIG_SOFTMMU) -+ uint16_t *label1_ptr, *label2_ptr; -+#endif -+ -+ data_reg = *args++; -+ addr_reg = *args++; -+ mem_index = *args; -+ -+ s_bits = opc; -+ -+ int arg0 = TCG_REG_R2; -+#ifdef CONFIG_SOFTMMU -+ int arg1 = TCG_REG_R3; -+ int arg2 = TCG_REG_R4; -+#endif -+ -+ /* fprintf(stderr,"tcg_out_qemu_st opc %d data_reg %d addr_reg %d mem_index %d s_bits %d\n", -+ opc, data_reg, addr_reg, mem_index, s_bits); */ -+ -+#ifdef CONFIG_SOFTMMU -+#if TARGET_LONG_BITS == 32 -+ tcg_out_b9(s, B9_LLGFR, arg1, addr_reg); -+ tcg_out_b9(s, B9_LLGFR, arg0, addr_reg); -+#else -+ tcg_out_b9(s, B9_LGR, arg1, addr_reg); -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+#endif -+ -+ tcg_out_sh64(s, SH64_SRLG, arg1, addr_reg, SH64_REG_NONE, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, TARGET_PAGE_MASK | ((1 << s_bits) - 1)); -+ tcg_out_b9(s, B9_NGR, arg0, TCG_REG_R13); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS); -+ tcg_out_b9(s, B9_NGR, arg1, TCG_REG_R13); -+ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, offsetof(CPUState, tlb_table[mem_index][0].addr_write)); -+ tcg_out_b9(s, B9_AGR, arg1, TCG_REG_R13); -+ -+ tcg_out_b9(s, B9_AGR, arg1, TCG_AREG0); -+ -+ tcg_out_e3(s, E3_CG, arg0, arg1, 0); -+ -+#if TARGET_LONG_BITS == 32 -+ tcg_out_b9(s, B9_LLGFR, arg0, addr_reg); -+#else -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+#endif -+ -+ /* jump to label1 */ -+ label1_ptr = (uint16_t*)s->code_ptr; -+ tcg_out32(s, 0xa7840000); /* je label1 */ -+ -+ /* call store helper */ -+ tcg_out_b9(s, B9_LGR, arg1, data_reg); -+ tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (tcg_target_ulong)qemu_st_helpers[s_bits]); -+ tcg_out_rr(s, RR_BASR, TCG_REG_R14, TCG_REG_R13); -+ -+ /* jump to label2 (end) */ -+ label2_ptr = (uint16_t*)s->code_ptr; -+ tcg_out32(s, 0xa7d50000); /* bras %r13, label2 */ -+ -+ /* this is label1, patch branch */ -+ *(label1_ptr + 1) = ((unsigned long)s->code_ptr - (unsigned long)label1_ptr) >> 1; -+ -+ tcg_out_e3(s, E3_LG, arg1, arg1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write)); -+ -+#if TARGET_LONG_BITS == 32 -+ /* zero upper 32 bits */ -+ tcg_out_b9(s, B9_LLGFR, arg0, addr_reg); -+#else -+ /* just copy */ -+ tcg_out_b9(s, B9_LGR, arg0, addr_reg); -+#endif -+ tcg_out_b9(s, B9_AGR, arg0, arg1); -+ -+#else /* CONFIG_SOFTMMU */ -+ /* user mode, no address translation required */ -+ arg0 = addr_reg; -+#endif -+ -+ switch (opc) { -+ case 0: -+ tcg_out_store(s, ST_STC, data_reg, arg0, 0); -+ break; -+ case 1: -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_store(s, ST_STH, data_reg, arg0, 0); -+#else -+ tcg_out_e3(s, E3_STRVH, data_reg, arg0, 0); -+#endif -+ break; -+ case 2: -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_store(s, ST_ST, data_reg, arg0, 0); -+#else -+ tcg_out_e3(s, E3_STRV, data_reg, arg0, 0); -+#endif -+ break; -+ case 3: -+#ifdef TARGET_WORDS_BIGENDIAN -+ tcg_out_e3(s, E3_STG, data_reg, arg0, 0); -+#else -+ tcg_out_e3(s, E3_STRVG, data_reg, arg0, 0); -+#endif -+ break; -+ default: -+ tcg_abort(); -+ } -+ -+#ifdef CONFIG_SOFTMMU -+ /* this is label2, patch branch */ -+ *(label2_ptr + 1) = ((unsigned long)s->code_ptr - (unsigned long)label2_ptr) >> 1; -+#endif -+} -+ -+static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, -+ int arg1, tcg_target_long arg2) -+{ -+ //fprintf(stderr,"tcg_out_st arg 0x%x arg1 0x%x arg2 0x%lx\n",arg,arg1,arg2); -+ if (type == TCG_TYPE_I32) { -+ if (((long)arg2) < -0x800 || ((long)arg2) > 0x7ff) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, arg2); -+ tcg_out_b9(s, B9_AGR, 13, arg1); -+ tcg_out_store(s, ST_ST, arg, TCG_REG_R13, 0); -+ } -+ else tcg_out_store(s, ST_ST, arg, arg1, arg2); -+ } -+ else { -+ if (((long)arg2) < -0x80000 || ((long)arg2) > 0x7ffff) tcg_abort(); -+ tcg_out_e3(s, E3_STG, arg, arg1, arg2); -+ } -+} -+ -+static inline void tcg_out_op(TCGContext *s, int opc, -+ const TCGArg *args, const int *const_args) -+{ -+ TCGLabel* l; -+ int op; -+ int op2; -+ //fprintf(stderr,"0x%x\n", INDEX_op_divu_i32); -+ switch (opc) { -+ case INDEX_op_exit_tb: -+ //fprintf(stderr,"op 0x%x exit_tb 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]); /* return value */ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (unsigned long)tb_ret_addr); -+ tcg_out16(s,0x7fd); /* br %r13 */ -+ break; -+ case INDEX_op_goto_tb: -+ //fprintf(stderr,"op 0x%x goto_tb 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (s->tb_jmp_offset) { -+ tcg_abort(); -+ } -+ else { -+ tcg_target_long off = ((tcg_target_long)(s->tb_next + args[0]) - (tcg_target_long)s->code_ptr) >> 1; -+ if (off > -0x80000000L && off < 0x7fffffffL) { /* load address relative to PC */ -+ /* larl %r13, off */ -+ tcg_out16(s,0xc0d0); tcg_out32(s,off); -+ } -+ else { /* too far for larl */ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, (tcg_target_long)(s->tb_next + args[0])); -+ } -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R13, TCG_REG_R13, 0); /* load address stored at s->tb_next + args[0] */ -+ tcg_out_rr(s, RR_BASR, TCG_REG_R13, TCG_REG_R13); /* and go there */ -+ } -+ s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; -+ break; -+ case INDEX_op_call: -+ //fprintf(stderr,"op 0x%x call 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (const_args[0]) { -+ tcg_target_long off = (args[0] - (tcg_target_long)s->code_ptr + 4) >> 1; /* FIXME: + 4? Where did that come from? */ -+ if (off > -0x80000000 && off < 0x7fffffff) { /* relative call */ -+ tcg_out_brasl(s, TCG_REG_R14, off << 1); -+ tcg_abort(); // untested -+ } -+ else { /* too far for a relative call, load full address */ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, args[0]); -+ tcg_out_rr(s, RR_BASR, TCG_REG_R14, TCG_REG_R13); -+ } -+ } -+ else { /* call function in register args[0] */ -+ tcg_out_rr(s, RR_BASR, TCG_REG_R14, args[0]); -+ } -+ break; -+ case INDEX_op_jmp: -+ fprintf(stderr,"op 0x%x jmp 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_abort(); -+ break; -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ //fprintf(stderr,"op 0x%x ld8u_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if ((long)args[2] > -0x80000 && (long)args[2] < 0x7ffff) { -+ tcg_out_e3(s, E3_LLGC, args[0], args[1], args[2]); -+ } -+ else { /* displacement too large, have to calculate address manually */ -+ tcg_abort(); -+ } -+ break; -+ case INDEX_op_ld8s_i32: -+ fprintf(stderr,"op 0x%x ld8s_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_abort(); -+ break; -+ case INDEX_op_ld16u_i32: -+ fprintf(stderr,"op 0x%x ld16u_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if ((long)args[2] > -0x80000 && (long)args[2] < 0x7ffff) { -+ tcg_out_e3(s, E3_LLGH, args[0], args[1], args[2]); -+ } -+ else { /* displacement too large, have to calculate address manually */ -+ tcg_abort(); -+ } -+ break; -+ case INDEX_op_ld16s_i32: -+ fprintf(stderr,"op 0x%x ld16s_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_abort(); -+ break; -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld32u_i64: -+ tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]); -+ break; -+ case INDEX_op_ld32s_i64: -+ if (args[2] < -0x80000 || args[2] > 0x7ffff) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, args[2]); /* load the displacement */ -+ tcg_out_b9(s, B9_AGR, TCG_REG_R13, args[1]); /* add the address */ -+ tcg_out_e3(s, E3_LGF, args[0], TCG_REG_R13, 0); /* load the data (sign-extended) */ -+ } -+ else { -+ tcg_out_e3(s, E3_LGF, args[0], args[1], args[2]); /* load the data (sign-extended) */ -+ } -+ break; -+ case INDEX_op_ld_i64: -+ tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]); -+ break; -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ //fprintf(stderr,"op 0x%x st8_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (((long)args[2]) >= -0x800 && ((long)args[2]) < 0x800) -+ tcg_out_store(s, ST_STC, args[0], args[1], args[2]); -+ else if (((long)args[2]) >= -0x80000 && ((long)args[2]) < 0x80000) { -+ tcg_out_e3(s, E3_STCY, args[0], args[1], args[2]); /* FIXME: requires long displacement facility */ -+ tcg_abort(); // untested -+ } -+ else tcg_abort(); -+ break; -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ //fprintf(stderr,"op 0x%x st16_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (((long)args[2]) >= -0x800 && ((long)args[2]) < 0x800) -+ tcg_out_store(s, ST_STH, args[0], args[1], args[2]); -+ else if (((long)args[2]) >= -0x80000 && ((long)args[2]) < 0x80000) { -+ tcg_out_e3(s, E3_STHY, args[0], args[1], args[2]); /* FIXME: requires long displacement facility */ -+ tcg_abort(); // untested -+ } -+ else tcg_abort(); -+ break; -+ case INDEX_op_st_i32: -+ case INDEX_op_st32_i64: -+ tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]); -+ break; -+ case INDEX_op_st_i64: -+ tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]); -+ break; -+ case INDEX_op_mov_i32: -+ fprintf(stderr,"op 0x%x mov_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_abort(); -+ break; -+ case INDEX_op_movi_i32: -+ fprintf(stderr,"op 0x%x movi_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_abort(); -+ break; -+ case INDEX_op_add_i32: -+ if (const_args[2]) { -+ if (args[0] == args[1]) tcg_out_a7(s, A7_AHI, args[1], args[2]); -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); -+ tcg_out_a7(s, A7_AHI, args[0], args[2]); -+ } -+ } -+ else if (args[0] == args[1]) { -+ tcg_out_rr(s, RR_AR, args[1], args[2]); -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_rr(s, RR_AR, args[0], args[1]); -+ } -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); -+ tcg_out_rr(s, RR_AR, args[0], args[2]); -+ } -+ break; -+ case INDEX_op_sub_i32: -+ //fprintf(stderr,"op 0x%x sub_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (args[0] == args[1]) { -+ tcg_out_rr(s, RR_SR, args[1], args[2]); /* sr %ra0/1, %ra2 */ -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_rr(s, RR_LR, TCG_REG_R13, args[2]); /* lr %r13, %raa0/2 */ -+ tcg_out_rr(s, RR_LR, args[0], args[1]); /* lr %ra0/2, %ra1 */ -+ tcg_out_rr(s, RR_SR, args[0], TCG_REG_R13); /* sr %ra0/2, %r13 */ -+ } -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); /* lr %ra0, %ra1 */ -+ tcg_out_rr(s, RR_SR, args[0], args[2]); /* sr %ra0, %ra2 */ -+ } -+ break; -+ -+ case INDEX_op_sub_i64: -+ //fprintf(stderr,"op 0x%x sub_i64 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (args[0] == args[1]) { -+ tcg_out_b9(s, B9_SGR, args[1], args[2]); /* sgr %ra0/1, %ra2 */ -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_b9(s, B9_LGR, TCG_REG_R13, args[2]); /* lgr %r13, %raa0/2 */ -+ tcg_out_b9(s, B9_LGR, args[0], args[1]); /* lgr %ra0/2, %ra1 */ -+ tcg_out_b9(s, B9_SGR, args[0], TCG_REG_R13); /* sgr %ra0/2, %r13 */ -+ } -+ else { -+ tcg_out_b9(s, B9_LGR, args[0], args[1]); /* lgr %ra0, %ra1 */ -+ tcg_out_b9(s, B9_SGR, args[0], args[2]); /* sgr %ra0, %ra2 */ -+ } -+ break; -+ case INDEX_op_add_i64: -+ //fprintf(stderr,"op 0x%x add_i64 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (args[0] == args[1]) { -+ tcg_out_b9(s, B9_AGR, args[1], args[2]); -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_b9(s, B9_AGR, args[0], args[1]); -+ } -+ else { -+ tcg_out_b9(s, B9_LGR, args[0], args[1]); -+ tcg_out_b9(s, B9_AGR, args[0], args[2]); -+ } -+ break; -+ -+ case INDEX_op_and_i32: -+ op = RR_NR; -+do_logic_i32: -+ if (args[0] == args[1]) { -+ tcg_out_rr(s, op, args[1], args[2]); /* xr %ra0/1, %ra2 */ -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_rr(s, op, args[0], args[1]); /* xr %ra0/2, %ra1 */ -+ } -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); /* lr %ra0, %ra1 */ -+ tcg_out_rr(s, op, args[0], args[2]); /* xr %ra0, %ra2 */ -+ } -+ break; -+ case INDEX_op_or_i32: op = RR_OR; goto do_logic_i32; -+ case INDEX_op_xor_i32: op = RR_XR; goto do_logic_i32; -+ -+ case INDEX_op_and_i64: -+ //fprintf(stderr,"op 0x%x and_i64 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ op = B9_NGR; -+do_logic_i64: -+ if (args[0] == args[1]) { -+ tcg_out_b9(s, op, args[0], args[2]); -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_b9(s, op, args[0], args[1]); -+ } -+ else { -+ tcg_out_b9(s, B9_LGR, args[0], args[1]); -+ tcg_out_b9(s, op, args[0], args[2]); -+ } -+ break; -+ case INDEX_op_or_i64: op = B9_OGR; goto do_logic_i64; -+ case INDEX_op_xor_i64: op = B9_XGR; goto do_logic_i64; -+ -+ case INDEX_op_neg_i32: -+ //fprintf(stderr,"op 0x%x neg_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ /* FIXME: optimize args[0] != args[1] case */ -+ tcg_out_rr(s, RR_LR, 13, args[1]); -+ tcg_out32(s, 0xa7090000 | (args[0] << 20)); /* lghi %ra0, 0 */ -+ tcg_out_rr(s, RR_SR, args[0], 13); -+ break; -+ case INDEX_op_neg_i64: -+ //fprintf(stderr,"op 0x%x neg_i64 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ /* FIXME: optimize args[0] != args[1] case */ -+ tcg_out_b9(s, B9_LGR, 13, args[1]); -+ tcg_out32(s, 0xa7090000 | (args[0] << 20)); /* lghi %ra0, 0 */ -+ tcg_out_b9(s, B9_SGR, args[0], 13); -+ break; -+ -+ case INDEX_op_mul_i32: -+ //fprintf(stderr,"op 0x%x mul_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (args[0] == args[1]) -+ tcg_out32(s, 0xb2520000 | (args[0] << 4) | args[2]); /* msr %ra0/1, %ra2 */ -+ else if (args[0] == args[2]) -+ tcg_out32(s, 0xb2520000 | (args[0] << 4) | args[1]); /* msr %ra0/2, %ra1 */ -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); -+ tcg_out32(s, 0xb2520000 | (args[0] << 4) | args[2]); /* msr %ra0, %ra2 */ -+ } -+ break; -+ case INDEX_op_mul_i64: -+ //fprintf(stderr,"op 0x%x mul_i64 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ if (args[0] == args[1]) { -+ tcg_out_b9(s, B9_MSGR, args[0], args[2]); -+ } -+ else if (args[0] == args[2]) { -+ tcg_out_b9(s, B9_MSGR, args[0], args[1]); -+ } -+ else tcg_abort(); -+ break; -+ -+ case INDEX_op_divu_i32: -+ case INDEX_op_remu_i32: -+ //fprintf(stderr,"op 0x%x div/remu_i32 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R12, 0); -+ tcg_out_rr(s, RR_LR, TCG_REG_R13, args[1]); -+ tcg_out_b9(s, B9_DLR, TCG_REG_R12, args[2]); -+ if (opc == INDEX_op_divu_i32) -+ tcg_out_rr(s, RR_LR, args[0], TCG_REG_R13); /* quotient */ -+ else -+ tcg_out_rr(s, RR_LR, args[0], TCG_REG_R12); /* remainder */ -+ break; -+ -+ case INDEX_op_shl_i32: -+ op = SH32_SLL; op2 = SH64_SLLG; -+do_shift32: -+ if (const_args[2]) { -+ if (args[0] == args[1]) { -+ tcg_out_sh32(s, op, args[0], SH32_REG_NONE, args[2]); -+ } -+ else { -+ tcg_out_rr(s, RR_LR, args[0], args[1]); -+ tcg_out_sh32(s, op, args[0], SH32_REG_NONE, args[2]); -+ } -+ } -+ else { -+ if (args[0] == args[1]) { -+ tcg_out_sh32(s, op, args[0], args[2], 0); -+ } -+ else -+ tcg_out_sh64(s, op2, args[0], args[1], args[2], 0); -+ } -+ break; -+ case INDEX_op_shr_i32: op = SH32_SRL; op2 = SH64_SRLG; goto do_shift32; -+ case INDEX_op_sar_i32: op = SH32_SRA; op2 = SH64_SRAG; goto do_shift32; -+ -+ case INDEX_op_shl_i64: -+ op = SH64_SLLG; -+do_shift64: -+ if (const_args[2]) { -+ tcg_out_sh64(s, op, args[0], args[1], SH64_REG_NONE, args[2]); -+ } -+ else { -+ tcg_out_sh64(s, op, args[0], args[1], args[2], 0); -+ } -+ break; -+ case INDEX_op_shr_i64: op = SH64_SRLG; goto do_shift64; -+ case INDEX_op_sar_i64: op = SH64_SRAG; goto do_shift64; -+ -+ case INDEX_op_br: -+ //fprintf(stderr,"op 0x%x br 0x%lx 0x%lx 0x%lx\n",opc,args[0],args[1],args[2]); -+ l = &s->labels[args[0]]; -+ if (l->has_value) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, l->u.value); -+ } -+ else { -+ /* larl %r13, ... */ -+ tcg_out16(s, 0xc0d0); -+ tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, args[0], -2); -+ s->code_ptr += 4; -+ } -+ tcg_out_rr(s, RR_BASR, TCG_REG_R13, TCG_REG_R13); -+ break; -+ case INDEX_op_brcond_i64: -+ //fprintf(stderr,"op 0x%x brcond_i64 0x%lx 0x%lx (c %d) 0x%lx\n",opc,args[0],args[1],const_args[1],args[2]); -+ if (args[2] > TCG_COND_GT) { /* unsigned */ -+ tcg_out_b9(s, B9_CLGR, args[0], args[1]); /* clgr %ra0, %ra1 */ -+ } -+ else { /* signed */ -+ tcg_out_b9(s, B9_CGR, args[0], args[1]); /* cgr %ra0, %ra1 */ -+ } -+ goto do_brcond; -+ case INDEX_op_brcond_i32: -+ //fprintf(stderr,"op 0x%x brcond_i32 0x%lx 0x%lx (c %d) 0x%lx\n",opc,args[0],args[1],const_args[1],args[2]); -+ if (args[2] > TCG_COND_GT) { /* unsigned */ -+ tcg_out_rr(s, RR_CLR, args[0], args[1]); /* clr %ra0, %ra1 */ -+ } -+ else { /* signed */ -+ tcg_out_rr(s, RR_CR, args[0], args[1]); /* cr %ra0, %ra1 */ -+ } -+do_brcond: -+ l = &s->labels[args[3]]; -+ if (l->has_value) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, l->u.value); -+ } -+ else { -+ /* larl %r13, ... */ -+ tcg_out16(s, 0xc0d0); -+ tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, args[3], -2); -+ s->code_ptr += 4; -+ } -+ tcg_out16(s, 0x070d | (tcg_cond_to_s390_cond[args[2]] << 4)); /* bcr cond,%r13 */ -+ break; -+ -+ case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0); break; -+ case INDEX_op_qemu_ld8s: tcg_out_qemu_ld(s, args, 0 | 4); break; -+ case INDEX_op_qemu_ld16u: tcg_out_qemu_ld(s, args, 1); break; -+ case INDEX_op_qemu_ld16s: tcg_out_qemu_ld(s, args, 1 | 4); break; -+ case INDEX_op_qemu_ld32u: tcg_out_qemu_ld(s, args, 2); break; -+ case INDEX_op_qemu_ld32s: tcg_out_qemu_ld(s, args, 2 | 4); break; -+ case INDEX_op_qemu_ld64: tcg_out_qemu_ld(s, args, 3); break; -+ case INDEX_op_qemu_st8: tcg_out_qemu_st(s, args, 0); break; -+ case INDEX_op_qemu_st16: tcg_out_qemu_st(s, args, 1); break; -+ case INDEX_op_qemu_st32: tcg_out_qemu_st(s, args, 2); break; -+ case INDEX_op_qemu_st64: tcg_out_qemu_st(s, args, 3); break; -+ -+ default: -+ fprintf(stderr,"unimplemented opc 0x%x\n",opc); -+ tcg_abort(); -+ } -+} -+ -+static const TCGTargetOpDef s390_op_defs[] = { -+ { INDEX_op_exit_tb, { } }, -+ { INDEX_op_goto_tb, { } }, -+ { INDEX_op_call, { "ri" } }, -+ { INDEX_op_jmp, { "ri" } }, -+ { INDEX_op_br, { } }, -+ -+ { INDEX_op_mov_i32, { "r", "r" } }, -+ { INDEX_op_movi_i32, { "r" } }, -+ -+ { INDEX_op_ld8u_i32, { "r", "r" } }, -+ { INDEX_op_ld8s_i32, { "r", "r" } }, -+ { INDEX_op_ld16u_i32, { "r", "r" } }, -+ { INDEX_op_ld16s_i32, { "r", "r" } }, -+ { INDEX_op_ld_i32, { "r", "r" } }, -+ { INDEX_op_st8_i32, { "r", "r" } }, -+ { INDEX_op_st16_i32, { "r", "r" } }, -+ { INDEX_op_st_i32, { "r", "r" } }, -+ -+ { INDEX_op_add_i32, { "r", "r", "rI" } }, -+ { INDEX_op_sub_i32, { "r", "r", "r" } }, -+ { INDEX_op_mul_i32, { "r", "r", "r" } }, -+ -+ { INDEX_op_div_i32, { "r", "r", "r" } }, -+ { INDEX_op_divu_i32, { "r", "r", "r" } }, -+ { INDEX_op_rem_i32, { "r", "r", "r" } }, -+ { INDEX_op_remu_i32, { "r", "r", "r" } }, -+ -+ { INDEX_op_and_i32, { "r", "r", "r" } }, -+ { INDEX_op_or_i32, { "r", "r", "r" } }, -+ { INDEX_op_xor_i32, { "r", "r", "r" } }, -+ { INDEX_op_neg_i32, { "r", "r" } }, -+ -+ { INDEX_op_shl_i32, { "r", "r", "Ri" } }, -+ { INDEX_op_shr_i32, { "r", "r", "Ri" } }, -+ { INDEX_op_sar_i32, { "r", "r", "Ri" } }, -+ -+ { INDEX_op_brcond_i32, { "r", "r" } }, -+ -+ { INDEX_op_qemu_ld8u, { "r", "L" } }, -+ { INDEX_op_qemu_ld8s, { "r", "L" } }, -+ { INDEX_op_qemu_ld16u, { "r", "L" } }, -+ { INDEX_op_qemu_ld16s, { "r", "L" } }, -+ { INDEX_op_qemu_ld32u, { "r", "L" } }, -+ { INDEX_op_qemu_ld32s, { "r", "L" } }, -+ -+ { INDEX_op_qemu_st8, { "S", "S" } }, -+ { INDEX_op_qemu_st16, { "S", "S" } }, -+ { INDEX_op_qemu_st32, { "S", "S" } }, -+ -+#if defined(__s390x__) -+ { INDEX_op_mov_i64, { "r", "r" } }, -+ { INDEX_op_movi_i64, { "r" } }, -+ -+ { INDEX_op_ld8u_i64, { "r", "r" } }, -+ { INDEX_op_ld8s_i64, { "r", "r" } }, -+ { INDEX_op_ld16u_i64, { "r", "r" } }, -+ { INDEX_op_ld16s_i64, { "r", "r" } }, -+ { INDEX_op_ld32u_i64, { "r", "r" } }, -+ { INDEX_op_ld32s_i64, { "r", "r" } }, -+ { INDEX_op_ld_i64, { "r", "r" } }, -+ -+ { INDEX_op_st8_i64, { "r", "r" } }, -+ { INDEX_op_st16_i64, { "r", "r" } }, -+ { INDEX_op_st32_i64, { "r", "r" } }, -+ { INDEX_op_st_i64, { "r", "r" } }, -+ -+ { INDEX_op_qemu_ld64, { "L", "L" } }, -+ { INDEX_op_qemu_st64, { "S", "S" } }, -+ -+ { INDEX_op_add_i64, { "r", "r", "r" } }, -+ { INDEX_op_mul_i64, { "r", "r", "r" } }, -+ { INDEX_op_sub_i64, { "r", "r", "r" } }, -+ -+ { INDEX_op_and_i64, { "r", "r", "r" } }, -+ { INDEX_op_or_i64, { "r", "r", "r" } }, -+ { INDEX_op_xor_i64, { "r", "r", "r" } }, -+ { INDEX_op_neg_i64, { "r", "r" } }, -+ -+ { INDEX_op_shl_i64, { "r", "r", "Ri" } }, -+ { INDEX_op_shr_i64, { "r", "r", "Ri" } }, -+ { INDEX_op_sar_i64, { "r", "r", "Ri" } }, -+ -+ { INDEX_op_brcond_i64, { "r", "r" } }, -+#endif -+ -+ { -1 }, -+}; -+ -+void tcg_target_init(TCGContext *s) -+{ -+ /* fail safe */ -+ if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) -+ tcg_abort(); -+ -+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); -+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff); -+ tcg_regset_set32(tcg_target_call_clobber_regs, 0, -+ (1 << TCG_REG_R0) | -+ (1 << TCG_REG_R1) | -+ (1 << TCG_REG_R2) | -+ (1 << TCG_REG_R3) | -+ (1 << TCG_REG_R4) | -+ (1 << TCG_REG_R5) | -+ (1 << TCG_REG_R14)); /* link register */ -+ -+ tcg_regset_clear(s->reserved_regs); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* frequently used as a temporary */ -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* another temporary */ -+ -+ tcg_add_target_add_op_defs(s390_op_defs); -+} -+ -+void tcg_target_qemu_prologue(TCGContext *s) -+{ -+ tcg_out16(s,0xeb6f);tcg_out32(s,0xf0300024); /* stmg %r6,%r15,48(%r15) (save registers) */ -+ tcg_out32(s, 0xa7fbff60); /* aghi %r15,-160 (stack frame) */ -+ tcg_out16(s,0x7f2); /* br %r2 (go to TB) */ -+ tb_ret_addr = s->code_ptr; -+ tcg_out16(s,0xeb6f);tcg_out32(s, 0xf0d00004); /* lmg %r6,%r15,208(%r15) (restore registers) */ -+ tcg_out16(s,0x7fe); /* br %r14 (return) */ -+} -+ -+ -+static inline void tcg_out_mov(TCGContext *s, int ret, int arg) -+{ -+ tcg_out_b9(s, B9_LGR, ret, arg); -+} -+ -+static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) -+{ -+ tcg_abort(); -+} -diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h -new file mode 100644 -index 0000000..fcb28d1 ---- /dev/null -+++ b/tcg/s390/tcg-target.h -@@ -0,0 +1,76 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2009 Ulrich Hecht -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+#define TCG_TARGET_S390 1 -+ -+#define TCG_TARGET_REG_BITS 64 -+#define TCG_TARGET_WORDS_BIGENDIAN -+#define TCG_TARGET_HAS_div_i32 -+#undef TCG_TARGET_HAS_div_i64 -+#undef TCG_TARGET_HAS_bswap_i32 -+#define TCG_TARGET_HAS_neg_i32 -+#define TCG_TARGET_HAS_neg_i64 -+#undef TCG_TARGET_STACK_GROWSUP -+ -+enum { -+ TCG_REG_R0 = 0, -+ TCG_REG_R1, -+ TCG_REG_R2, -+ TCG_REG_R3, -+ TCG_REG_R4, -+ TCG_REG_R5, -+ TCG_REG_R6, -+ TCG_REG_R7, -+ TCG_REG_R8, -+ TCG_REG_R9, -+ TCG_REG_R10, -+ TCG_REG_R11, -+ TCG_REG_R12, -+ TCG_REG_R13, -+ TCG_REG_R14, -+ TCG_REG_R15 -+}; -+#define TCG_TARGET_NB_REGS 16 -+ -+/* used for function call generation */ -+#define TCG_REG_CALL_STACK TCG_REG_R15 -+#define TCG_TARGET_STACK_ALIGN 8 -+#define TCG_TARGET_CALL_STACK_OFFSET 0 -+ -+enum { -+ /* Note: must be synced with dyngen-exec.h */ -+ TCG_AREG0 = TCG_REG_R10, -+ TCG_AREG1 = TCG_REG_R7, -+ TCG_AREG2 = TCG_REG_R8, -+ TCG_AREG3 = TCG_REG_R9, -+}; -+ -+static inline void flush_icache_range(unsigned long start, unsigned long stop) -+{ -+#if QEMU_GNUC_PREREQ(4, 1) -+ void __clear_cache(char *beg, char *end); -+ __clear_cache((char *) start, (char *) stop); -+#else -+#error not implemented -+#endif -+} --- -1.6.2.1 - diff --git a/0024-linux-user-S-390-64-bit-s390x-support.patch b/0024-linux-user-S-390-64-bit-s390x-support.patch deleted file mode 100644 index b0dbfce5..00000000 --- a/0024-linux-user-S-390-64-bit-s390x-support.patch +++ /dev/null @@ -1,1350 +0,0 @@ -From af1a4af732202b6bdacc12bdef6e6a338a38ef67 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Fri, 24 Jul 2009 16:57:31 +0200 -Subject: [PATCH 24/33] linux-user: S/390 64-bit (s390x) support - -code for running 64-bit S/390 Linux binaries - -Signed-off-by: Ulrich Hecht ---- - linux-user/elfload.c | 18 ++ - linux-user/main.c | 82 +++++++++ - linux-user/s390x/syscall.h | 25 +++ - linux-user/s390x/syscall_nr.h | 348 ++++++++++++++++++++++++++++++++++++++ - linux-user/s390x/target_signal.h | 26 +++ - linux-user/s390x/termbits.h | 283 +++++++++++++++++++++++++++++++ - linux-user/signal.c | 314 ++++++++++++++++++++++++++++++++++ - linux-user/syscall.c | 16 ++- - linux-user/syscall_defs.h | 56 ++++++- - qemu-binfmt-conf.sh | 5 +- - 10 files changed, 1166 insertions(+), 7 deletions(-) - create mode 100644 linux-user/s390x/syscall.h - create mode 100644 linux-user/s390x/syscall_nr.h - create mode 100644 linux-user/s390x/target_signal.h - create mode 100644 linux-user/s390x/termbits.h - -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 3a8268b..896592d 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -679,6 +679,24 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - - #endif /* TARGET_ALPHA */ - -+#ifdef TARGET_S390X -+ -+#define ELF_START_MMAP (0x20000000000ULL) -+ -+#define elf_check_arch(x) ( (x) == ELF_ARCH ) -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_DATA ELFDATA2MSB -+#define ELF_ARCH EM_S390 -+ -+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) -+{ -+ regs->psw.addr = infop->entry; -+ regs->gprs[15] = infop->start_stack; -+} -+ -+#endif /* TARGET_S390X */ -+ - #ifndef ELF_PLATFORM - #define ELF_PLATFORM (NULL) - #endif -diff --git a/linux-user/main.c b/linux-user/main.c -index 9038b58..d2f62e0 100644 ---- a/linux-user/main.c -+++ b/linux-user/main.c -@@ -2304,6 +2304,79 @@ void cpu_loop (CPUState *env) - } - #endif /* TARGET_ALPHA */ - -+#ifdef TARGET_S390X -+void cpu_loop(CPUS390XState *env) -+{ -+ int trapnr; -+ target_siginfo_t info; -+ -+ while (1) { -+ trapnr = cpu_s390x_exec (env); -+ -+ if ((trapnr & 0xffff0000) == EXCP_EXECUTE_SVC) { -+ int n = trapnr & 0xffff; -+ env->regs[2] = do_syscall(env, n, -+ env->regs[2], -+ env->regs[3], -+ env->regs[4], -+ env->regs[5], -+ env->regs[6], -+ env->regs[7]); -+ } -+ else switch (trapnr) { -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ case EXCP_DEBUG: -+ { -+ int sig; -+ -+ sig = gdb_handlesig (env, TARGET_SIGTRAP); -+ if (sig) { -+ info.si_signo = sig; -+ info.si_errno = 0; -+ info.si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.si_signo, &info); -+ } -+ } -+ break; -+ case EXCP_SVC: -+ { -+ int n = ldub(env->psw.addr - 1); -+ if (!n) n = env->regs[1]; /* syscalls > 255 */ -+ env->regs[2] = do_syscall(env, n, -+ env->regs[2], -+ env->regs[3], -+ env->regs[4], -+ env->regs[5], -+ env->regs[6], -+ env->regs[7]); -+ } -+ break; -+ case EXCP_ADDR: -+ { -+ info.si_signo = SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = TARGET_SEGV_MAPERR; -+ info._sifields._sigfault._addr = env->__excp_addr; -+ queue_signal(env, info.si_signo, &info); -+ } -+ break; -+ default: -+ printf ("Unhandled trap: 0x%x\n", trapnr); -+ if (trapnr == 42) { /* unimplemented insn */ -+ fprintf(stderr,"insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4)); -+ } -+ cpu_dump_state(env, stderr, fprintf, 0); -+ exit (1); -+ } -+ process_pending_signals (env); -+ } -+} -+ -+#endif /* TARGET_S390X */ -+ - static void usage(void) - { - printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n" -@@ -2900,6 +2973,15 @@ int main(int argc, char **argv, char **envp) - env->regs[15] = regs->acr; - env->pc = regs->erp; - } -+#elif defined(TARGET_S390X) -+ { -+ int i; -+ for (i = 0; i < 16; i++) { -+ env->regs[i] = regs->gprs[i]; -+ } -+ env->psw.mask = regs->psw.mask; -+ env->psw.addr = regs->psw.addr; -+ } - #else - #error unsupported target CPU - #endif -diff --git a/linux-user/s390x/syscall.h b/linux-user/s390x/syscall.h -new file mode 100644 -index 0000000..a3812a8 ---- /dev/null -+++ b/linux-user/s390x/syscall.h -@@ -0,0 +1,25 @@ -+/* this typedef defines how a Program Status Word looks like */ -+typedef struct -+{ -+ abi_ulong mask; -+ abi_ulong addr; -+} __attribute__ ((aligned(8))) target_psw_t; -+ -+/* -+ * The pt_regs struct defines the way the registers are stored on -+ * the stack during a system call. -+ */ -+ -+#define TARGET_NUM_GPRS 16 -+ -+struct target_pt_regs -+{ -+ abi_ulong args[1]; -+ target_psw_t psw; -+ abi_ulong gprs[TARGET_NUM_GPRS]; -+ abi_ulong orig_gpr2; -+ unsigned short ilc; -+ unsigned short trap; -+}; -+ -+#define UNAME_MACHINE "s390x" -diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h -new file mode 100644 -index 0000000..4a60b9a ---- /dev/null -+++ b/linux-user/s390x/syscall_nr.h -@@ -0,0 +1,348 @@ -+/* -+ * This file contains the system call numbers. -+ */ -+ -+#define TARGET_NR_exit 1 -+#define TARGET_NR_fork 2 -+#define TARGET_NR_read 3 -+#define TARGET_NR_write 4 -+#define TARGET_NR_open 5 -+#define TARGET_NR_close 6 -+#define TARGET_NR_restart_syscall 7 -+#define TARGET_NR_creat 8 -+#define TARGET_NR_link 9 -+#define TARGET_NR_unlink 10 -+#define TARGET_NR_execve 11 -+#define TARGET_NR_chdir 12 -+#define TARGET_NR_mknod 14 -+#define TARGET_NR_chmod 15 -+#define TARGET_NR_lseek 19 -+#define TARGET_NR_getpid 20 -+#define TARGET_NR_mount 21 -+#define TARGET_NR_umount 22 -+#define TARGET_NR_ptrace 26 -+#define TARGET_NR_alarm 27 -+#define TARGET_NR_pause 29 -+#define TARGET_NR_utime 30 -+#define TARGET_NR_access 33 -+#define TARGET_NR_nice 34 -+#define TARGET_NR_sync 36 -+#define TARGET_NR_kill 37 -+#define TARGET_NR_rename 38 -+#define TARGET_NR_mkdir 39 -+#define TARGET_NR_rmdir 40 -+#define TARGET_NR_dup 41 -+#define TARGET_NR_pipe 42 -+#define TARGET_NR_times 43 -+#define TARGET_NR_brk 45 -+#define TARGET_NR_signal 48 -+#define TARGET_NR_acct 51 -+#define TARGET_NR_umount2 52 -+#define TARGET_NR_ioctl 54 -+#define TARGET_NR_fcntl 55 -+#define TARGET_NR_setpgid 57 -+#define TARGET_NR_umask 60 -+#define TARGET_NR_chroot 61 -+#define TARGET_NR_ustat 62 -+#define TARGET_NR_dup2 63 -+#define TARGET_NR_getppid 64 -+#define TARGET_NR_getpgrp 65 -+#define TARGET_NR_setsid 66 -+#define TARGET_NR_sigaction 67 -+#define TARGET_NR_sigsuspend 72 -+#define TARGET_NR_sigpending 73 -+#define TARGET_NR_sethostname 74 -+#define TARGET_NR_setrlimit 75 -+#define TARGET_NR_getrusage 77 -+#define TARGET_NR_gettimeofday 78 -+#define TARGET_NR_settimeofday 79 -+#define TARGET_NR_symlink 83 -+#define TARGET_NR_readlink 85 -+#define TARGET_NR_uselib 86 -+#define TARGET_NR_swapon 87 -+#define TARGET_NR_reboot 88 -+#define TARGET_NR_readdir 89 -+#define TARGET_NR_mmap 90 -+#define TARGET_NR_munmap 91 -+#define TARGET_NR_truncate 92 -+#define TARGET_NR_ftruncate 93 -+#define TARGET_NR_fchmod 94 -+#define TARGET_NR_getpriority 96 -+#define TARGET_NR_setpriority 97 -+#define TARGET_NR_statfs 99 -+#define TARGET_NR_fstatfs 100 -+#define TARGET_NR_socketcall 102 -+#define TARGET_NR_syslog 103 -+#define TARGET_NR_setitimer 104 -+#define TARGET_NR_getitimer 105 -+#define TARGET_NR_stat 106 -+#define TARGET_NR_lstat 107 -+#define TARGET_NR_fstat 108 -+#define TARGET_NR_lookup_dcookie 110 -+#define TARGET_NR_vhangup 111 -+#define TARGET_NR_idle 112 -+#define TARGET_NR_wait4 114 -+#define TARGET_NR_swapoff 115 -+#define TARGET_NR_sysinfo 116 -+#define TARGET_NR_ipc 117 -+#define TARGET_NR_fsync 118 -+#define TARGET_NR_sigreturn 119 -+#define TARGET_NR_clone 120 -+#define TARGET_NR_setdomainname 121 -+#define TARGET_NR_uname 122 -+#define TARGET_NR_adjtimex 124 -+#define TARGET_NR_mprotect 125 -+#define TARGET_NR_sigprocmask 126 -+#define TARGET_NR_create_module 127 -+#define TARGET_NR_init_module 128 -+#define TARGET_NR_delete_module 129 -+#define TARGET_NR_get_kernel_syms 130 -+#define TARGET_NR_quotactl 131 -+#define TARGET_NR_getpgid 132 -+#define TARGET_NR_fchdir 133 -+#define TARGET_NR_bdflush 134 -+#define TARGET_NR_sysfs 135 -+#define TARGET_NR_personality 136 -+#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ -+#define TARGET_NR_getdents 141 -+#define TARGET_NR_flock 143 -+#define TARGET_NR_msync 144 -+#define TARGET_NR_readv 145 -+#define TARGET_NR_writev 146 -+#define TARGET_NR_getsid 147 -+#define TARGET_NR_fdatasync 148 -+#define TARGET_NR__sysctl 149 -+#define TARGET_NR_mlock 150 -+#define TARGET_NR_munlock 151 -+#define TARGET_NR_mlockall 152 -+#define TARGET_NR_munlockall 153 -+#define TARGET_NR_sched_setparam 154 -+#define TARGET_NR_sched_getparam 155 -+#define TARGET_NR_sched_setscheduler 156 -+#define TARGET_NR_sched_getscheduler 157 -+#define TARGET_NR_sched_yield 158 -+#define TARGET_NR_sched_get_priority_max 159 -+#define TARGET_NR_sched_get_priority_min 160 -+#define TARGET_NR_sched_rr_get_interval 161 -+#define TARGET_NR_nanosleep 162 -+#define TARGET_NR_mremap 163 -+#define TARGET_NR_query_module 167 -+#define TARGET_NR_poll 168 -+#define TARGET_NR_nfsservctl 169 -+#define TARGET_NR_prctl 172 -+#define TARGET_NR_rt_sigreturn 173 -+#define TARGET_NR_rt_sigaction 174 -+#define TARGET_NR_rt_sigprocmask 175 -+#define TARGET_NR_rt_sigpending 176 -+#define TARGET_NR_rt_sigtimedwait 177 -+#define TARGET_NR_rt_sigqueueinfo 178 -+#define TARGET_NR_rt_sigsuspend 179 -+#define TARGET_NR_pread64 180 -+#define TARGET_NR_pwrite64 181 -+#define TARGET_NR_getcwd 183 -+#define TARGET_NR_capget 184 -+#define TARGET_NR_capset 185 -+#define TARGET_NR_sigaltstack 186 -+#define TARGET_NR_sendfile 187 -+#define TARGET_NR_getpmsg 188 -+#define TARGET_NR_putpmsg 189 -+#define TARGET_NR_vfork 190 -+#define TARGET_NR_pivot_root 217 -+#define TARGET_NR_mincore 218 -+#define TARGET_NR_madvise 219 -+#define TARGET_NR_getdents64 220 -+#define TARGET_NR_readahead 222 -+#define TARGET_NR_setxattr 224 -+#define TARGET_NR_lsetxattr 225 -+#define TARGET_NR_fsetxattr 226 -+#define TARGET_NR_getxattr 227 -+#define TARGET_NR_lgetxattr 228 -+#define TARGET_NR_fgetxattr 229 -+#define TARGET_NR_listxattr 230 -+#define TARGET_NR_llistxattr 231 -+#define TARGET_NR_flistxattr 232 -+#define TARGET_NR_removexattr 233 -+#define TARGET_NR_lremovexattr 234 -+#define TARGET_NR_fremovexattr 235 -+#define TARGET_NR_gettid 236 -+#define TARGET_NR_tkill 237 -+#define TARGET_NR_futex 238 -+#define TARGET_NR_sched_setaffinity 239 -+#define TARGET_NR_sched_getaffinity 240 -+#define TARGET_NR_tgkill 241 -+/* Number 242 is reserved for tux */ -+#define TARGET_NR_io_setup 243 -+#define TARGET_NR_io_destroy 244 -+#define TARGET_NR_io_getevents 245 -+#define TARGET_NR_io_submit 246 -+#define TARGET_NR_io_cancel 247 -+#define TARGET_NR_exit_group 248 -+#define TARGET_NR_epoll_create 249 -+#define TARGET_NR_epoll_ctl 250 -+#define TARGET_NR_epoll_wait 251 -+#define TARGET_NR_set_tid_address 252 -+#define TARGET_NR_fadvise64 253 -+#define TARGET_NR_timer_create 254 -+#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1) -+#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2) -+#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3) -+#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4) -+#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5) -+#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6) -+#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) -+#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) -+/* Number 263 is reserved for vserver */ -+#define TARGET_NR_statfs64 265 -+#define TARGET_NR_fstatfs64 266 -+#define TARGET_NR_remap_file_pages 267 -+/* Number 268 is reserved for new sys_mbind */ -+/* Number 269 is reserved for new sys_get_mempolicy */ -+/* Number 270 is reserved for new sys_set_mempolicy */ -+#define TARGET_NR_mq_open 271 -+#define TARGET_NR_mq_unlink 272 -+#define TARGET_NR_mq_timedsend 273 -+#define TARGET_NR_mq_timedreceive 274 -+#define TARGET_NR_mq_notify 275 -+#define TARGET_NR_mq_getsetattr 276 -+#define TARGET_NR_kexec_load 277 -+#define TARGET_NR_add_key 278 -+#define TARGET_NR_request_key 279 -+#define TARGET_NR_keyctl 280 -+#define TARGET_NR_waitid 281 -+#define TARGET_NR_ioprio_set 282 -+#define TARGET_NR_ioprio_get 283 -+#define TARGET_NR_inotify_init 284 -+#define TARGET_NR_inotify_add_watch 285 -+#define TARGET_NR_inotify_rm_watch 286 -+/* Number 287 is reserved for new sys_migrate_pages */ -+#define TARGET_NR_openat 288 -+#define TARGET_NR_mkdirat 289 -+#define TARGET_NR_mknodat 290 -+#define TARGET_NR_fchownat 291 -+#define TARGET_NR_futimesat 292 -+#define TARGET_NR_unlinkat 294 -+#define TARGET_NR_renameat 295 -+#define TARGET_NR_linkat 296 -+#define TARGET_NR_symlinkat 297 -+#define TARGET_NR_readlinkat 298 -+#define TARGET_NR_fchmodat 299 -+#define TARGET_NR_faccessat 300 -+#define TARGET_NR_pselect6 301 -+#define TARGET_NR_ppoll 302 -+#define TARGET_NR_unshare 303 -+#define TARGET_NR_set_robust_list 304 -+#define TARGET_NR_get_robust_list 305 -+#define TARGET_NR_splice 306 -+#define TARGET_NR_sync_file_range 307 -+#define TARGET_NR_tee 308 -+#define TARGET_NR_vmsplice 309 -+/* Number 310 is reserved for new sys_move_pages */ -+#define TARGET_NR_getcpu 311 -+#define TARGET_NR_epoll_pwait 312 -+#define TARGET_NR_utimes 313 -+#define TARGET_NR_fallocate 314 -+#define TARGET_NR_utimensat 315 -+#define TARGET_NR_signalfd 316 -+#define TARGET_NR_timerfd 317 -+#define TARGET_NR_eventfd 318 -+#define TARGET_NR_timerfd_create 319 -+#define TARGET_NR_timerfd_settime 320 -+#define TARGET_NR_timerfd_gettime 321 -+#define TARGET_NR_signalfd4 322 -+#define TARGET_NR_eventfd2 323 -+#define TARGET_NR_inotify_init1 324 -+#define TARGET_NR_pipe2 325 -+#define TARGET_NR_dup3 326 -+#define TARGET_NR_epoll_create1 327 -+#define NR_syscalls 328 -+ -+/* -+ * There are some system calls that are not present on 64 bit, some -+ * have a different name although they do the same (e.g. TARGET_NR_chown32 -+ * is TARGET_NR_chown on 64 bit). -+ */ -+#ifndef TARGET_S390X -+ -+#define TARGET_NR_time 13 -+#define TARGET_NR_lchown 16 -+#define TARGET_NR_setuid 23 -+#define TARGET_NR_getuid 24 -+#define TARGET_NR_stime 25 -+#define TARGET_NR_setgid 46 -+#define TARGET_NR_getgid 47 -+#define TARGET_NR_geteuid 49 -+#define TARGET_NR_getegid 50 -+#define TARGET_NR_setreuid 70 -+#define TARGET_NR_setregid 71 -+#define TARGET_NR_getrlimit 76 -+#define TARGET_NR_getgroups 80 -+#define TARGET_NR_setgroups 81 -+#define TARGET_NR_fchown 95 -+#define TARGET_NR_ioperm 101 -+#define TARGET_NR_setfsuid 138 -+#define TARGET_NR_setfsgid 139 -+#define TARGET_NR__llseek 140 -+#define TARGET_NR__newselect 142 -+#define TARGET_NR_setresuid 164 -+#define TARGET_NR_getresuid 165 -+#define TARGET_NR_setresgid 170 -+#define TARGET_NR_getresgid 171 -+#define TARGET_NR_chown 182 -+#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ -+#define TARGET_NR_mmap2 192 -+#define TARGET_NR_truncate64 193 -+#define TARGET_NR_ftruncate64 194 -+#define TARGET_NR_stat64 195 -+#define TARGET_NR_lstat64 196 -+#define TARGET_NR_fstat64 197 -+#define TARGET_NR_lchown32 198 -+#define TARGET_NR_getuid32 199 -+#define TARGET_NR_getgid32 200 -+#define TARGET_NR_geteuid32 201 -+#define TARGET_NR_getegid32 202 -+#define TARGET_NR_setreuid32 203 -+#define TARGET_NR_setregid32 204 -+#define TARGET_NR_getgroups32 205 -+#define TARGET_NR_setgroups32 206 -+#define TARGET_NR_fchown32 207 -+#define TARGET_NR_setresuid32 208 -+#define TARGET_NR_getresuid32 209 -+#define TARGET_NR_setresgid32 210 -+#define TARGET_NR_getresgid32 211 -+#define TARGET_NR_chown32 212 -+#define TARGET_NR_setuid32 213 -+#define TARGET_NR_setgid32 214 -+#define TARGET_NR_setfsuid32 215 -+#define TARGET_NR_setfsgid32 216 -+#define TARGET_NR_fcntl64 221 -+#define TARGET_NR_sendfile64 223 -+#define TARGET_NR_fadvise64_64 264 -+#define TARGET_NR_fstatat64 293 -+ -+#else -+ -+#define TARGET_NR_select 142 -+#define TARGET_NR_getrlimit 191 /* SuS compliant getrlimit */ -+#define TARGET_NR_lchown 198 -+#define TARGET_NR_getuid 199 -+#define TARGET_NR_getgid 200 -+#define TARGET_NR_geteuid 201 -+#define TARGET_NR_getegid 202 -+#define TARGET_NR_setreuid 203 -+#define TARGET_NR_setregid 204 -+#define TARGET_NR_getgroups 205 -+#define TARGET_NR_setgroups 206 -+#define TARGET_NR_fchown 207 -+#define TARGET_NR_setresuid 208 -+#define TARGET_NR_getresuid 209 -+#define TARGET_NR_setresgid 210 -+#define TARGET_NR_getresgid 211 -+#define TARGET_NR_chown 212 -+#define TARGET_NR_setuid 213 -+#define TARGET_NR_setgid 214 -+#define TARGET_NR_setfsuid 215 -+#define TARGET_NR_setfsgid 216 -+#define TARGET_NR_newfstatat 293 -+ -+#endif -+ -diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h -new file mode 100644 -index 0000000..b4816b0 ---- /dev/null -+++ b/linux-user/s390x/target_signal.h -@@ -0,0 +1,26 @@ -+#ifndef TARGET_SIGNAL_H -+#define TARGET_SIGNAL_H -+ -+#include "cpu.h" -+ -+typedef struct target_sigaltstack { -+ abi_ulong ss_sp; -+ int ss_flags; -+ abi_ulong ss_size; -+} target_stack_t; -+ -+/* -+ * sigaltstack controls -+ */ -+#define TARGET_SS_ONSTACK 1 -+#define TARGET_SS_DISABLE 2 -+ -+#define TARGET_MINSIGSTKSZ 2048 -+#define TARGET_SIGSTKSZ 8192 -+ -+static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state) -+{ -+ return state->regs[15]; -+} -+ -+#endif /* TARGET_SIGNAL_H */ -diff --git a/linux-user/s390x/termbits.h b/linux-user/s390x/termbits.h -new file mode 100644 -index 0000000..2a78a05 ---- /dev/null -+++ b/linux-user/s390x/termbits.h -@@ -0,0 +1,283 @@ -+/* -+ * include/asm-s390/termbits.h -+ * -+ * S390 version -+ * -+ * Derived from "include/asm-i386/termbits.h" -+ */ -+ -+#define TARGET_NCCS 19 -+struct target_termios { -+ unsigned int c_iflag; /* input mode flags */ -+ unsigned int c_oflag; /* output mode flags */ -+ unsigned int c_cflag; /* control mode flags */ -+ unsigned int c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[TARGET_NCCS]; /* control characters */ -+}; -+ -+struct target_termios2 { -+ unsigned int c_iflag; /* input mode flags */ -+ unsigned int c_oflag; /* output mode flags */ -+ unsigned int c_cflag; /* control mode flags */ -+ unsigned int c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[TARGET_NCCS]; /* control characters */ -+ unsigned int c_ispeed; /* input speed */ -+ unsigned int c_ospeed; /* output speed */ -+}; -+ -+struct target_ktermios { -+ unsigned int c_iflag; /* input mode flags */ -+ unsigned int c_oflag; /* output mode flags */ -+ unsigned int c_cflag; /* control mode flags */ -+ unsigned int c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[TARGET_NCCS]; /* control characters */ -+ unsigned int c_ispeed; /* input speed */ -+ unsigned int c_ospeed; /* output speed */ -+}; -+ -+/* c_cc characters */ -+#define TARGET_VINTR 0 -+#define TARGET_VQUIT 1 -+#define TARGET_VERASE 2 -+#define TARGET_VKILL 3 -+#define TARGET_VEOF 4 -+#define TARGET_VTIME 5 -+#define TARGET_VMIN 6 -+#define TARGET_VSWTC 7 -+#define TARGET_VSTART 8 -+#define TARGET_VSTOP 9 -+#define TARGET_VSUSP 10 -+#define TARGET_VEOL 11 -+#define TARGET_VREPRINT 12 -+#define TARGET_VDISCARD 13 -+#define TARGET_VWERASE 14 -+#define TARGET_VLNEXT 15 -+#define TARGET_VEOL2 16 -+ -+/* c_iflag bits */ -+#define TARGET_IGNBRK 0000001 -+#define TARGET_BRKINT 0000002 -+#define TARGET_IGNPAR 0000004 -+#define TARGET_PARMRK 0000010 -+#define TARGET_INPCK 0000020 -+#define TARGET_ISTRIP 0000040 -+#define TARGET_INLCR 0000100 -+#define TARGET_IGNCR 0000200 -+#define TARGET_ICRNL 0000400 -+#define TARGET_IUCLC 0001000 -+#define TARGET_IXON 0002000 -+#define TARGET_IXANY 0004000 -+#define TARGET_IXOFF 0010000 -+#define TARGET_IMAXBEL 0020000 -+#define TARGET_IUTF8 0040000 -+ -+/* c_oflag bits */ -+#define TARGET_OPOST 0000001 -+#define TARGET_OLCUC 0000002 -+#define TARGET_ONLCR 0000004 -+#define TARGET_OCRNL 0000010 -+#define TARGET_ONOCR 0000020 -+#define TARGET_ONLRET 0000040 -+#define TARGET_OFILL 0000100 -+#define TARGET_OFDEL 0000200 -+#define TARGET_NLDLY 0000400 -+#define TARGET_NL0 0000000 -+#define TARGET_NL1 0000400 -+#define TARGET_CRDLY 0003000 -+#define TARGET_CR0 0000000 -+#define TARGET_CR1 0001000 -+#define TARGET_CR2 0002000 -+#define TARGET_CR3 0003000 -+#define TARGET_TABDLY 0014000 -+#define TARGET_TAB0 0000000 -+#define TARGET_TAB1 0004000 -+#define TARGET_TAB2 0010000 -+#define TARGET_TAB3 0014000 -+#define TARGET_XTABS 0014000 -+#define TARGET_BSDLY 0020000 -+#define TARGET_BS0 0000000 -+#define TARGET_BS1 0020000 -+#define TARGET_VTDLY 0040000 -+#define TARGET_VT0 0000000 -+#define TARGET_VT1 0040000 -+#define TARGET_FFDLY 0100000 -+#define TARGET_FF0 0000000 -+#define TARGET_FF1 0100000 -+ -+/* c_cflag bit meaning */ -+#define TARGET_CBAUD 0010017 -+#define TARGET_B0 0000000 /* hang up */ -+#define TARGET_B50 0000001 -+#define TARGET_B75 0000002 -+#define TARGET_B110 0000003 -+#define TARGET_B134 0000004 -+#define TARGET_B150 0000005 -+#define TARGET_B200 0000006 -+#define TARGET_B300 0000007 -+#define TARGET_B600 0000010 -+#define TARGET_B1200 0000011 -+#define TARGET_B1800 0000012 -+#define TARGET_B2400 0000013 -+#define TARGET_B4800 0000014 -+#define TARGET_B9600 0000015 -+#define TARGET_B19200 0000016 -+#define TARGET_B38400 0000017 -+#define TARGET_EXTA B19200 -+#define TARGET_EXTB B38400 -+#define TARGET_CSIZE 0000060 -+#define TARGET_CS5 0000000 -+#define TARGET_CS6 0000020 -+#define TARGET_CS7 0000040 -+#define TARGET_CS8 0000060 -+#define TARGET_CSTOPB 0000100 -+#define TARGET_CREAD 0000200 -+#define TARGET_PARENB 0000400 -+#define TARGET_PARODD 0001000 -+#define TARGET_HUPCL 0002000 -+#define TARGET_CLOCAL 0004000 -+#define TARGET_CBAUDEX 0010000 -+#define TARGET_BOTHER 0010000 -+#define TARGET_B57600 0010001 -+#define TARGET_B115200 0010002 -+#define TARGET_B230400 0010003 -+#define TARGET_B460800 0010004 -+#define TARGET_B500000 0010005 -+#define TARGET_B576000 0010006 -+#define TARGET_B921600 0010007 -+#define TARGET_B1000000 0010010 -+#define TARGET_B1152000 0010011 -+#define TARGET_B1500000 0010012 -+#define TARGET_B2000000 0010013 -+#define TARGET_B2500000 0010014 -+#define TARGET_B3000000 0010015 -+#define TARGET_B3500000 0010016 -+#define TARGET_B4000000 0010017 -+#define TARGET_CIBAUD 002003600000 /* input baud rate */ -+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ -+#define TARGET_CRTSCTS 020000000000 /* flow control */ -+ -+#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ -+ -+/* c_lflag bits */ -+#define TARGET_ISIG 0000001 -+#define TARGET_ICANON 0000002 -+#define TARGET_XCASE 0000004 -+#define TARGET_ECHO 0000010 -+#define TARGET_ECHOE 0000020 -+#define TARGET_ECHOK 0000040 -+#define TARGET_ECHONL 0000100 -+#define TARGET_NOFLSH 0000200 -+#define TARGET_TOSTOP 0000400 -+#define TARGET_ECHOCTL 0001000 -+#define TARGET_ECHOPRT 0002000 -+#define TARGET_ECHOKE 0004000 -+#define TARGET_FLUSHO 0010000 -+#define TARGET_PENDIN 0040000 -+#define TARGET_IEXTEN 0100000 -+ -+/* tcflow() and TCXONC use these */ -+#define TARGET_TCOOFF 0 -+#define TARGET_TCOON 1 -+#define TARGET_TCIOFF 2 -+#define TARGET_TCION 3 -+ -+/* tcflush() and TCFLSH use these */ -+#define TARGET_TCIFLUSH 0 -+#define TARGET_TCOFLUSH 1 -+#define TARGET_TCIOFLUSH 2 -+ -+/* tcsetattr uses these */ -+#define TARGET_TCSANOW 0 -+#define TARGET_TCSADRAIN 1 -+#define TARGET_TCSAFLUSH 2 -+ -+/* -+ * include/asm-s390/ioctls.h -+ * -+ * S390 version -+ * -+ * Derived from "include/asm-i386/ioctls.h" -+ */ -+ -+/* 0x54 is just a magic number to make these relatively unique ('T') */ -+ -+#define TARGET_TCGETS 0x5401 -+#define TARGET_TCSETS 0x5402 -+#define TARGET_TCSETSW 0x5403 -+#define TARGET_TCSETSF 0x5404 -+#define TARGET_TCGETA 0x5405 -+#define TARGET_TCSETA 0x5406 -+#define TARGET_TCSETAW 0x5407 -+#define TARGET_TCSETAF 0x5408 -+#define TARGET_TCSBRK 0x5409 -+#define TARGET_TCXONC 0x540A -+#define TARGET_TCFLSH 0x540B -+#define TARGET_TIOCEXCL 0x540C -+#define TARGET_TIOCNXCL 0x540D -+#define TARGET_TIOCSCTTY 0x540E -+#define TARGET_TIOCGPGRP 0x540F -+#define TARGET_TIOCSPGRP 0x5410 -+#define TARGET_TIOCOUTQ 0x5411 -+#define TARGET_TIOCSTI 0x5412 -+#define TARGET_TIOCGWINSZ 0x5413 -+#define TARGET_TIOCSWINSZ 0x5414 -+#define TARGET_TIOCMGET 0x5415 -+#define TARGET_TIOCMBIS 0x5416 -+#define TARGET_TIOCMBIC 0x5417 -+#define TARGET_TIOCMSET 0x5418 -+#define TARGET_TIOCGSOFTCAR 0x5419 -+#define TARGET_TIOCSSOFTCAR 0x541A -+#define TARGET_FIONREAD 0x541B -+#define TARGET_TIOCINQ FIONREAD -+#define TARGET_TIOCLINUX 0x541C -+#define TARGET_TIOCCONS 0x541D -+#define TARGET_TIOCGSERIAL 0x541E -+#define TARGET_TIOCSSERIAL 0x541F -+#define TARGET_TIOCPKT 0x5420 -+#define TARGET_FIONBIO 0x5421 -+#define TARGET_TIOCNOTTY 0x5422 -+#define TARGET_TIOCSETD 0x5423 -+#define TARGET_TIOCGETD 0x5424 -+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ -+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ -+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ -+#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2) -+#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2) -+#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2) -+#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2) -+#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -+#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -+#define TARGET_TIOCGDEV _IOR('T',0x32, unsigned int) /* Get real dev no below /dev/console */ -+ -+#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -+#define TARGET_FIOCLEX 0x5451 -+#define TARGET_FIOASYNC 0x5452 -+#define TARGET_TIOCSERCONFIG 0x5453 -+#define TARGET_TIOCSERGWILD 0x5454 -+#define TARGET_TIOCSERSWILD 0x5455 -+#define TARGET_TIOCGLCKTRMIOS 0x5456 -+#define TARGET_TIOCSLCKTRMIOS 0x5457 -+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ -+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ -+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ -+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ -+ -+#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -+#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ -+#define TARGET_FIOQSIZE 0x545E -+ -+/* Used for packet mode */ -+#define TARGET_TIOCPKT_DATA 0 -+#define TARGET_TIOCPKT_FLUSHREAD 1 -+#define TARGET_TIOCPKT_FLUSHWRITE 2 -+#define TARGET_TIOCPKT_STOP 4 -+#define TARGET_TIOCPKT_START 8 -+#define TARGET_TIOCPKT_NOSTOP 16 -+#define TARGET_TIOCPKT_DOSTOP 32 -+ -+#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -+ -diff --git a/linux-user/signal.c b/linux-user/signal.c -index 1aa9eab..d8ed2e8 100644 ---- a/linux-user/signal.c -+++ b/linux-user/signal.c -@@ -3432,6 +3432,320 @@ long do_rt_sigreturn(CPUState *env) - return -TARGET_ENOSYS; - } - -+#elif defined(TARGET_S390X) -+ -+#define __NUM_GPRS 16 -+#define __NUM_FPRS 16 -+#define __NUM_ACRS 16 -+ -+#define S390_SYSCALL_SIZE 2 -+#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */ -+ -+#define _SIGCONTEXT_NSIG 64 -+#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ -+#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) -+#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) -+#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */ -+#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) -+ -+typedef struct -+{ -+ target_psw_t psw; -+ target_ulong gprs[__NUM_GPRS]; -+ unsigned int acrs[__NUM_ACRS]; -+} target_s390_regs_common; -+ -+typedef struct -+{ -+ unsigned int fpc; -+ double fprs[__NUM_FPRS]; -+} target_s390_fp_regs; -+ -+typedef struct -+{ -+ target_s390_regs_common regs; -+ target_s390_fp_regs fpregs; -+} target_sigregs; -+ -+struct target_sigcontext -+{ -+ target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; -+ target_sigregs *sregs; -+}; -+ -+typedef struct -+{ -+ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; -+ struct target_sigcontext sc; -+ target_sigregs sregs; -+ int signo; -+ uint8_t retcode[S390_SYSCALL_SIZE]; -+} sigframe; -+ -+struct target_ucontext { -+ target_ulong uc_flags; -+ struct target_ucontext *uc_link; -+ target_stack_t uc_stack; -+ target_sigregs uc_mcontext; -+ target_sigset_t uc_sigmask; /* mask last for extensibility */ -+}; -+ -+typedef struct -+{ -+ uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; -+ uint8_t retcode[S390_SYSCALL_SIZE]; -+ struct target_siginfo info; -+ struct target_ucontext uc; -+} rt_sigframe; -+ -+static inline abi_ulong -+get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size) -+{ -+ abi_ulong sp; -+ -+ /* Default to using normal stack */ -+ sp = env->regs[15]; -+ -+ /* This is the X/Open sanctioned signal stack switching. */ -+ if (ka->sa_flags & TARGET_SA_ONSTACK) { -+ if (! sas_ss_flags(sp)) -+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; -+ } -+ -+ /* This is the legacy signal stack switching. */ -+ else if (/* FIXME !user_mode(regs) */ 0 && -+ !(ka->sa_flags & TARGET_SA_RESTORER) && -+ ka->sa_restorer) { -+ sp = (abi_ulong) ka->sa_restorer; -+ } -+ -+ return (sp - frame_size) & -8ul; -+} -+ -+static void save_sigregs(CPUState *env, target_sigregs *sregs) -+{ -+ int i; -+ //save_access_regs(current->thread.acrs); FIXME -+ -+ /* Copy a 'clean' PSW mask to the user to avoid leaking -+ information about whether PER is currently on. */ -+ __put_user(env->psw.mask, &sregs->regs.psw.mask); -+ __put_user(env->psw.addr, &sregs->regs.psw.addr); -+ for (i = 0; i < 16; i++) -+ __put_user(env->regs[i], &sregs->regs.gprs[i]); -+ for (i = 0; i < 16; i++) -+ __put_user(env->aregs[i], &sregs->regs.acrs[i]); -+ /* -+ * We have to store the fp registers to current->thread.fp_regs -+ * to merge them with the emulated registers. -+ */ -+ //save_fp_regs(¤t->thread.fp_regs); FIXME -+ for (i = 0; i < 16; i++) -+ __put_user(env->fregs[i].i, &sregs->fpregs.fprs[i]); -+} -+ -+static void setup_frame(int sig, struct target_sigaction *ka, -+ target_sigset_t *set, CPUState *env) -+{ -+ sigframe *frame; -+ abi_ulong frame_addr; -+ -+ frame_addr = get_sigframe(ka, env, sizeof *frame); -+ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) -+ goto give_sigsegv; -+ -+ qemu_log("%s: 1\n", __FUNCTION__); -+ if (__put_user(set->sig[0], &frame->sc.oldmask[0])) -+ goto give_sigsegv; -+ -+ save_sigregs(env, &frame->sregs); -+ -+ __put_user((abi_ulong)&frame->sregs, (abi_ulong *)&frame->sc.sregs); -+ -+ /* Set up to return from userspace. If provided, use a stub -+ already in userspace. */ -+ if (ka->sa_flags & TARGET_SA_RESTORER) { -+ env->regs[14] = (unsigned long) -+ ka->sa_restorer | PSW_ADDR_AMODE; -+ } else { -+ env->regs[14] = (unsigned long) -+ frame->retcode | PSW_ADDR_AMODE; -+ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, -+ (uint16_t *)(frame->retcode))) -+ goto give_sigsegv; -+ } -+ -+ /* Set up backchain. */ -+ if (__put_user(env->regs[15], (abi_ulong *) frame)) -+ goto give_sigsegv; -+ -+ /* Set up registers for signal handler */ -+ env->regs[15] = (target_ulong) frame; -+ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; -+ -+ env->regs[2] = sig; //map_signal(sig); -+ env->regs[3] = (target_ulong) &frame->sc; -+ -+ /* We forgot to include these in the sigcontext. -+ To avoid breaking binary compatibility, they are passed as args. */ -+ env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; -+ env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; -+ -+ /* Place signal number on stack to allow backtrace from handler. */ -+ if (__put_user(env->regs[2], (int *) &frame->signo)) -+ goto give_sigsegv; -+ unlock_user_struct(frame, frame_addr, 1); -+ return; -+ -+give_sigsegv: -+ qemu_log("%s: give_sigsegv\n", __FUNCTION__); -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sig(TARGET_SIGSEGV); -+} -+ -+static void setup_rt_frame(int sig, struct target_sigaction *ka, -+ target_siginfo_t *info, -+ target_sigset_t *set, CPUState *env) -+{ -+ int i; -+ rt_sigframe *frame; -+ abi_ulong frame_addr; -+ -+ frame_addr = get_sigframe(ka, env, sizeof *frame); -+ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) -+ goto give_sigsegv; -+ -+ qemu_log("%s: 1\n", __FUNCTION__); -+ if (copy_siginfo_to_user(&frame->info, info)) -+ goto give_sigsegv; -+ -+ /* Create the ucontext. */ -+ __put_user(0, &frame->uc.uc_flags); -+ __put_user((abi_ulong)NULL, (abi_ulong*)&frame->uc.uc_link); -+ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp); -+ __put_user(sas_ss_flags(get_sp_from_cpustate(env)), -+ &frame->uc.uc_stack.ss_flags); -+ __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size); -+ save_sigregs(env, &frame->uc.uc_mcontext); -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) { -+ __put_user((abi_ulong)set->sig[i], (abi_ulong*)&frame->uc.uc_sigmask.sig[i]); -+ } -+ -+ /* Set up to return from userspace. If provided, use a stub -+ already in userspace. */ -+ if (ka->sa_flags & TARGET_SA_RESTORER) { -+ env->regs[14] = (unsigned long) -+ ka->sa_restorer | PSW_ADDR_AMODE; -+ } else { -+ env->regs[14] = (unsigned long) -+ frame->retcode | PSW_ADDR_AMODE; -+ if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, -+ (uint16_t *)(frame->retcode))) -+ goto give_sigsegv; -+ } -+ -+ /* Set up backchain. */ -+ if (__put_user(env->regs[15], (abi_ulong *) frame)) -+ goto give_sigsegv; -+ -+ /* Set up registers for signal handler */ -+ env->regs[15] = (target_ulong) frame; -+ env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; -+ -+ env->regs[2] = sig; //map_signal(sig); -+ env->regs[3] = (target_ulong) &frame->info; -+ env->regs[4] = (target_ulong) &frame->uc; -+ return; -+ -+give_sigsegv: -+ qemu_log("%s: give_sigsegv\n", __FUNCTION__); -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sig(TARGET_SIGSEGV); -+} -+ -+static int -+restore_sigregs(CPUState *env, target_sigregs *sc) -+{ -+ int err = 0; -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ err |= __get_user(env->regs[i], &sc->regs.gprs[i]); -+ } -+ -+ err |= __get_user(env->psw.mask, &sc->regs.psw.mask); -+ qemu_log("%s: sc->regs.psw.addr 0x%lx env->psw.addr 0x%lx\n", __FUNCTION__, sc->regs.psw.addr, env->psw.addr); -+ err |= __get_user(env->psw.addr, &sc->regs.psw.addr); -+ /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ -+ -+ for (i = 0; i < 16; i++) { -+ err |= __get_user(env->aregs[i], &sc->regs.acrs[i]); -+ } -+ for (i = 0; i < 16; i++) { -+ err |= __get_user(env->fregs[i].i, &sc->fpregs.fprs[i]); -+ } -+ -+ return err; -+} -+ -+long do_sigreturn(CPUState *env) -+{ -+ sigframe *frame; -+ abi_ulong frame_addr = env->regs[15]; -+ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); -+ target_sigset_t target_set; -+ sigset_t set; -+ -+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) -+ goto badframe; -+ if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) -+ goto badframe; -+ -+ target_to_host_sigset_internal(&set, &target_set); -+ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ -+ -+ if (restore_sigregs(env, &frame->sregs)) -+ goto badframe; -+ -+ unlock_user_struct(frame, frame_addr, 0); -+ return env->regs[2]; -+ -+badframe: -+ unlock_user_struct(frame, frame_addr, 0); -+ force_sig(TARGET_SIGSEGV); -+ return 0; -+} -+ -+long do_rt_sigreturn(CPUState *env) -+{ -+ rt_sigframe *frame; -+ abi_ulong frame_addr = env->regs[15]; -+ qemu_log("%s: frame_addr 0x%lx\n", __FUNCTION__, frame_addr); -+ sigset_t set; -+ -+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) -+ goto badframe; -+ target_to_host_sigset(&set, &frame->uc.uc_sigmask); -+ -+ sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ -+ -+ if (restore_sigregs(env, &frame->uc.uc_mcontext)) -+ goto badframe; -+ -+ if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0, -+ get_sp_from_cpustate(env)) == -EFAULT) -+ goto badframe; -+ unlock_user_struct(frame, frame_addr, 0); -+ return env->regs[2]; -+ -+badframe: -+ unlock_user_struct(frame, frame_addr, 0); -+ force_sig(TARGET_SIGSEGV); -+ return 0; -+} -+ - #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) - - /* FIXME: Many of the structures are defined for both PPC and PPC64, but -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 548be54..e9b07df 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -5107,7 +5107,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - ret = get_errno(settimeofday(&tv, NULL)); - } - break; --#ifdef TARGET_NR_select -+#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390) - case TARGET_NR_select: - { - struct target_sel_arg_struct *sel; -@@ -5214,7 +5214,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - #endif - #ifdef TARGET_NR_mmap - case TARGET_NR_mmap: --#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) -+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \ -+ defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \ -+ || defined(TARGET_S390X) - { - abi_ulong *v; - abi_ulong v1, v2, v3, v4, v5, v6; -@@ -5698,6 +5700,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); - #elif defined(TARGET_CRIS) - ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5)); -+#elif defined(TARGET_S390X) -+ ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); - #else - ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); - #endif -@@ -5904,8 +5908,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - break; - #endif /* TARGET_NR_getdents64 */ --#ifdef TARGET_NR__newselect -+#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) -+#ifdef TARGET_S390X -+ case TARGET_NR_select: -+#else - case TARGET_NR__newselect: -+#endif - ret = do_select(arg1, arg2, arg3, arg4, arg5); - break; - #endif -@@ -6129,7 +6137,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - goto unimplemented; - case TARGET_NR_sigaltstack: - #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \ -- defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) -+ defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_S390X) - ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env)); - break; - #else -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 0cbe396..0f4fbd7 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -55,7 +55,7 @@ - #endif - - #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ -- || defined(TARGET_M68K) || defined(TARGET_CRIS) -+ || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_S390X) - - #define TARGET_IOC_SIZEBITS 14 - #define TARGET_IOC_DIRBITS 2 -@@ -315,7 +315,10 @@ struct target_sigaction; - int do_sigaction(int sig, const struct target_sigaction *act, - struct target_sigaction *oact); - --#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) -+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || \ -+ defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || \ -+ defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ -+ defined(TARGET_MICROBLAZE) || defined(TARGET_S390X) - - #if defined(TARGET_SPARC) - #define TARGET_SA_NOCLDSTOP 8u -@@ -1617,6 +1620,27 @@ struct target_stat { - - abi_long __unused[3]; - }; -+#elif defined(TARGET_S390X) -+struct target_stat { -+ abi_ulong st_dev; -+ abi_ulong st_ino; -+ abi_ulong st_nlink; -+ unsigned int st_mode; -+ unsigned int st_uid; -+ unsigned int st_gid; -+ unsigned int __pad1; -+ abi_ulong st_rdev; -+ abi_ulong st_size; -+ abi_ulong target_st_atime; -+ abi_ulong target_st_atime_nsec; -+ abi_ulong target_st_mtime; -+ abi_ulong target_st_mtime_nsec; -+ abi_ulong target_st_ctime; -+ abi_ulong target_st_ctime_nsec; -+ abi_ulong st_blksize; -+ abi_long st_blocks; -+ abi_ulong __unused[3]; -+}; - #else - #error unsupported CPU - #endif -@@ -1703,6 +1727,34 @@ struct target_statfs64 { - abi_long f_frsize; - abi_long f_spare[5]; - }; -+#elif defined(TARGET_S390X) -+struct target_statfs { -+ int32_t f_type; -+ int32_t f_bsize; -+ abi_long f_blocks; -+ abi_long f_bfree; -+ abi_long f_bavail; -+ abi_long f_files; -+ abi_long f_ffree; -+ kernel_fsid_t f_fsid; -+ int32_t f_namelen; -+ int32_t f_frsize; -+ int32_t f_spare[5]; -+}; -+ -+struct target_statfs64 { -+ int32_t f_type; -+ int32_t f_bsize; -+ abi_long f_blocks; -+ abi_long f_bfree; -+ abi_long f_bavail; -+ abi_long f_files; -+ abi_long f_ffree; -+ kernel_fsid_t f_fsid; -+ int32_t f_namelen; -+ int32_t f_frsize; -+ int32_t f_spare[5]; -+}; - #else - struct target_statfs { - uint32_t f_type; -diff --git a/qemu-binfmt-conf.sh b/qemu-binfmt-conf.sh -index 67d6728..e676f57 100644 ---- a/qemu-binfmt-conf.sh -+++ b/qemu-binfmt-conf.sh -@@ -1,5 +1,5 @@ - #!/bin/sh --# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC program execution by the kernel -+# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel - - # load the binfmt_misc module - if [ ! -d /proc/sys/fs/binfmt_misc ]; then -@@ -60,3 +60,6 @@ if [ $cpu != "mips" ] ; then - echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register - echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register - fi -+if [ $cpu != "s390x" ] ; then -+ echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register -+fi --- -1.6.2.1 - diff --git a/0025-linux-user-don-t-do-locking-in-single-threaded-proc.patch b/0025-linux-user-don-t-do-locking-in-single-threaded-proc.patch deleted file mode 100644 index 13962d4a..00000000 --- a/0025-linux-user-don-t-do-locking-in-single-threaded-proc.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 603d882c9c1c61475a69f657a9550bb335bf3ca9 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Wed, 22 Jul 2009 14:03:19 +0200 -Subject: [PATCH 25/33] linux-user: don't do locking in single-threaded processes - -Skips setting the tb_lock if a process doesn't have more than one thread, -which is usually the case. Results in about 20% performance gain (measured -with the s390x target, but the effect should be similar with other targets). - -Signed-off-by: Ulrich Hecht ---- - cpu-defs.h | 8 ++++++++ - cpu-exec.c | 14 ++++++++++++-- - linux-user/syscall.c | 1 + - 3 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/cpu-defs.h b/cpu-defs.h -index d73ec0a..27e5bb2 100644 ---- a/cpu-defs.h -+++ b/cpu-defs.h -@@ -135,6 +135,13 @@ typedef struct CPUWatchpoint { - } CPUWatchpoint; - - #define CPU_TEMP_BUF_NLONGS 128 -+ -+#ifdef CONFIG_USER_ONLY -+#define MULTITHREAD uint32_t multithreaded; -+#else -+#define MULTITHREAD -+#endif -+ - #define CPU_COMMON \ - struct TranslationBlock *current_tb; /* currently executing TB */ \ - /* soft mmu support */ \ -@@ -149,6 +156,7 @@ typedef struct CPUWatchpoint { - uint32_t stop; /* Stop request */ \ - uint32_t stopped; /* Artificially stopped */ \ - uint32_t interrupt_request; \ -+ MULTITHREAD /* needs locking when accessing TBs */ \ - volatile sig_atomic_t exit_request; \ - /* The meaning of the MMU modes is defined in the target code. */ \ - CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \ -diff --git a/cpu-exec.c b/cpu-exec.c -index 855ea3e..1371ce4 100644 ---- a/cpu-exec.c -+++ b/cpu-exec.c -@@ -219,6 +219,9 @@ int cpu_exec(CPUState *env1) - TranslationBlock *tb; - uint8_t *tc_ptr; - unsigned long next_tb; -+#ifdef CONFIG_USER_ONLY -+ uint32_t multithreaded; -+#endif - - if (cpu_halted(env1) == EXCP_HALTED) - return EXCP_HALTED; -@@ -604,7 +607,11 @@ int cpu_exec(CPUState *env1) - #endif - } - #endif -- spin_lock(&tb_lock); -+#ifdef CONFIG_USER_ONLY -+ multithreaded = env->multithreaded; -+ if (multithreaded) -+#endif -+ spin_lock(&tb_lock); - tb = tb_find_fast(); - /* Note: we do it here to avoid a gcc bug on Mac OS X when - doing it in tb_find_slow */ -@@ -632,7 +639,10 @@ int cpu_exec(CPUState *env1) - tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); - } - } -- spin_unlock(&tb_lock); -+#ifdef CONFIG_USER_ONLY -+ if (multithreaded) -+#endif -+ spin_unlock(&tb_lock); - env->current_tb = tb; - - /* cpu_interrupt might be called while translating the -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index e9b07df..f7a411d 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -3560,6 +3560,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, - ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE); - init_task_state(ts); - new_stack = ts->stack; -+ env->multithreaded = 1; - /* we create a new CPU instance. */ - new_env = cpu_copy(env); - /* Init regs that differ from the parent. */ --- -1.6.2.1 - diff --git a/0026-linux-user-dup3-fallocate-syscalls.patch b/0026-linux-user-dup3-fallocate-syscalls.patch deleted file mode 100644 index a76a81fd..00000000 --- a/0026-linux-user-dup3-fallocate-syscalls.patch +++ /dev/null @@ -1,80 +0,0 @@ -From ad0b7fcf697651a156c0e4a2911dd9fa69fd011c Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 14:33:36 +0200 -Subject: [PATCH 26/33] linux-user: dup3, fallocate syscalls - -implementations of dup3 and fallocate that are good enough to fool LTP - -Signed-off-by: Ulrich Hecht ---- - configure | 18 ++++++++++++++++++ - linux-user/syscall.c | 10 ++++++++++ - 2 files changed, 28 insertions(+), 0 deletions(-) - -diff --git a/configure b/configure -index e0874b5..4be25f6 100755 ---- a/configure -+++ b/configure -@@ -1355,6 +1355,21 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then - splice=yes - fi - -+# check for fallocate -+fallocate=no -+cat > $TMPC << EOF -+#include -+ -+int main(void) -+{ -+ fallocate(0, 0, 0, 0); -+ return 0; -+} -+EOF -+if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then -+ fallocate=yes -+fi -+ - # Check if tools are available to build documentation. - if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then - build_docs="no" -@@ -1707,6 +1722,9 @@ fi - if test "$splice" = "yes" ; then - echo "#define CONFIG_SPLICE 1" >> $config_host_h - fi -+if test "$fallocate" = "yes" ; then -+ echo "#define CONFIG_FALLOCATE 1" >> $config_host_h -+fi - if test "$inotify" = "yes" ; then - echo "#define CONFIG_INOTIFY 1" >> $config_host_h - fi -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index f7a411d..4fb7998 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -4750,6 +4750,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_NR_dup2: - ret = get_errno(dup2(arg1, arg2)); - break; -+#ifdef TARGET_NR_dup3 -+ case TARGET_NR_dup3: -+ ret = get_errno(dup3(arg1, arg2, arg3)); -+ break; -+#endif - #ifdef TARGET_NR_getppid /* not on alpha */ - case TARGET_NR_getppid: - ret = get_errno(getppid()); -@@ -7016,6 +7021,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - #endif - -+#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate) -+ case TARGET_NR_fallocate: -+ ret = get_errno(fallocate(arg1, arg2, arg3, arg4)); -+ break; -+#endif - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); --- -1.6.2.1 - diff --git a/0027-linux-user-fcntl-fixes-for-LTP.patch b/0027-linux-user-fcntl-fixes-for-LTP.patch deleted file mode 100644 index 5aa4c315..00000000 --- a/0027-linux-user-fcntl-fixes-for-LTP.patch +++ /dev/null @@ -1,171 +0,0 @@ -From e4f2e031fe5b5f9f11560a51ce607ffdd3090c05 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 15:10:30 +0200 -Subject: [PATCH 27/33] linux-user: fcntl fixes for LTP - -Fixes swaps on l_pid which were pretty much of random size. Implements -F_SETLEASE, F_GETLEASE. Now passes all LTP fcntl tests. - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 34 ++++++++++++++++++++++------------ - linux-user/syscall_defs.h | 7 +++++++ - 2 files changed, 29 insertions(+), 12 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 4fb7998..86754f1 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -3705,6 +3705,14 @@ static int target_to_host_fcntl_cmd(int cmd) - case TARGET_F_SETLKW64: - return F_SETLKW64; - #endif -+ case TARGET_F_SETLEASE: -+ return F_SETLEASE; -+ case TARGET_F_GETLEASE: -+ return F_GETLEASE; -+ case TARGET_F_DUPFD_CLOEXEC: -+ return F_DUPFD_CLOEXEC; -+ case TARGET_F_NOTIFY: -+ return F_NOTIFY; - default: - return -TARGET_EINVAL; - } -@@ -3731,7 +3739,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswapl(target_fl->l_start); - fl.l_len = tswapl(target_fl->l_len); -- fl.l_pid = tswapl(target_fl->l_pid); -+ fl.l_pid = tswap32(target_fl->l_pid); - unlock_user_struct(target_fl, arg, 0); - ret = get_errno(fcntl(fd, host_cmd, &fl)); - if (ret == 0) { -@@ -3741,7 +3749,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - target_fl->l_whence = tswap16(fl.l_whence); - target_fl->l_start = tswapl(fl.l_start); - target_fl->l_len = tswapl(fl.l_len); -- target_fl->l_pid = tswapl(fl.l_pid); -+ target_fl->l_pid = tswap32(fl.l_pid); - unlock_user_struct(target_fl, arg, 1); - } - break; -@@ -3754,7 +3762,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswapl(target_fl->l_start); - fl.l_len = tswapl(target_fl->l_len); -- fl.l_pid = tswapl(target_fl->l_pid); -+ fl.l_pid = tswap32(target_fl->l_pid); - unlock_user_struct(target_fl, arg, 0); - ret = get_errno(fcntl(fd, host_cmd, &fl)); - break; -@@ -3766,7 +3774,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - fl64.l_whence = tswap16(target_fl64->l_whence); - fl64.l_start = tswapl(target_fl64->l_start); - fl64.l_len = tswapl(target_fl64->l_len); -- fl64.l_pid = tswap16(target_fl64->l_pid); -+ fl64.l_pid = tswap32(target_fl64->l_pid); - unlock_user_struct(target_fl64, arg, 0); - ret = get_errno(fcntl(fd, host_cmd, &fl64)); - if (ret == 0) { -@@ -3776,7 +3784,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - target_fl64->l_whence = tswap16(fl64.l_whence); - target_fl64->l_start = tswapl(fl64.l_start); - target_fl64->l_len = tswapl(fl64.l_len); -- target_fl64->l_pid = tswapl(fl64.l_pid); -+ target_fl64->l_pid = tswap32(fl64.l_pid); - unlock_user_struct(target_fl64, arg, 1); - } - break; -@@ -3788,7 +3796,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - fl64.l_whence = tswap16(target_fl64->l_whence); - fl64.l_start = tswapl(target_fl64->l_start); - fl64.l_len = tswapl(target_fl64->l_len); -- fl64.l_pid = tswap16(target_fl64->l_pid); -+ fl64.l_pid = tswap32(target_fl64->l_pid); - unlock_user_struct(target_fl64, arg, 0); - ret = get_errno(fcntl(fd, host_cmd, &fl64)); - break; -@@ -3808,6 +3816,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) - case TARGET_F_GETOWN: - case TARGET_F_SETSIG: - case TARGET_F_GETSIG: -+ case TARGET_F_SETLEASE: -+ case TARGET_F_GETLEASE: - ret = get_errno(fcntl(fd, host_cmd, arg)); - break; - -@@ -6630,7 +6640,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - fl.l_whence = tswap16(target_efl->l_whence); - fl.l_start = tswap64(target_efl->l_start); - fl.l_len = tswap64(target_efl->l_len); -- fl.l_pid = tswapl(target_efl->l_pid); -+ fl.l_pid = tswap32(target_efl->l_pid); - unlock_user_struct(target_efl, arg3, 0); - } else - #endif -@@ -6641,7 +6651,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswap64(target_fl->l_start); - fl.l_len = tswap64(target_fl->l_len); -- fl.l_pid = tswapl(target_fl->l_pid); -+ fl.l_pid = tswap32(target_fl->l_pid); - unlock_user_struct(target_fl, arg3, 0); - } - ret = get_errno(fcntl(arg1, cmd, &fl)); -@@ -6654,7 +6664,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - target_efl->l_whence = tswap16(fl.l_whence); - target_efl->l_start = tswap64(fl.l_start); - target_efl->l_len = tswap64(fl.l_len); -- target_efl->l_pid = tswapl(fl.l_pid); -+ target_efl->l_pid = tswap32(fl.l_pid); - unlock_user_struct(target_efl, arg3, 1); - } else - #endif -@@ -6665,7 +6675,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - target_fl->l_whence = tswap16(fl.l_whence); - target_fl->l_start = tswap64(fl.l_start); - target_fl->l_len = tswap64(fl.l_len); -- target_fl->l_pid = tswapl(fl.l_pid); -+ target_fl->l_pid = tswap32(fl.l_pid); - unlock_user_struct(target_fl, arg3, 1); - } - } -@@ -6681,7 +6691,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - fl.l_whence = tswap16(target_efl->l_whence); - fl.l_start = tswap64(target_efl->l_start); - fl.l_len = tswap64(target_efl->l_len); -- fl.l_pid = tswapl(target_efl->l_pid); -+ fl.l_pid = tswap32(target_efl->l_pid); - unlock_user_struct(target_efl, arg3, 0); - } else - #endif -@@ -6692,7 +6702,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswap64(target_fl->l_start); - fl.l_len = tswap64(target_fl->l_len); -- fl.l_pid = tswapl(target_fl->l_pid); -+ fl.l_pid = tswap32(target_fl->l_pid); - unlock_user_struct(target_fl, arg3, 0); - } - ret = get_errno(fcntl(arg1, cmd, &fl)); -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 0f4fbd7..481ce59 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -1824,6 +1824,13 @@ struct target_statfs64 { - #define TARGET_F_SETLK64 13 - #define TARGET_F_SETLKW64 14 - #endif -+ -+#define TARGET_F_LINUX_SPECIFIC_BASE 1024 -+#define TARGET_F_SETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 0) -+#define TARGET_F_GETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 1) -+#define TARGET_F_DUPFD_CLOEXEC (TARGET_F_LINUX_SPECIFIC_BASE + 6) -+#define TARGET_F_NOTIFY (TARGET_F_LINUX_SPECIFIC_BASE+2) -+ - #if defined (TARGET_ARM) - #define TARGET_O_ACCMODE 0003 - #define TARGET_O_RDONLY 00 --- -1.6.2.1 - diff --git a/0028-linux-user-enable-getdents-for-32-bit-systems.patch b/0028-linux-user-enable-getdents-for-32-bit-systems.patch deleted file mode 100644 index 4ad79dde..00000000 --- a/0028-linux-user-enable-getdents-for-32-bit-systems.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0a1fc6cfd1798da391335a37ce7f3fd6141c7ff5 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 17:17:32 +0200 -Subject: [PATCH 28/33] linux-user: enable getdents for > 32-bit systems - -works perfectly fine with the example from getdents(2) and passes the LTP -tests (tested with s390x on x86_64 emulation) - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 6 +----- - 1 files changed, 1 insertions(+), 5 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 86754f1..49dfb40 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -195,9 +195,7 @@ static int gettid(void) { - return -ENOSYS; - } - #endif --#if TARGET_ABI_BITS == 32 - _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count); --#endif - #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) - _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count); - #endif -@@ -5820,9 +5818,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - break; - #endif - case TARGET_NR_getdents: --#if TARGET_ABI_BITS != 32 -- goto unimplemented; --#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 -+#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 - { - struct target_dirent *target_dirp; - struct linux_dirent *dirp; --- -1.6.2.1 - diff --git a/0029-linux-user-define-a-couple-of-syscalls-for-non-uid1.patch b/0029-linux-user-define-a-couple-of-syscalls-for-non-uid1.patch deleted file mode 100644 index 99079775..00000000 --- a/0029-linux-user-define-a-couple-of-syscalls-for-non-uid1.patch +++ /dev/null @@ -1,271 +0,0 @@ -From d9c50cda4f12fc4c64b8b494a298659b8ad341ed Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 17:41:57 +0200 -Subject: [PATCH 29/33] linux-user: define a couple of syscalls for non-uid16 targets - -Quite a number of syscalls are only defined on systems with USE_UID16 -defined; this patch defines them on other systems as well. - -Fixes a large number of uid/gid-related testcases on the s390x target -(and most likely on other targets as well) - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 125 ++++++++++++++++++++++++++++++++++++++++++-------- - 1 files changed, 105 insertions(+), 20 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 49dfb40..b1ef3c9 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -309,7 +309,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode) - return (fchmodat(dirfd, pathname, mode, 0)); - } - #endif --#if defined(TARGET_NR_fchownat) && defined(USE_UID16) -+#if defined(TARGET_NR_fchownat) - static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, - gid_t group, int flags) - { -@@ -418,7 +418,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode) - #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) - _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) - #endif --#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16) -+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) - _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, - uid_t,owner,gid_t,group,int,flags) - #endif -@@ -6382,18 +6382,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_NR_setfsgid: - ret = get_errno(setfsgid(arg1)); - break; -+#else /* USE_UID16 */ -+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) -+ case TARGET_NR_fchownat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5)); -+ unlock_user(p, arg2, 0); -+ break; -+#endif - #endif /* USE_UID16 */ - --#ifdef TARGET_NR_lchown32 -+#if defined(TARGET_NR_lchown32) || !defined(USE_UID16) -+#if defined(TARGET_NR_lchown32) - case TARGET_NR_lchown32: -+#else -+ case TARGET_NR_lchown: -+#endif - if (!(p = lock_user_string(arg1))) - goto efault; - ret = get_errno(lchown(p, arg2, arg3)); - unlock_user(p, arg1, 0); - break; - #endif --#ifdef TARGET_NR_getuid32 -+#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && !defined(USE_UID16)) -+#if defined(TARGET_NR_getuid32) - case TARGET_NR_getuid32: -+#else -+ case TARGET_NR_getuid: -+#endif - ret = get_errno(getuid()); - break; - #endif -@@ -6421,33 +6438,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - break; - #endif - --#ifdef TARGET_NR_getgid32 -+#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && !defined(USE_UID16)) -+#if defined(TARGET_NR_getgid32) - case TARGET_NR_getgid32: -+#else -+ case TARGET_NR_getgid: -+#endif - ret = get_errno(getgid()); - break; - #endif --#ifdef TARGET_NR_geteuid32 -+#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && !defined(USE_UID16)) -+#if defined(TARGET_NR_geteuid32) - case TARGET_NR_geteuid32: -+#else -+ case TARGET_NR_geteuid: -+#endif - ret = get_errno(geteuid()); - break; - #endif --#ifdef TARGET_NR_getegid32 -+#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && !defined(USE_UID16)) -+#if defined(TARGET_NR_getegid32) - case TARGET_NR_getegid32: -+#else -+ case TARGET_NR_getegid: -+#endif - ret = get_errno(getegid()); - break; - #endif --#ifdef TARGET_NR_setreuid32 -+#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setreuid32) - case TARGET_NR_setreuid32: -+#else -+ case TARGET_NR_setreuid: -+#endif - ret = get_errno(setreuid(arg1, arg2)); - break; - #endif --#ifdef TARGET_NR_setregid32 -+#if defined(TARGET_NR_setregid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setregid32) - case TARGET_NR_setregid32: -+#else -+ case TARGET_NR_setregid: -+#endif - ret = get_errno(setregid(arg1, arg2)); - break; - #endif --#ifdef TARGET_NR_getgroups32 -+#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16) -+#if defined(TARGET_NR_getgroups32) - case TARGET_NR_getgroups32: -+#else -+ case TARGET_NR_getgroups: -+#endif - { - int gidsetsize = arg1; - uint32_t *target_grouplist; -@@ -6471,8 +6512,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - break; - #endif --#ifdef TARGET_NR_setgroups32 -+#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setgroups32) - case TARGET_NR_setgroups32: -+#else -+ case TARGET_NR_setgroups: -+#endif - { - int gidsetsize = arg1; - uint32_t *target_grouplist; -@@ -6492,18 +6537,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - break; - #endif --#ifdef TARGET_NR_fchown32 -+#if defined(TARGET_NR_fchown32) || !defined(USE_UID16) -+#if defined(TARGET_NR_fchown32) - case TARGET_NR_fchown32: -+#else -+ case TARGET_NR_fchown: -+#endif - ret = get_errno(fchown(arg1, arg2, arg3)); - break; - #endif --#ifdef TARGET_NR_setresuid32 -+#if defined(TARGET_NR_setresuid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setresuid32) - case TARGET_NR_setresuid32: -+#else -+ case TARGET_NR_setresuid: -+#endif - ret = get_errno(setresuid(arg1, arg2, arg3)); - break; - #endif --#ifdef TARGET_NR_getresuid32 -+#if defined(TARGET_NR_getresuid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_getresuid32) - case TARGET_NR_getresuid32: -+#else -+ case TARGET_NR_getresuid: -+#endif - { - uid_t ruid, euid, suid; - ret = get_errno(getresuid(&ruid, &euid, &suid)); -@@ -6516,13 +6573,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - break; - #endif --#ifdef TARGET_NR_setresgid32 -+#if defined(TARGET_NR_setresgid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setresgid32) - case TARGET_NR_setresgid32: -+#else -+ case TARGET_NR_setresgid: -+#endif - ret = get_errno(setresgid(arg1, arg2, arg3)); - break; - #endif -+#if defined(TARGET_NR_getresgid32) || !defined(USE_UID16) - #ifdef TARGET_NR_getresgid32 - case TARGET_NR_getresgid32: -+#else -+ case TARGET_NR_getresgid: -+#endif - { - gid_t rgid, egid, sgid; - ret = get_errno(getresgid(&rgid, &egid, &sgid)); -@@ -6535,31 +6600,51 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - } - break; - #endif --#ifdef TARGET_NR_chown32 -+#if defined(TARGET_NR_chown32) || !defined(USE_UID16) -+#if defined(TARGET_NR_chown32) - case TARGET_NR_chown32: -+#else -+ case TARGET_NR_chown: -+#endif - if (!(p = lock_user_string(arg1))) - goto efault; - ret = get_errno(chown(p, arg2, arg3)); - unlock_user(p, arg1, 0); - break; - #endif --#ifdef TARGET_NR_setuid32 -+#if defined(TARGET_NR_setuid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setuid32) - case TARGET_NR_setuid32: -+#else -+ case TARGET_NR_setuid: -+#endif - ret = get_errno(setuid(arg1)); - break; - #endif --#ifdef TARGET_NR_setgid32 -+#if defined(TARGET_NR_setgid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setgid32) - case TARGET_NR_setgid32: -+#else -+ case TARGET_NR_setgid: -+#endif - ret = get_errno(setgid(arg1)); - break; - #endif --#ifdef TARGET_NR_setfsuid32 -+#if defined(TARGET_NR_setfsuid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setfsuid32) - case TARGET_NR_setfsuid32: -+#else -+ case TARGET_NR_setfsuid: -+#endif - ret = get_errno(setfsuid(arg1)); - break; - #endif --#ifdef TARGET_NR_setfsgid32 -+#if defined(TARGET_NR_setfsgid32) || !defined(USE_UID16) -+#if defined(TARGET_NR_setfsgid32) - case TARGET_NR_setfsgid32: -+#else -+ case TARGET_NR_setfsgid: -+#endif - ret = get_errno(setfsgid(arg1)); - break; - #endif --- -1.6.2.1 - diff --git a/0030-linux-user-getpriority-errno-fix.patch b/0030-linux-user-getpriority-errno-fix.patch deleted file mode 100644 index c7fa1691..00000000 --- a/0030-linux-user-getpriority-errno-fix.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 03004ec00de3f29699a6bb9458942ea111f528ed Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 17:55:41 +0200 -Subject: [PATCH 30/33] linux-user: getpriority errno fix - -getpriority returned wrong errno; fixes LTP test getpriority02. - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index b1ef3c9..30fb4ab 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -5327,7 +5327,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - /* libc does special remapping of the return value of - * sys_getpriority() so it's just easiest to call - * sys_getpriority() directly rather than through libc. */ -- ret = sys_getpriority(arg1, arg2); -+ ret = get_errno(sys_getpriority(arg1, arg2)); - break; - case TARGET_NR_setpriority: - ret = get_errno(setpriority(arg1, arg2, arg3)); --- -1.6.2.1 - diff --git a/0031-linux-user-fadvise64-implementation.patch b/0031-linux-user-fadvise64-implementation.patch deleted file mode 100644 index aa0d3988..00000000 --- a/0031-linux-user-fadvise64-implementation.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 51e609fc6a4a6ff29cd463babfe14032aea18254 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 23 Jul 2009 14:56:59 +0200 -Subject: [PATCH 31/33] linux-user: fadvise64 implementation - -good enough to pass all LTP fadvise64 tests - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 17 ++++++++++++++--- - 1 files changed, 14 insertions(+), 3 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 30fb4ab..c4b7001 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -6680,12 +6680,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - arg4 = temp; - } - #endif --#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) -+#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64) - #ifdef TARGET_NR_fadvise64_64 - case TARGET_NR_fadvise64_64: - #endif -- /* This is a hint, so ignoring and returning success is ok. */ -- ret = get_errno(0); -+#ifdef TARGET_NR_fadvise64 -+ case TARGET_NR_fadvise64: -+#endif -+#ifdef TARGET_S390X -+ switch (arg4) { -+ case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */ -+ case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */ -+ case 6: arg4 = POSIX_FADV_DONTNEED; break; -+ case 7: arg4 = POSIX_FADV_NOREUSE; break; -+ default: break; -+ } -+#endif -+ ret = -posix_fadvise(arg1, arg2, arg3, arg4); - break; - #endif - #ifdef TARGET_NR_madvise --- -1.6.2.1 - diff --git a/0032-linux-user-zero-fstat-buffer-to-initialize-nsec-fie.patch b/0032-linux-user-zero-fstat-buffer-to-initialize-nsec-fie.patch deleted file mode 100644 index ca88e2a3..00000000 --- a/0032-linux-user-zero-fstat-buffer-to-initialize-nsec-fie.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 50a2b3b61b897ada12c267538e9f65578c256880 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Fri, 10 Jul 2009 16:43:26 +0200 -Subject: [PATCH 32/33] linux-user: zero fstat buffer to initialize nsec fields - -The fstat implementation does not initialize the nanosecond fields in the -stat buffer; this caused funny values to turn up there, preventing, for -instance, cp -p from preserving timestamps because utimensat rejected -the out-of-bounds nanosecond values. Resetting the entire structure -to zero fixes that. - -Signed-off-by: Ulrich Hecht ---- - linux-user/syscall.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index c4b7001..ef76537 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -5552,6 +5552,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; -+ memset(target_st, 0, sizeof(*target_st)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); - __put_user(st.st_mode, &target_st->st_mode); --- -1.6.2.1 - diff --git a/0033-dup3-check-fallocate-check-fixed.patch b/0033-dup3-check-fallocate-check-fixed.patch deleted file mode 100644 index 7a48eb25..00000000 --- a/0033-dup3-check-fallocate-check-fixed.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 1e8223836a2e09899cd946db4e4ee99b64ceb7a4 Mon Sep 17 00:00:00 2001 -From: Ulrich Hecht -Date: Thu, 30 Jul 2009 16:02:52 +0200 -Subject: [PATCH 33/33] dup3 check, fallocate check fixed - -Signed-off-by: Ulrich Hecht ---- - configure | 20 +++++++++++++++++++- - linux-user/syscall.c | 4 +++- - 2 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/configure b/configure -index 4be25f6..8d3967d 100755 ---- a/configure -+++ b/configure -@@ -1370,6 +1370,21 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then - fallocate=yes - fi - -+# check for dup3 -+dup3=no -+cat > $TMPC << EOF -+#include -+ -+int main(void) -+{ -+ dup3(0, 0, 0); -+ return 0; -+} -+EOF -+if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then -+ dup3=yes -+fi -+ - # Check if tools are available to build documentation. - if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then - build_docs="no" -@@ -1723,7 +1738,10 @@ if test "$splice" = "yes" ; then - echo "#define CONFIG_SPLICE 1" >> $config_host_h - fi - if test "$fallocate" = "yes" ; then -- echo "#define CONFIG_FALLOCATE 1" >> $config_host_h -+ echo "CONFIG_FALLOCATE=y" >> $config_host_mak -+fi -+if test "$dup3" = "yes" ; then -+ echo "CONFIG_DUP3=y" >> $config_host_mak - fi - if test "$inotify" = "yes" ; then - echo "#define CONFIG_INOTIFY 1" >> $config_host_h -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index ef76537..6c109de 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -3707,8 +3707,10 @@ static int target_to_host_fcntl_cmd(int cmd) - return F_SETLEASE; - case TARGET_F_GETLEASE: - return F_GETLEASE; -+#ifdef F_DUPFD_CLOEXEC - case TARGET_F_DUPFD_CLOEXEC: - return F_DUPFD_CLOEXEC; -+#endif - case TARGET_F_NOTIFY: - return F_NOTIFY; - default: -@@ -4758,7 +4760,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_NR_dup2: - ret = get_errno(dup2(arg1, arg2)); - break; --#ifdef TARGET_NR_dup3 -+#if defined(TARGET_NR_dup3) && defined(CONFIG_DUP3) - case TARGET_NR_dup3: - ret = get_errno(dup3(arg1, arg2, arg3)); - break; --- -1.6.2.1 - diff --git a/qemu-0.11.0.tar.bz2 b/qemu-0.11.0.tar.bz2 deleted file mode 100644 index b86d869f..00000000 --- a/qemu-0.11.0.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58ad4225ba18ba5166977a7e0f5cd1bb94ee4e5f9fce65274d6dbb30035958ab -size 3292681 diff --git a/qemu-0.14.0-rc1.tar.bz2 b/qemu-0.14.0-rc1.tar.bz2 new file mode 100644 index 00000000..b48c9b43 --- /dev/null +++ b/qemu-0.14.0-rc1.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c4f5c01033e6a4a39f221cfad84e2d15e4e6c1023d263b8480d6aea4afbc0ac +size 4545302 diff --git a/qemu.changes b/qemu.changes index 1ce78260..2ab76fe8 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Thu Feb 10 14:48:36 CET 2011 - uli@suse.de + +- update -> 0.14.0-rc1 + See http://wiki.qemu.org/Changelog/0.14 for changes in 0.14. + (There is no such page for the 0.13 tree. The ChangeLog file ends at + 0.12.0, http://wiki.qemu.org/ChangeLog at 0.12.5 and suggests to look at + the git log. High-level information of what has changed in 0.13 is + apparently not available.) + +------------------------------------------------------------------- +Fri May 28 18:57:23 CEST 2010 - uli@suse.de + +- update -> 0.12.4 + see http://wiki.qemu.org/ChangeLog for changes + ------------------------------------------------------------------- Wed May 19 17:37:03 UTC 2010 - brogers@novell.com diff --git a/qemu.spec b/qemu.spec index 18870a08..25fada6c 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,5 +1,5 @@ # -# spec file for package qemu (Version 0.11.0) +# spec file for package qemu (Version 0.12.4) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -19,14 +19,14 @@ Name: qemu -BuildRequires: SDL-devel bison bluez-devel curl-devel cyrus-sasl-devel e2fsprogs-devel libaio-devel libgnutls-devel libpcap-devel ncurses-devel zlib-devel-static +BuildRequires: SDL-devel bison bluez-devel curl-devel cyrus-sasl-devel e2fsprogs-devel libaio libaio-devel libgnutls-devel libpcap-devel ncurses-devel zlib-devel-static Url: http://fabrice.bellard.free.fr/qemu/ License: BSD3c(or similar) ; GPLv2+ ; LGPLv2.1+ ; MIT License (or similar) Group: System/Emulators/PC Summary: Universal CPU emulator -Version: 0.11.0 -Release: 6 -Source: %name-0.11.0.tar.bz2 +Version: 0.14.0_rc1 +Release: 1 +Source: %name-0.14.0-rc1.tar.bz2 Patch1: 0001-qemu-0.7.0-amd64.patch Patch2: 0002-qemu-0.9.0.cvs-binfmt.patch Patch3: 0003-qemu-cvs-alsa_bitfield.patch @@ -35,31 +35,15 @@ Patch5: 0005-qemu-cvs-alsa_mmap.patch Patch6: 0006-qemu-cvs-gettimeofday.patch Patch7: 0007-qemu-cvs-ioctl_debug.patch Patch8: 0008-qemu-cvs-ioctl_nodirection.patch -Patch9: 0009-qemu-cvs-newpath.patch -Patch10: 0010-qemu-cvs-sched_getaffinity.patch -Patch11: 0011-qemu-cvs-mmap-amd64.patch -Patch12: 0012-qemu-cvs-pthread.patch -Patch13: 0013-qemu-img-vmdk-scsi.patch -Patch14: 0014-qemu-nonvoid_return.patch -Patch15: 0015-pcap-network-emulation.patch -Patch16: 0016-i386-linux-user-NPTL-support.patch -Patch17: 0017-qemu-0.11-git-ioctl_mount.patch -Patch18: 0018-qemu-0.11-git-user-linux-ppc-uid16_fix.patch -Patch19: 0019-Rewrite-mmap_find_vma-to-work-fine-on-64-bit-hosts.patch -Patch20: 0020-TCG-sync-op-32-bit-targets-fixed.patch -Patch21: 0021-S-390-CPU-emulation.patch -Patch22: 0022-S-390-host-target-build-system-support.patch -Patch23: 0023-S-390-host-support-for-TCG.patch -Patch24: 0024-linux-user-S-390-64-bit-s390x-support.patch -Patch25: 0025-linux-user-don-t-do-locking-in-single-threaded-proc.patch -Patch26: 0026-linux-user-dup3-fallocate-syscalls.patch -Patch27: 0027-linux-user-fcntl-fixes-for-LTP.patch -Patch28: 0028-linux-user-enable-getdents-for-32-bit-systems.patch -Patch29: 0029-linux-user-define-a-couple-of-syscalls-for-non-uid1.patch -Patch30: 0030-linux-user-getpriority-errno-fix.patch -Patch31: 0031-linux-user-fadvise64-implementation.patch -Patch32: 0032-linux-user-zero-fstat-buffer-to-initialize-nsec-fie.patch -Patch33: 0033-dup3-check-fallocate-check-fixed.patch +Patch9: 0009-qemu-cvs-sched_getaffinity.patch +Patch10: 0010-qemu-cvs-mmap-amd64.patch +Patch11: 0011-qemu-img-vmdk-scsi.patch +Patch12: 0012-qemu-nonvoid_return.patch +Patch13: 0013-i386-linux-user-NPTL-support.patch +Patch14: 0014-qemu-0.11-git-ioctl_mount.patch +Patch15: 0015-S-390-support.patch +Patch16: 0016-fix-mipsn32-linux-user-builds.patch +Patch17: 0017-S-390-build-fix.patch # this is to make lint happy Source300: rpmlintrc BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -80,7 +64,7 @@ Authors: Fabrice Bellard %prep -%setup -q -n qemu-0.11.0 +%setup -q -n %name-0.14.0-rc1 %patch1 -p1 %patch2 -p1 %patch3 -p1 @@ -95,34 +79,18 @@ Authors: %patch12 -p1 %patch13 -p1 %patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 %ifarch s390x ppc64 x86_64 # s390 target only builds on 64-bit machines -%patch22 -p1 +%patch15 -p1 +%patch17 -p1 %endif -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 +%patch16 -p1 %build # build QEMU mkdir -p dynamic # build qemu-system -./configure --prefix=/usr \ +./configure --prefix=/usr --sysconfdir=%_sysconfdir \ --interp-prefix=/usr/share/qemu/qemu-i386 \ --audio-card-list="ac97 es1370 sb16 cs4231a adlib gus" \ --audio-drv-list="alsa sdl" --enable-mixemu \ @@ -139,11 +107,11 @@ make qemu-img V=1 mv */qemu */qemu-* qemu-io dynamic || true make clean # build userland emus -./configure --prefix=/usr \ +./configure --prefix=/usr --sysconfdir=%_sysconfdir \ --interp-prefix=/usr/share/qemu/qemu-i386 \ --enable-linux-user \ --disable-system \ - --static \ + --static --disable-linux-aio \ --extra-cflags="$QEMU_OPT_FLAGS" make %{?jobs:-j%{jobs}} V=1 @@ -156,7 +124,7 @@ install -m 755 */qemu $RPM_BUILD_ROOT/usr/bin ln -sf qemu $RPM_BUILD_ROOT/usr/bin/qemu-system-i386 install -m 755 */qemu-*[^.]? $RPM_BUILD_ROOT/usr/bin install -d -m 755 $RPM_BUILD_ROOT/usr/sbin -install -m 755 qemu-binfmt-conf.sh $RPM_BUILD_ROOT/usr/sbin +install -m 755 dynamic/qemu-binfmt-conf.sh $RPM_BUILD_ROOT/usr/sbin %ifnarch %ix86 x86_64 ln -sf ../../../emul/ia32-linux $RPM_BUILD_ROOT/usr/share/qemu/qemu-i386 %endif @@ -178,5 +146,7 @@ rm -rf ${RPM_BUILD_ROOT} %ifnarch %ix86 x86_64 ia64 %dir /emul/ia32-linux %endif +%dir %_sysconfdir/qemu +%config %_sysconfdir/qemu/target-x86_64.conf %changelog