summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2011-05-03 17:00:22 -0300
committerMarcelo Tosatti <mtosatti@redhat.com>2011-05-03 17:00:22 -0300
commita670ad63cf5ce7aa71cfae8057d9d1dc72f36f10 (patch)
treeb98b68f8f1cdfa456e80687762d099acf122bc96
parent70757dcaa40e14978bf287084d8fab9efb815a2d (diff)
parent3110e2925489c571901e945e315942ce84fe696f (diff)
Merge commit '3110e2925489c571901e945e315942ce84fe696f' into upstream-merge
* commit '3110e2925489c571901e945e315942ce84fe696f': (41 commits) s390x: Enable s390x-softmmu target s390x: Prepare cpu.h for emulation move helpers.h to helper.h libcacard: fix opposite usage of isspace target-mips: clear softfpu exception state for comparison instructions target-mips: fix c.ps.* instructions target-mips: don't hardcode softfloat exception bits target-mips: simplify FP comparisons target-ppc: fix SPE comparison functions softfloat: improve description of comparison functions softfloat: move float*_eq and float*_eq_quiet softfloat: rename float*_eq_signaling() into float*_eq() softfloat: rename float*_eq() into float*_eq_quiet() target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions target-mips: use new float*_unordered*() functions target-alpha: use new float64_unordered_quiet() function softfloat-native: add float*_unordered_quiet() functions softfloat: add float*_unordered_{,quiet}() functions target-i386: add floatx_{add,mul,sub} and use them target-i386: use float unions from cpu-all.h ... Conflicts: cpu-exec.c Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--.gitignore3
-rw-r--r--Makefile5
-rw-r--r--acl.c1
-rw-r--r--arch_init.h2
-rw-r--r--arm-semi.c1
-rw-r--r--balloon.c1
-rw-r--r--bt-host.c1
-rw-r--r--bt-vhci.c1
-rw-r--r--buffered_file.c1
-rw-r--r--cpu-all.h10
-rw-r--r--cpu-exec.c8
-rw-r--r--cpus.c13
-rw-r--r--cpus.h4
-rw-r--r--device_tree.c1
-rw-r--r--fpu/softfloat-macros.h29
-rw-r--r--fpu/softfloat-native.h27
-rw-r--r--fpu/softfloat.c317
-rw-r--r--fpu/softfloat.h16
-rw-r--r--hw/an5206.c1
-rw-r--r--hw/armv7m.c1
-rw-r--r--hw/axis_dev88.c1
-rw-r--r--hw/blizzard.c1
-rw-r--r--hw/bt-hci-csr.c1
-rw-r--r--hw/cris-boot.c1
-rw-r--r--hw/dummy_m68k.c1
-rw-r--r--hw/empty_slot.c21
-rw-r--r--hw/etraxfs.c1
-rw-r--r--hw/gumstix.c1
-rw-r--r--hw/ide/ich.c1
-rw-r--r--hw/ide/isa.c1
-rw-r--r--hw/ide/macio.c1
-rw-r--r--hw/ide/microdrive.c1
-rw-r--r--hw/ide/mmio.c1
-rw-r--r--hw/ide/pci.c1
-rw-r--r--hw/integratorcp.c1
-rw-r--r--hw/isa-bus.c1
-rw-r--r--hw/lm32_boards.c1
-rw-r--r--hw/mainstone.c1
-rw-r--r--hw/omap_sx1.c1
-rw-r--r--hw/pcie.c3
-rw-r--r--hw/ppc440_bamboo.c1
-rw-r--r--hw/ppc4xx_devs.c1
-rw-r--r--hw/s390-virtio.c2
-rw-r--r--hw/stellaris.c1
-rw-r--r--hw/syborg.c1
-rw-r--r--hw/syborg_virtio.c1
-rw-r--r--hw/sysbus.c1
-rw-r--r--hw/tc58128.c1
-rw-r--r--hw/tosa.c1
-rw-r--r--hw/twl92230.c1
-rw-r--r--hw/usb-hid.c2
-rw-r--r--hw/usb-msd.c4
-rw-r--r--hw/virtio-balloon.c1
-rw-r--r--hw/virtio.c1
-rw-r--r--hw/vmport.c1
-rw-r--r--hw/xen_console.c1
-rw-r--r--hw/xen_domainbuild.c1
-rw-r--r--hw/xen_machine_pv.c1
-rw-r--r--hw/xenfb.c1
-rw-r--r--hw/xilinx_timer.c1
-rw-r--r--json-lexer.c6
-rw-r--r--kvm-stub.c1
-rw-r--r--libcacard/vcard_emul_nss.c4
-rw-r--r--linux-user/arm/nwfpe/fpa11_cprt.c2
-rw-r--r--migration-exec.c1
-rw-r--r--migration-fd.c1
-rw-r--r--migration-tcp.c1
-rw-r--r--migration-unix.c1
-rw-r--r--migration.h9
-rw-r--r--net.c1
-rw-r--r--net/dump.c2
-rw-r--r--net/slirp.c1
-rw-r--r--net/vde.c1
-rw-r--r--osdep.c1
-rw-r--r--qemu-common.h20
-rw-r--r--qemu-config.c1
-rw-r--r--qemu-error.c1
-rw-r--r--qemu-options.hx4
-rw-r--r--qemu-os-win32.h3
-rw-r--r--qemu-timer.c169
-rw-r--r--qemu-timer.h7
-rw-r--r--qemu-tool.c1
-rw-r--r--savevm.c3
-rw-r--r--sysemu.h34
-rw-r--r--target-alpha/op_helper.c9
-rw-r--r--target-arm/helper.c4
-rw-r--r--target-arm/helper.h (renamed from target-arm/helpers.h)0
-rw-r--r--target-arm/iwmmxt_helper.c2
-rw-r--r--target-arm/neon_helper.c2
-rw-r--r--target-arm/op_helper.c2
-rw-r--r--target-arm/translate.c6
-rw-r--r--target-i386/exec.h33
-rw-r--r--target-i386/helper.c12
-rw-r--r--target-i386/op_helper.c18
-rw-r--r--target-i386/ops_sse.h12
-rw-r--r--target-microblaze/op_helper.c4
-rw-r--r--target-mips/op_helper.c244
-rw-r--r--target-ppc/op_helper.c26
-rw-r--r--target-s390x/cpu.h774
-rw-r--r--target-s390x/exec.h11
-rw-r--r--target-s390x/helper.c4
-rw-r--r--target-s390x/kvm.c17
-rw-r--r--target-s390x/translate.c2
-rw-r--r--tests/test-mmap.c2
-rw-r--r--usb-linux.c5
105 files changed, 1466 insertions, 508 deletions
diff --git a/.gitignore b/.gitignore
index 4833233e8..113876e81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,9 @@ QMP/qmp-commands.txt
*.ky
*.log
*.pdf
+*.cps
+*.fns
+*.kys
*.pg
*.pyc
*.toc
diff --git a/Makefile b/Makefile
index 5fbd45806..7ff083d5f 100644
--- a/Makefile
+++ b/Makefile
@@ -163,7 +163,10 @@ distclean: clean
rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi
rm -f config-all-devices.mak
rm -f roms/seabios/config.mak roms/vgabios/config.mak
- rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr
+ rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps qemu-doc.dvi
+ rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
+ rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
+ rm -f qemu-doc.vr
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
for d in $(TARGET_DIRS) $(QEMULIBS); do \
rm -rf $$d || exit 1 ; \
diff --git a/acl.c b/acl.c
index 311dade4e..82c27043c 100644
--- a/acl.c
+++ b/acl.c
@@ -24,7 +24,6 @@
#include "qemu-common.h"
-#include "sysemu.h"
#include "acl.h"
#ifdef CONFIG_FNMATCH
diff --git a/arch_init.h b/arch_init.h
index c83360c3a..86ebc149b 100644
--- a/arch_init.h
+++ b/arch_init.h
@@ -22,8 +22,6 @@ enum {
extern const uint32_t arch_type;
void select_soundhw(const char *optarg);
-int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
-int ram_load(QEMUFile *f, void *opaque, int version_id);
void do_acpitable_option(const char *optarg);
void do_smbios_option(const char *optarg);
void cpudef_init(void);
diff --git a/arm-semi.c b/arm-semi.c
index 1d5179b60..e9e6f8993 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -33,7 +33,6 @@
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
#else
#include "qemu-common.h"
-#include "sysemu.h"
#include "gdbstub.h"
#endif
diff --git a/balloon.c b/balloon.c
index 0021fef4b..248c1b50a 100644
--- a/balloon.c
+++ b/balloon.c
@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
-#include "sysemu.h"
#include "monitor.h"
#include "qjson.h"
#include "qint.h"
diff --git a/bt-host.c b/bt-host.c
index 6931e7cc6..095254ddc 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -19,7 +19,6 @@
#include "qemu-common.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "net.h"
#include "bt-host.h"
diff --git a/bt-vhci.c b/bt-vhci.c
index 679c5e05d..3c5772093 100644
--- a/bt-vhci.c
+++ b/bt-vhci.c
@@ -19,7 +19,6 @@
#include "qemu-common.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "net.h"
#include "hw/bt.h"
diff --git a/buffered_file.c b/buffered_file.c
index b5e2baff4..41b42c3d5 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -14,7 +14,6 @@
#include "qemu-common.h"
#include "hw/hw.h"
#include "qemu-timer.h"
-#include "sysemu.h"
#include "qemu-char.h"
#include "buffered_file.h"
diff --git a/cpu-all.h b/cpu-all.h
index dc0f2f02a..0bae6df8e 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,6 +138,16 @@ typedef union {
uint64_t ll;
} CPU_DoubleU;
+#if defined(FLOATX80)
+typedef union {
+ floatx80 d;
+ struct {
+ uint64_t lower;
+ uint16_t upper;
+ } l;
+} CPU_LDoubleU;
+#endif
+
#if defined(CONFIG_SOFTFLOAT)
typedef union {
float128 q;
diff --git a/cpu-exec.c b/cpu-exec.c
index 277609f1d..584da7d31 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -353,6 +353,8 @@ int cpu_exec(CPUState *env1)
do_interrupt(0);
#elif defined(TARGET_IA64)
do_interrupt(env);
+#elif defined(TARGET_S390X)
+ do_interrupt(env);
#endif
env->exception_index = -1;
#endif
@@ -567,6 +569,12 @@ int cpu_exec(CPUState *env1)
do_interrupt(1);
next_tb = 0;
}
+#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
+ if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->psw.mask & PSW_MASK_EXT)) {
+ do_interrupt(env);
+ next_tb = 0;
+ }
#endif
/* Don't use the cached interupt_request value,
do_interrupt may have updated the EXITTB flag. */
diff --git a/cpus.c b/cpus.c
index 52e4fd784..5d1c39680 100644
--- a/cpus.c
+++ b/cpus.c
@@ -155,7 +155,7 @@ static bool cpu_thread_is_idle(CPUState *env)
return true;
}
-static bool all_cpu_threads_idle(void)
+bool all_cpu_threads_idle(void)
{
CPUState *env;
@@ -745,6 +745,9 @@ static void qemu_tcg_wait_io_event(void)
CPUState *env;
while (all_cpu_threads_idle()) {
+ /* Start accounting real time to the virtual clock if the CPUs
+ are idle. */
+ qemu_clock_warp(vm_clock);
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
}
@@ -836,6 +839,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
while (1) {
cpu_exec_all();
+ if (use_icount && qemu_next_icount_deadline() <= 0) {
+ qemu_notify_event();
+ }
qemu_tcg_wait_io_event();
}
@@ -1050,7 +1056,7 @@ static int tcg_cpu_exec(CPUState *env)
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
env->icount_decr.u16.low = 0;
env->icount_extra = 0;
- count = qemu_icount_round (qemu_next_deadline());
+ count = qemu_icount_round(qemu_next_icount_deadline());
qemu_icount += count;
decr = (count > 0xffff) ? 0xffff : count;
count -= decr;
@@ -1076,6 +1082,9 @@ bool cpu_exec_all(void)
{
int r;
+ /* Account partial waits to the vm_clock. */
+ qemu_clock_warp(vm_clock);
+
if (next_cpu == NULL) {
next_cpu = first_cpu;
}
diff --git a/cpus.h b/cpus.h
index e0211260c..6fdeb0d8f 100644
--- a/cpus.h
+++ b/cpus.h
@@ -8,6 +8,10 @@ void resume_all_vcpus(void);
void pause_all_vcpus(void);
void cpu_stop_current(void);
+void cpu_synchronize_all_states(void);
+void cpu_synchronize_all_post_reset(void);
+void cpu_synchronize_all_post_init(void);
+
/* vl.c */
extern int smp_cores;
extern int smp_threads;
diff --git a/device_tree.c b/device_tree.c
index 21be07075..f5d5eb1bc 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -20,7 +20,6 @@
#include "config.h"
#include "qemu-common.h"
-#include "sysemu.h"
#include "device_tree.h"
#include "hw/loader.h"
diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index 3128e60cb..e82ce2332 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -36,6 +36,17 @@ these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*----------------------------------------------------------------------------
+| This macro tests for minimum version of the GNU C compiler.
+*----------------------------------------------------------------------------*/
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0
+#endif
+
+
+/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
@@ -616,6 +627,13 @@ static uint32_t estimateSqrt32( int16 aExp, uint32_t a )
static int8 countLeadingZeros32( uint32_t a )
{
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+ if (a) {
+ return __builtin_clz(a);
+ } else {
+ return 32;
+ }
+#else
static const int8 countLeadingZerosHigh[] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -647,7 +665,7 @@ static int8 countLeadingZeros32( uint32_t a )
}
shiftCount += countLeadingZerosHigh[ a>>24 ];
return shiftCount;
-
+#endif
}
/*----------------------------------------------------------------------------
@@ -657,6 +675,13 @@ static int8 countLeadingZeros32( uint32_t a )
static int8 countLeadingZeros64( uint64_t a )
{
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+ if (a) {
+ return __builtin_clzll(a);
+ } else {
+ return 64;
+ }
+#else
int8 shiftCount;
shiftCount = 0;
@@ -668,7 +693,7 @@ static int8 countLeadingZeros64( uint64_t a )
}
shiftCount += countLeadingZeros32( a );
return shiftCount;
-
+#endif
}
/*----------------------------------------------------------------------------
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 80b5f288e..ea7a15e1c 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -210,7 +210,7 @@ INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
}
float32 float32_rem( float32, float32 STATUS_PARAM);
float32 float32_sqrt( float32 STATUS_PARAM);
-INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq_quiet( float32 a, float32 b STATUS_PARAM)
{
return a == b;
}
@@ -222,7 +222,7 @@ INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
{
return a < b;
}
-INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
{
return a <= b && a >= b;
}
@@ -237,7 +237,10 @@ INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
{
return isunordered(a, b);
-
+}
+INLINE int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM)
+{
+ return isunordered(a, b);
}
int float32_compare( float32, float32 STATUS_PARAM );
int float32_compare_quiet( float32, float32 STATUS_PARAM );
@@ -318,7 +321,7 @@ INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
}
float64 float64_rem( float64, float64 STATUS_PARAM );
float64 float64_sqrt( float64 STATUS_PARAM );
-INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq_quiet( float64 a, float64 b STATUS_PARAM)
{
return a == b;
}
@@ -330,7 +333,7 @@ INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
{
return a < b;
}
-INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
{
return a <= b && a >= b;
}
@@ -346,7 +349,10 @@ INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
{
return isunordered(a, b);
-
+}
+INLINE int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM)
+{
+ return isunordered(a, b);
}
int float64_compare( float64, float64 STATUS_PARAM );
int float64_compare_quiet( float64, float64 STATUS_PARAM );
@@ -422,7 +428,7 @@ INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
}
floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM)
{
return a == b;
}
@@ -434,7 +440,7 @@ INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
{
return a < b;
}
-INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
{
return a <= b && a >= b;
}
@@ -450,7 +456,10 @@ INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
{
return isunordered(a, b);
-
+}
+INLINE int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM)
+{
+ return isunordered(a, b);
}
int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 03fb9487b..6ce0b61c1 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2314,33 +2314,33 @@ float32 float32_log2( float32 a STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
+| the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_eq( float32 a, float32 b STATUS_PARAM )
{
+ uint32_t av, bv;
a = float32_squash_input_denormal(a STATUS_VAR);
b = float32_squash_input_denormal(b STATUS_VAR);
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
+ float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- return ( float32_val(a) == float32_val(b) ) ||
- ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
-
+ av = float32_val(a);
+ bv = float32_val(b);
+ return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise. The invalid
+| exception is raised if either operand is a NaN. The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_le( float32 a, float32 b STATUS_PARAM )
@@ -2367,8 +2367,9 @@ int float32_le( float32 a, float32 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_lt( float32 a, float32 b STATUS_PARAM )
@@ -2394,15 +2395,14 @@ int float32_lt( float32 a, float32 b STATUS_PARAM )
}
/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. The invalid exception is raised if either
+| operand is a NaN. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
-int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
+int float32_unordered( float32 a, float32 b STATUS_PARAM )
{
- uint32_t av, bv;
a = float32_squash_input_denormal(a STATUS_VAR);
b = float32_squash_input_denormal(b STATUS_VAR);
@@ -2410,12 +2410,33 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
- return 0;
+ return 1;
}
- av = float32_val(a);
- bv = float32_val(b);
- return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
+ return 0;
+}
+/*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point value `a' is equal to
+| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
+| exception. The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
+{
+ a = float32_squash_input_denormal(a STATUS_VAR);
+ b = float32_squash_input_denormal(b STATUS_VAR);
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return 0;
+ }
+ return ( float32_val(a) == float32_val(b) ) ||
+ ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
}
/*----------------------------------------------------------------------------
@@ -2481,6 +2502,29 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
}
/*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
+{
+ a = float32_squash_input_denormal(a STATUS_VAR);
+ b = float32_squash_input_denormal(b STATUS_VAR);
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
@@ -3536,7 +3580,8 @@ float64 float64_log2( float64 a STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The comparison is performed
+| corresponding value `b', and 0 otherwise. The invalid exception is raised
+| if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
@@ -3549,9 +3594,7 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
+ float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
av = float64_val(a);
@@ -3562,9 +3605,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| equal to the corresponding value `b', and 0 otherwise. The invalid
+| exception is raised if either operand is a NaN. The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_le( float64 a, float64 b STATUS_PARAM )
@@ -3591,8 +3634,9 @@ int float64_le( float64 a, float64 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_lt( float64 a, float64 b STATUS_PARAM )
@@ -3618,13 +3662,34 @@ int float64_lt( float64 a, float64 b STATUS_PARAM )
}
/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. The invalid exception is raised if either
+| operand is a NaN. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered( float64 a, float64 b STATUS_PARAM )
+{
+ a = float64_squash_input_denormal(a STATUS_VAR);
+ b = float64_squash_input_denormal(b STATUS_VAR);
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ return 1;
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The invalid exception is raised
-| if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
+| exception.The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
-int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
+int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
{
uint64_t av, bv;
a = float64_squash_input_denormal(a STATUS_VAR);
@@ -3633,7 +3698,9 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
- float_raise( float_flag_invalid STATUS_VAR);
+ if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
return 0;
}
av = float64_val(a);
@@ -3704,6 +3771,29 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
}
+/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
+{
+ a = float64_squash_input_denormal(a STATUS_VAR);
+ b = float64_squash_input_denormal(b STATUS_VAR);
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return 1;
+ }
+ return 0;
+}
+
#ifdef FLOATX80
/*----------------------------------------------------------------------------
@@ -4501,10 +4591,10 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
}
/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| Returns 1 if the extended double-precision floating-point value `a' is equal
+| to the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. Otherwise, the comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4515,10 +4605,7 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
+ float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
return
@@ -4533,8 +4620,9 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is
| less than or equal to the corresponding value `b', and 0 otherwise. The
-| comparison is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
+| invalid exception is raised if either operand is a NaN. The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
*----------------------------------------------------------------------------*/
int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4565,9 +4653,9 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is
-| less than the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| less than the corresponding value `b', and 0 otherwise. The invalid
+| exception is raised if either operand is a NaN. The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4597,13 +4685,32 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
}
/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is equal
-| to the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise. The invalid exception is raised if
+| either operand is a NaN. The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
+int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
+{
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ return 1;
+ }
+ return 0;
+}
-int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is
+| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
+| cause an exception. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
{
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -4611,7 +4718,10 @@ int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
) {
- float_raise( float_flag_invalid STATUS_VAR);
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
return 0;
}
return
@@ -4695,6 +4805,28 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
}
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise. Quiet NaNs do not cause an exception.
+| The comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return 1;
+ }
+ return 0;
+}
+
#endif
#ifdef FLOAT128
@@ -5625,7 +5757,8 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
+| the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
@@ -5637,10 +5770,7 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
+ float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
return
@@ -5654,9 +5784,9 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise. The invalid
+| exception is raised if either operand is a NaN. The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float128_le( float128 a, float128 b STATUS_PARAM )
@@ -5687,8 +5817,9 @@ int float128_le( float128 a, float128 b STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float128_lt( float128 a, float128 b STATUS_PARAM )
@@ -5718,13 +5849,33 @@ int float128_lt( float128 a, float128 b STATUS_PARAM )
}
/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. The invalid exception is raised if either
+| operand is a NaN. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered( float128 a, float128 b STATUS_PARAM )
+{
+ if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
+ && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+ || ( ( extractFloat128Exp( b ) == 0x7FFF )
+ && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ return 1;
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
+| exception. The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
-int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
+int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
{
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
@@ -5732,7 +5883,10 @@ int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
- float_raise( float_flag_invalid STATUS_VAR);
+ if ( float128_is_signaling_nan( a )
+ || float128_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
return 0;
}
return
@@ -5816,6 +5970,29 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
}
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
+{
+ if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
+ && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+ || ( ( extractFloat128Exp( b ) == 0x7FFF )
+ && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ ) {
+ if ( float128_is_signaling_nan( a )
+ || float128_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return 1;
+ }
+ return 0;
+}
+
#endif
/* misc functions */
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index c7654d4c6..340f0a9f2 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -323,9 +323,11 @@ float32 float32_log2( float32 STATUS_PARAM );
int float32_eq( float32, float32 STATUS_PARAM );
int float32_le( float32, float32 STATUS_PARAM );
int float32_lt( float32, float32 STATUS_PARAM );
-int float32_eq_signaling( float32, float32 STATUS_PARAM );
+int float32_unordered( float32, float32 STATUS_PARAM );
+int float32_eq_quiet( float32, float32 STATUS_PARAM );
int float32_le_quiet( float32, float32 STATUS_PARAM );
int float32_lt_quiet( float32, float32 STATUS_PARAM );
+int float32_unordered_quiet( float32, float32 STATUS_PARAM );
int float32_compare( float32, float32 STATUS_PARAM );
int float32_compare_quiet( float32, float32 STATUS_PARAM );
float32 float32_min(float32, float32 STATUS_PARAM);
@@ -437,9 +439,11 @@ float64 float64_log2( float64 STATUS_PARAM );
int float64_eq( float64, float64 STATUS_PARAM );
int float64_le( float64, float64 STATUS_PARAM );
int float64_lt( float64, float64 STATUS_PARAM );
-int float64_eq_signaling( float64, float64 STATUS_PARAM );
+int float64_unordered( float64, float64 STATUS_PARAM );
+int float64_eq_quiet( float64, float64 STATUS_PARAM );
int float64_le_quiet( float64, float64 STATUS_PARAM );
int float64_lt_quiet( float64, float64 STATUS_PARAM );
+int float64_unordered_quiet( float64, float64 STATUS_PARAM );
int float64_compare( float64, float64 STATUS_PARAM );
int float64_compare_quiet( float64, float64 STATUS_PARAM );
float64 float64_min(float64, float64 STATUS_PARAM);
@@ -538,9 +542,11 @@ floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
int floatx80_le( floatx80, floatx80 STATUS_PARAM );
int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_is_quiet_nan( floatx80 );
int floatx80_is_signaling_nan( floatx80 );
floatx80 floatx80_maybe_silence_nan( floatx80 );
@@ -621,9 +627,11 @@ float128 float128_sqrt( float128 STATUS_PARAM );
int float128_eq( float128, float128 STATUS_PARAM );
int float128_le( float128, float128 STATUS_PARAM );
int float128_lt( float128, float128 STATUS_PARAM );
-int float128_eq_signaling( float128, float128 STATUS_PARAM );
+int float128_unordered( float128, float128 STATUS_PARAM );
+int float128_eq_quiet( float128, float128 STATUS_PARAM );
int float128_le_quiet( float128, float128 STATUS_PARAM );
int float128_lt_quiet( float128, float128 STATUS_PARAM );
+int float128_unordered_quiet( float128, float128 STATUS_PARAM );
int float128_compare( float128, float128 STATUS_PARAM );
int float128_compare_quiet( float128, float128 STATUS_PARAM );
int float128_is_quiet_nan( float128 );
diff --git a/hw/an5206.c b/hw/an5206.c
index b9f19a994..42a0163fb 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -9,7 +9,6 @@
#include "hw.h"
#include "pc.h"
#include "mcf.h"
-#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 304cd34bc..72d010a63 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -9,7 +9,6 @@
#include "sysbus.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 57b5e2f04..0e2135afd 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -26,7 +26,6 @@
#include "net.h"
#include "flash.h"
#include "boards.h"
-#include "sysemu.h"
#include "etraxfs.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 5f329ad13..c5245504a 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -19,7 +19,6 @@
*/
#include "qemu-common.h"
-#include "sysemu.h"
#include "console.h"
#include "devices.h"
#include "vga_int.h"
diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c
index 65ffa37fd..d135ef479 100644
--- a/hw/bt-hci-csr.c
+++ b/hw/bt-hci-csr.c
@@ -22,7 +22,6 @@
#include "qemu-char.h"
#include "qemu-timer.h"
#include "irq.h"
-#include "sysemu.h"
#include "net.h"
#include "bt.h"
diff --git a/hw/cris-boot.c b/hw/cris-boot.c
index 2ef17f606..37894f8b5 100644
--- a/hw/cris-boot.c
+++ b/hw/cris-boot.c
@@ -23,7 +23,6 @@
*/
#include "hw.h"
-#include "sysemu.h"
#include "loader.h"
#include "elf.h"
#include "cris-boot.h"
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 61efb3989..cec1cc8e8 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -7,7 +7,6 @@
*/
#include "hw.h"
-#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 664b8d9c4..da8adc4d0 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -53,18 +53,21 @@ static CPUWriteMemoryFunc * const empty_slot_write[3] = {
void empty_slot_init(target_phys_addr_t addr, uint64_t slot_size)
{
- DeviceState *dev;
- SysBusDevice *s;
- EmptySlot *e;
+ if (slot_size > 0) {
+ /* Only empty slots larger than 0 byte need handling. */
+ DeviceState *dev;
+ SysBusDevice *s;
+ EmptySlot *e;
- dev = qdev_create(NULL, "empty_slot");
- s = sysbus_from_qdev(dev);
- e = FROM_SYSBUS(EmptySlot, s);
- e->size = slot_size;
+ dev = qdev_create(NULL, "empty_slot");
+ s = sysbus_from_qdev(dev);
+ e = FROM_SYSBUS(EmptySlot, s);
+ e->size = slot_size;
- qdev_init_nofail(dev);
+ qdev_init_nofail(dev);
- sysbus_mmio_map(s, 0, addr);
+ sysbus_mmio_map(s, 0, addr);
+ }
}
static int empty_slot_init1(SysBusDevice *dev)
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 5ee5f979a..b84d74a11 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -24,7 +24,6 @@
#include "sysbus.h"
#include "boards.h"
-#include "sysemu.h"
#include "net.h"
#include "flash.h"
#include "etraxfs.h"
diff --git a/hw/gumstix.c b/hw/gumstix.c
index ee63f634c..853f7e1ee 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -35,7 +35,6 @@
#include "pxa.h"
#include "net.h"
#include "flash.h"
-#include "sysemu.h"
#include "devices.h"
#include "boards.h"
#include "blockdev.h"
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index f242d7a81..a3d475c59 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -67,7 +67,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/pci.h>
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 8c59c5a47..4ac745324 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -27,7 +27,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index c1b4caab5..7107f6b3c 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -27,7 +27,6 @@
#include <hw/mac_dbdma.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 2ceeb87c0..9fbbf0e78 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -27,7 +27,6 @@
#include <hw/pcmcia.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 82b24b673..10f6f4063 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -25,7 +25,6 @@
#include <hw/hw.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 35168cb46..65cb56c38 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -28,7 +28,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/pci.h>
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index b04994082..a6c27be82 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -10,7 +10,6 @@
#include "sysbus.h"
#include "primecell.h"
#include "devices.h"
-#include "sysemu.h"
#include "boards.h"
#include "arm-misc.h"
#include "net.h"
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index d07aa410f..27655436a 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -17,7 +17,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
-#include "sysemu.h"
#include "monitor.h"
#include "sysbus.h"
#include "isa.h"
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index 85190f0bf..64629230c 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -21,7 +21,6 @@
#include "hw.h"
#include "net.h"
#include "flash.h"
-#include "sysemu.h"
#include "devices.h"
#include "boards.h"
#include "loader.h"
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 50691ca41..4792f0e3e 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -14,7 +14,6 @@
#include "net.h"
#include "devices.h"
#include "boards.h"
-#include "sysemu.h"
#include "flash.h"
#include "blockdev.h"
#include "sysbus.h"
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 06bccbdc4..a7b687bc4 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -26,7 +26,6 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
-#include "sysemu.h"
#include "console.h"
#include "omap.h"
#include "boards.h"
diff --git a/hw/pcie.c b/hw/pcie.c
index 6a113a932..9de614904 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -18,8 +18,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "sysemu.h"
-#include "range.h"
+#include "qemu-common.h"
#include "pci_bridge.h"
#include "pcie.h"
#include "msix.h"
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index db1f84abe..6627cd8aa 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -17,7 +17,6 @@
#include "hw.h"
#include "pci.h"
#include "boards.h"
-#include "sysemu.h"
#include "ppc440.h"
#include "kvm.h"
#include "kvm_ppc.h"
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 5f581fe2c..7f9ed1713 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "ppc.h"
#include "ppc4xx.h"
-#include "sysemu.h"
#include "qemu-log.h"
//#define DEBUG_MMIO
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index d429f10d5..48fb0d05c 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -82,7 +82,7 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
return ipi_states[cpu_addr];
}
-int s390_virtio_hypercall(CPUState *env)
+int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
{
int r = 0, i;
target_ulong mem = env->regs[2];
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 0d5292688..7932c2457 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -14,7 +14,6 @@
#include "qemu-timer.h"
#include "i2c.h"
#include "net.h"
-#include "sysemu.h"
#include "boards.h"
#define GPIO_A 0
diff --git a/hw/syborg.c b/hw/syborg.c
index 758c69a9c..bc200e48a 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -25,7 +25,6 @@
#include "sysbus.h"
#include "boards.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "net.h"
static struct arm_boot_info syborg_binfo;
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index ee08c4910..2f3e6da4e 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -26,7 +26,6 @@
#include "sysbus.h"
#include "virtio.h"
#include "virtio-net.h"
-#include "sysemu.h"
//#define DEBUG_SYBORG_VIRTIO
diff --git a/hw/sysbus.c b/hw/sysbus.c
index acad72abe..2e22be7b2 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -18,7 +18,6 @@
*/
#include "sysbus.h"
-#include "sysemu.h"
#include "monitor.h"
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
diff --git a/hw/tc58128.c b/hw/tc58128.c
index 672a01c46..61b99dd4d 100644
--- a/hw/tc58128.c
+++ b/hw/tc58128.c
@@ -1,6 +1,5 @@
#include "hw.h"
#include "sh.h"
-#include "sysemu.h"
#include "loader.h"
#define CE1 0x0100
diff --git a/hw/tosa.c b/hw/tosa.c
index b8b6c4f39..a7967a286 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -11,7 +11,6 @@
#include "hw.h"
#include "pxa.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "devices.h"
#include "sharpsl.h"
#include "pcmcia.h"
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 8e74acc05..a75448f06 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -22,7 +22,6 @@
#include "hw.h"
#include "qemu-timer.h"
#include "i2c.h"
-#include "sysemu.h"
#include "console.h"
#define VERBOSE 1
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c25362cc9..89c293c46 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -26,7 +26,7 @@
#include "console.h"
#include "usb.h"
#include "usb-desc.h"
-#include "sysemu.h"
+#include "qemu-timer.h"
/* HID interface requests */
#define GET_REPORT 0xa101
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 76f5b027b..947fd3f83 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -33,7 +33,7 @@ do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
enum USBMSDMode {
USB_MSDM_CBW, /* Command Block. */
- USB_MSDM_DATAOUT, /* Tranfer data to device. */
+ USB_MSDM_DATAOUT, /* Transfer data to device. */
USB_MSDM_DATAIN, /* Transfer data from device. */
USB_MSDM_CSW /* Command Status. */
};
@@ -253,7 +253,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
usb_msd_copy_data(s);
if (s->usb_len == 0) {
/* Set s->packet to NULL before calling usb_packet_complete
- because annother request may be issued before
+ because another request may be issued before
usb_packet_complete returns. */
DPRINTF("Packet complete %p\n", p);
s->packet = NULL;
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index f9add1cd4..447b337e0 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -15,7 +15,6 @@
#include "qemu-common.h"
#include "virtio.h"
#include "pc.h"
-#include "sysemu.h"
#include "cpu.h"
#include "monitor.h"
#include "balloon.h"
diff --git a/hw/virtio.c b/hw/virtio.c
index 31bd9e32d..6e8814cb6 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -16,7 +16,6 @@
#include "trace.h"
#include "qemu-error.h"
#include "virtio.h"
-#include "sysemu.h"
/* The alignment to use between consumer and producer parts of vring.
* x86 pagesize again. */
diff --git a/hw/vmport.c b/hw/vmport.c
index 19010e484..c8aefaabb 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "isa.h"
#include "pc.h"
-#include "sysemu.h"
#include "kvm.h"
#include "qdev.h"
diff --git a/hw/xen_console.c b/hw/xen_console.c
index d2261f413..c6c816381 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -33,7 +33,6 @@
#include <xenctrl.h>
#include "hw.h"
-#include "sysemu.h"
#include "qemu-char.h"
#include "xen_backend.h"
diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c
index 371c56206..4093587df 100644
--- a/hw/xen_domainbuild.c
+++ b/hw/xen_domainbuild.c
@@ -1,7 +1,6 @@
#include <signal.h>
#include "xen_backend.h"
#include "xen_domainbuild.h"
-#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-log.h"
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 77a34bf11..0d7f73ed8 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "pc.h"
-#include "sysemu.h"
#include "boards.h"
#include "xen_backend.h"
#include "xen_domainbuild.h"
diff --git a/hw/xenfb.c b/hw/xenfb.c
index da5297b49..1db75fbe4 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -44,7 +44,6 @@
#include <xen/io/protocols.h>
#include "hw.h"
-#include "sysemu.h"
#include "console.h"
#include "qemu-char.h"
#include "xen_backend.h"
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 30827b03c..d398c18e9 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -23,7 +23,6 @@
*/
#include "sysbus.h"
-#include "sysemu.h"
#include "qemu-timer.h"
#define D(x)
diff --git a/json-lexer.c b/json-lexer.c
index c736f4290..65c9720d6 100644
--- a/json-lexer.c
+++ b/json-lexer.c
@@ -28,7 +28,7 @@
*/
enum json_lexer_state {
- ERROR = 0,
+ IN_ERROR = 0,
IN_DQ_UCODE3,
IN_DQ_UCODE2,
IN_DQ_UCODE1,
@@ -150,7 +150,7 @@ static const uint8_t json_lexer[][256] = {
/* Zero */
[IN_ZERO] = {
TERMINAL(JSON_INTEGER),
- ['0' ... '9'] = ERROR,
+ ['0' ... '9'] = IN_ERROR,
['.'] = IN_MANTISSA,
},
@@ -302,7 +302,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch)
lexer->token = qstring_new();
new_state = IN_START;
break;
- case ERROR:
+ case IN_ERROR:
return -EINVAL;
default:
break;
diff --git a/kvm-stub.c b/kvm-stub.c
index fc2b81006..31bd77b3a 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -11,7 +11,6 @@
*/
#include "qemu-common.h"
-#include "sysemu.h"
#include "hw/hw.h"
#include "exec-all.h"
#include "gdbstub.h"
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index 71f2ba3ae..baada52a3 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -955,7 +955,7 @@ count_tokens(const char *str, char token, char token_end)
static const char *
strip(const char *str)
{
- for (; *str && !isspace(*str); str++) {
+ for (; *str && isspace(*str); str++) {
}
return str;
}
@@ -963,7 +963,7 @@ strip(const char *str)
static const char *
find_blank(const char *str)
{
- for (; *str && isspace(*str); str++) {
+ for (; *str && !isspace(*str); str++) {
}
return str;
}
diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
index be54e9515..801189798 100644
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -159,7 +159,7 @@ PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
}
/* test for equal condition */
- if (floatx80_eq(Fn,Fm, &fpa11->fp_status))
+ if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status))
{
flags |= CC_ZERO;
}
diff --git a/migration-exec.c b/migration-exec.c
index 14718dd1d..4b7aad8b6 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -17,7 +17,6 @@
#include "qemu_socket.h"
#include "migration.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "buffered_file.h"
#include "block.h"
#include <sys/types.h>
diff --git a/migration-fd.c b/migration-fd.c
index 6d1450563..66d51c1cc 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -16,7 +16,6 @@
#include "migration.h"
#include "monitor.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "buffered_file.h"
#include "block.h"
#include "qemu_socket.h"
diff --git a/migration-tcp.c b/migration-tcp.c
index e8dff9d71..d3d80c970 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -15,7 +15,6 @@
#include "qemu_socket.h"
#include "migration.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "buffered_file.h"
#include "block.h"
diff --git a/migration-unix.c b/migration-unix.c
index 8b967f293..c8625c7f6 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -15,7 +15,6 @@
#include "qemu_socket.h"
#include "migration.h"
#include "qemu-char.h"
-#include "sysemu.h"
#include "buffered_file.h"
#include "block.h"
diff --git a/migration.h b/migration.h
index 21707922e..050c56c5a 100644
--- a/migration.h
+++ b/migration.h
@@ -139,4 +139,13 @@ void add_migration_state_change_notifier(Notifier *notify);
void remove_migration_state_change_notifier(Notifier *notify);
int get_migration_state(void);
+uint64_t ram_bytes_remaining(void);
+uint64_t ram_bytes_transferred(void);
+uint64_t ram_bytes_total(void);
+
+int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
+int ram_load(QEMUFile *f, void *opaque, int version_id);
+
+extern int incoming_expected;
+
#endif
diff --git a/net.c b/net.c
index 8d6a55537..4f777c3da 100644
--- a/net.c
+++ b/net.c
@@ -32,7 +32,6 @@
#include "net/vde.h"
#include "net/util.h"
#include "monitor.h"
-#include "sysemu.h"
#include "qemu-common.h"
#include "qemu_socket.h"
#include "hw/qdev.h"
diff --git a/net/dump.c b/net/dump.c
index 83eda0fcc..0d0cbb259 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -24,9 +24,9 @@
#include "dump.h"
#include "qemu-common.h"
-#include "sysemu.h"
#include "qemu-error.h"
#include "qemu-log.h"
+#include "qemu-timer.h"
typedef struct DumpState {
VLANClientState nc;
diff --git a/net/slirp.c b/net/slirp.c
index b41c60a39..e387a116a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -30,7 +30,6 @@
#endif
#include "net.h"
#include "monitor.h"
-#include "sysemu.h"
#include "qemu_socket.h"
#include "slirp/libslirp.h"
diff --git a/net/vde.c b/net/vde.c
index 0b46fa640..ac48ab2f0 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -31,7 +31,6 @@
#include "qemu-char.h"
#include "qemu-common.h"
#include "qemu-option.h"
-#include "sysemu.h"
typedef struct VDEState {
VLANClientState nc;
diff --git a/osdep.c b/osdep.c
index 327583baf..56e6963f1 100644
--- a/osdep.c
+++ b/osdep.c
@@ -46,7 +46,6 @@ extern int madvise(caddr_t, size_t, int);
#include "qemu-common.h"
#include "trace.h"
-#include "sysemu.h"
#include "qemu_socket.h"
int qemu_madvise(void *addr, size_t len, int advice)
diff --git a/qemu-common.h b/qemu-common.h
index 82e27c18d..f9f705da8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -12,6 +12,7 @@
#endif
#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];
+#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
typedef struct QEMUTimer QEMUTimer;
typedef struct QEMUFile QEMUFile;
@@ -39,6 +40,14 @@ typedef struct Monitor Monitor;
#include <sys/time.h>
#include <assert.h>
+#ifdef _WIN32
+#include "qemu-os-win32.h"
+#endif
+
+#ifdef CONFIG_POSIX
+#include "qemu-os-posix.h"
+#endif
+
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
@@ -298,6 +307,7 @@ void qemu_notify_event(void);
void qemu_cpu_kick(void *env);
void qemu_cpu_kick_self(void);
int qemu_cpu_is_self(void *env);
+bool all_cpu_threads_idle(void);
/* work queue */
struct qemu_work_item {
@@ -338,6 +348,16 @@ void qemu_progress_init(int enabled, float min_skip);
void qemu_progress_end(void);
void qemu_progress_print(float percent, int max);
+#define QEMU_FILE_TYPE_BIOS 0
+#define QEMU_FILE_TYPE_KEYMAP 1
+char *qemu_find_file(int type, const char *name);
+
+/* OS specific functions */
+void os_setup_early_signal_handling(void);
+char *os_find_datadir(const char *argv0);
+void os_parse_cmd_args(int index, const char *optarg);
+void os_pidfile_error(void);
+
/* Convert a byte between binary and BCD. */
static inline uint8_t to_bcd(uint8_t val)
{
diff --git a/qemu-config.c b/qemu-config.c
index 6d9c23881..844c62deb 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -2,7 +2,6 @@
#include "qemu-error.h"
#include "qemu-option.h"
#include "qemu-config.h"
-#include "sysemu.h"
#include "hw/qdev.h"
static QemuOptsList qemu_drive_opts = {
diff --git a/qemu-error.c b/qemu-error.c
index 5a35e7c1c..41c191d52 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -12,7 +12,6 @@
#include <stdio.h>
#include "monitor.h"
-#include "sysemu.h"
/*
* Print to current monitor if we have one, else to stderr.
diff --git a/qemu-options.hx b/qemu-options.hx
index 66fffe30f..5956ec6a4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -939,8 +939,8 @@ a lot of bandwidth at the expense of quality.
Disable adaptive encodings. Adaptive encodings are enabled by default.
An adaptive encoding will try to detect frequently updated screen regions,
and send updates in these regions using a lossy encoding (like JPEG).
-This can be really helpfull to save bandwidth when playing videos. Disabling
-adaptive encodings allow to restore the original static behavior of encodings
+This can be really helpful to save bandwidth when playing videos. Disabling
+adaptive encodings allows to restore the original static behavior of encodings
like Tight.
@end table
diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index 1a07e5e26..ed2753d1b 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -26,6 +26,9 @@
#ifndef QEMU_OS_WIN32_H
#define QEMU_OS_WIN32_H
+#include <windows.h>
+#include <winsock2.h>
+
/* Polling handling */
/* return TRUE if no sleep should be done afterwards */
diff --git a/qemu-timer.c b/qemu-timer.c
index 50f1943af..b8c0c8870 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -110,9 +110,12 @@ static int64_t cpu_get_clock(void)
}
}
+#ifndef CONFIG_IOTHREAD
static int64_t qemu_icount_delta(void)
{
- if (use_icount == 1) {
+ if (!use_icount) {
+ return 5000 * (int64_t) 1000000;
+ } else if (use_icount == 1) {
/* When not using an adaptive execution frequency
we tend to get badly out of sync with real time,
so just delay for a reasonable amount of time. */
@@ -121,6 +124,7 @@ static int64_t qemu_icount_delta(void)
return cpu_get_icount() - cpu_get_clock();
}
}
+#endif
/* enable cpu_get_ticks() */
void cpu_enable_ticks(void)
@@ -153,6 +157,8 @@ void cpu_disable_ticks(void)
struct QEMUClock {
int type;
int enabled;
+
+ QEMUTimer *warp_timer;
};
struct QEMUTimer {
@@ -386,6 +392,90 @@ void qemu_clock_enable(QEMUClock *clock, int enabled)
clock->enabled = enabled;
}
+static int64_t vm_clock_warp_start;
+
+static void icount_warp_rt(void *opaque)
+{
+ if (vm_clock_warp_start == -1) {
+ return;
+ }
+
+ if (vm_running) {
+ int64_t clock = qemu_get_clock_ns(rt_clock);
+ int64_t warp_delta = clock - vm_clock_warp_start;
+ if (use_icount == 1) {
+ qemu_icount_bias += warp_delta;
+ } else {
+ /*
+ * In adaptive mode, do not let the vm_clock run too
+ * far ahead of real time.
+ */
+ int64_t cur_time = cpu_get_clock();
+ int64_t cur_icount = qemu_get_clock_ns(vm_clock);
+ int64_t delta = cur_time - cur_icount;
+ qemu_icount_bias += MIN(warp_delta, delta);
+ }
+ if (qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
+ qemu_get_clock_ns(vm_clock))) {
+ qemu_notify_event();
+ }
+ }
+ vm_clock_warp_start = -1;
+}
+
+void qemu_clock_warp(QEMUClock *clock)
+{
+ int64_t deadline;
+
+ if (!clock->warp_timer) {
+ return;
+ }
+
+ /*
+ * There are too many global variables to make the "warp" behavior
+ * applicable to other clocks. But a clock argument removes the
+ * need for if statements all over the place.
+ */
+ assert(clock == vm_clock);
+
+ /*
+ * If the CPUs have been sleeping, advance the vm_clock timer now. This
+ * ensures that the deadline for the timer is computed correctly below.
+ * This also makes sure that the insn counter is synchronized before the
+ * CPU starts running, in case the CPU is woken by an event other than
+ * the earliest vm_clock timer.
+ */
+ icount_warp_rt(NULL);
+ if (!all_cpu_threads_idle() || !active_timers[clock->type]) {
+ qemu_del_timer(clock->warp_timer);
+ return;
+ }
+
+ vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
+ deadline = qemu_next_icount_deadline();
+ if (deadline > 0) {
+ /*
+ * Ensure the vm_clock proceeds even when the virtual CPU goes to
+ * sleep. Otherwise, the CPU might be waiting for a future timer
+ * interrupt to wake it up, but the interrupt never comes because
+ * the vCPU isn't running any insns and thus doesn't advance the
+ * vm_clock.
+ *
+ * An extreme solution for this problem would be to never let VCPUs
+ * sleep in icount mode if there is a pending vm_clock timer; rather
+ * time could just advance to the next vm_clock event. Instead, we
+ * do stop VCPUs and only advance vm_clock after some "real" time,
+ * (related to the time left until the next event) has passed. This
+ * rt_clock timer will do this. This avoids that the warps are too
+ * visible externally---for example, you will not be sending network
+ * packets continously instead of every 100ms.
+ */
+ qemu_mod_timer(clock->warp_timer, vm_clock_warp_start + deadline);
+ } else {
+ qemu_notify_event();
+ }
+}
+
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
QEMUTimerCB *cb, void *opaque)
{
@@ -454,8 +544,10 @@ static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
qemu_rearm_alarm_timer(alarm_timer);
}
/* Interrupt execution to force deadline recalculation. */
- if (use_icount)
+ qemu_clock_warp(ts->clock);
+ if (use_icount) {
qemu_notify_event();
+ }
}
}
@@ -576,6 +668,10 @@ void configure_icount(const char *option)
if (!option)
return;
+#ifdef CONFIG_IOTHREAD
+ vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
+#endif
+
if (strcmp(option, "auto") != 0) {
icount_time_shift = strtol(option, NULL, 0);
use_icount = 1;
@@ -669,21 +765,16 @@ static void host_alarm_handler(int host_signum)
}
}
-int64_t qemu_next_deadline(void)
+int64_t qemu_next_icount_deadline(void)
{
/* To avoid problems with overflow limit this to 2^32. */
int64_t delta = INT32_MAX;
+ assert(use_icount);
if (active_timers[QEMU_CLOCK_VIRTUAL]) {
delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
qemu_get_clock_ns(vm_clock);
}
- if (active_timers[QEMU_CLOCK_HOST]) {
- int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
- qemu_get_clock_ns(host_clock);
- if (hdelta < delta)
- delta = hdelta;
- }
if (delta < 0)
delta = 0;
@@ -1055,39 +1146,41 @@ void quit_timers(void)
int qemu_calculate_timeout(void)
{
+#ifndef CONFIG_IOTHREAD
int timeout;
- int64_t add;
- int64_t delta;
-
- /* When using icount, making forward progress with qemu_icount when the
- guest CPU is idle is critical. We only use the static io-thread timeout
- for non icount runs. */
- if (!use_icount || !vm_running) {
- return 5000;
- }
- /* Advance virtual time to the next event. */
- delta = qemu_icount_delta();
- if (delta > 0) {
- /* If virtual time is ahead of real time then just
- wait for IO. */
- timeout = (delta + 999999) / 1000000;
- } else {
- /* Wait for either IO to occur or the next
- timer event. */
- add = qemu_next_deadline();
- /* We advance the timer before checking for IO.
- Limit the amount we advance so that early IO
- activity won't get the guest too far ahead. */
- if (add > 10000000)
- add = 10000000;
- delta += add;
- qemu_icount += qemu_icount_round (add);
- timeout = delta / 1000000;
- if (timeout < 0)
- timeout = 0;
+ if (!vm_running)
+ timeout = 5000;
+ else {
+ /* XXX: use timeout computed from timers */
+ int64_t add;
+ int64_t delta;
+ /* Advance virtual time to the next event. */
+ delta = qemu_icount_delta();
+ if (delta > 0) {
+ /* If virtual time is ahead of real time then just
+ wait for IO. */
+ timeout = (delta + 999999) / 1000000;
+ } else {
+ /* Wait for either IO to occur or the next
+ timer event. */
+ add = qemu_next_icount_deadline();
+ /* We advance the timer before checking for IO.
+ Limit the amount we advance so that early IO
+ activity won't get the guest too far ahead. */
+ if (add > 10000000)
+ add = 10000000;
+ delta += add;
+ qemu_icount += qemu_icount_round (add);
+ timeout = delta / 1000000;
+ if (timeout < 0)
+ timeout = 0;
+ }
}
return timeout;
+#else /* CONFIG_IOTHREAD */
+ return 1000;
+#endif
}
diff --git a/qemu-timer.h b/qemu-timer.h
index 75d567578..bbc3452bc 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -39,6 +39,7 @@ extern QEMUClock *host_clock;
int64_t qemu_get_clock_ns(QEMUClock *clock);
void qemu_clock_enable(QEMUClock *clock, int enabled);
+void qemu_clock_warp(QEMUClock *clock);
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
QEMUTimerCB *cb, void *opaque);
@@ -50,7 +51,7 @@ int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
void qemu_run_all_timers(void);
int qemu_alarm_pending(void);
-int64_t qemu_next_deadline(void);
+int64_t qemu_next_icount_deadline(void);
void configure_alarms(char const *opt);
void configure_icount(const char *option);
int qemu_calculate_timeout(void);
@@ -58,6 +59,10 @@ void init_clocks(void);
int init_timer_alarm(void);
void quit_timers(void);
+int64_t cpu_get_ticks(void);
+void cpu_enable_ticks(void);
+void cpu_disable_ticks(void);
+
static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
void *opaque)
{
diff --git a/qemu-tool.c b/qemu-tool.c
index d45840de2..f4a6ad081 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -15,7 +15,6 @@
#include "monitor.h"
#include "qemu-timer.h"
#include "qemu-log.h"
-#include "sysemu.h"
#include <sys/time.h>
diff --git a/savevm.c b/savevm.c
index 936f619d5..e26bf6e0c 100644
--- a/savevm.c
+++ b/savevm.c
@@ -82,6 +82,7 @@
#include "migration.h"
#include "qemu_socket.h"
#include "qemu-queue.h"
+#include "cpus.h"
#define SELF_ANNOUNCE_ROUNDS 5
@@ -1030,7 +1031,7 @@ const VMStateInfo vmstate_info_buffer = {
};
/* unused buffers: space that was used for some fields that are
- not usefull anymore */
+ not useful anymore */
static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
{
diff --git a/sysemu.h b/sysemu.h
index 07d85cd44..d58bec116 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -8,22 +8,9 @@
#include "qemu-timer.h"
#include "notify.h"
-#ifdef _WIN32
-#include <windows.h>
-#include "qemu-os-win32.h"
-#endif
-
-#ifdef CONFIG_POSIX
-#include "qemu-os-posix.h"
-#endif
-
/* vl.c */
extern const char *bios_name;
-#define QEMU_FILE_TYPE_BIOS 0
-#define QEMU_FILE_TYPE_KEYMAP 1
-char *qemu_find_file(int type, const char *name);
-
extern int vm_running;
extern const char *qemu_name;
extern uint8_t qemu_uuid[];
@@ -50,14 +37,6 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
void vm_start(void);
void vm_stop(int reason);
-uint64_t ram_bytes_remaining(void);
-uint64_t ram_bytes_transferred(void);
-uint64_t ram_bytes_total(void);
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
@@ -82,10 +61,6 @@ int load_vmstate(const char *name);
void do_delvm(Monitor *mon, const QDict *qdict);
void do_info_snapshots(Monitor *mon);
-void cpu_synchronize_all_states(void);
-void cpu_synchronize_all_post_reset(void);
-void cpu_synchronize_all_post_init(void);
-
void qemu_announce_self(void);
void main_loop_wait(int nonblocking);
@@ -101,12 +76,6 @@ int qemu_loadvm_state(QEMUFile *f);
/* SLIRP */
void do_info_slirp(Monitor *mon);
-/* OS specific functions */
-void os_setup_early_signal_handling(void);
-char *os_find_datadir(const char *argv0);
-void os_parse_cmd_args(int index, const char *optarg);
-void os_pidfile_error(void);
-
typedef enum DisplayType
{
DT_DEFAULT,
@@ -117,7 +86,6 @@ typedef enum DisplayType
} DisplayType;
extern int autostart;
-extern int incoming_expected;
extern int bios_size;
typedef enum {
@@ -196,8 +164,6 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
-
void do_usb_add(Monitor *mon, const QDict *qdict);
void do_usb_del(Monitor *mon, const QDict *qdict);
void usb_info(Monitor *mon);
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 6c2ae2061..9f71db4c3 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -904,10 +904,11 @@ uint64_t helper_cmptun (uint64_t a, uint64_t b)
fa = t_to_float64(a);
fb = t_to_float64(b);
- if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb))
+ if (float64_unordered_quiet(fa, fb, &FP_STATUS)) {
return 0x4000000000000000ULL;
- else
+ } else {
return 0;
+ }
}
uint64_t helper_cmpteq(uint64_t a, uint64_t b)
@@ -917,7 +918,7 @@ uint64_t helper_cmpteq(uint64_t a, uint64_t b)
fa = t_to_float64(a);
fb = t_to_float64(b);
- if (float64_eq(fa, fb, &FP_STATUS))
+ if (float64_eq_quiet(fa, fb, &FP_STATUS))
return 0x4000000000000000ULL;
else
return 0;
@@ -956,7 +957,7 @@ uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
fa = g_to_float64(a);
fb = g_to_float64(b);
- if (float64_eq(fa, fb, &FP_STATUS))
+ if (float64_eq_quiet(fa, fb, &FP_STATUS))
return 0x4000000000000000ULL;
else
return 0;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 9172fc727..12127dee7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5,7 +5,7 @@
#include "cpu.h"
#include "exec-all.h"
#include "gdbstub.h"
-#include "helpers.h"
+#include "helper.h"
#include "qemu-common.h"
#include "host-utils.h"
#if !defined(CONFIG_USER_ONLY)
@@ -1378,7 +1378,7 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
/* This may enable/disable the MMU, so do a TLB flush. */
tlb_flush(env, 1);
break;
- case 1: /* Auxiliary cotrol register. */
+ case 1: /* Auxiliary control register. */
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
env->cp15.c1_xscaleauxcr = val;
break;
diff --git a/target-arm/helpers.h b/target-arm/helper.h
index ae701e845..ae701e845 100644
--- a/target-arm/helpers.h
+++ b/target-arm/helper.h
diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c
index 3941f1fd8..ebe6eb9fa 100644
--- a/target-arm/iwmmxt_helper.c
+++ b/target-arm/iwmmxt_helper.c
@@ -24,7 +24,7 @@
#include "cpu.h"
#include "exec.h"
-#include "helpers.h"
+#include "helper.h"
/* iwMMXt macros extracted from GNU gdb. */
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 7df925ad3..f5b173aa7 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -11,7 +11,7 @@
#include "cpu.h"
#include "exec.h"
-#include "helpers.h"
+#include "helper.h"
#define SIGNBIT (uint32_t)0x80000000
#define SIGNBIT64 ((uint64_t)1 << 63)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 3de261034..ee7286b77 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -17,7 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "exec.h"
-#include "helpers.h"
+#include "helper.h"
#define SIGNBIT (uint32_t)0x80000000
#define SIGNBIT64 ((uint64_t)1 << 63)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6190028d0..fc9ff8d9e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -30,9 +30,9 @@
#include "tcg-op.h"
#include "qemu-log.h"
-#include "helpers.h"
+#include "helper.h"
#define GEN_HELPER 1
-#include "helpers.h"
+#include "helper.h"
#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
@@ -129,7 +129,7 @@ void arm_translate_init(void)
#endif
#define GEN_HELPER 2
-#include "helpers.h"
+#include "helper.h"
}
static inline TCGv load_cpu_offset(int offset)
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 6f9f709d8..ae6b94740 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -110,6 +110,9 @@ static inline void svm_check_intercept(uint32_t type)
#define float64_to_floatx float64_to_floatx80
#define floatx_to_float32 floatx80_to_float32
#define floatx_to_float64 floatx80_to_float64
+#define floatx_add floatx80_add
+#define floatx_mul floatx80_mul
+#define floatx_sub floatx80_sub
#define floatx_abs floatx80_abs
#define floatx_chs floatx80_chs
#define floatx_round_to_int floatx80_round_to_int
@@ -126,6 +129,9 @@ static inline void svm_check_intercept(uint32_t type)
#define float64_to_floatx(x, e) (x)
#define floatx_to_float32 float64_to_float32
#define floatx_to_float64(x, e) (x)
+#define floatx_add float64_add
+#define floatx_mul float64_mul
+#define floatx_sub float64_sub
#define floatx_abs float64_abs
#define floatx_chs float64_chs
#define floatx_round_to_int float64_round_to_int
@@ -144,13 +150,7 @@ static inline void svm_check_intercept(uint32_t type)
#ifdef USE_X86LDOUBLE
/* only for x86 */
-typedef union {
- long double d;
- struct {
- unsigned long long lower;
- unsigned short upper;
- } l;
-} CPU86_LDoubleU;
+typedef CPU_LDoubleU CPU86_LDoubleU;
/* the following deal with x86 long double-precision numbers */
#define MAXEXPD 0x7fff
@@ -162,24 +162,7 @@ typedef union {
#else
-/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
-typedef union {
- double d;
-#if !defined(HOST_WORDS_BIGENDIAN) && !defined(__arm__)
- struct {
- uint32_t lower;
- int32_t upper;
- } l;
-#else
- struct {
- int32_t upper;
- uint32_t lower;
- } l;
-#endif
-#ifndef __arm__
- int64_t ll;
-#endif
-} CPU86_LDoubleU;
+typedef CPU_DoubleU CPU86_LDoubleU;
/* the following deal with IEEE double-precision numbers */
#define MAXEXPD 0x7ff
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 3fdbe68f3..4ab5241eb 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -409,16 +409,10 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
env->mxcsr);
for(i=0;i<8;i++) {
#if defined(USE_X86LDOUBLE)
- union {
- long double d;
- struct {
- uint64_t lower;
- uint16_t upper;
- } l;
- } tmp;
- tmp.d = env->fpregs[i].d;
+ CPU_LDoubleU u;
+ u.d = env->fpregs[i].d;
cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
- i, tmp.l.lower, tmp.l.upper);
+ i, u.l.lower, u.l.upper);
#else
cpu_fprintf(f, "FPR%d=%016" PRIx64,
i, env->fpregs[i].mmx.q);
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 43fbd0c77..a73427fe4 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3711,22 +3711,22 @@ void helper_fucomi_ST0_FT0(void)
void helper_fadd_ST0_FT0(void)
{
- ST0 += FT0;
+ ST0 = floatx_add(ST0, FT0, &env->fp_status);
}
void helper_fmul_ST0_FT0(void)
{
- ST0 *= FT0;
+ ST0 = floatx_mul(ST0, FT0, &env->fp_status);
}
void helper_fsub_ST0_FT0(void)
{
- ST0 -= FT0;
+ ST0 = floatx_sub(ST0, FT0, &env->fp_status);
}
void helper_fsubr_ST0_FT0(void)
{
- ST0 = FT0 - ST0;
+ ST0 = floatx_sub(FT0, ST0, &env->fp_status);
}
void helper_fdiv_ST0_FT0(void)
@@ -3743,24 +3743,22 @@ void helper_fdivr_ST0_FT0(void)
void helper_fadd_STN_ST0(int st_index)
{
- ST(st_index) += ST0;
+ ST(st_index) = floatx_add(ST(st_index), ST0, &env->fp_status);
}
void helper_fmul_STN_ST0(int st_index)
{
- ST(st_index) *= ST0;
+ ST(st_index) = floatx_mul(ST(st_index), ST0, &env->fp_status);
}
void helper_fsub_STN_ST0(int st_index)
{
- ST(st_index) -= ST0;
+ ST(st_index) = floatx_sub(ST(st_index), ST0, &env->fp_status);
}
void helper_fsubr_STN_ST0(int st_index)
{
- CPU86_LDouble *p;
- p = &ST(st_index);
- *p = ST0 - *p;
+ ST(st_index) = floatx_sub(ST0, ST(st_index), &env->fp_status);
}
void helper_fdiv_STN_ST0(int st_index)
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index 3232abd96..ac0f15007 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -921,14 +921,14 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\
d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
}
-#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
+#define FPU_CMPEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? -1 : 0
#define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
#define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
-#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0
+#define FPU_CMPNEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? 0 : -1
#define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
#define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1
SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
SSE_HELPER_CMP(cmplt, FPU_CMPLT)
@@ -1216,8 +1216,8 @@ void helper_pfadd(MMXReg *d, MMXReg *s)
void helper_pfcmpeq(MMXReg *d, MMXReg *s)
{
- d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
- d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
+ d->MMX_L(0) = float32_eq_quiet(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
+ d->MMX_L(1) = float32_eq_quiet(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
}
void helper_pfcmpge(MMXReg *d, MMXReg *s)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 39b8ec1e1..b7cd6b288 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -338,7 +338,7 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
set_float_exception_flags(0, &env->fp_status);
fa.l = a;
fb.l = b;
- r = float32_eq(fa.f, fb.f, &env->fp_status);
+ r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
update_fpu_flags(flags & float_flag_invalid);
@@ -384,7 +384,7 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
fa.l = a;
fb.l = b;
set_float_exception_flags(0, &env->fp_status);
- r = !float32_eq(fa.f, fb.f, &env->fp_status);
+ r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
update_fpu_flags(flags & float_flag_invalid);
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index bd16ce354..8cba535a3 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2077,22 +2077,27 @@ void helper_ctc1 (target_ulong arg1, uint32_t reg)
helper_raise_exception(EXCP_FPE);
}
-static inline char ieee_ex_to_mips(char xcpt)
+static inline int ieee_ex_to_mips(int xcpt)
{
- return (xcpt & float_flag_inexact) >> 5 |
- (xcpt & float_flag_underflow) >> 3 |
- (xcpt & float_flag_overflow) >> 1 |
- (xcpt & float_flag_divbyzero) << 1 |
- (xcpt & float_flag_invalid) << 4;
-}
-
-static inline char mips_ex_to_ieee(char xcpt)
-{
- return (xcpt & FP_INEXACT) << 5 |
- (xcpt & FP_UNDERFLOW) << 3 |
- (xcpt & FP_OVERFLOW) << 1 |
- (xcpt & FP_DIV0) >> 1 |
- (xcpt & FP_INVALID) >> 4;
+ int ret = 0;
+ if (xcpt) {
+ if (xcpt & float_flag_invalid) {
+ ret |= FP_INVALID;
+ }
+ if (xcpt & float_flag_overflow) {
+ ret |= FP_OVERFLOW;
+ }
+ if (xcpt & float_flag_underflow) {
+ ret |= FP_UNDERFLOW;
+ }
+ if (xcpt & float_flag_divbyzero) {
+ ret |= FP_DIV0;
+ }
+ if (xcpt & float_flag_inexact) {
+ ret |= FP_INEXACT;
+ }
+ }
+ return ret;
}
static inline void update_fcr31(void)
@@ -2869,7 +2874,9 @@ uint64_t helper_float_mulr_ps(uint64_t fdt0, uint64_t fdt1)
#define FOP_COND_D(op, cond) \
void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
{ \
- int c = cond; \
+ int c; \
+ set_float_exception_flags(0, &env->active_fpu.fp_status); \
+ c = cond; \
update_fcr31(); \
if (c) \
SET_FP_COND(cc, env->active_fpu); \
@@ -2879,6 +2886,7 @@ void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
{ \
int c; \
+ set_float_exception_flags(0, &env->active_fpu.fp_status); \
fdt0 = float64_abs(fdt0); \
fdt1 = float64_abs(fdt1); \
c = cond; \
@@ -2889,45 +2897,33 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
CLEAR_FP_COND(cc, env->active_fpu); \
}
-static int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
-{
- if (float64_is_signaling_nan(a) ||
- float64_is_signaling_nan(b) ||
- (sig && (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)))) {
- float_raise(float_flag_invalid, status);
- return 1;
- } else if (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)) {
- return 1;
- } else {
- return 0;
- }
-}
-
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(f, (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(un, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered_quiet() is still called. */
+FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(sf, (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(lt, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(le, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered() is still called. */
+FOP_COND_D(sf, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(seq, float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt, float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le, float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
#define FOP_COND_S(op, cond) \
void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
{ \
- int c = cond; \
+ int c; \
+ set_float_exception_flags(0, &env->active_fpu.fp_status); \
+ c = cond; \
update_fcr31(); \
if (c) \
SET_FP_COND(cc, env->active_fpu); \
@@ -2937,6 +2933,7 @@ void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
{ \
int c; \
+ set_float_exception_flags(0, &env->active_fpu.fp_status); \
fst0 = float32_abs(fst0); \
fst1 = float32_abs(fst1); \
c = cond; \
@@ -2947,51 +2944,39 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
CLEAR_FP_COND(cc, env->active_fpu); \
}
-static flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
-{
- if (float32_is_signaling_nan(a) ||
- float32_is_signaling_nan(b) ||
- (sig && (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)))) {
- float_raise(float_flag_invalid, status);
- return 1;
- } else if (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)) {
- return 1;
- } else {
- return 0;
- }
-}
-
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(f, (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(un, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(un, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(eq, float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(sf, (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(lt, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(le, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_S(sf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt, float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le, float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status))
#define FOP_COND_PS(op, condl, condh) \
void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
{ \
- uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
- uint32_t fsth0 = float32_abs(fdt0 >> 32); \
- uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
- uint32_t fsth1 = float32_abs(fdt1 >> 32); \
- int cl = condl; \
- int ch = condh; \
- \
+ uint32_t fst0, fsth0, fst1, fsth1; \
+ int ch, cl; \
+ set_float_exception_flags(0, &env->active_fpu.fp_status); \
+ fst0 = fdt0 & 0XFFFFFFFF; \
+ fsth0 = fdt0 >> 32; \
+ fst1 = fdt1 & 0XFFFFFFFF; \
+ fsth1 = fdt1 >> 32; \
+ cl = condl; \
+ ch = condh; \
update_fcr31(); \
if (cl) \
SET_FP_COND(cc, env->active_fpu); \
@@ -3004,13 +2989,14 @@ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
} \
void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
{ \
- uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
- uint32_t fsth0 = float32_abs(fdt0 >> 32); \
- uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
- uint32_t fsth1 = float32_abs(fdt1 >> 32); \
- int cl = condl; \
- int ch = condh; \
- \
+ uint32_t fst0, fsth0, fst1, fsth1; \
+ int ch, cl; \
+ fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
+ fsth0 = float32_abs(fdt0 >> 32); \
+ fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
+ fsth1 = float32_abs(fdt1 >> 32); \
+ cl = condl; \
+ ch = condh; \
update_fcr31(); \
if (cl) \
SET_FP_COND(cc, env->active_fpu); \
@@ -3023,38 +3009,38 @@ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
}
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(f, (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0),
- (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(un, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status),
- float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0),
+ (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
+ float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
/* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(sf, (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0),
- (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status),
- float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(lt, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(le, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status),
- !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status),
- float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_PS(sf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
+ (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
+ float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+ float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt, float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+ float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le, float32_le(fst0, fst1, &env->active_fpu.fp_status),
+ float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+ float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 8c993a1cf..28d40ac9a 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3343,7 +3343,7 @@ HELPER_SPE_VECTOR_ARITH(fsmul);
HELPER_SPE_VECTOR_ARITH(fsdiv);
/* Single-precision floating-point comparisons */
-static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
@@ -3351,7 +3351,7 @@ static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0;
}
-static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
@@ -3359,7 +3359,7 @@ static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4;
}
-static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
@@ -3367,22 +3367,22 @@ static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
}
-static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return efststlt(op1, op2);
+ /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+ return efscmplt(op1, op2);
}
-static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return efststgt(op1, op2);
+ /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+ return efscmpgt(op1, op2);
}
-static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return efststeq(op1, op2);
+ /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+ return efscmpeq(op1, op2);
}
#define HELPER_SINGLE_SPE_CMP(name) \
@@ -3678,7 +3678,7 @@ uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2)
CPU_DoubleU u1, u2;
u1.ll = op1;
u2.ll = op2;
- return float64_eq(u1.d, u2.d, &env->vec_status) ? 4 : 0;
+ return float64_eq_quiet(u1.d, u2.d, &env->vec_status) ? 4 : 0;
}
uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index e47c372fb..a84b3ee18 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -26,24 +26,35 @@
#define CPUState struct CPUS390XState
#include "cpu-defs.h"
+#define TARGET_PAGE_BITS 12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 64
+#define TARGET_VIRT_ADDR_SPACE_BITS 64
+
+#include "cpu-all.h"
#include "softfloat.h"
-#define NB_MMU_MODES 2
+#define NB_MMU_MODES 3
-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;
+#define MMU_MODE0_SUFFIX _primary
+#define MMU_MODE1_SUFFIX _secondary
+#define MMU_MODE2_SUFFIX _home
+
+#define MMU_USER_IDX 1
+
+#define MAX_EXT_QUEUE 16
+
+typedef struct PSW {
+ uint64_t mask;
+ uint64_t addr;
+} PSW;
+
+typedef struct ExtQueue {
+ uint32_t code;
+ uint32_t param;
+ uint32_t param64;
+} ExtQueue;
typedef struct CPUS390XState {
uint64_t regs[16]; /* GP registers */
@@ -51,17 +62,42 @@ 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 {
- uint64_t mask;
- uint64_t addr;
- } psw;
+ PSW psw;
- int cc; /* condition code (0-3) */
+ uint32_t cc;
+ uint32_t cc_op;
+ uint64_t cc_src;
+ uint64_t cc_dst;
+ uint64_t cc_vr;
uint64_t __excp_addr;
+ uint64_t psa;
+
+ uint32_t int_pgm_code;
+ uint32_t int_pgm_ilc;
+
+ uint32_t int_svc_code;
+ uint32_t int_svc_ilc;
+
+ uint64_t cregs[16]; /* control registers */
+
+ int pending_int;
+ ExtQueue ext_queue[MAX_EXT_QUEUE];
+
+ /* reset does memset(0) up to here */
+
+ int ext_index;
+ int cpu_num;
+ uint8_t *storage_keys;
+
+ uint64_t tod_offset;
+ uint64_t tod_basetime;
+ QEMUTimer *tod_timer;
+
+ QEMUTimer *cpu_timer;
CPU_COMMON
} CPUS390XState;
@@ -69,24 +105,174 @@ typedef struct CPUS390XState {
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
- if (newsp)
+ if (newsp) {
env->regs[15] = newsp;
+ }
env->regs[0] = 0;
}
#endif
-#define MMU_MODE0_SUFFIX _kernel
-#define MMU_MODE1_SUFFIX _user
-#define MMU_USER_IDX 1
+/* Interrupt Codes */
+/* Program Interrupts */
+#define PGM_OPERATION 0x0001
+#define PGM_PRIVILEGED 0x0002
+#define PGM_EXECUTE 0x0003
+#define PGM_PROTECTION 0x0004
+#define PGM_ADDRESSING 0x0005
+#define PGM_SPECIFICATION 0x0006
+#define PGM_DATA 0x0007
+#define PGM_FIXPT_OVERFLOW 0x0008
+#define PGM_FIXPT_DIVIDE 0x0009
+#define PGM_DEC_OVERFLOW 0x000a
+#define PGM_DEC_DIVIDE 0x000b
+#define PGM_HFP_EXP_OVERFLOW 0x000c
+#define PGM_HFP_EXP_UNDERFLOW 0x000d
+#define PGM_HFP_SIGNIFICANCE 0x000e
+#define PGM_HFP_DIVIDE 0x000f
+#define PGM_SEGMENT_TRANS 0x0010
+#define PGM_PAGE_TRANS 0x0011
+#define PGM_TRANS_SPEC 0x0012
+#define PGM_SPECIAL_OP 0x0013
+#define PGM_OPERAND 0x0015
+#define PGM_TRACE_TABLE 0x0016
+#define PGM_SPACE_SWITCH 0x001c
+#define PGM_HFP_SQRT 0x001d
+#define PGM_PC_TRANS_SPEC 0x001f
+#define PGM_AFX_TRANS 0x0020
+#define PGM_ASX_TRANS 0x0021
+#define PGM_LX_TRANS 0x0022
+#define PGM_EX_TRANS 0x0023
+#define PGM_PRIM_AUTH 0x0024
+#define PGM_SEC_AUTH 0x0025
+#define PGM_ALET_SPEC 0x0028
+#define PGM_ALEN_SPEC 0x0029
+#define PGM_ALE_SEQ 0x002a
+#define PGM_ASTE_VALID 0x002b
+#define PGM_ASTE_SEQ 0x002c
+#define PGM_EXT_AUTH 0x002d
+#define PGM_STACK_FULL 0x0030
+#define PGM_STACK_EMPTY 0x0031
+#define PGM_STACK_SPEC 0x0032
+#define PGM_STACK_TYPE 0x0033
+#define PGM_STACK_OP 0x0034
+#define PGM_ASCE_TYPE 0x0038
+#define PGM_REG_FIRST_TRANS 0x0039
+#define PGM_REG_SEC_TRANS 0x003a
+#define PGM_REG_THIRD_TRANS 0x003b
+#define PGM_MONITOR 0x0040
+#define PGM_PER 0x0080
+#define PGM_CRYPTO 0x0119
+
+/* External Interrupts */
+#define EXT_INTERRUPT_KEY 0x0040
+#define EXT_CLOCK_COMP 0x1004
+#define EXT_CPU_TIMER 0x1005
+#define EXT_MALFUNCTION 0x1200
+#define EXT_EMERGENCY 0x1201
+#define EXT_EXTERNAL_CALL 0x1202
+#define EXT_ETR 0x1406
+#define EXT_SERVICE 0x2401
+#define EXT_VIRTIO 0x2603
+
+/* PSW defines */
+#undef PSW_MASK_PER
+#undef PSW_MASK_DAT
+#undef PSW_MASK_IO
+#undef PSW_MASK_EXT
+#undef PSW_MASK_KEY
+#undef PSW_SHIFT_KEY
+#undef PSW_MASK_MCHECK
+#undef PSW_MASK_WAIT
+#undef PSW_MASK_PSTATE
+#undef PSW_MASK_ASC
+#undef PSW_MASK_CC
+#undef PSW_MASK_PM
+#undef PSW_MASK_64
+
+#define PSW_MASK_PER 0x4000000000000000ULL
+#define PSW_MASK_DAT 0x0400000000000000ULL
+#define PSW_MASK_IO 0x0200000000000000ULL
+#define PSW_MASK_EXT 0x0100000000000000ULL
+#define PSW_MASK_KEY 0x00F0000000000000ULL
+#define PSW_SHIFT_KEY 56
+#define PSW_MASK_MCHECK 0x0004000000000000ULL
+#define PSW_MASK_WAIT 0x0002000000000000ULL
+#define PSW_MASK_PSTATE 0x0001000000000000ULL
+#define PSW_MASK_ASC 0x0000C00000000000ULL
+#define PSW_MASK_CC 0x0000300000000000ULL
+#define PSW_MASK_PM 0x00000F0000000000ULL
+#define PSW_MASK_64 0x0000000100000000ULL
+#define PSW_MASK_32 0x0000000080000000ULL
+
+#undef PSW_ASC_PRIMARY
+#undef PSW_ASC_ACCREG
+#undef PSW_ASC_SECONDARY
+#undef PSW_ASC_HOME
+
+#define PSW_ASC_PRIMARY 0x0000000000000000ULL
+#define PSW_ASC_ACCREG 0x0000400000000000ULL
+#define PSW_ASC_SECONDARY 0x0000800000000000ULL
+#define PSW_ASC_HOME 0x0000C00000000000ULL
+
+/* tb flags */
+
+#define FLAG_MASK_PER (PSW_MASK_PER >> 32)
+#define FLAG_MASK_DAT (PSW_MASK_DAT >> 32)
+#define FLAG_MASK_IO (PSW_MASK_IO >> 32)
+#define FLAG_MASK_EXT (PSW_MASK_EXT >> 32)
+#define FLAG_MASK_KEY (PSW_MASK_KEY >> 32)
+#define FLAG_MASK_MCHECK (PSW_MASK_MCHECK >> 32)
+#define FLAG_MASK_WAIT (PSW_MASK_WAIT >> 32)
+#define FLAG_MASK_PSTATE (PSW_MASK_PSTATE >> 32)
+#define FLAG_MASK_ASC (PSW_MASK_ASC >> 32)
+#define FLAG_MASK_CC (PSW_MASK_CC >> 32)
+#define FLAG_MASK_PM (PSW_MASK_PM >> 32)
+#define FLAG_MASK_64 (PSW_MASK_64 >> 32)
+#define FLAG_MASK_32 0x00001000
+
static inline int cpu_mmu_index (CPUState *env)
{
- /* XXX: Currently we don't implement virtual memory */
+ if (env->psw.mask & PSW_MASK_PSTATE) {
+ return 1;
+ }
+
return 0;
}
+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 >> 32) & ~FLAG_MASK_CC) |
+ ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
+}
+
+static inline int get_ilc(uint8_t opc)
+{
+ switch (opc >> 6) {
+ case 0:
+ return 1;
+ case 1:
+ case 2:
+ return 2;
+ case 3:
+ return 3;
+ }
+
+ return 0;
+}
+
+#define ILC_LATER 0x20
+#define ILC_LATER_INC 0x21
+#define ILC_LATER_INC_2 0x22
+
+
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);
+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
@@ -97,41 +283,61 @@ 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);
+int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall);
+
+void kvm_s390_interrupt(CPUState *env, int type, uint32_t code);
void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token);
+void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
+ uint64_t parm64, int vm);
CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
+
+#ifndef KVM_S390_SIGP_STOP
+#define KVM_S390_SIGP_STOP 0
+#define KVM_S390_PROGRAM_INT 0
+#define KVM_S390_SIGP_SET_PREFIX 0
+#define KVM_S390_RESTART 0
+#define KVM_S390_INT_VIRTIO 0
+#define KVM_S390_INT_SERVICE 0
+#define KVM_S390_INT_EMERGENCY 0
+#endif
+
#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 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
-#include "cpu-all.h"
+#include "exec-all.h"
+
+#ifdef CONFIG_USER_ONLY
#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 */
+#define EXCP_SPEC 6 /* specification exception */
-static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
- target_ulong *cs_base, int *flags)
-{
- *pc = env->psw.addr;
- /* XXX this is correct for user-mode emulation, but needs
- * the asce register information as well when softmmu
- * is implemented in the future */
- *cs_base = 0;
- *flags = env->psw.mask;
-}
+#else
+
+#define EXCP_EXT 1 /* external interrupt */
+#define EXCP_SVC 2 /* supervisor call (syscall) */
+#define EXCP_PGM 3 /* program interruption */
+
+#endif /* CONFIG_USER_ONLY */
+
+#define INTERRUPT_EXT (1 << 0)
+#define INTERRUPT_TOD (1 << 1)
+#define INTERRUPT_CPUTIMER (1 << 2)
/* Program Status Word. */
#define S390_PSWM_REGNUM 0
@@ -265,5 +471,485 @@ static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
#define S390_NUM_PSEUDO_REGS 2
#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+/* CC optimization */
+
+enum cc_op {
+ CC_OP_CONST0 = 0, /* CC is 0 */
+ CC_OP_CONST1, /* CC is 1 */
+ CC_OP_CONST2, /* CC is 2 */
+ CC_OP_CONST3, /* CC is 3 */
+
+ CC_OP_DYNAMIC, /* CC calculation defined by env->cc_op */
+ CC_OP_STATIC, /* CC value is env->cc_op */
+
+ CC_OP_NZ, /* env->cc_dst != 0 */
+ CC_OP_LTGT_32, /* signed less/greater than (32bit) */
+ CC_OP_LTGT_64, /* signed less/greater than (64bit) */
+ CC_OP_LTUGTU_32, /* unsigned less/greater than (32bit) */
+ CC_OP_LTUGTU_64, /* unsigned less/greater than (64bit) */
+ CC_OP_LTGT0_32, /* signed less/greater than 0 (32bit) */
+ CC_OP_LTGT0_64, /* signed less/greater than 0 (64bit) */
+
+ CC_OP_ADD_64, /* overflow on add (64bit) */
+ CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */
+ CC_OP_SUB_64, /* overflow on substraction (64bit) */
+ CC_OP_SUBU_64, /* overflow on unsigned substraction (64bit) */
+ CC_OP_ABS_64, /* sign eval on abs (64bit) */
+ CC_OP_NABS_64, /* sign eval on nabs (64bit) */
+
+ CC_OP_ADD_32, /* overflow on add (32bit) */
+ CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */
+ CC_OP_SUB_32, /* overflow on substraction (32bit) */
+ CC_OP_SUBU_32, /* overflow on unsigned substraction (32bit) */
+ CC_OP_ABS_32, /* sign eval on abs (64bit) */
+ CC_OP_NABS_32, /* sign eval on nabs (64bit) */
+
+ CC_OP_COMP_32, /* complement */
+ CC_OP_COMP_64, /* complement */
+
+ CC_OP_TM_32, /* test under mask (32bit) */
+ CC_OP_TM_64, /* test under mask (64bit) */
+
+ CC_OP_LTGT_F32, /* FP compare (32bit) */
+ CC_OP_LTGT_F64, /* FP compare (64bit) */
+
+ CC_OP_NZ_F32, /* FP dst != 0 (32bit) */
+ CC_OP_NZ_F64, /* FP dst != 0 (64bit) */
+
+ CC_OP_ICM, /* insert characters under mask */
+ CC_OP_SLAG, /* Calculate shift left signed */
+ CC_OP_MAX
+};
+
+static const char *cc_names[] = {
+ [CC_OP_CONST0] = "CC_OP_CONST0",
+ [CC_OP_CONST1] = "CC_OP_CONST1",
+ [CC_OP_CONST2] = "CC_OP_CONST2",
+ [CC_OP_CONST3] = "CC_OP_CONST3",
+ [CC_OP_DYNAMIC] = "CC_OP_DYNAMIC",
+ [CC_OP_STATIC] = "CC_OP_STATIC",
+ [CC_OP_NZ] = "CC_OP_NZ",
+ [CC_OP_LTGT_32] = "CC_OP_LTGT_32",
+ [CC_OP_LTGT_64] = "CC_OP_LTGT_64",
+ [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32",
+ [CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64",
+ [CC_OP_LTGT0_32] = "CC_OP_LTGT0_32",
+ [CC_OP_LTGT0_64] = "CC_OP_LTGT0_64",
+ [CC_OP_ADD_64] = "CC_OP_ADD_64",
+ [CC_OP_ADDU_64] = "CC_OP_ADDU_64",
+ [CC_OP_SUB_64] = "CC_OP_SUB_64",
+ [CC_OP_SUBU_64] = "CC_OP_SUBU_64",
+ [CC_OP_ABS_64] = "CC_OP_ABS_64",
+ [CC_OP_NABS_64] = "CC_OP_NABS_64",
+ [CC_OP_ADD_32] = "CC_OP_ADD_32",
+ [CC_OP_ADDU_32] = "CC_OP_ADDU_32",
+ [CC_OP_SUB_32] = "CC_OP_SUB_32",
+ [CC_OP_SUBU_32] = "CC_OP_SUBU_32",
+ [CC_OP_ABS_32] = "CC_OP_ABS_32",
+ [CC_OP_NABS_32] = "CC_OP_NABS_32",
+ [CC_OP_COMP_32] = "CC_OP_COMP_32",
+ [CC_OP_COMP_64] = "CC_OP_COMP_64",
+ [CC_OP_TM_32] = "CC_OP_TM_32",
+ [CC_OP_TM_64] = "CC_OP_TM_64",
+ [CC_OP_LTGT_F32] = "CC_OP_LTGT_F32",
+ [CC_OP_LTGT_F64] = "CC_OP_LTGT_F64",
+ [CC_OP_NZ_F32] = "CC_OP_NZ_F32",
+ [CC_OP_NZ_F64] = "CC_OP_NZ_F64",
+ [CC_OP_ICM] = "CC_OP_ICM",
+ [CC_OP_SLAG] = "CC_OP_SLAG",
+};
+
+static inline const char *cc_name(int cc_op)
+{
+ return cc_names[cc_op];
+}
+
+/* SCLP PV interface defines */
+#define SCLP_CMDW_READ_SCP_INFO 0x00020001
+#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
+
+#define SCP_LENGTH 0x00
+#define SCP_FUNCTION_CODE 0x02
+#define SCP_CONTROL_MASK 0x03
+#define SCP_RESPONSE_CODE 0x06
+#define SCP_MEM_CODE 0x08
+#define SCP_INCREMENT 0x0a
+
+typedef struct LowCore
+{
+ /* prefix area: defined by architecture */
+ uint32_t ccw1[2]; /* 0x000 */
+ uint32_t ccw2[4]; /* 0x008 */
+ uint8_t pad1[0x80-0x18]; /* 0x018 */
+ uint32_t ext_params; /* 0x080 */
+ uint16_t cpu_addr; /* 0x084 */
+ uint16_t ext_int_code; /* 0x086 */
+ uint16_t svc_ilc; /* 0x088 */
+ uint16_t svc_code; /* 0x08a */
+ uint16_t pgm_ilc; /* 0x08c */
+ uint16_t pgm_code; /* 0x08e */
+ uint32_t data_exc_code; /* 0x090 */
+ uint16_t mon_class_num; /* 0x094 */
+ uint16_t per_perc_atmid; /* 0x096 */
+ uint64_t per_address; /* 0x098 */
+ uint8_t exc_access_id; /* 0x0a0 */
+ uint8_t per_access_id; /* 0x0a1 */
+ uint8_t op_access_id; /* 0x0a2 */
+ uint8_t ar_access_id; /* 0x0a3 */
+ uint8_t pad2[0xA8-0xA4]; /* 0x0a4 */
+ uint64_t trans_exc_code; /* 0x0a8 */
+ uint64_t monitor_code; /* 0x0b0 */
+ uint16_t subchannel_id; /* 0x0b8 */
+ uint16_t subchannel_nr; /* 0x0ba */
+ uint32_t io_int_parm; /* 0x0bc */
+ uint32_t io_int_word; /* 0x0c0 */
+ uint8_t pad3[0xc8-0xc4]; /* 0x0c4 */
+ uint32_t stfl_fac_list; /* 0x0c8 */
+ uint8_t pad4[0xe8-0xcc]; /* 0x0cc */
+ uint32_t mcck_interruption_code[2]; /* 0x0e8 */
+ uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */
+ uint32_t external_damage_code; /* 0x0f4 */
+ uint64_t failing_storage_address; /* 0x0f8 */
+ uint8_t pad6[0x120-0x100]; /* 0x100 */
+ PSW restart_old_psw; /* 0x120 */
+ PSW external_old_psw; /* 0x130 */
+ PSW svc_old_psw; /* 0x140 */
+ PSW program_old_psw; /* 0x150 */
+ PSW mcck_old_psw; /* 0x160 */
+ PSW io_old_psw; /* 0x170 */
+ uint8_t pad7[0x1a0-0x180]; /* 0x180 */
+ PSW restart_psw; /* 0x1a0 */
+ PSW external_new_psw; /* 0x1b0 */
+ PSW svc_new_psw; /* 0x1c0 */
+ PSW program_new_psw; /* 0x1d0 */
+ PSW mcck_new_psw; /* 0x1e0 */
+ PSW io_new_psw; /* 0x1f0 */
+ PSW return_psw; /* 0x200 */
+ uint8_t irb[64]; /* 0x210 */
+ uint64_t sync_enter_timer; /* 0x250 */
+ uint64_t async_enter_timer; /* 0x258 */
+ uint64_t exit_timer; /* 0x260 */
+ uint64_t last_update_timer; /* 0x268 */
+ uint64_t user_timer; /* 0x270 */
+ uint64_t system_timer; /* 0x278 */
+ uint64_t last_update_clock; /* 0x280 */
+ uint64_t steal_clock; /* 0x288 */
+ PSW return_mcck_psw; /* 0x290 */
+ uint8_t pad8[0xc00-0x2a0]; /* 0x2a0 */
+ /* System info area */
+ uint64_t save_area[16]; /* 0xc00 */
+ uint8_t pad9[0xd40-0xc80]; /* 0xc80 */
+ uint64_t kernel_stack; /* 0xd40 */
+ uint64_t thread_info; /* 0xd48 */
+ uint64_t async_stack; /* 0xd50 */
+ uint64_t kernel_asce; /* 0xd58 */
+ uint64_t user_asce; /* 0xd60 */
+ uint64_t panic_stack; /* 0xd68 */
+ uint64_t user_exec_asce; /* 0xd70 */
+ uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */
+
+ /* SMP info area: defined by DJB */
+ uint64_t clock_comparator; /* 0xdc0 */
+ uint64_t ext_call_fast; /* 0xdc8 */
+ uint64_t percpu_offset; /* 0xdd0 */
+ uint64_t current_task; /* 0xdd8 */
+ uint32_t softirq_pending; /* 0xde0 */
+ uint32_t pad_0x0de4; /* 0xde4 */
+ uint64_t int_clock; /* 0xde8 */
+ uint8_t pad12[0xe00-0xdf0]; /* 0xdf0 */
+
+ /* 0xe00 is used as indicator for dump tools */
+ /* whether the kernel died with panic() or not */
+ uint32_t panic_magic; /* 0xe00 */
+
+ uint8_t pad13[0x11b8-0xe04]; /* 0xe04 */
+
+ /* 64 bit extparam used for pfault, diag 250 etc */
+ uint64_t ext_params2; /* 0x11B8 */
+
+ uint8_t pad14[0x1200-0x11C0]; /* 0x11C0 */
+
+ /* System info area */
+
+ uint64_t floating_pt_save_area[16]; /* 0x1200 */
+ uint64_t gpregs_save_area[16]; /* 0x1280 */
+ uint32_t st_status_fixed_logout[4]; /* 0x1300 */
+ uint8_t pad15[0x1318-0x1310]; /* 0x1310 */
+ uint32_t prefixreg_save_area; /* 0x1318 */
+ uint32_t fpt_creg_save_area; /* 0x131c */
+ uint8_t pad16[0x1324-0x1320]; /* 0x1320 */
+ uint32_t tod_progreg_save_area; /* 0x1324 */
+ uint32_t cpu_timer_save_area[2]; /* 0x1328 */
+ uint32_t clock_comp_save_area[2]; /* 0x1330 */
+ uint8_t pad17[0x1340-0x1338]; /* 0x1338 */
+ uint32_t access_regs_save_area[16]; /* 0x1340 */
+ uint64_t cregs_save_area[16]; /* 0x1380 */
+
+ /* align to the top of the prefix area */
+
+ uint8_t pad18[0x2000-0x1400]; /* 0x1400 */
+} __attribute__((packed)) LowCore;
+
+/* STSI */
+#define STSI_LEVEL_MASK 0x00000000f0000000ULL
+#define STSI_LEVEL_CURRENT 0x0000000000000000ULL
+#define STSI_LEVEL_1 0x0000000010000000ULL
+#define STSI_LEVEL_2 0x0000000020000000ULL
+#define STSI_LEVEL_3 0x0000000030000000ULL
+#define STSI_R0_RESERVED_MASK 0x000000000fffff00ULL
+#define STSI_R0_SEL1_MASK 0x00000000000000ffULL
+#define STSI_R1_RESERVED_MASK 0x00000000ffff0000ULL
+#define STSI_R1_SEL2_MASK 0x000000000000ffffULL
+
+/* Basic Machine Configuration */
+struct sysib_111 {
+ uint32_t res1[8];
+ uint8_t manuf[16];
+ uint8_t type[4];
+ uint8_t res2[12];
+ uint8_t model[16];
+ uint8_t sequence[16];
+ uint8_t plant[4];
+ uint8_t res3[156];
+};
+
+/* Basic Machine CPU */
+struct sysib_121 {
+ uint32_t res1[80];
+ uint8_t sequence[16];
+ uint8_t plant[4];
+ uint8_t res2[2];
+ uint16_t cpu_addr;
+ uint8_t res3[152];
+};
+
+/* Basic Machine CPUs */
+struct sysib_122 {
+ uint8_t res1[32];
+ uint32_t capability;
+ uint16_t total_cpus;
+ uint16_t active_cpus;
+ uint16_t standby_cpus;
+ uint16_t reserved_cpus;
+ uint16_t adjustments[2026];
+};
+
+/* LPAR CPU */
+struct sysib_221 {
+ uint32_t res1[80];
+ uint8_t sequence[16];
+ uint8_t plant[4];
+ uint16_t cpu_id;
+ uint16_t cpu_addr;
+ uint8_t res3[152];
+};
+
+/* LPAR CPUs */
+struct sysib_222 {
+ uint32_t res1[32];
+ uint16_t lpar_num;
+ uint8_t res2;
+ uint8_t lcpuc;
+ uint16_t total_cpus;
+ uint16_t conf_cpus;
+ uint16_t standby_cpus;
+ uint16_t reserved_cpus;
+ uint8_t name[8];
+ uint32_t caf;
+ uint8_t res3[16];
+ uint16_t dedicated_cpus;
+ uint16_t shared_cpus;
+ uint8_t res4[180];
+};
+
+/* VM CPUs */
+struct sysib_322 {
+ uint8_t res1[31];
+ uint8_t count;
+ struct {
+ uint8_t res2[4];
+ uint16_t total_cpus;
+ uint16_t conf_cpus;
+ uint16_t standby_cpus;
+ uint16_t reserved_cpus;
+ uint8_t name[8];
+ uint32_t caf;
+ uint8_t cpi[16];
+ uint8_t res3[24];
+ } vm[8];
+ uint8_t res4[3552];
+};
+
+/* MMU defines */
+#define _ASCE_ORIGIN ~0xfffULL /* segment table origin */
+#define _ASCE_SUBSPACE 0x200 /* subspace group control */
+#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */
+#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */
+#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */
+#define _ASCE_REAL_SPACE 0x20 /* real space control */
+#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */
+#define _ASCE_TYPE_REGION1 0x0c /* region first table type */
+#define _ASCE_TYPE_REGION2 0x08 /* region second table type */
+#define _ASCE_TYPE_REGION3 0x04 /* region third table type */
+#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */
+#define _ASCE_TABLE_LENGTH 0x03 /* region table length */
+
+#define _REGION_ENTRY_ORIGIN ~0xfffULL /* region/segment table origin */
+#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */
+#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */
+#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */
+#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */
+#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */
+#define _REGION_ENTRY_LENGTH 0x03 /* region third length */
+
+#define _SEGMENT_ENTRY_ORIGIN ~0x7ffULL /* segment table origin */
+#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
+#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
+
+#define _PAGE_RO 0x200 /* HW read-only bit */
+#define _PAGE_INVALID 0x400 /* HW invalid bit */
+
+
+
+/* EBCDIC handling */
+static const uint8_t ebcdic2ascii[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
+ 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+ 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
+ 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
+ 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
+ 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
+ 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
+ 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+ 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
+ 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
+ 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+ 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
+ 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
+ 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
+ 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
+ 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
+};
+
+static const uint8_t ascii2ebcdic [] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ p[i] = ascii2ebcdic[(int)ascii[i]];
+ }
+}
+
+#define SIGP_SENSE 0x01
+#define SIGP_EXTERNAL_CALL 0x02
+#define SIGP_EMERGENCY 0x03
+#define SIGP_START 0x04
+#define SIGP_STOP 0x05
+#define SIGP_RESTART 0x06
+#define SIGP_STOP_STORE_STATUS 0x09
+#define SIGP_INITIAL_CPU_RESET 0x0b
+#define SIGP_CPU_RESET 0x0c
+#define SIGP_SET_PREFIX 0x0d
+#define SIGP_STORE_STATUS_ADDR 0x0e
+#define SIGP_SET_ARCH 0x12
+
+/* cpu status bits */
+#define SIGP_STAT_EQUIPMENT_CHECK 0x80000000UL
+#define SIGP_STAT_INCORRECT_STATE 0x00000200UL
+#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL
+#define SIGP_STAT_EXT_CALL_PENDING 0x00000080UL
+#define SIGP_STAT_STOPPED 0x00000040UL
+#define SIGP_STAT_OPERATOR_INTERV 0x00000020UL
+#define SIGP_STAT_CHECK_STOP 0x00000010UL
+#define SIGP_STAT_INOPERATIVE 0x00000004UL
+#define SIGP_STAT_INVALID_ORDER 0x00000002UL
+#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL
+
+void load_psw(CPUState *env, uint64_t mask, uint64_t addr);
+int mmu_translate(CPUState *env, target_ulong vaddr, int rw, uint64_t asc,
+ target_ulong *raddr, int *flags);
+int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code);
+uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+ uint64_t vr);
+
+#define TARGET_HAS_ICE 1
+
+/* The value of the TOD clock for 1.1.1970. */
+#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
+
+/* Converts ns to s390's clock format */
+static inline uint64_t time2tod(uint64_t ns) {
+ return (ns << 9) / 125;
+}
+
+static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param,
+ uint64_t param64)
+{
+ if (env->ext_index == MAX_EXT_QUEUE - 1) {
+ /* ugh - can't queue anymore. Let's drop. */
+ return;
+ }
+
+ env->ext_index++;
+ assert(env->ext_index < MAX_EXT_QUEUE);
+
+ env->ext_queue[env->ext_index].code = code;
+ env->ext_queue[env->ext_index].param = param;
+ env->ext_queue[env->ext_index].param64 = param64;
+
+ env->pending_int |= INTERRUPT_EXT;
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
#endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index f7893f387..7a87fffca 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -31,7 +31,16 @@ register struct CPUS390XState *env asm(AREG0);
static inline int cpu_has_work(CPUState *env)
{
- return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
+ return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->psw.mask & PSW_MASK_EXT));
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+static inline void env_to_regs(void)
+{
}
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 4a5297be1..629dfd970 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -82,3 +82,7 @@ int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
return 0;
}
#endif /* CONFIG_USER_ONLY */
+
+void do_interrupt (CPUState *env)
+{
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index ae7dc561b..264346072 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -182,8 +182,8 @@ int kvm_arch_process_async_events(CPUState *env)
return 0;
}
-static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
- uint64_t parm64, int vm)
+void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
+ uint64_t parm64, int vm)
{
struct kvm_s390_interrupt kvmint;
int r;
@@ -218,7 +218,7 @@ void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
token, 1);
}
-static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
+void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
{
kvm_s390_interrupt_internal(env, type, code, 0, 0);
}
@@ -237,7 +237,8 @@ static void setcc(CPUState *env, uint64_t cc)
env->psw.mask |= (cc & 3) << 44;
}
-static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0)
+static int kvm_sclp_service_call(CPUState *env, struct kvm_run *run,
+ uint16_t ipbh0)
{
uint32_t sccb;
uint64_t code;
@@ -287,7 +288,7 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
dprintf("KVM: PRIV: %d\n", ipa1);
switch (ipa1) {
case PRIV_SCLP_CALL:
- r = sclp_service_call(env, run, ipbh0);
+ r = kvm_sclp_service_call(env, run, ipbh0);
break;
default:
dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
@@ -300,12 +301,10 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
static int handle_hypercall(CPUState *env, struct kvm_run *run)
{
- int r;
-
cpu_synchronize_state(env);
- r = s390_virtio_hypercall(env);
+ env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
- return r;
+ return 0;
}
static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index d33bfb1f3..2cb893f21 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -36,7 +36,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=%016" PRIx64, i, *(uint64_t *)&env->fregs[i]);
if ((i % 4) == 3) {
cpu_fprintf(f, "\n");
} else {
diff --git a/tests/test-mmap.c b/tests/test-mmap.c
index fcb365f40..c578e2572 100644
--- a/tests/test-mmap.c
+++ b/tests/test-mmap.c
@@ -164,6 +164,7 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
nlen = pagesize * 8;
p3 = mmap(NULL, nlen, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ fail_unless (p3 != MAP_FAILED);
/* Check if the mmaped areas collide. */
if (p3 < p2
@@ -174,7 +175,6 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
/* Make sure we get pages aligned with the pagesize. The
target expects this. */
- fail_unless (p3 != MAP_FAILED);
p = (uintptr_t) p3;
fail_unless ((p & pagemask) == 0);
munmap (p2, pagesize);
diff --git a/usb-linux.c b/usb-linux.c
index 255009f53..1f33c2c23 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -107,7 +107,7 @@ enum {
/*
* Control transfer state.
* Note that 'buffer' _must_ follow 'req' field because
- * we need contigious buffer when we submit control URB.
+ * we need contiguous buffer when we submit control URB.
*/
struct ctrl_struct {
uint16_t len;
@@ -344,6 +344,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
for (interface = 0; interface < nb_interfaces; interface++) {
ctrl.ioctl_code = USBDEVFS_DISCONNECT;
ctrl.ifno = interface;
+ ctrl.data = 0;
ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
if (ret < 0 && errno != ENODATA) {
perror("USBDEVFS_DISCONNECT");
@@ -579,7 +580,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
/*
* Setup ctrl transfer.
*
- * s->ctrl is layed out such that data buffer immediately follows
+ * s->ctrl is laid out such that data buffer immediately follows
* 'req' struct which is exactly what usbdevfs expects.
*/
urb = &aurb->urb;