mbox series

[00/10] fpu: Remove remaining target ifdefs and build only once

Message ID 20250217125055.160887-1-peter.maydell@linaro.org
Headers show
Series fpu: Remove remaining target ifdefs and build only once | expand

Message

Peter Maydell Feb. 17, 2025, 12:50 p.m. UTC
The work I needed to do to make various softfloat emulation behaviours
runtime-selectable for Arm FEAT_AFP has left the fpu code with very
few remaning target ifdefs. So this series turns the last remaning
ones into runtime behaviour choices and switches the fpu code into
"build once" rather than "build per target". The main driver of this
is that we're going to want to do this for the "multiple targets in
one binary" work.

The remaining fpu target ifdefs fall into two categories:

(1) floatx80 behaviours

Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
use in the xsrqpxp round-to-80-bit-precision operation, and the
Linux-user NWFPE emulation nominally supports it, but these are
minor.) x86 and m68k disagree about some of the corner cases of
floatx80 where the value has the explicit Integer bit wrongly set.  At
the moment the fpu code defaults to "floatx80 behaves like x86", with
TARGET_M68K ifdefs to get the other option.

The first six patches in this series remove those ifdefs, replacing
them with a floatx80_behaviour field in float_status which can have
various flags set to select the individual behaviours. The default is
"like x86", which allows us to set these only for m68k and not worry
about the minor "technically makes some use of floatx80" cases.

I do have a question about whether I've correctly understood what we
do (or don't do) for handling input pseudo-denormals, which we
currently do via the FloatFmt::m68k_denormal flag; see patch 6.  I'm
confident that the patch is correct, in the sense of not being a
behaviour change, but less sure about whether the TODO comment I've
added about existing incorrect handling is right.

(2) simple optimizations

A handful of the target ifdefs are making compile-time choices that
can trivially be pushed back to runtime by deleting the ifdef.
Patches 7-9 do these changes.

Then patch 10 can update the meson.build file to "build once".

Tested with 'make check-tcg' and 'make check-functional'; the
series is supposed to not have any behaviour changes.

thanks
-- PMM

Peter Maydell (10):
  fpu: Make targets specify floatx80 default Inf at runtime
  target/m68k: Avoid using floatx80_infinity global const
  target/i386: Avoid using floatx80_infinity global const
  fpu: Make targets specify whether floatx80 Inf can have Int bit clear
  fpu: Make floatx80 invalid encoding settable at runtime
  fpu: Move m68k_denormal fmt flag into floatx80_behaviour
  fpu: Always decide no_signaling_nans() at runtime
  fpu: Always decide snan_bit_is_one() at runtime
  fpu: Don't compile-time disable hardfloat for PPC targets
  fpu: Build only once

 include/fpu/softfloat-helpers.h | 12 +++++
 include/fpu/softfloat-types.h   | 42 +++++++++++++++
 include/fpu/softfloat.h         | 91 ++++++++++++++++++---------------
 fpu/softfloat.c                 | 23 +++------
 target/hppa/fpu_helper.c        |  1 +
 target/i386/tcg/fpu_helper.c    | 51 +++++++++---------
 target/m68k/cpu.c               | 35 +++++++++++++
 target/m68k/fpu_helper.c        |  2 +-
 target/m68k/softfloat.c         | 47 ++++++-----------
 target/sh4/cpu.c                |  1 +
 fpu/softfloat-parts.c.inc       | 20 ++++++--
 fpu/softfloat-specialize.c.inc  | 29 ++++-------
 fpu/meson.build                 |  2 +-
 13 files changed, 220 insertions(+), 136 deletions(-)

Comments

Philippe Mathieu-Daudé Feb. 20, 2025, 8:48 a.m. UTC | #1
On 17/2/25 13:50, Peter Maydell wrote:
> The work I needed to do to make various softfloat emulation behaviours
> runtime-selectable for Arm FEAT_AFP has left the fpu code with very
> few remaning target ifdefs. So this series turns the last remaning
> ones into runtime behaviour choices and switches the fpu code into
> "build once" rather than "build per target". The main driver of this
> is that we're going to want to do this for the "multiple targets in
> one binary" work.

Indeed the following 332 symbols are now removed for each target:

     bfloat16_add
     bfloat16_compare
     bfloat16_compare_quiet
     bfloat16_default_nan
     bfloat16_div
     bfloat16_is_quiet_nan
     bfloat16_is_signaling_nan
     bfloat16_max
     bfloat16_maximum_number
     bfloat16_maxnum
     bfloat16_maxnummag
     bfloat16_min
     bfloat16_minimum_number
     bfloat16_minnum
     bfloat16_minnummag
     bfloat16_mul
     bfloat16_muladd
     bfloat16_round_to_int
     bfloat16_scalbn
     bfloat16_silence_nan
     bfloat16_sqrt
     bfloat16_squash_input_denormal
     bfloat16_sub
     bfloat16_to_float32
     bfloat16_to_float64
     bfloat16_to_int16
     bfloat16_to_int16_round_to_zero
     bfloat16_to_int16_scalbn
     bfloat16_to_int32
     bfloat16_to_int32_round_to_zero
     bfloat16_to_int32_scalbn
     bfloat16_to_int64
     bfloat16_to_int64_round_to_zero
     bfloat16_to_int64_scalbn
     bfloat16_to_int8
     bfloat16_to_int8_round_to_zero
     bfloat16_to_int8_scalbn
     bfloat16_to_uint16
     bfloat16_to_uint16_round_to_zero
     bfloat16_to_uint16_scalbn
     bfloat16_to_uint32
     bfloat16_to_uint32_round_to_zero
     bfloat16_to_uint32_scalbn
     bfloat16_to_uint64
     bfloat16_to_uint64_round_to_zero
     bfloat16_to_uint64_scalbn
     bfloat16_to_uint8
     bfloat16_to_uint8_round_to_zero
     bfloat16_to_uint8_scalbn
     float128_add
     float128_compare
     float128_compare_quiet
     float128_default_nan
     float128_div
     float128_is_quiet_nan
     float128_is_signaling_nan
     float128_max
     float128_maximum_number
     float128_maxnum
     float128_maxnummag
     float128_min
     float128_minimum_number
     float128_minnum
     float128_minnummag
     float128_mul
     float128_muladd
     float128_rem
     float128_round_to_int
     float128_scalbn
     float128_silence_nan
     float128_sqrt
     float128_sub
     float128_to_float32
     float128_to_float64
     float128_to_floatx80
     float128_to_int128
     float128_to_int128_round_to_zero
     float128_to_int32
     float128_to_int32_round_to_zero
     float128_to_int64
     float128_to_int64_round_to_zero
     float128_to_uint128
     float128_to_uint128_round_to_zero
     float128_to_uint32
     float128_to_uint32_round_to_zero
     float128_to_uint64
     float128_to_uint64_round_to_zero
     float16_add
     float16_compare
     float16_compare_quiet
     float16_default_nan
     float16_div
     float16_is_quiet_nan
     float16_is_signaling_nan
     float16_max
     float16_maximum_number
     float16_maxnum
     float16_maxnummag
     float16_min
     float16_minimum_number
     float16_minnum
     float16_minnummag
     float16_mul
     float16_muladd
     float16_muladd_scalbn
     float16_round_to_int
     float16_scalbn
     float16_silence_nan
     float16_sqrt
     float16_squash_input_denormal
     float16_sub
     float16_to_float32
     float16_to_float64
     float16_to_int16
     float16_to_int16_round_to_zero
     float16_to_int16_scalbn
     float16_to_int32
     float16_to_int32_round_to_zero
     float16_to_int32_scalbn
     float16_to_int64
     float16_to_int64_round_to_zero
     float16_to_int64_scalbn
     float16_to_int8
     float16_to_int8_scalbn
     float16_to_uint16
     float16_to_uint16_round_to_zero
     float16_to_uint16_scalbn
     float16_to_uint32
     float16_to_uint32_round_to_zero
     float16_to_uint32_scalbn
     float16_to_uint64
     float16_to_uint64_round_to_zero
     float16_to_uint64_scalbn
     float16_to_uint8
     float16_to_uint8_scalbn
     float32_add
     float32_compare
     float32_compare_quiet
     float32_default_nan
     float32_div
     float32_exp2
     float32_is_quiet_nan
     float32_is_signaling_nan
     float32_log2
     float32_max
     float32_maximum_number
     float32_maxnum
     float32_maxnummag
     float32_min
     float32_minimum_number
     float32_minnum
     float32_minnummag
     float32_mul
     float32_muladd
     float32_muladd_scalbn
     float32_rem
     float32_round_to_int
     float32_scalbn
     float32_silence_nan
     float32_sqrt
     float32_squash_input_denormal
     float32_sub
     float32_to_bfloat16
     float32_to_float128
     float32_to_float16
     float32_to_float64
     float32_to_floatx80
     float32_to_int16
     float32_to_int16_round_to_zero
     float32_to_int16_scalbn
     float32_to_int32
     float32_to_int32_round_to_zero
     float32_to_int32_scalbn
     float32_to_int64
     float32_to_int64_round_to_zero
     float32_to_int64_scalbn
     float32_to_uint16
     float32_to_uint16_round_to_zero
     float32_to_uint16_scalbn
     float32_to_uint32
     float32_to_uint32_round_to_zero
     float32_to_uint32_scalbn
     float32_to_uint64
     float32_to_uint64_round_to_zero
     float32_to_uint64_scalbn
     float64_add
     float64_compare
     float64_compare_quiet
     float64_default_nan
     float64_div
     float64_is_quiet_nan
     float64_is_signaling_nan
     float64_log2
     float64_max
     float64_maximum_number
     float64_maxnum
     float64_maxnummag
     float64_min
     float64_minimum_number
     float64_minnum
     float64_minnummag
     float64_mul
     float64_muladd
     float64_muladd_scalbn
     float64_rem
     float64_round_to_int
     float64_scalbn
     float64_silence_nan
     float64_sqrt
     float64_squash_input_denormal
     float64_sub
     float64_to_bfloat16
     float64_to_float128
     float64_to_float16
     float64_to_float32
     float64_to_floatx80
     float64_to_int16
     float64_to_int16_round_to_zero
     float64_to_int16_scalbn
     float64_to_int32
     float64_to_int32_modulo
     float64_to_int32_round_to_zero
     float64_to_int32_scalbn
     float64_to_int64
     float64_to_int64_modulo
     float64_to_int64_round_to_zero
     float64_to_int64_scalbn
     float64_to_uint16
     float64_to_uint16_round_to_zero
     float64_to_uint16_scalbn
     float64_to_uint32
     float64_to_uint32_round_to_zero
     float64_to_uint32_scalbn
     float64_to_uint64
     float64_to_uint64_round_to_zero
     float64_to_uint64_scalbn
     float64r32_add
     float64r32_div
     float64r32_mul
     float64r32_muladd
     float64r32_sqrt
     float64r32_sub
     floatx80_add
     floatx80_compare
     floatx80_compare_quiet
     floatx80_default_nan
     floatx80_div
     floatx80_infinity
     floatx80_is_quiet_nan
     floatx80_is_signaling_nan
     floatx80_mod
     floatx80_modrem
     floatx80_mul
     floatx80_rem
     floatx80_round
     floatx80_round_to_int
     floatx80_scalbn
     floatx80_silence_nan
     floatx80_sqrt
     floatx80_sub
     floatx80_to_float128
     floatx80_to_float32
     floatx80_to_float64
     floatx80_to_int32
     floatx80_to_int32_round_to_zero
     floatx80_to_int64
     floatx80_to_int64_round_to_zero
     int128_to_float128
     int16_to_bfloat16
     int16_to_bfloat16_scalbn
     int16_to_float16
     int16_to_float16_scalbn
     int16_to_float32
     int16_to_float32_scalbn
     int16_to_float64
     int16_to_float64_scalbn
     int32_to_bfloat16
     int32_to_bfloat16_scalbn
     int32_to_float128
     int32_to_float16
     int32_to_float16_scalbn
     int32_to_float32
     int32_to_float32_scalbn
     int32_to_float64
     int32_to_float64_scalbn
     int32_to_floatx80
     int64_to_bfloat16
     int64_to_bfloat16_scalbn
     int64_to_float128
     int64_to_float16
     int64_to_float16_scalbn
     int64_to_float32
     int64_to_float32_scalbn
     int64_to_float64
     int64_to_float64_scalbn
     int64_to_floatx80
     int8_to_bfloat16
     int8_to_bfloat16_scalbn
     int8_to_float16
     normalizeFloatx80Subnormal
     normalizeRoundAndPackFloatx80
     propagateFloatx80NaN
     roundAndPackFloatx80
     uint128_to_float128
     uint16_to_bfloat16
     uint16_to_bfloat16_scalbn
     uint16_to_float16
     uint16_to_float16_scalbn
     uint16_to_float32
     uint16_to_float32_scalbn
     uint16_to_float64
     uint16_to_float64_scalbn
     uint32_to_bfloat16
     uint32_to_bfloat16_scalbn
     uint32_to_float16
     uint32_to_float16_scalbn
     uint32_to_float32
     uint32_to_float32_scalbn
     uint32_to_float64
     uint32_to_float64_scalbn
     uint64_to_bfloat16
     uint64_to_bfloat16_scalbn
     uint64_to_float128
     uint64_to_float16
     uint64_to_float16_scalbn
     uint64_to_float32
     uint64_to_float32_scalbn
     uint64_to_float64
     uint64_to_float64_scalbn
     uint8_to_bfloat16
     uint8_to_bfloat16_scalbn
     uint8_to_float16

and my single binary duplicate symbols list drastically reduced:

-ld: 1759 duplicate symbols
+ld: 1427 duplicate symbols

Thank you a lot for this huge help! :)

FWIW:
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Philippe Mathieu-Daudé Feb. 20, 2025, 9 a.m. UTC | #2
On 20/2/25 09:48, Philippe Mathieu-Daudé wrote:
> On 17/2/25 13:50, Peter Maydell wrote:
>> The work I needed to do to make various softfloat emulation behaviours
>> runtime-selectable for Arm FEAT_AFP has left the fpu code with very
>> few remaning target ifdefs. So this series turns the last remaning
>> ones into runtime behaviour choices and switches the fpu code into
>> "build once" rather than "build per target". The main driver of this
>> is that we're going to want to do this for the "multiple targets in
>> one binary" work.


> and my single binary duplicate symbols list drastically reduced:
> 
> -ld: 1759 duplicate symbols
> +ld: 1427 duplicate symbols

(being so far for a microblaze+xtensa config:)

CpuModelCompareResult_lookup
CpuModelExpansionType_lookup
QAPIEvent_lookup
accel_cpu_common_realize
accel_cpu_common_unrealize
accel_cpu_instance_init
accel_find
accel_init_interfaces
accel_supported_gdbstub_sstep_flags
address_space_access_valid
address_space_cache_destroy
address_space_cache_init
address_space_cache_invalidate
address_space_destroy
address_space_dispatch_compact
address_space_dispatch_free
address_space_dispatch_new
address_space_get_flatview
address_space_get_iotlb_entry
address_space_init
address_space_io
address_space_ldl
address_space_ldl_be
address_space_ldl_be_cached_slow
address_space_ldl_cached_slow
address_space_ldl_le
address_space_ldl_le_cached_slow
address_space_ldq
address_space_ldq_be
address_space_ldq_be_cached_slow
address_space_ldq_cached_slow
address_space_ldq_le
address_space_ldq_le_cached_slow
address_space_ldub
address_space_ldub_cached_slow
address_space_lduw
address_space_lduw_be
address_space_lduw_be_cached_slow
address_space_lduw_cached_slow
address_space_lduw_le
address_space_lduw_le_cached_slow
address_space_map
address_space_memory
address_space_read_cached_slow
address_space_read_full
address_space_register_map_client
address_space_remove_listeners
address_space_rw
address_space_set
address_space_stb
address_space_stb_cached_slow
address_space_stl
address_space_stl_be
address_space_stl_be_cached_slow
address_space_stl_cached_slow
address_space_stl_le
address_space_stl_le_cached_slow
address_space_stl_notdirty
address_space_stl_notdirty_cached_slow
address_space_stq
address_space_stq_be
address_space_stq_be_cached_slow
address_space_stq_cached_slow
address_space_stq_le
address_space_stq_le_cached_slow
address_space_stw
address_space_stw_be
address_space_stw_be_cached_slow
address_space_stw_cached_slow
address_space_stw_le
address_space_stw_le_cached_slow
address_space_translate_for_iotlb
address_space_unmap
address_space_unregister_map_client
address_space_write
address_space_write_cached_slow
address_space_write_rom
arch_type
colo_flush_ram_cache
colo_incoming_start_dirty_log
colo_init_ram_cache
colo_record_bitmap
colo_release_ram_cache
cpu_abort
cpu_address_space_destroy
cpu_address_space_init
cpu_atomic_add_fetchb_mmu
cpu_atomic_add_fetchl_be_mmu
cpu_atomic_add_fetchl_le_mmu
cpu_atomic_add_fetchq_be_mmu
cpu_atomic_add_fetchq_le_mmu
cpu_atomic_add_fetchw_be_mmu
cpu_atomic_add_fetchw_le_mmu
cpu_atomic_and_fetchb_mmu
cpu_atomic_and_fetchl_be_mmu
cpu_atomic_and_fetchl_le_mmu
cpu_atomic_and_fetchq_be_mmu
cpu_atomic_and_fetchq_le_mmu
cpu_atomic_and_fetchw_be_mmu
cpu_atomic_and_fetchw_le_mmu
cpu_atomic_cmpxchgb_mmu
cpu_atomic_cmpxchgl_be_mmu
cpu_atomic_cmpxchgl_le_mmu
cpu_atomic_cmpxchgo_be_mmu
cpu_atomic_cmpxchgo_le_mmu
cpu_atomic_cmpxchgq_be_mmu
cpu_atomic_cmpxchgq_le_mmu
cpu_atomic_cmpxchgw_be_mmu
cpu_atomic_cmpxchgw_le_mmu
cpu_atomic_fetch_addb_mmu
cpu_atomic_fetch_addl_be_mmu
cpu_atomic_fetch_addl_le_mmu
cpu_atomic_fetch_addq_be_mmu
cpu_atomic_fetch_addq_le_mmu
cpu_atomic_fetch_addw_be_mmu
cpu_atomic_fetch_addw_le_mmu
cpu_atomic_fetch_andb_mmu
cpu_atomic_fetch_andl_be_mmu
cpu_atomic_fetch_andl_le_mmu
cpu_atomic_fetch_andq_be_mmu
cpu_atomic_fetch_andq_le_mmu
cpu_atomic_fetch_andw_be_mmu
cpu_atomic_fetch_andw_le_mmu
cpu_atomic_fetch_orb_mmu
cpu_atomic_fetch_orl_be_mmu
cpu_atomic_fetch_orl_le_mmu
cpu_atomic_fetch_orq_be_mmu
cpu_atomic_fetch_orq_le_mmu
cpu_atomic_fetch_orw_be_mmu
cpu_atomic_fetch_orw_le_mmu
cpu_atomic_fetch_smaxb_mmu
cpu_atomic_fetch_smaxl_be_mmu
cpu_atomic_fetch_smaxl_le_mmu
cpu_atomic_fetch_smaxq_be_mmu
cpu_atomic_fetch_smaxq_le_mmu
cpu_atomic_fetch_smaxw_be_mmu
cpu_atomic_fetch_smaxw_le_mmu
cpu_atomic_fetch_sminb_mmu
cpu_atomic_fetch_sminl_be_mmu
cpu_atomic_fetch_sminl_le_mmu
cpu_atomic_fetch_sminq_be_mmu
cpu_atomic_fetch_sminq_le_mmu
cpu_atomic_fetch_sminw_be_mmu
cpu_atomic_fetch_sminw_le_mmu
cpu_atomic_fetch_umaxb_mmu
cpu_atomic_fetch_umaxl_be_mmu
cpu_atomic_fetch_umaxl_le_mmu
cpu_atomic_fetch_umaxq_be_mmu
cpu_atomic_fetch_umaxq_le_mmu
cpu_atomic_fetch_umaxw_be_mmu
cpu_atomic_fetch_umaxw_le_mmu
cpu_atomic_fetch_uminb_mmu
cpu_atomic_fetch_uminl_be_mmu
cpu_atomic_fetch_uminl_le_mmu
cpu_atomic_fetch_uminq_be_mmu
cpu_atomic_fetch_uminq_le_mmu
cpu_atomic_fetch_uminw_be_mmu
cpu_atomic_fetch_uminw_le_mmu
cpu_atomic_fetch_xorb_mmu
cpu_atomic_fetch_xorl_be_mmu
cpu_atomic_fetch_xorl_le_mmu
cpu_atomic_fetch_xorq_be_mmu
cpu_atomic_fetch_xorq_le_mmu
cpu_atomic_fetch_xorw_be_mmu
cpu_atomic_fetch_xorw_le_mmu
cpu_atomic_or_fetchb_mmu
cpu_atomic_or_fetchl_be_mmu
cpu_atomic_or_fetchl_le_mmu
cpu_atomic_or_fetchq_be_mmu
cpu_atomic_or_fetchq_le_mmu
cpu_atomic_or_fetchw_be_mmu
cpu_atomic_or_fetchw_le_mmu
cpu_atomic_smax_fetchb_mmu
cpu_atomic_smax_fetchl_be_mmu
cpu_atomic_smax_fetchl_le_mmu
cpu_atomic_smax_fetchq_be_mmu
cpu_atomic_smax_fetchq_le_mmu
cpu_atomic_smax_fetchw_be_mmu
cpu_atomic_smax_fetchw_le_mmu
cpu_atomic_smin_fetchb_mmu
cpu_atomic_smin_fetchl_be_mmu
cpu_atomic_smin_fetchl_le_mmu
cpu_atomic_smin_fetchq_be_mmu
cpu_atomic_smin_fetchq_le_mmu
cpu_atomic_smin_fetchw_be_mmu
cpu_atomic_smin_fetchw_le_mmu
cpu_atomic_umax_fetchb_mmu
cpu_atomic_umax_fetchl_be_mmu
cpu_atomic_umax_fetchl_le_mmu
cpu_atomic_umax_fetchq_be_mmu
cpu_atomic_umax_fetchq_le_mmu
cpu_atomic_umax_fetchw_be_mmu
cpu_atomic_umax_fetchw_le_mmu
cpu_atomic_umin_fetchb_mmu
cpu_atomic_umin_fetchl_be_mmu
cpu_atomic_umin_fetchl_le_mmu
cpu_atomic_umin_fetchq_be_mmu
cpu_atomic_umin_fetchq_le_mmu
cpu_atomic_umin_fetchw_be_mmu
cpu_atomic_umin_fetchw_le_mmu
cpu_atomic_xchgb_mmu
cpu_atomic_xchgl_be_mmu
cpu_atomic_xchgl_le_mmu
cpu_atomic_xchgq_be_mmu
cpu_atomic_xchgq_le_mmu
cpu_atomic_xchgw_be_mmu
cpu_atomic_xchgw_le_mmu
cpu_atomic_xor_fetchb_mmu
cpu_atomic_xor_fetchl_be_mmu
cpu_atomic_xor_fetchl_le_mmu
cpu_atomic_xor_fetchq_be_mmu
cpu_atomic_xor_fetchq_le_mmu
cpu_atomic_xor_fetchw_be_mmu
cpu_atomic_xor_fetchw_le_mmu
cpu_check_watchpoint
cpu_class_init_props
cpu_exec
cpu_exec_init_all
cpu_exec_initfn
cpu_exec_realizefn
cpu_exec_step_atomic
cpu_exec_unrealizefn
cpu_flush_icache_range
cpu_get_address_space
cpu_inb
cpu_inl
cpu_inw
cpu_io_recompile
cpu_ld16_mmu
cpu_ldb_code_mmu
cpu_ldb_mmu
cpu_ldl_be_data
cpu_ldl_be_data_ra
cpu_ldl_be_mmuidx_ra
cpu_ldl_code
cpu_ldl_code_mmu
cpu_ldl_le_data
cpu_ldl_le_data_ra
cpu_ldl_le_mmuidx_ra
cpu_ldl_mmu
cpu_ldq_be_data
cpu_ldq_be_data_ra
cpu_ldq_be_mmuidx_ra
cpu_ldq_code
cpu_ldq_code_mmu
cpu_ldq_le_data
cpu_ldq_le_data_ra
cpu_ldq_le_mmuidx_ra
cpu_ldq_mmu
cpu_ldsb_data
cpu_ldsb_data_ra
cpu_ldsb_mmuidx_ra
cpu_ldsw_be_data
cpu_ldsw_be_data_ra
cpu_ldsw_be_mmuidx_ra
cpu_ldsw_le_data
cpu_ldsw_le_data_ra
cpu_ldsw_le_mmuidx_ra
cpu_ldub_code
cpu_ldub_data
cpu_ldub_data_ra
cpu_ldub_mmuidx_ra
cpu_lduw_be_data
cpu_lduw_be_data_ra
cpu_lduw_be_mmuidx_ra
cpu_lduw_code
cpu_lduw_le_data
cpu_lduw_le_data_ra
cpu_lduw_le_mmuidx_ra
cpu_ldw_code_mmu
cpu_ldw_mmu
cpu_memory_rw_debug
cpu_model_from_type
cpu_outb
cpu_outl
cpu_outw
cpu_physical_memory_is_io
cpu_physical_memory_map
cpu_physical_memory_rw
cpu_physical_memory_snapshot_and_clear_dirty
cpu_physical_memory_snapshot_get_dirty
cpu_physical_memory_test_and_clear_dirty
cpu_physical_memory_unmap
cpu_restore_state
cpu_restore_state_from_tb
cpu_single_step
cpu_st16_mmu
cpu_stb_data
cpu_stb_data_ra
cpu_stb_mmu
cpu_stb_mmuidx_ra
cpu_stl_be_data
cpu_stl_be_data_ra
cpu_stl_be_mmuidx_ra
cpu_stl_le_data
cpu_stl_le_data_ra
cpu_stl_le_mmuidx_ra
cpu_stl_mmu
cpu_stq_be_data
cpu_stq_be_data_ra
cpu_stq_be_mmuidx_ra
cpu_stq_le_data
cpu_stq_le_data_ra
cpu_stq_le_mmuidx_ra
cpu_stq_mmu
cpu_stw_be_data
cpu_stw_be_data_ra
cpu_stw_be_mmuidx_ra
cpu_stw_le_data
cpu_stw_le_data_ra
cpu_stw_le_mmuidx_ra
cpu_stw_mmu
cpu_unwind_state_data
cpu_watchpoint_address_matches
cpu_watchpoint_insert
cpu_watchpoint_remove
cpu_watchpoint_remove_all
cpu_watchpoint_remove_by_ref
create_win_dump
curr_cflags
current_accel_name
finalize_target_page_bits
flatview_add_to_dispatch
flatview_for_each_range
flatview_read_continue
flatview_translate
flatview_unref
foreach_not_ignored_block
gdb_static_features
get_monitor_def
get_page_addr_code_hostp
get_system_io
get_system_memory
global_dirty_tracking
gpa2hva
graphic_depth
graphic_height
graphic_width
helper_atomic_add_fetchb
helper_atomic_add_fetchl_be
helper_atomic_add_fetchl_le
helper_atomic_add_fetchq_be
helper_atomic_add_fetchq_le
helper_atomic_add_fetchw_be
helper_atomic_add_fetchw_le
helper_atomic_and_fetchb
helper_atomic_and_fetchl_be
helper_atomic_and_fetchl_le
helper_atomic_and_fetchq_be
helper_atomic_and_fetchq_le
helper_atomic_and_fetchw_be
helper_atomic_and_fetchw_le
helper_atomic_cmpxchgb
helper_atomic_cmpxchgl_be
helper_atomic_cmpxchgl_le
helper_atomic_cmpxchgo_be
helper_atomic_cmpxchgo_le
helper_atomic_cmpxchgq_be
helper_atomic_cmpxchgq_le
helper_atomic_cmpxchgw_be
helper_atomic_cmpxchgw_le
helper_atomic_fetch_addb
helper_atomic_fetch_addl_be
helper_atomic_fetch_addl_le
helper_atomic_fetch_addq_be
helper_atomic_fetch_addq_le
helper_atomic_fetch_addw_be
helper_atomic_fetch_addw_le
helper_atomic_fetch_andb
helper_atomic_fetch_andl_be
helper_atomic_fetch_andl_le
helper_atomic_fetch_andq_be
helper_atomic_fetch_andq_le
helper_atomic_fetch_andw_be
helper_atomic_fetch_andw_le
helper_atomic_fetch_orb
helper_atomic_fetch_orl_be
helper_atomic_fetch_orl_le
helper_atomic_fetch_orq_be
helper_atomic_fetch_orq_le
helper_atomic_fetch_orw_be
helper_atomic_fetch_orw_le
helper_atomic_fetch_smaxb
helper_atomic_fetch_smaxl_be
helper_atomic_fetch_smaxl_le
helper_atomic_fetch_smaxq_be
helper_atomic_fetch_smaxq_le
helper_atomic_fetch_smaxw_be
helper_atomic_fetch_smaxw_le
helper_atomic_fetch_sminb
helper_atomic_fetch_sminl_be
helper_atomic_fetch_sminl_le
helper_atomic_fetch_sminq_be
helper_atomic_fetch_sminq_le
helper_atomic_fetch_sminw_be
helper_atomic_fetch_sminw_le
helper_atomic_fetch_umaxb
helper_atomic_fetch_umaxl_be
helper_atomic_fetch_umaxl_le
helper_atomic_fetch_umaxq_be
helper_atomic_fetch_umaxq_le
helper_atomic_fetch_umaxw_be
helper_atomic_fetch_umaxw_le
helper_atomic_fetch_uminb
helper_atomic_fetch_uminl_be
helper_atomic_fetch_uminl_le
helper_atomic_fetch_uminq_be
helper_atomic_fetch_uminq_le
helper_atomic_fetch_uminw_be
helper_atomic_fetch_uminw_le
helper_atomic_fetch_xorb
helper_atomic_fetch_xorl_be
helper_atomic_fetch_xorl_le
helper_atomic_fetch_xorq_be
helper_atomic_fetch_xorq_le
helper_atomic_fetch_xorw_be
helper_atomic_fetch_xorw_le
helper_atomic_or_fetchb
helper_atomic_or_fetchl_be
helper_atomic_or_fetchl_le
helper_atomic_or_fetchq_be
helper_atomic_or_fetchq_le
helper_atomic_or_fetchw_be
helper_atomic_or_fetchw_le
helper_atomic_smax_fetchb
helper_atomic_smax_fetchl_be
helper_atomic_smax_fetchl_le
helper_atomic_smax_fetchq_be
helper_atomic_smax_fetchq_le
helper_atomic_smax_fetchw_be
helper_atomic_smax_fetchw_le
helper_atomic_smin_fetchb
helper_atomic_smin_fetchl_be
helper_atomic_smin_fetchl_le
helper_atomic_smin_fetchq_be
helper_atomic_smin_fetchq_le
helper_atomic_smin_fetchw_be
helper_atomic_smin_fetchw_le
helper_atomic_umax_fetchb
helper_atomic_umax_fetchl_be
helper_atomic_umax_fetchl_le
helper_atomic_umax_fetchq_be
helper_atomic_umax_fetchq_le
helper_atomic_umax_fetchw_be
helper_atomic_umax_fetchw_le
helper_atomic_umin_fetchb
helper_atomic_umin_fetchl_be
helper_atomic_umin_fetchl_le
helper_atomic_umin_fetchq_be
helper_atomic_umin_fetchq_le
helper_atomic_umin_fetchw_be
helper_atomic_umin_fetchw_le
helper_atomic_xchgb
helper_atomic_xchgl_be
helper_atomic_xchgl_le
helper_atomic_xchgq_be
helper_atomic_xchgq_le
helper_atomic_xchgw_be
helper_atomic_xchgw_le
helper_atomic_xor_fetchb
helper_atomic_xor_fetchl_be
helper_atomic_xor_fetchl_le
helper_atomic_xor_fetchq_be
helper_atomic_xor_fetchq_le
helper_atomic_xor_fetchw_be
helper_atomic_xor_fetchw_le
helper_clrsb_i32
helper_clrsb_i64
helper_clz_i32
helper_clz_i64
helper_ctpop_i32
helper_ctpop_i64
helper_ctz_i32
helper_ctz_i64
helper_div_i32
helper_div_i64
helper_divs
helper_divu
helper_divu_i32
helper_divu_i64
helper_exit_atomic
helper_fadd
helper_fcmp_eq
helper_fcmp_ge
helper_fcmp_gt
helper_fcmp_le
helper_fcmp_lt
helper_fcmp_ne
helper_fcmp_un
helper_fdiv
helper_fint
helper_flt
helper_fmul
helper_frsub
helper_fsqrt
helper_get
helper_gvec_abs16
helper_gvec_abs32
helper_gvec_abs64
helper_gvec_abs8
helper_gvec_add16
helper_gvec_add32
helper_gvec_add64
helper_gvec_add8
helper_gvec_adds16
helper_gvec_adds32
helper_gvec_adds64
helper_gvec_adds8
helper_gvec_and
helper_gvec_andc
helper_gvec_andcs
helper_gvec_ands
helper_gvec_bitsel
helper_gvec_dup16
helper_gvec_dup32
helper_gvec_dup64
helper_gvec_dup8
helper_gvec_eq16
helper_gvec_eq32
helper_gvec_eq64
helper_gvec_eq8
helper_gvec_eqs16
helper_gvec_eqs32
helper_gvec_eqs64
helper_gvec_eqs8
helper_gvec_eqv
helper_gvec_le16
helper_gvec_le32
helper_gvec_le64
helper_gvec_le8
helper_gvec_les16
helper_gvec_les32
helper_gvec_les64
helper_gvec_les8
helper_gvec_leu16
helper_gvec_leu32
helper_gvec_leu64
helper_gvec_leu8
helper_gvec_leus16
helper_gvec_leus32
helper_gvec_leus64
helper_gvec_leus8
helper_gvec_lt16
helper_gvec_lt32
helper_gvec_lt64
helper_gvec_lt8
helper_gvec_lts16
helper_gvec_lts32
helper_gvec_lts64
helper_gvec_lts8
helper_gvec_ltu16
helper_gvec_ltu32
helper_gvec_ltu64
helper_gvec_ltu8
helper_gvec_ltus16
helper_gvec_ltus32
helper_gvec_ltus64
helper_gvec_ltus8
helper_gvec_mov
helper_gvec_mul16
helper_gvec_mul32
helper_gvec_mul64
helper_gvec_mul8
helper_gvec_muls16
helper_gvec_muls32
helper_gvec_muls64
helper_gvec_muls8
helper_gvec_nand
helper_gvec_ne16
helper_gvec_ne32
helper_gvec_ne64
helper_gvec_ne8
helper_gvec_neg16
helper_gvec_neg32
helper_gvec_neg64
helper_gvec_neg8
helper_gvec_nor
helper_gvec_not
helper_gvec_or
helper_gvec_orc
helper_gvec_ors
helper_gvec_rotl16i
helper_gvec_rotl16v
helper_gvec_rotl32i
helper_gvec_rotl32v
helper_gvec_rotl64i
helper_gvec_rotl64v
helper_gvec_rotl8i
helper_gvec_rotl8v
helper_gvec_rotr16v
helper_gvec_rotr32v
helper_gvec_rotr64v
helper_gvec_rotr8v
helper_gvec_sar16i
helper_gvec_sar16v
helper_gvec_sar32i
helper_gvec_sar32v
helper_gvec_sar64i
helper_gvec_sar64v
helper_gvec_sar8i
helper_gvec_sar8v
helper_gvec_shl16i
helper_gvec_shl16v
helper_gvec_shl32i
helper_gvec_shl32v
helper_gvec_shl64i
helper_gvec_shl64v
helper_gvec_shl8i
helper_gvec_shl8v
helper_gvec_shr16i
helper_gvec_shr16v
helper_gvec_shr32i
helper_gvec_shr32v
helper_gvec_shr64i
helper_gvec_shr64v
helper_gvec_shr8i
helper_gvec_shr8v
helper_gvec_smax16
helper_gvec_smax32
helper_gvec_smax64
helper_gvec_smax8
helper_gvec_smin16
helper_gvec_smin32
helper_gvec_smin64
helper_gvec_smin8
helper_gvec_ssadd16
helper_gvec_ssadd32
helper_gvec_ssadd64
helper_gvec_ssadd8
helper_gvec_sssub16
helper_gvec_sssub32
helper_gvec_sssub64
helper_gvec_sssub8
helper_gvec_sub16
helper_gvec_sub32
helper_gvec_sub64
helper_gvec_sub8
helper_gvec_subs16
helper_gvec_subs32
helper_gvec_subs64
helper_gvec_subs8
helper_gvec_umax16
helper_gvec_umax32
helper_gvec_umax64
helper_gvec_umax8
helper_gvec_umin16
helper_gvec_umin32
helper_gvec_umin64
helper_gvec_umin8
helper_gvec_usadd16
helper_gvec_usadd32
helper_gvec_usadd64
helper_gvec_usadd8
helper_gvec_ussub16
helper_gvec_ussub32
helper_gvec_ussub64
helper_gvec_ussub8
helper_gvec_xor
helper_gvec_xors
helper_info_atomic_add_fetchb
helper_info_atomic_add_fetchl_be
helper_info_atomic_add_fetchl_le
helper_info_atomic_add_fetchq_be
helper_info_atomic_add_fetchq_le
helper_info_atomic_add_fetchw_be
helper_info_atomic_add_fetchw_le
helper_info_atomic_and_fetchb
helper_info_atomic_and_fetchl_be
helper_info_atomic_and_fetchl_le
helper_info_atomic_and_fetchq_be
helper_info_atomic_and_fetchq_le
helper_info_atomic_and_fetchw_be
helper_info_atomic_and_fetchw_le
helper_info_atomic_cmpxchgb
helper_info_atomic_cmpxchgl_be
helper_info_atomic_cmpxchgl_le
helper_info_atomic_cmpxchgo_be
helper_info_atomic_cmpxchgo_le
helper_info_atomic_cmpxchgq_be
helper_info_atomic_cmpxchgq_le
helper_info_atomic_cmpxchgw_be
helper_info_atomic_cmpxchgw_le
helper_info_atomic_fetch_addb
helper_info_atomic_fetch_addl_be
helper_info_atomic_fetch_addl_le
helper_info_atomic_fetch_addq_be
helper_info_atomic_fetch_addq_le
helper_info_atomic_fetch_addw_be
helper_info_atomic_fetch_addw_le
helper_info_atomic_fetch_andb
helper_info_atomic_fetch_andl_be
helper_info_atomic_fetch_andl_le
helper_info_atomic_fetch_andq_be
helper_info_atomic_fetch_andq_le
helper_info_atomic_fetch_andw_be
helper_info_atomic_fetch_andw_le
helper_info_atomic_fetch_orb
helper_info_atomic_fetch_orl_be
helper_info_atomic_fetch_orl_le
helper_info_atomic_fetch_orq_be
helper_info_atomic_fetch_orq_le
helper_info_atomic_fetch_orw_be
helper_info_atomic_fetch_orw_le
helper_info_atomic_fetch_smaxb
helper_info_atomic_fetch_smaxl_be
helper_info_atomic_fetch_smaxl_le
helper_info_atomic_fetch_smaxq_be
helper_info_atomic_fetch_smaxq_le
helper_info_atomic_fetch_smaxw_be
helper_info_atomic_fetch_smaxw_le
helper_info_atomic_fetch_sminb
helper_info_atomic_fetch_sminl_be
helper_info_atomic_fetch_sminl_le
helper_info_atomic_fetch_sminq_be
helper_info_atomic_fetch_sminq_le
helper_info_atomic_fetch_sminw_be
helper_info_atomic_fetch_sminw_le
helper_info_atomic_fetch_umaxb
helper_info_atomic_fetch_umaxl_be
helper_info_atomic_fetch_umaxl_le
helper_info_atomic_fetch_umaxq_be
helper_info_atomic_fetch_umaxq_le
helper_info_atomic_fetch_umaxw_be
helper_info_atomic_fetch_umaxw_le
helper_info_atomic_fetch_uminb
helper_info_atomic_fetch_uminl_be
helper_info_atomic_fetch_uminl_le
helper_info_atomic_fetch_uminq_be
helper_info_atomic_fetch_uminq_le
helper_info_atomic_fetch_uminw_be
helper_info_atomic_fetch_uminw_le
helper_info_atomic_fetch_xorb
helper_info_atomic_fetch_xorl_be
helper_info_atomic_fetch_xorl_le
helper_info_atomic_fetch_xorq_be
helper_info_atomic_fetch_xorq_le
helper_info_atomic_fetch_xorw_be
helper_info_atomic_fetch_xorw_le
helper_info_atomic_or_fetchb
helper_info_atomic_or_fetchl_be
helper_info_atomic_or_fetchl_le
helper_info_atomic_or_fetchq_be
helper_info_atomic_or_fetchq_le
helper_info_atomic_or_fetchw_be
helper_info_atomic_or_fetchw_le
helper_info_atomic_smax_fetchb
helper_info_atomic_smax_fetchl_be
helper_info_atomic_smax_fetchl_le
helper_info_atomic_smax_fetchq_be
helper_info_atomic_smax_fetchq_le
helper_info_atomic_smax_fetchw_be
helper_info_atomic_smax_fetchw_le
helper_info_atomic_smin_fetchb
helper_info_atomic_smin_fetchl_be
helper_info_atomic_smin_fetchl_le
helper_info_atomic_smin_fetchq_be
helper_info_atomic_smin_fetchq_le
helper_info_atomic_smin_fetchw_be
helper_info_atomic_smin_fetchw_le
helper_info_atomic_umax_fetchb
helper_info_atomic_umax_fetchl_be
helper_info_atomic_umax_fetchl_le
helper_info_atomic_umax_fetchq_be
helper_info_atomic_umax_fetchq_le
helper_info_atomic_umax_fetchw_be
helper_info_atomic_umax_fetchw_le
helper_info_atomic_umin_fetchb
helper_info_atomic_umin_fetchl_be
helper_info_atomic_umin_fetchl_le
helper_info_atomic_umin_fetchq_be
helper_info_atomic_umin_fetchq_le
helper_info_atomic_umin_fetchw_be
helper_info_atomic_umin_fetchw_le
helper_info_atomic_xchgb
helper_info_atomic_xchgl_be
helper_info_atomic_xchgl_le
helper_info_atomic_xchgq_be
helper_info_atomic_xchgq_le
helper_info_atomic_xchgw_be
helper_info_atomic_xchgw_le
helper_info_atomic_xor_fetchb
helper_info_atomic_xor_fetchl_be
helper_info_atomic_xor_fetchl_le
helper_info_atomic_xor_fetchq_be
helper_info_atomic_xor_fetchq_le
helper_info_atomic_xor_fetchw_be
helper_info_atomic_xor_fetchw_le
helper_info_clrsb_i32
helper_info_clrsb_i64
helper_info_clz_i32
helper_info_clz_i64
helper_info_ctpop_i32
helper_info_ctpop_i64
helper_info_ctz_i32
helper_info_ctz_i64
helper_info_div_i32
helper_info_div_i64
helper_info_divs
helper_info_divu
helper_info_divu_i32
helper_info_divu_i64
helper_info_exit_atomic
helper_info_fadd
helper_info_fcmp_eq
helper_info_fcmp_ge
helper_info_fcmp_gt
helper_info_fcmp_le
helper_info_fcmp_lt
helper_info_fcmp_ne
helper_info_fcmp_un
helper_info_fdiv
helper_info_fint
helper_info_flt
helper_info_fmul
helper_info_frsub
helper_info_fsqrt
helper_info_get
helper_info_gvec_abs16
helper_info_gvec_abs32
helper_info_gvec_abs64
helper_info_gvec_abs8
helper_info_gvec_add16
helper_info_gvec_add32
helper_info_gvec_add64
helper_info_gvec_add8
helper_info_gvec_adds16
helper_info_gvec_adds32
helper_info_gvec_adds64
helper_info_gvec_adds8
helper_info_gvec_and
helper_info_gvec_andc
helper_info_gvec_andcs
helper_info_gvec_ands
helper_info_gvec_bitsel
helper_info_gvec_dup16
helper_info_gvec_dup32
helper_info_gvec_dup64
helper_info_gvec_dup8
helper_info_gvec_eq16
helper_info_gvec_eq32
helper_info_gvec_eq64
helper_info_gvec_eq8
helper_info_gvec_eqs16
helper_info_gvec_eqs32
helper_info_gvec_eqs64
helper_info_gvec_eqs8
helper_info_gvec_eqv
helper_info_gvec_le16
helper_info_gvec_le32
helper_info_gvec_le64
helper_info_gvec_le8
helper_info_gvec_les16
helper_info_gvec_les32
helper_info_gvec_les64
helper_info_gvec_les8
helper_info_gvec_leu16
helper_info_gvec_leu32
helper_info_gvec_leu64
helper_info_gvec_leu8
helper_info_gvec_leus16
helper_info_gvec_leus32
helper_info_gvec_leus64
helper_info_gvec_leus8
helper_info_gvec_lt16
helper_info_gvec_lt32
helper_info_gvec_lt64
helper_info_gvec_lt8
helper_info_gvec_lts16
helper_info_gvec_lts32
helper_info_gvec_lts64
helper_info_gvec_lts8
helper_info_gvec_ltu16
helper_info_gvec_ltu32
helper_info_gvec_ltu64
helper_info_gvec_ltu8
helper_info_gvec_ltus16
helper_info_gvec_ltus32
helper_info_gvec_ltus64
helper_info_gvec_ltus8
helper_info_gvec_mov
helper_info_gvec_mul16
helper_info_gvec_mul32
helper_info_gvec_mul64
helper_info_gvec_mul8
helper_info_gvec_muls16
helper_info_gvec_muls32
helper_info_gvec_muls64
helper_info_gvec_muls8
helper_info_gvec_nand
helper_info_gvec_ne16
helper_info_gvec_ne32
helper_info_gvec_ne64
helper_info_gvec_ne8
helper_info_gvec_neg16
helper_info_gvec_neg32
helper_info_gvec_neg64
helper_info_gvec_neg8
helper_info_gvec_nor
helper_info_gvec_not
helper_info_gvec_or
helper_info_gvec_orc
helper_info_gvec_ors
helper_info_gvec_rotl16i
helper_info_gvec_rotl16v
helper_info_gvec_rotl32i
helper_info_gvec_rotl32v
helper_info_gvec_rotl64i
helper_info_gvec_rotl64v
helper_info_gvec_rotl8i
helper_info_gvec_rotl8v
helper_info_gvec_rotr16v
helper_info_gvec_rotr32v
helper_info_gvec_rotr64v
helper_info_gvec_rotr8v
helper_info_gvec_sar16i
helper_info_gvec_sar16v
helper_info_gvec_sar32i
helper_info_gvec_sar32v
helper_info_gvec_sar64i
helper_info_gvec_sar64v
helper_info_gvec_sar8i
helper_info_gvec_sar8v
helper_info_gvec_shl16i
helper_info_gvec_shl16v
helper_info_gvec_shl32i
helper_info_gvec_shl32v
helper_info_gvec_shl64i
helper_info_gvec_shl64v
helper_info_gvec_shl8i
helper_info_gvec_shl8v
helper_info_gvec_shr16i
helper_info_gvec_shr16v
helper_info_gvec_shr32i
helper_info_gvec_shr32v
helper_info_gvec_shr64i
helper_info_gvec_shr64v
helper_info_gvec_shr8i
helper_info_gvec_shr8v
helper_info_gvec_smax16
helper_info_gvec_smax32
helper_info_gvec_smax64
helper_info_gvec_smax8
helper_info_gvec_smin16
helper_info_gvec_smin32
helper_info_gvec_smin64
helper_info_gvec_smin8
helper_info_gvec_ssadd16
helper_info_gvec_ssadd32
helper_info_gvec_ssadd64
helper_info_gvec_ssadd8
helper_info_gvec_sssub16
helper_info_gvec_sssub32
helper_info_gvec_sssub64
helper_info_gvec_sssub8
helper_info_gvec_sub16
helper_info_gvec_sub32
helper_info_gvec_sub64
helper_info_gvec_sub8
helper_info_gvec_subs16
helper_info_gvec_subs32
helper_info_gvec_subs64
helper_info_gvec_subs8
helper_info_gvec_umax16
helper_info_gvec_umax32
helper_info_gvec_umax64
helper_info_gvec_umax8
helper_info_gvec_umin16
helper_info_gvec_umin32
helper_info_gvec_umin64
helper_info_gvec_umin8
helper_info_gvec_usadd16
helper_info_gvec_usadd32
helper_info_gvec_usadd64
helper_info_gvec_usadd8
helper_info_gvec_ussub16
helper_info_gvec_ussub32
helper_info_gvec_ussub64
helper_info_gvec_ussub8
helper_info_gvec_xor
helper_info_gvec_xors
helper_info_ld_i128
helper_info_lookup_tb_ptr
helper_info_memset
helper_info_mmu_read
helper_info_mmu_write
helper_info_mulsh_i64
helper_info_muluh_i64
helper_info_nonatomic_cmpxchgo
helper_info_pcmpbf
helper_info_put
helper_info_raise_exception
helper_info_rem_i32
helper_info_rem_i64
helper_info_remu_i32
helper_info_remu_i64
helper_info_sar_i64
helper_info_shl_i64
helper_info_shr_i64
helper_info_st_i128
helper_info_stackprot
helper_ld16_mmu
helper_ld_i128
helper_ldq_mmu
helper_ldsb_mmu
helper_ldsl_mmu
helper_ldsw_mmu
helper_ldub_mmu
helper_ldul_mmu
helper_lduw_mmu
helper_lookup_tb_ptr
helper_mmu_read
helper_mmu_write
helper_mulsh_i64
helper_muluh_i64
helper_nonatomic_cmpxchgo
helper_pcmpbf
helper_put
helper_raise_exception
helper_rem_i32
helper_rem_i64
helper_remu_i32
helper_remu_i64
helper_sar_i64
helper_shl_i64
helper_shr_i64
helper_st16_mmu
helper_st_i128
helper_stackprot
helper_stb_mmu
helper_stl_mmu
helper_stq_mmu
helper_stw_mmu
hmp_cmds
hmp_compare_cmd
hmp_gpa2hva
hmp_gva2gpa
hmp_info_registers
hmp_memory_dump
hmp_physical_memory_dump
icount_handle_deadline
icount_handle_interrupt
icount_percpu_budget
icount_prepare_for_run
icount_process_data
iotlb_to_section
kvm_allowed
kvm_arm_supports_user_irq
kvm_async_interrupts_allowed
kvm_cpu_synchronize_state
kvm_create_guest_memfd
kvm_dirty_ring_enabled
kvm_dirty_ring_size
kvm_flush_coalesced_mmio_buffer
kvm_get_free_memslots
kvm_get_max_memslots
kvm_gsi_direct_mapping
kvm_gsi_routing_allowed
kvm_has_sync_mmu
kvm_hwpoisoned_mem
kvm_init_cpu_signals
kvm_init_irq_routing
kvm_irqchip_add_change_notifier
kvm_irqchip_add_irqfd_notifier_gsi
kvm_irqchip_add_msi_route
kvm_irqchip_change_notify
kvm_irqchip_commit_routes
kvm_irqchip_release_virq
kvm_irqchip_remove_change_notifier
kvm_irqchip_remove_irqfd_notifier_gsi
kvm_irqchip_update_msi_route
kvm_kernel_irqchip
kvm_msi_use_devid
kvm_msi_via_irqfd_allowed
kvm_on_sigbus
kvm_on_sigbus_vcpu
kvm_readonly_mem_allowed
kvm_resamplefds_allowed
kvm_state
list_cpus
max_advance
max_delay
memory_access_size
memory_get_xlat_addr
memory_global_after_dirty_log_sync
memory_global_dirty_log_start
memory_global_dirty_log_stop
memory_global_dirty_log_sync
memory_listener_register
memory_listener_unregister
memory_region_access_valid
memory_region_add_coalescing
memory_region_add_eventfd
memory_region_add_subregion
memory_region_add_subregion_overlap
memory_region_clear_coalescing
memory_region_clear_dirty_bitmap
memory_region_clear_flush_coalesced
memory_region_del_eventfd
memory_region_del_subregion
memory_region_dispatch_read
memory_region_dispatch_write
memory_region_find
memory_region_flush_rom_device
memory_region_from_host
memory_region_get_alignment
memory_region_get_dirty_log_mask
memory_region_get_fd
memory_region_get_ram_addr
memory_region_get_ram_discard_manager
memory_region_get_ram_ptr
memory_region_has_guest_memfd
memory_region_init
memory_region_init_alias
memory_region_init_io
memory_region_init_iommu
memory_region_init_ram
memory_region_init_ram_device_ptr
memory_region_init_ram_flags_nomigrate
memory_region_init_ram_from_fd
memory_region_init_ram_from_file
memory_region_init_ram_guest_memfd
memory_region_init_ram_nomigrate
memory_region_init_ram_ptr
memory_region_init_resizeable_ram
memory_region_init_rom
memory_region_init_rom_device
memory_region_init_rom_device_nomigrate
memory_region_init_rom_nomigrate
memory_region_iommu_attrs_to_index
memory_region_iommu_get_attr
memory_region_iommu_get_min_page_size
memory_region_iommu_num_indexes
memory_region_iommu_replay
memory_region_is_logging
memory_region_is_mapped
memory_region_is_protected
memory_region_is_ram_device
memory_region_msync
memory_region_name
memory_region_notify_iommu
memory_region_notify_iommu_one
memory_region_owner
memory_region_present
memory_region_ram_resize
memory_region_ref
memory_region_register_iommu_notifier
memory_region_reset_dirty
memory_region_rom_device_set_romd
memory_region_section_free_copy
memory_region_section_get_iotlb
memory_region_section_new_copy
memory_region_set_address
memory_region_set_alias_offset
memory_region_set_coalescing
memory_region_set_dirty
memory_region_set_enabled
memory_region_set_flush_coalesced
memory_region_set_log
memory_region_set_nonvolatile
memory_region_set_ram_discard_manager
memory_region_set_readonly
memory_region_set_size
memory_region_set_unmergeable
memory_region_size
memory_region_snapshot_and_clear_dirty
memory_region_snapshot_get_dirty
memory_region_transaction_begin
memory_region_transaction_commit
memory_region_unmap_iommu_notifier_range
memory_region_unref
memory_region_unregister_iommu_notifier
memory_region_writeback
microblaze_load_kernel
mig_throttle_counter_reset
migrate_ram_is_ignored
migration_bitmap_sync_precopy
migration_populate_vfio_info
migration_reset_vfio_bytes_transferred
mmu_init
mmu_read
mmu_translate
mmu_write
mon_get_cpu
mon_get_cpu_env
monitor_get_cpu_index
monitor_register_hmp
monitor_register_hmp_info_hrt
monitor_set_cpu
mtree_info
mtree_print_dispatch
mttcg_enabled
mttcg_kick_vcpu_thread
mttcg_start_vcpu_thread
one_insn_per_tb
page_init
page_table_config_init
parse_cpu_option
portio_list_add
portio_list_del
portio_list_destroy
portio_list_init
portio_list_set_address
portio_list_set_enabled
portio_list_set_flush_coalesced
postcopy_preempt_shutdown_file
precopy_add_notifier
precopy_infrastructure_init
precopy_notify
precopy_remove_notifier
prepare_mmio_access
probe_access
probe_access_flags
probe_access_full
probe_access_full_mmu
qapi_dummy_qapi_commands_c
qapi_dummy_qapi_commands_machine_target_c
qapi_dummy_qapi_commands_misc_target_c
qapi_dummy_qapi_emit_events_c
qapi_dummy_qapi_events_c
qapi_dummy_qapi_events_machine_target_c
qapi_dummy_qapi_events_misc_target_c
qapi_dummy_qapi_init_commands_c
qapi_dummy_qapi_introspect_c
qapi_dummy_qapi_types_c
qapi_dummy_qapi_types_machine_target_c
qapi_dummy_qapi_types_misc_target_c
qapi_dummy_qapi_visit_c
qapi_dummy_qapi_visit_machine_target_c
qapi_dummy_qapi_visit_misc_target_c
qapi_free_CpuModelInfo
qapi_free_SGXEPCSection
qapi_free_SGXEPCSectionList
qemu_flush_coalesced_mmio_buffer
qemu_guest_free_page_hint
qemu_init_arch_modules
qemu_map_ram_ptr
qemu_maxrampagesize
qemu_minrampagesize
qemu_mutex_lock_ramlist
qemu_mutex_unlock_ramlist
qemu_ram_addr_from_host
qemu_ram_addr_from_host_nofail
qemu_ram_alloc
qemu_ram_alloc_from_fd
qemu_ram_alloc_from_file
qemu_ram_alloc_from_ptr
qemu_ram_alloc_resizeable
qemu_ram_block_by_name
qemu_ram_block_from_host
qemu_ram_block_host_offset
qemu_ram_foreach_block
qemu_ram_free
qemu_ram_get_fd
qemu_ram_get_host_addr
qemu_ram_get_idstr
qemu_ram_get_max_length
qemu_ram_get_offset
qemu_ram_get_used_length
qemu_ram_is_migratable
qemu_ram_is_named_file
qemu_ram_is_noreserve
qemu_ram_is_shared
qemu_ram_is_uf_zeroable
qemu_ram_msync
qemu_ram_pagesize
qemu_ram_pagesize_largest
qemu_ram_remap
qemu_ram_resize
qemu_ram_set_idstr
qemu_ram_set_migratable
qemu_ram_set_uf_zeroable
qemu_ram_unset_idstr
qemu_ram_unset_migratable
qemu_semihosting_guestfd_init
qemu_target_page_bits
qemu_target_page_bits_min
qemu_target_page_mask
qemu_target_page_size
qemu_target_pages_to_MiB
qmp_init_marshal
qmp_query_hv_balloon_status_report
qmp_schema_qlit
qmp_xen_set_global_dirty_log
ram_block_coordinated_discard_require
ram_block_discard_disable
ram_block_discard_guest_memfd_range
ram_block_discard_is_disabled
ram_block_discard_is_required
ram_block_discard_range
ram_block_discard_require
ram_block_format
ram_block_uncoordinated_discard_disable
ram_bytes_remaining
ram_bytes_total
ram_dirty_bitmap_reload
ram_discard_manager_get_min_granularity
ram_discard_manager_is_populated
ram_discard_manager_register_listener
ram_discard_manager_replay_discarded
ram_discard_manager_replay_populated
ram_discard_manager_unregister_listener
ram_discard_range
ram_get_total_transferred_pages
ram_handle_zero
ram_list
ram_load_postcopy
ram_mig_init
ram_pagesize_summary
ram_postcopy_incoming_init
ram_postcopy_migrated_memory_release
ram_postcopy_send_discard_bitmap
ram_release_page
ram_save_queue_pages
ram_transferred_add
ram_write_tracking_available
ram_write_tracking_compatible
ram_write_tracking_start
ram_write_tracking_stop
ramblock_is_pmem
ramblock_page_is_discarded
ramblock_recv_bitmap_send
ramblock_recv_bitmap_set
ramblock_recv_bitmap_set_offset
ramblock_recv_bitmap_set_range
ramblock_recv_bitmap_test
ramblock_recv_bitmap_test_byte_offset
ramblock_set_file_bmap_atomic
rr_kick_vcpu_thread
rr_start_vcpu_thread
set_preferred_target_page_bits
target_name
target_words_bigendian
tb_check_watchpoint
tb_ctx
tb_flush
tb_gen_code
tb_htable_init
tb_invalidate_phys_range
tb_invalidate_phys_range_fast
tb_link_page
tb_lock_page0
tb_lock_page1
tb_phys_invalidate
tb_reset_jump
tb_set_jmp_target
tb_unlock_page1
tb_unlock_pages
tcg_cflags_has
tcg_cflags_set
tcg_cpu_destroy
tcg_cpu_exec
tcg_cpu_init_cflags
tcg_exec_realizefn
tcg_exec_unrealizefn
tcg_flush_jmp_cache
tcg_handle_interrupt
tcg_iommu_free_notifier_list
tcg_iommu_init_notifier_list
tlb_destroy
tlb_flush
tlb_flush_all_cpus_synced
tlb_flush_by_mmuidx
tlb_flush_by_mmuidx_all_cpus_synced
tlb_flush_page
tlb_flush_page_all_cpus_synced
tlb_flush_page_bits_by_mmuidx
tlb_flush_page_bits_by_mmuidx_all_cpus_synced
tlb_flush_page_by_mmuidx
tlb_flush_page_by_mmuidx_all_cpus_synced
tlb_flush_range_by_mmuidx
tlb_flush_range_by_mmuidx_all_cpus_synced
tlb_init
tlb_protect_code
tlb_reset_dirty
tlb_reset_dirty_range_all
tlb_set_page
tlb_set_page_full
tlb_set_page_with_attrs
tlb_unprotect_code
tlb_vaddr_to_host
trace_event_set_state_dynamic
trace_event_set_state_dynamic_init
translator_fake_ld
translator_io_start
translator_is_same_page
translator_ldl
translator_ldq
translator_ldub
translator_lduw
translator_loop
translator_st
translator_st_len
translator_use_goto_tb
unassigned_io_ops
unassigned_mem_ops
visit_type_CpuModelCompareResult
visit_type_CpuModelExpansionType
visit_type_CpuModelInfo
visit_type_CpuModelInfo_members
visit_type_SGXEPCSection
visit_type_SGXEPCSectionList
visit_type_SGXEPCSection_members
vmstate_cpu_common
win_dump_available
xbzrle_cache_resize
xbzrle_counters
xen_allowed
xen_evtchn_deliver_pirq_msi
xen_evtchn_remove_pci_device
xen_evtchn_snoop_msi
xen_primary_console_create
xen_primary_console_set_be_port
Philippe Mathieu-Daudé Feb. 21, 2025, 10:48 a.m. UTC | #3
On 20/2/25 09:48, Philippe Mathieu-Daudé wrote:
> On 17/2/25 13:50, Peter Maydell wrote:
>> The work I needed to do to make various softfloat emulation behaviours
>> runtime-selectable for Arm FEAT_AFP has left the fpu code with very
>> few remaning target ifdefs. So this series turns the last remaning
>> ones into runtime behaviour choices and switches the fpu code into
>> "build once" rather than "build per target". The main driver of this
>> is that we're going to want to do this for the "multiple targets in
>> one binary" work.


> FWIW:
> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Oops, that tag is only for patch 10 (meson buildsys change), not for
the whole series.
Philippe Mathieu-Daudé Feb. 21, 2025, 1:05 p.m. UTC | #4
Hi Peter,

On 17/2/25 13:50, Peter Maydell wrote:

> (1) floatx80 behaviours
> 
> Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
> use in the xsrqpxp round-to-80-bit-precision operation, and the
> Linux-user NWFPE emulation nominally supports it, but these are
> minor.) x86 and m68k disagree about some of the corner cases of
> floatx80 where the value has the explicit Integer bit wrongly set.  At
> the moment the fpu code defaults to "floatx80 behaves like x86", with
> TARGET_M68K ifdefs to get the other option.
> 
> The first six patches in this series remove those ifdefs, replacing
> them with a floatx80_behaviour field in float_status which can have
> various flags set to select the individual behaviours. The default is
> "like x86", which allows us to set these only for m68k and not worry
> about the minor "technically makes some use of floatx80" cases.


> Peter Maydell (10):
>    fpu: Make targets specify floatx80 default Inf at runtime
>    target/m68k: Avoid using floatx80_infinity global const
>    target/i386: Avoid using floatx80_infinity global const

Could you add a preparatory patch passing float_status argument
here? This eases the following patch review.

-- >8 --
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index afae3906024..3c83d703baf 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -999 +999 @@ static inline floatx80 floatx80_chs(floatx80 a)
-static inline bool floatx80_is_infinity(floatx80 a)
+static inline bool floatx80_is_infinity(floatx80 a, float_status *status)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 741af09f908..3b79bc049d1 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -1395,3 +1395,4 @@ void helper_fpatan(CPUX86State *env)
          /* Pass this zero through.  */
-    } else if (((floatx80_is_infinity(ST0) && 
!floatx80_is_infinity(ST1)) ||
+    } else if (((floatx80_is_infinity(ST0, &env->fp_status) &&
+                 !floatx80_is_infinity(ST1, &env->fp_status)) ||
                   arg0_exp - arg1_exp >= 80) &&
@@ -1444,4 +1445,4 @@ void helper_fpatan(CPUX86State *env)
              rsig1 = pi_sig_low;
-        } else if (floatx80_is_infinity(ST1)) {
-            if (floatx80_is_infinity(ST0)) {
+        } else if (floatx80_is_infinity(ST1, &env->fp_status)) {
+            if (floatx80_is_infinity(ST0, &env->fp_status)) {
                  if (arg0_sign) {
@@ -1464,3 +1465,4 @@ void helper_fpatan(CPUX86State *env)
              rsig1 = pi_2_sig_low;
-        } else if (floatx80_is_infinity(ST0) || arg0_exp - arg1_exp >= 
80) {
+        } else if (floatx80_is_infinity(ST0, &env->fp_status) ||
+                   arg0_exp - arg1_exp >= 80) {
              /* ST0 is negative.  */
@@ -1831,3 +1833,3 @@ void helper_fxtract(CPUX86State *env)
          ST0 = ST1;
-    } else if (floatx80_is_infinity(ST0)) {
+    } else if (floatx80_is_infinity(ST0, &env->fp_status)) {
          fpush(env);
@@ -2175,3 +2177,3 @@ void helper_fyl2x(CPUX86State *env)
          ST1 = floatx80_default_nan(&env->fp_status);
-    } else if (floatx80_is_infinity(ST1)) {
+    } else if (floatx80_is_infinity(ST1, &env->fp_status)) {
          FloatRelation cmp = floatx80_compare(ST0, floatx80_one,
@@ -2190,3 +2192,3 @@ void helper_fyl2x(CPUX86State *env)
          }
-    } else if (floatx80_is_infinity(ST0)) {
+    } else if (floatx80_is_infinity(ST0, &env->fp_status)) {
          if (floatx80_is_zero(ST1)) {
@@ -2343,3 +2345,3 @@ void helper_fscale(CPUX86State *env)
          }
-    } else if (floatx80_is_infinity(ST1) &&
+    } else if (floatx80_is_infinity(ST1, &env->fp_status) &&
                 !floatx80_invalid_encoding(ST0) &&
@@ -2347,3 +2349,3 @@ void helper_fscale(CPUX86State *env)
          if (floatx80_is_neg(ST1)) {
-            if (floatx80_is_infinity(ST0)) {
+            if (floatx80_is_infinity(ST0, &env->fp_status)) {
                  float_raise(float_flag_invalid, &env->fp_status);
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 339b73ad7dc..eb1cb8c6872 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -458 +458 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
-    } else if (floatx80_is_infinity(val->d)) {
+    } else if (floatx80_is_infinity(val->d, &env->fp_status)) {
---

>    fpu: Make targets specify whether floatx80 Inf can have Int bit clear

Ditto here:

-- >8 --
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 07259c59303..1c8f3cbb78d 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -1084 +1084 @@ static inline bool floatx80_unordered_quiet(floatx80 
a, floatx80 b,
-static inline bool floatx80_invalid_encoding(floatx80 a)
+static inline bool floatx80_invalid_encoding(floatx80 a, float_status *s)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index b12ad2b42a9..2a20ae871eb 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1813 +1813 @@ static bool floatx80_unpack_canonical(FloatParts128 
*p, floatx80 f,
-    if (unlikely(floatx80_invalid_encoding(f))) {
+    if (unlikely(floatx80_invalid_encoding(f, s))) {
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 3b79bc049d1..4858ae9a5fb 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -1143,3 +1143,3 @@ void helper_f2xm1(CPUX86State *env)

-    if (floatx80_invalid_encoding(ST0)) {
+    if (floatx80_invalid_encoding(ST0, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -1385,4 +1385,4 @@ void helper_fpatan(CPUX86State *env)
          ST1 = floatx80_silence_nan(ST1, &env->fp_status);
-    } else if (floatx80_invalid_encoding(ST0) ||
-               floatx80_invalid_encoding(ST1)) {
+    } else if (floatx80_invalid_encoding(ST0, &env->fp_status) ||
+               floatx80_invalid_encoding(ST1, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -1821,3 +1821,3 @@ void helper_fxtract(CPUX86State *env)
          ST0 = temp.d;
-    } else if (floatx80_invalid_encoding(ST0)) {
+    } else if (floatx80_invalid_encoding(ST0, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -1872,3 +1872,4 @@ static void helper_fprem_common(CPUX86State *env, 
bool mod)
          exp0 == 0x7fff || exp1 == 0x7fff ||
-        floatx80_invalid_encoding(ST0) || floatx80_invalid_encoding(ST1)) {
+        floatx80_invalid_encoding(ST0, &env->fp_status) ||
+        floatx80_invalid_encoding(ST1, &env->fp_status)) {
          ST0 = floatx80_modrem(ST0, ST1, mod, &quotient, &env->fp_status);
@@ -2068,4 +2069,4 @@ void helper_fyl2xp1(CPUX86State *env)
          ST1 = floatx80_silence_nan(ST1, &env->fp_status);
-    } else if (floatx80_invalid_encoding(ST0) ||
-               floatx80_invalid_encoding(ST1)) {
+    } else if (floatx80_invalid_encoding(ST0, &env->fp_status) ||
+               floatx80_invalid_encoding(ST1, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -2166,4 +2167,4 @@ void helper_fyl2x(CPUX86State *env)
          ST1 = floatx80_silence_nan(ST1, &env->fp_status);
-    } else if (floatx80_invalid_encoding(ST0) ||
-               floatx80_invalid_encoding(ST1)) {
+    } else if (floatx80_invalid_encoding(ST0, &env->fp_status) ||
+               floatx80_invalid_encoding(ST1, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -2333,3 +2334,4 @@ void helper_fscale(CPUX86State *env)
      uint8_t old_flags = save_exception_flags(env);
-    if (floatx80_invalid_encoding(ST1) || floatx80_invalid_encoding(ST0)) {
+    if (floatx80_invalid_encoding(ST1, &env->fp_status) ||
+        floatx80_invalid_encoding(ST0, &env->fp_status)) {
          float_raise(float_flag_invalid, &env->fp_status);
@@ -2346,3 +2348,3 @@ void helper_fscale(CPUX86State *env)
      } else if (floatx80_is_infinity(ST1, &env->fp_status) &&
-               !floatx80_invalid_encoding(ST0) &&
+               !floatx80_invalid_encoding(ST0, &env->fp_status) &&
                 !floatx80_is_any_nan(ST0)) {
---

>    fpu: Make floatx80 invalid encoding settable at runtime
>    fpu: Move m68k_denormal fmt flag into floatx80_behaviour
>    fpu: Always decide no_signaling_nans() at runtime
>    fpu: Always decide snan_bit_is_one() at runtime
>    fpu: Don't compile-time disable hardfloat for PPC targets
>    fpu: Build only once

Thanks,

Phil.
Peter Maydell Feb. 21, 2025, 1:28 p.m. UTC | #5
On Fri, 21 Feb 2025 at 13:05, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> Hi Peter,
>
> On 17/2/25 13:50, Peter Maydell wrote:
>
> > (1) floatx80 behaviours
> >
> > Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
> > use in the xsrqpxp round-to-80-bit-precision operation, and the
> > Linux-user NWFPE emulation nominally supports it, but these are
> > minor.) x86 and m68k disagree about some of the corner cases of
> > floatx80 where the value has the explicit Integer bit wrongly set.  At
> > the moment the fpu code defaults to "floatx80 behaves like x86", with
> > TARGET_M68K ifdefs to get the other option.
> >
> > The first six patches in this series remove those ifdefs, replacing
> > them with a floatx80_behaviour field in float_status which can have
> > various flags set to select the individual behaviours. The default is
> > "like x86", which allows us to set these only for m68k and not worry
> > about the minor "technically makes some use of floatx80" cases.
>
>
> > Peter Maydell (10):
> >    fpu: Make targets specify floatx80 default Inf at runtime
> >    target/m68k: Avoid using floatx80_infinity global const
> >    target/i386: Avoid using floatx80_infinity global const
>
> Could you add a preparatory patch passing float_status argument
> here? This eases the following patch review.

I could, and in retrospect I agree it would have been a better
division of patches, but both you and RTH have already reviewed
patches 4 and 5 in their current form, so is it worth doing now ?

thanks
-- PMM
Philippe Mathieu-Daudé Feb. 21, 2025, 1:48 p.m. UTC | #6
On 21/2/25 14:28, Peter Maydell wrote:
> On Fri, 21 Feb 2025 at 13:05, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>>
>> Hi Peter,
>>
>> On 17/2/25 13:50, Peter Maydell wrote:
>>
>>> (1) floatx80 behaviours
>>>
>>> Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
>>> use in the xsrqpxp round-to-80-bit-precision operation, and the
>>> Linux-user NWFPE emulation nominally supports it, but these are
>>> minor.) x86 and m68k disagree about some of the corner cases of
>>> floatx80 where the value has the explicit Integer bit wrongly set.  At
>>> the moment the fpu code defaults to "floatx80 behaves like x86", with
>>> TARGET_M68K ifdefs to get the other option.
>>>
>>> The first six patches in this series remove those ifdefs, replacing
>>> them with a floatx80_behaviour field in float_status which can have
>>> various flags set to select the individual behaviours. The default is
>>> "like x86", which allows us to set these only for m68k and not worry
>>> about the minor "technically makes some use of floatx80" cases.
>>
>>
>>> Peter Maydell (10):
>>>     fpu: Make targets specify floatx80 default Inf at runtime
>>>     target/m68k: Avoid using floatx80_infinity global const
>>>     target/i386: Avoid using floatx80_infinity global const
>>
>> Could you add a preparatory patch passing float_status argument
>> here? This eases the following patch review.
> 
> I could, and in retrospect I agree it would have been a better
> division of patches, but both you and RTH have already reviewed
> patches 4 and 5 in their current form, so is it worth doing now ?

If it isn't too much a burden, I'd prefer to have the extra patches
included. Not for today's review, but for our future readers learning
from the git history (as I'm custom to).

I understand you are waiting RTH's ack on patch #6 to update it and
don't plan to respin. If you agree to split, I suppose it isn't in
your principles to merge a series without posting the final result
on the list. I have the patches locally split so can post as v2 base
if that helps. Otherwise I won't insist, up to your workflow :)

Regards,

Phil.
Philippe Mathieu-Daudé Feb. 21, 2025, 2:41 p.m. UTC | #7
On 17/2/25 13:50, Peter Maydell wrote:

> (1) floatx80 behaviours
> 
> Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
> use in the xsrqpxp round-to-80-bit-precision operation, and the
> Linux-user NWFPE emulation nominally supports it, but these are
> minor.) x86 and m68k disagree about some of the corner cases of
> floatx80 where the value has the explicit Integer bit wrongly set.  At
> the moment the fpu code defaults to "floatx80 behaves like x86", with
> TARGET_M68K ifdefs to get the other option.
> 
> The first six patches in this series remove those ifdefs, replacing
> them with a floatx80_behaviour field in float_status which can have
> various flags set to select the individual behaviours. The default is
> "like x86", which allows us to set these only for m68k and not worry
> about the minor "technically makes some use of floatx80" cases.


> Peter Maydell (10):
>    fpu: Make targets specify floatx80 default Inf at runtime
>    target/m68k: Avoid using floatx80_infinity global const
>    target/i386: Avoid using floatx80_infinity global const

Bothering again, we can add the floatx80_default_inf() refactor as the
first patch:

-- >8 --
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 09a40b43106..afae3906024 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -963,0 +964 @@ extern const floatx80 floatx80_infinity;
+floatx80 floatx80_default_inf(bool zSign, float_status *status);
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index f4fed9bfda9..f56ae886c53 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5147,3 +5147 @@ floatx80 roundAndPackFloatx80(FloatX80RoundPrec 
roundingPrecision, bool zSign,
-            return packFloatx80(zSign,
-                                floatx80_infinity_high,
-                                floatx80_infinity_low);
+            return floatx80_default_inf(zSign, status);
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index f112c6c6737..741af09f908 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -1835 +1835 @@ void helper_fxtract(CPUX86State *env)
-        ST1 = floatx80_infinity;
+        ST1 = floatx80_default_inf(0, &env->fp_status);
@@ -2361,3 +2361,2 @@ void helper_fscale(CPUX86State *env)
-                ST0 = (floatx80_is_neg(ST0) ?
-                       floatx80_chs(floatx80_infinity) :
-                       floatx80_infinity);
+                ST0 = floatx80_default_inf(floatx80_is_neg(ST0),
+                                           &env->fp_status);
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
index 02dcc03d15d..d1f150e641f 100644
--- a/target/m68k/softfloat.c
+++ b/target/m68k/softfloat.c
@@ -145,2 +145 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b, 
float_status *status)
-        return packFloatx80(aSign, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(aSign, status);
@@ -248 +247 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status)
-        return packFloatx80(0, floatx80_infinity.high, 
floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
@@ -258,2 +257 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status)
-            return packFloatx80(aSign, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(aSign, status);
@@ -445,2 +443 @@ floatx80 floatx80_logn(floatx80 a, float_status *status)
-            return packFloatx80(0, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(0, status);
@@ -455,2 +452 @@ floatx80 floatx80_logn(floatx80 a, float_status *status)
-            return packFloatx80(1, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(1, status);
@@ -613,2 +609 @@ floatx80 floatx80_log10(floatx80 a, float_status *status)
-            return packFloatx80(0, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(0, status);
@@ -620,2 +615 @@ floatx80 floatx80_log10(floatx80 a, float_status *status)
-        return packFloatx80(1, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(1, status);
@@ -671,2 +665 @@ floatx80 floatx80_log2(floatx80 a, float_status *status)
-            return packFloatx80(0, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(0, status);
@@ -679,2 +672 @@ floatx80 floatx80_log2(floatx80 a, float_status *status)
-            return packFloatx80(1, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(1, status);
@@ -743,2 +735 @@ floatx80 floatx80_etox(floatx80 a, float_status *status)
-        return packFloatx80(0, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
@@ -927,2 +918 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status)
-        return packFloatx80(0, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
@@ -1078,2 +1068 @@ floatx80 floatx80_tentox(floatx80 a, float_status 
*status)
-        return packFloatx80(0, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
@@ -2263,2 +2252 @@ floatx80 floatx80_atanh(floatx80 a, float_status 
*status)
-            return packFloatx80(aSign, floatx80_infinity.high,
-                                floatx80_infinity.low);
+            return floatx80_default_inf(aSign, status);
@@ -2323,2 +2311 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status 
*status)
-        return packFloatx80(0, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
@@ -2690,2 +2677 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status)
-        return packFloatx80(aSign, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(aSign, status);
@@ -2777,2 +2763 @@ floatx80 floatx80_cosh(floatx80 a, float_status *status)
-        return packFloatx80(0, floatx80_infinity.high,
-                            floatx80_infinity.low);
+        return floatx80_default_inf(0, status);
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index cbbbab52ba3..403f7a9d69d 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -239,0 +240,5 @@ const floatx80 floatx80_infinity
+floatx80 floatx80_default_inf(bool zSign, float_status *status)
+{
+    return packFloatx80(zSign, floatx80_infinity_high, 
floatx80_infinity_low);
+}
+
---

The single non-obvious thing to mention is the x86 floatx80_chs()
removal.

This effectively absorb patch #3 (x86).

Then patch #2 (m68k) becomes:

-- >8 --
diff --git a/include/fpu/softfloat-helpers.h 
b/include/fpu/softfloat-helpers.h
index 8983c2748ec..90862f5cd22 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -77,0 +78,6 @@ static inline void 
set_floatx80_rounding_precision(FloatX80RoundPrec val,
+static inline void set_floatx80_behaviour(FloatX80Behaviour b,
+                                          float_status *status)
+{
+    status->floatx80_behaviour = b;
+}
+
@@ -153,0 +160,6 @@ get_floatx80_rounding_precision(const float_status 
*status)
+static inline FloatX80Behaviour
+get_floatx80_behaviour(const float_status *status)
+{
+    return status->floatx80_behaviour;
+}
+
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 53d5eb85210..dd22ecdbe60 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -322,0 +323,12 @@ typedef enum __attribute__((__packed__)) {
+/*
+ * floatx80 is primarily used by x86 and m68k, and there are
+ * differences in the handling, largely related to the explicit
+ * Integer bit which floatx80 has and the other float formats do not.
+ * These flag values allow specification of the target's requirements
+ * and can be ORed together to set floatx80_behaviour.
+ */
+typedef enum __attribute__((__packed__)) {
+    /* In the default Infinity value, is the Integer bit 0 ? */
+    floatx80_default_inf_int_bit_is_zero = 1,
+} FloatX80Behaviour;
+
@@ -333,0 +346 @@ typedef struct float_status {
+    FloatX80Behaviour floatx80_behaviour;
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index f56ae886c53..b12ad2b42a9 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1863 +1863,2 @@ static floatx80 
floatx80_round_pack_canonical(FloatParts128 *p,
-        frac = floatx80_infinity_low;
+        frac = s->floatx80_behaviour & 
floatx80_default_inf_int_bit_is_zero ?
+               0 : (1ULL << 63);
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 41dfdf58045..df66e8ba22a 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -109,0 +110,6 @@ static void m68k_cpu_reset_hold(Object *obj, 
ResetType type)
+    /*
+     * m68k-specific floatx80 behaviour:
+     *  * default Infinity values have a zero Integer bit
+     */
+    set_floatx80_behaviour(floatx80_default_inf_int_bit_is_zero,
+                           &env->fp_status);
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 403f7a9d69d..77a43f46597 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -242 +242,6 @@ floatx80 floatx80_default_inf(bool zSign, float_status 
*status)
-    return packFloatx80(zSign, floatx80_infinity_high, 
floatx80_infinity_low);
+    /*
+     * Whether the Integer bit is set in the default Infinity is
+     * target dependent.
+     */
+    bool z = status->floatx80_behaviour & 
floatx80_default_inf_int_bit_is_zero;
+    return packFloatx80(zSign, 0x7fff, z ? 0 : (1ULL << 63));
---
Peter Maydell Feb. 21, 2025, 3:19 p.m. UTC | #8
On Fri, 21 Feb 2025 at 14:41, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> On 17/2/25 13:50, Peter Maydell wrote:
>
> > (1) floatx80 behaviours
> >
> > Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
> > use in the xsrqpxp round-to-80-bit-precision operation, and the
> > Linux-user NWFPE emulation nominally supports it, but these are
> > minor.) x86 and m68k disagree about some of the corner cases of
> > floatx80 where the value has the explicit Integer bit wrongly set.  At
> > the moment the fpu code defaults to "floatx80 behaves like x86", with
> > TARGET_M68K ifdefs to get the other option.
> >
> > The first six patches in this series remove those ifdefs, replacing
> > them with a floatx80_behaviour field in float_status which can have
> > various flags set to select the individual behaviours. The default is
> > "like x86", which allows us to set these only for m68k and not worry
> > about the minor "technically makes some use of floatx80" cases.
>
>
> > Peter Maydell (10):
> >    fpu: Make targets specify floatx80 default Inf at runtime
> >    target/m68k: Avoid using floatx80_infinity global const
> >    target/i386: Avoid using floatx80_infinity global const
>
> Bothering again, we can add the floatx80_default_inf() refactor as the
> first patch:

I really think at this point this is just doing extra
work shuffling code changes between patches for no real benefit.
The patches aren't super huge and they've already been
reviewed. I'm OK with splitting out the "add the status
argument" part as you suggested previously, as that
makes the patches more reasonably split between "just
mechanical" and "interesting change" which is not a big
split to do and could be helpful for potential bisection
later, but churning the patchset beyond that doesn't
seem worthwhile to me.

-- PMM