* [PATCH v4 00/55] single-binary: link multi-targets into qemu-system
@ 2026-09-26 6:59 Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 01/55] target-info: Introduce target_riscv32 Yonggang Luo
` (54 more replies)
0 siblings, 55 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 6:59 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
This series produces one qemu-system binary that can run ARM (32 and 64) and
MicroBlaze. Upstream filters machines with TypeInfo.is_available. This series
passes a TargetInfo into that callback and compiles ARM and MicroBlaze once so
they can share qemu-system.
ARM virt keeps the QOM name virt. MicroBlaze boards keep their own names, so
TYPE_ACCEL_CPU and the virt ACPI helpers stay per target. aarch64 and arm share
one copy of the ARM sources. MicroBlaze is folded the same way. qemu-system
links a target only when its arch sources are target-info-def.c alone. Machine
is_available accepts ARM-family boards for arm and aarch64, aarch64-only boards
for aarch64, and MicroBlaze boards for microblaze.
target_ulong and TCG _tl helpers:
arm and microblaze are 32-bit and aarch64 is 64-bit, so the shared compile uses
a uint64_t target_ulong in softmmu common code. MO_TL follows
target_long_bits(). target_long stays per-target. tcg_gen_*_tl and the TL memory
helpers call the i32 or i64 operation through tl_is_64(). A helper tl argument
uses an i64 slot in common code: tcg_gen_callN zero-extends a 32-bit temp into
that slot and truncates an i64 return. Per-target builds keep target_ulong and
TCGv tied to TARGET_LONG_BITS.
Target selection has to work with more than one TargetInfo:
- The combined binary takes arch:name on -M/-machine and in a [machine] type
(aarch64:virt). arch: binds the target. microblaze: runs that target's
default machine. arm and aarch64 have no default. No -M leaves target none
and the empty none machine. qemu-system-$arch keeps the historic -M name.
-M help lists every target; arch:help lists one. A later bare name keeps the
last arch prefix. query-targets lists each linked target, including none.
- TargetInfo is a constructor list. target_info_select() picks the entry,
including SYS_EMU_TARGET_NONE. is_available takes const TargetInfo *. A
single-target binary keeps its TargetInfo. arch: must match that binary or
the machine is rejected. That binary drops types that fail is_available at
registration. The combined binary keeps those types and filters with
is_available for the selected target.
Peter Maydell suggested this arch:name form in review of
https://patchwork.ozlabs.org/project/qemu-devel/cover/20260828225901.367438-1-pierrick.bouvier@oss.qualcomm.com/#3749257
Daniel P. Berrange asked to query every machine in the binary and which targets
can run it. This series adds query-targets for that:
https://patchwork.ozlabs.org/project/qemu-devel/cover/20260828225901.367438-1-pierrick.bouvier@oss.qualcomm.com/#3749292
qemu-system-$TARGET is still built, including the Windows *w twin. qemu-system
is extra. It links aarch64, arm, and microblaze. Do not add qemu-systemw for
that binary. A GUI twin would keep QEMU exporting data from the .exe into
DLLs, and those data exports cannot be delay-loaded (qdev_prop_array and other
qdev_prop_*). That would block enabling modules globally on Windows.
Examples:
qemu-system -M aarch64:virt ...
qemu-system -M microblaze:petalogix-s3adsp1800 ...
qemu-system-aarch64 -M virt ...
A bare machine name on qemu-system needs an arch: prefix. An unknown target
fails with "target '...' is not available".
v1: https://patchew.org/QEMU/20260823150731.896-1-luoyonggang@gmail.com/
v2: https://patchew.org/QEMU/20260826184229.1145-1-luoyonggang@gmail.com/
v3: https://patchew.org/QEMU/20260923131635.1894-1-luoyonggang@gmail.com/
branch: https://gitlab.com/lygstate-qemu/qemu/-/tree/single-binary-arm-riscv?ref_type=heads
x86_64 and i386: https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads
Changes v3 -> v4:
v4 keeps arch:name selection, target none, and query-targets. qemu-system links
ARM and MicroBlaze only.
- Limit the combined binary to aarch64, arm, and microblaze. RISC-V stays on
qemu-system-riscv32 and qemu-system-riscv64. Remove the target/riscv and
hw/riscv compile-once patches and the RISC-V TARGET_LONG_BITS rewrites.
- Drop virt QOM prefixes, MachineInfo typename, the shared TYPE_ACCEL_CPU
parent, virt ACPI prefixes, and the RISC-V crc32, crc32c, and wfi helper
renames. Those names are already unique for ARM and MicroBlaze.
- Drop TargetCpuOps, AccelClass is_available, the move of kvm and whpx onto
system_ss, and TargetInfo-gated migration fields.
- The combined binary registers every machine and filters with is_available
for the selected target. v3 skipped that filter while the target was none.
v4 builds without these series:
[PATCH v2 0/9] machine: uniquify virt QOM names
https://patchew.org/QEMU/20260922215533.641-1-luoyonggang@gmail.com/
[PATCH 00/21] accel/tcg: share raise_excp across TCG targets
https://patchew.org/QEMU/20260918004225.827-1-luoyonggang@gmail.com/
[PATCH v5 00/11] single-binary: Compile hw/riscv once
https://patchew.org/QEMU/20260918-hw-riscv-cpu-int-v5-0-f98c5a244636@rev.ng/
Anton Johansson via qemu development (1):
target-info: Introduce target_riscv32
Pierrick Bouvier (2):
configs/targets: remove target info definitions
target-info: rename target-info-stub.c in target-info-def.c
Yonggang Luo (52):
target-info: rename target-info-impl.h to target-info-def.h
vl: parse early options before target-info init
target-info: replace QOM registration with a constructor list
tests/unit: add test-target-info
tests/qtest: prepare machine-list-test for combined qemu-system
kconfig: rename REGISTER to HW_REGISTER
target-info: add TargetKconfig
target-info: add target_is_* helpers for each architecture
target-info: add target_is_any()
qom: pass TargetInfo to is_available for latter use
target/arm: move kvm_arm_set_cpreg_mig_tolerances to kvm.c
target/arm: allow -cpu host with Nitro
target/arm: gate -cpu host with TypeIsAvailable
target/arm: replace target_long in A64 translate
target/arm: use vaddr for the A64 insn_start pc
tests/qtest: raise aspeed_smc-test timeout to 12 minutes
target-info: add tl_is_64() and target_is_tl32/64 helpers
tcg: declare TCGv in tcg.h
tcg: dispatch TL memory helpers from tcg-op-mem.h
tcg: dispatch tcg_gen_*_tl without TARGET_LONG_BITS
tcg: dispatch tcg_gen_gvec_dup_tl at runtime
tcg: give common-system helper tl an i64 slot
accel/tcg: move helper_exit_atomic next to cpu_loop_exit_atomic
tcg: move dup_const into tcg.c
tcg: move goto_tb helpers into tcg-op-ldst.c
accel/tcg: move gvec helpers into tcg-runtime-gvec.h
accel/tcg: move helper_lookup_tb_ptr into cpu-exec.h
accel/tcg: move memory helpers out of tcg-runtime.h
tests/unit: cover common-system tl dispatch and calls
target/arm: fix A64 guest address width at 64
target/arm: pass tl temps into SVE and SME helpers
exec: provide target_ulong for softmmu common code
exec: compile abi_ptr.h without per-target cpu-param.h
accel/tcg: keep cpu-ldst endian aliases per-target
target/arm: fold arm_ss into common source sets
target/microblaze: fold system sources into common source sets
meson: link shared objects into qemu-system
target-info: add SysEmuTarget none
module: load every arch-tagged module when target is none
accel/tcg: tolerate NULL target_cpu_type for -M none
target-info: select combined qemu-system target by name
vl: parse arch: machine types on combined qemu-system
qapi: add query-targets
target-info: add target_is_microblaze
hw/microblaze: set petalogix-s3adsp1800 TypeInfo.is_available
hw/microblaze: expand petalogix-ml605 and xlnx-zynqmp-pmu to TypeInfo
hw/arm: expand leftover 32-bit DEFINE_MACHINE to TypeInfo
hw/arm: expand imx8mm-evk DEFINE_MACHINE to TypeInfo
hw/arm: set virt TypeInfo.is_available
hw/arm: set remaining 32-bit machine TypeInfo.is_available
hw/arm: set aarch64-only machine TypeInfo.is_available
tests/qtest: cover combined qemu-system machines
accel/tcg/atomic_common.c.inc | 4 +
accel/tcg/atomic_common.h | 70 ++
accel/tcg/cpu-exec-common.c | 10 +
accel/tcg/cpu-exec-common.h | 1 +
accel/tcg/cpu-exec.c | 5 +
accel/tcg/cpu-exec.h | 1 +
accel/tcg/ldst_common.c.inc | 4 +
accel/tcg/ldst_common.h | 13 +
accel/tcg/meson.build | 2 +-
accel/tcg/tcg-all.c | 9 +-
accel/tcg/tcg-runtime-gvec.c | 3 +
.../tcg/{tcg-runtime.h => tcg-runtime-gvec.h} | 111 ---
accel/tcg/tcg-runtime.c | 8 -
accel/tcg/tcg-runtime.h | 293 ------
configs/targets/aarch64-softmmu.c | 25 -
configs/targets/arm-softmmu.c | 25 -
configs/targets/meson.build | 6 -
configs/targets/riscv32-softmmu.c | 24 -
configs/targets/riscv64-softmmu.c | 24 -
hw/Kconfig | 2 +-
hw/arm/aspeed_ast1040_evb.c | 1 +
hw/arm/aspeed_ast10x0_evb.c | 2 +
hw/arm/aspeed_ast2400_palmetto.c | 1 +
hw/arm/aspeed_ast2400_quanta-q71l.c | 1 +
hw/arm/aspeed_ast2400_supermicrox11.c | 1 +
hw/arm/aspeed_ast2500_evb.c | 1 +
hw/arm/aspeed_ast2500_g220a.c | 1 +
hw/arm/aspeed_ast2500_romulus.c | 1 +
hw/arm/aspeed_ast2500_supermicro-x11spi.c | 1 +
hw/arm/aspeed_ast2500_tiogapass.c | 1 +
hw/arm/aspeed_ast2500_witherspoon.c | 1 +
hw/arm/aspeed_ast2500_yosemitev2.c | 1 +
hw/arm/aspeed_ast2600_anacapa.c | 1 +
hw/arm/aspeed_ast2600_bletchley.c | 1 +
hw/arm/aspeed_ast2600_catalina.c | 1 +
hw/arm/aspeed_ast2600_evb.c | 1 +
hw/arm/aspeed_ast2600_fby35.c | 1 +
hw/arm/aspeed_ast2600_fuji.c | 1 +
hw/arm/aspeed_ast2600_gb200nvl.c | 1 +
hw/arm/aspeed_ast2600_rainier.c | 1 +
hw/arm/aspeed_ast2600_sanmiguel.c | 1 +
hw/arm/aspeed_ast27x0-fc.c | 2 +-
hw/arm/aspeed_ast27x0_evb.c | 4 +-
hw/arm/ax3000-evk.c | 1 +
hw/arm/b-l475e-iot01a.c | 1 +
hw/arm/bananapi_m2u.c | 22 +-
hw/arm/collie.c | 1 +
hw/arm/cubieboard.c | 23 +-
hw/arm/digic_boards.c | 19 +-
hw/arm/exynos4_boards.c | 2 +
hw/arm/imx25_pdk.c | 19 +-
hw/arm/imx8mm-evk.c | 23 +-
hw/arm/imx8mp-evk.c | 1 +
hw/arm/integratorcp.c | 23 +-
hw/arm/kzm.c | 19 +-
hw/arm/max78000fthr.c | 19 +-
hw/arm/mcimx6ul-evk.c | 19 +-
hw/arm/mcimx7d-sabre.c | 23 +-
hw/arm/microbit.c | 1 +
hw/arm/mps2-tz.c | 5 +
hw/arm/mps2.c | 4 +
hw/arm/mps3r.c | 1 +
hw/arm/msf2-som.c | 19 +-
hw/arm/musca.c | 2 +
hw/arm/netduino2.c | 19 +-
hw/arm/netduinoplus2.c | 19 +-
hw/arm/npcm7xx_boards.c | 5 +
hw/arm/npcm8xx_boards.c | 1 +
hw/arm/olimex-stm32-h405.c | 19 +-
hw/arm/omap_sx1.c | 2 +
hw/arm/orangepi.c | 23 +-
hw/arm/raspi.c | 7 +-
hw/arm/raspi4b.c | 2 +-
hw/arm/realview.c | 4 +
hw/arm/sabrelite.c | 1 +
hw/arm/sbsa-ref.c | 1 +
hw/arm/stellaris.c | 2 +
hw/arm/stm32vldiscovery.c | 19 +-
hw/arm/versatilepb.c | 2 +
hw/arm/vexpress.c | 2 +
hw/arm/virt.c | 1 +
hw/arm/xen-pvh.c | 1 +
hw/arm/xilinx_zynq.c | 1 +
hw/arm/xlnx-versal-virt.c | 2 +
hw/arm/xlnx-zcu102.c | 1 +
hw/core/Kconfig | 2 +-
hw/core/machine-qmp-cmds.c | 30 +
hw/core/meson.build | 2 +-
hw/dma/Kconfig | 4 +-
hw/i2c/Kconfig | 2 +-
hw/microblaze/petalogix_ml605_mmu.c | 19 +-
hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
hw/microblaze/xlnx-zynqmp-pmu.c | 19 +-
hw/usb/Kconfig | 2 +-
include/accel/tcg/cpu-ldst.h | 4 +-
include/exec/abi_ptr.h | 7 +-
include/exec/helper-gen-common.h | 20 +
include/exec/helper-head.h.inc | 21 +-
include/exec/helper-proto-common.h | 20 +
include/exec/target_long.h | 11 +
include/qemu/config-file.h | 2 +
include/qemu/module.h | 1 -
include/qemu/target-info-def.h | 90 ++
include/qemu/target-info-impl.h | 42 -
include/qemu/target-info-init.h | 53 --
include/qemu/target-info-qom.h | 30 -
include/qemu/target-info-select.h | 24 +
include/qemu/target-info.h | 174 +++-
include/qemu/target-kconfig-has.h | 7 +
include/qemu/target-kconfig.h | 34 +
include/qom/object.h | 26 +-
include/tcg/tcg-op-gvec.h | 21 +-
include/tcg/tcg-op-mem.h | 114 ++-
include/tcg/tcg-op-tl.h | 568 ++++++++++++
include/tcg/tcg-op.h | 291 +-----
include/tcg/tcg.h | 73 +-
meson.build | 233 ++++-
page-vary-common.c | 2 +-
page-vary-system.c | 2 +-
qapi/machine.json | 48 +-
qemu-options.hx | 11 +-
qom/object.c | 20 +-
scripts/gen-target-kconfig.py | 162 ++++
stubs/meson.build | 1 +
stubs/target-info-select.c | 14 +
system/target-info-select.c | 26 +
system/vl.c | 312 ++++++-
target-info-stub.c => target-info-def.c | 9 +-
target-info-qom.c | 55 --
target-info.c | 180 +++-
target-kconfig.c | 20 +
target/arm/cpu.c | 6 +-
target/arm/cpu.h | 1 +
target/arm/cpu64.c | 80 +-
target/arm/hvf/hvf-stub.c | 14 +
target/arm/hvf/meson.build | 1 +
target/arm/kvm-stub.c | 5 +
target/arm/kvm.c | 36 +
target/arm/kvm_arm.h | 9 +
target/arm/meson.build | 4 +-
target/arm/tcg/translate-a64.c | 6 +-
target/arm/tcg/translate-a64.h | 3 +
target/arm/tcg/translate-sme.c | 5 +-
target/arm/tcg/translate-sve.c | 18 +-
target/arm/whpx/whpx-stub.c | 5 +
target/microblaze/meson.build | 2 +-
target/none/cpu-param.h | 7 +
target/none/cpu-qom.h | 6 +
target/none/cpu.h | 18 +
tcg/meson.build | 9 +-
tcg/tcg-op-gvec.c | 17 -
tcg/tcg-op-ldst.c | 31 +
tcg/tcg-op.c | 32 -
tcg/tcg.c | 52 +-
tests/qtest/fuzz/fuzz.c | 3 -
.../qtest/machine-list-combined-targets.h.in | 4 +
tests/qtest/machine-list-combined-test.c | 104 +++
tests/qtest/machine-list-test.c | 94 ++
tests/qtest/machine-list-test.inc.h | 876 ++++++++++++++++++
tests/qtest/machine-option-test.c | 714 ++++++++++++++
tests/qtest/meson.build | 41 +-
tests/unit/meson.build | 35 +
tests/unit/test-helper-tl.c | 20 +
tests/unit/test-helper-tl.h | 25 +
tests/unit/test-helper-tl32.c | 27 +
tests/unit/test-helper-tl64.c | 27 +
tests/unit/test-target-info.c | 38 +
tests/unit/test-target-kconfig-has.c | 22 +
tests/unit/test-tcg-call-tl-stubs.c | 45 +
tests/unit/test-tcg-call-tl.c | 280 ++++++
tests/unit/test-tcg-op-dispatch.h | 203 ++++
tests/unit/test-tcg-op-mem-config32.h | 2 +
tests/unit/test-tcg-op-mem-config64.h | 2 +
tests/unit/test-tcg-op-mem-tl32.c | 26 +
tests/unit/test-tcg-op-mem-tl64.c | 26 +
tests/unit/test-tcg-op-mem-va32-tl64.c | 35 +
tests/unit/test-tcg-op-mem.c | 51 +
tests/unit/test-tcg-op-tl32.c | 24 +
tests/unit/test-tcg-op-tl64.c | 24 +
tests/unit/test-tcg-op.c | 66 ++
util/module.c | 4 +-
util/qemu-config.c | 10 +-
182 files changed, 5772 insertions(+), 1281 deletions(-)
create mode 100644 accel/tcg/atomic_common.h
create mode 100644 accel/tcg/cpu-exec-common.h
create mode 100644 accel/tcg/cpu-exec.h
create mode 100644 accel/tcg/ldst_common.h
copy accel/tcg/{tcg-runtime.h => tcg-runtime-gvec.h} (70%)
delete mode 100644 configs/targets/aarch64-softmmu.c
delete mode 100644 configs/targets/arm-softmmu.c
delete mode 100644 configs/targets/meson.build
delete mode 100644 configs/targets/riscv32-softmmu.c
delete mode 100644 configs/targets/riscv64-softmmu.c
create mode 100644 include/qemu/target-info-def.h
delete mode 100644 include/qemu/target-info-impl.h
delete mode 100644 include/qemu/target-info-init.h
delete mode 100644 include/qemu/target-info-qom.h
create mode 100644 include/qemu/target-info-select.h
create mode 100644 include/qemu/target-kconfig-has.h
create mode 100644 include/qemu/target-kconfig.h
create mode 100644 include/tcg/tcg-op-tl.h
create mode 100644 scripts/gen-target-kconfig.py
create mode 100644 stubs/target-info-select.c
create mode 100644 system/target-info-select.c
rename target-info-stub.c => target-info-def.c (88%)
delete mode 100644 target-info-qom.c
create mode 100644 target-kconfig.c
create mode 100644 target/arm/hvf/hvf-stub.c
create mode 100644 target/none/cpu-param.h
create mode 100644 target/none/cpu-qom.h
create mode 100644 target/none/cpu.h
create mode 100644 tests/qtest/machine-list-combined-targets.h.in
create mode 100644 tests/qtest/machine-list-combined-test.c
create mode 100644 tests/qtest/machine-list-test.c
create mode 100644 tests/qtest/machine-list-test.inc.h
create mode 100644 tests/qtest/machine-option-test.c
create mode 100644 tests/unit/test-helper-tl.c
create mode 100644 tests/unit/test-helper-tl.h
create mode 100644 tests/unit/test-helper-tl32.c
create mode 100644 tests/unit/test-helper-tl64.c
create mode 100644 tests/unit/test-target-info.c
create mode 100644 tests/unit/test-target-kconfig-has.c
create mode 100644 tests/unit/test-tcg-call-tl-stubs.c
create mode 100644 tests/unit/test-tcg-call-tl.c
create mode 100644 tests/unit/test-tcg-op-dispatch.h
create mode 100644 tests/unit/test-tcg-op-mem-config32.h
create mode 100644 tests/unit/test-tcg-op-mem-config64.h
create mode 100644 tests/unit/test-tcg-op-mem-tl32.c
create mode 100644 tests/unit/test-tcg-op-mem-tl64.c
create mode 100644 tests/unit/test-tcg-op-mem-va32-tl64.c
create mode 100644 tests/unit/test-tcg-op-mem.c
create mode 100644 tests/unit/test-tcg-op-tl32.c
create mode 100644 tests/unit/test-tcg-op-tl64.c
create mode 100644 tests/unit/test-tcg-op.c
--
2.52.0.windows.1
^ permalink raw reply [flat|nested] 82+ messages in thread
* [PATCH v4 01/55] target-info: Introduce target_riscv32
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 02/55] configs/targets: remove target info definitions Yonggang Luo
` (53 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
From: Anton Johansson via qemu development <qemu-devel@nongnu.org>
Will be used in the following commit to filter machines using
TypeInfo::is_available, so a simple !target_riscv64() is not sufficient.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Anton Johansson <anjo@rev.ng>
---
include/qemu/target-info.h | 7 +++++++
target-info.c | 5 +++++
2 files changed, 12 insertions(+)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index b23e5bc5865..c09e5d2a3ec 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -91,6 +91,13 @@ bool target_ppc64(void);
*/
bool target_s390x(void);
+/**
+ * target_riscv32:
+ *
+ * Returns whether the target architecture is riscv32
+ */
+bool target_riscv32(void);
+
/**
* target_riscv64:
*
diff --git a/target-info.c b/target-info.c
index 012b384036d..bba4503151a 100644
--- a/target-info.c
+++ b/target-info.c
@@ -89,6 +89,11 @@ bool target_s390x(void)
return target_arch() == SYS_EMU_TARGET_S390X;
}
+bool target_riscv32(void)
+{
+ return target_arch() == SYS_EMU_TARGET_RISCV32;
+}
+
bool target_riscv64(void)
{
return target_arch() == SYS_EMU_TARGET_RISCV64;
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 02/55] configs/targets: remove target info definitions
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 01/55] target-info: Introduce target_riscv32 Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 03/55] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo
` (52 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Now that we remove machine_typename, we don't need to keep duplicated
file per target anymore. So we can just rely on target-info-stub.c.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
configs/targets/aarch64-softmmu.c | 25 -------------------------
configs/targets/arm-softmmu.c | 25 -------------------------
configs/targets/meson.build | 6 ------
configs/targets/riscv32-softmmu.c | 24 ------------------------
configs/targets/riscv64-softmmu.c | 24 ------------------------
meson.build | 7 +------
6 files changed, 1 insertion(+), 110 deletions(-)
delete mode 100644 configs/targets/aarch64-softmmu.c
delete mode 100644 configs/targets/arm-softmmu.c
delete mode 100644 configs/targets/meson.build
delete mode 100644 configs/targets/riscv32-softmmu.c
delete mode 100644 configs/targets/riscv64-softmmu.c
diff --git a/configs/targets/aarch64-softmmu.c b/configs/targets/aarch64-softmmu.c
deleted file mode 100644
index fdebdcc3582..00000000000
--- a/configs/targets/aarch64-softmmu.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * QEMU binary/target API (qemu-system-aarch64)
- *
- * Copyright (c) Linaro
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qemu/target-info-impl.h"
-#include "qemu/target-info-init.h"
-#include "target/arm/cpu-qom.h"
-#include "target/arm/cpu-param.h"
-
-static const TargetInfo target_info_aarch64_system = {
- .target_name = "aarch64",
- .target_arch = SYS_EMU_TARGET_AARCH64,
- .long_bits = 64,
- .cpu_type = TYPE_ARM_CPU,
- .endianness = ENDIAN_MODE_LITTLE,
- .page_bits_vary = true,
- .page_bits_init = TARGET_PAGE_BITS_LEGACY,
-};
-
-target_info_init(target_info_aarch64_system)
diff --git a/configs/targets/arm-softmmu.c b/configs/targets/arm-softmmu.c
deleted file mode 100644
index 2b98f65a0f8..00000000000
--- a/configs/targets/arm-softmmu.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * QEMU binary/target API (qemu-system-arm)
- *
- * Copyright (c) Linaro
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qemu/target-info-impl.h"
-#include "qemu/target-info-init.h"
-#include "target/arm/cpu-qom.h"
-#include "target/arm/cpu-param.h"
-
-static const TargetInfo target_info_arm_system = {
- .target_name = "arm",
- .target_arch = SYS_EMU_TARGET_ARM,
- .long_bits = 32,
- .cpu_type = TYPE_ARM_CPU,
- .endianness = ENDIAN_MODE_LITTLE,
- .page_bits_vary = true,
- .page_bits_init = TARGET_PAGE_BITS_LEGACY,
-};
-
-target_info_init(target_info_arm_system)
diff --git a/configs/targets/meson.build b/configs/targets/meson.build
deleted file mode 100644
index 2ab4d27eaf5..00000000000
--- a/configs/targets/meson.build
+++ /dev/null
@@ -1,6 +0,0 @@
-foreach target : [
- 'arm-softmmu', 'aarch64-softmmu',
- 'riscv32-softmmu', 'riscv64-softmmu'
- ]
- config_target_info += {target : files(target + '.c')}
-endforeach
diff --git a/configs/targets/riscv32-softmmu.c b/configs/targets/riscv32-softmmu.c
deleted file mode 100644
index 0829ab84de5..00000000000
--- a/configs/targets/riscv32-softmmu.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * QEMU binary/target API (qemu-system-riscv32)
- *
- * Copyright (c) rev.ng Labs Srl.
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qemu/target-info-impl.h"
-#include "qemu/target-info-init.h"
-#include "target/riscv/cpu-qom.h"
-#include "target/riscv/cpu-param.h"
-
-static const TargetInfo target_info_riscv32_system = {
- .target_name = "riscv32",
- .target_arch = SYS_EMU_TARGET_RISCV32,
- .long_bits = 32,
- .cpu_type = TYPE_RISCV_CPU,
- .endianness = ENDIAN_MODE_LITTLE,
- .page_bits_init = TARGET_PAGE_BITS,
-};
-
-target_info_init(target_info_riscv32_system)
diff --git a/configs/targets/riscv64-softmmu.c b/configs/targets/riscv64-softmmu.c
deleted file mode 100644
index 553bd1f75fe..00000000000
--- a/configs/targets/riscv64-softmmu.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * QEMU binary/target API (qemu-system-riscv64)
- *
- * Copyright (c) rev.ng Labs Srl.
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qemu/target-info-impl.h"
-#include "qemu/target-info-init.h"
-#include "target/riscv/cpu-qom.h"
-#include "target/riscv/cpu-param.h"
-
-static const TargetInfo target_info_riscv64_system = {
- .target_name = "riscv64",
- .target_arch = SYS_EMU_TARGET_RISCV64,
- .long_bits = 64,
- .cpu_type = TYPE_RISCV_CPU,
- .endianness = ENDIAN_MODE_LITTLE,
- .page_bits_init = TARGET_PAGE_BITS,
-};
-
-target_info_init(target_info_riscv64_system)
diff --git a/meson.build b/meson.build
index cfac634cf13..732f0a885ba 100644
--- a/meson.build
+++ b/meson.build
@@ -3754,7 +3754,6 @@ subdir('dump')
subdir('accel')
subdir('backends')
-subdir('configs/targets')
subdir('disas')
subdir('migration')
subdir('monitor')
@@ -4331,11 +4330,7 @@ foreach target : target_dirs
endif
endif
- if target in config_target_info
- arch_srcs += config_target_info[target]
- else
- arch_srcs += files('target-info-stub.c')
- endif
+ arch_srcs += files('target-info-stub.c')
if target_base_arch in target_arch
t = target_arch[target_base_arch].apply(config_target, strict: false)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 03/55] target-info: rename target-info-stub.c in target-info-def.c
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 01/55] target-info: Introduce target_riscv32 Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 02/55] configs/targets: remove target info definitions Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 04/55] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo
` (51 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Now it's the only file left to define target info, we call it def to
make the intent more clear.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
meson.build | 2 +-
target-info-stub.c => target-info-def.c | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename target-info-stub.c => target-info-def.c (100%)
diff --git a/meson.build b/meson.build
index 732f0a885ba..51bc0905294 100644
--- a/meson.build
+++ b/meson.build
@@ -4330,7 +4330,7 @@ foreach target : target_dirs
endif
endif
- arch_srcs += files('target-info-stub.c')
+ arch_srcs += files('target-info-def.c')
if target_base_arch in target_arch
t = target_arch[target_base_arch].apply(config_target, strict: false)
diff --git a/target-info-stub.c b/target-info-def.c
similarity index 100%
rename from target-info-stub.c
rename to target-info-def.c
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 04/55] target-info: rename target-info-impl.h to target-info-def.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (2 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 03/55] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 05/55] vl: parse early options before target-info init Yonggang Luo
` (50 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Rename the TargetInfo structure header and its include guard.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/{target-info-impl.h => target-info-def.h} | 4 ++--
include/qemu/target-info-qom.h | 2 +-
page-vary-common.c | 2 +-
page-vary-system.c | 2 +-
target-info-def.c | 2 +-
target-info-qom.c | 2 +-
target-info.c | 2 +-
7 files changed, 8 insertions(+), 8 deletions(-)
rename include/qemu/{target-info-impl.h => target-info-def.h} (94%)
diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-def.h
similarity index 94%
rename from include/qemu/target-info-impl.h
rename to include/qemu/target-info-def.h
index cf42aabbc8b..8019d2c7196 100644
--- a/include/qemu/target-info-impl.h
+++ b/include/qemu/target-info-def.h
@@ -6,8 +6,8 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#ifndef QEMU_TARGET_INFO_IMPL_H
-#define QEMU_TARGET_INFO_IMPL_H
+#ifndef QEMU_TARGET_INFO_DEF_H
+#define QEMU_TARGET_INFO_DEF_H
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-types-machine.h"
diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
index 91be415ed33..0f6772e65c3 100644
--- a/include/qemu/target-info-qom.h
+++ b/include/qemu/target-info-qom.h
@@ -9,7 +9,7 @@
#ifndef QEMU_TARGET_INFO_QOM_H
#define QEMU_TARGET_INFO_QOM_H
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
#include "qom/object.h"
#define TYPE_TARGET_INFO "target-info"
diff --git a/page-vary-common.c b/page-vary-common.c
index ddd08633788..5a4654725a8 100644
--- a/page-vary-common.c
+++ b/page-vary-common.c
@@ -20,7 +20,7 @@
#define IN_PAGE_VARY 1
#include "qemu/osdep.h"
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
#include "exec/page-vary.h"
/* WARNING: This file must *not* be complied with -flto. */
diff --git a/page-vary-system.c b/page-vary-system.c
index 6c49c10e23b..9773685dc16 100644
--- a/page-vary-system.c
+++ b/page-vary-system.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "exec/page-vary.h"
#include "exec/tlb-flags.h"
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
QEMU_BUILD_BUG_ON(TLB_FLAGS_MASK & ((1u < TARGET_PAGE_BITS_MIN) - 1));
diff --git a/target-info-def.c b/target-info-def.c
index d121b8c0170..fa19cabc55f 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -8,7 +8,7 @@
#include "qemu/osdep.h"
#include "qemu/target-info.h"
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
#include "qemu/target-info-init.h"
#include "hw/core/boards.h"
#include "cpu.h"
diff --git a/target-info-qom.c b/target-info-qom.c
index 6965e4d1169..2b38673a3f8 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -9,7 +9,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qom/object.h"
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
#include "qemu/target-info-init.h"
#include "qemu/target-info-qom.h"
diff --git a/target-info.c b/target-info.c
index bba4503151a..9abe72b1f55 100644
--- a/target-info.c
+++ b/target-info.c
@@ -9,7 +9,7 @@
#include "qemu/osdep.h"
#include "qemu/target-info.h"
#include "qemu/target-info-qapi.h"
-#include "qemu/target-info-impl.h"
+#include "qemu/target-info-def.h"
#include "qapi/error.h"
const char *target_name(void)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 05/55] vl: parse early options before target-info init
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (3 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 04/55] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 06/55] target-info: replace QOM registration with a constructor list Yonggang Luo
` (49 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Move the first argv pass ahead of MODULE_INIT_TARGET_INFO so later
target-info selection can use command-line options before QOM init.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
system/vl.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index 468a9fc247a..3efa4968a20 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2912,16 +2912,6 @@ void qemu_init(int argc, char **argv)
error_init(argv[0]);
qemu_init_exec_dir(argv[0]);
- os_setup_limits();
-
- module_call_init(MODULE_INIT_TARGET_INFO);
- target_info_qom_set_target();
-
- module_init_info(qemu_modinfo);
- module_allow_arch(target_name());
-
- qemu_init_subsystems();
-
/* first pass of option parsing */
optind = 1;
while (optind < argc) {
@@ -2940,6 +2930,16 @@ void qemu_init(int argc, char **argv)
}
}
+ os_setup_limits();
+
+ module_call_init(MODULE_INIT_TARGET_INFO);
+ target_info_qom_set_target();
+
+ module_init_info(qemu_modinfo);
+ module_allow_arch(target_name());
+
+ qemu_init_subsystems();
+
machine_opts_dict = qdict_new();
if (userconfig) {
qemu_read_default_config_file(&error_fatal);
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 06/55] target-info: replace QOM registration with a constructor list
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (4 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 05/55] vl: parse early options before target-info init Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 07/55] tests/unit: add test-target-info Yonggang Luo
` (48 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace MODULE_INIT_TARGET_INFO and target_info_qom_set_target with a
constructor list. target_info_init builds a TargetInfoNode;
target_info_list_add inserts it, sorted by target_arch, before main().
target_info() starts as an "unknown" TargetInfo and target_info_select
sets the current entry. target-info.c moves into libqom.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/module.h | 1 -
include/qemu/target-info-def.h | 56 ++++++++++++++++++++++++++++++---
include/qemu/target-info-init.h | 53 -------------------------------
include/qemu/target-info-qom.h | 30 ------------------
include/qemu/target-info.h | 11 +++++++
meson.build | 6 ++--
system/vl.c | 4 ---
target-info-def.c | 1 -
target-info-qom.c | 55 --------------------------------
target-info.c | 56 ++++++++++++++++++++++++++++++++-
tests/qtest/fuzz/fuzz.c | 3 --
11 files changed, 120 insertions(+), 156 deletions(-)
delete mode 100644 include/qemu/target-info-init.h
delete mode 100644 include/qemu/target-info-qom.h
delete mode 100644 target-info-qom.c
diff --git a/include/qemu/module.h b/include/qemu/module.h
index fccf017bf9e..9885ac9afb3 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -43,7 +43,6 @@ typedef enum {
MODULE_INIT_MIGRATION,
MODULE_INIT_BLOCK,
MODULE_INIT_OPTS,
- MODULE_INIT_TARGET_INFO,
MODULE_INIT_QOM,
MODULE_INIT_TRACE,
MODULE_INIT_XEN_BACKEND,
diff --git a/include/qemu/target-info-def.h b/include/qemu/target-info-def.h
index 8019d2c7196..080e30a5b0e 100644
--- a/include/qemu/target-info-def.h
+++ b/include/qemu/target-info-def.h
@@ -11,8 +11,10 @@
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-types-machine.h"
+#include "qemu/queue.h"
+#include "qemu/target-info.h"
-typedef struct TargetInfo {
+struct TargetInfo {
/* runtime equivalent of TARGET_NAME definition */
const char *target_name;
/* related to TARGET_ARCH definition */
@@ -30,13 +32,57 @@ typedef struct TargetInfo {
unsigned page_bits_init;
/* runtime equivalent of TARGET_PAGE_BITS_VARY definition */
bool page_bits_vary;
-} TargetInfo;
+};
+
+typedef struct TargetInfoNode TargetInfoNode;
+typedef QLIST_HEAD(, TargetInfoNode) TargetInfoList;
+
+struct TargetInfoNode {
+ const TargetInfo *info;
+ QLIST_ENTRY(TargetInfoNode) next;
+};
+
+/**
+ * target_info_list:
+ *
+ * TargetInfo is a static list, not a QOM type. Constructors insert
+ * entries before main(), so type_init can use it.
+ *
+ * Returns: registered TargetInfoNode list head, sorted by
+ * info->target_arch. The list is owned by target-info
+ * and must not be modified. Iterate with
+ * QLIST_FOREACH(..., next) and use node->info.
+ */
+const TargetInfoList *target_info_list(void);
/**
- * target_info:
+ * target_info_select:
+ * @ti: TargetInfo to make current
*
- * Returns: The TargetInfo structure definition for this target binary.
+ * Sets target_info() to @ti.
+ */
+void target_info_select(const TargetInfo *ti);
+
+/**
+ * target_info_list_add:
+ * @node: static TargetInfoNode whose info points at a const TargetInfo
+ *
+ * Inserts @node into target_info_list(), sorted by info->target_arch.
+ * Sets target_info() to the first list entry.
+ */
+void target_info_list_add(TargetInfoNode *node);
+
+/*
+ * Register @ti before main(). Linked into the executable, not a DSO.
+ * @ti is a unique identifier in this translation unit.
*/
-const TargetInfo *target_info(void);
+#define target_info_init(ti) \
+ static TargetInfoNode ti##_node = { \
+ .info = &(ti), \
+ }; \
+ static void __attribute__((constructor)) do_qemu_init_##ti(void) \
+ { \
+ target_info_list_add(&ti##_node); \
+ }
#endif
diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
deleted file mode 100644
index b7024c9faef..00000000000
--- a/include/qemu/target-info-init.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * QEMU target info initialization
- *
- * Copyright (c) Qualcomm
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- *
- * This file is included by each file defining a TargetInfo structure and is
- * responsible for registering it.
- */
-
-#ifndef QEMU_TARGET_INFO_INIT_H
-#define QEMU_TARGET_INFO_INIT_H
-
-#define DEFINE_TARGET_INFO_TYPE(info) \
-static void do_qemu_init_target_info(void) \
-{ \
- type_register_static(&info); \
-} \
-module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
-
-#ifdef COMPILING_PER_TARGET
-#ifdef CONFIG_USER_ONLY
-
-/*
- * User mode does not support multiple targets in the same binary, so just
- * define target_info().
- */
-#define target_info_init(ti_var) \
-const TargetInfo *target_info(void) \
-{ \
- return &ti_var; \
-}
-
-#else /* CONFIG_USER_ONLY */
-
-#include "qemu/target-info-qom.h"
-#include "qom/object.h"
-
-#define target_info_init(ti_var) \
-static const TypeInfo target_info_qom_target_type_info = { \
- .name = TYPE_TARGET_INFO"-"TARGET_NAME, \
- .parent = TYPE_TARGET_INFO, \
- .instance_size = sizeof(TargetInfoQom), \
- .class_size = sizeof(TargetInfoQomClass), \
- .class_data = &ti_var, \
-}; \
-DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info)
-
-#endif /* CONFIG_USER_ONLY */
-#endif /* COMPILING_PER_TARGET */
-
-#endif /* QEMU_TARGET_INFO_INIT_H */
diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
deleted file mode 100644
index 0f6772e65c3..00000000000
--- a/include/qemu/target-info-qom.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * QEMU target info QOM types
- *
- * Copyright (c) Qualcomm
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef QEMU_TARGET_INFO_QOM_H
-#define QEMU_TARGET_INFO_QOM_H
-
-#include "qemu/target-info-def.h"
-#include "qom/object.h"
-
-#define TYPE_TARGET_INFO "target-info"
-
-typedef struct TargetInfoQom {
- Object parent_obj;
-} TargetInfoQom;
-
-typedef struct TargetInfoQomClass {
- ObjectClass parent_class;
- const TargetInfo *target_info;
-} TargetInfoQomClass;
-
-OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
-
-void target_info_qom_set_target(void);
-
-#endif /* QEMU_TARGET_INFO_QOM_H */
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index c09e5d2a3ec..c48973f20be 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -9,6 +9,17 @@
#ifndef QEMU_TARGET_INFO_H
#define QEMU_TARGET_INFO_H
+#include <stdbool.h>
+
+typedef struct TargetInfo TargetInfo;
+
+/**
+ * target_info:
+ *
+ * Returns: The TargetInfo structure definition for the selected target.
+ */
+const TargetInfo *target_info(void);
+
/**
* target_name:
*
diff --git a/meson.build b/meson.build
index 51bc0905294..c404d222d9f 100644
--- a/meson.build
+++ b/meson.build
@@ -3776,6 +3776,9 @@ if enable_modules
modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO')
endif
+qom_ss.add(files(
+ 'target-info.c',
+))
qom_ss = qom_ss.apply({})
libqom = static_library('qom', qom_ss.sources() + genh,
dependencies: [qom_ss.dependencies()],
@@ -3870,9 +3873,6 @@ endif
common_ss.add(pagevary)
system_ss.add(files('page-vary-system.c'))
-common_ss.add(files('target-info.c'))
-system_ss.add(files('target-info-qom.c'))
-
if 'CONFIG_TCG' in config_all_accel
subdir('contrib/plugins')
endif
diff --git a/system/vl.c b/system/vl.c
index 3efa4968a20..7f1381d84ff 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -28,7 +28,6 @@
#include "qemu/units.h"
#include "qemu/module.h"
#include "qemu/target-info.h"
-#include "qemu/target-info-qom.h"
#include "exec/cpu-common.h"
#include "exec/page-vary.h"
#include "hw/core/qdev-properties.h"
@@ -2932,9 +2931,6 @@ void qemu_init(int argc, char **argv)
os_setup_limits();
- module_call_init(MODULE_INIT_TARGET_INFO);
- target_info_qom_set_target();
-
module_init_info(qemu_modinfo);
module_allow_arch(target_name());
diff --git a/target-info-def.c b/target-info-def.c
index fa19cabc55f..3041d64ccd2 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -9,7 +9,6 @@
#include "qemu/osdep.h"
#include "qemu/target-info.h"
#include "qemu/target-info-def.h"
-#include "qemu/target-info-init.h"
#include "hw/core/boards.h"
#include "cpu.h"
#include "exec/cpu-defs.h"
diff --git a/target-info-qom.c b/target-info-qom.c
deleted file mode 100644
index 2b38673a3f8..00000000000
--- a/target-info-qom.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * QEMU binary/target API (QOM types)
- *
- * Copyright (c) Linaro
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qom/object.h"
-#include "qemu/target-info-def.h"
-#include "qemu/target-info-init.h"
-#include "qemu/target-info-qom.h"
-
-static void target_info_qom_class_init(ObjectClass *oc, const void * data)
-{
- TargetInfoQomClass *klass = TARGET_INFO_CLASS(oc);
- klass->target_info = data;
-}
-
-static const TypeInfo target_info_parent_type = {
- .name = TYPE_TARGET_INFO,
- .parent = TYPE_OBJECT,
- .instance_size = sizeof(TargetInfoQom),
- .class_size = sizeof(TargetInfoQomClass),
- /* use class_base_init so children classes can set class_data accordingly */
- .class_base_init = target_info_qom_class_init,
- /* children classes will be concrete, which allows to easily query them
- * without listing this parent class also */
- .abstract = true,
-};
-
-DEFINE_TARGET_INFO_TYPE(target_info_parent_type)
-
-static const TargetInfo *target_info_ptr;
-
-const TargetInfo *target_info(void)
-{
- return target_info_ptr;
-}
-
-void target_info_qom_set_target(void)
-{
- g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
-
- size_t num_found = g_slist_length(targets);
- if (num_found != 1) {
- error_setg(&error_fatal, num_found == 0 ?
- "no target-info is available" :
- "more than one target-info is available");
- }
-
- target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
-}
diff --git a/target-info.c b/target-info.c
index 9abe72b1f55..6e66f48e1ff 100644
--- a/target-info.c
+++ b/target-info.c
@@ -10,7 +10,61 @@
#include "qemu/target-info.h"
#include "qemu/target-info-qapi.h"
#include "qemu/target-info-def.h"
-#include "qapi/error.h"
+#include "exec/page-vary.h"
+
+static const TargetInfo target_info_default = {
+ .target_arch = SYS_EMU_TARGET__MAX,
+ .target_name = "unknown",
+ .long_bits = 64,
+ .endianness = ENDIAN_MODE_LITTLE,
+ .page_bits_init = TARGET_PAGE_BITS_MIN,
+};
+
+static const TargetInfo *target_info_ptr = &target_info_default;
+static TargetInfoList target_infos = QLIST_HEAD_INITIALIZER(target_infos);
+
+const TargetInfo *target_info(void)
+{
+ g_assert(target_info_ptr != NULL);
+ return target_info_ptr;
+}
+
+const TargetInfoList *target_info_list(void)
+{
+ return &target_infos;
+}
+
+void target_info_select(const TargetInfo *ti)
+{
+ g_assert(ti != NULL);
+ target_info_ptr = ti;
+}
+
+void target_info_list_add(TargetInfoNode *node)
+{
+ const TargetInfo *info;
+ TargetInfoNode *cur, *prev = NULL;
+
+ g_assert(node && node->info);
+ info = node->info;
+ QLIST_FOREACH(cur, &target_infos, next) {
+ if (info->target_arch < cur->info->target_arch) {
+ QLIST_INSERT_BEFORE(cur, node, next);
+ break;
+ }
+ prev = cur;
+ }
+ if (!cur) {
+ if (prev) {
+ QLIST_INSERT_AFTER(prev, node, next);
+ } else {
+ QLIST_INSERT_HEAD(&target_infos, node, next);
+ }
+ }
+
+ /* Single-target default: the first list entry. */
+ target_info_select(QLIST_FIRST(&target_infos)->info);
+}
const char *target_name(void)
{
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index a3a131c80f8..d2355989616 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -22,7 +22,6 @@
#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "qemu/rcu.h"
-#include "qemu/target-info-qom.h"
#include "tests/qtest/libqtest.h"
#include "tests/qtest/libqos/qgraph.h"
#include "fuzz.h"
@@ -173,8 +172,6 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
/* Initialize qgraph and modules */
qos_graph_init();
- module_call_init(MODULE_INIT_TARGET_INFO);
- target_info_qom_set_target();
module_call_init(MODULE_INIT_FUZZ_TARGET);
module_call_init(MODULE_INIT_QOM);
module_call_init(MODULE_INIT_LIBQOS);
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 07/55] tests/unit: add test-target-info
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (5 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 06/55] target-info: replace QOM registration with a constructor list Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 9:07 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 08/55] tests/qtest: prepare machine-list-test for combined qemu-system Yonggang Luo
` (47 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Collect each target-info-def.c object in target_info_def_objects,
keyed by target dir. Link every value so constructors fill the
list. Assert target_info() is not NULL and target_info_list() has
one entry per linked object.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
meson.build | 6 +++++-
tests/unit/meson.build | 4 ++++
tests/unit/test-target-info.c | 38 +++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 1 deletion(-)
create mode 100644 tests/unit/test-target-info.c
diff --git a/meson.build b/meson.build
index c404d222d9f..93237429713 100644
--- a/meson.build
+++ b/meson.build
@@ -4259,6 +4259,8 @@ endif
traceable = []
emulators = {}
+target_info_def = files('target-info-def.c')
+target_info_def_objects = {}
foreach target : target_dirs
config_target = config_target_mak[target]
target_name = config_target['TARGET_NAME']
@@ -4330,7 +4332,7 @@ foreach target : target_dirs
endif
endif
- arch_srcs += files('target-info-def.c')
+ arch_srcs += target_info_def
if target_base_arch in target_arch
t = target_arch[target_base_arch].apply(config_target, strict: false)
@@ -4408,6 +4410,8 @@ foreach target : target_dirs
c_args: c_args,
build_by_default: false)
+ target_info_def_objects += {target: lib.extract_objects(target_info_def)}
+
if target.endswith('-softmmu')
execs = [{
'name': 'qemu-system-' + target_name,
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index e47bc7225ab..dc980a35955 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -43,6 +43,10 @@ tests = {
'test-qgraph': ['../qtest/libqos/qgraph.c'],
'check-qom-interface': [qom],
'check-qom-proplist': [qom],
+ 'test-target-info': [qom, declare_dependency(
+ objects: target_info_def_objects.values(),
+ compile_args: ['-DTARGET_INFO_DEF_COUNT=@0@'.format(
+ target_info_def_objects.values().length())])],
'test-qemu-opts': [],
'test-keyval': [testqapi],
'test-logging': [],
diff --git a/tests/unit/test-target-info.c b/tests/unit/test-target-info.c
new file mode 100644
index 00000000000..e6de9b259e8
--- /dev/null
+++ b/tests/unit/test-target-info.c
@@ -0,0 +1,38 @@
+/*
+ * TargetInfo unit tests
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-info.h"
+#include "qemu/target-info-def.h"
+
+static int target_info_list_count(void)
+{
+ TargetInfoNode *node;
+ int n = 0;
+
+ QLIST_FOREACH(node, target_info_list(), next) {
+ n++;
+ }
+ return n;
+}
+
+static void test_target_info_not_null(void)
+{
+ g_assert_nonnull(target_info());
+}
+
+static void test_target_info_list_count(void)
+{
+ g_assert_cmpint(target_info_list_count(), ==, TARGET_INFO_DEF_COUNT);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/target-info/not-null", test_target_info_not_null);
+ g_test_add_func("/target-info/list-count", test_target_info_list_count);
+ return g_test_run();
+}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 08/55] tests/qtest: prepare machine-list-test for combined qemu-system
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (6 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 07/55] tests/unit: add test-target-info Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 09/55] kconfig: rename REGISTER to HW_REGISTER Yonggang Luo
` (46 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Each built qemu-system target checks its query-target arch and
query-machines names, including the none machine and omitting the
abstract pegasos parent. xen, vmapple, nitro, and x-remote appear
only when that host build has them. The lists in
machine-list-test.inc.h are shared for a later combined
qemu-system test.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
tests/qtest/machine-list-test.c | 94 +++
tests/qtest/machine-list-test.inc.h | 876 ++++++++++++++++++++++++++++
tests/qtest/meson.build | 1 +
3 files changed, 971 insertions(+)
create mode 100644 tests/qtest/machine-list-test.c
create mode 100644 tests/qtest/machine-list-test.inc.h
diff --git a/tests/qtest/machine-list-test.c b/tests/qtest/machine-list-test.c
new file mode 100644
index 00000000000..35fb365197d
--- /dev/null
+++ b/tests/qtest/machine-list-test.c
@@ -0,0 +1,94 @@
+/*
+ * Per-target machine list tests.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qobject/qdict.h"
+#include "qobject/qlist.h"
+#include "qobject/qstring.h"
+
+/* query-target "arch" is SysEmuTarget, not always TARGET_NAME. */
+static const char *query_arch_for_target(const char *target_info)
+{
+ static const struct {
+ const char *target_name;
+ const char *arch;
+ } map[] = {
+ { "armeb", "arm" },
+ { "microblazeel", "microblaze" },
+ { "mips64el", "mips64" },
+ { "mipsel", "mips" },
+ { "ppc64le", "ppc64" },
+ { "sh4eb", "sh4" },
+ { "xtensaeb", "xtensa" },
+ };
+ size_t i;
+
+ for (i = 0; i < G_N_ELEMENTS(map); i++) {
+ if (!strcmp(target_info, map[i].target_name)) {
+ return map[i].arch;
+ }
+ }
+ return target_info;
+}
+
+#include "machine-list-test.inc.h"
+
+static QList *query_machine_names(QTestState *qts)
+{
+ QDict *resp;
+ QList *machines;
+ QList *names;
+ const QListEntry *e;
+
+ resp = qtest_qmp(qts, "{'execute': 'query-machines'}");
+ g_assert(qdict_haskey(resp, "return"));
+ machines = qdict_get_qlist(resp, "return");
+ g_assert_nonnull(machines);
+ names = qlist_new();
+ for (e = qlist_first(machines); e; e = qlist_next(e)) {
+ QDict *m = qobject_to(QDict, qlist_entry_obj(e));
+ const char *name;
+
+ g_assert_nonnull(m);
+ name = qdict_get_str(m, "name");
+ qlist_append_str(names, name);
+ }
+ qobject_unref(resp);
+ return names;
+}
+
+static void test_historic_machine_list(void)
+{
+ const char *target = qtest_get_arch();
+ const struct ShippedTarget *t = lookup_shipped_target(target);
+ QTestState *qts;
+ QDict *resp;
+ QDict *ret;
+ g_autoptr(QList) names = NULL;
+
+ qts = qtest_init("-nodefaults -M none");
+ read_accel_flags(qts);
+ resp = qtest_qmp(qts, "{'execute': 'query-target'}");
+ g_assert(qdict_haskey(resp, "return"));
+ ret = qdict_get_qdict(resp, "return");
+ g_assert_cmpstr(qdict_get_str(ret, "arch"), ==,
+ query_arch_for_target(target));
+ qobject_unref(resp);
+ names = query_machine_names(qts);
+ if (t) {
+ assert_name_list(names, t->name, t->machines, t->n_machines);
+ }
+ qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("machine-list", test_historic_machine_list);
+ return g_test_run();
+}
diff --git a/tests/qtest/machine-list-test.inc.h b/tests/qtest/machine-list-test.inc.h
new file mode 100644
index 00000000000..e6e6f3ea7cd
--- /dev/null
+++ b/tests/qtest/machine-list-test.inc.h
@@ -0,0 +1,876 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* Normal machine lists for every softmmu target. */
+/* Xen, vmapple, nitro, and x-remote stay in special_machine_map. */
+
+static const char * const aarch64_machines[] = {
+ "amd-versal-virt",
+ "amd-versal2-virt",
+ "anacapa-bmc",
+ "ast1030-evb",
+ "ast1040-evb",
+ "ast1060-evb",
+ "ast2500-evb",
+ "ast2600-evb",
+ "ast2700a1-evb",
+ "ast2700a2-evb",
+ "ast2700fc",
+ "axiado-scm3003",
+ "b-l475e-iot01a",
+ "bletchley-bmc",
+ "bpim2u",
+ "canon-a1100",
+ "catalina-bmc",
+ "collie",
+ "cubieboard",
+ "emcraft-sf2",
+ "fby35-bmc",
+ "fuji-bmc",
+ "g220a-bmc",
+ "gb200nvl-bmc",
+ "imx25-pdk",
+ "imx8mm-evk",
+ "imx8mp-evk",
+ "integratorcp",
+ "kudo-bmc",
+ "kzm",
+ "lm3s6965evb",
+ "lm3s811evb",
+ "max78000fthr",
+ "mcimx6ul-evk",
+ "mcimx7d-sabre",
+ "microbit",
+ "mori-bmc",
+ "mps2-an385",
+ "mps2-an386",
+ "mps2-an500",
+ "mps2-an505",
+ "mps2-an511",
+ "mps2-an521",
+ "mps3-an524",
+ "mps3-an536",
+ "mps3-an547",
+ "mps3-an555",
+ "musca-a",
+ "musca-b1",
+ "netduino2",
+ "netduinoplus2",
+ "none",
+ "npcm750-evb",
+ "npcm845-evb",
+ "nuri",
+ "olimex-stm32-h405",
+ "orangepi-pc",
+ "palmetto-bmc",
+ "quanta-gbs-bmc",
+ "quanta-gsj",
+ "quanta-q71l-bmc",
+ "rainier-bmc",
+ "raspi0",
+ "raspi1ap",
+ "raspi2b",
+ "raspi3ap",
+ "raspi3b",
+ "raspi4b",
+ "realview-eb",
+ "realview-eb-mpcore",
+ "realview-pb-a8",
+ "realview-pbx-a9",
+ "romulus-bmc",
+ "sabrelite",
+ "sanmiguel-bmc",
+ "sbsa-ref",
+ "smdkc210",
+ "stm32vldiscovery",
+ "supermicro-x11spi-bmc",
+ "supermicrox11-bmc",
+ "sx1",
+ "sx1-v1",
+ "tiogapass-bmc",
+ "versatileab",
+ "versatilepb",
+ "vexpress-a15",
+ "vexpress-a9",
+ "virt-10.0",
+ "virt-10.1",
+ "virt-10.2",
+ "virt-11.0",
+ "virt-11.1",
+ "virt-11.2",
+ "virt-6.0",
+ "virt-6.1",
+ "virt-6.2",
+ "virt-7.0",
+ "virt-7.1",
+ "virt-7.2",
+ "virt-8.0",
+ "virt-8.1",
+ "virt-8.2",
+ "virt-9.0",
+ "virt-9.1",
+ "virt-9.2",
+ "witherspoon-bmc",
+ "xilinx-zynq-a9",
+ "xlnx-zcu102",
+ "yosemitev2-bmc",
+};
+
+static const char * const alpha_machines[] = {
+ "clipper",
+ "none",
+};
+
+static const char * const arm_machines[] = {
+ "anacapa-bmc",
+ "ast1030-evb",
+ "ast1040-evb",
+ "ast1060-evb",
+ "ast2500-evb",
+ "ast2600-evb",
+ "b-l475e-iot01a",
+ "bletchley-bmc",
+ "bpim2u",
+ "canon-a1100",
+ "catalina-bmc",
+ "collie",
+ "cubieboard",
+ "emcraft-sf2",
+ "fby35-bmc",
+ "fuji-bmc",
+ "g220a-bmc",
+ "gb200nvl-bmc",
+ "imx25-pdk",
+ "integratorcp",
+ "kudo-bmc",
+ "kzm",
+ "lm3s6965evb",
+ "lm3s811evb",
+ "max78000fthr",
+ "mcimx6ul-evk",
+ "mcimx7d-sabre",
+ "microbit",
+ "mori-bmc",
+ "mps2-an385",
+ "mps2-an386",
+ "mps2-an500",
+ "mps2-an505",
+ "mps2-an511",
+ "mps2-an521",
+ "mps3-an524",
+ "mps3-an536",
+ "mps3-an547",
+ "mps3-an555",
+ "musca-a",
+ "musca-b1",
+ "netduino2",
+ "netduinoplus2",
+ "none",
+ "npcm750-evb",
+ "nuri",
+ "olimex-stm32-h405",
+ "orangepi-pc",
+ "palmetto-bmc",
+ "quanta-gbs-bmc",
+ "quanta-gsj",
+ "quanta-q71l-bmc",
+ "rainier-bmc",
+ "raspi0",
+ "raspi1ap",
+ "raspi2b",
+ "realview-eb",
+ "realview-eb-mpcore",
+ "realview-pb-a8",
+ "realview-pbx-a9",
+ "romulus-bmc",
+ "sabrelite",
+ "sanmiguel-bmc",
+ "smdkc210",
+ "stm32vldiscovery",
+ "supermicro-x11spi-bmc",
+ "supermicrox11-bmc",
+ "sx1",
+ "sx1-v1",
+ "tiogapass-bmc",
+ "versatileab",
+ "versatilepb",
+ "vexpress-a15",
+ "vexpress-a9",
+ "virt-10.0",
+ "virt-10.1",
+ "virt-10.2",
+ "virt-11.0",
+ "virt-11.1",
+ "virt-11.2",
+ "virt-6.0",
+ "virt-6.1",
+ "virt-6.2",
+ "virt-7.0",
+ "virt-7.1",
+ "virt-7.2",
+ "virt-8.0",
+ "virt-8.1",
+ "virt-8.2",
+ "virt-9.0",
+ "virt-9.1",
+ "virt-9.2",
+ "witherspoon-bmc",
+ "xilinx-zynq-a9",
+ "yosemitev2-bmc",
+};
+
+static const char * const avr_machines[] = {
+ "arduino-duemilanove",
+ "arduino-mega",
+ "arduino-mega-2560-v3",
+ "arduino-uno",
+ "none",
+};
+
+static const char * const hexagon_machines[] = {
+ "V66G_1024",
+ "V68N_1024",
+ "V81DGB_1",
+ "V81QA_1",
+ "none",
+ "virt",
+};
+
+static const char * const hppa_machines[] = {
+ "715",
+ "A400",
+ "B160L",
+ "C3700",
+ "none",
+};
+
+static const char * const i386_machines[] = {
+ "isapc",
+ "microvm",
+ "none",
+ "pc-i440fx-10.0",
+ "pc-i440fx-10.1",
+ "pc-i440fx-10.2",
+ "pc-i440fx-11.0",
+ "pc-i440fx-11.1",
+ "pc-i440fx-11.2",
+ "pc-i440fx-6.0",
+ "pc-i440fx-6.1",
+ "pc-i440fx-6.2",
+ "pc-i440fx-7.0",
+ "pc-i440fx-7.1",
+ "pc-i440fx-7.2",
+ "pc-i440fx-8.0",
+ "pc-i440fx-8.1",
+ "pc-i440fx-8.2",
+ "pc-i440fx-9.0",
+ "pc-i440fx-9.1",
+ "pc-i440fx-9.2",
+ "pc-q35-10.0",
+ "pc-q35-10.1",
+ "pc-q35-10.2",
+ "pc-q35-11.0",
+ "pc-q35-11.1",
+ "pc-q35-11.2",
+ "pc-q35-6.0",
+ "pc-q35-6.1",
+ "pc-q35-6.2",
+ "pc-q35-7.0",
+ "pc-q35-7.1",
+ "pc-q35-7.2",
+ "pc-q35-8.0",
+ "pc-q35-8.1",
+ "pc-q35-8.2",
+ "pc-q35-9.0",
+ "pc-q35-9.1",
+ "pc-q35-9.2",
+};
+
+static const char * const loongarch64_machines[] = {
+ "none",
+ "virt-11.1",
+ "virt-11.2",
+};
+
+static const char * const m68k_machines[] = {
+ "an5206",
+ "mcf5208evb",
+ "next-cube",
+ "none",
+ "q800",
+ "virt-10.0",
+ "virt-10.1",
+ "virt-10.2",
+ "virt-11.0",
+ "virt-11.1",
+ "virt-11.2",
+ "virt-6.0",
+ "virt-6.1",
+ "virt-6.2",
+ "virt-7.0",
+ "virt-7.1",
+ "virt-7.2",
+ "virt-8.0",
+ "virt-8.1",
+ "virt-8.2",
+ "virt-9.0",
+ "virt-9.1",
+ "virt-9.2",
+};
+
+static const char * const microblaze_machines[] = {
+ "none",
+ "petalogix-ml605",
+ "petalogix-s3adsp1800",
+ "xlnx-zynqmp-pmu",
+};
+
+static const char * const mips_machines[] = {
+ "malta",
+ "none",
+};
+
+static const char * const mips64_machines[] = {
+ "magnum",
+ "malta",
+ "none",
+ "pica61",
+};
+
+static const char * const mips64el_machines[] = {
+ "boston",
+ "fuloong2e",
+ "loongson3-virt",
+ "magnum",
+ "malta",
+ "none",
+ "pica61",
+};
+
+static const char * const mipsel_machines[] = {
+ "malta",
+ "none",
+};
+
+static const char * const or1k_machines[] = {
+ "none",
+ "or1k-sim",
+ "virt",
+};
+
+static const char * const ppc_machines[] = {
+ "40p",
+ "amigaone",
+ "bamboo",
+ "g3beige",
+ "mac99",
+ "mpc8544ds",
+ "none",
+ "pegasos1",
+ "pegasos2",
+ "ppce500",
+ "ppe42_machine",
+ "sam460ex",
+ "virtex-ml507",
+};
+
+static const char * const ppc64_machines[] = {
+ "40p",
+ "amigaone",
+ "bamboo",
+ "g3beige",
+ "mac99",
+ "mpc8544ds",
+ "none",
+ "pegasos1",
+ "pegasos2",
+ "powernv10",
+ "powernv10-rainier",
+ "powernv11",
+ "powernv8",
+ "powernv9",
+ "ppce500",
+ "ppe42_machine",
+ "pseries-10.0",
+ "pseries-10.1",
+ "pseries-10.2",
+ "pseries-11.0",
+ "pseries-11.1",
+ "pseries-11.2",
+ "pseries-6.0",
+ "pseries-6.1",
+ "pseries-6.2",
+ "pseries-7.0",
+ "pseries-7.1",
+ "pseries-7.2",
+ "pseries-8.0",
+ "pseries-8.1",
+ "pseries-8.2",
+ "pseries-9.0",
+ "pseries-9.1",
+ "pseries-9.2",
+ "sam460ex",
+ "virtex-ml507",
+};
+
+static const char * const riscv32_machines[] = {
+ "amd-microblaze-v-generic",
+ "none",
+ "opentitan",
+ "sifive_e",
+ "sifive_u",
+ "spike",
+ "virt",
+};
+
+static const char * const riscv64_machines[] = {
+ "amd-microblaze-v-generic",
+ "boston-aia",
+ "k230",
+ "microchip-icicle-kit",
+ "none",
+ "shakti_c",
+ "sifive_e",
+ "sifive_u",
+ "spike",
+ "tt-atlantis",
+ "virt",
+ "xiangshan-kunminghu",
+};
+
+static const char * const rx_machines[] = {
+ "gdbsim-r5f562n7",
+ "gdbsim-r5f562n8",
+ "none",
+};
+
+static const char * const s390x_machines[] = {
+ "none",
+ "s390-ccw-virtio-10.0",
+ "s390-ccw-virtio-10.1",
+ "s390-ccw-virtio-10.2",
+ "s390-ccw-virtio-11.0",
+ "s390-ccw-virtio-11.1",
+ "s390-ccw-virtio-11.2",
+ "s390-ccw-virtio-6.0",
+ "s390-ccw-virtio-6.1",
+ "s390-ccw-virtio-6.2",
+ "s390-ccw-virtio-7.0",
+ "s390-ccw-virtio-7.1",
+ "s390-ccw-virtio-7.2",
+ "s390-ccw-virtio-8.0",
+ "s390-ccw-virtio-8.1",
+ "s390-ccw-virtio-8.2",
+ "s390-ccw-virtio-9.0",
+ "s390-ccw-virtio-9.1",
+ "s390-ccw-virtio-9.2",
+};
+
+static const char * const sh4_machines[] = {
+ "none",
+ "r2d",
+};
+
+static const char * const sh4eb_machines[] = {
+ "none",
+ "r2d",
+};
+
+static const char * const sparc_machines[] = {
+ "LX",
+ "SPARCClassic",
+ "SPARCbook",
+ "SS-10",
+ "SS-20",
+ "SS-4",
+ "SS-5",
+ "SS-600MP",
+ "Voyager",
+ "leon3_generic",
+ "none",
+};
+
+static const char * const sparc64_machines[] = {
+ "niagara",
+ "none",
+ "sun4u",
+ "sun4v",
+};
+
+static const char * const tricore_machines[] = {
+ "KIT_AURIX_TC277_TRB",
+ "none",
+ "tricore_testboard",
+};
+
+static const char * const x86_64_machines[] = {
+ "isapc",
+ "microvm",
+ "none",
+ "pc-i440fx-10.0",
+ "pc-i440fx-10.1",
+ "pc-i440fx-10.2",
+ "pc-i440fx-11.0",
+ "pc-i440fx-11.1",
+ "pc-i440fx-11.2",
+ "pc-i440fx-6.0",
+ "pc-i440fx-6.1",
+ "pc-i440fx-6.2",
+ "pc-i440fx-7.0",
+ "pc-i440fx-7.1",
+ "pc-i440fx-7.2",
+ "pc-i440fx-8.0",
+ "pc-i440fx-8.1",
+ "pc-i440fx-8.2",
+ "pc-i440fx-9.0",
+ "pc-i440fx-9.1",
+ "pc-i440fx-9.2",
+ "pc-q35-10.0",
+ "pc-q35-10.1",
+ "pc-q35-10.2",
+ "pc-q35-11.0",
+ "pc-q35-11.1",
+ "pc-q35-11.2",
+ "pc-q35-6.0",
+ "pc-q35-6.1",
+ "pc-q35-6.2",
+ "pc-q35-7.0",
+ "pc-q35-7.1",
+ "pc-q35-7.2",
+ "pc-q35-8.0",
+ "pc-q35-8.1",
+ "pc-q35-8.2",
+ "pc-q35-9.0",
+ "pc-q35-9.1",
+ "pc-q35-9.2",
+};
+
+static const char * const xtensa_machines[] = {
+ "kc705",
+ "kc705-nommu",
+ "lx200",
+ "lx200-nommu",
+ "lx60",
+ "lx60-nommu",
+ "ml605",
+ "ml605-nommu",
+ "none",
+ "sim",
+ "virt",
+};
+
+static const char * const xtensaeb_machines[] = {
+ "kc705",
+ "kc705-nommu",
+ "lx200",
+ "lx200-nommu",
+ "lx60",
+ "lx60-nommu",
+ "ml605",
+ "ml605-nommu",
+ "none",
+ "sim",
+ "virt",
+};
+
+static const struct ShippedTarget {
+ const char *name;
+ const char *arch;
+ const char *endianness;
+ const char * const *machines;
+ size_t n_machines;
+} shipped_targets[] = {
+ { "aarch64", "aarch64", "little",
+ aarch64_machines, G_N_ELEMENTS(aarch64_machines) },
+ { "alpha", "alpha", "little",
+ alpha_machines, G_N_ELEMENTS(alpha_machines) },
+ { "arm", "arm", "little",
+ arm_machines, G_N_ELEMENTS(arm_machines) },
+ { "avr", "avr", "little",
+ avr_machines, G_N_ELEMENTS(avr_machines) },
+ { "hexagon", "hexagon", "little",
+ hexagon_machines, G_N_ELEMENTS(hexagon_machines) },
+ { "hppa", "hppa", "big",
+ hppa_machines, G_N_ELEMENTS(hppa_machines) },
+ { "i386", "i386", "little",
+ i386_machines, G_N_ELEMENTS(i386_machines) },
+ { "loongarch64", "loongarch64", "little",
+ loongarch64_machines, G_N_ELEMENTS(loongarch64_machines) },
+ { "m68k", "m68k", "big",
+ m68k_machines, G_N_ELEMENTS(m68k_machines) },
+ { "microblaze", "microblaze", "big",
+ microblaze_machines, G_N_ELEMENTS(microblaze_machines) },
+ { "mips", "mips", "big",
+ mips_machines, G_N_ELEMENTS(mips_machines) },
+ { "mips64", "mips64", "big",
+ mips64_machines, G_N_ELEMENTS(mips64_machines) },
+ { "mips64el", "mips64", "little",
+ mips64el_machines, G_N_ELEMENTS(mips64el_machines) },
+ { "mipsel", "mips", "little",
+ mipsel_machines, G_N_ELEMENTS(mipsel_machines) },
+ { "or1k", "or1k", "big",
+ or1k_machines, G_N_ELEMENTS(or1k_machines) },
+ { "ppc", "ppc", "big",
+ ppc_machines, G_N_ELEMENTS(ppc_machines) },
+ { "ppc64", "ppc64", "big",
+ ppc64_machines, G_N_ELEMENTS(ppc64_machines) },
+ { "riscv32", "riscv32", "little",
+ riscv32_machines, G_N_ELEMENTS(riscv32_machines) },
+ { "riscv64", "riscv64", "little",
+ riscv64_machines, G_N_ELEMENTS(riscv64_machines) },
+ { "rx", "rx", "little",
+ rx_machines, G_N_ELEMENTS(rx_machines) },
+ { "s390x", "s390x", "big",
+ s390x_machines, G_N_ELEMENTS(s390x_machines) },
+ { "sh4", "sh4", "little",
+ sh4_machines, G_N_ELEMENTS(sh4_machines) },
+ { "sh4eb", "sh4", "big",
+ sh4eb_machines, G_N_ELEMENTS(sh4eb_machines) },
+ { "sparc", "sparc", "big",
+ sparc_machines, G_N_ELEMENTS(sparc_machines) },
+ { "sparc64", "sparc64", "big",
+ sparc64_machines, G_N_ELEMENTS(sparc64_machines) },
+ { "tricore", "tricore", "little",
+ tricore_machines, G_N_ELEMENTS(tricore_machines) },
+ { "x86_64", "x86_64", "little",
+ x86_64_machines, G_N_ELEMENTS(x86_64_machines) },
+ { "xtensa", "xtensa", "little",
+ xtensa_machines, G_N_ELEMENTS(xtensa_machines) },
+ { "xtensaeb", "xtensa", "big",
+ xtensaeb_machines, G_N_ELEMENTS(xtensaeb_machines) },
+};
+
+/*
+ * Machines omitted from the normal lists. Merged in when @accel is
+ * present (NULL means no accel check) and the host matches (NULL
+ * host_os or host_cpu means any). xenfv is an alias of xenfv-4.2.
+ * aarch64 HVF (vmapple) is built only on an aarch64 Darwin host.
+ * nitro is Linux-only, on x86_64-softmmu for an x86_64 host and
+ * aarch64-softmmu for an aarch64 host. x-remote follows KVM on Linux
+ * when host_cpu is the host that builds KVM for that target.
+ */
+static const char * const xen_pc_machines[] = {
+ "xenpv",
+ "xenpvh",
+ "xenfv-4.2",
+};
+
+static const char * const xen_aarch64_machines[] = {
+ "xenpvh",
+};
+
+static const char * const hvf_aarch64_machines[] = {
+ "vmapple",
+};
+
+static const char * const nitro_machines[] = {
+ "nitro",
+};
+
+static const char * const x_remote_machines[] = {
+ "x-remote",
+};
+
+static const struct SpecialMachineMap {
+ const char *target;
+ const char *accel;
+ const char *host_os;
+ const char *host_cpu;
+ const char * const *machines;
+ size_t n_machines;
+} special_machine_map[] = {
+ { "i386", "xen", NULL, "x86_64",
+ xen_pc_machines, G_N_ELEMENTS(xen_pc_machines) },
+ { "i386", "xen", NULL, "aarch64",
+ xen_pc_machines, G_N_ELEMENTS(xen_pc_machines) },
+ { "x86_64", "xen", NULL, "x86_64",
+ xen_pc_machines, G_N_ELEMENTS(xen_pc_machines) },
+ { "x86_64", "xen", NULL, "aarch64",
+ xen_pc_machines, G_N_ELEMENTS(xen_pc_machines) },
+ { "aarch64", "xen", NULL, "aarch64",
+ xen_aarch64_machines, G_N_ELEMENTS(xen_aarch64_machines) },
+ { "aarch64", "hvf", "darwin", "aarch64",
+ hvf_aarch64_machines, G_N_ELEMENTS(hvf_aarch64_machines) },
+ { "x86_64", NULL, "linux", "x86_64",
+ nitro_machines, G_N_ELEMENTS(nitro_machines) },
+ { "aarch64", NULL, "linux", "aarch64",
+ nitro_machines, G_N_ELEMENTS(nitro_machines) },
+ { "i386", "kvm", "linux", "x86_64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "x86_64", "kvm", "linux", "x86_64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "aarch64", "kvm", "linux", "aarch64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "ppc", "kvm", "linux", "ppc64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "ppc64", "kvm", "linux", "ppc64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "s390x", "kvm", "linux", "s390x",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "riscv64", "kvm", "linux", "riscv64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+ { "loongarch64", "kvm", "linux", "loongarch64",
+ x_remote_machines, G_N_ELEMENTS(x_remote_machines) },
+};
+
+static const struct ShippedTarget *lookup_shipped_target(const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < G_N_ELEMENTS(shipped_targets); i++) {
+ if (!strcmp(shipped_targets[i].name, name)) {
+ return &shipped_targets[i];
+ }
+ }
+ return NULL;
+}
+
+static bool have_xen;
+static bool have_hvf;
+static bool have_kvm;
+
+static const char *host_cpu(void)
+{
+#if defined(__aarch64__) || defined(_M_ARM64)
+ return "aarch64";
+#elif defined(__x86_64__) || defined(_M_X64)
+ return "x86_64";
+#elif defined(__powerpc64__)
+ return "ppc64";
+#elif defined(__s390x__)
+ return "s390x";
+#elif defined(__riscv) && __riscv_xlen == 64
+ return "riscv64";
+#elif defined(__loongarch64)
+ return "loongarch64";
+#else
+ return "other";
+#endif
+}
+
+static bool host_os_matches(const char *host_os)
+{
+ if (!host_os) {
+ return true;
+ }
+#if defined(CONFIG_LINUX)
+ return !strcmp(host_os, "linux");
+#elif defined(CONFIG_DARWIN)
+ return !strcmp(host_os, "darwin");
+#else
+ return false;
+#endif
+}
+
+static bool accel_present(const char *accel)
+{
+ if (!accel) {
+ return true;
+ }
+ if (!strcmp(accel, "xen")) {
+ return have_xen;
+ }
+ if (!strcmp(accel, "hvf")) {
+ return have_hvf;
+ }
+ if (!strcmp(accel, "kvm")) {
+ return have_kvm;
+ }
+ return false;
+}
+
+static bool host_cpu_matches(const char *want)
+{
+ if (!want) {
+ return true;
+ }
+ return !strcmp(want, host_cpu());
+}
+
+static bool special_applies(const struct SpecialMachineMap *s,
+ const char *target)
+{
+ return !strcmp(s->target, target) &&
+ accel_present(s->accel) &&
+ host_os_matches(s->host_os) &&
+ host_cpu_matches(s->host_cpu);
+}
+
+static void assert_name_list(QList *names, const char *target,
+ const char * const *expect, size_t n_expect)
+{
+ GHashTable *got = g_hash_table_new(g_str_hash, g_str_equal);
+ GHashTable *want = g_hash_table_new(g_str_hash, g_str_equal);
+ const QListEntry *e;
+ GHashTableIter iter;
+ gpointer key;
+ size_t i;
+
+ g_assert_nonnull(names);
+ for (e = qlist_first(names); e; e = qlist_next(e)) {
+ QString *qs = qobject_to(QString, qlist_entry_obj(e));
+
+ g_assert_nonnull(qs);
+ g_hash_table_add(got, (gpointer)qstring_get_str(qs));
+ }
+ for (i = 0; i < n_expect; i++) {
+ g_hash_table_add(want, (gpointer)expect[i]);
+ }
+ for (i = 0; i < G_N_ELEMENTS(special_machine_map); i++) {
+ const struct SpecialMachineMap *s = &special_machine_map[i];
+ size_t j;
+
+ if (!special_applies(s, target)) {
+ continue;
+ }
+ for (j = 0; j < s->n_machines; j++) {
+ g_hash_table_add(want, (gpointer)s->machines[j]);
+ }
+ }
+ g_hash_table_iter_init(&iter, got);
+ while (g_hash_table_iter_next(&iter, &key, NULL)) {
+ if (!g_hash_table_contains(want, key)) {
+ g_printerr("unexpected machine: %s\n", (const char *)key);
+ }
+ }
+ g_hash_table_iter_init(&iter, want);
+ while (g_hash_table_iter_next(&iter, &key, NULL)) {
+ if (!g_hash_table_contains(got, key)) {
+ g_printerr("missing machine: %s\n", (const char *)key);
+ }
+ }
+ g_assert_cmpuint(g_hash_table_size(got), ==, g_hash_table_size(want));
+ g_hash_table_unref(got);
+ g_hash_table_unref(want);
+}
+
+static void read_accel_flags(QTestState *qts)
+{
+ QDict *resp;
+ QDict *ret;
+ QList *present;
+ const QListEntry *e;
+
+ have_xen = false;
+ have_hvf = false;
+ have_kvm = false;
+ resp = qtest_qmp(qts, "{'execute': 'query-accelerators'}");
+ g_assert(qdict_haskey(resp, "return"));
+ ret = qdict_get_qdict(resp, "return");
+ present = qdict_get_qlist(ret, "present");
+ g_assert_nonnull(present);
+ for (e = qlist_first(present); e; e = qlist_next(e)) {
+ QString *qs = qobject_to(QString, qlist_entry_obj(e));
+ const char *name;
+
+ g_assert_nonnull(qs);
+ name = qstring_get_str(qs);
+ if (!strcmp(name, "xen")) {
+ have_xen = true;
+ } else if (!strcmp(name, "hvf")) {
+ have_hvf = true;
+ } else if (!strcmp(name, "kvm")) {
+ have_kvm = true;
+ }
+ }
+ qobject_unref(resp);
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 33f58b0e95c..8c53bb2e30e 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -23,6 +23,7 @@ qtests_generic = [
'cdrom-test',
'device-introspect-test',
'machine-none-test',
+ 'machine-list-test',
'qmp-test',
'qmp-cmd-test',
'qom-test',
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 09/55] kconfig: rename REGISTER to HW_REGISTER
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (7 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 08/55] tests/qtest: prepare machine-list-test for combined qemu-system Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 10/55] target-info: add TargetKconfig Yonggang Luo
` (45 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Rename config REGISTER to HW_REGISTER. register is a C keyword, and a
later TargetKconfig commit will use it as a struct member.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/Kconfig | 2 +-
hw/core/Kconfig | 2 +-
hw/core/meson.build | 2 +-
hw/dma/Kconfig | 4 ++--
hw/i2c/Kconfig | 2 +-
hw/usb/Kconfig | 2 +-
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/hw/Kconfig b/hw/Kconfig
index c92ca2b13a3..94f963f2944 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -85,7 +85,7 @@ config XILINX_AXI
config XLNX_ZYNQMP
bool
- select REGISTER
+ select HW_REGISTER
select CAN_BUS
select PTIMER
select XLNX_BBRAM
diff --git a/hw/core/Kconfig b/hw/core/Kconfig
index d1bdf765ee8..839e249b9d0 100644
--- a/hw/core/Kconfig
+++ b/hw/core/Kconfig
@@ -29,7 +29,7 @@ config PLATFORM_BUS
bool
depends on DEVICE_TREE
-config REGISTER
+config HW_REGISTER
bool
config SPLIT_IRQ
diff --git a/hw/core/meson.build b/hw/core/meson.build
index 8fe776d2c86..1c645d7041d 100644
--- a/hw/core/meson.build
+++ b/hw/core/meson.build
@@ -21,7 +21,7 @@ system_ss.add(when: 'CONFIG_GUEST_LOADER', if_true: files('guest-loader.c'))
system_ss.add(when: 'CONFIG_OR_IRQ', if_true: files('or-irq.c'))
system_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('platform-bus.c'))
system_ss.add(when: 'CONFIG_PTIMER', if_true: files('ptimer.c'))
-system_ss.add(when: 'CONFIG_REGISTER', if_true: files('register.c'))
+system_ss.add(when: 'CONFIG_HW_REGISTER', if_true: files('register.c'))
system_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c'))
system_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c'))
system_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig
index 0a23e7d7b87..8f221b20634 100644
--- a/hw/dma/Kconfig
+++ b/hw/dma/Kconfig
@@ -16,7 +16,7 @@ config I8257
config ZYNQ_DEVCFG
bool
- select REGISTER
+ select HW_REGISTER
config XLNX_ZDMA
bool
@@ -29,7 +29,7 @@ config SIFIVE_PDMA
config XLNX_CSU_DMA
bool
- select REGISTER
+ select HW_REGISTER
config K230_GSDMA
bool
\ No newline at end of file
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
index 0766130b596..3482f475cf9 100644
--- a/hw/i2c/Kconfig
+++ b/hw/i2c/Kconfig
@@ -20,7 +20,7 @@ config ARM_SBCON_I2C
config DESIGNWARE_I2C
bool
- select REGISTER
+ select HW_REGISTER
select I2C
config ACPI_SMBUS
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index e8c00f813a6..43771291a06 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -137,7 +137,7 @@ config IMX_USBPHY
config USB_DWC3
bool
select USB_XHCI_SYSBUS
- select REGISTER
+ select HW_REGISTER
config XLNX_USB_SUBSYS
bool
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 10/55] target-info: add TargetKconfig
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (8 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 09/55] kconfig: rename REGISTER to HW_REGISTER Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 11/55] target-info: add target_is_* helpers for each architecture Yonggang Luo
` (44 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Add a packed TargetKconfig of device and accel CONFIG_* bits,
generated from the Kconfig tree, and attach it to TargetInfo.
target_kconfig() returns the current bits, and
target_has_kconfig_<name>() tests them. Initialize
target_info_stub.kconfig from CONFIG_DEVICES.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info-def.h | 2 +
include/qemu/target-kconfig-has.h | 7 ++
include/qemu/target-kconfig.h | 34 ++++++
meson.build | 14 +++
scripts/gen-target-kconfig.py | 162 +++++++++++++++++++++++++++
target-info-def.c | 6 +
target-kconfig.c | 20 ++++
tests/unit/meson.build | 1 +
tests/unit/test-target-kconfig-has.c | 22 ++++
9 files changed, 268 insertions(+)
create mode 100644 include/qemu/target-kconfig-has.h
create mode 100644 include/qemu/target-kconfig.h
create mode 100644 scripts/gen-target-kconfig.py
create mode 100644 target-kconfig.c
create mode 100644 tests/unit/test-target-kconfig-has.c
diff --git a/include/qemu/target-info-def.h b/include/qemu/target-info-def.h
index 080e30a5b0e..ae6374583a7 100644
--- a/include/qemu/target-info-def.h
+++ b/include/qemu/target-info-def.h
@@ -13,6 +13,7 @@
#include "qapi/qapi-types-machine.h"
#include "qemu/queue.h"
#include "qemu/target-info.h"
+#include "qemu/target-kconfig.h"
struct TargetInfo {
/* runtime equivalent of TARGET_NAME definition */
@@ -32,6 +33,7 @@ struct TargetInfo {
unsigned page_bits_init;
/* runtime equivalent of TARGET_PAGE_BITS_VARY definition */
bool page_bits_vary;
+ TargetKconfig kconfig;
};
typedef struct TargetInfoNode TargetInfoNode;
diff --git a/include/qemu/target-kconfig-has.h b/include/qemu/target-kconfig-has.h
new file mode 100644
index 00000000000..6616f75845a
--- /dev/null
+++ b/include/qemu/target-kconfig-has.h
@@ -0,0 +1,7 @@
+/*
+ * QEMU target_has_kconfig_* helpers
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "target-kconfig-has-gen.h"
diff --git a/include/qemu/target-kconfig.h b/include/qemu/target-kconfig.h
new file mode 100644
index 00000000000..21b2ba576ec
--- /dev/null
+++ b/include/qemu/target-kconfig.h
@@ -0,0 +1,34 @@
+/*
+ * QEMU target kconfig API
+ *
+ * Copyright (c) Yonggang Luo
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_TARGET_KCONFIG_H
+#define QEMU_TARGET_KCONFIG_H
+
+#include "qemu/compiler.h"
+
+/**
+ * struct TargetKconfig:
+ *
+ * Compile-time device and accel CONFIG_* bits. Not Kconfig.host
+ * or target/Kconfig. Target identity is TargetInfo, not these
+ * bits. Not kvm_enabled() etc. Fields and
+ * target_has_kconfig_<name>() are generated by
+ * scripts/gen-target-kconfig.py.
+ */
+typedef struct TargetKconfig {
+#include "target-kconfig-fields.h"
+} QEMU_PACKED TargetKconfig;
+
+/**
+ * target_kconfig:
+ *
+ * Returns: The current TargetKconfig (target_info()->kconfig).
+ */
+const TargetKconfig *target_kconfig(void);
+
+#endif
diff --git a/meson.build b/meson.build
index 93237429713..9485f4e97be 100644
--- a/meson.build
+++ b/meson.build
@@ -3444,6 +3444,19 @@ genh += custom_target('config-poison.h',
capture: true,
command: [find_program('scripts/make-config-poison.sh'),
target_configs_h])
+genh += custom_target('target-kconfig',
+ output: ['target-kconfig-fields.h',
+ 'target-kconfig-init.h',
+ 'target-kconfig-has-gen.h',
+ 'target-kconfig-has.c.inc'],
+ depfile: 'target-kconfig.d',
+ command: [python, files('scripts/gen-target-kconfig.py'),
+ '--kconfig', meson.current_source_dir() / 'Kconfig',
+ '--depfile', '@DEPFILE@',
+ '--fields', '@OUTPUT0@',
+ '--init', '@OUTPUT1@',
+ '--has', '@OUTPUT2@',
+ '--has-c', '@OUTPUT3@'])
if fdt_required.length() > 0
error('fdt disabled but required by targets ' + ', '.join(fdt_required))
@@ -3778,6 +3791,7 @@ endif
qom_ss.add(files(
'target-info.c',
+ 'target-kconfig.c',
))
qom_ss = qom_ss.apply({})
libqom = static_library('qom', qom_ss.sources() + genh,
diff --git a/scripts/gen-target-kconfig.py b/scripts/gen-target-kconfig.py
new file mode 100644
index 00000000000..afeffc75ca0
--- /dev/null
+++ b/scripts/gen-target-kconfig.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+"""Generate TargetKconfig CONFIG_* field, initializer, and has headers.
+
+The field list is every `config FOO` from the QEMU Kconfig tree,
+parsed with scripts/minikconf.py (including accel/Kconfig: KVM,
+XEN, HVF, TCG, ...). Host proxies in Kconfig.host and the
+target/Kconfig tree (arch tokens and TARGET_BIG_ENDIAN) are
+omitted. Target identity is TargetInfo, not TargetKconfig.
+
+Each field also gets target_has_kconfig_<name>(const TargetInfo *).
+"""
+
+import argparse
+import os
+import sys
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from minikconf import KconfigData, KconfigParser
+
+
+def field_name(config: str) -> str:
+ return config[len("CONFIG_"):].lower()
+
+
+def collect_from_kconfig(root: str) -> tuple[set[str], list[str]]:
+ data = KconfigData()
+ with open(root, "rt", encoding="utf-8") as fp:
+ KconfigParser.parse(fp, data)
+ names = {"CONFIG_" + name for name in data.defined_vars}
+ return names, list(data.previously_included)
+
+
+def collect_kconfig_names(path: str) -> set[str]:
+ data = KconfigData()
+ with open(path, "rt", encoding="utf-8") as fp:
+ KconfigParser.parse(fp, data)
+ return {"CONFIG_" + name for name in data.defined_vars}
+
+
+def collect_host_kconfig_names(kconfig_root: str) -> set[str]:
+ host = os.path.join(os.path.dirname(os.path.abspath(kconfig_root)),
+ "Kconfig.host")
+ return collect_kconfig_names(host)
+
+
+def collect_target_kconfig_names(kconfig_root: str) -> set[str]:
+ target = os.path.join(os.path.dirname(os.path.abspath(kconfig_root)),
+ "target", "Kconfig")
+ return collect_kconfig_names(target)
+
+
+def write_fields(path: str, configs: list[str]) -> None:
+ lines = [
+ "/* Generated by scripts/gen-target-kconfig.py. Do not edit. */",
+ "",
+ ]
+ for name in configs:
+ lines.append(f" uint32_t {field_name(name)} : 1;")
+ lines.append("")
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
+ fh.write("\n".join(lines))
+
+
+def write_init(path: str, configs: list[str]) -> None:
+ lines = [
+ "/* Generated by scripts/gen-target-kconfig.py. Do not edit. */",
+ "",
+ ]
+ for name in configs:
+ field = field_name(name)
+ lines.append(f"#if defined({name})")
+ lines.append(f" .{field} = true,")
+ lines.append("#endif")
+ lines.append("")
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
+ fh.write("\n".join(lines))
+
+
+def has_fn(config: str) -> str:
+ return "target_has_kconfig_" + field_name(config)
+
+
+def write_has_h(path: str, configs: list[str]) -> None:
+ lines = [
+ "/* Generated by scripts/gen-target-kconfig.py. Do not edit. */",
+ "",
+ "#ifndef TARGET_KCONFIG_HAS_GEN_H",
+ "#define TARGET_KCONFIG_HAS_GEN_H",
+ "",
+ "#include <stdbool.h>",
+ "",
+ "typedef struct TargetInfo TargetInfo;",
+ "",
+ ]
+ for name in configs:
+ lines.append(f"bool {has_fn(name)}(const TargetInfo *ti);")
+ lines.append("")
+ lines.append("#endif")
+ lines.append("")
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
+ fh.write("\n".join(lines))
+
+
+def write_has_c(path: str, configs: list[str]) -> None:
+ lines = [
+ "/* Generated by scripts/gen-target-kconfig.py. Do not edit. */",
+ "",
+ ]
+ for name in configs:
+ fn = has_fn(name)
+ field = field_name(name)
+ lines.append(f"bool {fn}(const TargetInfo *ti)")
+ lines.append("{")
+ lines.append(f" return ti->kconfig.{field};")
+ lines.append("}")
+ lines.append("")
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
+ fh.write("\n".join(lines))
+
+
+def write_depfile(path: str, outputs: list[str], deps: list[str]) -> None:
+ lines = [" ".join(outputs) + ":" ]
+ for dep in deps:
+ lines.append(f" {dep} \\")
+ if len(lines) > 1:
+ lines[-1] = lines[-1][:-2]
+ lines.append("")
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
+ fh.write("\n".join(lines))
+
+
+def main(argv: list[str]) -> int:
+ parser = argparse.ArgumentParser(
+ description="Generate TargetKconfig CONFIG_* include headers"
+ )
+ parser.add_argument("--fields", required=True, help="output fields header")
+ parser.add_argument("--init", required=True, help="output initializer header")
+ parser.add_argument("--has", required=True, help="output has-function header")
+ parser.add_argument("--has-c", required=True, help="output has-function bodies")
+ parser.add_argument("--kconfig", required=True, help="root Kconfig")
+ parser.add_argument("--depfile", help="ninja depfile of walked Kconfig files")
+ args = parser.parse_args(argv)
+
+ names, kconfig_files = collect_from_kconfig(args.kconfig)
+ names -= collect_host_kconfig_names(args.kconfig)
+ names -= collect_target_kconfig_names(args.kconfig)
+ configs = sorted(names)
+
+ write_fields(args.fields, configs)
+ write_init(args.init, configs)
+ write_has_h(args.has, configs)
+ write_has_c(args.has_c, configs)
+ if args.depfile:
+ write_depfile(args.depfile,
+ [args.fields, args.init, args.has, args.has_c],
+ kconfig_files)
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/target-info-def.c b/target-info-def.c
index 3041d64ccd2..c02d98e6875 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -7,6 +7,9 @@
*/
#include "qemu/osdep.h"
+#ifdef CONFIG_DEVICES
+#include CONFIG_DEVICES
+#endif
#include "qemu/target-info.h"
#include "qemu/target-info-def.h"
#include "hw/core/boards.h"
@@ -38,6 +41,9 @@ static const TargetInfo target_info_stub = {
.page_bits_vary = false,
.page_bits_init = TARGET_PAGE_BITS,
#endif
+ .kconfig = {
+#include "target-kconfig-init.h"
+ },
};
target_info_init(target_info_stub)
diff --git a/target-kconfig.c b/target-kconfig.c
new file mode 100644
index 00000000000..078c0d8e7f3
--- /dev/null
+++ b/target-kconfig.c
@@ -0,0 +1,20 @@
+/*
+ * QEMU target kconfig helpers
+ *
+ * Copyright (c) Yonggang Luo
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-info.h"
+#include "qemu/target-info-def.h"
+#include "qemu/target-kconfig.h"
+#include "qemu/target-kconfig-has.h"
+
+const TargetKconfig *target_kconfig(void)
+{
+ return &target_info()->kconfig;
+}
+
+#include "target-kconfig-has.c.inc"
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index dc980a35955..c806dbc4ffa 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -47,6 +47,7 @@ tests = {
objects: target_info_def_objects.values(),
compile_args: ['-DTARGET_INFO_DEF_COUNT=@0@'.format(
target_info_def_objects.values().length())])],
+ 'test-target-kconfig-has': [qom],
'test-qemu-opts': [],
'test-keyval': [testqapi],
'test-logging': [],
diff --git a/tests/unit/test-target-kconfig-has.c b/tests/unit/test-target-kconfig-has.c
new file mode 100644
index 00000000000..289ed89b854
--- /dev/null
+++ b/tests/unit/test-target-kconfig-has.c
@@ -0,0 +1,22 @@
+/*
+ * target-kconfig-has.h include path test
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-kconfig-has.h"
+
+static void test_include(void)
+{
+ bool (*fn)(const TargetInfo *ti) = target_has_kconfig_tcg;
+
+ g_assert_nonnull(fn);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/target-kconfig-has/include", test_include);
+ return g_test_run();
+}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 11/55] target-info: add target_is_* helpers for each architecture
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (9 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 10/55] target-info: add TargetKconfig Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 12/55] target-info: add target_is_any() Yonggang Luo
` (43 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
This is added for latter use with is_available.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info.h | 91 +++++++++++++++++++++++++++++++++++++-
target-info.c | 83 +++++++++++++++++++++++++++++-----
2 files changed, 161 insertions(+), 13 deletions(-)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index c48973f20be..89656da1ca4 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -53,6 +53,14 @@ const char *target_cpu_type(void);
*/
bool target_big_endian(void);
+/**
+ * target_is_base_arm:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is ARM or Aarch64.
+ */
+bool target_is_base_arm(const TargetInfo *ti);
+
/**
* target_base_arm:
*
@@ -60,6 +68,14 @@ bool target_big_endian(void);
*/
bool target_base_arm(void);
+/**
+ * target_is_arm:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is ARM (32-bit, not Aarch64).
+ */
+bool target_is_arm(const TargetInfo *ti);
+
/**
* target_arm:
*
@@ -67,6 +83,14 @@ bool target_base_arm(void);
*/
bool target_arm(void);
+/**
+ * target_is_aarch64:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is Aarch64.
+ */
+bool target_is_aarch64(const TargetInfo *ti);
+
/**
* target_aarch64:
*
@@ -74,6 +98,14 @@ bool target_arm(void);
*/
bool target_aarch64(void);
+/**
+ * target_is_base_ppc:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is PowerPC 32-bit or 64-bit.
+ */
+bool target_is_base_ppc(const TargetInfo *ti);
+
/**
* target_base_ppc:
*
@@ -81,6 +113,14 @@ bool target_aarch64(void);
*/
bool target_base_ppc(void);
+/**
+ * target_is_ppc:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is PowerPC 32-bit.
+ */
+bool target_is_ppc(const TargetInfo *ti);
+
/**
* target_ppc:
*
@@ -88,6 +128,14 @@ bool target_base_ppc(void);
*/
bool target_ppc(void);
+/**
+ * target_is_ppc64:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is PowerPC 64-bit.
+ */
+bool target_is_ppc64(const TargetInfo *ti);
+
/**
* target_ppc64:
*
@@ -95,6 +143,14 @@ bool target_ppc(void);
*/
bool target_ppc64(void);
+/**
+ * target_is_s390x:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is S390x.
+ */
+bool target_is_s390x(const TargetInfo *ti);
+
/**
* target_s390x:
*
@@ -102,17 +158,48 @@ bool target_ppc64(void);
*/
bool target_s390x(void);
+/**
+ * target_is_base_riscv:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is RISC-V 32-bit or 64-bit.
+ */
+bool target_is_base_riscv(const TargetInfo *ti);
+
+/**
+ * target_base_riscv:
+ *
+ * Returns whether the target architecture is RISC-V 32-bit or 64-bit.
+ */
+bool target_base_riscv(void);
+
+/**
+ * target_is_riscv32:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is RISC-V 32-bit.
+ */
+bool target_is_riscv32(const TargetInfo *ti);
+
/**
* target_riscv32:
*
- * Returns whether the target architecture is riscv32
+ * Returns whether the target architecture is RISC-V 32-bit.
*/
bool target_riscv32(void);
+/**
+ * target_is_riscv64:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is RISC-V 64-bit.
+ */
+bool target_is_riscv64(const TargetInfo *ti);
+
/**
* target_riscv64:
*
- * Returns whether the target architecture is riscv64
+ * Returns whether the target architecture is RISC-V 64-bit.
*/
bool target_riscv64(void);
diff --git a/target-info.c b/target-info.c
index 6e66f48e1ff..6d57cad5d33 100644
--- a/target-info.c
+++ b/target-info.c
@@ -96,9 +96,9 @@ bool target_big_endian(void)
return target_endian_mode() == ENDIAN_MODE_BIG;
}
-bool target_base_arm(void)
+bool target_is_base_arm(const TargetInfo *ti)
{
- switch (target_arch()) {
+ switch (ti->target_arch) {
case SYS_EMU_TARGET_ARM:
case SYS_EMU_TARGET_AARCH64:
return true;
@@ -107,19 +107,34 @@ bool target_base_arm(void)
}
}
+bool target_base_arm(void)
+{
+ return target_is_base_arm(target_info());
+}
+
+bool target_is_arm(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_ARM;
+}
+
bool target_arm(void)
{
- return target_arch() == SYS_EMU_TARGET_ARM;
+ return target_is_arm(target_info());
+}
+
+bool target_is_aarch64(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_AARCH64;
}
bool target_aarch64(void)
{
- return target_arch() == SYS_EMU_TARGET_AARCH64;
+ return target_is_aarch64(target_info());
}
-bool target_base_ppc(void)
+bool target_is_base_ppc(const TargetInfo *ti)
{
- switch (target_arch()) {
+ switch (ti->target_arch) {
case SYS_EMU_TARGET_PPC:
case SYS_EMU_TARGET_PPC64:
return true;
@@ -128,27 +143,73 @@ bool target_base_ppc(void)
}
}
+bool target_base_ppc(void)
+{
+ return target_is_base_ppc(target_info());
+}
+
+bool target_is_ppc(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_PPC;
+}
+
bool target_ppc(void)
{
- return target_arch() == SYS_EMU_TARGET_PPC;
+ return target_is_ppc(target_info());
+}
+
+bool target_is_ppc64(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_PPC64;
}
bool target_ppc64(void)
{
- return target_arch() == SYS_EMU_TARGET_PPC64;
+ return target_is_ppc64(target_info());
+}
+
+bool target_is_s390x(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_S390X;
}
bool target_s390x(void)
{
- return target_arch() == SYS_EMU_TARGET_S390X;
+ return target_is_s390x(target_info());
+}
+
+bool target_is_base_riscv(const TargetInfo *ti)
+{
+ switch (ti->target_arch) {
+ case SYS_EMU_TARGET_RISCV32:
+ case SYS_EMU_TARGET_RISCV64:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool target_base_riscv(void)
+{
+ return target_is_base_riscv(target_info());
+}
+
+bool target_is_riscv32(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_RISCV32;
}
bool target_riscv32(void)
{
- return target_arch() == SYS_EMU_TARGET_RISCV32;
+ return target_is_riscv32(target_info());
+}
+
+bool target_is_riscv64(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_RISCV64;
}
bool target_riscv64(void)
{
- return target_arch() == SYS_EMU_TARGET_RISCV64;
+ return target_is_riscv64(target_info());
}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 12/55] target-info: add target_is_any()
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (10 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 11/55] target-info: add target_is_* helpers for each architecture Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 13/55] qom: pass TargetInfo to is_available for latter use Yonggang Luo
` (42 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
target_is_any() returns true for every TargetInfo. A type that is
not target-scoped can use it as TypeInfo.is_available.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info.h | 9 +++++++++
target-info.c | 6 ++++++
2 files changed, 15 insertions(+)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index 89656da1ca4..3bbe1d9b607 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -53,6 +53,15 @@ const char *target_cpu_type(void);
*/
bool target_big_endian(void);
+/**
+ * target_is_any:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns true for every TargetInfo. Usable as TypeInfo.is_available
+ * for types that are not target-scoped (TYPE_OBJECT).
+ */
+bool target_is_any(const TargetInfo *ti);
+
/**
* target_is_base_arm:
* @ti: TargetInfo to inspect
diff --git a/target-info.c b/target-info.c
index 6d57cad5d33..ad93a4b125e 100644
--- a/target-info.c
+++ b/target-info.c
@@ -96,6 +96,12 @@ bool target_big_endian(void)
return target_endian_mode() == ENDIAN_MODE_BIG;
}
+bool target_is_any(const TargetInfo *ti)
+{
+ (void)ti;
+ return true;
+}
+
bool target_is_base_arm(const TargetInfo *ti)
{
switch (ti->target_arch) {
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 13/55] qom: pass TargetInfo to is_available for latter use
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (11 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 12/55] target-info: add target_is_any() Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 14/55] target/arm: move kvm_arm_set_cpreg_mig_tolerances to kvm.c Yonggang Luo
` (41 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Change TypeInfo.is_available to TypeIsAvailable taking const TargetInfo *.
Store the callback on TypeImpl. object_class_get_is_available() returns
that callback, or target_is_any() when the class has none.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/aspeed_ast27x0-fc.c | 2 +-
hw/arm/aspeed_ast27x0_evb.c | 4 ++--
hw/arm/raspi.c | 4 ++--
hw/arm/raspi4b.c | 2 +-
include/qom/object.h | 26 +++++++++++++++++++++++---
qom/object.c | 14 +++++++++++++-
6 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c
index 73362b60d2a..8a7c6a116ac 100644
--- a/hw/arm/aspeed_ast27x0-fc.c
+++ b/hw/arm/aspeed_ast27x0-fc.c
@@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = {
.parent = TYPE_MACHINE,
.class_init = ast2700fc_class_init,
.instance_size = sizeof(Ast2700FCState),
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
},
};
diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c
index 460c9ff0d2e..02a8cff1d9d 100644
--- a/hw/arm/aspeed_ast27x0_evb.c
+++ b/hw/arm/aspeed_ast27x0_evb.c
@@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = {
.name = MACHINE_TYPE_NAME("ast2700a1-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_ast2700a1_evb_class_init,
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
},
{
.name = MACHINE_TYPE_NAME("ast2700a2-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_ast2700a2_evb_class_init,
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
}
};
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index fadbacb2534..22b06c6ca22 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = {
.name = MACHINE_TYPE_NAME("raspi3ap"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi3ap_machine_class_init,
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
}, {
.name = MACHINE_TYPE_NAME("raspi3b"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi3b_machine_class_init,
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
}, {
.name = TYPE_RASPI_MACHINE,
.parent = TYPE_RASPI_BASE_MACHINE,
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 566d64572db..a1dc477f25e 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = {
.parent = TYPE_RASPI_BASE_MACHINE,
.instance_size = sizeof(Raspi4bMachineState),
.class_init = raspi4b_machine_class_init,
- .is_available = target_aarch64,
+ .is_available = target_is_aarch64,
};
static void raspi4b_machine_register_type(void)
diff --git a/include/qom/object.h b/include/qom/object.h
index 4c0645817a5..3791f335fdb 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -16,6 +16,7 @@
#include "qapi/qapi-builtin-types.h"
#include "qemu/module.h"
+#include "qemu/target-info.h"
struct TypeImpl;
typedef struct TypeImpl *Type;
@@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj);
*/
typedef void (ObjectFree)(void *obj);
+/**
+ * typedef TypeIsAvailable:
+ * @ti: TargetInfo to test.
+ *
+ * Returns whether a type is available for @ti. Typical implementations
+ * are target_is_*().
+ */
+typedef bool (TypeIsAvailable)(const TargetInfo *ti);
+
#define OBJECT_CLASS_CAST_CACHE 4
/**
@@ -473,8 +483,10 @@ struct Object
* @class_data: Data to pass to the @class_init,
* @class_base_init. This can be useful when building dynamic
* classes.
- * @is_available: callback invoked at registration time, to dynamically check if
- * this type should be available or not.
+ * @is_available: Optional callback. Unset inherits the parent type's
+ * callback in the MODULE_INIT_QOM after pass (parents are not all
+ * registered at type_register time). After inherit the callback is
+ * never NULL. Callers may also invoke it with a chosen TargetInfo.
* @interfaces: The list of interfaces associated with this type. This
* should point to a static array that's terminated with a zero filled
* element.
@@ -498,7 +510,7 @@ struct TypeInfo
void (*class_base_init)(ObjectClass *klass, const void *data);
const void *class_data;
- bool (*is_available)(void);
+ TypeIsAvailable *is_available;
const InterfaceInfo *interfaces;
};
@@ -1087,6 +1099,14 @@ bool object_class_is_abstract(ObjectClass *klass);
*/
bool object_class_is_secure(ObjectClass *klass);
+/**
+ * object_class_get_is_available:
+ * @klass: The class to obtain TypeInfo.is_available for.
+ *
+ * Returns: The class is_available callback, never %NULL.
+ */
+TypeIsAvailable *object_class_get_is_available(ObjectClass *klass);
+
/**
* object_class_by_name:
* @typename: The QOM typename to obtain the class for.
diff --git a/qom/object.c b/qom/object.c
index 96498f3d001..76b0b0806b3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -15,6 +15,7 @@
#include "qom/compat-properties.h"
#include "qom/object.h"
#include "qom/object_interfaces.h"
+#include "qemu/target-info-qapi.h"
#include "qemu/cutils.h"
#include "qemu/memalign.h"
#include "qapi/visitor.h"
@@ -71,6 +72,8 @@ struct TypeImpl
bool abstract;
bool secure;
+ TypeIsAvailable *is_available;
+
const char *parent;
TypeImpl *parent_type;
@@ -126,6 +129,7 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->abstract = info->abstract;
ti->secure = info->secure;
+ ti->is_available = info->is_available;
for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
@@ -167,7 +171,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
abort();
}
- if (info->is_available && !info->is_available()) {
+ if (info->is_available && !info->is_available(target_info())) {
return NULL;
}
@@ -1153,6 +1157,14 @@ bool object_class_is_secure(ObjectClass *klass)
return klass->type->secure;
}
+TypeIsAvailable *object_class_get_is_available(ObjectClass *klass)
+{
+ if (klass->type->is_available) {
+ return klass->type->is_available;
+ }
+ return target_is_any;
+}
+
const char *object_class_get_name(ObjectClass *klass)
{
return klass->type->name;
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 14/55] target/arm: move kvm_arm_set_cpreg_mig_tolerances to kvm.c
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (12 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 13/55] qom: pass TargetInfo to is_available for latter use Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 15/55] target/arm: allow -cpu host with Nitro Yonggang Luo
` (40 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Keep KVM kernel register-list migration policy with the other KVM
cpreg helpers.
- Move kvm_arm_set_cpreg_mig_tolerances from cpu64.c to kvm.c
- Declare it in kvm_arm.h
- Add a kvm-stub.c assert stub
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/cpu64.c | 38 --------------------------------------
target/arm/kvm-stub.c | 5 +++++
target/arm/kvm.c | 36 ++++++++++++++++++++++++++++++++++++
target/arm/kvm_arm.h | 9 +++++++++
4 files changed, 50 insertions(+), 38 deletions(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 4e8c4725308..1e64eb54cdc 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -754,44 +754,6 @@ static void aarch64_a53_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
-#if defined(CONFIG_KVM)
-static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
-{
- /*
- * Registers that may be in the incoming stream and not exposed
- * on the destination
- */
-
- /*
- * TCR_EL1 was erroneously unconditionnally exposed before linux v6.13.
- * See commit 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace
- * when disabled for guests")
- */
- arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 2, 0, 3),
- 0, 0, ToleranceNotOnBothEnds);
- /*
- * PIRE0_EL1 and PIR_EL1 were erroneously unconditionnally exposed
- * before linux v6.13. See commit a68cddbe47ef ("KVM: arm64: Hide
- * S1PIE registers from userspace when disabled for guests")
- */
- arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 2),
- 0, 0, ToleranceNotOnBothEnds);
- arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
- 0, 0, ToleranceNotOnBothEnds);
-
- /*
- * KVM_REG_ARM_VENDOR_HYP_BMAP_2 pseudo FW register is exposed
- * from v6.15 onwards. Backward migration from a >= v6.15 to an older
- * kernel would fail without cpreg migration tolerance definition.
- * If the register is present on source but not on destination, make
- * sure it has its reset value, ie. 0, meaning no service is exposed
- * to the guest.
- */
- arm_register_cpreg_mig_tolerance(cpu, KVM_REG_ARM_FW_FEAT_BMAP_REG(3),
- UINT64_MAX, 0, ToleranceOnlySrcTestValue);
-}
-#endif
-
void aarch64_host_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index 88cbe8d85c4..ecbd4f9aca1 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -50,6 +50,11 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
g_assert_not_reached();
}
+void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
+
void kvm_arm_add_vcpu_properties(ARMCPU *cpu)
{
g_assert_not_reached();
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ed99be7fd80..2525b9d429c 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -505,6 +505,42 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
env->features = arm_host_cpu_features.features;
}
+void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
+{
+ /*
+ * Registers that may be in the incoming stream and not exposed
+ * on the destination
+ */
+
+ /*
+ * TCR_EL1 was erroneously unconditionnally exposed before linux v6.13.
+ * See commit 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace
+ * when disabled for guests")
+ */
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 2, 0, 3),
+ 0, 0, ToleranceNotOnBothEnds);
+ /*
+ * PIRE0_EL1 and PIR_EL1 were erroneously unconditionnally exposed
+ * before linux v6.13. See commit a68cddbe47ef ("KVM: arm64: Hide
+ * S1PIE registers from userspace when disabled for guests")
+ */
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 2),
+ 0, 0, ToleranceNotOnBothEnds);
+ arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
+ 0, 0, ToleranceNotOnBothEnds);
+
+ /*
+ * KVM_REG_ARM_VENDOR_HYP_BMAP_2 pseudo FW register is exposed
+ * from v6.15 onwards. Backward migration from a >= v6.15 to an older
+ * kernel would fail without cpreg migration tolerance definition.
+ * If the register is present on source but not on destination, make
+ * sure it has its reset value, ie. 0, meaning no service is exposed
+ * to the guest.
+ */
+ arm_register_cpreg_mig_tolerance(cpu, KVM_REG_ARM_FW_FEAT_BMAP_REG(3),
+ UINT64_MAX, 0, ToleranceOnlySrcTestValue);
+}
+
static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
{
return !ARM_CPU(obj)->kvm_adjvtime;
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index e7c40fb003e..014b7bad65b 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -133,6 +133,15 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
*/
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
+/**
+ * kvm_arm_set_cpreg_mig_tolerances:
+ * @cpu: ARMCPU to register the tolerances on
+ *
+ * Register KVM cpreg migration tolerances for kernel register-list
+ * differences (hidden sysregs and newer FW feature bitmaps).
+ */
+void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu);
+
/**
* kvm_arm_add_vcpu_properties:
* @cpu: The CPU object to add the properties to
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 15/55] target/arm: allow -cpu host with Nitro
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (13 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 14/55] target/arm: move kvm_arm_set_cpreg_mig_tolerances to kvm.c Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 10:06 ` Philippe Mathieu-Daudé
2026-09-26 7:00 ` [PATCH v4 16/55] target/arm: gate -cpu host with TypeIsAvailable Yonggang Luo
` (39 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Register the AArch64 host CPU when CONFIG_NITRO is set, matching
the existing initfn early-return for nitro_enabled().
- Add CONFIG_NITRO to the aarch64_cpus host type guard
- Treat nitro_enabled() like the other accels in realize
- Mention Nitro in the host-CPU realize error
- Set host_cpu_probe_failed instead of asserting when only Nitro
is compiled in and it is not selected
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/cpu.c | 5 +++--
target/arm/cpu64.c | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 090470da40a..c138c4c0587 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1835,8 +1835,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* this is the first point where we can report it.
*/
if (cpu->host_cpu_probe_failed) {
- if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled()) {
- error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF or WHPX");
+ if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled() &&
+ !nitro_enabled()) {
+ error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF, WHPX or Nitro");
} else {
error_setg(errp, "Failed to retrieve host CPU features");
}
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 1e64eb54cdc..03f3d55f6ba 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -774,7 +774,7 @@ void aarch64_host_initfn(Object *obj)
#elif defined(CONFIG_WHPX)
whpx_arm_set_cpu_features_from_host(cpu);
#else
- g_assert_not_reached();
+ cpu->host_cpu_probe_failed = true;
#endif
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
aarch64_add_pauth_properties(obj);
@@ -784,7 +784,8 @@ void aarch64_host_initfn(Object *obj)
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF) || defined(CONFIG_WHPX)
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF) || defined(CONFIG_WHPX) || \
+ defined(CONFIG_NITRO)
{ .name = "host", .initfn = aarch64_host_initfn },
#endif
};
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 16/55] target/arm: gate -cpu host with TypeIsAvailable
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (14 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 15/55] target/arm: allow -cpu host with Nitro Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 17/55] target/arm: replace target_long in A64 translate Yonggang Luo
` (38 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Register the host ARMCPU type for every target and hide it with
is_available. aarch64_host_initfn picks kvm, hvf, whpx, or nitro
from TargetKconfig instead of CONFIG_* ifdefs.
- Add ARMCPUInfo.is_available and pass it from arm_cpu_register
- target_has_arm_host_cpu covers kvm, hvf, whpx, and nitro
- Add hvf and whpx set_cpu_features_from_host stubs
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/cpu.c | 1 +
target/arm/cpu.h | 1 +
target/arm/cpu64.c | 43 +++++++++++++++++++++----------------
target/arm/hvf/hvf-stub.c | 14 ++++++++++++
target/arm/hvf/meson.build | 1 +
target/arm/whpx/whpx-stub.c | 5 +++++
6 files changed, 47 insertions(+), 18 deletions(-)
create mode 100644 target/arm/hvf/hvf-stub.c
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index c138c4c0587..9b498632c86 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2685,6 +2685,7 @@ void arm_cpu_register(const ARMCPUInfo *info)
.instance_init = arm_cpu_instance_init,
.class_init = info->class_init ?: cpu_register_class_init,
.class_data = info,
+ .is_available = info->is_available,
};
type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e3f931dba26..87de7e9ff09 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1177,6 +1177,7 @@ typedef struct ARMCPUInfo {
const char *deprecation_note;
void (*initfn)(Object *obj);
void (*class_init)(ObjectClass *oc, const void *data);
+ TypeIsAvailable *is_available;
} ARMCPUInfo;
/**
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 03f3d55f6ba..168639ac2f4 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -20,6 +20,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qemu/target-info.h"
+#include "qemu/target-kconfig-has.h"
#include "cpu.h"
#include "cpregs.h"
#include "qemu/module.h"
@@ -757,37 +759,42 @@ static void aarch64_a53_initfn(Object *obj)
void aarch64_host_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ const TargetInfo *ti = target_info();
-#if defined(CONFIG_NITRO)
- if (nitro_enabled()) {
+ if (target_has_kconfig_nitro(ti) && nitro_enabled()) {
/* The nitro accel uses -cpu host, but does not actually consume it */
return;
}
-#endif
-#if defined(CONFIG_KVM)
- kvm_arm_set_cpreg_mig_tolerances(cpu);
- kvm_arm_set_cpu_features_from_host(cpu);
- aarch64_add_sve_properties(obj);
-#elif defined(CONFIG_HVF)
- hvf_arm_set_cpu_features_from_host(cpu);
-#elif defined(CONFIG_WHPX)
- whpx_arm_set_cpu_features_from_host(cpu);
-#else
- cpu->host_cpu_probe_failed = true;
-#endif
+ if (target_has_kconfig_kvm(ti)) {
+ kvm_arm_set_cpreg_mig_tolerances(cpu);
+ kvm_arm_set_cpu_features_from_host(cpu);
+ aarch64_add_sve_properties(obj);
+ } else if (target_has_kconfig_hvf(ti)) {
+ hvf_arm_set_cpu_features_from_host(cpu);
+ } else if (target_has_kconfig_whpx(ti)) {
+ whpx_arm_set_cpu_features_from_host(cpu);
+ } else {
+ cpu->host_cpu_probe_failed = true;
+ }
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
aarch64_add_pauth_properties(obj);
}
}
+static bool target_has_arm_host_cpu(const TargetInfo *ti)
+{
+ return target_has_kconfig_kvm(ti)
+ || target_has_kconfig_hvf(ti)
+ || target_has_kconfig_whpx(ti)
+ || target_has_kconfig_nitro(ti);
+}
+
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF) || defined(CONFIG_WHPX) || \
- defined(CONFIG_NITRO)
- { .name = "host", .initfn = aarch64_host_initfn },
-#endif
+ { .name = "host", .initfn = aarch64_host_initfn,
+ .is_available = target_has_arm_host_cpu },
};
static void aarch64_cpu_register_types(void)
diff --git a/target/arm/hvf/hvf-stub.c b/target/arm/hvf/hvf-stub.c
new file mode 100644
index 00000000000..3c8148316c9
--- /dev/null
+++ b/target/arm/hvf/hvf-stub.c
@@ -0,0 +1,14 @@
+/*
+ * QEMU HVF ARM specific function stubs
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hvf_arm.h"
+
+void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
diff --git a/target/arm/hvf/meson.build b/target/arm/hvf/meson.build
index afc509a470e..055fab56fb6 100644
--- a/target/arm/hvf/meson.build
+++ b/target/arm/hvf/meson.build
@@ -1,3 +1,4 @@
arm_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
'hvf.c',
))
+arm_stubs_ss.add(files('hvf-stub.c'))
diff --git a/target/arm/whpx/whpx-stub.c b/target/arm/whpx/whpx-stub.c
index 32e434a5f6a..3d1cbb33a28 100644
--- a/target/arm/whpx/whpx-stub.c
+++ b/target/arm/whpx/whpx-stub.c
@@ -13,3 +13,8 @@ uint32_t whpx_arm_get_ipa_bit_size(void)
{
g_assert_not_reached();
}
+
+void whpx_arm_set_cpu_features_from_host(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 17/55] target/arm: replace target_long in A64 translate
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (15 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 16/55] target/arm: gate -cpu host with TypeIsAvailable Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 18/55] target/arm: use vaddr for the A64 insn_start pc Yonggang Luo
` (37 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
- Change gen_pc_plus_diff and gen_a64_update_pc to take int64_t.
Family-common has no signed target_long under -DCPU_DEFS_H.
- Match translate.h and the A32 gen_pc_plus_diff signature.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/tcg/translate-a64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index c60f4c4103d..a9b29583f43 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -184,7 +184,7 @@ static void reset_btype(DisasContext *s)
}
}
-static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
+static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, int64_t diff)
{
assert(s->pc_save != -1);
if (tb_cflags(s->base.tb) & CF_PCREL) {
@@ -194,7 +194,7 @@ static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
}
}
-void gen_a64_update_pc(DisasContext *s, target_long diff)
+void gen_a64_update_pc(DisasContext *s, int64_t diff)
{
gen_pc_plus_diff(s, cpu_pc, diff);
s->pc_save = s->pc_curr + diff;
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 18/55] target/arm: use vaddr for the A64 insn_start pc
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (16 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 17/55] target/arm: replace target_long in A64 translate Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 19/55] tests/qtest: raise aspeed_smc-test timeout to 12 minutes Yonggang Luo
` (36 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
aarch64_tr_insn_start records the guest pc as vaddr. Common compiles
have no per-target target_ulong for that value.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/tcg/translate-a64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index a9b29583f43..50c2b491ce2 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -11115,7 +11115,7 @@ static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
- target_ulong pc_arg = dc->base.pc_next;
+ vaddr pc_arg = dc->base.pc_next;
if (tb_cflags(dcbase->tb) & CF_PCREL) {
pc_arg &= ~TARGET_PAGE_MASK;
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 19/55] tests/qtest: raise aspeed_smc-test timeout to 12 minutes
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (17 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 18/55] target/arm: use vaddr for the A64 insn_start pc Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 20/55] target-info: add tl_is_64() and target_is_tl32/64 helpers Yonggang Luo
` (35 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The two AST2400 block-protect cases walk a 32MB flash 16 times each.
On this host that is about 220 seconds per case, so the whole test
passes 6 minutes and meson sends SIGTERM at the old 360 second limit.
Raise the slow_qtests entry to 720 seconds.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
tests/qtest/meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 8c53bb2e30e..aef99d2bf52 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -1,6 +1,6 @@
slow_qtests = {
'ahci-test': 150,
- 'aspeed_smc-test': 360,
+ 'aspeed_smc-test': 720,
'bios-tables-test' : 910,
'cdrom-test' : 610,
'device-introspect-test' : 720,
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 20/55] target-info: add tl_is_64() and target_is_tl32/64 helpers
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (18 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 19/55] tests/qtest: raise aspeed_smc-test timeout to 12 minutes Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 21/55] tcg: declare TCGv in tcg.h Yonggang Luo
` (34 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
- Add tl_is_64() using TARGET_LONG_BITS per-target and
target_long_bits() in common builds.
- Add target_is_tl32() and target_is_tl64() for a TargetInfo.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info.h | 28 ++++++++++++++++++++++++++++
target-info.c | 10 ++++++++++
2 files changed, 38 insertions(+)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index 3bbe1d9b607..a5dcf60dd9e 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -34,6 +34,34 @@ const char *target_name(void);
*/
unsigned target_long_bits(void);
+#ifdef COMPILING_PER_TARGET
+static inline bool tl_is_64(void)
+{
+ return TARGET_LONG_BITS == 64;
+}
+#else
+static inline bool tl_is_64(void)
+{
+ return target_long_bits() == 64;
+}
+#endif
+
+/**
+ * target_is_tl32:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti uses a 32-bit target long.
+ */
+bool target_is_tl32(const TargetInfo *ti);
+
+/**
+ * target_is_tl64:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti uses a 64-bit target long.
+ */
+bool target_is_tl64(const TargetInfo *ti);
+
/**
* target_cpu_type:
*
diff --git a/target-info.c b/target-info.c
index ad93a4b125e..1bdf3869605 100644
--- a/target-info.c
+++ b/target-info.c
@@ -76,6 +76,16 @@ unsigned target_long_bits(void)
return target_info()->long_bits;
}
+bool target_is_tl32(const TargetInfo *ti)
+{
+ return ti->long_bits == 32;
+}
+
+bool target_is_tl64(const TargetInfo *ti)
+{
+ return ti->long_bits == 64;
+}
+
SysEmuTarget target_arch(void)
{
return target_info()->target_arch;
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 21/55] tcg: declare TCGv in tcg.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (19 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 20/55] target-info: add tl_is_64() and target_is_tl32/64 helpers Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 22/55] tcg: dispatch TL memory helpers from tcg-op-mem.h Yonggang Luo
` (33 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Move the TCGv typedef into tcg.h. Per-target builds keep it as an
alias of TCGv_i32 or TCGv_i64. Common-system builds use an opaque
TCGv, with TCGv_tl and tcg_imm_tl beside it. The tcg_gen_*_tl macros
stay in tcg-op.h.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/tcg/tcg-op.h | 2 --
include/tcg/tcg.h | 22 ++++++++++++++++++++--
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 37211642365..6835ad97901 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -32,14 +32,12 @@
#endif
#if TARGET_LONG_BITS == 32
-typedef TCGv_i32 TCGv;
#define tcg_temp_new() tcg_temp_new_i32()
#define tcg_global_mem_new tcg_global_mem_new_i32
#define tcgv_tl_temp tcgv_i32_temp
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
#elif TARGET_LONG_BITS == 64
-typedef TCGv_i64 TCGv;
#define tcg_temp_new() tcg_temp_new_i64()
#define tcg_global_mem_new tcg_global_mem_new_i64
#define tcgv_tl_temp tcgv_i64_temp
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 7669dc1c2db..7790228eeef 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -179,8 +179,11 @@ typedef tcg_target_ulong TCGArg;
* TCGv_vaddr: an integer type wide enough to hold a target pointer type
* TCGv_vec : a host vector type; the exact size is not exposed
to the CPU front-end code.
- * TCGv : an integer type the same size as target_ulong
- (an alias for either TCGv_i32 or TCGv_i64)
+ * TCGv : an integer type the same size as target_ulong.
+ Per-target compiles alias TCGv_i32 or TCGv_i64.
+ Common-system compiles use a distinct opaque TCGv;
+ use tcg_gen_*_tl.
+ * TCGv_tl : alias of TCGv for helper-head glue(TCGv_, tl)
The compiler's type checking will complain if you mix them
up and pass the wrong sized TCGv to a function.
@@ -203,6 +206,21 @@ typedef struct TCGv_i64_d *TCGv_i64;
typedef struct TCGv_i128_d *TCGv_i128;
typedef struct TCGv_ptr_d *TCGv_ptr;
typedef struct TCGv_vec_d *TCGv_vec;
+#ifdef COMPILING_PER_TARGET
+# include "exec/target_long.h"
+# if TARGET_LONG_BITS == 32
+typedef TCGv_i32 TCGv;
+# elif TARGET_LONG_BITS == 64
+typedef TCGv_i64 TCGv;
+# else
+# error Unhandled TARGET_LONG_BITS value
+# endif
+typedef target_long tcg_imm_tl;
+#else
+typedef struct TCGv_d *TCGv;
+typedef int64_t tcg_imm_tl;
+#endif
+typedef TCGv TCGv_tl;
typedef TCGv_ptr TCGv_env;
#if __SIZEOF_POINTER__ == 4
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 22/55] tcg: dispatch TL memory helpers from tcg-op-mem.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (20 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 21/55] tcg: declare TCGv in tcg.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 23/55] tcg: dispatch tcg_gen_*_tl without TARGET_LONG_BITS Yonggang Luo
` (32 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Move tcg_temp_new, tcg_global_mem_new, qemu ld/st, and the atomic
*_tl helpers into tcg-op-mem.h. Width follows tl_is_64(), and
TCG_ADDRESS_BITS is no longer forced to TARGET_LONG_BITS.
tcg_type_tl, the TL casts, and tcgv_tl_temp live in tcg.h so helper
wrappers can see them. Per-target tcgv_tl_temp aliases tcgv_i32_temp
or tcgv_i64_temp. The common-build inline picks the width with
tl_is_64(). A common build aliases TCGv_va to TCGv. Per-target
builds still use TARGET_LONG_BITS unless the caller sets
TCG_ADDRESS_BITS. Unit tests cover both fixed widths and a 32-bit VA
with a 64-bit target long.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/tcg/tcg-op-mem.h | 114 +++++++++++++++++++++++--
include/tcg/tcg-op.h | 61 -------------
include/tcg/tcg.h | 51 +++++++++++
tests/unit/meson.build | 10 +++
tests/unit/test-tcg-op-mem-config32.h | 2 +
tests/unit/test-tcg-op-mem-config64.h | 2 +
tests/unit/test-tcg-op-mem-tl32.c | 26 ++++++
tests/unit/test-tcg-op-mem-tl64.c | 26 ++++++
tests/unit/test-tcg-op-mem-va32-tl64.c | 35 ++++++++
tests/unit/test-tcg-op-mem.c | 51 +++++++++++
10 files changed, 310 insertions(+), 68 deletions(-)
create mode 100644 tests/unit/test-tcg-op-mem-config32.h
create mode 100644 tests/unit/test-tcg-op-mem-config64.h
create mode 100644 tests/unit/test-tcg-op-mem-tl32.c
create mode 100644 tests/unit/test-tcg-op-mem-tl64.c
create mode 100644 tests/unit/test-tcg-op-mem-va32-tl64.c
create mode 100644 tests/unit/test-tcg-op-mem.c
diff --git a/include/tcg/tcg-op-mem.h b/include/tcg/tcg-op-mem.h
index ea35a02fb40..82aa8a62caf 100644
--- a/include/tcg/tcg-op-mem.h
+++ b/include/tcg/tcg-op-mem.h
@@ -8,24 +8,57 @@
#ifndef TCG_TCG_OP_MEM_H
#define TCG_TCG_OP_MEM_H
-#ifndef TCG_ADDRESS_BITS
-#error TCG_ADDRESS_BITS must be defined
-#endif
-
#include "tcg/tcg-op-common.h"
+#include "qemu/target-info.h"
+
+static inline TCGv tcg_temp_new(void)
+{
+ if (tl_is_64()) {
+ return tcg_tl_from_i64(tcg_temp_new_i64());
+ }
+ return tcg_tl_from_i32(tcg_temp_new_i32());
+}
+
+static inline TCGv tcg_global_mem_new(TCGv_ptr reg, intptr_t off,
+ const char *name)
+{
+ if (tl_is_64()) {
+ return tcg_tl_from_i64(tcg_global_mem_new_i64(reg, off, name));
+ }
+ return tcg_tl_from_i32(tcg_global_mem_new_i32(reg, off, name));
+}
+
+#ifdef TCG_ADDRESS_BITS
+# define TCG_VA_BITS TCG_ADDRESS_BITS
+#elif defined(COMPILING_PER_TARGET)
+# define TCG_VA_BITS TARGET_LONG_BITS
+#endif
-#if TCG_ADDRESS_BITS == 32
+#ifdef TCG_VA_BITS
+# if TCG_VA_BITS == 32
typedef TCGv_i32 TCGv_va;
#define TCG_TYPE_VA TCG_TYPE_I32
#define tcgv_va_temp tcgv_i32_temp
#define tcgv_va_temp_new tcg_temp_new_i32
-#elif TCG_ADDRESS_BITS == 64
+# elif TCG_VA_BITS == 64
typedef TCGv_i64 TCGv_va;
#define TCG_TYPE_VA TCG_TYPE_I64
#define tcgv_va_temp tcgv_i64_temp
#define tcgv_va_temp_new tcg_temp_new_i64
+# else
+# error
+# endif
#else
-#error
+/*
+ * Without a fixed TCG_ADDRESS_BITS, the VA width follows tcg_type_tl()
+ * at translation time. TCGv_va names the address role in APIs, but it
+ * aliases TCGv because their runtime widths are identical. This is
+ * semantic separation, not C type separation.
+ */
+typedef TCGv TCGv_va;
+#define TCG_TYPE_VA tcg_type_tl()
+#define tcgv_va_temp tcgv_tl_temp
+#define tcgv_va_temp_new tcg_temp_new
#endif
static inline void
@@ -125,4 +158,71 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
#undef DEF_ATOMIC2
#undef DEF_ATOMIC3
+static inline void tcg_gen_qemu_ld_tl(TCGv v, TCGv_va a, TCGArg i, MemOp m)
+{
+ if (tl_is_64()) {
+ tcg_gen_qemu_ld_i64(tcg_i64_from_tl(v), a, i, m);
+ } else {
+ tcg_gen_qemu_ld_i32(tcg_i32_from_tl(v), a, i, m);
+ }
+}
+
+static inline void tcg_gen_qemu_st_tl(TCGv v, TCGv_va a, TCGArg i, MemOp m)
+{
+ if (tl_is_64()) {
+ tcg_gen_qemu_st_i64(tcg_i64_from_tl(v), a, i, m);
+ } else {
+ tcg_gen_qemu_st_i32(tcg_i32_from_tl(v), a, i, m);
+ }
+}
+
+#define DEF_ATOMIC2_TL(N) \
+ static inline void N##_tl(TCGv r, TCGv_va a, TCGv v, \
+ TCGArg i, MemOp m) \
+ { \
+ if (tl_is_64()) { \
+ N##_i64(tcg_i64_from_tl(r), a, tcg_i64_from_tl(v), \
+ i, m); \
+ } else { \
+ N##_i32(tcg_i32_from_tl(r), a, tcg_i32_from_tl(v), \
+ i, m); \
+ } \
+ }
+
+#define DEF_ATOMIC3_TL(N) \
+ static inline void N##_tl(TCGv r, TCGv_va a, TCGv o, \
+ TCGv n, TCGArg i, MemOp m) \
+ { \
+ if (tl_is_64()) { \
+ N##_i64(tcg_i64_from_tl(r), a, tcg_i64_from_tl(o), \
+ tcg_i64_from_tl(n), i, m); \
+ } else { \
+ N##_i32(tcg_i32_from_tl(r), a, tcg_i32_from_tl(o), \
+ tcg_i32_from_tl(n), i, m); \
+ } \
+ }
+
+DEF_ATOMIC3_TL(tcg_gen_atomic_cmpxchg)
+
+DEF_ATOMIC2_TL(tcg_gen_atomic_xchg)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_add)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_and)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_or)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_xor)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_smin)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_umin)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_smax)
+DEF_ATOMIC2_TL(tcg_gen_atomic_fetch_umax)
+DEF_ATOMIC2_TL(tcg_gen_atomic_add_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_and_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_or_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_xor_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_smin_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_umin_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_smax_fetch)
+DEF_ATOMIC2_TL(tcg_gen_atomic_umax_fetch)
+
+#undef DEF_ATOMIC2_TL
+#undef DEF_ATOMIC3_TL
+
#endif /* TCG_TCG_OP_MEM_H */
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 6835ad97901..158df47bf18 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -16,37 +16,12 @@
#error must include QEMU headers
#endif
-#define TCG_ADDRESS_BITS TARGET_LONG_BITS
#include "tcg/tcg-op-mem.h"
-#if TARGET_LONG_BITS == 32
-# define TCG_TYPE_TL TCG_TYPE_I32
-#elif TARGET_LONG_BITS == 64
-# define TCG_TYPE_TL TCG_TYPE_I64
-#else
-# error
-#endif
-
#if INSN_START_WORDS != 3
# error Mismatch with insn-start-words.h
#endif
-#if TARGET_LONG_BITS == 32
-#define tcg_temp_new() tcg_temp_new_i32()
-#define tcg_global_mem_new tcg_global_mem_new_i32
-#define tcgv_tl_temp tcgv_i32_temp
-#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
-#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
-#elif TARGET_LONG_BITS == 64
-#define tcg_temp_new() tcg_temp_new_i64()
-#define tcg_global_mem_new tcg_global_mem_new_i64
-#define tcgv_tl_temp tcgv_i64_temp
-#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
-#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
-#else
-#error Unhandled TARGET_LONG_BITS value
-#endif
-
#if TARGET_LONG_BITS == 64
#define tcg_gen_movi_tl tcg_gen_movi_i64
#define tcg_gen_mov_tl tcg_gen_mov_i64
@@ -152,24 +127,6 @@
#define tcg_gen_smax_tl tcg_gen_smax_i64
#define tcg_gen_umax_tl tcg_gen_umax_i64
#define tcg_gen_ussub_tl tcg_gen_ussub_i64
-#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i64
-#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i64
-#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i64
-#define tcg_gen_atomic_fetch_and_tl tcg_gen_atomic_fetch_and_i64
-#define tcg_gen_atomic_fetch_or_tl tcg_gen_atomic_fetch_or_i64
-#define tcg_gen_atomic_fetch_xor_tl tcg_gen_atomic_fetch_xor_i64
-#define tcg_gen_atomic_fetch_smin_tl tcg_gen_atomic_fetch_smin_i64
-#define tcg_gen_atomic_fetch_umin_tl tcg_gen_atomic_fetch_umin_i64
-#define tcg_gen_atomic_fetch_smax_tl tcg_gen_atomic_fetch_smax_i64
-#define tcg_gen_atomic_fetch_umax_tl tcg_gen_atomic_fetch_umax_i64
-#define tcg_gen_atomic_add_fetch_tl tcg_gen_atomic_add_fetch_i64
-#define tcg_gen_atomic_and_fetch_tl tcg_gen_atomic_and_fetch_i64
-#define tcg_gen_atomic_or_fetch_tl tcg_gen_atomic_or_fetch_i64
-#define tcg_gen_atomic_xor_fetch_tl tcg_gen_atomic_xor_fetch_i64
-#define tcg_gen_atomic_smin_fetch_tl tcg_gen_atomic_smin_fetch_i64
-#define tcg_gen_atomic_umin_fetch_tl tcg_gen_atomic_umin_fetch_i64
-#define tcg_gen_atomic_smax_fetch_tl tcg_gen_atomic_smax_fetch_i64
-#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i64
#define tcg_gen_dup_tl_vec tcg_gen_dup_i64_vec
#define tcg_gen_dup_tl tcg_gen_dup_i64
#define dup_const_tl dup_const
@@ -275,24 +232,6 @@
#define tcg_gen_smax_tl tcg_gen_smax_i32
#define tcg_gen_umax_tl tcg_gen_umax_i32
#define tcg_gen_ussub_tl tcg_gen_ussub_i32
-#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i32
-#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i32
-#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i32
-#define tcg_gen_atomic_fetch_and_tl tcg_gen_atomic_fetch_and_i32
-#define tcg_gen_atomic_fetch_or_tl tcg_gen_atomic_fetch_or_i32
-#define tcg_gen_atomic_fetch_xor_tl tcg_gen_atomic_fetch_xor_i32
-#define tcg_gen_atomic_fetch_smin_tl tcg_gen_atomic_fetch_smin_i32
-#define tcg_gen_atomic_fetch_umin_tl tcg_gen_atomic_fetch_umin_i32
-#define tcg_gen_atomic_fetch_smax_tl tcg_gen_atomic_fetch_smax_i32
-#define tcg_gen_atomic_fetch_umax_tl tcg_gen_atomic_fetch_umax_i32
-#define tcg_gen_atomic_add_fetch_tl tcg_gen_atomic_add_fetch_i32
-#define tcg_gen_atomic_and_fetch_tl tcg_gen_atomic_and_fetch_i32
-#define tcg_gen_atomic_or_fetch_tl tcg_gen_atomic_or_fetch_i32
-#define tcg_gen_atomic_xor_fetch_tl tcg_gen_atomic_xor_fetch_i32
-#define tcg_gen_atomic_smin_fetch_tl tcg_gen_atomic_smin_fetch_i32
-#define tcg_gen_atomic_umin_fetch_tl tcg_gen_atomic_umin_fetch_i32
-#define tcg_gen_atomic_smax_fetch_tl tcg_gen_atomic_smax_fetch_i32
-#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i32
#define tcg_gen_dup_tl_vec tcg_gen_dup_i32_vec
#define tcg_gen_dup_tl tcg_gen_dup_i32
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 7790228eeef..61c0ea78946 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -30,6 +30,7 @@
#include "qemu/bitops.h"
#include "qemu/plugin.h"
#include "qemu/queue.h"
+#include "qemu/target-info.h"
#include "tcg/tcg-mo.h"
#include "tcg/target-reg-bits.h"
#include "tcg-target.h"
@@ -520,6 +521,56 @@ static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v)
return tcgv_i32_temp((TCGv_i32)v);
}
+static inline TCGType tcg_type_tl(void)
+{
+ return tl_is_64() ? TCG_TYPE_I64 : TCG_TYPE_I32;
+}
+
+/* Runtime TCGType from tcg_type_tl(); not a compile-time constant. */
+#define TCG_TYPE_TL tcg_type_tl()
+
+static inline TCGv_i64 tcg_i64_from_tl(TCGv v)
+{
+ tcg_debug_assert(tl_is_64());
+ return (TCGv_i64)v;
+}
+
+static inline TCGv_i32 tcg_i32_from_tl(TCGv v)
+{
+ tcg_debug_assert(!tl_is_64());
+ return (TCGv_i32)v;
+}
+
+static inline TCGv tcg_tl_from_i64(TCGv_i64 v)
+{
+ tcg_debug_assert(tl_is_64());
+ return (TCGv)v;
+}
+
+static inline TCGv tcg_tl_from_i32(TCGv_i32 v)
+{
+ tcg_debug_assert(!tl_is_64());
+ return (TCGv)v;
+}
+
+#ifdef COMPILING_PER_TARGET
+# if TARGET_LONG_BITS == 32
+# define tcgv_tl_temp tcgv_i32_temp
+# elif TARGET_LONG_BITS == 64
+# define tcgv_tl_temp tcgv_i64_temp
+# else
+# error Unhandled TARGET_LONG_BITS value
+# endif
+#else
+static inline TCGTemp *tcgv_tl_temp(TCGv v)
+{
+ if (tl_is_64()) {
+ return tcgv_i64_temp(tcg_i64_from_tl(v));
+ }
+ return tcgv_i32_temp(tcg_i32_from_tl(v));
+}
+#endif
+
static inline TCGTemp *tcgv_i128_temp(TCGv_i128 v)
{
return tcgv_i32_temp((TCGv_i32)v);
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index c806dbc4ffa..dc139889c1d 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -43,6 +43,16 @@ tests = {
'test-qgraph': ['../qtest/libqos/qgraph.c'],
'check-qom-interface': [qom],
'check-qom-proplist': [qom],
+ 'test-tcg-op-mem': [qom],
+ 'test-tcg-op-mem-tl32': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config32.h"'])],
+ 'test-tcg-op-mem-tl64': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config64.h"'])],
+ 'test-tcg-op-mem-va32-tl64': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config64.h"'])],
'test-target-info': [qom, declare_dependency(
objects: target_info_def_objects.values(),
compile_args: ['-DTARGET_INFO_DEF_COUNT=@0@'.format(
diff --git a/tests/unit/test-tcg-op-mem-config32.h b/tests/unit/test-tcg-op-mem-config32.h
new file mode 100644
index 00000000000..37183223edc
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem-config32.h
@@ -0,0 +1,2 @@
+#define TARGET_LONG_BITS 32
+#define TARGET_BIG_ENDIAN 0
diff --git a/tests/unit/test-tcg-op-mem-config64.h b/tests/unit/test-tcg-op-mem-config64.h
new file mode 100644
index 00000000000..bcc429333bf
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem-config64.h
@@ -0,0 +1,2 @@
+#define TARGET_LONG_BITS 64
+#define TARGET_BIG_ENDIAN 0
diff --git a/tests/unit/test-tcg-op-mem-tl32.c b/tests/unit/test-tcg-op-mem-tl32.c
new file mode 100644
index 00000000000..1af53172cdb
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem-tl32.c
@@ -0,0 +1,26 @@
+/*
+ * tcg-op-mem.h with TARGET_LONG_BITS == 32.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op-mem.h"
+
+static void test_tl32_aliases(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 32);
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv_i32));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcg_global_mem_new(NULL, 0, "t")), TCGv_i32));
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcgv_tl_temp),
+ __typeof__(tcgv_i32_temp)));
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op-mem/tl32", test_tl32_aliases);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op-mem-tl64.c b/tests/unit/test-tcg-op-mem-tl64.c
new file mode 100644
index 00000000000..956c428fc31
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem-tl64.c
@@ -0,0 +1,26 @@
+/*
+ * tcg-op-mem.h with TARGET_LONG_BITS == 64.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op-mem.h"
+
+static void test_tl64_aliases(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 64);
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv_i64));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcg_global_mem_new(NULL, 0, "t")), TCGv_i64));
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcgv_tl_temp),
+ __typeof__(tcgv_i64_temp)));
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op-mem/tl64", test_tl64_aliases);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op-mem-va32-tl64.c b/tests/unit/test-tcg-op-mem-va32-tl64.c
new file mode 100644
index 00000000000..acb834f7cb5
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem-va32-tl64.c
@@ -0,0 +1,35 @@
+/*
+ * tcg-op-mem.h with a 32-bit VA and a 64-bit target long.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#define TCG_ADDRESS_BITS 32
+#include "tcg/tcg-op-mem.h"
+
+static void test_va32_tl64(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 64);
+ g_assert_cmpint(TCG_ADDRESS_BITS, ==, 32);
+ g_assert_cmpint(tcg_type_tl(), ==, TCG_TYPE_I64);
+ g_assert_cmpint(TCG_TYPE_VA, ==, TCG_TYPE_I32);
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv_i64));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcg_global_mem_new(NULL, 0, "t")), TCGv_i64));
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcgv_tl_temp),
+ __typeof__(tcgv_i64_temp)));
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcgv_va_temp_new()),
+ TCGv_i32));
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcgv_va_temp),
+ __typeof__(tcgv_i32_temp)));
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op-mem/va32-tl64", test_va32_tl64);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op-mem.c b/tests/unit/test-tcg-op-mem.c
new file mode 100644
index 00000000000..b6bda01e93b
--- /dev/null
+++ b/tests/unit/test-tcg-op-mem.c
@@ -0,0 +1,51 @@
+/*
+ * Compile tcg-op-mem.h with no fixed VA width.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-info-def.h"
+#include "tcg/tcg-op-mem.h"
+
+static const TargetInfo tl32_info = {
+ .target_name = "tl32",
+ .long_bits = 32,
+};
+
+static const TargetInfo tl64_info = {
+ .target_name = "tl64",
+ .long_bits = 64,
+};
+
+static void test_runtime_tl_ops(void)
+{
+ TCGType expect = tl_is_64() ? TCG_TYPE_I64 : TCG_TYPE_I32;
+
+ g_assert_cmpint(tcg_type_tl(), ==, expect);
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcg_global_mem_new(NULL, 0, "t")), TCGv));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcgv_tl_temp((TCGv)NULL)), TCGTemp *));
+}
+
+static void test_runtime_tl_width(void)
+{
+ target_info_select(&tl32_info);
+ g_assert_false(tl_is_64());
+ g_assert_cmpint(tcg_type_tl(), ==, TCG_TYPE_I32);
+
+ target_info_select(&tl64_info);
+ g_assert_true(tl_is_64());
+ g_assert_cmpint(tcg_type_tl(), ==, TCG_TYPE_I64);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op-mem/runtime-tl", test_runtime_tl_ops);
+ g_test_add_func("/tcg/op-mem/runtime-tl-width", test_runtime_tl_width);
+ return g_test_run();
+}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 23/55] tcg: dispatch tcg_gen_*_tl without TARGET_LONG_BITS
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (21 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 22/55] tcg: dispatch TL memory helpers from tcg-op-mem.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 24/55] tcg: dispatch tcg_gen_gvec_dup_tl at runtime Yonggang Luo
` (31 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace the TARGET_LONG_BITS aliases in tcg-op.h with the runtime
helpers in tcg-op-tl.h. The width follows tl_is_64(), and tcg-op.h
no longer includes exec/target_long.h.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/tcg/tcg-op-tl.h | 568 ++++++++++++++++++++++++++++++++++++++++
include/tcg/tcg-op.h | 228 +---------------
2 files changed, 569 insertions(+), 227 deletions(-)
create mode 100644 include/tcg/tcg-op-tl.h
diff --git a/include/tcg/tcg-op-tl.h b/include/tcg/tcg-op-tl.h
new file mode 100644
index 00000000000..e05d00a9aaa
--- /dev/null
+++ b/include/tcg/tcg-op-tl.h
@@ -0,0 +1,568 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * target_ulong TCG ops. Width follows target_long_bits() at
+ * translate time. Does not include exec/target_long.h.
+ */
+
+#ifndef TCG_TCG_OP_TL_H
+#define TCG_TCG_OP_TL_H
+
+#include "tcg/tcg-op-mem.h"
+
+/* Load: same callee name on i32 and i64. */
+#define DEF_TL_LD(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv r, TCGv_ptr b, \
+ tcg_target_long o) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(r), b, o); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(r), b, o); \
+ } \
+ }
+
+DEF_TL_LD(ld)
+DEF_TL_LD(ld8u)
+DEF_TL_LD(ld8s)
+DEF_TL_LD(ld16u)
+DEF_TL_LD(ld16s)
+#undef DEF_TL_LD
+
+/* i32 target long is the full register, so a 32-bit load is ld. */
+
+static inline void tcg_gen_ld32u_tl(TCGv r, TCGv_ptr b, tcg_target_long o)
+{
+ if (tl_is_64()) {
+ tcg_gen_ld32u_i64(tcg_i64_from_tl(r), b, o);
+ } else {
+ tcg_gen_ld_i32(tcg_i32_from_tl(r), b, o);
+ }
+}
+
+static inline void tcg_gen_ld32s_tl(TCGv r, TCGv_ptr b, tcg_target_long o)
+{
+ if (tl_is_64()) {
+ tcg_gen_ld32s_i64(tcg_i64_from_tl(r), b, o);
+ } else {
+ tcg_gen_ld_i32(tcg_i32_from_tl(r), b, o);
+ }
+}
+
+/* Store: same callee name on i32 and i64. */
+#define DEF_TL_ST(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv v, TCGv_ptr b, \
+ tcg_target_long o) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(v), b, o); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(v), b, o); \
+ } \
+ }
+
+DEF_TL_ST(st)
+DEF_TL_ST(st8)
+DEF_TL_ST(st16)
+#undef DEF_TL_ST
+
+/* i32 target long is the full register, so a 32-bit store is st. */
+
+static inline void tcg_gen_st32_tl(TCGv r, TCGv_ptr b, tcg_target_long o)
+{
+ if (tl_is_64()) {
+ tcg_gen_st32_i64(tcg_i64_from_tl(r), b, o);
+ } else {
+ tcg_gen_st_i32(tcg_i32_from_tl(r), b, o);
+ }
+}
+
+static inline void tcg_gen_movi_tl(TCGv r, tcg_imm_tl i)
+{
+ if (tl_is_64()) {
+ tcg_gen_movi_i64(tcg_i64_from_tl(r), i);
+ } else {
+ tcg_gen_movi_i32(tcg_i32_from_tl(r), i);
+ }
+}
+
+static inline void tcg_gen_discard_tl(TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_discard_i64(tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_discard_i32(tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_subfi_tl(TCGv r, tcg_imm_tl i, TCGv x)
+{
+ if (tl_is_64()) {
+ tcg_gen_subfi_i64(tcg_i64_from_tl(r), i, tcg_i64_from_tl(x));
+ } else {
+ tcg_gen_subfi_i32(tcg_i32_from_tl(r), i, tcg_i32_from_tl(x));
+ }
+}
+
+/* Unary: same callee name on i32 and i64. */
+#define DEF_TL_UNOP(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv r, TCGv v) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v)); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v)); \
+ } \
+ }
+
+DEF_TL_UNOP(mov)
+DEF_TL_UNOP(neg)
+DEF_TL_UNOP(abs)
+DEF_TL_UNOP(not)
+DEF_TL_UNOP(ext8u)
+DEF_TL_UNOP(ext8s)
+DEF_TL_UNOP(ext16u)
+DEF_TL_UNOP(ext16s)
+DEF_TL_UNOP(clrsb)
+DEF_TL_UNOP(ctpop)
+DEF_TL_UNOP(hswap)
+DEF_TL_UNOP(revbit8)
+#undef DEF_TL_UNOP
+
+/* Binary: same callee name on i32 and i64. */
+#define DEF_TL_BINOP(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv r, TCGv x, TCGv y) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(x), \
+ tcg_i64_from_tl(y)); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(x), \
+ tcg_i32_from_tl(y)); \
+ } \
+ }
+
+DEF_TL_BINOP(add)
+DEF_TL_BINOP(sub)
+DEF_TL_BINOP(and)
+DEF_TL_BINOP(or)
+DEF_TL_BINOP(xor)
+DEF_TL_BINOP(andc)
+DEF_TL_BINOP(eqv)
+DEF_TL_BINOP(nand)
+DEF_TL_BINOP(nor)
+DEF_TL_BINOP(orc)
+DEF_TL_BINOP(shl)
+DEF_TL_BINOP(shr)
+DEF_TL_BINOP(sar)
+DEF_TL_BINOP(mul)
+DEF_TL_BINOP(div)
+DEF_TL_BINOP(rem)
+DEF_TL_BINOP(divu)
+DEF_TL_BINOP(remu)
+DEF_TL_BINOP(clz)
+DEF_TL_BINOP(ctz)
+DEF_TL_BINOP(rotl)
+DEF_TL_BINOP(rotr)
+DEF_TL_BINOP(smin)
+DEF_TL_BINOP(umin)
+DEF_TL_BINOP(smax)
+DEF_TL_BINOP(umax)
+DEF_TL_BINOP(ussub)
+#undef DEF_TL_BINOP
+
+/* Immediate: same callee name on i32 and i64. */
+#define DEF_TL_OPI(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv r, TCGv x, tcg_imm_tl i) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(x), i); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(x), i); \
+ } \
+ }
+
+DEF_TL_OPI(addi)
+DEF_TL_OPI(subi)
+DEF_TL_OPI(andi)
+DEF_TL_OPI(ori)
+DEF_TL_OPI(xori)
+DEF_TL_OPI(muli)
+DEF_TL_OPI(shli)
+DEF_TL_OPI(shri)
+DEF_TL_OPI(sari)
+DEF_TL_OPI(clzi)
+DEF_TL_OPI(ctzi)
+DEF_TL_OPI(rotli)
+DEF_TL_OPI(rotri)
+#undef DEF_TL_OPI
+
+static inline void tcg_gen_brcond_tl(TCGCond cond, TCGv x, TCGv y,
+ TCGLabel *l)
+{
+ if (tl_is_64()) {
+ tcg_gen_brcond_i64(cond, tcg_i64_from_tl(x), tcg_i64_from_tl(y), l);
+ } else {
+ tcg_gen_brcond_i32(cond, tcg_i32_from_tl(x), tcg_i32_from_tl(y), l);
+ }
+}
+
+static inline void tcg_gen_brcondi_tl(TCGCond cond, TCGv x, tcg_imm_tl i,
+ TCGLabel *l)
+{
+ if (tl_is_64()) {
+ tcg_gen_brcondi_i64(cond, tcg_i64_from_tl(x), i, l);
+ } else {
+ tcg_gen_brcondi_i32(cond, tcg_i32_from_tl(x), i, l);
+ }
+}
+
+#define DEF_TL_COND(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGCond cond, TCGv r, \
+ TCGv x, TCGv y) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(cond, tcg_i64_from_tl(r), \
+ tcg_i64_from_tl(x), tcg_i64_from_tl(y)); \
+ } else { \
+ tcg_gen_##NAME##_i32(cond, tcg_i32_from_tl(r), \
+ tcg_i32_from_tl(x), tcg_i32_from_tl(y)); \
+ } \
+ }
+
+DEF_TL_COND(setcond)
+DEF_TL_COND(negsetcond)
+#undef DEF_TL_COND
+
+#define DEF_TL_CONDI(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGCond cond, TCGv r, \
+ TCGv x, tcg_imm_tl i) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(cond, tcg_i64_from_tl(r), \
+ tcg_i64_from_tl(x), i); \
+ } else { \
+ tcg_gen_##NAME##_i32(cond, tcg_i32_from_tl(r), \
+ tcg_i32_from_tl(x), i); \
+ } \
+ }
+
+DEF_TL_CONDI(setcondi)
+DEF_TL_CONDI(negsetcondi)
+#undef DEF_TL_CONDI
+
+static inline void tcg_gen_movcond_tl(TCGCond cond, TCGv r, TCGv c1,
+ TCGv c2, TCGv v1, TCGv v2)
+{
+ if (tl_is_64()) {
+ tcg_gen_movcond_i64(cond, tcg_i64_from_tl(r), tcg_i64_from_tl(c1),
+ tcg_i64_from_tl(c2), tcg_i64_from_tl(v1),
+ tcg_i64_from_tl(v2));
+ } else {
+ tcg_gen_movcond_i32(cond, tcg_i32_from_tl(r), tcg_i32_from_tl(c1),
+ tcg_i32_from_tl(c2), tcg_i32_from_tl(v1),
+ tcg_i32_from_tl(v2));
+ }
+}
+
+static inline void tcg_gen_trunc_tl_i32(TCGv_i32 r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_extrl_i64_i32(r, tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_mov_i32(r, tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_trunc_i64_tl(TCGv r, TCGv_i64 v)
+{
+ if (tl_is_64()) {
+ tcg_gen_mov_i64(tcg_i64_from_tl(r), v);
+ } else {
+ tcg_gen_extrl_i64_i32(tcg_i32_from_tl(r), v);
+ }
+}
+
+static inline void tcg_gen_extu_i32_tl(TCGv r, TCGv_i32 v)
+{
+ if (tl_is_64()) {
+ tcg_gen_extu_i32_i64(tcg_i64_from_tl(r), v);
+ } else {
+ tcg_gen_mov_i32(tcg_i32_from_tl(r), v);
+ }
+}
+
+static inline void tcg_gen_ext_i32_tl(TCGv r, TCGv_i32 v)
+{
+ if (tl_is_64()) {
+ tcg_gen_ext_i32_i64(tcg_i64_from_tl(r), v);
+ } else {
+ tcg_gen_mov_i32(tcg_i32_from_tl(r), v);
+ }
+}
+
+static inline void tcg_gen_extu_tl_i64(TCGv_i64 r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_mov_i64(r, tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_extu_i32_i64(r, tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_ext_tl_i64(TCGv_i64 r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_mov_i64(r, tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_ext_i32_i64(r, tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_ext32u_tl(TCGv r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_ext32u_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_mov_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_ext32s_tl(TCGv r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_ext32s_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_mov_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_ext_tl(TCGv r, TCGv v, MemOp opc)
+{
+ if (tl_is_64()) {
+ tcg_gen_ext_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v), opc);
+ } else {
+ tcg_gen_ext_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v), opc);
+ }
+}
+
+static inline void tcg_gen_bswap16_tl(TCGv r, TCGv v, int flags)
+{
+ if (tl_is_64()) {
+ tcg_gen_bswap16_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v), flags);
+ } else {
+ tcg_gen_bswap16_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v), flags);
+ }
+}
+
+static inline void tcg_gen_bswap32_tl(TCGv r, TCGv v, int flags)
+{
+ if (tl_is_64()) {
+ tcg_gen_bswap32_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v), flags);
+ } else {
+ tcg_gen_bswap32_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_bswap64_tl(TCGv r, TCGv v)
+{
+ tcg_debug_assert(tl_is_64());
+ tcg_gen_bswap64_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+}
+
+static inline void tcg_gen_bswap_tl(TCGv r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_bswap64_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_bswap32_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_wswap_tl(TCGv r, TCGv v)
+{
+ tcg_debug_assert(tl_is_64());
+ tcg_gen_wswap_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+}
+
+static inline void tcg_gen_revbit32_tl(TCGv r, TCGv v, int flags)
+{
+ if (tl_is_64()) {
+ tcg_gen_revbit32_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v), flags);
+ } else {
+ tcg_gen_revbit32_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_revbit64_tl(TCGv r, TCGv v)
+{
+ tcg_debug_assert(tl_is_64());
+ tcg_gen_revbit64_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+}
+
+static inline void tcg_gen_revbit_tl(TCGv r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_revbit64_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_revbit32_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_concat_tl_i64(TCGv_i64 r, TCGv lo, TCGv hi)
+{
+ if (tl_is_64()) {
+ tcg_gen_concat32_i64(r, tcg_i64_from_tl(lo), tcg_i64_from_tl(hi));
+ } else {
+ tcg_gen_concat_i32_i64(r, tcg_i32_from_tl(lo), tcg_i32_from_tl(hi));
+ }
+}
+
+static inline void tcg_gen_extr_i64_tl(TCGv lo, TCGv hi, TCGv_i64 v)
+{
+ if (tl_is_64()) {
+ tcg_gen_extr32_i64(tcg_i64_from_tl(lo), tcg_i64_from_tl(hi), v);
+ } else {
+ tcg_gen_extr_i64_i32(tcg_i32_from_tl(lo), tcg_i32_from_tl(hi), v);
+ }
+}
+
+static inline void tcg_gen_deposit_tl(TCGv r, TCGv x, TCGv y, unsigned pos,
+ unsigned len)
+{
+ if (tl_is_64()) {
+ tcg_gen_deposit_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(x),
+ tcg_i64_from_tl(y), pos, len);
+ } else {
+ tcg_gen_deposit_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(x),
+ tcg_i32_from_tl(y), pos, len);
+ }
+}
+
+#define DEF_TL_EXTRACT(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv r, TCGv v, \
+ unsigned pos, unsigned len) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(v), \
+ pos, len); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(v), \
+ pos, len); \
+ } \
+ }
+
+DEF_TL_EXTRACT(deposit_z)
+DEF_TL_EXTRACT(extract)
+DEF_TL_EXTRACT(sextract)
+#undef DEF_TL_EXTRACT
+
+static inline void tcg_gen_extract2_tl(TCGv r, TCGv lo, TCGv hi,
+ unsigned ofs)
+{
+ if (tl_is_64()) {
+ tcg_gen_extract2_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(lo),
+ tcg_i64_from_tl(hi), ofs);
+ } else {
+ tcg_gen_extract2_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(lo),
+ tcg_i32_from_tl(hi), ofs);
+ }
+}
+
+static inline TCGv tcg_constant_tl(tcg_imm_tl val)
+{
+ if (tl_is_64()) {
+ return tcg_tl_from_i64(tcg_constant_i64(val));
+ }
+ return tcg_tl_from_i32(tcg_constant_i32(val));
+}
+
+#define DEF_TL_ADD2(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv rl, TCGv rh, TCGv al, \
+ TCGv ah, TCGv bl, TCGv bh) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(rl), tcg_i64_from_tl(rh), \
+ tcg_i64_from_tl(al), tcg_i64_from_tl(ah), \
+ tcg_i64_from_tl(bl), tcg_i64_from_tl(bh)); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(rl), tcg_i32_from_tl(rh), \
+ tcg_i32_from_tl(al), tcg_i32_from_tl(ah), \
+ tcg_i32_from_tl(bl), tcg_i32_from_tl(bh)); \
+ } \
+ }
+
+DEF_TL_ADD2(add2)
+DEF_TL_ADD2(sub2)
+#undef DEF_TL_ADD2
+
+static inline void tcg_gen_addcio_tl(TCGv r, TCGv co, TCGv x, TCGv y,
+ TCGv ci)
+{
+ if (tl_is_64()) {
+ tcg_gen_addcio_i64(tcg_i64_from_tl(r), tcg_i64_from_tl(co),
+ tcg_i64_from_tl(x), tcg_i64_from_tl(y),
+ tcg_i64_from_tl(ci));
+ } else {
+ tcg_gen_addcio_i32(tcg_i32_from_tl(r), tcg_i32_from_tl(co),
+ tcg_i32_from_tl(x), tcg_i32_from_tl(y),
+ tcg_i32_from_tl(ci));
+ }
+}
+
+#define DEF_TL_MUL2(NAME) \
+ static inline void tcg_gen_##NAME##_tl(TCGv rl, TCGv rh, \
+ TCGv x, TCGv y) \
+ { \
+ if (tl_is_64()) { \
+ tcg_gen_##NAME##_i64(tcg_i64_from_tl(rl), tcg_i64_from_tl(rh), \
+ tcg_i64_from_tl(x), tcg_i64_from_tl(y)); \
+ } else { \
+ tcg_gen_##NAME##_i32(tcg_i32_from_tl(rl), tcg_i32_from_tl(rh), \
+ tcg_i32_from_tl(x), tcg_i32_from_tl(y)); \
+ } \
+ }
+
+DEF_TL_MUL2(mulu2)
+DEF_TL_MUL2(muls2)
+DEF_TL_MUL2(mulsu2)
+#undef DEF_TL_MUL2
+
+static inline void tcg_gen_dup_tl_vec(unsigned vece, TCGv_vec r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_dup_i64_vec(vece, r, tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_dup_i32_vec(vece, r, tcg_i32_from_tl(v));
+ }
+}
+
+static inline void tcg_gen_dup_tl(unsigned vece, TCGv r, TCGv v)
+{
+ if (tl_is_64()) {
+ tcg_gen_dup_i64(vece, tcg_i64_from_tl(r), tcg_i64_from_tl(v));
+ } else {
+ tcg_gen_dup_i32(vece, tcg_i32_from_tl(r), tcg_i32_from_tl(v));
+ }
+}
+
+static inline tcg_imm_tl dup_const_tl(unsigned vece, uint64_t c)
+{
+ if (tl_is_64()) {
+ return dup_const(vece, c);
+ }
+ if (__builtin_constant_p(vece)) {
+ switch (vece) {
+ case MO_8:
+ return 0x01010101ul * (uint8_t)c;
+ case MO_16:
+ return 0x00010001ul * (uint16_t)c;
+ case MO_32:
+ return 0x00000001ul * (uint32_t)c;
+ default:
+ qemu_build_not_reached();
+ }
+ }
+ return (uint32_t)dup_const(vece, c);
+}
+
+#endif /* TCG_TCG_OP_TL_H */
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 158df47bf18..99cd2779687 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -10,238 +10,12 @@
#include "tcg/tcg-op-common.h"
#include "tcg/insn-start-words.h"
-#include "exec/target_long.h"
-
-#ifndef TARGET_LONG_BITS
-#error must include QEMU headers
-#endif
#include "tcg/tcg-op-mem.h"
+#include "tcg/tcg-op-tl.h"
#if INSN_START_WORDS != 3
# error Mismatch with insn-start-words.h
#endif
-#if TARGET_LONG_BITS == 64
-#define tcg_gen_movi_tl tcg_gen_movi_i64
-#define tcg_gen_mov_tl tcg_gen_mov_i64
-#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
-#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
-#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
-#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
-#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
-#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
-#define tcg_gen_ld_tl tcg_gen_ld_i64
-#define tcg_gen_st8_tl tcg_gen_st8_i64
-#define tcg_gen_st16_tl tcg_gen_st16_i64
-#define tcg_gen_st32_tl tcg_gen_st32_i64
-#define tcg_gen_st_tl tcg_gen_st_i64
-#define tcg_gen_add_tl tcg_gen_add_i64
-#define tcg_gen_addi_tl tcg_gen_addi_i64
-#define tcg_gen_sub_tl tcg_gen_sub_i64
-#define tcg_gen_neg_tl tcg_gen_neg_i64
-#define tcg_gen_abs_tl tcg_gen_abs_i64
-#define tcg_gen_subfi_tl tcg_gen_subfi_i64
-#define tcg_gen_subi_tl tcg_gen_subi_i64
-#define tcg_gen_and_tl tcg_gen_and_i64
-#define tcg_gen_andi_tl tcg_gen_andi_i64
-#define tcg_gen_or_tl tcg_gen_or_i64
-#define tcg_gen_ori_tl tcg_gen_ori_i64
-#define tcg_gen_xor_tl tcg_gen_xor_i64
-#define tcg_gen_xori_tl tcg_gen_xori_i64
-#define tcg_gen_not_tl tcg_gen_not_i64
-#define tcg_gen_shl_tl tcg_gen_shl_i64
-#define tcg_gen_shli_tl tcg_gen_shli_i64
-#define tcg_gen_shr_tl tcg_gen_shr_i64
-#define tcg_gen_shri_tl tcg_gen_shri_i64
-#define tcg_gen_sar_tl tcg_gen_sar_i64
-#define tcg_gen_sari_tl tcg_gen_sari_i64
-#define tcg_gen_brcond_tl tcg_gen_brcond_i64
-#define tcg_gen_brcondi_tl tcg_gen_brcondi_i64
-#define tcg_gen_setcond_tl tcg_gen_setcond_i64
-#define tcg_gen_setcondi_tl tcg_gen_setcondi_i64
-#define tcg_gen_negsetcond_tl tcg_gen_negsetcond_i64
-#define tcg_gen_negsetcondi_tl tcg_gen_negsetcondi_i64
-#define tcg_gen_mul_tl tcg_gen_mul_i64
-#define tcg_gen_muli_tl tcg_gen_muli_i64
-#define tcg_gen_div_tl tcg_gen_div_i64
-#define tcg_gen_rem_tl tcg_gen_rem_i64
-#define tcg_gen_divu_tl tcg_gen_divu_i64
-#define tcg_gen_remu_tl tcg_gen_remu_i64
-#define tcg_gen_discard_tl tcg_gen_discard_i64
-#define tcg_gen_trunc_tl_i32 tcg_gen_extrl_i64_i32
-#define tcg_gen_trunc_i64_tl tcg_gen_mov_i64
-#define tcg_gen_extu_i32_tl tcg_gen_extu_i32_i64
-#define tcg_gen_ext_i32_tl tcg_gen_ext_i32_i64
-#define tcg_gen_extu_tl_i64 tcg_gen_mov_i64
-#define tcg_gen_ext_tl_i64 tcg_gen_mov_i64
-#define tcg_gen_ext8u_tl tcg_gen_ext8u_i64
-#define tcg_gen_ext8s_tl tcg_gen_ext8s_i64
-#define tcg_gen_ext16u_tl tcg_gen_ext16u_i64
-#define tcg_gen_ext16s_tl tcg_gen_ext16s_i64
-#define tcg_gen_ext32u_tl tcg_gen_ext32u_i64
-#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
-#define tcg_gen_ext_tl tcg_gen_ext_i64
-#define tcg_gen_bswap16_tl tcg_gen_bswap16_i64
-#define tcg_gen_bswap32_tl tcg_gen_bswap32_i64
-#define tcg_gen_bswap64_tl tcg_gen_bswap64_i64
-#define tcg_gen_bswap_tl tcg_gen_bswap64_i64
-#define tcg_gen_hswap_tl tcg_gen_hswap_i64
-#define tcg_gen_wswap_tl tcg_gen_wswap_i64
-#define tcg_gen_revbit8_tl tcg_gen_revbit8_i64
-#define tcg_gen_revbit32_tl tcg_gen_revbit32_i64
-#define tcg_gen_revbit64_tl tcg_gen_revbit64_i64
-#define tcg_gen_revbit_tl tcg_gen_revbit64_i64
-#define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64
-#define tcg_gen_extr_i64_tl tcg_gen_extr32_i64
-#define tcg_gen_andc_tl tcg_gen_andc_i64
-#define tcg_gen_eqv_tl tcg_gen_eqv_i64
-#define tcg_gen_nand_tl tcg_gen_nand_i64
-#define tcg_gen_nor_tl tcg_gen_nor_i64
-#define tcg_gen_orc_tl tcg_gen_orc_i64
-#define tcg_gen_clz_tl tcg_gen_clz_i64
-#define tcg_gen_ctz_tl tcg_gen_ctz_i64
-#define tcg_gen_clzi_tl tcg_gen_clzi_i64
-#define tcg_gen_ctzi_tl tcg_gen_ctzi_i64
-#define tcg_gen_clrsb_tl tcg_gen_clrsb_i64
-#define tcg_gen_ctpop_tl tcg_gen_ctpop_i64
-#define tcg_gen_rotl_tl tcg_gen_rotl_i64
-#define tcg_gen_rotli_tl tcg_gen_rotli_i64
-#define tcg_gen_rotr_tl tcg_gen_rotr_i64
-#define tcg_gen_rotri_tl tcg_gen_rotri_i64
-#define tcg_gen_deposit_tl tcg_gen_deposit_i64
-#define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i64
-#define tcg_gen_extract_tl tcg_gen_extract_i64
-#define tcg_gen_sextract_tl tcg_gen_sextract_i64
-#define tcg_gen_extract2_tl tcg_gen_extract2_i64
-#define tcg_constant_tl tcg_constant_i64
-#define tcg_gen_movcond_tl tcg_gen_movcond_i64
-#define tcg_gen_add2_tl tcg_gen_add2_i64
-#define tcg_gen_sub2_tl tcg_gen_sub2_i64
-#define tcg_gen_addcio_tl tcg_gen_addcio_i64
-#define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
-#define tcg_gen_muls2_tl tcg_gen_muls2_i64
-#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64
-#define tcg_gen_smin_tl tcg_gen_smin_i64
-#define tcg_gen_umin_tl tcg_gen_umin_i64
-#define tcg_gen_smax_tl tcg_gen_smax_i64
-#define tcg_gen_umax_tl tcg_gen_umax_i64
-#define tcg_gen_ussub_tl tcg_gen_ussub_i64
-#define tcg_gen_dup_tl_vec tcg_gen_dup_i64_vec
-#define tcg_gen_dup_tl tcg_gen_dup_i64
-#define dup_const_tl dup_const
-#else
-#define tcg_gen_movi_tl tcg_gen_movi_i32
-#define tcg_gen_mov_tl tcg_gen_mov_i32
-#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
-#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
-#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
-#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
-#define tcg_gen_ld32u_tl tcg_gen_ld_i32
-#define tcg_gen_ld32s_tl tcg_gen_ld_i32
-#define tcg_gen_ld_tl tcg_gen_ld_i32
-#define tcg_gen_st8_tl tcg_gen_st8_i32
-#define tcg_gen_st16_tl tcg_gen_st16_i32
-#define tcg_gen_st32_tl tcg_gen_st_i32
-#define tcg_gen_st_tl tcg_gen_st_i32
-#define tcg_gen_add_tl tcg_gen_add_i32
-#define tcg_gen_addi_tl tcg_gen_addi_i32
-#define tcg_gen_sub_tl tcg_gen_sub_i32
-#define tcg_gen_neg_tl tcg_gen_neg_i32
-#define tcg_gen_abs_tl tcg_gen_abs_i32
-#define tcg_gen_subfi_tl tcg_gen_subfi_i32
-#define tcg_gen_subi_tl tcg_gen_subi_i32
-#define tcg_gen_and_tl tcg_gen_and_i32
-#define tcg_gen_andi_tl tcg_gen_andi_i32
-#define tcg_gen_or_tl tcg_gen_or_i32
-#define tcg_gen_ori_tl tcg_gen_ori_i32
-#define tcg_gen_xor_tl tcg_gen_xor_i32
-#define tcg_gen_xori_tl tcg_gen_xori_i32
-#define tcg_gen_not_tl tcg_gen_not_i32
-#define tcg_gen_shl_tl tcg_gen_shl_i32
-#define tcg_gen_shli_tl tcg_gen_shli_i32
-#define tcg_gen_shr_tl tcg_gen_shr_i32
-#define tcg_gen_shri_tl tcg_gen_shri_i32
-#define tcg_gen_sar_tl tcg_gen_sar_i32
-#define tcg_gen_sari_tl tcg_gen_sari_i32
-#define tcg_gen_brcond_tl tcg_gen_brcond_i32
-#define tcg_gen_brcondi_tl tcg_gen_brcondi_i32
-#define tcg_gen_setcond_tl tcg_gen_setcond_i32
-#define tcg_gen_setcondi_tl tcg_gen_setcondi_i32
-#define tcg_gen_negsetcond_tl tcg_gen_negsetcond_i32
-#define tcg_gen_negsetcondi_tl tcg_gen_negsetcondi_i32
-#define tcg_gen_mul_tl tcg_gen_mul_i32
-#define tcg_gen_muli_tl tcg_gen_muli_i32
-#define tcg_gen_div_tl tcg_gen_div_i32
-#define tcg_gen_rem_tl tcg_gen_rem_i32
-#define tcg_gen_divu_tl tcg_gen_divu_i32
-#define tcg_gen_remu_tl tcg_gen_remu_i32
-#define tcg_gen_discard_tl tcg_gen_discard_i32
-#define tcg_gen_trunc_tl_i32 tcg_gen_mov_i32
-#define tcg_gen_trunc_i64_tl tcg_gen_extrl_i64_i32
-#define tcg_gen_extu_i32_tl tcg_gen_mov_i32
-#define tcg_gen_ext_i32_tl tcg_gen_mov_i32
-#define tcg_gen_extu_tl_i64 tcg_gen_extu_i32_i64
-#define tcg_gen_ext_tl_i64 tcg_gen_ext_i32_i64
-#define tcg_gen_ext8u_tl tcg_gen_ext8u_i32
-#define tcg_gen_ext8s_tl tcg_gen_ext8s_i32
-#define tcg_gen_ext16u_tl tcg_gen_ext16u_i32
-#define tcg_gen_ext16s_tl tcg_gen_ext16s_i32
-#define tcg_gen_ext32u_tl tcg_gen_mov_i32
-#define tcg_gen_ext32s_tl tcg_gen_mov_i32
-#define tcg_gen_ext_tl tcg_gen_ext_i32
-#define tcg_gen_bswap16_tl tcg_gen_bswap16_i32
-#define tcg_gen_bswap32_tl(D, S, F) tcg_gen_bswap32_i32(D, S)
-#define tcg_gen_bswap_tl tcg_gen_bswap32_i32
-#define tcg_gen_hswap_tl tcg_gen_hswap_i32
-#define tcg_gen_revbit8_tl tcg_gen_revbit8_i32
-#define tcg_gen_revbit32_tl(D, S, F) tcg_gen_revbit32_i32(D, S)
-#define tcg_gen_revbit_tl tcg_gen_revbit32_i32
-#define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64
-#define tcg_gen_extr_i64_tl tcg_gen_extr_i64_i32
-#define tcg_gen_andc_tl tcg_gen_andc_i32
-#define tcg_gen_eqv_tl tcg_gen_eqv_i32
-#define tcg_gen_nand_tl tcg_gen_nand_i32
-#define tcg_gen_nor_tl tcg_gen_nor_i32
-#define tcg_gen_orc_tl tcg_gen_orc_i32
-#define tcg_gen_clz_tl tcg_gen_clz_i32
-#define tcg_gen_ctz_tl tcg_gen_ctz_i32
-#define tcg_gen_clzi_tl tcg_gen_clzi_i32
-#define tcg_gen_ctzi_tl tcg_gen_ctzi_i32
-#define tcg_gen_clrsb_tl tcg_gen_clrsb_i32
-#define tcg_gen_ctpop_tl tcg_gen_ctpop_i32
-#define tcg_gen_rotl_tl tcg_gen_rotl_i32
-#define tcg_gen_rotli_tl tcg_gen_rotli_i32
-#define tcg_gen_rotr_tl tcg_gen_rotr_i32
-#define tcg_gen_rotri_tl tcg_gen_rotri_i32
-#define tcg_gen_deposit_tl tcg_gen_deposit_i32
-#define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i32
-#define tcg_gen_extract_tl tcg_gen_extract_i32
-#define tcg_gen_sextract_tl tcg_gen_sextract_i32
-#define tcg_gen_extract2_tl tcg_gen_extract2_i32
-#define tcg_constant_tl tcg_constant_i32
-#define tcg_gen_movcond_tl tcg_gen_movcond_i32
-#define tcg_gen_add2_tl tcg_gen_add2_i32
-#define tcg_gen_sub2_tl tcg_gen_sub2_i32
-#define tcg_gen_addcio_tl tcg_gen_addcio_i32
-#define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
-#define tcg_gen_muls2_tl tcg_gen_muls2_i32
-#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32
-#define tcg_gen_smin_tl tcg_gen_smin_i32
-#define tcg_gen_umin_tl tcg_gen_umin_i32
-#define tcg_gen_smax_tl tcg_gen_smax_i32
-#define tcg_gen_umax_tl tcg_gen_umax_i32
-#define tcg_gen_ussub_tl tcg_gen_ussub_i32
-#define tcg_gen_dup_tl_vec tcg_gen_dup_i32_vec
-#define tcg_gen_dup_tl tcg_gen_dup_i32
-
-#define dup_const_tl(VECE, C) \
- (__builtin_constant_p(VECE) \
- ? ( (VECE) == MO_8 ? 0x01010101ul * (uint8_t)(C) \
- : (VECE) == MO_16 ? 0x00010001ul * (uint16_t)(C) \
- : (VECE) == MO_32 ? 0x00000001ul * (uint32_t)(C) \
- : (qemu_build_not_reached_always(), 0)) \
- : (target_long)dup_const(VECE, C))
-
-#endif /* TARGET_LONG_BITS == 64 */
#endif /* TCG_TCG_OP_H */
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 24/55] tcg: dispatch tcg_gen_gvec_dup_tl at runtime
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (22 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 23/55] tcg: dispatch tcg_gen_*_tl without TARGET_LONG_BITS Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 25/55] tcg: give common-system helper tl an i64 slot Yonggang Luo
` (30 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace the TARGET_LONG_BITS alias in tcg-op-gvec.h with a static
inline. The duplicate follows tl_is_64() and casts through
tcg_i64_from_tl and tcg_i32_from_tl.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/tcg/tcg-op-gvec.h | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
index d82ba6dfaac..96e73178558 100644
--- a/include/tcg/tcg-op-gvec.h
+++ b/include/tcg/tcg-op-gvec.h
@@ -9,17 +9,16 @@
#define TCG_TCG_OP_GVEC_H
#include "tcg/tcg-op-gvec-common.h"
+#include "tcg/tcg-op-mem.h"
-#ifndef TARGET_LONG_BITS
-#error must include QEMU headers
-#endif
-
-#if TARGET_LONG_BITS == 64
-#define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i64
-#elif TARGET_LONG_BITS == 32
-#define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i32
-#else
-# error
-#endif
+static inline void tcg_gen_gvec_dup_tl(unsigned vece, uint32_t dofs,
+ uint32_t s, uint32_t m, TCGv c)
+{
+ if (tl_is_64()) {
+ tcg_gen_gvec_dup_i64(vece, dofs, s, m, tcg_i64_from_tl(c));
+ } else {
+ tcg_gen_gvec_dup_i32(vece, dofs, s, m, tcg_i32_from_tl(c));
+ }
+}
#endif
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 25/55] tcg: give common-system helper tl an i64 slot
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (23 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 24/55] tcg: dispatch tcg_gen_gvec_dup_tl at runtime Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 26/55] accel/tcg: move helper_exit_atomic next to cpu_loop_exit_atomic Yonggang Luo
` (29 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
dh_alias_tl stays tl. In common-system code the helper C slot stays
uint64_t and the typecode stays i64, because one typemask is shared
by 32- and 64-bit guests. tcg_gen_callN zero-extends an I32 temp into
that slot and truncates an i64 return.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/exec/helper-head.h.inc | 21 ++++++++++++++++++--
tcg/tcg.c | 35 ++++++++++++++++++++++++++++++++--
2 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
index 7dec5f5b067..6612937c5ae 100644
--- a/include/exec/helper-head.h.inc
+++ b/include/exec/helper-head.h.inc
@@ -45,16 +45,29 @@
#define dh_ctype_noreturn G_NORETURN void
#define dh_ctype(t) dh_ctype_##t
+#define dh_alias_tl tl
#ifdef COMPILING_PER_TARGET
# include "exec/target_long.h"
# if TARGET_LONG_BITS == 32
-# define dh_alias_tl i32
# define dh_typecode_tl dh_typecode_i32
# else
-# define dh_alias_tl i64
# define dh_typecode_tl dh_typecode_i64
# endif
# define dh_ctype_tl target_ulong
+#else
+/*
+ * Common-system helper FFI only: helper_info.typemask is compile-time
+ * and shared by 32- and 64-bit guests, so the C/libffi slot is
+ * max(i32, i64) -- always i64 / uint64_t. This is not the TCG temp
+ * width. TCGv_tl stays dynamic (I32 or I64 via tcg_type_tl());
+ * tcgv_tl_temp() is the handle-to-TCGTemp accessor and is valid for
+ * either size. Call lowering zero-extends an I32 temp into this
+ * unsigned i64 slot (dh_typecode_tl is i64, not s64). A helper C
+ * body that needs a signed guest value must narrow to XLEN and
+ * sign-extend itself; (int64_t)arg is not a 32-bit sign-extend.
+ */
+# define dh_typecode_tl dh_typecode_i64
+# define dh_ctype_tl uint64_t
#endif /* COMPILING_PER_TARGET */
#if __SIZEOF_POINTER__ == 4
@@ -76,6 +89,7 @@
#define dh_retvar_decl0_i64 TCGv_i64 retval
#define dh_retval_decl0_i128 TCGv_i128 retval
#define dh_retvar_decl0_ptr TCGv_ptr retval
+#define dh_retvar_decl0_tl TCGv_tl retval
#define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
#define dh_retvar_decl_void
@@ -84,6 +98,7 @@
#define dh_retvar_decl_i64 TCGv_i64 retval,
#define dh_retvar_decl_i128 TCGv_i128 retval,
#define dh_retvar_decl_ptr TCGv_ptr retval,
+#define dh_retvar_decl_tl TCGv_tl retval,
#define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
#define dh_retvar_void NULL
@@ -92,6 +107,7 @@
#define dh_retvar_i64 tcgv_i64_temp(retval)
#define dh_retvar_i128 tcgv_i128_temp(retval)
#define dh_retvar_ptr tcgv_ptr_temp(retval)
+#define dh_retvar_tl tcgv_tl_temp(retval)
#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
#define dh_typecode_void 0
@@ -115,6 +131,7 @@
#define dh_callflag_i64 0
#define dh_callflag_i128 0
#define dh_callflag_ptr 0
+#define dh_callflag_tl 0
#define dh_callflag_void 0
#define dh_callflag_noreturn TCG_CALL_NO_RETURN
#define dh_callflag(t) glue(dh_callflag_, dh_alias(t))
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ecc1f54c1bf..ba2a1127f92 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2515,6 +2515,8 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
TCGTemp *ret, TCGTemp **args)
{
TCGv_i64 extend_free[MAX_CALL_IARGS];
+ TCGv_i64 ret_temp = NULL;
+ TCGTemp *orig_ret = ret;
int n_extend = 0;
TCGOp *op;
int i, n, pi = 0, total_args;
@@ -2524,6 +2526,19 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
g_once_init_leave(HELPER_INFO_INIT(info), HELPER_INFO_INIT_VAL(info));
}
+ /*
+ * An I32 temp in an i64 slot is zero-extended; s64 is sign-extended.
+ * The call returns the wide temp, then extrl writes the I32 back.
+ */
+ if (ret != NULL && ret->type == TCG_TYPE_I32) {
+ unsigned typecode = info->typemask & 7;
+
+ if (typecode == dh_typecode_i64 || typecode == dh_typecode_s64) {
+ ret_temp = tcg_temp_ebb_new_i64();
+ ret = tcgv_i64_temp(ret_temp);
+ }
+ }
+
total_args = info->nr_out + info->nr_in + 2;
op = tcg_op_alloc(INDEX_op_call, total_args);
@@ -2560,8 +2575,19 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
for (i = 0; i < n; i++) {
const TCGCallArgumentLoc *loc = &info->in[i];
TCGTemp *ts = args[loc->arg_idx] + loc->tmp_subindex;
+ TCGCallArgumentKind kind = loc->kind;
- switch (loc->kind) {
+ if (kind == TCG_CALL_ARG_NORMAL && ts->type == TCG_TYPE_I32) {
+ unsigned typecode =
+ extract32(info->typemask, (loc->arg_idx + 1) * 3, 3);
+
+ if (typecode == dh_typecode_i64 ||
+ typecode == dh_typecode_s64) {
+ kind = TCG_CALL_ARG_EXTEND_U + (typecode & 1);
+ }
+ }
+
+ switch (kind) {
case TCG_CALL_ARG_NORMAL:
case TCG_CALL_ARG_BY_REF:
case TCG_CALL_ARG_BY_REF_N:
@@ -2574,7 +2600,7 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
TCGv_i64 temp = tcg_temp_ebb_new_i64();
TCGv_i32 orig = temp_tcgv_i32(ts);
- if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
+ if (kind == TCG_CALL_ARG_EXTEND_S) {
tcg_gen_ext_i32_i64(temp, orig);
} else {
tcg_gen_extu_i32_i64(temp, orig);
@@ -2602,6 +2628,11 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
for (i = 0; i < n_extend; ++i) {
tcg_temp_free_i64(extend_free[i]);
}
+
+ if (ret_temp != NULL) {
+ tcg_gen_extrl_i64_i32(temp_tcgv_i32(orig_ret), ret_temp);
+ tcg_temp_free_i64(ret_temp);
+ }
}
void tcg_gen_call0(void *func, TCGHelperInfo *info, TCGTemp *ret)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 26/55] accel/tcg: move helper_exit_atomic next to cpu_loop_exit_atomic
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (24 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 25/55] tcg: give common-system helper tl an i64 slot Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 27/55] tcg: move dup_const into tcg.c Yonggang Luo
` (28 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
helper_exit_atomic only forwards to cpu_loop_exit_atomic. Define it
in cpu-exec-common.c with that function, and move its DEF_HELPER line
to cpu-exec-common.h. That file emits helper_info_exit_atomic.
tcg-runtime.c keeps the integer helpers.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/cpu-exec-common.c | 10 ++++++++++
accel/tcg/cpu-exec-common.h | 1 +
accel/tcg/tcg-runtime.c | 8 --------
accel/tcg/tcg-runtime.h | 2 --
include/exec/helper-gen-common.h | 4 ++++
include/exec/helper-proto-common.h | 4 ++++
6 files changed, 19 insertions(+), 10 deletions(-)
create mode 100644 accel/tcg/cpu-exec-common.h
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
index 68077c8fd9d..d20cece1c5f 100644
--- a/accel/tcg/cpu-exec-common.c
+++ b/accel/tcg/cpu-exec-common.c
@@ -23,8 +23,13 @@
#include "qemu/plugin.h"
#include "qemu/main-loop.h"
#include "accel/tcg/cpu-loop.h"
+#include "exec/helper-proto-common.h"
#include "internal-common.h"
+#define HELPER_H "accel/tcg/cpu-exec-common.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
+
bool tcg_allowed;
/*
@@ -120,3 +125,8 @@ void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc)
cpu->exception_index = EXCP_ATOMIC;
cpu_loop_exit_restore(cpu, pc);
}
+
+void HELPER(exit_atomic)(CPUArchState *env)
+{
+ cpu_loop_exit_atomic(env_cpu(env), GETPC());
+}
diff --git a/accel/tcg/cpu-exec-common.h b/accel/tcg/cpu-exec-common.h
new file mode 100644
index 00000000000..922acc2179d
--- /dev/null
+++ b/accel/tcg/cpu-exec-common.h
@@ -0,0 +1 @@
+DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
index 7c0aab98a80..764c62c684d 100644
--- a/accel/tcg/tcg-runtime.c
+++ b/accel/tcg/tcg-runtime.c
@@ -23,10 +23,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
-#include "exec/cpu-common.h"
#include "exec/helper-proto-common.h"
-#include "accel/tcg/cpu-loop.h"
-#include "accel/tcg/getpc.h"
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-info.c.inc"
@@ -129,8 +126,3 @@ uint64_t HELPER(ctpop_i64)(uint64_t arg)
{
return ctpop64(arg);
}
-
-void HELPER(exit_atomic)(CPUArchState *env)
-{
- cpu_loop_exit_atomic(env_cpu(env), GETPC());
-}
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index 0b832176b33..9b4c1c24916 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -22,8 +22,6 @@ DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)
-DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)
-
#ifndef IN_HELPER_PROTO
/*
* Pass calls to memset directly to libc, without a thunk in qemu.
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index 834590dc4e5..ed5521ad881 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -7,6 +7,10 @@
#ifndef HELPER_GEN_COMMON_H
#define HELPER_GEN_COMMON_H
+#define HELPER_H "accel/tcg/cpu-exec-common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-gen.h.inc"
#undef HELPER_H
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 76e6c25becb..28afa7782d0 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -9,6 +9,10 @@
#include "qemu/atomic128.h" /* for HAVE_CMPXCHG128 */
+#define HELPER_H "accel/tcg/cpu-exec-common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-proto.h.inc"
#undef HELPER_H
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 27/55] tcg: move dup_const into tcg.c
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (25 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 26/55] accel/tcg: move helper_exit_atomic next to cpu_loop_exit_atomic Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 28/55] tcg: move goto_tb helpers into tcg-op-ldst.c Yonggang Luo
` (27 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
dup_const replicates a constant by element size. Define it next to
tcg_constant_vec in tcg.c and drop the copy in tcg-op-gvec.c.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
tcg/tcg-op-gvec.c | 17 -----------------
tcg/tcg.c | 17 +++++++++++++++++
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 0d649cc13b2..c30b9d5d6fc 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -417,23 +417,6 @@ static inline bool check_size_impl(uint32_t oprsz, uint32_t lnsz)
static void expand_clr(TCGv_ptr dbase, uint32_t dofs, uint32_t maxsz);
-/* Duplicate C as per VECE. */
-uint64_t (dup_const)(unsigned vece, uint64_t c)
-{
- switch (vece) {
- case MO_8:
- return 0x0101010101010101ull * (uint8_t)c;
- case MO_16:
- return 0x0001000100010001ull * (uint16_t)c;
- case MO_32:
- return 0x0000000100000001ull * (uint32_t)c;
- case MO_64:
- return c;
- default:
- g_assert_not_reached();
- }
-}
-
/* Duplicate IN into OUT as per VECE. */
void tcg_gen_dup_i32(unsigned vece, TCGv_i32 out, TCGv_i32 in)
{
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ba2a1127f92..6362eef36bd 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2287,6 +2287,23 @@ TCGv_ptr tcg_constant_ptr_int(intptr_t val)
return temp_tcgv_ptr(tcg_constant_internal(TCG_TYPE_PTR, val));
}
+/* Duplicate C as per VECE. */
+uint64_t (dup_const)(unsigned vece, uint64_t c)
+{
+ switch (vece) {
+ case MO_8:
+ return 0x0101010101010101ull * (uint8_t)c;
+ case MO_16:
+ return 0x0001000100010001ull * (uint16_t)c;
+ case MO_32:
+ return 0x0000000100000001ull * (uint32_t)c;
+ case MO_64:
+ return c;
+ default:
+ g_assert_not_reached();
+ }
+}
+
TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val)
{
val = dup_const(vece, val);
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 28/55] tcg: move goto_tb helpers into tcg-op-ldst.c
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (26 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 27/55] tcg: move dup_const into tcg.c Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 29/55] accel/tcg: move gvec helpers into tcg-runtime-gvec.h Yonggang Luo
` (26 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
tcg_gen_goto_tb and tcg_gen_lookup_and_goto_ptr call plugin and
lookup_tb_ptr helpers. Define them in tcg-op-ldst.c. tcg_gen_op1i is
static in tcg-op.c, so the moved calls use tcg_gen_op1.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
tcg/tcg-op-ldst.c | 31 +++++++++++++++++++++++++++++++
tcg/tcg-op.c | 32 --------------------------------
2 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
index 22211ccb452..fb13c2f1523 100644
--- a/tcg/tcg-op-ldst.c
+++ b/tcg/tcg-op-ldst.c
@@ -1346,3 +1346,34 @@ GEN_ATOMIC_HELPER128(xchg, mov2, 0)
#undef GEN_ATOMIC_HELPER
#undef GEN_ATOMIC_HELPER128
+
+void tcg_gen_goto_tb(unsigned idx)
+{
+ /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
+ tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
+ /* We only support two chained exits. */
+ tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
+#ifdef CONFIG_DEBUG_TCG
+ /* Verify that we haven't seen this numbered exit before. */
+ tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
+ tcg_ctx->goto_tb_issue_mask |= 1 << idx;
+#endif
+ plugin_gen_disable_mem_helpers();
+ tcg_gen_op1(INDEX_op_goto_tb, 0, idx);
+}
+
+void tcg_gen_lookup_and_goto_ptr(void)
+{
+ TCGv_ptr ptr;
+
+ if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
+ tcg_gen_exit_tb(NULL, 0);
+ return;
+ }
+
+ plugin_gen_disable_mem_helpers();
+ ptr = tcg_temp_ebb_new_ptr();
+ gen_helper_lookup_tb_ptr(ptr, tcg_env);
+ tcg_gen_op1(INDEX_op_goto_ptr, TCG_TYPE_PTR, tcgv_ptr_arg(ptr));
+ tcg_temp_free_ptr(ptr);
+}
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 2c88f4f7ca9..bd3bae37500 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -27,7 +27,6 @@
#include "tcg/tcg-temp-internal.h"
#include "tcg/tcg-op-common.h"
#include "exec/translation-block.h"
-#include "exec/plugin-gen.h"
#include "tcg-internal.h"
#include "tcg-has.h"
@@ -2699,34 +2698,3 @@ void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
tcg_gen_op1i(INDEX_op_exit_tb, 0, val);
}
-
-void tcg_gen_goto_tb(unsigned idx)
-{
- /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
- tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
- /* We only support two chained exits. */
- tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
-#ifdef CONFIG_DEBUG_TCG
- /* Verify that we haven't seen this numbered exit before. */
- tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
- tcg_ctx->goto_tb_issue_mask |= 1 << idx;
-#endif
- plugin_gen_disable_mem_helpers();
- tcg_gen_op1i(INDEX_op_goto_tb, 0, idx);
-}
-
-void tcg_gen_lookup_and_goto_ptr(void)
-{
- TCGv_ptr ptr;
-
- if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
- tcg_gen_exit_tb(NULL, 0);
- return;
- }
-
- plugin_gen_disable_mem_helpers();
- ptr = tcg_temp_ebb_new_ptr();
- gen_helper_lookup_tb_ptr(ptr, tcg_env);
- tcg_gen_op1i(INDEX_op_goto_ptr, TCG_TYPE_PTR, tcgv_ptr_arg(ptr));
- tcg_temp_free_ptr(ptr);
-}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 29/55] accel/tcg: move gvec helpers into tcg-runtime-gvec.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (27 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 28/55] tcg: move goto_tb helpers into tcg-op-ldst.c Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 30/55] accel/tcg: move helper_lookup_tb_ptr into cpu-exec.h Yonggang Luo
` (25 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The gvec helpers are implemented in tcg-runtime-gvec.c. Move their
DEF_HELPER lines to tcg-runtime-gvec.h and emit the helper_info
records from that file.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/tcg-runtime-gvec.c | 3 +
.../tcg/{tcg-runtime.h => tcg-runtime-gvec.h} | 109 ----------
accel/tcg/tcg-runtime.h | 204 ------------------
include/exec/helper-gen-common.h | 4 +
include/exec/helper-proto-common.h | 4 +
5 files changed, 11 insertions(+), 313 deletions(-)
copy accel/tcg/{tcg-runtime.h => tcg-runtime-gvec.h} (71%)
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 67a741e45e1..1bc8fbc31fa 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -22,6 +22,9 @@
#include "exec/helper-proto-common.h"
#include "tcg/tcg-gvec-desc.h"
+#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc)
{
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime-gvec.h
similarity index 71%
copy from accel/tcg/tcg-runtime.h
copy to accel/tcg/tcg-runtime-gvec.h
index 9b4c1c24916..603b0ba8590 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime-gvec.h
@@ -1,112 +1,3 @@
-DEF_HELPER_FLAGS_2(div_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32)
-DEF_HELPER_FLAGS_2(rem_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32)
-DEF_HELPER_FLAGS_2(divu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(remu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-
-DEF_HELPER_FLAGS_2(div_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(rem_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(divu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(remu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(clz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(ctz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(clz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(ctz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-
-DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)
-
-#ifndef IN_HELPER_PROTO
-/*
- * Pass calls to memset directly to libc, without a thunk in qemu.
- * Do not re-declare memset, especially since we fudge the type here;
- * we assume sizeof(void *) == sizeof(size_t), which is true for
- * all supported hosts.
- */
-#define helper_memset memset
-DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr)
-#endif /* IN_HELPER_PROTO */
-
-DEF_HELPER_FLAGS_3(ld_i128, TCG_CALL_NO_WG, i128, env, i64, i32)
-DEF_HELPER_FLAGS_4(st_i128, TCG_CALL_NO_WG, void, env, i64, i128, i32)
-
-DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgw_be, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgw_le, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgl_be, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgl_le, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgq_be, TCG_CALL_NO_WG,
- i64, env, i64, i64, i64, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgq_le, TCG_CALL_NO_WG,
- i64, env, i64, i64, i64, i32)
-#if HAVE_CMPXCHG128
-DEF_HELPER_FLAGS_5(atomic_cmpxchgo_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i128, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgo_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_xchgo_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_xchgo_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_ando_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_ando_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_oro_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_oro_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-#endif
-
-#define GEN_ATOMIC_HELPERS(NAME) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_le), \
- TCG_CALL_NO_WG, i64, env, i64, i64, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_be), \
- TCG_CALL_NO_WG, i64, env, i64, i64, i32)
-
-GEN_ATOMIC_HELPERS(fetch_add)
-GEN_ATOMIC_HELPERS(fetch_and)
-GEN_ATOMIC_HELPERS(fetch_or)
-GEN_ATOMIC_HELPERS(fetch_xor)
-GEN_ATOMIC_HELPERS(fetch_smin)
-GEN_ATOMIC_HELPERS(fetch_umin)
-GEN_ATOMIC_HELPERS(fetch_smax)
-GEN_ATOMIC_HELPERS(fetch_umax)
-
-GEN_ATOMIC_HELPERS(add_fetch)
-GEN_ATOMIC_HELPERS(and_fetch)
-GEN_ATOMIC_HELPERS(or_fetch)
-GEN_ATOMIC_HELPERS(xor_fetch)
-GEN_ATOMIC_HELPERS(smin_fetch)
-GEN_ATOMIC_HELPERS(umin_fetch)
-GEN_ATOMIC_HELPERS(smax_fetch)
-GEN_ATOMIC_HELPERS(umax_fetch)
-
-GEN_ATOMIC_HELPERS(xchg)
-
-#undef GEN_ATOMIC_HELPERS
-
DEF_HELPER_FLAGS_3(gvec_mov, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(gvec_dup8, TCG_CALL_NO_RWG, void, ptr, i32, i32)
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index 9b4c1c24916..c0626fa0e02 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -106,207 +106,3 @@ GEN_ATOMIC_HELPERS(umax_fetch)
GEN_ATOMIC_HELPERS(xchg)
#undef GEN_ATOMIC_HELPERS
-
-DEF_HELPER_FLAGS_3(gvec_mov, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_dup8, TCG_CALL_NO_RWG, void, ptr, i32, i32)
-DEF_HELPER_FLAGS_3(gvec_dup16, TCG_CALL_NO_RWG, void, ptr, i32, i32)
-DEF_HELPER_FLAGS_3(gvec_dup32, TCG_CALL_NO_RWG, void, ptr, i32, i32)
-DEF_HELPER_FLAGS_3(gvec_dup64, TCG_CALL_NO_RWG, void, ptr, i32, i64)
-
-DEF_HELPER_FLAGS_4(gvec_add8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_add16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_add32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_add64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_adds8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_adds16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_adds32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_adds64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_sub8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sub16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sub32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sub64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_subs8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_subs16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_subs32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_subs64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_mul8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_mul16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_mul32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_mul64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_muls8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_muls16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_muls32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_muls64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ssadd8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ssadd16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ssadd32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ssadd64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_sssub8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sssub16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sssub32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sssub64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_usadd8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_usadd16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_usadd32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_usadd64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ussub8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ussub16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ussub32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ussub64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_smin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_smax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_smax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_umin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_umax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_umax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_neg8, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_neg16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_neg32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_neg64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_abs8, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_abs16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_abs32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_abs64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_not, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_and, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_or, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_xor, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_andc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_orc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_nand, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_nor, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_eqv, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ands, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_andcs, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_xors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_ors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_3(gvec_shl8i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shl16i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shl32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shl64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_shr8i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shr16i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shr32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_shr64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_sar8i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_sar16i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_sar32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_sar64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_3(gvec_rotl8i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_rotl16i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_rotl32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(gvec_rotl64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_shl8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shl16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shl32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shl64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_shr8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shr16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shr32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_shr64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_sar8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sar16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sar32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_sar64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_rotl8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotl16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotl32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotl64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_rotr8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotr16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotr32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_rotr64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_eq8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_eq16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_eq32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_eq64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ne8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ne16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ne32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ne64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_lt8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_lt16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_lt32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_lt64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_le8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_le16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_le32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_le64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ltu8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ltu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ltu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_ltu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_leu8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-
-DEF_HELPER_FLAGS_4(gvec_eqs8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_eqs16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_eqs32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_eqs64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_lts8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_lts16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_lts32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_lts64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_les8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_les16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_les32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_les64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_ltus8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_ltus16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_ltus32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_ltus64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_4(gvec_leus8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_leus16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_leus32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_leus64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
-
-DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index ed5521ad881..fa571d88147 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -15,4 +15,8 @@
#include "exec/helper-gen.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
#endif /* HELPER_GEN_COMMON_H */
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 28afa7782d0..1b098777e8d 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -17,6 +17,10 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
#include "accel/tcg/getpc.h"
#endif /* HELPER_PROTO_COMMON_H */
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 30/55] accel/tcg: move helper_lookup_tb_ptr into cpu-exec.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (28 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 29/55] accel/tcg: move gvec helpers into tcg-runtime-gvec.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h Yonggang Luo
` (24 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
helper_lookup_tb_ptr is implemented in cpu-exec.c. Move its
DEF_HELPER line to cpu-exec.h and emit helper_info_lookup_tb_ptr
from that file.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/cpu-exec.c | 5 +++++
accel/tcg/cpu-exec.h | 1 +
accel/tcg/tcg-runtime.h | 2 --
include/exec/helper-gen-common.h | 4 ++++
include/exec/helper-proto-common.h | 4 ++++
5 files changed, 14 insertions(+), 2 deletions(-)
create mode 100644 accel/tcg/cpu-exec.h
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 5b4bca5084f..021912dc022 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -40,6 +40,11 @@
#include "exec/replay-core.h"
#include "system/tcg.h"
#include "exec/helper-proto-common.h"
+
+#define HELPER_H "accel/tcg/cpu-exec.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
+
#include "tcg-accel-ops.h"
#include "tb-jmp-cache.h"
#include "tb-hash.h"
diff --git a/accel/tcg/cpu-exec.h b/accel/tcg/cpu-exec.h
new file mode 100644
index 00000000000..e4803ebc1a6
--- /dev/null
+++ b/accel/tcg/cpu-exec.h
@@ -0,0 +1 @@
+DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index c0626fa0e02..26e0baeca51 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -20,8 +20,6 @@ DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)
-
#ifndef IN_HELPER_PROTO
/*
* Pass calls to memset directly to libc, without a thunk in qemu.
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index fa571d88147..73e979a35f3 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -11,6 +11,10 @@
#include "exec/helper-gen.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/cpu-exec.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-gen.h.inc"
#undef HELPER_H
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 1b098777e8d..3c32f95f4c1 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -13,6 +13,10 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/cpu-exec.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-proto.h.inc"
#undef HELPER_H
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (29 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 30/55] accel/tcg: move helper_lookup_tb_ptr into cpu-exec.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 10:40 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 32/55] tests/unit: cover common-system tl dispatch and calls Yonggang Luo
` (23 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
memset, ld_i128, and st_i128 are declared in ldst_common.h, and
ldst_common.c.inc emits their helper info. Atomic helpers move to
atomic_common.h, with info records emitted from atomic_common.c.inc.
tcg-runtime.h keeps the integer helpers implemented in tcg-runtime.c.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/atomic_common.c.inc | 4 +
accel/tcg/{tcg-runtime.h => atomic_common.h} | 36 ---------
accel/tcg/ldst_common.c.inc | 4 +
accel/tcg/ldst_common.h | 13 +++
accel/tcg/tcg-runtime.h | 85 --------------------
include/exec/helper-gen-common.h | 8 ++
include/exec/helper-proto-common.h | 8 ++
7 files changed, 37 insertions(+), 121 deletions(-)
copy accel/tcg/{tcg-runtime.h => atomic_common.h} (65%)
create mode 100644 accel/tcg/ldst_common.h
diff --git a/accel/tcg/atomic_common.c.inc b/accel/tcg/atomic_common.c.inc
index 7d779dd51db..a24250be75e 100644
--- a/accel/tcg/atomic_common.c.inc
+++ b/accel/tcg/atomic_common.c.inc
@@ -101,3 +101,7 @@ ATOMIC_HELPER(fetch_oro_le, Int128)
#undef ATOMIC_HELPER
#undef GEN_ATOMIC_HELPERS
+
+#define HELPER_H "accel/tcg/atomic_common.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/atomic_common.h
similarity index 65%
copy from accel/tcg/tcg-runtime.h
copy to accel/tcg/atomic_common.h
index 26e0baeca51..4fee73cf916 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/atomic_common.h
@@ -1,39 +1,3 @@
-DEF_HELPER_FLAGS_2(div_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32)
-DEF_HELPER_FLAGS_2(rem_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32)
-DEF_HELPER_FLAGS_2(divu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(remu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-
-DEF_HELPER_FLAGS_2(div_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(rem_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(divu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(remu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
-DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(clz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(ctz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(clz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(ctz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-
-#ifndef IN_HELPER_PROTO
-/*
- * Pass calls to memset directly to libc, without a thunk in qemu.
- * Do not re-declare memset, especially since we fudge the type here;
- * we assume sizeof(void *) == sizeof(size_t), which is true for
- * all supported hosts.
- */
-#define helper_memset memset
-DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr)
-#endif /* IN_HELPER_PROTO */
-
-DEF_HELPER_FLAGS_3(ld_i128, TCG_CALL_NO_WG, i128, env, i64, i32)
-DEF_HELPER_FLAGS_4(st_i128, TCG_CALL_NO_WG, void, env, i64, i128, i32)
-
DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG,
i32, env, i64, i32, i32, i32)
DEF_HELPER_FLAGS_5(atomic_cmpxchgw_be, TCG_CALL_NO_WG,
diff --git a/accel/tcg/ldst_common.c.inc b/accel/tcg/ldst_common.c.inc
index 57f3e061924..bf74d65dd75 100644
--- a/accel/tcg/ldst_common.c.inc
+++ b/accel/tcg/ldst_common.c.inc
@@ -119,6 +119,10 @@ void helper_st_i128(CPUArchState *env, uint64_t addr, Int128 val, MemOpIdx oi)
helper_st16_mmu(env, addr, val, oi, GETPC());
}
+#define HELPER_H "accel/tcg/ldst_common.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
+
/*
* Load helpers for cpu_ldst.h
*/
diff --git a/accel/tcg/ldst_common.h b/accel/tcg/ldst_common.h
new file mode 100644
index 00000000000..cec4751ff16
--- /dev/null
+++ b/accel/tcg/ldst_common.h
@@ -0,0 +1,13 @@
+#ifndef IN_HELPER_PROTO
+/*
+ * Pass calls to memset directly to libc, without a thunk in qemu.
+ * Do not re-declare memset, especially since we fudge the type here;
+ * we assume sizeof(void *) == sizeof(size_t), which is true for
+ * all supported hosts.
+ */
+#define helper_memset memset
+DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr)
+#endif /* IN_HELPER_PROTO */
+
+DEF_HELPER_FLAGS_3(ld_i128, TCG_CALL_NO_WG, i128, env, i64, i32)
+DEF_HELPER_FLAGS_4(st_i128, TCG_CALL_NO_WG, void, env, i64, i128, i32)
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index 26e0baeca51..d635e6b708b 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -19,88 +19,3 @@ DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
-
-#ifndef IN_HELPER_PROTO
-/*
- * Pass calls to memset directly to libc, without a thunk in qemu.
- * Do not re-declare memset, especially since we fudge the type here;
- * we assume sizeof(void *) == sizeof(size_t), which is true for
- * all supported hosts.
- */
-#define helper_memset memset
-DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr)
-#endif /* IN_HELPER_PROTO */
-
-DEF_HELPER_FLAGS_3(ld_i128, TCG_CALL_NO_WG, i128, env, i64, i32)
-DEF_HELPER_FLAGS_4(st_i128, TCG_CALL_NO_WG, void, env, i64, i128, i32)
-
-DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgw_be, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgw_le, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgl_be, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgl_le, TCG_CALL_NO_WG,
- i32, env, i64, i32, i32, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgq_be, TCG_CALL_NO_WG,
- i64, env, i64, i64, i64, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgq_le, TCG_CALL_NO_WG,
- i64, env, i64, i64, i64, i32)
-#if HAVE_CMPXCHG128
-DEF_HELPER_FLAGS_5(atomic_cmpxchgo_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i128, i32)
-DEF_HELPER_FLAGS_5(atomic_cmpxchgo_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_xchgo_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_xchgo_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_ando_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_ando_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_oro_be, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-DEF_HELPER_FLAGS_4(atomic_fetch_oro_le, TCG_CALL_NO_WG,
- i128, env, i64, i128, i32)
-#endif
-
-#define GEN_ATOMIC_HELPERS(NAME) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \
- TCG_CALL_NO_WG, i32, env, i64, i32, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_le), \
- TCG_CALL_NO_WG, i64, env, i64, i64, i32) \
- DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_be), \
- TCG_CALL_NO_WG, i64, env, i64, i64, i32)
-
-GEN_ATOMIC_HELPERS(fetch_add)
-GEN_ATOMIC_HELPERS(fetch_and)
-GEN_ATOMIC_HELPERS(fetch_or)
-GEN_ATOMIC_HELPERS(fetch_xor)
-GEN_ATOMIC_HELPERS(fetch_smin)
-GEN_ATOMIC_HELPERS(fetch_umin)
-GEN_ATOMIC_HELPERS(fetch_smax)
-GEN_ATOMIC_HELPERS(fetch_umax)
-
-GEN_ATOMIC_HELPERS(add_fetch)
-GEN_ATOMIC_HELPERS(and_fetch)
-GEN_ATOMIC_HELPERS(or_fetch)
-GEN_ATOMIC_HELPERS(xor_fetch)
-GEN_ATOMIC_HELPERS(smin_fetch)
-GEN_ATOMIC_HELPERS(umin_fetch)
-GEN_ATOMIC_HELPERS(smax_fetch)
-GEN_ATOMIC_HELPERS(umax_fetch)
-
-GEN_ATOMIC_HELPERS(xchg)
-
-#undef GEN_ATOMIC_HELPERS
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index 73e979a35f3..5943a3aedf0 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -19,6 +19,14 @@
#include "exec/helper-gen.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/ldst_common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/atomic_common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
#include "exec/helper-gen.h.inc"
#undef HELPER_H
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 3c32f95f4c1..eabe7828047 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -21,6 +21,14 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/ldst_common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/atomic_common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
#include "exec/helper-proto.h.inc"
#undef HELPER_H
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 32/55] tests/unit: cover common-system tl dispatch and calls
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (30 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 33/55] target/arm: fix A64 guest address width at 64 Yonggang Luo
` (22 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
test-tcg-op calls bswap32_tl, revbit32_tl, trunc, and ext from a
common build and checks the i32 or i64 callee, including the 32-bit
flag drop. dup_const_tl is checked for MO_8, MO_16, and MO_32.
Per-target tests cover both fixed widths.
The call test checks the tl alias and C type for a common build and
for both per-target widths. tcg_gen_callN zero-extends an I32 temp
into an i64 slot, sign-extends it into an s64 slot, and truncates an
i64 return back to I32.
Both tests link through tcg_core_deps. That list starts empty and,
with TCG enabled, holds the tcg_core objects already built into
libsystem, pagevary, and stubs for disas and the qemu ld/st helpers.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/meson.build | 2 +-
meson.build | 16 ++
tcg/meson.build | 9 +-
tests/unit/meson.build | 20 ++
tests/unit/test-helper-tl.c | 20 ++
tests/unit/test-helper-tl.h | 25 +++
tests/unit/test-helper-tl32.c | 27 +++
tests/unit/test-helper-tl64.c | 27 +++
tests/unit/test-tcg-call-tl-stubs.c | 45 +++++
tests/unit/test-tcg-call-tl.c | 280 ++++++++++++++++++++++++++++
tests/unit/test-tcg-op-dispatch.h | 203 ++++++++++++++++++++
tests/unit/test-tcg-op-tl32.c | 24 +++
tests/unit/test-tcg-op-tl64.c | 24 +++
tests/unit/test-tcg-op.c | 66 +++++++
14 files changed, 784 insertions(+), 4 deletions(-)
create mode 100644 tests/unit/test-helper-tl.c
create mode 100644 tests/unit/test-helper-tl.h
create mode 100644 tests/unit/test-helper-tl32.c
create mode 100644 tests/unit/test-helper-tl64.c
create mode 100644 tests/unit/test-tcg-call-tl-stubs.c
create mode 100644 tests/unit/test-tcg-call-tl.c
create mode 100644 tests/unit/test-tcg-op-dispatch.h
create mode 100644 tests/unit/test-tcg-op-tl32.c
create mode 100644 tests/unit/test-tcg-op-tl64.c
create mode 100644 tests/unit/test-tcg-op.c
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index 002aa8f4588..21da63c252f 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -3,11 +3,11 @@ if not have_tcg
endif
tcg_ss = ss.source_set()
+tcg_core.add(files('tcg-runtime.c'))
tcg_ss.add(files(
'cpu-exec.c',
'cpu-exec-common.c',
- 'tcg-runtime.c',
'tcg-runtime-gvec.c',
'tb-maint.c',
'tcg-all.c',
diff --git a/meson.build b/meson.build
index 9485f4e97be..d5639a2d676 100644
--- a/meson.build
+++ b/meson.build
@@ -3731,6 +3731,8 @@ stub_ss = ss.source_set()
trace_ss = ss.source_set()
user_ss = ss.source_set()
util_ss = ss.source_set()
+tcg_core = ss.source_set()
+tcg_core_deps = []
# accel modules
qtest_module_ss = ss.source_set()
@@ -4139,6 +4141,20 @@ libsystem = static_library('system',
dependencies: system_ss.all_dependencies(),
build_by_default: false)
+if have_tcg
+ # tcg_core is compiled into libsystem. Reuse those objects.
+ # page-vary-common.c is in common_all, not tcg_core.
+ tcg_core_deps = files('tests/unit/test-tcg-call-tl-stubs.c') + [
+ declare_dependency(
+ objects: libsystem.extract_objects(tcg_core.all_sources()),
+ compile_args: [
+ '-DCOMPILING_SYSTEM_VS_USER',
+ '-DCONFIG_SOFTMMU',
+ ]),
+ ]
+ tcg_core_deps += pagevary
+endif
+
# Note that this library is never used directly (only through extract_objects)
# and is not built by default; therefore, source files not used by the build
# configuration will be in build.ninja, but are never built by default.
diff --git a/tcg/meson.build b/tcg/meson.build
index 706a6eb260e..dced8eb781c 100644
--- a/tcg/meson.build
+++ b/tcg/meson.build
@@ -4,15 +4,17 @@ endif
tcg_ss = ss.source_set()
-tcg_ss.add(files(
+tcg_core.add(files(
'optimize.c',
'region.c',
'tcg.c',
'tcg-common.c',
'tcg-op.c',
+ 'tcg-op-vec.c',
+))
+tcg_ss.add(files(
'tcg-op-ldst.c',
'tcg-op-gvec.c',
- 'tcg-op-vec.c',
))
if get_option('tcg_interpreter')
@@ -24,8 +26,9 @@ endif
tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
if host_os == 'linux'
- tcg_ss.add(files('perf.c'))
+ tcg_core.add(files('perf.c'))
endif
+tcg_ss.add_all(tcg_core)
user_ss.add_all(tcg_ss)
system_ss.add_all(tcg_ss)
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index dc139889c1d..552f96e37dd 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -43,6 +43,13 @@ tests = {
'test-qgraph': ['../qtest/libqos/qgraph.c'],
'check-qom-interface': [qom],
'check-qom-proplist': [qom],
+ 'test-tcg-op': [qom] + tcg_core_deps,
+ 'test-tcg-op-tl32': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config32.h"'])],
+ 'test-tcg-op-tl64': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config64.h"'])],
'test-tcg-op-mem': [qom],
'test-tcg-op-mem-tl32': [declare_dependency(compile_args: [
'-DCOMPILING_PER_TARGET',
@@ -53,6 +60,13 @@ tests = {
'test-tcg-op-mem-va32-tl64': [declare_dependency(compile_args: [
'-DCOMPILING_PER_TARGET',
'-DCONFIG_TARGET="test-tcg-op-mem-config64.h"'])],
+ 'test-helper-tl': [],
+ 'test-helper-tl32': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config32.h"'])],
+ 'test-helper-tl64': [declare_dependency(compile_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="test-tcg-op-mem-config64.h"'])],
'test-target-info': [qom, declare_dependency(
objects: target_info_def_objects.values(),
compile_args: ['-DTARGET_INFO_DEF_COUNT=@0@'.format(
@@ -67,6 +81,12 @@ tests = {
'test-envlist': [],
}
+if have_tcg
+ tests += {
+ 'test-tcg-call-tl': tcg_core_deps,
+ }
+endif
+
if have_system or have_tools
tests += {
'test-qmp-event': [testqapi],
diff --git a/tests/unit/test-helper-tl.c b/tests/unit/test-helper-tl.c
new file mode 100644
index 00000000000..47719ccd95f
--- /dev/null
+++ b/tests/unit/test-helper-tl.c
@@ -0,0 +1,20 @@
+/*
+ * Common-system tl helper slot stays an i64 C type.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "exec/helper-head.h.inc"
+
+#define HELPER_TL_EXPECT_TYPECODE dh_typecode_i64
+#define HELPER_TL_EXPECT_CTYPE uint64_t
+#include "test-helper-tl.h"
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/helper-tl/alias", test_helper_tl_alias);
+ g_test_add_func("/tcg/helper-tl/slot", test_helper_tl_slot);
+ return g_test_run();
+}
diff --git a/tests/unit/test-helper-tl.h b/tests/unit/test-helper-tl.h
new file mode 100644
index 00000000000..3ab660217f4
--- /dev/null
+++ b/tests/unit/test-helper-tl.h
@@ -0,0 +1,25 @@
+/*
+ * Shared checks for the tl helper slot.
+ *
+ * The including file defines HELPER_TL_EXPECT_TYPECODE and
+ * HELPER_TL_EXPECT_CTYPE after including exec/helper-head.h.inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+static void test_helper_tl_alias(void)
+{
+#define HELPER_TL_ALIAS_PROBE_tl 1
+#define HELPER_TL_ALIAS_PROBE_i32 0
+#define HELPER_TL_ALIAS_PROBE_i64 0
+ g_assert_cmpint(glue(HELPER_TL_ALIAS_PROBE_, dh_alias(tl)), ==, 1);
+}
+
+static void test_helper_tl_slot(void)
+{
+ g_assert_cmpint(dh_typecode(tl), ==, HELPER_TL_EXPECT_TYPECODE);
+ g_assert_cmpint(dh_typemask(tl, 0), ==, HELPER_TL_EXPECT_TYPECODE);
+ g_assert_cmpint(dh_callflag(tl), ==, 0);
+ g_assert_true(__builtin_types_compatible_p(dh_ctype(tl),
+ HELPER_TL_EXPECT_CTYPE));
+}
diff --git a/tests/unit/test-helper-tl32.c b/tests/unit/test-helper-tl32.c
new file mode 100644
index 00000000000..1e99c22d6a9
--- /dev/null
+++ b/tests/unit/test-helper-tl32.c
@@ -0,0 +1,27 @@
+/*
+ * Per-target tl helper slot with TARGET_LONG_BITS == 32.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "exec/helper-head.h.inc"
+
+#define HELPER_TL_EXPECT_TYPECODE dh_typecode_i32
+#define HELPER_TL_EXPECT_CTYPE uint32_t
+#include "test-helper-tl.h"
+
+static void test_helper_tl32_ctype(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 32);
+ g_assert_true(__builtin_types_compatible_p(dh_ctype(tl), target_ulong));
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/helper-tl/tl32-alias", test_helper_tl_alias);
+ g_test_add_func("/tcg/helper-tl/tl32-slot", test_helper_tl_slot);
+ g_test_add_func("/tcg/helper-tl/tl32-ctype", test_helper_tl32_ctype);
+ return g_test_run();
+}
diff --git a/tests/unit/test-helper-tl64.c b/tests/unit/test-helper-tl64.c
new file mode 100644
index 00000000000..499a84bbf62
--- /dev/null
+++ b/tests/unit/test-helper-tl64.c
@@ -0,0 +1,27 @@
+/*
+ * Per-target tl helper slot with TARGET_LONG_BITS == 64.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "exec/helper-head.h.inc"
+
+#define HELPER_TL_EXPECT_TYPECODE dh_typecode_i64
+#define HELPER_TL_EXPECT_CTYPE uint64_t
+#include "test-helper-tl.h"
+
+static void test_helper_tl64_ctype(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 64);
+ g_assert_true(__builtin_types_compatible_p(dh_ctype(tl), target_ulong));
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/helper-tl/tl64-alias", test_helper_tl_alias);
+ g_test_add_func("/tcg/helper-tl/tl64-slot", test_helper_tl_slot);
+ g_test_add_func("/tcg/helper-tl/tl64-ctype", test_helper_tl64_ctype);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-call-tl-stubs.c b/tests/unit/test-tcg-call-tl-stubs.c
new file mode 100644
index 00000000000..ec1414b88ba
--- /dev/null
+++ b/tests/unit/test-tcg-call-tl-stubs.c
@@ -0,0 +1,45 @@
+/*
+ * Stubs for symbols referenced by extracted tcg_core objects.
+ * The call-slot test does not execute these paths.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/helper-info.h"
+
+void disas(FILE *out, const void *code, size_t size);
+void helper_ldub_mmu(void);
+void helper_lduw_mmu(void);
+void helper_ldul_mmu(void);
+void helper_ldq_mmu(void);
+void helper_ld16_mmu(void);
+void helper_ldsb_mmu(void);
+void helper_ldsw_mmu(void);
+void helper_ldsl_mmu(void);
+void helper_stb_mmu(void);
+void helper_stw_mmu(void);
+void helper_stl_mmu(void);
+void helper_stq_mmu(void);
+void helper_st16_mmu(void);
+
+void disas(FILE *out, const void *code, size_t size)
+{
+ (void)out;
+ (void)code;
+ (void)size;
+}
+
+void helper_ldub_mmu(void) {}
+void helper_lduw_mmu(void) {}
+void helper_ldul_mmu(void) {}
+void helper_ldq_mmu(void) {}
+void helper_ld16_mmu(void) {}
+void helper_ldsb_mmu(void) {}
+void helper_ldsw_mmu(void) {}
+void helper_ldsl_mmu(void) {}
+void helper_stb_mmu(void) {}
+void helper_stw_mmu(void) {}
+void helper_stl_mmu(void) {}
+void helper_stq_mmu(void) {}
+void helper_st16_mmu(void) {}
diff --git a/tests/unit/test-tcg-call-tl.c b/tests/unit/test-tcg-call-tl.c
new file mode 100644
index 00000000000..fc39bbaabae
--- /dev/null
+++ b/tests/unit/test-tcg-call-tl.c
@@ -0,0 +1,280 @@
+/*
+ * Execute tcg_gen_callN when an I32 temp meets an i64 or s64 slot.
+ *
+ * The common-system tl helper uses a fixed i64 C slot. tcg_gen_callN
+ * zero-extends an I32 argument into that slot, sign-extends an I32
+ * argument into an s64 slot, and truncates an i64 or s64 return back
+ * to an I32 temp. A matching width leaves the call op alone.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op-common.h"
+
+static TCGContext *ctx;
+
+static void dummy_helper(void)
+{
+}
+
+static void reset_ctx(void)
+{
+ if (!ctx) {
+ ctx = g_new0(TCGContext, 1);
+ tcg_ctx = ctx;
+ }
+ tcg_func_start(ctx);
+}
+
+static TCGTemp *new_temp(TCGType type)
+{
+ if (type == TCG_TYPE_I32) {
+ return tcgv_i32_temp(tcg_temp_new_i32());
+ }
+ return tcgv_i64_temp(tcg_temp_new_i64());
+}
+
+static void prep_info(TCGHelperInfo *info, unsigned typemask)
+{
+ if (!info->func) {
+ info->func = dummy_helper;
+ info->typemask = typemask;
+ info->flags = TCG_CALL_NO_SIDE_EFFECTS;
+ }
+}
+
+static int collect_ops(TCGOpcode *out, int max)
+{
+ TCGOp *op;
+ int n = 0;
+
+ QTAILQ_FOREACH(op, &ctx->ops, link) {
+ g_assert_cmpint(n, <, max);
+ out[n++] = op->opc;
+ }
+ return n;
+}
+
+static void assert_ops(const TCGOpcode *exp, int nexp)
+{
+ TCGOpcode got[8];
+ int n = collect_ops(got, ARRAY_SIZE(got));
+ int i;
+
+ g_assert_cmpint(n, ==, nexp);
+ for (i = 0; i < n; i++) {
+ g_assert_cmpint(got[i], ==, exp[i]);
+ }
+}
+
+static void assert_call_shape(int nr_out, int nr_in)
+{
+ TCGOp *op;
+ int calls = 0;
+
+ QTAILQ_FOREACH(op, &ctx->ops, link) {
+ if (op->opc == INDEX_op_call) {
+ g_assert_cmpint(TCGOP_CALLO(op), ==, nr_out);
+ g_assert_cmpint(TCGOP_CALLI(op), ==, nr_in);
+ calls++;
+ }
+ }
+ g_assert_cmpint(calls, ==, 1);
+}
+
+static void emit_call1(TCGHelperInfo *info, bool has_ret,
+ TCGType ret_type, TCGType arg_type)
+{
+ TCGTemp *ret = NULL;
+ TCGTemp *arg;
+
+ reset_ctx();
+ if (has_ret) {
+ ret = new_temp(ret_type);
+ }
+ arg = new_temp(arg_type);
+ tcg_gen_call1(dummy_helper, info, ret, arg);
+}
+
+static void emit_call2(TCGHelperInfo *info, TCGType arg0, TCGType arg1)
+{
+ TCGTemp *a0, *a1;
+
+ reset_ctx();
+ a0 = new_temp(arg0);
+ a1 = new_temp(arg1);
+ tcg_gen_call2(dummy_helper, info, NULL, a0, a1);
+}
+
+static void test_i32_arg_i64_ret(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_extu_i32_i64,
+ INDEX_op_call,
+ INDEX_op_extrl_i64_i32,
+ };
+
+ prep_info(&info, dh_typemask(i64, 0) | dh_typemask(i64, 1));
+ emit_call1(&info, true, TCG_TYPE_I32, TCG_TYPE_I32);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(1, 1);
+}
+
+static void test_i32_arg_s64_ret(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_ext_i32_i64,
+ INDEX_op_call,
+ INDEX_op_extrl_i64_i32,
+ };
+
+ prep_info(&info, dh_typemask(s64, 0) | dh_typemask(s64, 1));
+ emit_call1(&info, true, TCG_TYPE_I32, TCG_TYPE_I32);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(1, 1);
+}
+
+static void test_i64_arg_i64_ret(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = { INDEX_op_call };
+
+ prep_info(&info, dh_typemask(i64, 0) | dh_typemask(i64, 1));
+ emit_call1(&info, true, TCG_TYPE_I64, TCG_TYPE_I64);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(1, 1);
+}
+
+static void test_i64_arg_i32_ret(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_call,
+ INDEX_op_extrl_i64_i32,
+ };
+
+ prep_info(&info, dh_typemask(i64, 0) | dh_typemask(i64, 1));
+ emit_call1(&info, true, TCG_TYPE_I32, TCG_TYPE_I64);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(1, 1);
+}
+
+static void test_void_i32_arg_i64(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_extu_i32_i64,
+ INDEX_op_call,
+ };
+
+ prep_info(&info, dh_typemask(void, 0) | dh_typemask(i64, 1));
+ emit_call1(&info, false, 0, TCG_TYPE_I32);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(0, 1);
+}
+
+/*
+ * An i32 or s32 slot keeps the host ABI kind. tcg_gen_callN must not
+ * also apply the i64-slot extend, and must not truncate the return.
+ */
+static void test_i32_slot(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[2];
+ int n = 0;
+
+ prep_info(&info, dh_typemask(i32, 0) | dh_typemask(i32, 1));
+ emit_call1(&info, true, TCG_TYPE_I32, TCG_TYPE_I32);
+ if (info.in[0].kind == TCG_CALL_ARG_EXTEND_U) {
+ exp[n++] = INDEX_op_extu_i32_i64;
+ } else if (info.in[0].kind == TCG_CALL_ARG_EXTEND_S) {
+ exp[n++] = INDEX_op_ext_i32_i64;
+ } else {
+ g_assert_cmpint(info.in[0].kind, ==, TCG_CALL_ARG_NORMAL);
+ }
+ exp[n++] = INDEX_op_call;
+ assert_ops(exp, n);
+ assert_call_shape(1, 1);
+}
+
+static void test_s32_slot(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[2];
+ int n = 0;
+
+ prep_info(&info, dh_typemask(s32, 0) | dh_typemask(s32, 1));
+ emit_call1(&info, true, TCG_TYPE_I32, TCG_TYPE_I32);
+ if (info.in[0].kind == TCG_CALL_ARG_EXTEND_U) {
+ exp[n++] = INDEX_op_extu_i32_i64;
+ } else if (info.in[0].kind == TCG_CALL_ARG_EXTEND_S) {
+ exp[n++] = INDEX_op_ext_i32_i64;
+ } else {
+ g_assert_cmpint(info.in[0].kind, ==, TCG_CALL_ARG_NORMAL);
+ }
+ exp[n++] = INDEX_op_call;
+ assert_ops(exp, n);
+ assert_call_shape(1, 1);
+}
+
+static void test_i32_arg_ptr_slot(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = { INDEX_op_call };
+
+ prep_info(&info, dh_typemask(ptr, 0) | dh_typemask(ptr, 1));
+ emit_call1(&info, true, TCG_TYPE_PTR, TCG_TYPE_I32);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(1, 1);
+}
+
+static void test_two_args_i32_then_i64(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_extu_i32_i64,
+ INDEX_op_call,
+ };
+
+ prep_info(&info, dh_typemask(void, 0) | dh_typemask(i64, 1) |
+ dh_typemask(i64, 2));
+ emit_call2(&info, TCG_TYPE_I32, TCG_TYPE_I64);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(0, 2);
+}
+
+static void test_two_args_i64_then_s64(void)
+{
+ static TCGHelperInfo info;
+ TCGOpcode exp[] = {
+ INDEX_op_ext_i32_i64,
+ INDEX_op_call,
+ };
+
+ prep_info(&info, dh_typemask(void, 0) | dh_typemask(i64, 1) |
+ dh_typemask(s64, 2));
+ emit_call2(&info, TCG_TYPE_I64, TCG_TYPE_I32);
+ assert_ops(exp, ARRAY_SIZE(exp));
+ assert_call_shape(0, 2);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/call-tl/i32-arg-i64-ret", test_i32_arg_i64_ret);
+ g_test_add_func("/tcg/call-tl/i32-arg-s64-ret", test_i32_arg_s64_ret);
+ g_test_add_func("/tcg/call-tl/i64-arg-i64-ret", test_i64_arg_i64_ret);
+ g_test_add_func("/tcg/call-tl/i64-arg-i32-ret", test_i64_arg_i32_ret);
+ g_test_add_func("/tcg/call-tl/void-i32-arg-i64", test_void_i32_arg_i64);
+ g_test_add_func("/tcg/call-tl/i32-slot", test_i32_slot);
+ g_test_add_func("/tcg/call-tl/s32-slot", test_s32_slot);
+ g_test_add_func("/tcg/call-tl/i32-arg-ptr-slot", test_i32_arg_ptr_slot);
+ g_test_add_func("/tcg/call-tl/two-args-i32-then-i64",
+ test_two_args_i32_then_i64);
+ g_test_add_func("/tcg/call-tl/two-args-i64-then-s64",
+ test_two_args_i64_then_s64);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op-dispatch.h b/tests/unit/test-tcg-op-dispatch.h
new file mode 100644
index 00000000000..991126b3743
--- /dev/null
+++ b/tests/unit/test-tcg-op-dispatch.h
@@ -0,0 +1,203 @@
+/*
+ * Intercept tcg_gen_* callees so tcg-op-tl.h dispatch can be called
+ * without a TCG context.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef TEST_TCG_OP_DISPATCH_H
+#define TEST_TCG_OP_DISPATCH_H
+
+#include "tcg/tcg.h"
+
+static struct {
+ int bswap32_i32;
+ int bswap32_i64;
+ int bswap32_i64_flags;
+ int revbit32_i32;
+ int revbit32_i64;
+ int revbit32_i64_flags;
+ int mov_i32;
+ int mov_i64;
+ int extrl_i64_i32;
+ int extu_i32_i64;
+ int ext_i32_i64;
+} tcg_op_test_saw;
+
+#define tcg_gen_bswap32_i32 tcg_op_test_record_bswap32_i32
+#define tcg_gen_bswap32_i64 tcg_op_test_record_bswap32_i64
+#define tcg_gen_revbit32_i32 tcg_op_test_record_revbit32_i32
+#define tcg_gen_revbit32_i64 tcg_op_test_record_revbit32_i64
+#define tcg_gen_mov_i32 tcg_op_test_record_mov_i32
+#define tcg_gen_mov_i64 tcg_op_test_record_mov_i64
+#define tcg_gen_extrl_i64_i32 tcg_op_test_record_extrl_i64_i32
+#define tcg_gen_extu_i32_i64 tcg_op_test_record_extu_i32_i64
+#define tcg_gen_ext_i32_i64 tcg_op_test_record_ext_i32_i64
+
+#include "tcg/tcg-op.h"
+
+void tcg_op_test_record_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
+{
+ tcg_op_test_saw.bswap32_i32++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
+{
+ tcg_op_test_saw.bswap32_i64++;
+ tcg_op_test_saw.bswap32_i64_flags = flags;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_revbit32_i32(TCGv_i32 ret, TCGv_i32 arg)
+{
+ tcg_op_test_saw.revbit32_i32++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_revbit32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
+{
+ tcg_op_test_saw.revbit32_i64++;
+ tcg_op_test_saw.revbit32_i64_flags = flags;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
+{
+ tcg_op_test_saw.mov_i32++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
+{
+ tcg_op_test_saw.mov_i64++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
+{
+ tcg_op_test_saw.extrl_i64_i32++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
+{
+ tcg_op_test_saw.extu_i32_i64++;
+ (void)ret;
+ (void)arg;
+}
+
+void tcg_op_test_record_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
+{
+ tcg_op_test_saw.ext_i32_i64++;
+ (void)ret;
+ (void)arg;
+}
+
+static void tcg_op_test_saw_reset(void)
+{
+ memset(&tcg_op_test_saw, 0, sizeof(tcg_op_test_saw));
+}
+
+G_GNUC_UNUSED
+static void tcg_op_test_expect_i32(void)
+{
+ g_assert_false(tl_is_64());
+
+ tcg_op_test_saw_reset();
+ tcg_gen_bswap32_tl((TCGv)NULL, (TCGv)NULL, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.bswap32_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.bswap32_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_revbit32_tl((TCGv)NULL, (TCGv)NULL, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.revbit32_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.revbit32_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_trunc_tl_i32(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.extrl_i64_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_trunc_i64_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.extrl_i64_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_extu_i32_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.extu_i32_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_ext_i32_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.ext_i32_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_extu_tl_i64(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.extu_i32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_ext_tl_i64(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.ext_i32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 0);
+}
+
+G_GNUC_UNUSED
+static void tcg_op_test_expect_i64(void)
+{
+ g_assert_true(tl_is_64());
+
+ tcg_op_test_saw_reset();
+ tcg_gen_bswap32_tl((TCGv)NULL, (TCGv)NULL, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.bswap32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.bswap32_i64_flags, ==, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.bswap32_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_revbit32_tl((TCGv)NULL, (TCGv)NULL, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.revbit32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.revbit32_i64_flags, ==, 0x15);
+ g_assert_cmpint(tcg_op_test_saw.revbit32_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_trunc_tl_i32(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.extrl_i64_i32, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_trunc_i64_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.extrl_i64_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_extu_i32_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.extu_i32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_ext_i32_tl((TCGv)NULL, NULL);
+ g_assert_cmpint(tcg_op_test_saw.ext_i32_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.mov_i32, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_extu_tl_i64(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.extu_i32_i64, ==, 0);
+
+ tcg_op_test_saw_reset();
+ tcg_gen_ext_tl_i64(NULL, (TCGv)NULL);
+ g_assert_cmpint(tcg_op_test_saw.mov_i64, ==, 1);
+ g_assert_cmpint(tcg_op_test_saw.ext_i32_i64, ==, 0);
+}
+
+#endif /* TEST_TCG_OP_DISPATCH_H */
diff --git a/tests/unit/test-tcg-op-tl32.c b/tests/unit/test-tcg-op-tl32.c
new file mode 100644
index 00000000000..5d7cf05c5ea
--- /dev/null
+++ b/tests/unit/test-tcg-op-tl32.c
@@ -0,0 +1,24 @@
+/*
+ * tcg-op.h with TARGET_LONG_BITS == 32.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "test-tcg-op-dispatch.h"
+
+static void test_tl32(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 32);
+ g_assert_false(tl_is_64());
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv_i32));
+ tcg_op_test_expect_i32();
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op/tl32-dispatch", test_tl32);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op-tl64.c b/tests/unit/test-tcg-op-tl64.c
new file mode 100644
index 00000000000..0d9a7e2d0fc
--- /dev/null
+++ b/tests/unit/test-tcg-op-tl64.c
@@ -0,0 +1,24 @@
+/*
+ * tcg-op.h with TARGET_LONG_BITS == 64.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "test-tcg-op-dispatch.h"
+
+static void test_tl64(void)
+{
+ g_assert_cmpint(TARGET_LONG_BITS, ==, 64);
+ g_assert_true(tl_is_64());
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv_i64));
+ tcg_op_test_expect_i64();
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op/tl64-dispatch", test_tl64);
+ return g_test_run();
+}
diff --git a/tests/unit/test-tcg-op.c b/tests/unit/test-tcg-op.c
new file mode 100644
index 00000000000..92041349b47
--- /dev/null
+++ b/tests/unit/test-tcg-op.c
@@ -0,0 +1,66 @@
+/*
+ * Compile and call tcg-op.h with no TARGET_LONG_BITS.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-info-def.h"
+#include "test-tcg-op-dispatch.h"
+
+static const TargetInfo tl32_info = {
+ .target_name = "tl32",
+ .long_bits = 32,
+};
+
+static const TargetInfo tl64_info = {
+ .target_name = "tl64",
+ .long_bits = 64,
+};
+
+static void test_common_tl_types(void)
+{
+ g_assert_true(__builtin_types_compatible_p(__typeof__(tcg_temp_new()),
+ TCGv));
+ g_assert_true(__builtin_types_compatible_p(
+ __typeof__(tcg_constant_tl(0)), TCGv));
+}
+
+static void test_dispatch_both_widths(void)
+{
+ target_info_select(&tl32_info);
+ tcg_op_test_expect_i32();
+
+ target_info_select(&tl64_info);
+ tcg_op_test_expect_i64();
+}
+
+static void test_dup_const_tl_width(void)
+{
+ target_info_select(&tl32_info);
+ g_assert_false(tl_is_64());
+ g_assert_cmpint(tcg_type_tl(), ==, TCG_TYPE_I32);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_8, 0xab), ==, 0xababababu);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_16, 0xabcd), ==, 0xabcdabcdu);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_32, 0x01020304), ==,
+ 0x01020304u);
+
+ target_info_select(&tl64_info);
+ g_assert_true(tl_is_64());
+ g_assert_cmpint(tcg_type_tl(), ==, TCG_TYPE_I64);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_8, 0xab), ==,
+ 0xababababababababull);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_16, 0xabcd), ==,
+ 0xabcdabcdabcdabcdull);
+ g_assert_cmpuint((uint64_t)dup_const_tl(MO_32, 0x01020304), ==,
+ 0x0102030401020304ull);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tcg/op/common-tl-types", test_common_tl_types);
+ g_test_add_func("/tcg/op/dispatch-both-widths", test_dispatch_both_widths);
+ g_test_add_func("/tcg/op/dup-const-tl-width", test_dup_const_tl_width);
+ return g_test_run();
+}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 33/55] target/arm: fix A64 guest address width at 64
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (31 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 32/55] tests/unit: cover common-system tl dispatch and calls Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 34/55] target/arm: pass tl temps into SVE and SME helpers Yonggang Luo
` (21 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Define TCG_ADDRESS_BITS 64 in translate-a64.h so A64 qemu_ld and
qemu_st take a 64-bit address, matching TCG_ADDRESS_BITS 32 in
translate.c.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/tcg/translate-a64.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index 35f8d4f82e3..d4265de9dcb 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -18,6 +18,9 @@
#ifndef TARGET_ARM_TRANSLATE_A64_H
#define TARGET_ARM_TRANSLATE_A64_H
+/* A64 qemu_ld/st addresses are always 64-bit. Set before tcg-op.h. */
+#define TCG_ADDRESS_BITS 64
+
TCGv_i64 cpu_reg(DisasContext *s, int reg);
TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf);
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 34/55] target/arm: pass tl temps into SVE and SME helpers
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (32 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 33/55] target/arm: fix A64 guest address width at 64 Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 35/55] exec: provide target_ulong for softmmu common code Yonggang Luo
` (20 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
SVE and SME helpers take tl, which is TCGv. A64 addresses and
cpu_reg() are TCGv_i64, so convert with tcg_tl_from_i64. Truncate the
SME tile index with extrl_i64_i32.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/tcg/translate-sme.c | 5 +++--
target/arm/tcg/translate-sve.c | 18 ++++++++++--------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index 08b25b0be9d..e34e7d8744f 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -64,7 +64,7 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
/* Compute the final index, which is Rs+imm. */
tmp = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(tmp, cpu_reg(s, rs));
+ tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rs));
/*
* Round the vector index down to a multiple of vec_mod if necessary.
* We do this before adding the offset, to handle cases like
@@ -469,7 +469,8 @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
- fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
+ fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg,
+ tcg_tl_from_i64(addr),
tcg_constant_i64(desc));
return true;
}
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 10375577b1e..9fd10168876 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -36,9 +36,9 @@ typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
TCGv_ptr, TCGv_ptr, TCGv_i32);
-typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i64);
+typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv, TCGv_i64);
typedef void gen_helper_gvec_mem_scatter(TCGv_env, TCGv_ptr, TCGv_ptr,
- TCGv_ptr, TCGv_i64, TCGv_i64);
+ TCGv_ptr, TCGv, TCGv_i64);
/*
* Helpers for extracting complex instruction fields.
@@ -5378,7 +5378,7 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
t_pg = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
- fn(tcg_env, t_pg, addr, tcg_constant_i64(desc));
+ fn(tcg_env, t_pg, tcg_tl_from_i64(addr), tcg_constant_i64(desc));
}
/* Indexed by [mte][be][dtype][nreg] */
@@ -5861,7 +5861,7 @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
gen_helper_gvec_mem *fn
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
- fn(tcg_env, t_pg, addr, tcg_constant_i64(desc));
+ fn(tcg_env, t_pg, tcg_tl_from_i64(addr), tcg_constant_i64(desc));
/* Replicate that first quadword. */
if (vsz > 16) {
@@ -5945,7 +5945,7 @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
gen_helper_gvec_mem *fn
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
- fn(tcg_env, t_pg, addr, tcg_constant_i64(desc));
+ fn(tcg_env, t_pg, tcg_tl_from_i64(addr), tcg_constant_i64(desc));
/*
* Replicate that first octaword.
@@ -6286,7 +6286,8 @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
- fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i64(desc));
+ fn(tcg_env, t_zt, t_pg, t_zm, tcg_tl_from_i64(scalar),
+ tcg_constant_i64(desc));
}
/* Indexed by [mte][be][ff][xs][u][msz]. */
@@ -8682,7 +8683,7 @@ TRANS_FEAT(SQCVTUN_sh, aa64_sme2_or_sve2p1, gen_gvec_ool_zz,
static bool gen_ldst_c(DisasContext *s, TCGv_i64 addr, int zd, int png,
MemOp esz, bool is_write, int n, bool strided)
{
- typedef void ldst_c_fn(TCGv_env, TCGv_ptr, TCGv_i64,
+ typedef void ldst_c_fn(TCGv_env, TCGv_ptr, TCGv,
TCGv_i32, TCGv_i64);
static ldst_c_fn * const f_ldst[2][2][4] = {
{ { gen_helper_sve2p1_ld1bb_c,
@@ -8747,7 +8748,8 @@ static bool gen_ldst_c(DisasContext *s, TCGv_i64 addr, int zd, int png,
t_zd = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t_zd, tcg_env, vec_full_reg_offset(s, zd));
- f_ldst[is_write][be][esz](tcg_env, t_zd, addr, t_png, t_desc);
+ f_ldst[is_write][be][esz](tcg_env, t_zd, tcg_tl_from_i64(addr),
+ t_png, t_desc);
return true;
}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 35/55] exec: provide target_ulong for softmmu common code
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (33 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 34/55] target/arm: pass tl temps into SVE and SME helpers Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 36/55] exec: compile abi_ptr.h without per-target cpu-param.h Yonggang Luo
` (19 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Softmmu common code gets a 64-bit target_ulong and a runtime MO_TL.
target_long and TARGET_FMT_* stay per-target. The per-target half of
target_long.h is unchanged.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/exec/target_long.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/exec/target_long.h b/include/exec/target_long.h
index 3cd8e26a23f..c7bc65a60c9 100644
--- a/include/exec/target_long.h
+++ b/include/exec/target_long.h
@@ -10,6 +10,7 @@
#ifndef _TARGET_LONG_H_
#define _TARGET_LONG_H_
+#if defined(COMPILING_PER_TARGET)
/*
* Usually this should only be included via cpu-defs.h however for
* certain cases where we want to build only two versions of a binary
@@ -40,5 +41,15 @@ typedef uint64_t target_ulong;
#else
#error TARGET_LONG_SIZE undefined
#endif
+#elif defined(CONFIG_SOFTMMU)
+/*
+ * softmmu common: widest target_ulong and runtime MO_TL only.
+ * target_long, TARGET_LONG_SIZE, and TARGET_FMT_* stay per-target
+ * (TARGET_LONG_BITS / TARGET_FMT_* are poisoned here).
+ */
+#include "qemu/target-info.h"
+typedef uint64_t target_ulong;
+#define MO_TL (target_long_bits() == 64 ? MO_64 : MO_32)
+#endif
#endif /* _TARGET_LONG_H_ */
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 36/55] exec: compile abi_ptr.h without per-target cpu-param.h
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (34 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 35/55] exec: provide target_ulong for softmmu common code Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 37/55] accel/tcg: keep cpu-ldst endian aliases per-target Yonggang Luo
` (18 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Include cpu-param.h only for user-mode, where abi_ptr depends on
TARGET_VIRT_ADDR_SPACE_BITS. Softmmu abi_ptr remains target_ulong,
and its format is PRIx64 when COMPILING_PER_TARGET is unset.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/exec/abi_ptr.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/exec/abi_ptr.h b/include/exec/abi_ptr.h
index 2aedcceb0c2..7e8a78bc980 100644
--- a/include/exec/abi_ptr.h
+++ b/include/exec/abi_ptr.h
@@ -6,13 +6,12 @@
#ifndef EXEC_ABI_PTR_H
#define EXEC_ABI_PTR_H
-#include "cpu-param.h"
-
#if defined(CONFIG_USER_ONLY)
/*
* sparc32plus has 64bit long but 32bit space address
* this can make bad result with g2h() and h2g()
*/
+#include "cpu-param.h"
#if TARGET_VIRT_ADDR_SPACE_BITS <= 32
typedef uint32_t abi_ptr;
#define TARGET_ABI_FMT_ptr "%x"
@@ -26,7 +25,11 @@ typedef uint64_t abi_ptr;
#include "exec/target_long.h"
typedef target_ulong abi_ptr;
+#ifdef COMPILING_PER_TARGET
#define TARGET_ABI_FMT_ptr TARGET_FMT_lx
+#else
+#define TARGET_ABI_FMT_ptr "%" PRIx64
+#endif
#endif /* !CONFIG_USER_ONLY */
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 37/55] accel/tcg: keep cpu-ldst endian aliases per-target
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (35 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 36/55] exec: compile abi_ptr.h without per-target cpu-param.h Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 38/55] target/arm: fold arm_ss into common source sets Yonggang Luo
` (17 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Wrap the TARGET_BIG_ENDIAN cpu_ld*_data aliases in
COMPILING_PER_TARGET so common code can include cpu-ldst.h.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/accel/tcg/cpu-ldst.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/accel/tcg/cpu-ldst.h b/include/accel/tcg/cpu-ldst.h
index 1facabccb23..e3082db53e5 100644
--- a/include/accel/tcg/cpu-ldst.h
+++ b/include/accel/tcg/cpu-ldst.h
@@ -1,5 +1,5 @@
/*
- * Software MMU support (per-target)
+ * Software MMU support
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -423,6 +423,7 @@ cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
cpu_stq_le_data_ra(env, addr, val, 0);
}
+#ifdef COMPILING_PER_TARGET
#ifndef TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API
#if TARGET_BIG_ENDIAN
# define cpu_lduw_data cpu_lduw_be_data
@@ -470,5 +471,6 @@ cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
# define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
#endif
#endif /* TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API */
+#endif /* COMPILING_PER_TARGET */
#endif /* ACCEL_TCG_CPU_LDST_H */
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 38/55] target/arm: fold arm_ss into common source sets
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (36 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 37/55] accel/tcg: keep cpu-ldst endian aliases per-target Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 39/55] target/microblaze: fold system sources " Yonggang Luo
` (16 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Add arm_ss to arm_common_user_system_ss and arm_system_ss to
arm_common_system_ss. Drop target_arch and target_system_arch
so ARM CPU objects are not built per target.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/arm/meson.build | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 0369f96b4cc..11815a0908d 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -68,11 +68,11 @@ if 'CONFIG_TCG' in config_all_accel
subdir('tcg')
endif
+arm_common_user_system_ss.add_all(arm_ss)
arm_user_ss.add_all(arm_common_user_system_ss)
arm_common_system_ss.add_all(arm_common_user_system_ss)
+arm_common_system_ss.add_all(arm_system_ss)
-target_arch += {'arm': arm_ss}
-target_system_arch += {'arm': arm_system_ss}
target_user_arch += {'arm': arm_user_ss}
target_common_arch += {'arm': arm_common_ss}
target_common_system_arch += {'arm': arm_common_system_ss}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 39/55] target/microblaze: fold system sources into common source sets
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (37 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 38/55] target/arm: fold arm_ss into common source sets Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 40/55] meson: link shared objects into qemu-system Yonggang Luo
` (15 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Add microblaze_system_ss to microblaze_common_system_ss and drop
target_system_arch so mmu.c and machine.c are not built per target.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
target/microblaze/meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/microblaze/meson.build b/target/microblaze/meson.build
index 9c1ecd1cf1c..93138637bf2 100644
--- a/target/microblaze/meson.build
+++ b/target/microblaze/meson.build
@@ -21,7 +21,7 @@ microblaze_system_ss.add(files(
'mmu.c',
'machine.c',
))
+microblaze_common_system_ss.add_all(microblaze_system_ss)
target_user_arch += {'microblaze': microblaze_user_ss}
-target_system_arch += {'microblaze': microblaze_system_ss}
target_common_system_arch += {'microblaze': microblaze_common_system_ss}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 40/55] meson: link shared objects into qemu-system
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (38 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 39/55] target/microblaze: fold system sources " Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 11:41 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 41/55] target-info: add SysEmuTarget none Yonggang Luo
` (14 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Extract common_ss, system_ss, and family-common objects into one
qemu-system binary. Only arm, aarch64, microblaze-softmmu are
listed; a new target must have arch_srcs equal to target_info_def
only (target-info-def.c). Config headers stay in arch_genh.
- Union non-TARGET_* keys with y taking precedence
- Reject leftover arch_srcs on participating targets
- Reject TARGET_* conditions on common_ss and system_ss
- Link SDL, install the binary, and apply Darwin entitlements
Adding a target that still has per-target sources fails meson, for
example:
combined qemu-system leftover for :
expected:
target-info-def.c
arch_srcs:
target/microblaze/mmu.c
target/microblaze/machine.c
target-info-def.c
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
meson.build | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 147 insertions(+), 4 deletions(-)
diff --git a/meson.build b/meson.build
index d5639a2d676..7ab5c7971a8 100644
--- a/meson.build
+++ b/meson.build
@@ -4288,15 +4288,30 @@ if host_os == 'darwin'
endif
traceable = []
+single_binary_target_info_objects = []
+single_binary_config = {}
+single_binary_bases = {}
+single_binary_deps = []
+single_binary_crates = []
+single_binary_available = false
+
+single_binary_supported_targets = [
+ 'aarch64-softmmu',
+ 'arm-softmmu',
+ 'microblaze-softmmu',
+]
+
emulators = {}
-target_info_def = files('target-info-def.c')
+target_info_def_src = 'target-info-def.c'
+target_info_def = files(target_info_def_src)
target_info_def_objects = {}
foreach target : target_dirs
config_target = config_target_mak[target]
target_name = config_target['TARGET_NAME']
target_base_arch = config_target['TARGET_BASE_ARCH']
- arch_srcs = [config_target_h[target]]
+ arch_srcs = []
arch_deps = []
+ arch_genh = [config_target_h[target]]
c_args = ['-DCOMPILING_PER_TARGET',
'-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
]
@@ -4322,7 +4337,7 @@ foreach target : target_dirs
endif
c_args += ['-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
- arch_srcs += config_devices_h[target]
+ arch_genh += config_devices_h[target]
link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
else
abi = config_target['TARGET_ABI_DIR']
@@ -4433,7 +4448,7 @@ foreach target : target_dirs
endforeach
lib = static_library('qemu-' + target,
- sources: arch_srcs + genh,
+ sources: arch_srcs + arch_genh + genh,
dependencies: lib_deps,
objects: objects,
include_directories: target_inc,
@@ -4443,6 +4458,45 @@ foreach target : target_dirs
target_info_def_objects += {target: lib.extract_objects(target_info_def)}
if target.endswith('-softmmu')
+ if target in single_binary_supported_targets
+ arch_src_rels = []
+ foreach src : arch_srcs
+ arch_src_rels += fs.relative_to(src, meson.project_source_root())
+ endforeach
+ if arch_src_rels != [target_info_def_src]
+ error('combined qemu-system leftover for ' + target + ':\n'
+ + 'expected:\n' + target_info_def_src + '\n'
+ + 'arch_srcs:\n' + '\n'.join(arch_src_rels))
+ endif
+ single_target_config = {}
+ foreach k, v : config_target
+ if not k.startswith('TARGET_')
+ single_target_config += {k: v}
+ if k not in single_binary_config or v == 'y'
+ single_binary_config += {k: v}
+ endif
+ endif
+ endforeach
+ target_common_no_target = common_ss.apply(
+ single_target_config, strict: false)
+ if (target_common.sources() != target_common_no_target.sources() or
+ target_common.dependencies() != target_common_no_target.dependencies())
+ error('common_ss must not use TARGET_* conditions')
+ endif
+ target_system = system_ss.apply(config_target, strict: false)
+ target_system_no_target = system_ss.apply(
+ single_target_config, strict: false)
+ if (target_system.sources() != target_system_no_target.sources() or
+ target_system.dependencies() != target_system_no_target.dependencies())
+ error('system_ss must not use TARGET_* conditions')
+ endif
+ single_binary_target_info_objects += lib.extract_objects(target_info_def)
+ single_binary_bases += {target_base_arch: true}
+ single_binary_deps += arch_deps
+ single_binary_deps += target_stubs
+ single_binary_crates += main_rs
+ single_binary_available = true
+ endif
execs = [{
'name': 'qemu-system-' + target_name,
'win_subsystem': 'console',
@@ -4524,6 +4578,95 @@ foreach target : target_dirs
endforeach
endforeach
+# Combined qemu-system: one apply + extract, same sources as
+# qemu-system-$target.
+#
+# common_ss / system_ss use single_binary_config, the non-TARGET_* union where
+# 'y' takes precedence.
+# Do not use when: 'TARGET_*' on these sets; those keys are dropped and the file
+# would vanish from qemu-system.
+#
+# Family common/system libs use config_base_arch_mak[base] (every target of that
+# TARGET_BASE_ARCH, including user-mode if enabled).
+#
+# Each qemu-* lib contributes target-info-def.c. Participating targets must have
+# arch_srcs equal to target_info_def only.
+if single_binary_available
+ single_binary_objects = []
+ target_common = common_ss.apply(single_binary_config, strict: false)
+ single_binary_objects += common_all.extract_objects(target_common.sources())
+ single_binary_deps += target_common.dependencies()
+
+ target_system = system_ss.apply(single_binary_config, strict: false)
+ single_binary_objects += libsystem.extract_objects(target_system.sources())
+ single_binary_deps += target_system.dependencies()
+
+ foreach base, _ : single_binary_bases
+ config_base = config_base_arch_mak[base]
+ if base in target_common_arch_libs
+ src = target_common_arch[base].apply(config_base, strict: false)
+ single_binary_objects += target_common_arch_libs[base].extract_objects(
+ src.sources())
+ single_binary_deps += src.dependencies()
+ endif
+ if base in target_common_system_arch_libs
+ src = target_common_system_arch[base].apply(config_base, strict: false)
+ single_binary_objects += target_common_system_arch_libs[base].extract_objects(
+ src.sources())
+ single_binary_deps += src.dependencies()
+ endif
+ endforeach
+ single_binary_objects += single_binary_target_info_objects
+
+ single_binary_link_args = emulator_link_args
+ single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
+ qemu_system_name = 'qemu-system'
+ if host_os == 'darwin'
+ qemu_system_name += '-unsigned'
+ endif
+ qemu_system = executable(qemu_system_name,
+ sources: [single_binary_crates, files('system/main.c')],
+ dependencies: single_binary_deps + [sdl],
+ objects: single_binary_objects,
+ link_depends: [block_syms, qemu_syms],
+ link_args: single_binary_link_args,
+ build_by_default: true,
+ install: true)
+ if host_os == 'darwin'
+ icon = 'pc-bios/qemu.rsrc'
+ build_input = [qemu_system, files(icon)]
+ install_input = [
+ get_option('bindir') / qemu_system_name,
+ meson.current_source_dir() / icon
+ ]
+ if 'CONFIG_HVF' in single_binary_config
+ entitlements = 'accel/hvf/entitlements.plist'
+ build_input += files(entitlements)
+ install_input += meson.current_source_dir() / entitlements
+ endif
+ emulators += {'qemu-system': custom_target('qemu-system',
+ input: build_input,
+ output: 'qemu-system',
+ build_by_default: true,
+ command: [entitlement, '@OUTPUT@', '@INPUT@'])
+ }
+ meson.add_install_script(entitlement, '--install',
+ get_option('bindir') / 'qemu-system',
+ install_input)
+ else
+ emulators += {'qemu-system': qemu_system}
+ endif
+else
+ error_str = f'''qemu-system only support targets:
+@single_binary_supported_targets@
+
+use ./configure --target-list= to choose at least one of them'''
+ t = custom_target(command: ['sh', '-c', 'echo "' + error_str + '" && exit 1'],
+ output: 'none',
+ build_by_default: false)
+ alias_target('qemu-system', t)
+endif
+
# Other build targets
if get_option('plugins')
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 41/55] target-info: add SysEmuTarget none
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (39 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 40/55] meson: link shared objects into qemu-system Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 11:47 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 42/55] module: load every arch-tagged module when target is none Yonggang Luo
` (13 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Add a none target for when no TargetInfo is selected. It is last
so existing SYS_EMU_TARGET_* values stay put, and it is not a
qemu-system- executable name. target_is_none() and target_none()
report that state.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info.h | 15 +++++++++++++++
qapi/machine.json | 13 +++++++++----
target-info.c | 10 ++++++++++
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index a5dcf60dd9e..812e4b04a7b 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -90,6 +90,21 @@ bool target_big_endian(void);
*/
bool target_is_any(const TargetInfo *ti);
+/**
+ * target_is_none:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is SYS_EMU_TARGET_NONE.
+ */
+bool target_is_none(const TargetInfo *ti);
+
+/**
+ * target_none:
+ *
+ * Returns: %true if the current TargetInfo is SYS_EMU_TARGET_NONE.
+ */
+bool target_none(void);
+
/**
* target_is_base_arm:
* @ti: TargetInfo to inspect
diff --git a/qapi/machine.json b/qapi/machine.json
index b1be5608b61..6aaa2af709a 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -22,6 +22,10 @@
# The individual target constants are not documented here, for the
# time being.
#
+# @none: no TargetInfo selected. Not a qemu-system- executable name.
+# Last enumerator so existing SYS_EMU_TARGET_* values stay put.
+# (since 11.2)
+#
# @rx: since 5.0
#
# @avr: since 5.1
@@ -30,9 +34,10 @@
#
# @hexagon: since 11.0
#
-# .. note:: The resulting QMP strings can be appended to the
-# "qemu-system-" prefix to produce the corresponding QEMU
-# executable name. This is true even for "qemu-system-x86_64".
+# .. note:: Except for ``none``, the resulting QMP strings can be
+# appended to the "qemu-system-" prefix to produce the
+# corresponding QEMU executable name. This is true even for
+# "qemu-system-x86_64".
#
# Since: 3.0
##
@@ -42,7 +47,7 @@
'mips64el', 'mipsel', 'or1k', 'ppc',
'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
'sh4eb', 'sparc', 'sparc64', 'tricore',
- 'x86_64', 'xtensa', 'xtensaeb' ] }
+ 'x86_64', 'xtensa', 'xtensaeb', 'none' ] }
##
# @S390CpuState:
diff --git a/target-info.c b/target-info.c
index 1bdf3869605..b25e2ada438 100644
--- a/target-info.c
+++ b/target-info.c
@@ -112,6 +112,16 @@ bool target_is_any(const TargetInfo *ti)
return true;
}
+bool target_is_none(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_NONE;
+}
+
+bool target_none(void)
+{
+ return target_is_none(target_info());
+}
+
bool target_is_base_arm(const TargetInfo *ti)
{
switch (ti->target_arch) {
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 42/55] module: load every arch-tagged module when target is none
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (40 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 41/55] target-info: add SysEmuTarget none Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 43/55] accel/tcg: tolerate NULL target_cpu_type for -M none Yonggang Luo
` (12 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The none target allows every arch-tagged module, so modular
qemu-system help can list devices from all architectures.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
util/module.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/util/module.c b/util/module.c
index 8f8e6994f11..2e08c7f03a2 100644
--- a/util/module.c
+++ b/util/module.c
@@ -137,7 +137,9 @@ static bool module_check_arch(const QemuModinfo *modinfo)
/* no arch set -> ignore all */
return false;
}
- if (strcmp(module_arch, modinfo->arch) != 0) {
+ /* "none" is SYS_EMU_TARGET_NONE: load every arch-tagged module. */
+ if (strcmp(module_arch, "none") != 0 &&
+ strcmp(module_arch, modinfo->arch) != 0) {
/* mismatch */
return false;
}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 43/55] accel/tcg: tolerate NULL target_cpu_type for -M none
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (41 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 42/55] module: load every arch-tagged module when target is none Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 44/55] target-info: select combined qemu-system target by name Yonggang Luo
` (11 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Combined qemu-system -M none keeps SYS_EMU_TARGET_NONE, so
target_cpu_type() is NULL. Skip the CPUClass lookup and leave
MTTCG off instead of crashing in tcg_init_machine().
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
accel/tcg/tcg-all.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 767e8805552..e44856f8304 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -107,8 +107,13 @@ static int tcg_init_machine(AccelState *as, MachineState *ms)
unsigned max_threads = 1;
#ifndef CONFIG_USER_ONLY
- CPUClass *cc = CPU_CLASS(object_class_by_name(target_cpu_type()));
- bool mttcg_supported = cc->tcg_ops->mttcg_supported;
+ /*
+ * Combined qemu-system -M none keeps SYS_EMU_TARGET_NONE, so
+ * target_cpu_type() is NULL. MTTCG defaults off.
+ */
+ ObjectClass *oc = object_class_by_name(target_cpu_type());
+ CPUClass *cc = oc ? CPU_CLASS(oc) : NULL;
+ bool mttcg_supported = cc && cc->tcg_ops && cc->tcg_ops->mttcg_supported;
switch (s->mttcg_enabled) {
case ON_OFF_AUTO_AUTO:
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 44/55] target-info: select combined qemu-system target by name
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (42 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 43/55] accel/tcg: tolerate NULL target_cpu_type for -M none Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 45/55] vl: parse arch: machine types on combined qemu-system Yonggang Luo
` (10 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The combined qemu-system binary can select a registered target by
name, or stay on SYS_EMU_TARGET_NONE. A single-target binary does
not switch target.
The none entry is the same target-info-def.c stub as other targets,
compiled with TARGET_BASE_ARCH NONE. target/none/cpu.h supplies
ArchCPU for that stub, and cpu-param.h sets
TARGET_VIRT_ADDR_SPACE_BITS. TYPE_NONE_CPU is NULL because there is
no none CPU QOM type.
type_register_internal() keeps types on the combined binary and
filters them with TypeInfo.is_available. A single-target binary
still omits types that cannot run.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info-select.h | 24 +++++++++++++++++++++
meson.build | 35 +++++++++++++++++++++++++++++++
qom/object.c | 8 ++++++-
stubs/meson.build | 1 +
stubs/target-info-select.c | 14 +++++++++++++
system/target-info-select.c | 26 +++++++++++++++++++++++
target/none/cpu-param.h | 7 +++++++
target/none/cpu-qom.h | 6 ++++++
target/none/cpu.h | 18 ++++++++++++++++
9 files changed, 138 insertions(+), 1 deletion(-)
create mode 100644 include/qemu/target-info-select.h
create mode 100644 stubs/target-info-select.c
create mode 100644 system/target-info-select.c
create mode 100644 target/none/cpu-param.h
create mode 100644 target/none/cpu-qom.h
create mode 100644 target/none/cpu.h
diff --git a/include/qemu/target-info-select.h b/include/qemu/target-info-select.h
new file mode 100644
index 00000000000..0659bb47567
--- /dev/null
+++ b/include/qemu/target-info-select.h
@@ -0,0 +1,24 @@
+#ifndef QEMU_TARGET_INFO_SELECT_H
+#define QEMU_TARGET_INFO_SELECT_H
+
+/**
+ * target_combined_binary:
+ *
+ * Returns: %true if this is the combined qemu-system binary.
+ */
+bool target_combined_binary(void);
+
+typedef struct Error Error;
+
+/**
+ * target_info_select_by_name:
+ * @name: target_name to select, or NULL
+ * @errp: error location
+ *
+ * Combined qemu-system only. NULL selects "none". Every name, including
+ * "none", is looked up in target_info_list(). The stub is a no-op on
+ * single-target binaries.
+ */
+void target_info_select_by_name(const char *name, Error **errp);
+
+#endif
diff --git a/meson.build b/meson.build
index 7ab5c7971a8..96f493cb746 100644
--- a/meson.build
+++ b/meson.build
@@ -4618,6 +4618,41 @@ if single_binary_available
endforeach
single_binary_objects += single_binary_target_info_objects
+ none_config_target_data = configuration_data()
+ none_config_target_data.set_quoted('TARGET_NAME', 'none')
+ none_config_target_data.set('TARGET_ARCH', 'NONE')
+ none_config_target_data.set('TARGET_BASE_ARCH', 'NONE')
+ none_config_target_data.set('TARGET_LONG_BITS', 64)
+ none_config_target_data.set('TARGET_BIG_ENDIAN', 0)
+ none_config_target_h = configure_file(output: 'none-config-target.h',
+ configuration: none_config_target_data)
+ none_config_devices_data = configuration_data()
+ foreach k, v : single_binary_config
+ if v == 'y'
+ none_config_devices_data.set(k, 1)
+ endif
+ endforeach
+ none_config_devices_h = configure_file(output: 'none-config-devices.h',
+ configuration: none_config_devices_data)
+ qemu_none_ss = ss.source_set()
+ qemu_none_ss.add(files('system/target-info-select.c'))
+ qemu_none_ss.add(target_info_def)
+ qemu_none_src = qemu_none_ss.apply(single_binary_config, strict: false)
+ qemu_none = static_library('qemu-none',
+ sources: qemu_none_src.sources() + genh +
+ [none_config_target_h,
+ none_config_devices_h],
+ dependencies: qemu_none_src.dependencies(),
+ include_directories: include_directories(
+ 'target' / 'none'),
+ c_args: [
+ '-DCOMPILING_PER_TARGET',
+ '-DCONFIG_TARGET="none-config-target.h"',
+ '-DCONFIG_DEVICES="none-config-devices.h"',
+ ],
+ build_by_default: false)
+ single_binary_objects += qemu_none.extract_objects(qemu_none_src.sources())
+
single_binary_link_args = emulator_link_args
single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
qemu_system_name = 'qemu-system'
diff --git a/qom/object.c b/qom/object.c
index 76b0b0806b3..2ce6c369df5 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -16,6 +16,7 @@
#include "qom/object.h"
#include "qom/object_interfaces.h"
#include "qemu/target-info-qapi.h"
+#include "qemu/target-info-select.h"
#include "qemu/cutils.h"
#include "qemu/memalign.h"
#include "qapi/visitor.h"
@@ -171,7 +172,12 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
abort();
}
- if (info->is_available && !info->is_available(target_info())) {
+ /*
+ * Single-target binaries omit types that cannot run. The combined
+ * binary keeps them and filters with is_available per target.
+ */
+ if (!target_combined_binary() && info->is_available &&
+ !info->is_available(target_info())) {
return NULL;
}
diff --git a/stubs/meson.build b/stubs/meson.build
index 29b6644b254..3765537778d 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -3,6 +3,7 @@
# below, so that it is clear who needs the stubbed functionality.
stub_ss.add(files('cpu-get-clock.c'))
+stub_ss.add(files('target-info-select.c'))
stub_ss.add(files('fdset.c'))
stub_ss.add(files('iothread-lock.c'))
stub_ss.add(files('is-daemonized.c'))
diff --git a/stubs/target-info-select.c b/stubs/target-info-select.c
new file mode 100644
index 00000000000..5c9e8dc6e19
--- /dev/null
+++ b/stubs/target-info-select.c
@@ -0,0 +1,14 @@
+#include "qemu/osdep.h"
+#include "qemu/target-info-select.h"
+#include "qapi/error.h"
+
+bool target_combined_binary(void)
+{
+ return false;
+}
+
+void target_info_select_by_name(const char *name, Error **errp)
+{
+ (void)name;
+ (void)errp;
+}
diff --git a/system/target-info-select.c b/system/target-info-select.c
new file mode 100644
index 00000000000..4b4a9fdf256
--- /dev/null
+++ b/system/target-info-select.c
@@ -0,0 +1,26 @@
+#include "qemu/osdep.h"
+#include "qemu/target-info-def.h"
+#include "qemu/target-info-select.h"
+#include "qapi/error.h"
+
+bool target_combined_binary(void)
+{
+ return true;
+}
+
+void target_info_select_by_name(const char *name, Error **errp)
+{
+ TargetInfoNode *node;
+
+ if (!name) {
+ name = "none";
+ }
+
+ QLIST_FOREACH(node, target_info_list(), next) {
+ if (!strcmp(name, node->info->target_name)) {
+ target_info_select(node->info);
+ return;
+ }
+ }
+ error_setg(errp, "target '%s' is not available", name);
+}
diff --git a/target/none/cpu-param.h b/target/none/cpu-param.h
new file mode 100644
index 00000000000..3c0818a2f02
--- /dev/null
+++ b/target/none/cpu-param.h
@@ -0,0 +1,7 @@
+#ifndef NONE_CPU_PARAM_H
+#define NONE_CPU_PARAM_H
+
+#define TARGET_PAGE_BITS 9
+#define TARGET_VIRT_ADDR_SPACE_BITS 64
+
+#endif
diff --git a/target/none/cpu-qom.h b/target/none/cpu-qom.h
new file mode 100644
index 00000000000..114faa8077a
--- /dev/null
+++ b/target/none/cpu-qom.h
@@ -0,0 +1,6 @@
+#ifndef QEMU_NONE_CPU_QOM_H
+#define QEMU_NONE_CPU_QOM_H
+
+#define TYPE_NONE_CPU NULL
+
+#endif
diff --git a/target/none/cpu.h b/target/none/cpu.h
new file mode 100644
index 00000000000..ffb9a0d28dc
--- /dev/null
+++ b/target/none/cpu.h
@@ -0,0 +1,18 @@
+#ifndef QEMU_NONE_CPU_H
+#define QEMU_NONE_CPU_H
+
+#include "cpu-qom.h"
+#include "hw/core/cpu.h"
+
+#define CPU_RESOLVING_TYPE TYPE_NONE_CPU
+
+typedef struct CPUArchState {
+ uint64_t unused;
+} CPUArchState;
+
+struct ArchCPU {
+ CPUState parent_obj;
+ CPUArchState env;
+};
+
+#endif
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 45/55] vl: parse arch: machine types on combined qemu-system
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (43 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 44/55] target-info: select combined qemu-system target by name Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 46/55] qapi: add query-targets Yonggang Luo
` (9 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The combined binary takes arch:name on -M/-machine and in a
[machine] type from the default config file or -readconfig, and
selects that target before QOM init. The default file is read
first. -nouserconfig skips only that file. select_machine()
matches the machine in the selected target.
qemu_read_config_file_cb() supplies the callback for that early
pass. qemu-options.hx documents arch:name and arch:help.
- A later bare name keeps the last arch prefix
- Last -M wins for help
- Plain -M help lists every target; arch:help lists one target
- qemu-system-<arch> still prints machine help after early options
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/config-file.h | 2 +
qemu-options.hx | 11 +-
system/vl.c | 294 ++++++++++++++++++++++++++++++++++---
util/qemu-config.c | 10 +-
4 files changed, 291 insertions(+), 26 deletions(-)
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index 51b310fa3b4..f733b0e9769 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -22,6 +22,8 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname,
void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp);
int qemu_read_config_file(const char *filename, QEMUConfigCB *f, Error **errp);
+int qemu_read_config_file_cb(const char *filename, QEMUConfigCB *f,
+ void *opaque, Error **errp);
/* Parse QDict options as a replacement for a config file (allowing multiple
enumerated (0..(n-1)) configuration "sections") */
diff --git a/qemu-options.hx b/qemu-options.hx
index 2f6863180b0..32be1ceeda2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -27,6 +27,8 @@ ERST
DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
"-machine [type=]name[,prop=value[,...]]\n"
" selects emulated machine ('-machine help' for list)\n"
+ " use arch:name (e.g. aarch64:virt) on the combined binary\n"
+ " '-machine help' lists all targets; use arch:help for one\n"
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, hvf, nitro, nvmm, whpx, mshv or tcg (default: tcg)\n"
" vmport=on|off|auto controls emulation of vmport (default: auto)\n"
@@ -53,7 +55,14 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
SRST
``-machine [type=]name[,prop=value[,...]]``
Select the emulated machine by name. Use ``-machine help`` to list
- available machines.
+ available machines. On a single-target binary this lists that
+ target. On the combined qemu-system binary, ``-machine help``
+ lists every target; pass ``arch:name`` (for example
+ ``aarch64:virt``) to select one, or ``arch:help`` (for example
+ ``aarch64:help``) to list that target only. A ``[machine]``
+ ``type`` in the default config file or ``-readconfig`` uses the
+ same form. The default file is read first. A later bare name
+ keeps the last arch prefix.
For architectures which aim to support live migration compatibility
across releases, each release will introduce a new versioned machine
diff --git a/system/vl.c b/system/vl.c
index 7f1381d84ff..1bdd5b2da05 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -28,6 +28,8 @@
#include "qemu/units.h"
#include "qemu/module.h"
#include "qemu/target-info.h"
+#include "qemu/target-info-select.h"
+#include "qemu/target-info-def.h"
#include "exec/cpu-common.h"
#include "exec/page-vary.h"
#include "hw/core/qdev-properties.h"
@@ -842,6 +844,12 @@ static bool usb_parse(const char *cmdline, Error **errp)
/***********************************************************/
/* machine registration */
+/* Same grouping as -M help: each machine must have is_available. */
+static bool machine_class_in_target(MachineClass *mc, const TargetInfo *ti)
+{
+ return object_class_get_is_available(OBJECT_CLASS(mc))(ti);
+}
+
static MachineClass *find_machine(const char *name, GSList *machines)
{
GSList *el;
@@ -850,6 +858,9 @@ static MachineClass *find_machine(const char *name, GSList *machines)
MachineClass *mc = el->data;
if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
+ if (!machine_class_in_target(mc, target_info())) {
+ continue;
+ }
return mc;
}
}
@@ -866,6 +877,9 @@ static MachineClass *find_default_machine(GSList *machines)
MachineClass *mc = el->data;
if (mc->is_default) {
+ if (!machine_class_in_target(mc, target_info())) {
+ continue;
+ }
assert(default_machineclass == NULL && "Multiple default machines");
default_machineclass = mc;
}
@@ -874,6 +888,106 @@ static MachineClass *find_default_machine(GSList *machines)
return default_machineclass;
}
+/*
+ * Split "aarch64:virt". "aarch64:" binds arch and leaves an empty name.
+ * A leading colon is not a prefix. *machine_name always takes the latest
+ * parsed name; NULL type leaves it unchanged. keep_target leaves
+ * *machine_target unchanged when the new type has no prefix.
+ */
+static void machine_type_parse_target(const char *type,
+ char **machine_name,
+ char **machine_target,
+ bool keep_target)
+{
+ const char *colon = NULL;
+ const char *parsed_name = NULL;
+ const char *parsed_target = NULL;
+
+ if (type) {
+ colon = strchr(type, ':');
+ if (!colon || colon == type) {
+ parsed_name = type;
+ } else {
+ parsed_target = type;
+ parsed_name = colon + 1;
+ }
+ }
+
+ if (parsed_name) {
+ g_free(*machine_name);
+ *machine_name = g_strdup(parsed_name);
+ }
+ if (parsed_target || !keep_target) {
+ g_free(*machine_target);
+ *machine_target = parsed_target ?
+ g_strndup(parsed_target, colon - parsed_target) : NULL;
+ }
+}
+
+typedef struct MachineTypeOpt {
+ char *type;
+ char *name;
+ char *target;
+ bool help;
+} MachineTypeOpt;
+
+static void machine_type_opt_clear(MachineTypeOpt *opt)
+{
+ g_free(opt->type);
+ g_free(opt->name);
+ g_free(opt->target);
+ opt->type = NULL;
+ opt->name = NULL;
+ opt->target = NULL;
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(MachineTypeOpt, machine_type_opt_clear)
+
+/* A bare name keeps the previous arch prefix. */
+static void machine_type_opt_set(MachineTypeOpt *opt, const char *type,
+ bool help)
+{
+ if (!type && !help) {
+ return;
+ }
+ if (type) {
+ g_free(opt->type);
+ opt->type = g_strdup(type);
+ machine_type_parse_target(opt->type, &opt->name, &opt->target, true);
+ }
+ opt->help = help || (type && opt->name && is_help_option(opt->name));
+}
+
+static void qemu_config_set_machine_type(const char *group, QDict *qdict,
+ void *opaque, Error **errp)
+{
+ MachineTypeOpt *opt = opaque;
+
+ (void)errp;
+ if (strcmp(group, "machine") != 0) {
+ return;
+ }
+ machine_type_opt_set(opt, qdict_get_try_str(qdict, "type"), false);
+}
+
+static void machine_type_config_file(const char *filename, bool optional,
+ MachineTypeOpt *opt)
+{
+ Error *err = NULL;
+ int ret;
+
+ ret = qemu_read_config_file_cb(filename, qemu_config_set_machine_type,
+ opt, &err);
+ if (ret < 0) {
+ if (optional && ret == -ENOENT) {
+ error_free(err);
+ return;
+ }
+ error_report_err(err);
+ exit(1);
+ }
+}
+
static void version(void)
{
printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
@@ -1563,25 +1677,31 @@ static gint machine_class_cmp(gconstpointer a, gconstpointer b, gpointer d)
object_class_get_name(OBJECT_CLASS(mc1)));
}
-static void machine_help_func(const QDict *qdict)
+static void machine_help_print_target(GSList *machines, const TargetInfo *ti,
+ const char *machine_target)
{
- g_autoptr(GSList) machines = NULL;
+ bool printed = false;
GSList *el;
- const char *type = qdict_get_try_str(qdict, "type");
+ bool combined = target_combined_binary();
+ bool print_header = combined && !machine_target;
- machines = object_class_get_list(TYPE_MACHINE, false);
- if (type) {
- ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines));
- if (machine_class) {
- type_print_class_properties(object_class_get_name(machine_class));
- return;
- }
+ if (!combined) {
+ g_assert(ti == target_info());
+ } else if (machine_target && ti != target_info()) {
+ /* -M arch:help: skip every target except the selected one. */
+ return;
}
- printf("Supported machines are:\n");
- machines = g_slist_sort_with_data(machines, machine_class_cmp, NULL);
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
+
+ if (!machine_class_in_target(mc, ti)) {
+ continue;
+ }
+ if (print_header && !printed) {
+ printf("%s:\n", ti->target_name);
+ printed = true;
+ }
if (mc->alias) {
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
@@ -1590,6 +1710,54 @@ static void machine_help_func(const QDict *qdict)
mc->deprecation_reason ? " (deprecated)" : "",
object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "");
}
+
+ if (print_header && printed) {
+ printf("\n");
+ }
+}
+
+static void machine_help_func(const char *type,
+ const char *machine_name,
+ const char *machine_target)
+{
+ g_autoptr(GSList) machines = NULL;
+ MachineClass *mc = NULL;
+ TargetInfoNode *node;
+
+ machines = object_class_get_list(TYPE_MACHINE, false);
+
+ if (machine_name && *machine_name && !is_help_option(machine_name)) {
+ mc = find_machine(machine_name, machines);
+ if (mc) {
+ type_print_class_properties(object_class_get_name(OBJECT_CLASS(mc)));
+ return;
+ }
+ if (target_none()) {
+ error_report("machine type \"%s\" needs an arch: prefix",
+ machine_name);
+ exit(1);
+ }
+ error_report("unsupported machine type: \"%s\"", type);
+ exit(1);
+ }
+
+ if (type && (!machine_name || !*machine_name)) {
+ if (!target_none()) {
+ mc = find_default_machine(machines);
+ if (!mc) {
+ error_report("No machine specified, and there is no default");
+ exit(1);
+ }
+ type_print_class_properties(object_class_get_name(OBJECT_CLASS(mc)));
+ return;
+ }
+ }
+
+ printf("Supported machines are:\n");
+ machines = g_slist_sort_with_data(machines, machine_class_cmp, NULL);
+ QLIST_FOREACH(node, target_info_list(), next) {
+ machine_help_print_target(machines, node->info, machine_target);
+ }
}
static void
@@ -1684,18 +1852,58 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
const char *machine_type = qdict_get_try_str(qdict, "type");
g_autoptr(GSList) machines = object_class_get_list(TYPE_MACHINE, false);
MachineClass *machine_class = NULL;
+ g_autofree char *machine_target = NULL;
+ g_autofree char *machine_name = NULL;
if (machine_type) {
- machine_class = find_machine(machine_type, machines);
+ machine_type_parse_target(machine_type, &machine_name, &machine_target, false);
+ if (machine_target && strcmp(target_name(), machine_target) != 0) {
+ error_setg(errp, "machine type \"%s\" is not available "
+ "for target %s", machine_type, target_name());
+ error_append_hint(errp,
+ "Use -machine help to list supported "
+ "machines\n");
+ return NULL;
+ }
+ }
+
+ if (machine_name && *machine_name) {
+ machine_class = find_machine(machine_name, machines);
if (!machine_class) {
- error_setg(errp, "unsupported machine type: \"%s\"", machine_type);
+ if (machine_target && target_none()) {
+ error_setg(errp, "machine type \"%s\" is not available "
+ "for target %s", machine_type, target_name());
+ } else if (target_none()) {
+ error_setg(errp,
+ "machine type \"%s\" needs an arch: prefix",
+ machine_name);
+ error_append_hint(errp,
+ "Use -M arch:name (e.g. aarch64:virt) "
+ "or -machine help\n");
+ return NULL;
+ } else {
+ error_setg(errp, "unsupported machine type: \"%s\"",
+ machine_type);
+ }
}
- qdict_del(qdict, "type");
- } else {
+ } else if (!target_none()) {
machine_class = find_default_machine(machines);
if (!machine_class) {
error_setg(errp, "No machine specified, and there is no default");
}
+ } else {
+ machine_class = find_machine("none", machines);
+ if (!machine_class) {
+ error_setg(errp, "No machine specified");
+ error_append_hint(errp,
+ "Use -M arch:name (e.g. aarch64:virt) or "
+ "-machine help\n");
+ return NULL;
+ }
+ }
+
+ if (machine_type) {
+ qdict_del(qdict, "type");
}
if (!machine_class) {
@@ -2872,6 +3080,9 @@ void qemu_init(int argc, char **argv)
const char *optarg;
MachineClass *machine_class;
bool userconfig = true;
+ int parse_opt_pass = 0;
+ /* Combined: NULL target selects NONE. Single-target stub ignores this. */
+ g_auto(MachineTypeOpt) machine_opt = { };
FILE *vmstate_dump_file = NULL;
qemu_add_opts(&qemu_drive_opts);
@@ -2911,9 +3122,23 @@ void qemu_init(int argc, char **argv)
error_init(argv[0]);
qemu_init_exec_dir(argv[0]);
- /* first pass of option parsing */
+ /*
+ * Pass 0 records -nouserconfig. Pass 1 parses -M and -readconfig
+ * into machine_opt. The loop ends only after pass 1.
+ */
optind = 1;
- while (optind < argc) {
+ for (parse_opt_pass = 0; parse_opt_pass < 2;) {
+ if (optind >= argc) {
+ if (parse_opt_pass == 0 && userconfig) {
+ g_autofree char *file =
+ get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
+
+ machine_type_config_file(file, true, &machine_opt);
+ }
+ parse_opt_pass += 1;
+ optind = 1;
+ continue;
+ }
if (argv[optind][0] != '-') {
/* disk image */
optind++;
@@ -2923,7 +3148,27 @@ void qemu_init(int argc, char **argv)
popt = lookup_opt(argc, argv, &optarg, &optind);
switch (popt->index) {
case QEMU_OPTION_nouserconfig:
- userconfig = false;
+ if (parse_opt_pass == 0) {
+ userconfig = false;
+ }
+ break;
+ case QEMU_OPTION_M:
+ case QEMU_OPTION_machine:
+ if (parse_opt_pass == 1) {
+ bool help = false;
+ g_autoptr(QDict) dict = qdict_new();
+ const char *type;
+
+ keyval_parse_into(dict, optarg, "type", &help,
+ &error_fatal);
+ type = qdict_get_try_str(dict, "type");
+ machine_type_opt_set(&machine_opt, type, help);
+ }
+ break;
+ case QEMU_OPTION_readconfig:
+ if (parse_opt_pass == 1) {
+ machine_type_config_file(optarg, false, &machine_opt);
+ }
break;
}
}
@@ -2931,6 +3176,8 @@ void qemu_init(int argc, char **argv)
os_setup_limits();
+ target_info_select_by_name(machine_opt.target, &error_fatal);
+
module_init_info(qemu_modinfo);
module_allow_arch(target_name());
@@ -3435,10 +3682,6 @@ void qemu_init(int argc, char **argv)
bool help;
keyval_parse_into(machine_opts_dict, optarg, "type", &help, &error_fatal);
- if (help) {
- machine_help_func(machine_opts_dict);
- exit(EXIT_SUCCESS);
- }
break;
}
case QEMU_OPTION_accel:
@@ -3770,6 +4013,11 @@ void qemu_init(int argc, char **argv)
qemu_process_early_options();
qemu_process_help_options();
+ if (machine_opt.help) {
+ machine_help_func(machine_opt.type, machine_opt.name,
+ machine_opt.target);
+ exit(EXIT_SUCCESS);
+ }
qemu_maybe_daemonize(pid_file);
/*
diff --git a/util/qemu-config.c b/util/qemu-config.c
index d1fc49c507d..f0ef711450e 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -183,7 +183,8 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
return qemu_config_foreach(fp, qemu_config_do_parse, lists, fname, errp);
}
-int qemu_read_config_file(const char *filename, QEMUConfigCB *cb, Error **errp)
+int qemu_read_config_file_cb(const char *filename, QEMUConfigCB *cb,
+ void *opaque, Error **errp)
{
FILE *f = fopen(filename, "r");
int ret;
@@ -193,11 +194,16 @@ int qemu_read_config_file(const char *filename, QEMUConfigCB *cb, Error **errp)
return -errno;
}
- ret = qemu_config_foreach(f, cb, vm_config_groups, filename, errp);
+ ret = qemu_config_foreach(f, cb, opaque, filename, errp);
fclose(f);
return ret;
}
+int qemu_read_config_file(const char *filename, QEMUConfigCB *cb, Error **errp)
+{
+ return qemu_read_config_file_cb(filename, cb, vm_config_groups, errp);
+}
+
static bool config_parse_qdict_section(QDict *options, QemuOptsList *opts,
Error **errp)
{
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 46/55] qapi: add query-targets
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (44 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 45/55] vl: parse arch: machine types on combined qemu-system Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-28 10:13 ` Daniel P. Berrangé
2026-09-26 7:00 ` [PATCH v4 47/55] target-info: add target_is_microblaze Yonggang Luo
` (8 subsequent siblings)
54 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
query-targets lists each linked target, including none, with its
arch, endianness, and the machines that target accepts.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 9c08b17510a..c7b73efa31d 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -21,6 +21,7 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/type-helpers.h"
#include "qemu/uuid.h"
+#include "qemu/target-info-def.h"
#include "qemu/target-info.h"
#include "qemu/target-info-qapi.h"
#include "qom/qom-qobject.h"
@@ -173,6 +174,35 @@ QemuTargetInfo *qmp_query_target(Error **errp)
return info;
}
+TargetMachinesList *qmp_query_targets(Error **errp)
+{
+ TargetMachinesList *head = NULL;
+ TargetMachinesList **tail = &head;
+ GSList *machines, *el;
+ TargetInfoNode *node;
+
+ machines = object_class_get_list(TYPE_MACHINE, false);
+ QLIST_FOREACH(node, target_info_list(), next) {
+ const TargetInfo *ti = node->info;
+ TargetMachines *row = g_new0(TargetMachines, 1);
+ strList **names = &row->machines;
+
+ row->arch = ti->target_arch;
+ row->endianness = ti->endianness;
+ for (el = machines; el; el = el->next) {
+ MachineClass *mc = el->data;
+
+ if (!object_class_get_is_available(OBJECT_CLASS(mc))(ti)) {
+ continue;
+ }
+ QAPI_LIST_APPEND(names, g_strdup(mc->name));
+ }
+ QAPI_LIST_APPEND(tail, row);
+ }
+ g_slist_free(machines);
+ return head;
+}
+
HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
{
MachineState *ms = MACHINE(qdev_get_machine());
diff --git a/qapi/machine.json b/qapi/machine.json
index 6aaa2af709a..d8cdea6203e 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -307,6 +307,41 @@
##
{ 'command': 'query-target', 'returns': 'QemuTargetInfo' }
+##
+# @TargetMachines:
+#
+# One registered system target and the machines that can run on it.
+#
+# @arch: the target architecture
+#
+# @endianness: the target endianness
+#
+# @machines: machine type names, not aliases
+#
+# Since: 11.2
+##
+{ 'struct': 'TargetMachines',
+ 'data': { 'arch': 'SysEmuTarget',
+ 'endianness': 'EndianMode',
+ 'machines': ['str'] } }
+
+##
+# @query-targets:
+#
+# Return each target linked into this QEMU binary and the machines
+# whose availability check accepts that target.
+#
+# Since: 11.2
+#
+# .. qmp-example::
+#
+# -> { "execute": "query-targets" }
+# <- { "return": [ { "arch": "aarch64", "endianness": "little",
+# "machines": [ "virt" ] } ] }
+##
+{ 'command': 'query-targets',
+ 'returns': ['TargetMachines'] }
+
##
# @UuidInfo:
#
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 47/55] target-info: add target_is_microblaze
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (45 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 46/55] qapi: add query-targets Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 48/55] hw/microblaze: set petalogix-s3adsp1800 TypeInfo.is_available Yonggang Luo
` (7 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Add target_is_microblaze() and target_microblaze(). The first
reports SYS_EMU_TARGET_MICROBLAZE. The second checks the current
TargetInfo.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info.h | 15 +++++++++++++++
target-info.c | 10 ++++++++++
2 files changed, 25 insertions(+)
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index 812e4b04a7b..17fafa0888e 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -210,6 +210,21 @@ bool target_is_s390x(const TargetInfo *ti);
*/
bool target_s390x(void);
+/**
+ * target_is_microblaze:
+ * @ti: TargetInfo to inspect
+ *
+ * Returns whether @ti is Microblaze.
+ */
+bool target_is_microblaze(const TargetInfo *ti);
+
+/**
+ * target_microblaze:
+ *
+ * Returns whether the target architecture is Microblaze.
+ */
+bool target_microblaze(void);
+
/**
* target_is_base_riscv:
* @ti: TargetInfo to inspect
diff --git a/target-info.c b/target-info.c
index b25e2ada438..0716e2021b8 100644
--- a/target-info.c
+++ b/target-info.c
@@ -204,6 +204,16 @@ bool target_s390x(void)
return target_is_s390x(target_info());
}
+bool target_is_microblaze(const TargetInfo *ti)
+{
+ return ti->target_arch == SYS_EMU_TARGET_MICROBLAZE;
+}
+
+bool target_microblaze(void)
+{
+ return target_is_microblaze(target_info());
+}
+
bool target_is_base_riscv(const TargetInfo *ti)
{
switch (ti->target_arch) {
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 48/55] hw/microblaze: set petalogix-s3adsp1800 TypeInfo.is_available
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (46 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 47/55] target-info: add target_is_microblaze Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 49/55] hw/microblaze: expand petalogix-ml605 and xlnx-zynqmp-pmu to TypeInfo Yonggang Luo
` (6 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Set TypeInfo.is_available on the petalogix-s3adsp1800 leaf to
target_is_microblaze.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index c5f64319009..a1f41b10348 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -189,6 +189,7 @@ static const TypeInfo petalogix_s3adsp1800_machine_types[] = {
.name = TYPE_PETALOGIX_S3ADSP1800_MACHINE,
.parent = TYPE_MACHINE,
.class_init = petalogix_s3adsp1800_machine_class_init,
+ .is_available = target_is_microblaze,
.instance_size = sizeof(S3Adsp1800MachineState),
},
};
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 49/55] hw/microblaze: expand petalogix-ml605 and xlnx-zynqmp-pmu to TypeInfo
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (47 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 48/55] hw/microblaze: set petalogix-s3adsp1800 TypeInfo.is_available Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 50/55] hw/arm: expand leftover 32-bit DEFINE_MACHINE " Yonggang Luo
` (5 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace DEFINE_MACHINE with TypeInfo. Rename *_machine_init to
*_machine_class_init and set is_available to target_is_microblaze.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/microblaze/petalogix_ml605_mmu.c | 19 +++++++++++++++++--
hw/microblaze/xlnx-zynqmp-pmu.c | 19 +++++++++++++++++--
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 8f9f54ff1e2..508a8005a63 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -26,6 +26,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "target/microblaze/cpu.h"
@@ -214,10 +215,24 @@ petalogix_ml605_init(MachineState *machine)
}
-static void petalogix_ml605_machine_init(MachineClass *mc)
+static void petalogix_ml605_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "PetaLogix linux refdesign for xilinx ml605 (little endian)";
mc->init = petalogix_ml605_init;
}
-DEFINE_MACHINE("petalogix-ml605", petalogix_ml605_machine_init)
+static const TypeInfo petalogix_ml605_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("petalogix-ml605"),
+ .parent = TYPE_MACHINE,
+ .class_init = petalogix_ml605_machine_class_init,
+ .is_available = target_is_microblaze,
+};
+
+static void petalogix_ml605_machine_class_init_register_types(void)
+{
+ type_register_static(&petalogix_ml605_machine_class_init_typeinfo);
+}
+
+type_init(petalogix_ml605_machine_class_init_register_types)
diff --git a/hw/microblaze/xlnx-zynqmp-pmu.c b/hw/microblaze/xlnx-zynqmp-pmu.c
index 00154236bf8..79b70eb5ad7 100644
--- a/hw/microblaze/xlnx-zynqmp-pmu.c
+++ b/hw/microblaze/xlnx-zynqmp-pmu.c
@@ -16,6 +16,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "system/address-spaces.h"
#include "hw/core/boards.h"
@@ -179,10 +180,24 @@ static void xlnx_zynqmp_pmu_init(MachineState *machine)
NULL);
}
-static void xlnx_zynqmp_pmu_machine_init(MachineClass *mc)
+static void xlnx_zynqmp_pmu_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "Xilinx ZynqMP PMU machine (little endian)";
mc->init = xlnx_zynqmp_pmu_init;
}
-DEFINE_MACHINE("xlnx-zynqmp-pmu", xlnx_zynqmp_pmu_machine_init)
+static const TypeInfo xlnx_zynqmp_pmu_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("xlnx-zynqmp-pmu"),
+ .parent = TYPE_MACHINE,
+ .class_init = xlnx_zynqmp_pmu_machine_class_init,
+ .is_available = target_is_microblaze,
+};
+
+static void xlnx_zynqmp_pmu_machine_class_init_register_types(void)
+{
+ type_register_static(&xlnx_zynqmp_pmu_machine_class_init_typeinfo);
+}
+
+type_init(xlnx_zynqmp_pmu_machine_class_init_register_types)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 50/55] hw/arm: expand leftover 32-bit DEFINE_MACHINE to TypeInfo
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (48 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 49/55] hw/microblaze: expand petalogix-ml605 and xlnx-zynqmp-pmu to TypeInfo Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 51/55] hw/arm: expand imx8mm-evk " Yonggang Luo
` (4 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace remaining 32-bit DEFINE_MACHINE and DEFINE_MACHINE_EXTENDED
call sites with TypeInfo. Rename *_machine_init to
*_machine_class_init and set is_available to target_is_base_arm.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/bananapi_m2u.c | 22 +++++++++++++++++++---
hw/arm/cubieboard.c | 23 +++++++++++++++++++----
hw/arm/digic_boards.c | 19 +++++++++++++++++--
hw/arm/imx25_pdk.c | 19 +++++++++++++++++--
hw/arm/integratorcp.c | 23 +++++++++++++++++++----
hw/arm/kzm.c | 19 +++++++++++++++++--
hw/arm/max78000fthr.c | 19 +++++++++++++++++--
hw/arm/mcimx6ul-evk.c | 19 +++++++++++++++++--
hw/arm/mcimx7d-sabre.c | 23 +++++++++++++++++++----
hw/arm/msf2-som.c | 19 +++++++++++++++++--
hw/arm/netduino2.c | 19 +++++++++++++++++--
hw/arm/netduinoplus2.c | 19 +++++++++++++++++--
hw/arm/olimex-stm32-h405.c | 19 +++++++++++++++++--
hw/arm/orangepi.c | 23 +++++++++++++++++++----
hw/arm/stm32vldiscovery.c | 19 +++++++++++++++++--
15 files changed, 265 insertions(+), 39 deletions(-)
diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
index ccf60ba2955..a1d9105ce0d 100644
--- a/hw/arm/bananapi_m2u.c
+++ b/hw/arm/bananapi_m2u.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qemu/units.h"
#include "system/address-spaces.h"
#include "qapi/error.h"
@@ -133,8 +134,10 @@ static void bpim2u_init(MachineState *machine)
arm_load_kernel(&r40->cpus[0], machine, &bpms->bootinfo);
}
-static void bpim2u_machine_init(MachineClass *mc)
+static void bpim2u_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-a7"),
NULL
@@ -152,5 +155,18 @@ static void bpim2u_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE_EXTENDED("bpim2u", MACHINE, Bpim2uMachineState,
- bpim2u_machine_init, false, false, NULL)
+static const TypeInfo bpim2u_machine_class_init_typeinfo = {
+ .name = TYPE_BPIM2U_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = bpim2u_machine_class_init,
+ .instance_size = sizeof(Bpim2uMachineState),
+ .abstract = false,
+ .is_available = target_is_base_arm,
+};
+
+static void bpim2u_machine_class_init_register_types(void)
+{
+ type_register_static(&bpim2u_machine_class_init_typeinfo);
+}
+
+type_init(bpim2u_machine_class_init_register_types)
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index e4fef9cd76b..6e14d0e3351 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -16,6 +16,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/core/boards.h"
@@ -113,8 +114,10 @@ static void cubieboard_init(MachineState *machine)
arm_load_kernel(&a10->cpu, machine, &cbs->bootinfo);
}
-static void cubieboard_machine_init(MachineClass *mc)
+static void cubieboard_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-a8"),
NULL
@@ -132,6 +135,18 @@ static void cubieboard_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE_EXTENDED("cubieboard", MACHINE, CubieboardMachineState,
- cubieboard_machine_init, false, false,
- NULL)
+static const TypeInfo cubieboard_machine_class_init_typeinfo = {
+ .name = TYPE_CUBIEBOARD_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = cubieboard_machine_class_init,
+ .instance_size = sizeof(CubieboardMachineState),
+ .abstract = false,
+ .is_available = target_is_base_arm,
+};
+
+static void cubieboard_machine_class_init_register_types(void)
+{
+ type_register_static(&cubieboard_machine_class_init_typeinfo);
+}
+
+type_init(cubieboard_machine_class_init_register_types)
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 90c19106ad0..e92d3177039 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "qemu/datadir.h"
#include "hw/core/boards.h"
@@ -136,8 +137,10 @@ static void canon_a1100_init(MachineState *machine)
digic4_board_init(machine, &digic4_board_canon_a1100);
}
-static void canon_a1100_machine_init(MachineClass *mc)
+static void canon_a1100_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "Canon PowerShot A1100 IS (ARM946)";
mc->init = &canon_a1100_init;
mc->ignore_memory_transaction_failures = true;
@@ -145,4 +148,16 @@ static void canon_a1100_machine_init(MachineClass *mc)
mc->default_ram_id = "ram";
}
-DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
+static const TypeInfo canon_a1100_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("canon-a1100"),
+ .parent = TYPE_MACHINE,
+ .class_init = canon_a1100_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void canon_a1100_machine_class_init_register_types(void)
+{
+ type_register_static(&canon_a1100_machine_class_init_typeinfo);
+}
+
+type_init(canon_a1100_machine_class_init_register_types)
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
index 243c30a67e7..c0c473e7103 100644
--- a/hw/arm/imx25_pdk.c
+++ b/hw/arm/imx25_pdk.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/qdev-properties.h"
#include "hw/arm/fsl-imx25.h"
@@ -140,8 +141,10 @@ static void imx25_pdk_init(MachineState *machine)
}
}
-static void imx25_pdk_machine_init(MachineClass *mc)
+static void imx25_pdk_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "ARM i.MX25 PDK board (ARM926)";
mc->init = imx25_pdk_init;
mc->ignore_memory_transaction_failures = true;
@@ -149,4 +152,16 @@ static void imx25_pdk_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE("imx25-pdk", imx25_pdk_machine_init)
+static const TypeInfo imx25_pdk_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("imx25-pdk"),
+ .parent = TYPE_MACHINE,
+ .class_init = imx25_pdk_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void imx25_pdk_machine_class_init_register_types(void)
+{
+ type_register_static(&imx25_pdk_machine_class_init_typeinfo);
+}
+
+type_init(imx25_pdk_machine_class_init_register_types)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index b766edeeee1..94ab08591ce 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/sysbus.h"
#include "migration/vmstate.h"
@@ -691,8 +692,10 @@ static void integratorcp_init(MachineState *machine)
arm_load_kernel(cpu, machine, &icms->bootinfo);
}
-static void integratorcp_machine_init(MachineClass *mc)
+static void integratorcp_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
mc->init = integratorcp_init;
mc->ignore_memory_transaction_failures = true;
@@ -703,9 +706,21 @@ static void integratorcp_machine_init(MachineClass *mc)
machine_add_audiodev_property(mc);
}
-DEFINE_MACHINE_EXTENDED("integratorcp", MACHINE, IntegratorcpMachineState,
- integratorcp_machine_init, false, false,
- NULL)
+static const TypeInfo integratorcp_machine_class_init_typeinfo = {
+ .name = TYPE_INTEGRATORCP_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = integratorcp_machine_class_init,
+ .instance_size = sizeof(IntegratorcpMachineState),
+ .abstract = false,
+ .is_available = target_is_base_arm,
+};
+
+static void integratorcp_machine_class_init_register_types(void)
+{
+ type_register_static(&integratorcp_machine_class_init_typeinfo);
+}
+
+type_init(integratorcp_machine_class_init_register_types)
static const Property core_properties[] = {
DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 387bf54ced1..aaff504564f 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -14,6 +14,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx31.h"
#include "hw/arm/boot.h"
@@ -129,12 +130,26 @@ static void kzm_init(MachineState *machine)
}
}
-static void kzm_machine_init(MachineClass *mc)
+static void kzm_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "ARM KZM Emulation Baseboard (ARM1136)";
mc->init = kzm_init;
mc->ignore_memory_transaction_failures = true;
mc->default_ram_id = "kzm.ram";
}
-DEFINE_MACHINE("kzm", kzm_machine_init)
+static const TypeInfo kzm_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("kzm"),
+ .parent = TYPE_MACHINE,
+ .class_init = kzm_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void kzm_machine_class_init_register_types(void)
+{
+ type_register_static(&kzm_machine_class_init_typeinfo);
+}
+
+type_init(kzm_machine_class_init_register_types)
diff --git a/hw/arm/max78000fthr.c b/hw/arm/max78000fthr.c
index ed50bb91979..dce29ccb6a1 100644
--- a/hw/arm/max78000fthr.c
+++ b/hw/arm/max78000fthr.c
@@ -7,6 +7,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -35,8 +36,10 @@ static void max78000_init(MachineState *machine)
0x00000000, FLASH_SIZE);
}
-static void max78000_machine_init(MachineClass *mc)
+static void max78000_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m4"),
NULL
@@ -47,4 +50,16 @@ static void max78000_machine_init(MachineClass *mc)
mc->valid_cpu_types = valid_cpu_types;
}
-DEFINE_MACHINE("max78000fthr", max78000_machine_init)
+static const TypeInfo max78000_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("max78000fthr"),
+ .parent = TYPE_MACHINE,
+ .class_init = max78000_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void max78000_machine_class_init_register_types(void)
+{
+ type_register_static(&max78000_machine_class_init_typeinfo);
+}
+
+type_init(max78000_machine_class_init_register_types)
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
index 40071d2c7b9..30de24727ad 100644
--- a/hw/arm/mcimx6ul-evk.c
+++ b/hw/arm/mcimx6ul-evk.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx6ul.h"
#include "hw/arm/boot.h"
@@ -68,8 +69,10 @@ static void mcimx6ul_evk_init(MachineState *machine)
}
}
-static void mcimx6ul_evk_machine_init(MachineClass *mc)
+static void mcimx6ul_evk_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex-A7)";
mc->init = mcimx6ul_evk_init;
mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
@@ -77,4 +80,16 @@ static void mcimx6ul_evk_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
+static const TypeInfo mcimx6ul_evk_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("mcimx6ul-evk"),
+ .parent = TYPE_MACHINE,
+ .class_init = mcimx6ul_evk_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void mcimx6ul_evk_machine_class_init_register_types(void)
+{
+ type_register_static(&mcimx6ul_evk_machine_class_init_typeinfo);
+}
+
+type_init(mcimx6ul_evk_machine_class_init_register_types)
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
index 65fdb19c06f..14e6de8662a 100644
--- a/hw/arm/mcimx7d-sabre.c
+++ b/hw/arm/mcimx7d-sabre.c
@@ -13,6 +13,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx7.h"
#include "hw/arm/boot.h"
@@ -76,8 +77,10 @@ static void mcimx7d_sabre_init(MachineState *machine)
}
}
-static void mcimx7d_sabre_machine_init(MachineClass *mc)
+static void mcimx7d_sabre_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex-A7)";
mc->init = mcimx7d_sabre_init;
mc->max_cpus = FSL_IMX7_NUM_CPUS;
@@ -85,6 +88,18 @@ static void mcimx7d_sabre_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE_EXTENDED("mcimx7d-sabre", MACHINE, Mcimx7dSabreMachineState,
- mcimx7d_sabre_machine_init, false, false,
- NULL)
+static const TypeInfo mcimx7d_sabre_machine_class_init_typeinfo = {
+ .name = TYPE_MCIMX7D_SABRE_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = mcimx7d_sabre_machine_class_init,
+ .instance_size = sizeof(Mcimx7dSabreMachineState),
+ .abstract = false,
+ .is_available = target_is_base_arm,
+};
+
+static void mcimx7d_sabre_machine_class_init_register_types(void)
+{
+ type_register_static(&mcimx7d_sabre_machine_class_init_typeinfo);
+}
+
+type_init(mcimx7d_sabre_machine_class_init_register_types)
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
index 1372d7f628a..5dc30b54d7d 100644
--- a/hw/arm/msf2-som.c
+++ b/hw/arm/msf2-som.c
@@ -26,6 +26,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
@@ -96,8 +97,10 @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
0, soc->envm_size);
}
-static void emcraft_sf2_machine_init(MachineClass *mc)
+static void emcraft_sf2_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m3"),
NULL
@@ -108,4 +111,16 @@ static void emcraft_sf2_machine_init(MachineClass *mc)
mc->valid_cpu_types = valid_cpu_types;
}
-DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
+static const TypeInfo emcraft_sf2_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("emcraft-sf2"),
+ .parent = TYPE_MACHINE,
+ .class_init = emcraft_sf2_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void emcraft_sf2_machine_class_init_register_types(void)
+{
+ type_register_static(&emcraft_sf2_machine_class_init_typeinfo);
+}
+
+type_init(emcraft_sf2_machine_class_init_register_types)
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
index 0db8798b4bd..5cb7d05877f 100644
--- a/hw/arm/netduino2.c
+++ b/hw/arm/netduino2.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -52,8 +53,10 @@ static void netduino2_init(MachineState *machine)
0, FLASH_SIZE);
}
-static void netduino2_machine_init(MachineClass *mc)
+static void netduino2_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m3"),
NULL
@@ -65,4 +68,16 @@ static void netduino2_machine_init(MachineClass *mc)
mc->ignore_memory_transaction_failures = true;
}
-DEFINE_MACHINE("netduino2", netduino2_machine_init)
+static const TypeInfo netduino2_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("netduino2"),
+ .parent = TYPE_MACHINE,
+ .class_init = netduino2_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void netduino2_machine_class_init_register_types(void)
+{
+ type_register_static(&netduino2_machine_class_init_typeinfo);
+}
+
+type_init(netduino2_machine_class_init_register_types)
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
index 5ac0eb81637..7a750988f17 100644
--- a/hw/arm/netduinoplus2.c
+++ b/hw/arm/netduinoplus2.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -53,8 +54,10 @@ static void netduinoplus2_init(MachineState *machine)
0, FLASH_SIZE);
}
-static void netduinoplus2_machine_init(MachineClass *mc)
+static void netduinoplus2_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m4"),
NULL
@@ -65,4 +68,16 @@ static void netduinoplus2_machine_init(MachineClass *mc)
mc->valid_cpu_types = valid_cpu_types;
}
-DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)
+static const TypeInfo netduinoplus2_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("netduinoplus2"),
+ .parent = TYPE_MACHINE,
+ .class_init = netduinoplus2_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void netduinoplus2_machine_class_init_register_types(void)
+{
+ type_register_static(&netduinoplus2_machine_class_init_typeinfo);
+}
+
+type_init(netduinoplus2_machine_class_init_register_types)
diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c
index de9ac4978ce..4e93a245998 100644
--- a/hw/arm/olimex-stm32-h405.c
+++ b/hw/arm/olimex-stm32-h405.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -56,8 +57,10 @@ static void olimex_stm32_h405_init(MachineState *machine)
0, FLASH_SIZE);
}
-static void olimex_stm32_h405_machine_init(MachineClass *mc)
+static void olimex_stm32_h405_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m4"),
NULL
@@ -71,4 +74,16 @@ static void olimex_stm32_h405_machine_init(MachineClass *mc)
mc->default_ram_size = 0;
}
-DEFINE_MACHINE("olimex-stm32-h405", olimex_stm32_h405_machine_init)
+static const TypeInfo olimex_stm32_h405_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("olimex-stm32-h405"),
+ .parent = TYPE_MACHINE,
+ .class_init = olimex_stm32_h405_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void olimex_stm32_h405_machine_class_init_register_types(void)
+{
+ type_register_static(&olimex_stm32_h405_machine_class_init_typeinfo);
+}
+
+type_init(olimex_stm32_h405_machine_class_init_register_types)
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
index 18ed174032b..c6b0906c980 100644
--- a/hw/arm/orangepi.c
+++ b/hw/arm/orangepi.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qemu/units.h"
#include "system/address-spaces.h"
#include "qapi/error.h"
@@ -111,8 +112,10 @@ static void orangepi_init(MachineState *machine)
arm_load_kernel(&h3->cpus[0], machine, &opms->bootinfo);
}
-static void orangepi_machine_init(MachineClass *mc)
+static void orangepi_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-a7"),
NULL
@@ -132,6 +135,18 @@ static void orangepi_machine_init(MachineClass *mc)
mc->auto_create_sdcard = true;
}
-DEFINE_MACHINE_EXTENDED("orangepi-pc", MACHINE, OrangePiMachineState,
- orangepi_machine_init, false, false,
- NULL)
+static const TypeInfo orangepi_machine_class_init_typeinfo = {
+ .name = TYPE_ORANGEPI_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = orangepi_machine_class_init,
+ .instance_size = sizeof(OrangePiMachineState),
+ .abstract = false,
+ .is_available = target_is_base_arm,
+};
+
+static void orangepi_machine_class_init_register_types(void)
+{
+ type_register_static(&orangepi_machine_class_init_typeinfo);
+}
+
+type_init(orangepi_machine_class_init_register_types)
diff --git a/hw/arm/stm32vldiscovery.c b/hw/arm/stm32vldiscovery.c
index d899a134b38..3b439c80a67 100644
--- a/hw/arm/stm32vldiscovery.c
+++ b/hw/arm/stm32vldiscovery.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "qapi/error.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -56,8 +57,10 @@ static void stm32vldiscovery_init(MachineState *machine)
0, FLASH_SIZE);
}
-static void stm32vldiscovery_machine_init(MachineClass *mc)
+static void stm32vldiscovery_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m3"),
NULL
@@ -68,4 +71,16 @@ static void stm32vldiscovery_machine_init(MachineClass *mc)
mc->valid_cpu_types = valid_cpu_types;
}
-DEFINE_MACHINE("stm32vldiscovery", stm32vldiscovery_machine_init)
+static const TypeInfo stm32vldiscovery_machine_class_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("stm32vldiscovery"),
+ .parent = TYPE_MACHINE,
+ .class_init = stm32vldiscovery_machine_class_init,
+ .is_available = target_is_base_arm,
+};
+
+static void stm32vldiscovery_machine_class_init_register_types(void)
+{
+ type_register_static(&stm32vldiscovery_machine_class_init_typeinfo);
+}
+
+type_init(stm32vldiscovery_machine_class_init_register_types)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 51/55] hw/arm: expand imx8mm-evk DEFINE_MACHINE to TypeInfo
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (49 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 50/55] hw/arm: expand leftover 32-bit DEFINE_MACHINE " Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 52/55] hw/arm: set virt TypeInfo.is_available Yonggang Luo
` (3 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Replace DEFINE_MACHINE_EXTENDED with a TypeInfo, rename
imx8mm_evk_machine_init to imx8mm_evk_machine_class_init, and set
is_available to target_is_aarch64.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/imx8mm-evk.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
index c3215b11cb9..5dfd8250459 100644
--- a/hw/arm/imx8mm-evk.c
+++ b/hw/arm/imx8mm-evk.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/target-info.h"
#include "system/address-spaces.h"
#include "hw/arm/boot.h"
#include "hw/arm/fsl-imx8mm.h"
@@ -122,8 +123,10 @@ static const char *imx8mm_evk_get_default_cpu_type(const MachineState *ms)
return ARM_CPU_TYPE_NAME("cortex-a53");
}
-static void imx8mm_evk_machine_init(MachineClass *mc)
+static void imx8mm_evk_machine_class_init(ObjectClass *oc, const void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "NXP i.MX 8MM EVK Board";
mc->init = imx8mm_evk_init;
mc->max_cpus = FSL_IMX8MM_NUM_CPUS;
@@ -133,6 +136,18 @@ static void imx8mm_evk_machine_init(MachineClass *mc)
mc->get_default_cpu_type = imx8mm_evk_get_default_cpu_type;
}
-DEFINE_MACHINE_EXTENDED("imx8mm-evk", MACHINE, Imx8mmEvkMachineState,
- imx8mm_evk_machine_init, false, false,
- NULL)
+static const TypeInfo imx8mm_evk_machine_class_init_typeinfo = {
+ .name = TYPE_IMX8MM_EVK_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = imx8mm_evk_machine_class_init,
+ .instance_size = sizeof(Imx8mmEvkMachineState),
+ .abstract = false,
+ .is_available = target_is_aarch64,
+};
+
+static void imx8mm_evk_machine_class_init_register_types(void)
+{
+ type_register_static(&imx8mm_evk_machine_class_init_typeinfo);
+}
+
+type_init(imx8mm_evk_machine_class_init_register_types)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 52/55] hw/arm: set virt TypeInfo.is_available
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (50 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 51/55] hw/arm: expand imx8mm-evk " Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 53/55] hw/arm: set remaining 32-bit machine TypeInfo.is_available Yonggang Luo
` (2 subsequent siblings)
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Set TypeInfo.is_available to target_is_base_arm on
DEFINE_VIRT_MACHINE_IMPL.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/virt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3eecf094bcc..a0a954ce693 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -132,6 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc)
.name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
.parent = TYPE_VIRT_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
+ .is_available = target_is_base_arm, \
}; \
static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
{ \
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 53/55] hw/arm: set remaining 32-bit machine TypeInfo.is_available
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (51 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 52/55] hw/arm: set virt TypeInfo.is_available Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 54/55] hw/arm: set aarch64-only " Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 55/55] tests/qtest: cover combined qemu-system machines Yonggang Luo
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Set TypeInfo.is_available to target_is_base_arm on remaining
32-bit TypeInfo leaves, including aspeed, raspi0/1/2, mps, and
npcm7xx. raspi3ap/3b use target_is_aarch64 in the same raspi
TypeInfo array.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/aspeed_ast1040_evb.c | 1 +
hw/arm/aspeed_ast10x0_evb.c | 2 ++
hw/arm/aspeed_ast2400_palmetto.c | 1 +
hw/arm/aspeed_ast2400_quanta-q71l.c | 1 +
hw/arm/aspeed_ast2400_supermicrox11.c | 1 +
hw/arm/aspeed_ast2500_evb.c | 1 +
hw/arm/aspeed_ast2500_g220a.c | 1 +
hw/arm/aspeed_ast2500_romulus.c | 1 +
hw/arm/aspeed_ast2500_supermicro-x11spi.c | 1 +
hw/arm/aspeed_ast2500_tiogapass.c | 1 +
hw/arm/aspeed_ast2500_witherspoon.c | 1 +
hw/arm/aspeed_ast2500_yosemitev2.c | 1 +
hw/arm/aspeed_ast2600_anacapa.c | 1 +
hw/arm/aspeed_ast2600_bletchley.c | 1 +
hw/arm/aspeed_ast2600_catalina.c | 1 +
hw/arm/aspeed_ast2600_evb.c | 1 +
hw/arm/aspeed_ast2600_fby35.c | 1 +
hw/arm/aspeed_ast2600_fuji.c | 1 +
hw/arm/aspeed_ast2600_gb200nvl.c | 1 +
hw/arm/aspeed_ast2600_rainier.c | 1 +
hw/arm/aspeed_ast2600_sanmiguel.c | 1 +
hw/arm/b-l475e-iot01a.c | 1 +
hw/arm/collie.c | 1 +
hw/arm/exynos4_boards.c | 2 ++
hw/arm/microbit.c | 1 +
hw/arm/mps2-tz.c | 5 +++++
hw/arm/mps2.c | 4 ++++
hw/arm/mps3r.c | 1 +
hw/arm/musca.c | 2 ++
hw/arm/npcm7xx_boards.c | 5 +++++
hw/arm/omap_sx1.c | 2 ++
hw/arm/raspi.c | 3 +++
hw/arm/realview.c | 4 ++++
hw/arm/sabrelite.c | 1 +
hw/arm/stellaris.c | 2 ++
hw/arm/versatilepb.c | 2 ++
hw/arm/vexpress.c | 2 ++
hw/arm/xilinx_zynq.c | 1 +
38 files changed, 61 insertions(+)
diff --git a/hw/arm/aspeed_ast1040_evb.c b/hw/arm/aspeed_ast1040_evb.c
index 486f0f6a1ba..d66847c602c 100644
--- a/hw/arm/aspeed_ast1040_evb.c
+++ b/hw/arm/aspeed_ast1040_evb.c
@@ -79,6 +79,7 @@ static const TypeInfo aspeed_ast1040_evb_types[] = {
{
.name = MACHINE_TYPE_NAME("ast1040-evb"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_ast1040_evb_class_init,
}
};
diff --git a/hw/arm/aspeed_ast10x0_evb.c b/hw/arm/aspeed_ast10x0_evb.c
index c937bb74665..5b5adf7018e 100644
--- a/hw/arm/aspeed_ast10x0_evb.c
+++ b/hw/arm/aspeed_ast10x0_evb.c
@@ -117,10 +117,12 @@ static const TypeInfo aspeed_ast10x0_evb_types[] = {
{
.name = MACHINE_TYPE_NAME("ast1030-evb"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
}, {
.name = MACHINE_TYPE_NAME("ast1060-evb"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_minibmc_machine_ast1060_evb_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2400_palmetto.c b/hw/arm/aspeed_ast2400_palmetto.c
index e2350e5b6ca..f8abd041c3a 100644
--- a/hw/arm/aspeed_ast2400_palmetto.c
+++ b/hw/arm/aspeed_ast2400_palmetto.c
@@ -71,6 +71,7 @@ static const TypeInfo aspeed_ast2400_palmetto_types[] = {
{
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_palmetto_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2400_quanta-q71l.c b/hw/arm/aspeed_ast2400_quanta-q71l.c
index e8cbbb8a052..6636d19d142 100644
--- a/hw/arm/aspeed_ast2400_quanta-q71l.c
+++ b/hw/arm/aspeed_ast2400_quanta-q71l.c
@@ -77,6 +77,7 @@ static const TypeInfo aspeed_ast2400_quanta_q71l_types[] = {
{
.name = MACHINE_TYPE_NAME("quanta-q71l-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_quanta_q71l_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2400_supermicrox11.c b/hw/arm/aspeed_ast2400_supermicrox11.c
index c75898cc6d1..14a49c82c86 100644
--- a/hw/arm/aspeed_ast2400_supermicrox11.c
+++ b/hw/arm/aspeed_ast2400_supermicrox11.c
@@ -72,6 +72,7 @@ static const TypeInfo aspeed_ast2400_supermicrox11_types[] = {
{
.name = MACHINE_TYPE_NAME("supermicrox11-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_supermicrox11_bmc_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_evb.c b/hw/arm/aspeed_ast2500_evb.c
index 6ca2a36322c..58c6ed316f0 100644
--- a/hw/arm/aspeed_ast2500_evb.c
+++ b/hw/arm/aspeed_ast2500_evb.c
@@ -58,6 +58,7 @@ static const TypeInfo aspeed_ast2500_evb_types[] = {
{
.name = MACHINE_TYPE_NAME("ast2500-evb"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_ast2500_evb_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_g220a.c b/hw/arm/aspeed_ast2500_g220a.c
index 00bb1c61053..5deedad77cb 100644
--- a/hw/arm/aspeed_ast2500_g220a.c
+++ b/hw/arm/aspeed_ast2500_g220a.c
@@ -83,6 +83,7 @@ static const TypeInfo aspeed_ast2500_g220a_types[] = {
{
.name = MACHINE_TYPE_NAME("g220a-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_g220a_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_romulus.c b/hw/arm/aspeed_ast2500_romulus.c
index 340a74408b6..5668915db55 100644
--- a/hw/arm/aspeed_ast2500_romulus.c
+++ b/hw/arm/aspeed_ast2500_romulus.c
@@ -53,6 +53,7 @@ static const TypeInfo aspeed_ast2500_romulus_types[] = {
{
.name = MACHINE_TYPE_NAME("romulus-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_romulus_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_supermicro-x11spi.c b/hw/arm/aspeed_ast2500_supermicro-x11spi.c
index 5a7e49d6ccd..9e5e8c4246c 100644
--- a/hw/arm/aspeed_ast2500_supermicro-x11spi.c
+++ b/hw/arm/aspeed_ast2500_supermicro-x11spi.c
@@ -68,6 +68,7 @@ static const TypeInfo aspeed_ast2500_supermicro_x11spi_types[] = {
{
.name = MACHINE_TYPE_NAME("supermicro-x11spi-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_supermicro_x11spi_bmc_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_tiogapass.c b/hw/arm/aspeed_ast2500_tiogapass.c
index 6cb567526c4..d9ecc98f96f 100644
--- a/hw/arm/aspeed_ast2500_tiogapass.c
+++ b/hw/arm/aspeed_ast2500_tiogapass.c
@@ -81,6 +81,7 @@ static const TypeInfo aspeed_ast2500_tiogapass_types[] = {
{
.name = MACHINE_TYPE_NAME("tiogapass-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_tiogapass_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_witherspoon.c b/hw/arm/aspeed_ast2500_witherspoon.c
index 26ddb673470..e2bf25ee512 100644
--- a/hw/arm/aspeed_ast2500_witherspoon.c
+++ b/hw/arm/aspeed_ast2500_witherspoon.c
@@ -103,6 +103,7 @@ static const TypeInfo aspeed_ast2500_witherspoon_types[] = {
{
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_witherspoon_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2500_yosemitev2.c b/hw/arm/aspeed_ast2500_yosemitev2.c
index 3ba1ed5f6fa..71375dbacd0 100644
--- a/hw/arm/aspeed_ast2500_yosemitev2.c
+++ b/hw/arm/aspeed_ast2500_yosemitev2.c
@@ -82,6 +82,7 @@ static const TypeInfo aspeed_ast2500_yosemitev2_types[] = {
{
.name = MACHINE_TYPE_NAME("yosemitev2-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_yosemitev2_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_anacapa.c b/hw/arm/aspeed_ast2600_anacapa.c
index 25578db5894..0d81ba069d5 100644
--- a/hw/arm/aspeed_ast2600_anacapa.c
+++ b/hw/arm/aspeed_ast2600_anacapa.c
@@ -366,6 +366,7 @@ static const TypeInfo aspeed_ast2600_anacapa_types[] = {
{
.name = MACHINE_TYPE_NAME("anacapa-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_anacapa_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_bletchley.c b/hw/arm/aspeed_ast2600_bletchley.c
index 6fa606c047e..abe59887d8f 100644
--- a/hw/arm/aspeed_ast2600_bletchley.c
+++ b/hw/arm/aspeed_ast2600_bletchley.c
@@ -88,6 +88,7 @@ static const TypeInfo aspeed_ast2600_bletchley_types[] = {
{
.name = MACHINE_TYPE_NAME("bletchley-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_bletchley_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c
index 4f2b396f6f0..c98dd587f74 100644
--- a/hw/arm/aspeed_ast2600_catalina.c
+++ b/hw/arm/aspeed_ast2600_catalina.c
@@ -672,6 +672,7 @@ static const TypeInfo aspeed_ast2600_catalina_types[] = {
{
.name = MACHINE_TYPE_NAME("catalina-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_catalina_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_evb.c b/hw/arm/aspeed_ast2600_evb.c
index 8a17c4453e9..b3930d13a7a 100644
--- a/hw/arm/aspeed_ast2600_evb.c
+++ b/hw/arm/aspeed_ast2600_evb.c
@@ -56,6 +56,7 @@ static const TypeInfo aspeed_ast2600_evb_types[] = {
{
.name = MACHINE_TYPE_NAME("ast2600-evb"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_ast2600_evb_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_fby35.c b/hw/arm/aspeed_ast2600_fby35.c
index 28c9c143d88..9c180470883 100644
--- a/hw/arm/aspeed_ast2600_fby35.c
+++ b/hw/arm/aspeed_ast2600_fby35.c
@@ -169,6 +169,7 @@ static const TypeInfo aspeed_ast2600_fby35_types[] = {
{
.name = MACHINE_TYPE_NAME("fby35-bmc"),
.parent = MACHINE_TYPE_NAME("ast2600-evb"),
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_fby35_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_fuji.c b/hw/arm/aspeed_ast2600_fuji.c
index 08d809b2fd9..6fc9dd7a2e6 100644
--- a/hw/arm/aspeed_ast2600_fuji.c
+++ b/hw/arm/aspeed_ast2600_fuji.c
@@ -129,6 +129,7 @@ static const TypeInfo aspeed_ast2600_fuji_types[] = {
{
.name = MACHINE_TYPE_NAME("fuji-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_fuji_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_gb200nvl.c b/hw/arm/aspeed_ast2600_gb200nvl.c
index c9c0b6cb6e4..1b52cd42876 100644
--- a/hw/arm/aspeed_ast2600_gb200nvl.c
+++ b/hw/arm/aspeed_ast2600_gb200nvl.c
@@ -102,6 +102,7 @@ static const TypeInfo aspeed_ast2600_gb200nvl_types[] = {
{
.name = MACHINE_TYPE_NAME("gb200nvl-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_gb200nvl_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_rainier.c b/hw/arm/aspeed_ast2600_rainier.c
index 43a8f01a9e7..812c801a095 100644
--- a/hw/arm/aspeed_ast2600_rainier.c
+++ b/hw/arm/aspeed_ast2600_rainier.c
@@ -189,6 +189,7 @@ static const TypeInfo aspeed_ast2600_rainier_types[] = {
{
.name = MACHINE_TYPE_NAME("rainier-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_rainier_class_init,
}
};
diff --git a/hw/arm/aspeed_ast2600_sanmiguel.c b/hw/arm/aspeed_ast2600_sanmiguel.c
index 345a9c94167..b0979f3815f 100644
--- a/hw/arm/aspeed_ast2600_sanmiguel.c
+++ b/hw/arm/aspeed_ast2600_sanmiguel.c
@@ -396,6 +396,7 @@ static const TypeInfo aspeed_ast2600_sanmiguel_types[] = {
{
.name = MACHINE_TYPE_NAME("sanmiguel-bmc"),
.parent = TYPE_ASPEED_MACHINE,
+ .is_available = target_is_base_arm,
.class_init = aspeed_machine_sanmiguel_class_init,
}
};
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
index de19212ab85..f7322eb8de8 100644
--- a/hw/arm/b-l475e-iot01a.c
+++ b/hw/arm/b-l475e-iot01a.c
@@ -129,6 +129,7 @@ static const TypeInfo bl475e_machine_type[] = {
{
.name = TYPE_B_L475E_IOT01A,
.parent = TYPE_MACHINE,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(Bl475eMachineState),
.class_init = bl475e_machine_init,
}
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index ca6b3addb7b..0c81feaea16 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -83,6 +83,7 @@ static const TypeInfo collie_machine_typeinfo = {
.name = TYPE_COLLIE_MACHINE,
.parent = TYPE_MACHINE,
.class_init = collie_machine_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(CollieMachineState),
};
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 78632877df8..6927bee5a33 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -168,6 +168,7 @@ static const TypeInfo nuri_type = {
.name = MACHINE_TYPE_NAME("nuri"),
.parent = TYPE_MACHINE,
.class_init = nuri_class_init,
+ .is_available = target_is_base_arm,
};
static void smdkc210_class_init(ObjectClass *oc, const void *data)
@@ -188,6 +189,7 @@ static const TypeInfo smdkc210_type = {
.name = MACHINE_TYPE_NAME("smdkc210"),
.parent = TYPE_MACHINE,
.class_init = smdkc210_class_init,
+ .is_available = target_is_base_arm,
};
static void exynos4_machines_init(void)
diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c
index c1a3f6903fe..d6e52c1865a 100644
--- a/hw/arm/microbit.c
+++ b/hw/arm/microbit.c
@@ -74,6 +74,7 @@ static const TypeInfo microbit_info = {
.parent = TYPE_MACHINE,
.instance_size = sizeof(MicrobitMachineState),
.class_init = microbit_machine_class_init,
+ .is_available = target_is_base_arm,
};
static void microbit_machine_init(void)
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 7f41a74df1a..08d875dc373 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -1621,30 +1621,35 @@ static const TypeInfo mps2tz_an505_info = {
.name = TYPE_MPS2TZ_AN505_MACHINE,
.parent = TYPE_MPS2TZ_MACHINE,
.class_init = mps2tz_an505_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps2tz_an521_info = {
.name = TYPE_MPS2TZ_AN521_MACHINE,
.parent = TYPE_MPS2TZ_MACHINE,
.class_init = mps2tz_an521_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps3tz_an524_info = {
.name = TYPE_MPS3TZ_AN524_MACHINE,
.parent = TYPE_MPS2TZ_MACHINE,
.class_init = mps3tz_an524_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps3tz_an547_info = {
.name = TYPE_MPS3TZ_AN547_MACHINE,
.parent = TYPE_MPS2TZ_MACHINE,
.class_init = mps3tz_an547_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps3tz_an555_info = {
.name = TYPE_MPS3TZ_AN555_MACHINE,
.parent = TYPE_MPS2TZ_MACHINE,
.class_init = mps3tz_an555_class_init,
+ .is_available = target_is_base_arm,
};
static void mps2tz_machine_init(void)
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 35d867328a9..c38d3f5ae6a 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -567,24 +567,28 @@ static const TypeInfo mps2_an385_info = {
.name = TYPE_MPS2_AN385_MACHINE,
.parent = TYPE_MPS2_MACHINE,
.class_init = mps2_an385_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps2_an386_info = {
.name = TYPE_MPS2_AN386_MACHINE,
.parent = TYPE_MPS2_MACHINE,
.class_init = mps2_an386_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps2_an500_info = {
.name = TYPE_MPS2_AN500_MACHINE,
.parent = TYPE_MPS2_MACHINE,
.class_init = mps2_an500_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo mps2_an511_info = {
.name = TYPE_MPS2_AN511_MACHINE,
.parent = TYPE_MPS2_MACHINE,
.class_init = mps2_an511_class_init,
+ .is_available = target_is_base_arm,
};
static void mps2_machine_init(void)
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
index 4bd5d83d567..320eb518b79 100644
--- a/hw/arm/mps3r.c
+++ b/hw/arm/mps3r.c
@@ -626,6 +626,7 @@ static const TypeInfo mps3r_machine_types[] = {
.name = TYPE_MPS3R_AN536_MACHINE,
.parent = TYPE_MPS3R_MACHINE,
.class_init = mps3r_an536_class_init,
+ .is_available = target_is_base_arm,
},
};
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
index 571bee1b72b..ebdebcd4495 100644
--- a/hw/arm/musca.c
+++ b/hw/arm/musca.c
@@ -657,12 +657,14 @@ static const TypeInfo musca_a_info = {
.name = TYPE_MUSCA_A_MACHINE,
.parent = TYPE_MUSCA_MACHINE,
.class_init = musca_a_class_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo musca_b1_info = {
.name = TYPE_MUSCA_B1_MACHINE,
.parent = TYPE_MUSCA_MACHINE,
.class_init = musca_b1_class_init,
+ .is_available = target_is_base_arm,
};
static void musca_machine_init(void)
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 9c526a26839..6aa29b4d2a9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -549,22 +549,27 @@ static const TypeInfo npcm7xx_machine_types[] = {
.name = MACHINE_TYPE_NAME("npcm750-evb"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = npcm750_evb_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("quanta-gsj"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = gsj_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = gbs_bmc_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("kudo-bmc"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = kudo_bmc_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("mori-bmc"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = mori_bmc_machine_class_init,
+ .is_available = target_is_base_arm,
},
};
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index a7e469ea6a3..5d2aaacbbe4 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -224,6 +224,7 @@ static const TypeInfo sx1_machine_v2_type = {
.name = MACHINE_TYPE_NAME("sx1"),
.parent = TYPE_MACHINE,
.class_init = sx1_machine_v2_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(Sx1MachineState),
};
@@ -244,6 +245,7 @@ static const TypeInfo sx1_machine_v1_type = {
.name = MACHINE_TYPE_NAME("sx1-v1"),
.parent = TYPE_MACHINE,
.class_init = sx1_machine_v1_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(Sx1MachineState),
};
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 22b06c6ca22..7ec650eada7 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -391,14 +391,17 @@ static const TypeInfo raspi_machine_types[] = {
.name = MACHINE_TYPE_NAME("raspi0"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi0_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("raspi1ap"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi1ap_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("raspi2b"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi2b_machine_class_init,
+ .is_available = target_is_base_arm,
}, {
.name = MACHINE_TYPE_NAME("raspi3ap"),
.parent = TYPE_RASPI_MACHINE,
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index ceba0331b08..4cffa725d60 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -435,6 +435,7 @@ static const TypeInfo realview_eb_type = {
.name = MACHINE_TYPE_NAME("realview-eb"),
.parent = TYPE_MACHINE,
.class_init = realview_eb_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(RealViewMachineState),
};
@@ -457,6 +458,7 @@ static const TypeInfo realview_eb_mpcore_type = {
.name = MACHINE_TYPE_NAME("realview-eb-mpcore"),
.parent = TYPE_MACHINE,
.class_init = realview_eb_mpcore_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(RealViewMachineState),
};
@@ -477,6 +479,7 @@ static const TypeInfo realview_pb_a8_type = {
.name = MACHINE_TYPE_NAME("realview-pb-a8"),
.parent = TYPE_MACHINE,
.class_init = realview_pb_a8_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(RealViewMachineState),
};
@@ -498,6 +501,7 @@ static const TypeInfo realview_pbx_a9_type = {
.name = MACHINE_TYPE_NAME("realview-pbx-a9"),
.parent = TYPE_MACHINE,
.class_init = realview_pbx_a9_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(RealViewMachineState),
};
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
index 05dfabd9376..e8aa9f41925 100644
--- a/hw/arm/sabrelite.c
+++ b/hw/arm/sabrelite.c
@@ -151,6 +151,7 @@ static const TypeInfo sabrelite_machine_init_typeinfo = {
.instance_init = sabrelite_machine_instance_init,
.instance_size = sizeof(SabreliteMachineState),
.abstract = false,
+ .is_available = target_is_base_arm,
};
static void sabrelite_machine_init_register_types(void)
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index f41315e1928..ec4faf26055 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1427,6 +1427,7 @@ static const TypeInfo lm3s811evb_type = {
.name = MACHINE_TYPE_NAME("lm3s811evb"),
.parent = TYPE_MACHINE,
.class_init = lm3s811evb_class_init,
+ .is_available = target_is_base_arm,
};
/*
@@ -1448,6 +1449,7 @@ static const TypeInfo lm3s6965evb_type = {
.name = MACHINE_TYPE_NAME("lm3s6965evb"),
.parent = TYPE_MACHINE,
.class_init = lm3s6965evb_class_init,
+ .is_available = target_is_base_arm,
};
static void stellaris_machine_init(void)
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index f94bf96599e..99ff59ca418 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -437,6 +437,7 @@ static const TypeInfo versatilepb_type = {
.parent = TYPE_MACHINE,
.class_init = versatilepb_class_init,
.instance_size = sizeof(VersatileMachineState),
+ .is_available = target_is_base_arm,
};
static void versatileab_class_init(ObjectClass *oc, const void *data)
@@ -459,6 +460,7 @@ static const TypeInfo versatileab_type = {
.parent = TYPE_MACHINE,
.class_init = versatileab_class_init,
.instance_size = sizeof(VersatileMachineState),
+ .is_available = target_is_base_arm,
};
static void versatile_machine_init(void)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a4328ec74bd..a2ad870af85 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -842,6 +842,7 @@ static const TypeInfo vexpress_a9_info = {
.parent = TYPE_VEXPRESS_MACHINE,
.class_init = vexpress_a9_class_init,
.instance_init = vexpress_a9_instance_init,
+ .is_available = target_is_base_arm,
};
static const TypeInfo vexpress_a15_info = {
@@ -849,6 +850,7 @@ static const TypeInfo vexpress_a15_info = {
.parent = TYPE_VEXPRESS_MACHINE,
.class_init = vexpress_a15_class_init,
.instance_init = vexpress_a15_instance_init,
+ .is_available = target_is_base_arm,
};
static void vexpress_machine_init(void)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index c1897ab1cf3..bc34cadfd11 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -477,6 +477,7 @@ static const TypeInfo zynq_machine_type = {
.name = TYPE_ZYNQ_MACHINE,
.parent = TYPE_MACHINE,
.class_init = zynq_machine_class_init,
+ .is_available = target_is_base_arm,
.instance_size = sizeof(ZynqMachineState),
};
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 54/55] hw/arm: set aarch64-only machine TypeInfo.is_available
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (52 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 53/55] hw/arm: set remaining 32-bit machine TypeInfo.is_available Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 55/55] tests/qtest: cover combined qemu-system machines Yonggang Luo
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Set TypeInfo.is_available to target_is_aarch64 on sbsa-ref,
versal leaves, xlnx-zcu102, imx8mp-evk, npcm845, axiado-scm3003,
and ARM xen-pvh.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/arm/ax3000-evk.c | 1 +
hw/arm/imx8mp-evk.c | 1 +
hw/arm/npcm8xx_boards.c | 1 +
hw/arm/sbsa-ref.c | 1 +
hw/arm/xen-pvh.c | 1 +
hw/arm/xlnx-versal-virt.c | 2 ++
hw/arm/xlnx-zcu102.c | 1 +
7 files changed, 8 insertions(+)
diff --git a/hw/arm/ax3000-evk.c b/hw/arm/ax3000-evk.c
index a1708488710..0c3e53e4e7d 100644
--- a/hw/arm/ax3000-evk.c
+++ b/hw/arm/ax3000-evk.c
@@ -21,6 +21,7 @@ static const TypeInfo ax3000_evk_types[] = {
.name = MACHINE_TYPE_NAME("axiado-scm3003"),
.parent = TYPE_AX3000_MACHINE,
.class_init = axiado_scm3003_class_init,
+ .is_available = target_is_aarch64,
}
};
diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c
index 3f376f86d91..bac2f9cbedf 100644
--- a/hw/arm/imx8mp-evk.c
+++ b/hw/arm/imx8mp-evk.c
@@ -159,6 +159,7 @@ static const TypeInfo imx8mp_evk_machine_types[] = {
.name = TYPE_IMX8MPEVK_MACHINE,
.parent = TYPE_MACHINE,
.class_init = imx8mp_evk_machine_class_init,
+ .is_available = target_is_aarch64,
.instance_init = imx8mp_evk_machine_init,
.instance_size = sizeof(FslImx8mpEvkState),
},
diff --git a/hw/arm/npcm8xx_boards.c b/hw/arm/npcm8xx_boards.c
index 4b3af165034..67b10843d88 100644
--- a/hw/arm/npcm8xx_boards.c
+++ b/hw/arm/npcm8xx_boards.c
@@ -248,6 +248,7 @@ static const TypeInfo npcm8xx_machine_types[] = {
.name = MACHINE_TYPE_NAME("npcm845-evb"),
.parent = TYPE_NPCM8XX_MACHINE,
.class_init = npcm845_evb_machine_class_init,
+ .is_available = target_is_aarch64,
},
};
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 158b461eb48..426fa914e80 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -945,6 +945,7 @@ static const TypeInfo sbsa_ref_info = {
.instance_finalize = sbsa_ref_instance_finalize,
.class_init = sbsa_ref_class_init,
.instance_size = sizeof(SBSAMachineState),
+ .is_available = target_is_aarch64,
};
static void sbsa_ref_machine_init(void)
diff --git a/hw/arm/xen-pvh.c b/hw/arm/xen-pvh.c
index f05956c1662..d9515f23e3b 100644
--- a/hw/arm/xen-pvh.c
+++ b/hw/arm/xen-pvh.c
@@ -95,6 +95,7 @@ static const TypeInfo xen_arm_machine_type = {
.class_init = xen_arm_machine_class_init,
.instance_size = sizeof(XenPVHMachineState),
.instance_init = xen_arm_instance_init,
+ .is_available = target_is_aarch64,
};
static void xen_arm_machine_register_types(void)
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 4018f2bf7d1..c02aa011916 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -401,12 +401,14 @@ static const TypeInfo versal_virt_machine_init_typeinfo = {
.name = TYPE_XLNX_VERSAL_VIRT_MACHINE,
.parent = TYPE_XLNX_VERSAL_VIRT_BASE_MACHINE,
.class_init = versal_virt_machine_class_init,
+ .is_available = target_is_aarch64,
};
static const TypeInfo versal2_virt_machine_init_typeinfo = {
.name = TYPE_XLNX_VERSAL2_VIRT_MACHINE,
.parent = TYPE_XLNX_VERSAL_VIRT_BASE_MACHINE,
.class_init = versal2_virt_machine_class_init,
+ .is_available = target_is_aarch64,
};
static void versal_virt_machine_init_register_types(void)
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index bb596218540..03b03b8317c 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -302,6 +302,7 @@ static const TypeInfo xlnx_zcu102_machine_init_typeinfo = {
.class_init = xlnx_zcu102_machine_class_init,
.instance_init = xlnx_zcu102_machine_instance_init,
.instance_size = sizeof(XlnxZCU102),
+ .is_available = target_is_aarch64,
};
static void xlnx_zcu102_machine_init_register_types(void)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v4 55/55] tests/qtest: cover combined qemu-system machines
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
` (53 preceding siblings ...)
2026-09-26 7:00 ` [PATCH v4 54/55] hw/arm: set aarch64-only " Yonggang Luo
@ 2026-09-26 7:00 ` Yonggang Luo
54 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-26 7:00 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
The combined qemu-system qtests check the linked machine list and
arch-prefixed -M help and errors. -readconfig [machine] type uses
arch:name, and a later bare -M keeps that prefix. The expected
arches come from single_binary_targets, plus none and the none
machine. Single-target binaries keep the historic -M cases.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
meson.build | 2 +
.../qtest/machine-list-combined-targets.h.in | 4 +
tests/qtest/machine-list-combined-test.c | 104 +++
tests/qtest/machine-option-test.c | 714 ++++++++++++++++++
tests/qtest/meson.build | 38 +
5 files changed, 862 insertions(+)
create mode 100644 tests/qtest/machine-list-combined-targets.h.in
create mode 100644 tests/qtest/machine-list-combined-test.c
create mode 100644 tests/qtest/machine-option-test.c
diff --git a/meson.build b/meson.build
index 96f493cb746..085151d65f8 100644
--- a/meson.build
+++ b/meson.build
@@ -4294,6 +4294,7 @@ single_binary_bases = {}
single_binary_deps = []
single_binary_crates = []
single_binary_available = false
+single_binary_targets = []
single_binary_supported_targets = [
'aarch64-softmmu',
@@ -4496,6 +4497,7 @@ foreach target : target_dirs
single_binary_deps += target_stubs
single_binary_crates += main_rs
single_binary_available = true
+ single_binary_targets += target_name
endif
execs = [{
'name': 'qemu-system-' + target_name,
diff --git a/tests/qtest/machine-list-combined-targets.h.in b/tests/qtest/machine-list-combined-targets.h.in
new file mode 100644
index 00000000000..ede99c53762
--- /dev/null
+++ b/tests/qtest/machine-list-combined-targets.h.in
@@ -0,0 +1,4 @@
+/* Generated from configured single_binary_supported_targets. */
+static const char * const combined_targets[] = {
+@COMBINED_TARGETS@
+};
diff --git a/tests/qtest/machine-list-combined-test.c b/tests/qtest/machine-list-combined-test.c
new file mode 100644
index 00000000000..90c4ae7b377
--- /dev/null
+++ b/tests/qtest/machine-list-combined-test.c
@@ -0,0 +1,104 @@
+/*
+ * Combined qemu-system machine list tests.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qobject/qdict.h"
+#include "qobject/qlist.h"
+#include "qobject/qstring.h"
+
+#include "machine-list-test.inc.h"
+
+#include "machine-list-combined-targets.h"
+
+static bool qemu_binary_is_combined(void)
+{
+ const char *bin = qtest_qemu_binary(NULL);
+
+ return g_str_has_suffix(bin, "qemu-system") ||
+ g_str_has_suffix(bin, "qemu-system.exe");
+}
+
+static QList *query_targets(QTestState *qts)
+{
+ QDict *resp;
+ QList *list;
+
+ resp = qtest_qmp(qts, "{'execute': 'query-targets'}");
+ g_assert(qdict_haskey(resp, "return"));
+ list = qdict_get_qlist(resp, "return");
+ qobject_ref(list);
+ qobject_unref(resp);
+ return list;
+}
+
+static QDict *target_entry(QList *targets, const char *arch,
+ const char *endianness)
+{
+ const QListEntry *e;
+
+ for (e = qlist_first(targets); e; e = qlist_next(e)) {
+ QDict *t = qobject_to(QDict, qlist_entry_obj(e));
+
+ if (!strcmp(qdict_get_str(t, "arch"), arch) &&
+ !strcmp(qdict_get_str(t, "endianness"), endianness)) {
+ return t;
+ }
+ }
+ return NULL;
+}
+
+static void test_combined_machine_list(void)
+{
+ QTestState *qts;
+ g_autoptr(QList) targets = NULL;
+ size_t i;
+
+ qts = qtest_init("-nodefaults -M none");
+ read_accel_flags(qts);
+ targets = query_targets(qts);
+ qtest_quit(qts);
+
+ g_assert_cmpuint(qlist_size(targets), ==,
+ G_N_ELEMENTS(combined_targets) + 1);
+ for (i = 0; i < G_N_ELEMENTS(combined_targets); i++) {
+ const struct ShippedTarget *t = lookup_shipped_target(combined_targets[i]);
+ QDict *tgt;
+
+ g_assert_nonnull(t);
+ tgt = target_entry(targets, t->arch, t->endianness);
+ g_assert_nonnull(tgt);
+ assert_name_list(qdict_get_qlist(tgt, "machines"), t->name,
+ t->machines, t->n_machines);
+ }
+ {
+ QDict *none = target_entry(targets, "none", "little");
+ QList *names;
+ const QListEntry *e;
+ bool saw_none = false;
+
+ g_assert_nonnull(none);
+ names = qdict_get_qlist(none, "machines");
+ for (e = qlist_first(names); e; e = qlist_next(e)) {
+ const char *name = qstring_get_str(qobject_to(QString,
+ qlist_entry_obj(e)));
+
+ if (!strcmp(name, "none")) {
+ saw_none = true;
+ }
+ }
+ g_assert_true(saw_none);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_assert_true(qemu_binary_is_combined());
+ g_test_add_func("/machine-list/combined", test_combined_machine_list);
+ return g_test_run();
+}
diff --git a/tests/qtest/machine-option-test.c b/tests/qtest/machine-option-test.c
new file mode 100644
index 00000000000..4ccc854fba0
--- /dev/null
+++ b/tests/qtest/machine-option-test.c
@@ -0,0 +1,714 @@
+/*
+ * Combined and historic -M / -machine option tests.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qobject/qdict.h"
+#include "qobject/qlist.h"
+#include "qobject/qstring.h"
+
+#include "machine-list-test.inc.h"
+
+static bool test_target_exists(const char *target_info);
+static bool spawn_args_targets_exist(const char *const *args);
+static bool cli_targets_exist(const char *cli);
+
+static bool qemu_binary_is_combined(void)
+{
+ const char *bin = qtest_qemu_binary(NULL);
+
+ return g_str_has_suffix(bin, "qemu-system") ||
+ g_str_has_suffix(bin, "qemu-system.exe");
+}
+
+static void spawn_qemu(gchar **out, gchar **err, int *code,
+ const char *const *argv_tail)
+{
+ g_autoptr(GPtrArray) argv = g_ptr_array_new();
+ g_autofree gchar *stdout_buf = NULL;
+ g_autofree gchar *stderr_buf = NULL;
+ gint status = 0;
+ GError *gerr = NULL;
+ const char *const *p;
+
+ g_ptr_array_add(argv, (gpointer)qtest_qemu_binary(NULL));
+ for (p = argv_tail; *p; p++) {
+ g_ptr_array_add(argv, (gpointer)*p);
+ }
+ g_ptr_array_add(argv, NULL);
+
+ g_assert(g_spawn_sync(NULL, (char **)argv->pdata, NULL,
+ G_SPAWN_DEFAULT, NULL, NULL,
+ &stdout_buf, &stderr_buf, &status, &gerr));
+ g_assert_no_error(gerr);
+#ifdef _WIN32
+ *code = status;
+#else
+ g_assert(WIFEXITED(status));
+ *code = WEXITSTATUS(status);
+#endif
+ if (out) {
+ *out = g_steal_pointer(&stdout_buf);
+ }
+ if (err) {
+ *err = g_steal_pointer(&stderr_buf);
+ }
+}
+
+static void assert_spawn(const char *target_info, const char *const *args,
+ int expect_code, const char *out_need,
+ const char *err_need)
+{
+ g_autofree gchar *out = NULL;
+ g_autofree gchar *err = NULL;
+ int code;
+
+ if (!test_target_exists(target_info) ||
+ (target_info && !spawn_args_targets_exist(args))) {
+ return;
+ }
+ spawn_qemu(&out, &err, &code, args);
+ g_assert_cmpint(code, ==, expect_code);
+ if (out_need) {
+ g_assert_nonnull(strstr(out ? out : "", out_need));
+ }
+ if (err_need) {
+ g_assert_nonnull(strstr(err ? err : "", err_need));
+ }
+}
+
+static void assert_spawn_not(const char *target_info, const char *const *args,
+ int expect_code, const char *out_need,
+ const char *out_forbid)
+{
+ g_autofree gchar *out = NULL;
+ g_autofree gchar *err = NULL;
+ int code;
+
+ if (!test_target_exists(target_info) ||
+ (target_info && !spawn_args_targets_exist(args))) {
+ return;
+ }
+ spawn_qemu(&out, &err, &code, args);
+ g_assert_cmpint(code, ==, expect_code);
+ g_assert_nonnull(strstr(out ? out : "", out_need));
+ g_assert_null(strstr(out ? out : "", out_forbid));
+}
+
+static char *qom_machine_type(QTestState *qts)
+{
+ QDict *resp;
+ char *type;
+
+ resp = qtest_qmp(qts,
+ "{'execute': 'qom-get', 'arguments':"
+ " {'path': '/machine', 'property': 'type'}}");
+ g_assert(qdict_haskey(resp, "return"));
+ type = g_strdup(qdict_get_str(resp, "return"));
+ qobject_unref(resp);
+ return type;
+}
+
+static char *query_target_arch(QTestState *qts)
+{
+ QDict *resp, *ret;
+ char *arch;
+
+ resp = qtest_qmp(qts, "{'execute': 'query-target'}");
+ g_assert(qdict_haskey(resp, "return"));
+ ret = qdict_get_qdict(resp, "return");
+ arch = g_strdup(qdict_get_str(ret, "arch"));
+ qobject_unref(resp);
+ return arch;
+}
+
+/* query-target "arch" is SysEmuTarget, not always TARGET_NAME. */
+static const char *query_arch_for_target(const char *target_info)
+{
+ static const struct {
+ const char *target_name;
+ const char *arch;
+ } map[] = {
+ { "armeb", "arm" },
+ { "microblazeel", "microblaze" },
+ { "mips64el", "mips64" },
+ { "mipsel", "mips" },
+ { "ppc64le", "ppc64" },
+ { "sh4eb", "sh4" },
+ { "xtensaeb", "xtensa" },
+ };
+ size_t i;
+
+ for (i = 0; i < G_N_ELEMENTS(map); i++) {
+ if (!strcmp(target_info, map[i].target_name)) {
+ return map[i].arch;
+ }
+ }
+ return target_info;
+}
+
+static const struct ShippedTarget *lookup_shipped_arch(const char *arch,
+ const char *endianness)
+{
+ size_t i;
+
+ for (i = 0; i < G_N_ELEMENTS(shipped_targets); i++) {
+ if (!strcmp(shipped_targets[i].arch, arch) &&
+ !strcmp(shipped_targets[i].endianness, endianness)) {
+ return &shipped_targets[i];
+ }
+ }
+ return NULL;
+}
+
+static const char *preferred_machine(const struct ShippedTarget *t)
+{
+ size_t i;
+
+ for (i = 0; i < t->n_machines; i++) {
+ if (!strcmp(t->machines[i], "virt")) {
+ return t->machines[i];
+ }
+ }
+ return t->n_machines ? t->machines[0] : NULL;
+}
+
+static bool help_section_header(const char *line, const char **name,
+ size_t *name_len)
+{
+ size_t n;
+ size_t i;
+
+ if (!line[0]) {
+ return false;
+ }
+ n = strlen(line);
+ if (line[n - 1] != ':') {
+ return false;
+ }
+ for (i = 0; i < n - 1; i++) {
+ char c = line[i];
+
+ if (!g_ascii_isalnum(c) && c != '_' && c != '-' && c != '.') {
+ return false;
+ }
+ }
+ *name = line;
+ *name_len = n - 1;
+ return true;
+}
+
+/* First-column machine names. Aliases are omitted.
+ * only_section NULL keeps every section (historic help).
+ */
+static QList *names_from_help(const char *text, const char *only_section)
+{
+ g_auto(GStrv) lines = g_strsplit(text ? text : "", "\n", 0);
+ g_autofree char *section = NULL;
+ QList *names = qlist_new();
+ int i;
+
+ for (i = 0; lines[i]; i++) {
+ const char *line = lines[i];
+ const char *header;
+ size_t header_len;
+ const char *sp;
+ g_autofree char *tok = NULL;
+
+ if (help_section_header(line, &header, &header_len)) {
+ g_free(section);
+ section = g_strndup(header, header_len);
+ continue;
+ }
+ if (only_section &&
+ (!section || strcmp(section, only_section))) {
+ continue;
+ }
+ if (!line[0] || g_str_has_prefix(line, "Supported machines")) {
+ continue;
+ }
+ if (strstr(line, "(alias of ")) {
+ continue;
+ }
+ sp = line;
+ while (*sp && !g_ascii_isspace(*sp)) {
+ sp++;
+ }
+ if (sp == line) {
+ continue;
+ }
+ tok = g_strndup(line, sp - line);
+ qlist_append_str(names, tok);
+ }
+ return names;
+}
+
+static QList *query_targets(QTestState *qts)
+{
+ QDict *resp;
+ QList *list;
+
+ resp = qtest_qmp(qts, "{'execute': 'query-targets'}");
+ g_assert(qdict_haskey(resp, "return"));
+ list = qdict_get_qlist(resp, "return");
+ qobject_ref(list);
+ qobject_unref(resp);
+ return list;
+}
+
+static void read_accels(void)
+{
+ QTestState *qts = qtest_init("-nodefaults -M none");
+
+ read_accel_flags(qts);
+ qtest_quit(qts);
+}
+
+static bool combined_has_target(const char *target_info)
+{
+ g_autofree char *opt = g_strdup_printf("%s:help", target_info);
+ const char *args[] = { "-M", opt, NULL };
+ g_autofree gchar *err = NULL;
+ int code = 1;
+
+ spawn_qemu(NULL, &err, &code, args);
+ return code == 0;
+}
+
+static bool test_target_exists(const char *target_info)
+{
+ static GHashTable *cache;
+ gpointer cached;
+ gboolean have;
+
+ if (!target_info) {
+ return true;
+ }
+ if (!strcmp(target_info, "none")) {
+ return true;
+ }
+ if (!qemu_binary_is_combined()) {
+ return strcmp(target_info, qtest_get_arch()) == 0;
+ }
+ if (!cache) {
+ cache = g_hash_table_new(g_str_hash, g_str_equal);
+ }
+ if (g_hash_table_lookup_extended(cache, target_info, NULL, &cached)) {
+ return GPOINTER_TO_INT(cached);
+ }
+ have = combined_has_target(target_info);
+ g_hash_table_insert(cache, (gpointer)target_info, GINT_TO_POINTER(have));
+ return have;
+}
+
+static bool machine_optarg_targets_exist(const char *optarg)
+{
+ const char *type = optarg;
+ const char *colon;
+ g_autofree char *prefix = NULL;
+
+ if (!optarg) {
+ return true;
+ }
+ if (g_str_has_prefix(type, "type=")) {
+ type += 5;
+ }
+ colon = strchr(type, ':');
+ if (!colon || colon == type) {
+ return true;
+ }
+ prefix = g_strndup(type, colon - type);
+ return test_target_exists(prefix);
+}
+
+static bool spawn_args_targets_exist(const char *const *args)
+{
+ const char *const *p;
+
+ for (p = args; *p; p++) {
+ if ((!strcmp(*p, "-M") || !strcmp(*p, "-machine")) && p[1]) {
+ if (!machine_optarg_targets_exist(p[1])) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool cli_targets_exist(const char *cli)
+{
+ g_auto(GStrv) tokens = g_strsplit(cli ? cli : "", " ", 0);
+ int i;
+
+ for (i = 0; tokens[i]; i++) {
+ if ((!strcmp(tokens[i], "-M") || !strcmp(tokens[i], "-machine")) &&
+ tokens[i + 1] && !machine_optarg_targets_exist(tokens[i + 1])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void assert_run(const char *target_info, const char *cli,
+ const char *type_need)
+{
+ QTestState *qts;
+ g_autofree char *got_arch = NULL;
+ g_autofree char *got_type = NULL;
+
+ if (!test_target_exists(target_info) || !cli_targets_exist(cli)) {
+ return;
+ }
+ qts = qtest_initf("-nodefaults %s", cli);
+ got_arch = query_target_arch(qts);
+ g_assert_cmpstr(got_arch, ==, query_arch_for_target(target_info));
+ if (type_need) {
+ got_type = qom_machine_type(qts);
+ g_assert_nonnull(strstr(got_type, type_need));
+ }
+ qtest_quit(qts);
+}
+
+static void test_combined_help(void)
+{
+ const char *help[] = { "-M", "help", NULL };
+ const char *qmark[] = { "-M", "?", NULL };
+ const char *aarch64_help[] = { "-M", "aarch64:help", NULL };
+ const char *aarch64_q[] = { "-M", "aarch64:?", NULL };
+ const char *riscv64_help[] = { "-M", "riscv64:help", NULL };
+ const char *none_help[] = { "-M", "none:help", NULL };
+
+ assert_spawn("none", help, 0, "none:\n", NULL);
+ assert_spawn("aarch64", help, 0, "aarch64:\n", NULL);
+ assert_spawn("none", qmark, 0, "none:\n", NULL);
+ assert_spawn("aarch64", aarch64_help, 0, "virt", NULL);
+ assert_spawn_not("aarch64", aarch64_help, 0, "virt", "q35");
+ assert_spawn_not("aarch64", aarch64_help, 0, "virt", "none:\n");
+ assert_spawn("aarch64", aarch64_q, 0, "virt", NULL);
+ assert_spawn("riscv64", riscv64_help, 0, "virt", NULL);
+ assert_spawn("none", none_help, 0, "none", NULL);
+ assert_spawn_not("none", none_help, 0, "empty machine", "aarch64:\n");
+}
+
+static void test_combined_props(void)
+{
+ const char *virt_help[] = { "-M", "aarch64:virt,help", NULL };
+ const char *def_help[] = { "-M", "aarch64:,help", NULL };
+ const char *bare_help[] = { "-M", "virt,help", NULL };
+ const char *none_help[] = { "-M", "none,help", NULL };
+
+ assert_spawn("aarch64", virt_help, 0, "gic-version", NULL);
+ assert_spawn("aarch64", def_help, 1, NULL,
+ "No machine specified, and there is no default");
+ assert_spawn(NULL, bare_help, 1, NULL, "needs an arch: prefix");
+ assert_spawn("none", none_help, 0, "none-machine", NULL);
+}
+
+static void test_combined_errors(void)
+{
+ const char *virt[] = { "-M", "virt", NULL };
+ const char *riscv64[] = { "-M", "riscv64", NULL };
+ const char *aarch64[] = { "-M", "aarch64", NULL };
+ const char *q35[] = { "-M", "aarch64:q35", NULL };
+ const char *sbsa[] = { "-M", "arm:sbsa-ref", NULL };
+ const char *nosuch_m[] = { "-M", "aarch64:no-such", NULL };
+ const char *nosuch_t[] = { "-M", "no-such:virt", NULL };
+ const char *upper[] = { "-M", "AARCH64:virt", NULL };
+ const char *none_virt[] = { "-M", "none:virt", NULL };
+ const char *lead[] = { "-M", ":virt", NULL };
+ const char *colon[] = { "-M", ":", NULL };
+ const char *extra[] = { "-M", "aarch64:virt:extra", NULL };
+
+ assert_spawn(NULL, virt, 1, NULL, "needs an arch: prefix");
+ assert_spawn(NULL, riscv64, 1, NULL, "needs an arch: prefix");
+ assert_spawn(NULL, aarch64, 1, NULL, "needs an arch: prefix");
+ assert_spawn("aarch64", q35, 1, NULL,
+ "unsupported machine type: \"aarch64:q35\"");
+ assert_spawn("arm", sbsa, 1, NULL,
+ "unsupported machine type: \"arm:sbsa-ref\"");
+ assert_spawn("aarch64", nosuch_m, 1, NULL,
+ "unsupported machine type: \"aarch64:no-such\"");
+ assert_spawn(NULL, nosuch_t, 1, NULL, "target 'no-such' is not available");
+ assert_spawn(NULL, upper, 1, NULL, "target 'AARCH64' is not available");
+ assert_spawn("none", none_virt, 1, NULL,
+ "machine type \"none:virt\" is not available for target none");
+ assert_spawn(NULL, lead, 1, NULL, "needs an arch: prefix");
+ assert_spawn(NULL, colon, 1, NULL, "needs an arch: prefix");
+ assert_spawn("aarch64", extra, 1, NULL,
+ "unsupported machine type: \"aarch64:virt:extra\"");
+}
+
+static void test_combined_last_help(void)
+{
+ const char *run_then_help[] = { "-M", "aarch64:virt", "-M", "help", NULL };
+
+ assert_spawn("aarch64", run_then_help, 0, "virt", NULL);
+ assert_spawn_not("aarch64", run_then_help, 0, "virt", "q35");
+}
+
+static void test_combined_run(void)
+{
+ const char *aarch64_def[] = { "-M", "aarch64:", NULL };
+ const char *riscv64_def[] = { "-M", "riscv64:", NULL };
+ const char *last_riscv_def[] = {
+ "-M", "aarch64:virt", "-M", "riscv64:", NULL
+ };
+
+ assert_run("aarch64", "-M aarch64:virt", "virt");
+ assert_run("riscv64", "-M riscv64:virt", "virt");
+ assert_run("aarch64", "-M type=aarch64:virt", "virt");
+ assert_run("aarch64", "-machine aarch64:virt", "virt");
+ assert_spawn("aarch64", aarch64_def, 1, NULL,
+ "No machine specified, and there is no default");
+ assert_spawn("riscv64", riscv64_def, 1, NULL,
+ "No machine specified, and there is no default");
+ assert_run("x86_64", "-M x86_64:q35", "q35");
+ assert_run("x86_64", "-M x86_64:", NULL);
+ assert_run("x86_64", "-M aarch64:virt -M x86_64:q35", "q35");
+ assert_run("i386", "-M i386:", NULL);
+ assert_run("none", "-M none:", "none");
+ assert_run("none", "", "none");
+ assert_run("none", "-M none", "none");
+ assert_run("none", "-M none:none", "none");
+ assert_run("aarch64", "-M aarch64:none", "none");
+ assert_run("aarch64", "-M aarch64:virt -M none", "none");
+ assert_run("riscv64", "-M aarch64:virt -M riscv64:virt", "virt");
+ assert_run("aarch64", "-M aarch64:virt -M virt", "virt");
+ assert_run("aarch64", "-M virt -M aarch64:virt", "virt");
+ assert_run("aarch64", "-M aarch64: -M virt", "virt");
+ assert_spawn("riscv64", last_riscv_def, 1, NULL,
+ "No machine specified, and there is no default");
+ assert_run("aarch64", "-M help -M aarch64:virt", "virt");
+}
+
+static void test_historic_help(void)
+{
+ const char *target_info = qtest_get_arch();
+ const struct ShippedTarget *t = lookup_shipped_target(target_info);
+ const char *help[] = { "-M", "help", NULL };
+ g_autofree gchar *out = NULL;
+ g_autofree gchar *err = NULL;
+ g_autoptr(QList) names = NULL;
+ int code;
+
+ spawn_qemu(&out, &err, &code, help);
+ g_assert_cmpint(code, ==, 0);
+ g_assert_nonnull(strstr(out ? out : "", "Supported machines are:"));
+ g_assert_null(strstr(out ? out : "", "none:\n"));
+ if (!t) {
+ return;
+ }
+ read_accels();
+ names = names_from_help(out, NULL);
+ assert_name_list(names, t->name, t->machines, t->n_machines);
+}
+
+static void test_historic_machine_help(void)
+{
+ const char *target_info = qtest_get_arch();
+ const struct ShippedTarget *t = lookup_shipped_target(target_info);
+ const char *machine;
+ g_autofree char *opt = NULL;
+ const char *args[] = { "-M", NULL, NULL };
+ size_t i;
+ bool have_virt = false;
+
+ if (!t) {
+ return;
+ }
+ machine = preferred_machine(t);
+ if (!machine) {
+ return;
+ }
+ opt = g_strdup_printf("%s,help", machine);
+ args[1] = opt;
+ assert_spawn(target_info, args, 0, machine, NULL);
+ for (i = 0; i < t->n_machines; i++) {
+ if (!strcmp(t->machines[i], "virt")) {
+ have_virt = true;
+ break;
+ }
+ }
+ if (have_virt &&
+ (!strcmp(target_info, "arm") || !strcmp(target_info, "aarch64"))) {
+ const char *virt_args[] = { "-M", "virt,help", NULL };
+
+ assert_spawn(target_info, virt_args, 0, "gic-version", NULL);
+ }
+}
+
+static void test_historic_run(void)
+{
+ const char *target_info = qtest_get_arch();
+ g_autofree char *match = g_strdup_printf("-M %s:none", target_info);
+ const char *mismatch[] = { "-M", "aarch64:virt", NULL };
+
+ assert_run(target_info, "-M none", "none");
+ assert_run(target_info, match, "none");
+ if (strcmp(target_info, "aarch64")) {
+ assert_spawn(target_info, mismatch, 1, NULL,
+ "is not available for target");
+ } else {
+ assert_run(target_info, "-M virt", "virt");
+ assert_run(target_info, "-M aarch64:virt", "virt");
+ }
+}
+
+static void test_combined_help_lists(void)
+{
+ const char *help[] = { "-M", "help", NULL };
+ g_autofree gchar *out = NULL;
+ g_autofree gchar *err = NULL;
+ g_autoptr(QList) targets = NULL;
+ const QListEntry *e;
+ QTestState *qts;
+ int code;
+
+ spawn_qemu(&out, &err, &code, help);
+ g_assert_cmpint(code, ==, 0);
+ qts = qtest_init("-nodefaults -M none");
+ read_accel_flags(qts);
+ targets = query_targets(qts);
+ qtest_quit(qts);
+ g_assert_cmpuint(qlist_size(targets), >, 0);
+ for (e = qlist_first(targets); e; e = qlist_next(e)) {
+ QDict *tgt = qobject_to(QDict, qlist_entry_obj(e));
+ const struct ShippedTarget *t;
+ g_autoptr(QList) names = NULL;
+
+ g_assert_nonnull(tgt);
+ if (!strcmp(qdict_get_str(tgt, "arch"), "none")) {
+ QList *qmp_names = qdict_get_qlist(tgt, "machines");
+ g_autoptr(QList) help_names = names_from_help(out, "none");
+ const QListEntry *ne;
+ bool saw_none = false;
+
+ g_assert_nonnull(strstr(out, "none:\n"));
+ g_assert_cmpuint(qlist_size(help_names), ==, qlist_size(qmp_names));
+ for (ne = qlist_first(qmp_names); ne; ne = qlist_next(ne)) {
+ const char *name = qstring_get_str(qobject_to(QString,
+ qlist_entry_obj(ne)));
+ const QListEntry *he;
+ bool found = false;
+
+ if (!strcmp(name, "none")) {
+ saw_none = true;
+ }
+ for (he = qlist_first(help_names); he; he = qlist_next(he)) {
+ const char *hn = qstring_get_str(
+ qobject_to(QString, qlist_entry_obj(he)));
+
+ if (!strcmp(name, hn)) {
+ found = true;
+ break;
+ }
+ }
+ g_assert_true(found);
+ }
+ g_assert_true(saw_none);
+ continue;
+ }
+ t = lookup_shipped_arch(qdict_get_str(tgt, "arch"),
+ qdict_get_str(tgt, "endianness"));
+ g_assert_nonnull(t);
+ names = names_from_help(out, t->name);
+ assert_name_list(names, t->name, t->machines, t->n_machines);
+ }
+}
+
+static char *write_machine_config(const char *type)
+{
+ g_autofree char *text = g_strdup_printf("[machine]\ntype = \"%s\"\n", type);
+ g_autofree char *path = NULL;
+ GError *err = NULL;
+ int fd;
+
+ fd = g_file_open_tmp("qemu-m-XXXXXX", &path, &err);
+ g_assert_no_error(err);
+ g_assert_cmpint(fd, >=, 0);
+ close(fd);
+ g_assert_true(g_file_set_contents(path, text, -1, &err));
+ g_assert_no_error(err);
+ return g_steal_pointer(&path);
+}
+
+static void test_combined_readconfig(void)
+{
+ g_autofree char *aarch64_cfg = write_machine_config("aarch64:virt");
+ g_autofree char *none_cfg = write_machine_config("none:");
+ g_autofree char *riscv_cfg = write_machine_config("riscv64:virt");
+ g_autofree char *from_cfg = NULL;
+ g_autofree char *then_none = NULL;
+ g_autofree char *cfg_none = NULL;
+ g_autofree char *then_riscv = NULL;
+
+ from_cfg = g_strdup_printf("-readconfig \"%s\"", aarch64_cfg);
+ assert_run("aarch64", from_cfg, "virt");
+ then_none = g_strdup_printf("-readconfig \"%s\" -M none", aarch64_cfg);
+ assert_run("aarch64", then_none, "none");
+ cfg_none = g_strdup_printf("-readconfig \"%s\"", none_cfg);
+ assert_run("none", cfg_none, "none");
+ then_riscv = g_strdup_printf("-M aarch64:virt -readconfig \"%s\"",
+ riscv_cfg);
+ assert_run("riscv64", then_riscv, "virt");
+
+ unlink(aarch64_cfg);
+ unlink(none_cfg);
+ unlink(riscv_cfg);
+}
+
+static void test_combined_run_listed(void)
+{
+ g_autoptr(QList) targets = NULL;
+ const QListEntry *e;
+ QTestState *qts;
+
+ qts = qtest_init("-nodefaults -M none");
+ targets = query_targets(qts);
+ qtest_quit(qts);
+ for (e = qlist_first(targets); e; e = qlist_next(e)) {
+ QDict *tgt = qobject_to(QDict, qlist_entry_obj(e));
+ const struct ShippedTarget *t;
+ const char *machine;
+ g_autofree char *cli = NULL;
+
+ g_assert_nonnull(tgt);
+ if (!strcmp(qdict_get_str(tgt, "arch"), "none")) {
+ assert_run("none", "-M none:none", "none");
+ continue;
+ }
+ t = lookup_shipped_arch(qdict_get_str(tgt, "arch"),
+ qdict_get_str(tgt, "endianness"));
+ g_assert_nonnull(t);
+ machine = preferred_machine(t);
+ g_assert_nonnull(machine);
+ cli = g_strdup_printf("-M %s:%s", t->name, machine);
+ assert_run(t->name, cli, machine);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ if (qemu_binary_is_combined()) {
+ g_test_add_func("/machine-option/help", test_combined_help);
+ g_test_add_func("/machine-option/help-lists", test_combined_help_lists);
+ g_test_add_func("/machine-option/props", test_combined_props);
+ g_test_add_func("/machine-option/errors", test_combined_errors);
+ g_test_add_func("/machine-option/last-help", test_combined_last_help);
+ g_test_add_func("/machine-option/run", test_combined_run);
+ g_test_add_func("/machine-option/readconfig", test_combined_readconfig);
+ g_test_add_func("/machine-option/run-listed", test_combined_run_listed);
+ } else {
+ qtest_add_func("machine-option/help", test_historic_help);
+ qtest_add_func("machine-option/machine-help", test_historic_machine_help);
+ qtest_add_func("machine-option/run", test_historic_run);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index aef99d2bf52..99b7b19283b 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -19,6 +19,11 @@ slow_qtests = {
'vmgenid-test': 610,
}
+qtests_single_binary = [
+ 'machine-option-test',
+ 'machine-list-combined-test',
+]
+
qtests_generic = [
'cdrom-test',
'device-introspect-test',
@@ -527,3 +532,36 @@ foreach dir : target_dirs
(slow_qtests.has_key(test) ? ['slow'] : []))
endforeach
endforeach
+
+if is_variable('qemu_system')
+ qtest_env_sb = environment()
+ qtest_env_sb.set('G_TEST_DBUS_DAEMON',
+ meson.project_source_root() / 'tests/dbus-daemon.sh')
+ qtest_env_sb.set('QTEST_QEMU_BINARY', './qemu-system')
+ qtest_env_sb.set('PYTHON', python.full_path())
+ combined_targets_text = []
+ foreach name : single_binary_targets
+ combined_targets_text += ' "@0@",'.format(name)
+ endforeach
+ combined_targets_conf = configuration_data()
+ combined_targets_conf.set('COMBINED_TARGETS', '\n'.join(combined_targets_text))
+ combined_targets_h = configure_file(
+ input: 'machine-list-combined-targets.h.in',
+ output: 'machine-list-combined-targets.h',
+ configuration: combined_targets_conf,
+ )
+ foreach test : qtests_single_binary
+ qtest_executables += {
+ test: executable(test, [test + '.c', combined_targets_h],
+ dependencies: [qemuutil, qos])
+ }
+ test('qtest-single-binary/' + test,
+ qtest_executables[test],
+ depends: [qemu_system, emulator_modules],
+ env: qtest_env_sb,
+ args: ['--tap', '-k'],
+ protocol: 'tap',
+ timeout: test == 'machine-option-test' ? 180 : 60,
+ suite: ['qtest', 'qtest-single-binary'])
+ endforeach
+endif
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 82+ messages in thread
* Re: [PATCH v4 07/55] tests/unit: add test-target-info
2026-09-26 7:00 ` [PATCH v4 07/55] tests/unit: add test-target-info Yonggang Luo
@ 2026-09-28 9:07 ` Markus Armbruster
[not found] ` <CAE2XoE9_R13NsUWu-s12QA9RBJykR87TEMh3VmndNEXQsCkNtg@mail.gmail.com>
0 siblings, 1 reply; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 9:07 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> Collect each target-info-def.c object in target_info_def_objects,
> keyed by target dir. Link every value so constructors fill the
> list. Assert target_info() is not NULL and target_info_list() has
> one entry per linked object.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Doesn't compile for me:
../tests/unit/meson.build:47:37: ERROR: Unknown method "values" in object <[DictHolder] holds [dict]: {'aarch64-linux-user': <ExtractedObjects 'qemu-aarch64-linux-user': [<File: target-info-def.c (not built)>]>, 'aarch64_be-linux-user': <ExtractedObjects 'qemu-aarch64_be-linux-user': [<File: target-info-def.c (not built)>]>, 'alpha-linux-user': <ExtractedObjects 'qemu-alpha-linux-user': [<File: target-info-def.c (not built)>]>, 'arm-linux-user': <ExtractedObjects 'qemu-arm-linux-user': [<File: target-info-def.c (not built)>]>, 'armeb-linux-user': <ExtractedObjects 'qemu-armeb-linux-user': [<File: target-info-def.c (not built)>]>, 'hexagon-linux-user': <ExtractedObjects 'qemu-hexagon-linux-user': [<File: target-info-def.c (not built)>]>, 'hppa-linux-user': <ExtractedObjects 'qemu-hppa-linux-user': [<File: target-info-def.c (not built)>]>, 'i386-linux-user': <ExtractedObjects 'qemu-i386-linux-user': [<File: target-info-def.c (not built)>]>, 'loongarch64-linux-user': <ExtractedObjects 'qemu-loongarch64-linux-user': [<File: target-info-def.c (not built)>]>, 'm68k-linux-user': <ExtractedObjects 'qemu-m68k-linux-user': [<File: target-info-def.c (not built)>]>, 'microblaze-linux-user': <ExtractedObjects 'qemu-microblaze-linux-user': [<File: target-info-def.c (not built)>]>, 'microblazeel-linux-user': <ExtractedObjects 'qemu-microblazeel-linux-user': [<File: target-info-def.c (not built)>]>, 'mips-linux-user': <ExtractedObjects 'qemu-mips-linux-user': [<File: target-info-def.c (not built)>]>, 'mips64-linux-user': <ExtractedObjects 'qemu-mips64-linux-user': [<File: target-info-def.c (not built)>]>, 'mips64el-linux-user': <ExtractedObjects 'qemu-mips64el-linux-user': [<File: target-info-def.c (not built)>]>, 'mipsel-linux-user': <ExtractedObjects 'qemu-mipsel-linux-user': [<File: target-info-def.c (not built)>]>, 'mipsn32-linux-user': <ExtractedObjects 'qemu-mipsn32-linux-user': [<File: target-info-def.c (not built)>]>, 'mipsn32el-linux-user': <ExtractedObjects 'qemu-mipsn32el-linux-user': [<File: target-info-def.c (not built)>]>, 'or1k-linux-user': <ExtractedObjects 'qemu-or1k-linux-user': [<File: target-info-def.c (not built)>]>, 'ppc-linux-user': <ExtractedObjects 'qemu-ppc-linux-user': [<File: target-info-def.c (not built)>]>, 'ppc64-linux-user': <ExtractedObjects 'qemu-ppc64-linux-user': [<File: target-info-def.c (not built)>]>, 'ppc64le-linux-user': <ExtractedObjects 'qemu-ppc64le-linux-user': [<File: target-info-def.c (not built)>]>, 'riscv32-linux-user': <ExtractedObjects 'qemu-riscv32-linux-user': [<File: target-info-def.c (not built)>]>, 'riscv64-linux-user': <ExtractedObjects 'qemu-riscv64-linux-user': [<File: target-info-def.c (not built)>]>, 's390x-linux-user': <ExtractedObjects 'qemu-s390x-linux-user': [<File: target-info-def.c (not built)>]>, 'sh4-linux-user': <ExtractedObjects 'qemu-sh4-linux-user': [<File: target-info-def.c (not built)>]>, 'sh4eb-linux-user': <ExtractedObjects 'qemu-sh4eb-linux-user': [<File: target-info-def.c (not built)>]>, 'sparc-linux-user': <ExtractedObjects 'qemu-sparc-linux-user': [<File: target-info-def.c (not built)>]>, 'sparc32plus-linux-user': <ExtractedObjects 'qemu-sparc32plus-linux-user': [<File: target-info-def.c (not built)>]>, 'sparc64-linux-user': <ExtractedObjects 'qemu-sparc64-linux-user': [<File: target-info-def.c (not built)>]>, 'x86_64-linux-user': <ExtractedObjects 'qemu-x86_64-linux-user': [<File: target-info-def.c (not built)>]>, 'xtensa-linux-user': <ExtractedObjects 'qemu-xtensa-linux-user': [<File: target-info-def.c (not built)>]>, 'xtensaeb-linux-user': <ExtractedObjects 'qemu-xtensaeb-linux-user': [<File: target-info-def.c (not built)>]>, 'aarch64-softmmu': <ExtractedObjects 'qemu-aarch64-softmmu': [<File: target-info-def.c (not built)>]>, 'alpha-softmmu': <ExtractedObjects 'qemu-alpha-softmmu': [<File: target-info-def.c (not built)>]>, 'arm-softmmu': <ExtractedObjects 'qemu-arm-softmmu': [<File: target-info-def.c (not built)>]>, 'avr-softmmu': <ExtractedObjects 'qemu-avr-softmmu': [<File: target-info-def.c (not built)>]>, 'hexagon-softmmu': <ExtractedObjects 'qemu-hexagon-softmmu': [<File: target-info-def.c (not built)>]>, 'hppa-softmmu': <ExtractedObjects 'qemu-hppa-softmmu': [<File: target-info-def.c (not built)>]>, 'i386-softmmu': <ExtractedObjects 'qemu-i386-softmmu': [<File: target-info-def.c (not built)>]>, 'loongarch64-softmmu': <ExtractedObjects 'qemu-loongarch64-softmmu': [<File: target-info-def.c (not built)>]>, 'm68k-softmmu': <ExtractedObjects 'qemu-m68k-softmmu': [<File: target-info-def.c (not built)>]>, 'microblaze-softmmu': <ExtractedObjects 'qemu-microblaze-softmmu': [<File: target-info-def.c (not built)>]>, 'mips-softmmu': <ExtractedObjects 'qemu-mips-softmmu': [<File: target-info-def.c (not built)>]>, 'mips64-softmmu': <ExtractedObjects 'qemu-mips64-softmmu': [<File: target-info-def.c (not built)>]>, 'mips64el-softmmu': <ExtractedObjects 'qemu-mips64el-softmmu': [<File: target-info-def.c (not built)>]>, 'mipsel-softmmu': <ExtractedObjects 'qemu-mipsel-softmmu': [<File: target-info-def.c (not built)>]>, 'or1k-softmmu': <ExtractedObjects 'qemu-or1k-softmmu': [<File: target-info-def.c (not built)>]>, 'ppc-softmmu': <ExtractedObjects 'qemu-ppc-softmmu': [<File: target-info-def.c (not built)>]>, 'ppc64-softmmu': <ExtractedObjects 'qemu-ppc64-softmmu': [<File: target-info-def.c (not built)>]>, 'riscv32-softmmu': <ExtractedObjects 'qemu-riscv32-softmmu': [<File: target-info-def.c (not built)>]>, 'riscv64-softmmu': <ExtractedObjects 'qemu-riscv64-softmmu': [<File: target-info-def.c (not built)>]>, 'rx-softmmu': <ExtractedObjects 'qemu-rx-softmmu': [<File: target-info-def.c (not built)>]>, 's390x-softmmu': <ExtractedObjects 'qemu-s390x-softmmu': [<File: target-info-def.c (not built)>]>, 'sh4-softmmu': <ExtractedObjects 'qemu-sh4-softmmu': [<File: target-info-def.c (not built)>]>, 'sh4eb-softmmu': <ExtractedObjects 'qemu-sh4eb-softmmu': [<File: target-info-def.c (not built)>]>, 'sparc-softmmu': <ExtractedObjects 'qemu-sparc-softmmu': [<File: target-info-def.c (not built)>]>, 'sparc64-softmmu': <ExtractedObjects 'qemu-sparc64-softmmu': [<File: target-info-def.c (not built)>]>, 'tricore-softmmu': <ExtractedObjects 'qemu-tricore-softmmu': [<File: target-info-def.c (not built)>]>, 'x86_64-softmmu': <ExtractedObjects 'qemu-x86_64-softmmu': [<File: target-info-def.c (not built)>]>, 'xtensa-softmmu': <ExtractedObjects 'qemu-xtensa-softmmu': [<File: target-info-def.c (not built)>]>, 'xtensaeb-softmmu': <ExtractedObjects 'qemu-xtensaeb-softmmu': [<File: target-info-def.c (not built)>]>}> of type DictHolder.
I have meson 1.8.5.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 07/55] tests/unit: add test-target-info
[not found] ` <CAE2XoE9_R13NsUWu-s12QA9RBJykR87TEMh3VmndNEXQsCkNtg@mail.gmail.com>
@ 2026-09-28 9:43 ` Daniel P. Berrangé
2026-09-28 9:48 ` Markus Armbruster
1 sibling, 0 replies; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 9:43 UTC (permalink / raw)
To: Yonggang Luo
Cc: Markus Armbruster, qemu-devel, Richard Henderson,
Philippe Mathieu-Daudé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 05:21:06PM +0800, Yonggang Luo wrote:
> On Mon, Sep 28, 2026 at 5:07 PM Markus Armbruster <armbru@redhat.com> wrote:
> >
> > Yonggang Luo <luoyonggang@gmail.com> writes:
> >
> > > Collect each target-info-def.c object in target_info_def_objects,
> > > keyed by target dir. Link every value so constructors fill the
> > > list. Assert target_info() is not NULL and target_info_list() has
> > > one entry per linked object.
> > >
> > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >
> > Doesn't compile for me:
snip
> >
> > I have meson 1.8.5.
> >
>
> Hi, It's because I use a feature from meson 1.10.0, you can install meson
> 1.12.0 for it. and the remote branch I also fixed for KVM and got gitlab
> running. but for this series you need to install meson 1.12.x
There needs to be a patch in this series that bumps the required
meson version then.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 07/55] tests/unit: add test-target-info
[not found] ` <CAE2XoE9_R13NsUWu-s12QA9RBJykR87TEMh3VmndNEXQsCkNtg@mail.gmail.com>
2026-09-28 9:43 ` Daniel P. Berrangé
@ 2026-09-28 9:48 ` Markus Armbruster
1 sibling, 0 replies; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 9:48 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> On Mon, Sep 28, 2026 at 5:07 PM Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > Collect each target-info-def.c object in target_info_def_objects,
>> > keyed by target dir. Link every value so constructors fill the
>> > list. Assert target_info() is not NULL and target_info_list() has
>> > one entry per linked object.
>> >
>> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>
>> Doesn't compile for me:
[...]
>> I have meson 1.8.5.
>>
>
> Hi, It's because I use a feature from meson 1.10.0, you can install meson
> 1.12.0 for it. and the remote branch I also fixed for KVM and got gitlab
> running. but for this series you need to install meson 1.12.x
Your series cannot be merged as is. You have to make it work with the
minimum required version (1.6.0 as far as I can tell), or get that
version increased sufficiently.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 15/55] target/arm: allow -cpu host with Nitro
2026-09-26 7:00 ` [PATCH v4 15/55] target/arm: allow -cpu host with Nitro Yonggang Luo
@ 2026-09-28 10:06 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 82+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-28 10:06 UTC (permalink / raw)
To: Yonggang Luo, qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Edgar E. Iglesias,
Pierrick Bouvier, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
Alistair Francis, Peter Maydell, Marc-André Lureau, qemu-arm,
kvm
On 26/9/26 09:00, Yonggang Luo wrote:
> Register the AArch64 host CPU when CONFIG_NITRO is set, matching
> the existing initfn early-return for nitro_enabled().
>
> - Add CONFIG_NITRO to the aarch64_cpus host type guard
> - Treat nitro_enabled() like the other accels in realize
> - Mention Nitro in the host-CPU realize error
> - Set host_cpu_probe_failed instead of asserting when only Nitro
> is compiled in and it is not selected
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
> target/arm/cpu.c | 5 +++--
> target/arm/cpu64.c | 5 +++--
> 2 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 090470da40a..c138c4c0587 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1835,8 +1835,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
> * this is the first point where we can report it.
> */
> if (cpu->host_cpu_probe_failed) {
> - if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled()) {
> - error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF or WHPX");
> + if (!kvm_enabled() && !hvf_enabled() && !whpx_enabled() &&
> + !nitro_enabled()) {
> + error_setg(errp, "The 'host' CPU type can only be used with KVM, HVF, WHPX or Nitro");
if (!hwaccel_enabled()) { "'host' CPU type can only be used with
hardware accelerator" } ?
> } else {
> error_setg(errp, "Failed to retrieve host CPU features");
> }
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-26 7:00 ` [PATCH v4 46/55] qapi: add query-targets Yonggang Luo
@ 2026-09-28 10:13 ` Daniel P. Berrangé
2026-09-28 10:39 ` Philippe Mathieu-Daudé
` (2 more replies)
0 siblings, 3 replies; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 10:13 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm
On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> query-targets lists each linked target, including none, with its
> arch, endianness, and the machines that target accepts.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> 2 files changed, 65 insertions(+)
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 6aaa2af709a..d8cdea6203e 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -307,6 +307,41 @@
> ##
> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>
> +##
> +# @TargetMachines:
> +#
> +# One registered system target and the machines that can run on it.
> +#
> +# @arch: the target architecture
> +#
> +# @endianness: the target endianness
> +#
> +# @machines: machine type names, not aliases
> +#
> +# Since: 11.2
> +##
> +{ 'struct': 'TargetMachines',
> + 'data': { 'arch': 'SysEmuTarget',
> + 'endianness': 'EndianMode',
> + 'machines': ['str'] } }
We already have 'QemuTargetInfo' struct which is used
with 'query-target', that should also be used with the
new 'query-targets' command.
We need to add the 'endianness' field to QemuTargetInfo.
I don't think that we need to report machines though.
We already have 'query-machines' which gives much broader
information on the machines. "MachineInfo" needs to
gain
"targets": ["SysEmuTarget"]
to list which target(s) a machine can be used with.
> +
> +##
> +# @query-targets:
> +#
> +# Return each target linked into this QEMU binary and the machines
> +# whose availability check accepts that target.
> +#
> +# Since: 11.2
> +#
> +# .. qmp-example::
> +#
> +# -> { "execute": "query-targets" }
> +# <- { "return": [ { "arch": "aarch64", "endianness": "little",
> +# "machines": [ "virt" ] } ] }
> +##
> +{ 'command': 'query-targets',
> + 'returns': ['TargetMachines'] }
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 10:13 ` Daniel P. Berrangé
@ 2026-09-28 10:39 ` Philippe Mathieu-Daudé
[not found] ` <CAE2XoE9qsZZ+AnfGQ797SQj5yXP8SDOZyxYoKP=oh57UPFqq0Q@mail.gmail.com>
[not found] ` <CAE2XoE8Fp8w4m0WBjEXF3LceFXUqKDcXhdSmhCThgkAM3wRVaQ@mail.gmail.com>
2026-09-28 12:03 ` Markus Armbruster
2026-09-28 14:24 ` Yonggang Luo
2 siblings, 2 replies; 82+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-28 10:39 UTC (permalink / raw)
To: Daniel P. Berrangé, Yonggang Luo
Cc: qemu-devel, Richard Henderson, Edgar E. Iglesias,
Pierrick Bouvier, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
Alistair Francis, Peter Maydell, Marc-André Lureau, qemu-arm,
kvm, Thomas Huth
On 28/9/26 12:13, Daniel P. Berrangé wrote:
> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
>> query-targets lists each linked target, including none, with its
>> arch, endianness, and the machines that target accepts.
>>
>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>> ---
>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
>> 2 files changed, 65 insertions(+)
>
>
>> diff --git a/qapi/machine.json b/qapi/machine.json
>> index 6aaa2af709a..d8cdea6203e 100644
>> --- a/qapi/machine.json
>> +++ b/qapi/machine.json
>> @@ -307,6 +307,41 @@
>> ##
>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>>
>> +##
>> +# @TargetMachines:
>> +#
>> +# One registered system target and the machines that can run on it.
>> +#
>> +# @arch: the target architecture
>> +#
>> +# @endianness: the target endianness
>> +#
>> +# @machines: machine type names, not aliases
>> +#
>> +# Since: 11.2
>> +##
>> +{ 'struct': 'TargetMachines',
>> + 'data': { 'arch': 'SysEmuTarget',
>> + 'endianness': 'EndianMode',
>> + 'machines': ['str'] } }
>
> We already have 'QemuTargetInfo' struct which is used
> with 'query-target', that should also be used with the
> new 'query-targets' command.
>
> We need to add the 'endianness' field to QemuTargetInfo.
Why do we want to expose endianness, and what endianness to
expose? Endianness is a runtime bit state of CPUs. Sometime
this bit is hardwired but that is an implementation detail.
See commit 0e2c5647d92 and surrounding for MicroBlaze for
example.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h
2026-09-26 7:00 ` [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h Yonggang Luo
@ 2026-09-28 10:40 ` Markus Armbruster
0 siblings, 0 replies; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 10:40 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> memset, ld_i128, and st_i128 are declared in ldst_common.h, and
> ldst_common.c.inc emits their helper info. Atomic helpers move to
> atomic_common.h, with info records emitted from atomic_common.c.inc.
> tcg-runtime.h keeps the integer helpers implemented in tcg-runtime.c.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Another compilation failure:
cc -m64 -o tests/unit/test-tcg-call-tl libevent-loop-base.a.p/event-loop-base.c.o libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o libqom.a.p/qom_compat-properties.c.o libqom.a.p/target-info.c.o libqom.a.p/target-kconfig.c.o libsystem.a.p/accel_tcg_tcg-runtime.c.o libsystem.a.p/tcg_optimize.c.o libsystem.a.p/tcg_region.c.o libsystem.a.p/tcg_tcg.c.o libsystem.a.p/tcg_tcg-common.c.o libsystem.a.p/tcg_tcg-op.c.o libsystem.a.p/tcg_tcg-op-vec.c.o libsystem.a.p/tcg_perf.c.o tests/unit/test-tcg-call-tl.p/test-tcg-call-tl.c.o tests/unit/test-tcg-call-tl.p/test-tcg-call-tl-stubs.c.o tests/unit/test-tcg-call-tl.p/.._.._page-vary-common.c.o -Wl,--as-needed -Wl,--no-undefined -pie -fstack-protector-strong -Wl,-z,relro -Wl,-z,now -Wl,--start-group libqemuutil.a subprojects/libvhost-user/libvhost-user-glib.a subprojects/libvhost-user/libvhost-user.a -lnuma /usr/lib64/liburing.so /usr/lib64/libgio-2.0.so /usr/lib64/libgobject-2.0.so /usr/lib64/libglib-2.0.so /usr/lib64/libgmodule-2.0.so -pthread /usr/lib64/libgnutls.so -lm /usr/lib64/libpixman-1.so /usr/lib64/libepoxy.so -Wl,--end-group
/usr/bin/ld: libsystem.a.p/tcg_perf.c.o: in function `perf_report_code':
/work/armbru/qemu/bld/../tcg/perf.c:328:(.text+0x5e9): undefined reference to `debuginfo_lock'
/usr/bin/ld: /work/armbru/qemu/bld/../tcg/perf.c:341:(.text+0x66f): undefined reference to `debuginfo_query'
/usr/bin/ld: /work/armbru/qemu/bld/../tcg/perf.c:361:(.text+0xa91): undefined reference to `debuginfo_unlock'
collect2: error: ld returned 1 exit status
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
[not found] ` <CAE2XoE9qsZZ+AnfGQ797SQj5yXP8SDOZyxYoKP=oh57UPFqq0Q@mail.gmail.com>
@ 2026-09-28 10:57 ` Daniel P. Berrangé
2026-09-28 11:29 ` Philippe Mathieu-Daudé
2026-09-28 11:34 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 10:57 UTC (permalink / raw)
To: Yonggang Luo
Cc: Philippe Mathieu-Daudé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On Mon, Sep 28, 2026 at 06:51:41PM +0800, Yonggang Luo wrote:
> On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> philmd@oss.qualcomm.com> wrote:
> >
> > On 28/9/26 12:13, Daniel P. Berrangé wrote:
> > > On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> > >> query-targets lists each linked target, including none, with its
> > >> arch, endianness, and the machines that target accepts.
> > >>
> > >> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > >> ---
> > >> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> > >> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> > >> 2 files changed, 65 insertions(+)
> > >
> > >
> > >> diff --git a/qapi/machine.json b/qapi/machine.json
> > >> index 6aaa2af709a..d8cdea6203e 100644
> > >> --- a/qapi/machine.json
> > >> +++ b/qapi/machine.json
> > >> @@ -307,6 +307,41 @@
> > >> ##
> > >> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> > >>
> > >> +##
> > >> +# @TargetMachines:
> > >> +#
> > >> +# One registered system target and the machines that can run on it.
> > >> +#
> > >> +# @arch: the target architecture
> > >> +#
> > >> +# @endianness: the target endianness
> > >> +#
> > >> +# @machines: machine type names, not aliases
> > >> +#
> > >> +# Since: 11.2
> > >> +##
> > >> +{ 'struct': 'TargetMachines',
> > >> + 'data': { 'arch': 'SysEmuTarget',
> > >> + 'endianness': 'EndianMode',
> > >> + 'machines': ['str'] } }
> > >
> > > We already have 'QemuTargetInfo' struct which is used
> > > with 'query-target', that should also be used with the
> > > new 'query-targets' command.
> > >
> > > We need to add the 'endianness' field to QemuTargetInfo.
> >
> > Why do we want to expose endianness, and what endianness to
> > expose? Endianness is a runtime bit state of CPUs. Sometime
> > this bit is hardwired but that is an implementation detail.
>
> For some targets it's, but for some targets it's not. for example
>
> mips-softmmu.mak
> mipsel-softmmu.mak
> mips64el-softmmu.mak
> mips64-softmmu.mak
>
>
> mips64el-softmmu.mak
> mips64-softmmu.mak
> only differ the endianless
"EndianMode" is a tri-state including 'unspecified' as a value,
so we can cope with both scenarios - the targets where endianness
is runtime switchable in the CPU can use 'unspecified' as the
EndianMode. That behaviour should be documented in the QAPI
docs for QemuTargetInfo
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 10:57 ` Daniel P. Berrangé
@ 2026-09-28 11:29 ` Philippe Mathieu-Daudé
2026-09-28 11:36 ` Daniel P. Berrangé
0 siblings, 1 reply; 82+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-28 11:29 UTC (permalink / raw)
To: Daniel P. Berrangé, Yonggang Luo
Cc: qemu-devel, Richard Henderson, Edgar E. Iglesias,
Pierrick Bouvier, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
Alistair Francis, Peter Maydell, Marc-André Lureau, qemu-arm,
kvm, Thomas Huth
On 28/9/26 12:57, Daniel P. Berrangé wrote:
> On Mon, Sep 28, 2026 at 06:51:41PM +0800, Yonggang Luo wrote:
>> On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
>> philmd@oss.qualcomm.com> wrote:
>>>
>>> On 28/9/26 12:13, Daniel P. Berrangé wrote:
>>>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
>>>>> query-targets lists each linked target, including none, with its
>>>>> arch, endianness, and the machines that target accepts.
>>>>>
>>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>>>> ---
>>>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
>>>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
>>>>> 2 files changed, 65 insertions(+)
>>>>
>>>>
>>>>> diff --git a/qapi/machine.json b/qapi/machine.json
>>>>> index 6aaa2af709a..d8cdea6203e 100644
>>>>> --- a/qapi/machine.json
>>>>> +++ b/qapi/machine.json
>>>>> @@ -307,6 +307,41 @@
>>>>> ##
>>>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>>>>>
>>>>> +##
>>>>> +# @TargetMachines:
>>>>> +#
>>>>> +# One registered system target and the machines that can run on it.
>>>>> +#
>>>>> +# @arch: the target architecture
>>>>> +#
>>>>> +# @endianness: the target endianness
>>>>> +#
>>>>> +# @machines: machine type names, not aliases
>>>>> +#
>>>>> +# Since: 11.2
>>>>> +##
>>>>> +{ 'struct': 'TargetMachines',
>>>>> + 'data': { 'arch': 'SysEmuTarget',
>>>>> + 'endianness': 'EndianMode',
>>>>> + 'machines': ['str'] } }
>>>>
>>>> We already have 'QemuTargetInfo' struct which is used
>>>> with 'query-target', that should also be used with the
>>>> new 'query-targets' command.
>>>>
>>>> We need to add the 'endianness' field to QemuTargetInfo.
>>>
>>> Why do we want to expose endianness, and what endianness to
>>> expose? Endianness is a runtime bit state of CPUs. Sometime
>>> this bit is hardwired but that is an implementation detail.
>>
>> For some targets it's, but for some targets it's not. for example
>>
>> mips-softmmu.mak
>> mipsel-softmmu.mak
>> mips64el-softmmu.mak
>> mips64-softmmu.mak
>>
>>
>> mips64el-softmmu.mak
>> mips64-softmmu.mak
>> only differ the endianless
>
> "EndianMode" is a tri-state including 'unspecified' as a value,
> so we can cope with both scenarios - the targets where endianness
> is runtime switchable in the CPU can use 'unspecified' as the
> EndianMode. That behaviour should be documented in the QAPI
> docs for QemuTargetInfo
OK but still I don't understand the usefulness of exposing that
at the machine level, since this is a CPU property.
Machine != QEMU binary.
Are you trying to expose binary properties to management layer?
Can you explain the use case?
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
[not found] ` <CAE2XoE9qsZZ+AnfGQ797SQj5yXP8SDOZyxYoKP=oh57UPFqq0Q@mail.gmail.com>
2026-09-28 10:57 ` Daniel P. Berrangé
@ 2026-09-28 11:34 ` Philippe Mathieu-Daudé
2026-09-28 18:50 ` Yonggang Luo
1 sibling, 1 reply; 82+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-28 11:34 UTC (permalink / raw)
To: luoyonggang
Cc: Daniel P. Berrangé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On 28/9/26 12:51, Yonggang Luo wrote:
> On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> philmd@oss.qualcomm.com> wrote:
>>
>> On 28/9/26 12:13, Daniel P. Berrangé wrote:
>>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
>>>> query-targets lists each linked target, including none, with its
>>>> arch, endianness, and the machines that target accepts.
>>>>
>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>>> ---
>>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
>>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
>>>> 2 files changed, 65 insertions(+)
>>>
>>>
>>>> diff --git a/qapi/machine.json b/qapi/machine.json
>>>> index 6aaa2af709a..d8cdea6203e 100644
>>>> --- a/qapi/machine.json
>>>> +++ b/qapi/machine.json
>>>> @@ -307,6 +307,41 @@
>>>> ##
>>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>>>>
>>>> +##
>>>> +# @TargetMachines:
>>>> +#
>>>> +# One registered system target and the machines that can run on it.
>>>> +#
>>>> +# @arch: the target architecture
>>>> +#
>>>> +# @endianness: the target endianness
>>>> +#
>>>> +# @machines: machine type names, not aliases
>>>> +#
>>>> +# Since: 11.2
>>>> +##
>>>> +{ 'struct': 'TargetMachines',
>>>> + 'data': { 'arch': 'SysEmuTarget',
>>>> + 'endianness': 'EndianMode',
>>>> + 'machines': ['str'] } }
>>>
>>> We already have 'QemuTargetInfo' struct which is used
>>> with 'query-target', that should also be used with the
>>> new 'query-targets' command.
>>>
>>> We need to add the 'endianness' field to QemuTargetInfo.
>>
>> Why do we want to expose endianness, and what endianness to
>> expose? Endianness is a runtime bit state of CPUs. Sometime
>> this bit is hardwired but that is an implementation detail.
>
> For some targets it's, but for some targets it's not. for example
>
> mips-softmmu.mak
> mipsel-softmmu.mak
> mips64el-softmmu.mak
> mips64-softmmu.mak
>
>
> mips64el-softmmu.mak
> mips64-softmmu.mak
> only differ the endianless
If you look at git / mailing list history you'll see I spent more
than a year unifying QEMU endianness. It was too much work for a
single person so we decided to reduce the scope to ARM + MicroBlaze
for single binary and we got MicroBlaze unified. We don't want
an endianness-specific single binary. I'm not sure what you are
trying to build, you didn't clearly explained what is your goal here.
You can find series unifying endianness for MIPS, not merged because
more things need to be addressed and not the priority.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 11:29 ` Philippe Mathieu-Daudé
@ 2026-09-28 11:36 ` Daniel P. Berrangé
0 siblings, 0 replies; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 11:36 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Yonggang Luo, qemu-devel, Richard Henderson, Edgar E. Iglesias,
Pierrick Bouvier, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
Alistair Francis, Peter Maydell, Marc-André Lureau, qemu-arm,
kvm, Thomas Huth
On Mon, Sep 28, 2026 at 01:29:26PM +0200, Philippe Mathieu-Daudé wrote:
> On 28/9/26 12:57, Daniel P. Berrangé wrote:
> > On Mon, Sep 28, 2026 at 06:51:41PM +0800, Yonggang Luo wrote:
> > > On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> > > philmd@oss.qualcomm.com> wrote:
> > > >
> > > > On 28/9/26 12:13, Daniel P. Berrangé wrote:
> > > > > On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> > > > > > query-targets lists each linked target, including none, with its
> > > > > > arch, endianness, and the machines that target accepts.
> > > > > >
> > > > > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > > > > > ---
> > > > > > hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> > > > > > qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> > > > > > 2 files changed, 65 insertions(+)
> > > > >
> > > > >
> > > > > > diff --git a/qapi/machine.json b/qapi/machine.json
> > > > > > index 6aaa2af709a..d8cdea6203e 100644
> > > > > > --- a/qapi/machine.json
> > > > > > +++ b/qapi/machine.json
> > > > > > @@ -307,6 +307,41 @@
> > > > > > ##
> > > > > > { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> > > > > >
> > > > > > +##
> > > > > > +# @TargetMachines:
> > > > > > +#
> > > > > > +# One registered system target and the machines that can run on it.
> > > > > > +#
> > > > > > +# @arch: the target architecture
> > > > > > +#
> > > > > > +# @endianness: the target endianness
> > > > > > +#
> > > > > > +# @machines: machine type names, not aliases
> > > > > > +#
> > > > > > +# Since: 11.2
> > > > > > +##
> > > > > > +{ 'struct': 'TargetMachines',
> > > > > > + 'data': { 'arch': 'SysEmuTarget',
> > > > > > + 'endianness': 'EndianMode',
> > > > > > + 'machines': ['str'] } }
> > > > >
> > > > > We already have 'QemuTargetInfo' struct which is used
> > > > > with 'query-target', that should also be used with the
> > > > > new 'query-targets' command.
> > > > >
> > > > > We need to add the 'endianness' field to QemuTargetInfo.
> > > >
> > > > Why do we want to expose endianness, and what endianness to
> > > > expose? Endianness is a runtime bit state of CPUs. Sometime
> > > > this bit is hardwired but that is an implementation detail.
> > >
> > > For some targets it's, but for some targets it's not. for example
> > >
> > > mips-softmmu.mak
> > > mipsel-softmmu.mak
> > > mips64el-softmmu.mak
> > > mips64-softmmu.mak
> > >
> > >
> > > mips64el-softmmu.mak
> > > mips64-softmmu.mak
> > > only differ the endianless
> >
> > "EndianMode" is a tri-state including 'unspecified' as a value,
> > so we can cope with both scenarios - the targets where endianness
> > is runtime switchable in the CPU can use 'unspecified' as the
> > EndianMode. That behaviour should be documented in the QAPI
> > docs for QemuTargetInfo
>
> OK but still I don't understand the usefulness of exposing that
> at the machine level, since this is a CPU property.
True, and exposing this does not look like a pre-requisite for
having a single binary. It will be better if we can focus on
just what is neccessary to get the basics working initially.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 40/55] meson: link shared objects into qemu-system
2026-09-26 7:00 ` [PATCH v4 40/55] meson: link shared objects into qemu-system Yonggang Luo
@ 2026-09-28 11:41 ` Markus Armbruster
2026-09-28 11:47 ` Daniel P. Berrangé
0 siblings, 1 reply; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 11:41 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> Extract common_ss, system_ss, and family-common objects into one
> qemu-system binary. Only arm, aarch64, microblaze-softmmu are
> listed; a new target must have arch_srcs equal to target_info_def
> only (target-info-def.c). Config headers stay in arch_genh.
>
> - Union non-TARGET_* keys with y taking precedence
> - Reject leftover arch_srcs on participating targets
> - Reject TARGET_* conditions on common_ss and system_ss
> - Link SDL, install the binary, and apply Darwin entitlements
>
> Adding a target that still has per-target sources fails meson, for
> example:
>
> combined qemu-system leftover for :
> expected:
> target-info-def.c
> arch_srcs:
> target/microblaze/mmu.c
> target/microblaze/machine.c
> target-info-def.c
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Watch query-target lie:
$ qemu-system -S -nodefaults -display none -qmp stdio
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 11}, "package": "v11.1.0-1902-g88f617913a"}, "capabilities": ["oob"]}}
qemu-system: warning: nic xlnx.xps-ethernetlite.0 has no peer
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{'execute': 'query-target'}
--> {"return": {"arch": "aarch64"}}
Perhaps you can fix this by reordering patches. If you can't,
deficiencies like this one need a prominent mention in the commit
message.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 40/55] meson: link shared objects into qemu-system
2026-09-28 11:41 ` Markus Armbruster
@ 2026-09-28 11:47 ` Daniel P. Berrangé
2026-09-28 12:23 ` Markus Armbruster
0 siblings, 1 reply; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 11:47 UTC (permalink / raw)
To: Markus Armbruster
Cc: Yonggang Luo, qemu-devel, Richard Henderson,
Philippe Mathieu-Daudé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 01:41:58PM +0200, Markus Armbruster wrote:
> Yonggang Luo <luoyonggang@gmail.com> writes:
>
> > Extract common_ss, system_ss, and family-common objects into one
> > qemu-system binary. Only arm, aarch64, microblaze-softmmu are
> > listed; a new target must have arch_srcs equal to target_info_def
> > only (target-info-def.c). Config headers stay in arch_genh.
> >
> > - Union non-TARGET_* keys with y taking precedence
> > - Reject leftover arch_srcs on participating targets
> > - Reject TARGET_* conditions on common_ss and system_ss
> > - Link SDL, install the binary, and apply Darwin entitlements
> >
> > Adding a target that still has per-target sources fails meson, for
> > example:
> >
> > combined qemu-system leftover for :
> > expected:
> > target-info-def.c
> > arch_srcs:
> > target/microblaze/mmu.c
> > target/microblaze/machine.c
> > target-info-def.c
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>
> Watch query-target lie:
>
> $ qemu-system -S -nodefaults -display none -qmp stdio
> {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 11}, "package": "v11.1.0-1902-g88f617913a"}, "capabilities": ["oob"]}}
> qemu-system: warning: nic xlnx.xps-ethernetlite.0 has no peer
> {"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
> {"return": {}}
> {'execute': 'query-target'}
> --> {"return": {"arch": "aarch64"}}
>
> Perhaps you can fix this by reordering patches. If you can't,
> deficiencies like this one need a prominent mention in the commit
> message.
What do you think the behaviour of 'query-target' ought to be in
this scenario ?
The 'none' machine has no associated target. Should we add a
'none' or 'unspecified' target to SysEmuTarget, or should we
just declare that "query-target" will report an error if no
target is activate.
I'd probably lean towards the latter. Latter in this series
is a new 'query-targets' command that can enumerate all
available targets in 'qemu-system', so 'query-target' merely
tells us which is active (if any). Perhaps 'query-targets'
should in fact tell us that straightaway, such that we can
declare 'query-target' to be obsolete (and even deprecate
it)
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 41/55] target-info: add SysEmuTarget none
2026-09-26 7:00 ` [PATCH v4 41/55] target-info: add SysEmuTarget none Yonggang Luo
@ 2026-09-28 11:47 ` Markus Armbruster
[not found] ` <CAE2XoE_QozVhBix251nyUQkFMi6p_4idGXpVOT0LSP7VYK8ddw@mail.gmail.com>
0 siblings, 1 reply; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 11:47 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> Add a none target for when no TargetInfo is selected. It is last
> so existing SYS_EMU_TARGET_* values stay put, and it is not a
> qemu-system- executable name. target_is_none() and target_none()
> report that state.
Why does it matter that existing SYS_EMU_TARGET_* stay put?
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
[...]
> diff --git a/qapi/machine.json b/qapi/machine.json
> index b1be5608b61..6aaa2af709a 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -22,6 +22,10 @@
> # The individual target constants are not documented here, for the
> # time being.
> #
> +# @none: no TargetInfo selected.
Doc comments are reference documentation for users. TargetInfo is an
internal thing. Please rephrase in terms that make sense to users.
> Not a qemu-system- executable name.
This barely makes sense. I recommend to leave documenting the
qemu-system-T naming convention to the note below.
> +# Last enumerator so existing SYS_EMU_TARGET_* values stay put.
Of no concern to users, therefore inappropriate for user documentation.
> +# (since 11.2)
> +#
> # @rx: since 5.0
> #
> # @avr: since 5.1
> @@ -30,9 +34,10 @@
> #
> # @hexagon: since 11.0
> #
> -# .. note:: The resulting QMP strings can be appended to the
> -# "qemu-system-" prefix to produce the corresponding QEMU
> -# executable name. This is true even for "qemu-system-x86_64".
> +# .. note:: Except for ``none``, the resulting QMP strings can be
> +# appended to the "qemu-system-" prefix to produce the
> +# corresponding QEMU executable name. This is true even for
> +# "qemu-system-x86_64".
Not this patch's concern: I don't understand what's so special about
x86_64.
> #
> # Since: 3.0
> ##
> @@ -42,7 +47,7 @@
> 'mips64el', 'mipsel', 'or1k', 'ppc',
> 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
> 'sh4eb', 'sparc', 'sparc64', 'tricore',
> - 'x86_64', 'xtensa', 'xtensaeb' ] }
> + 'x86_64', 'xtensa', 'xtensaeb', 'none' ] }
>
> ##
> # @S390CpuState:
[...]
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 10:13 ` Daniel P. Berrangé
2026-09-28 10:39 ` Philippe Mathieu-Daudé
@ 2026-09-28 12:03 ` Markus Armbruster
2026-09-28 12:08 ` Daniel P. Berrangé
2026-09-28 14:24 ` Yonggang Luo
2 siblings, 1 reply; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 12:03 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Yonggang Luo, qemu-devel, Richard Henderson,
Philippe Mathieu-Daudé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Daniel P. Berrangé <berrange@redhat.com> writes:
> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
>> query-targets lists each linked target, including none, with its
>> arch, endianness, and the machines that target accepts.
>>
>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>> ---
>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
>> 2 files changed, 65 insertions(+)
>
>
>> diff --git a/qapi/machine.json b/qapi/machine.json
>> index 6aaa2af709a..d8cdea6203e 100644
>> --- a/qapi/machine.json
>> +++ b/qapi/machine.json
>> @@ -307,6 +307,41 @@
>> ##
>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>>
>> +##
>> +# @TargetMachines:
>> +#
>> +# One registered system target and the machines that can run on it.
>> +#
>> +# @arch: the target architecture
>> +#
>> +# @endianness: the target endianness
>> +#
>> +# @machines: machine type names, not aliases
>> +#
>> +# Since: 11.2
>> +##
>> +{ 'struct': 'TargetMachines',
>> + 'data': { 'arch': 'SysEmuTarget',
>> + 'endianness': 'EndianMode',
>> + 'machines': ['str'] } }
>
> We already have 'QemuTargetInfo' struct which is used
> with 'query-target', that should also be used with the
> new 'query-targets' command.
>
> We need to add the 'endianness' field to QemuTargetInfo.
>
> I don't think that we need to report machines though.
> We already have 'query-machines' which gives much broader
> information on the machines. "MachineInfo" needs to
> gain
>
> "targets": ["SysEmuTarget"]
>
> to list which target(s) a machine can be used with.
Do we need query-targets at all? What information does it provide that
cannot easily be computed from query-machines once we add @target and
@endiannes to MachineInfo?
>> +
>> +##
>> +# @query-targets:
>> +#
>> +# Return each target linked into this QEMU binary and the machines
>> +# whose availability check accepts that target.
>> +#
>> +# Since: 11.2
>> +#
>> +# .. qmp-example::
>> +#
>> +# -> { "execute": "query-targets" }
>> +# <- { "return": [ { "arch": "aarch64", "endianness": "little",
>> +# "machines": [ "virt" ] } ] }
>> +##
>> +{ 'command': 'query-targets',
>> + 'returns': ['TargetMachines'] }
>
>
> With regards,
> Daniel
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 12:03 ` Markus Armbruster
@ 2026-09-28 12:08 ` Daniel P. Berrangé
0 siblings, 0 replies; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 12:08 UTC (permalink / raw)
To: Markus Armbruster
Cc: Yonggang Luo, qemu-devel, Richard Henderson,
Philippe Mathieu-Daudé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 02:03:19PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> >> query-targets lists each linked target, including none, with its
> >> arch, endianness, and the machines that target accepts.
> >>
> >> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >> ---
> >> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> >> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> >> 2 files changed, 65 insertions(+)
> >
> >
> >> diff --git a/qapi/machine.json b/qapi/machine.json
> >> index 6aaa2af709a..d8cdea6203e 100644
> >> --- a/qapi/machine.json
> >> +++ b/qapi/machine.json
> >> @@ -307,6 +307,41 @@
> >> ##
> >> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> >>
> >> +##
> >> +# @TargetMachines:
> >> +#
> >> +# One registered system target and the machines that can run on it.
> >> +#
> >> +# @arch: the target architecture
> >> +#
> >> +# @endianness: the target endianness
> >> +#
> >> +# @machines: machine type names, not aliases
> >> +#
> >> +# Since: 11.2
> >> +##
> >> +{ 'struct': 'TargetMachines',
> >> + 'data': { 'arch': 'SysEmuTarget',
> >> + 'endianness': 'EndianMode',
> >> + 'machines': ['str'] } }
> >
> > We already have 'QemuTargetInfo' struct which is used
> > with 'query-target', that should also be used with the
> > new 'query-targets' command.
> >
> > We need to add the 'endianness' field to QemuTargetInfo.
> >
> > I don't think that we need to report machines though.
> > We already have 'query-machines' which gives much broader
> > information on the machines. "MachineInfo" needs to
> > gain
> >
> > "targets": ["SysEmuTarget"]
> >
> > to list which target(s) a machine can be used with.
>
> Do we need query-targets at all? What information does it provide that
> cannot easily be computed from query-machines once we add @target and
> @endiannes to MachineInfo?
Hmm, yes, I need to get out of the "target oriented" mindset,
"machines" are the top level object of interest, and target
just a property of each.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 41/55] target-info: add SysEmuTarget none
[not found] ` <CAE2XoE_QozVhBix251nyUQkFMi6p_4idGXpVOT0LSP7VYK8ddw@mail.gmail.com>
@ 2026-09-28 12:17 ` Markus Armbruster
[not found] ` <CAE2XoE88wDu5dYzqVd4gvwNV=bf8qcztLos0xx3iMFnWB+=Nvw@mail.gmail.com>
0 siblings, 1 reply; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 12:17 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> On Mon, Sep 28, 2026 at 7:48 PM Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > Add a none target for when no TargetInfo is selected. It is last
>> > so existing SYS_EMU_TARGET_* values stay put, and it is not a
>> > qemu-system- executable name. target_is_none() and target_none()
>> > report that state.
>>
>> Why does it matter that existing SYS_EMU_TARGET_* stay put?
>
> We need a state that not a real CPU target is selected( I called it none),
> then we can use it to list all targets. for example, do query-targets.
> query-machines(all machines for all targets).
> Any better ways to handle it would be appreciated, I am not choosing to set
> it to NULL because
> that would cause too much NULL-check error, as the pre-existing code
> presume there is always a
> CPU target present.
Doesn't answer my question, so let me try again :)
In your commit message, you explain "it is last so existing
SYS_EMU_TARGET_* values stay put". They do, but why is that useful?
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 40/55] meson: link shared objects into qemu-system
2026-09-28 11:47 ` Daniel P. Berrangé
@ 2026-09-28 12:23 ` Markus Armbruster
0 siblings, 0 replies; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 12:23 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Yonggang Luo, qemu-devel, Richard Henderson,
Philippe Mathieu-Daudé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Daniel P. Berrangé <berrange@redhat.com> writes:
> On Mon, Sep 28, 2026 at 01:41:58PM +0200, Markus Armbruster wrote:
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > Extract common_ss, system_ss, and family-common objects into one
>> > qemu-system binary. Only arm, aarch64, microblaze-softmmu are
>> > listed; a new target must have arch_srcs equal to target_info_def
>> > only (target-info-def.c). Config headers stay in arch_genh.
>> >
>> > - Union non-TARGET_* keys with y taking precedence
>> > - Reject leftover arch_srcs on participating targets
>> > - Reject TARGET_* conditions on common_ss and system_ss
>> > - Link SDL, install the binary, and apply Darwin entitlements
>> >
>> > Adding a target that still has per-target sources fails meson, for
>> > example:
>> >
>> > combined qemu-system leftover for :
>> > expected:
>> > target-info-def.c
>> > arch_srcs:
>> > target/microblaze/mmu.c
>> > target/microblaze/machine.c
>> > target-info-def.c
>> >
>> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>
>> Watch query-target lie:
>>
>> $ qemu-system -S -nodefaults -display none -qmp stdio
>> {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 11}, "package": "v11.1.0-1902-g88f617913a"}, "capabilities": ["oob"]}}
>> qemu-system: warning: nic xlnx.xps-ethernetlite.0 has no peer
>> {"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
>> {"return": {}}
>> {'execute': 'query-target'}
>> --> {"return": {"arch": "aarch64"}}
>>
>> Perhaps you can fix this by reordering patches. If you can't,
>> deficiencies like this one need a prominent mention in the commit
>> message.
>
> What do you think the behaviour of 'query-target' ought to be in
> this scenario ?
>
> The 'none' machine has no associated target. Should we add a
> 'none' or 'unspecified' target to SysEmuTarget, or should we
> just declare that "query-target" will report an error if no
> target is activate.
Both solutions could work. To have a preference, I'd have to think some
more. Thinking costs extra! ;)
For what it's worth, the next patch adds member "none" to SysEmuTarget.
> I'd probably lean towards the latter. Latter in this series
> is a new 'query-targets' command that can enumerate all
> available targets in 'qemu-system', so 'query-target' merely
> tells us which is active (if any). Perhaps 'query-targets'
> should in fact tell us that straightaway, such that we can
> declare 'query-target' to be obsolete (and even deprecate
> it)
>
> With regards,
> Daniel
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 41/55] target-info: add SysEmuTarget none
[not found] ` <CAE2XoE88wDu5dYzqVd4gvwNV=bf8qcztLos0xx3iMFnWB+=Nvw@mail.gmail.com>
@ 2026-09-28 12:24 ` Markus Armbruster
0 siblings, 0 replies; 82+ messages in thread
From: Markus Armbruster @ 2026-09-28 12:24 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Edgar E. Iglesias, Pierrick Bouvier,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini, Alistair Francis,
Peter Maydell, Marc-André Lureau, qemu-arm, kvm
Yonggang Luo <luoyonggang@gmail.com> writes:
> On Mon, Sep 28, 2026 at 8:18 PM Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > On Mon, Sep 28, 2026 at 7:48 PM Markus Armbruster <armbru@redhat.com>
> wrote:
>> >>
>> >> Yonggang Luo <luoyonggang@gmail.com> writes:
>> >>
>> >> > Add a none target for when no TargetInfo is selected. It is last
>> >> > so existing SYS_EMU_TARGET_* values stay put, and it is not a
>> >> > qemu-system- executable name. target_is_none() and target_none()
>> >> > report that state.
>> >>
>> >> Why does it matter that existing SYS_EMU_TARGET_* stay put?
>> >
>> > We need a state that not a real CPU target is selected( I called it
> none),
>> > then we can use it to list all targets. for example, do query-targets.
>> > query-machines(all machines for all targets).
>> > Any better ways to handle it would be appreciated, I am not choosing to
> set
>> > it to NULL because
>> > that would cause too much NULL-check error, as the pre-existing code
>> > presume there is always a
>> > CPU target present.
>>
>> Doesn't answer my question, so let me try again :)
>>
>> In your commit message, you explain "it is last so existing
>> SYS_EMU_TARGET_* values stay put". They do, but why is that useful?
>
> Just to keep the pre-existing enum value not changed, yeap, not that useful.
> I'll drop this misleading comment. Another choice is keep none
> as the first enum value, so it's always "0", maybe that's better?
I think it is, because similar "none" are first elsewhere.
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 10:13 ` Daniel P. Berrangé
2026-09-28 10:39 ` Philippe Mathieu-Daudé
2026-09-28 12:03 ` Markus Armbruster
@ 2026-09-28 14:24 ` Yonggang Luo
2026-09-28 14:37 ` Daniel P. Berrangé
2 siblings, 1 reply; 82+ messages in thread
From: Yonggang Luo @ 2026-09-28 14:24 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 6:14 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> I don't think that we need to report machines though.
> We already have 'query-machines' which gives much broader
> information on the machines. "MachineInfo" needs to
> gain
>
> "targets": ["SysEmuTarget"]
>
> to list which target(s) a machine can be used with.
>
This is my final design for the query-target / query-targets / query-machines,
for consistency and testability.
Per review: reuse `QemuTargetInfo` for both target commands, drop the
per-target machine list, and let
`MachineInfo` say which target(s) each machine runs on.
`QemuTargetInfo` stays small; `query-target` and `query-targets` return a
derived struct that adds the target's device and accel Kconfig state.
## QemuTargetInfo
```
{ 'struct': 'QemuTargetInfo',
'data': { 'arch': 'SysEmuTarget' } } # since 1.2
```
`mips` and `mipsel` are distinct `SysEmuTarget` values; the target value
identifies the system emulator, including its endianness, rather than only
the underlying architecture family.
## QemuTargetDetails: QemuTargetInfo plus kconfig
```
{ 'struct': 'QemuTargetDetails',
'base': 'QemuTargetInfo',
'data': { 'kconfig': 'any' } }
```
`kconfig` maps every device and accel `CONFIG_*` symbol to whether it
is enabled for that target.
For example, `TYPE_NITRO_ENCLAVE_MACHINE` is available only when
`CONFIG_NITRO_ENCLAVE` is enabled for the target:
```
{ "arch": "x86_64",
"kconfig": { "CONFIG_NITRO_ENCLAVE": true } }
```
Examples below are trimmed.
## query-target (now returns QemuTargetDetails)
Adding members to a return type is backward compatible; existing
clients reading only `arch` are unaffected.
```
{ 'command': 'query-target', 'returns': 'QemuTargetDetails' }
```
Single-target binary (`qemu-system-aarch64`):
```
-> { "execute": "query-target" }
<- { "return": { "arch": "aarch64",
"kconfig": { "CONFIG_ARM_VIRT": true,
"CONFIG_Q35": false,
... } } }
```
## query-targets (new, returns ['QemuTargetDetails'])
Single-target binary:
```
-> { "execute": "query-targets" }
<- { "return": [ { "arch": "aarch64",
"kconfig": { "CONFIG_ARM_VIRT": true,
"CONFIG_Q35": false, ... } } ] }
```
Combined `qemu-system` linking aarch64 and riscv64 (`none` is always
present):
```
-> { "execute": "query-targets" }
<- { "return": [ { "arch": "aarch64",
"kconfig": { "CONFIG_ARM_VIRT": true,
"CONFIG_RISCV_VIRT": false, ... } },
{ "arch": "riscv64",
"kconfig": { "CONFIG_ARM_VIRT": false,
"CONFIG_RISCV_VIRT": true, ... } },
{ "arch": "none",
"kconfig": { "CONFIG_ARM_VIRT": false,
"CONFIG_RISCV_VIRT": false, ... } } ] }
```
## query-machines: MachineInfo gains targets
```
{ 'struct': 'MachineInfo',
'data': { 'name': 'str', 'typename': 'str', ...existing members...,
'targets': ['QemuTargetInfo'] } } # since 11.2
```
Combined `qemu-system` (other MachineInfo members trimmed):
```
-> { "execute": "query-machines" }
<- { "return": [
{ "name": "virt-11.2", "typename": "arm-virt-11.2-machine",
"alias": "virt", "is-default": false,
"cpu-max": 512, "deprecated": false, "secure": true,
"targets": [ { "arch": "aarch64" } ] },
{ "name": "virt", "typename": "riscv-virt-machine",
"cpu-max": 512, "deprecated": false,
"secure": true,
"targets": [ { "arch": "riscv64" } ] },
{ "name": "none", "typename": "none-machine",
"cpu-max": 1, "deprecated": false,
"secure": false,
"targets": [ { "arch": "aarch64" },
{ "arch": "riscv64" },
{ "arch": "none" } ] }
] }
```
Single-target binary: every entry has exactly one element in
`targets`, equal to `query-target`'s `arch`.
A client that wants the old "machines per target" view filters
`query-machines` on `targets`.
## Open questions for the list
Machine names are not unique in a combined binary (`virt` above exists
for aarch64 and riscv64). `typename` is the unique QOM identity, so the
list contains one `MachineInfo` per `typename`; `targets` lists the
targets on which that machine type is available.
1. `kconfig` on `QemuTargetDetails`. The use case is tests telling "not
built" apart from "missing". Open points:
- `'any'` (a JSON object) vs. a list of enabled symbol names.
The object makes a typo (symbol absent) distinguishable from
"disabled" (`false`).
- Stable, or an `unstable` feature, given that Kconfig symbol
names are internal and can be renamed.
- Size: several hundred entries per target, which is why it is
in `QemuTargetDetails` (`query-target`, `query-targets`) and not
in `QemuTargetInfo` (which contains only the target architecture).
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 14:24 ` Yonggang Luo
@ 2026-09-28 14:37 ` Daniel P. Berrangé
2026-09-28 16:05 ` Yonggang Luo
0 siblings, 1 reply; 82+ messages in thread
From: Daniel P. Berrangé @ 2026-09-28 14:37 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 10:24:39PM +0800, Yonggang Luo wrote:
> On Mon, Sep 28, 2026 at 6:14 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > I don't think that we need to report machines though.
> > We already have 'query-machines' which gives much broader
> > information on the machines. "MachineInfo" needs to
> > gain
> >
> > "targets": ["SysEmuTarget"]
> >
> > to list which target(s) a machine can be used with.
> >
>
> This is my final design for the query-target / query-targets / query-machines,
> for consistency and testability.
>
> Per review: reuse `QemuTargetInfo` for both target commands, drop the
> per-target machine list, and let
> `MachineInfo` say which target(s) each machine runs on.
> `QemuTargetInfo` stays small; `query-target` and `query-targets` return a
> derived struct that adds the target's device and accel Kconfig state.
>
> ## QemuTargetInfo
>
> ```
> { 'struct': 'QemuTargetInfo',
> 'data': { 'arch': 'SysEmuTarget' } } # since 1.2
> ```
> ## QemuTargetDetails: QemuTargetInfo plus kconfig
>
> ```
> { 'struct': 'QemuTargetDetails',
> 'base': 'QemuTargetInfo',
> 'data': { 'kconfig': 'any' } }
> ```
>
> `kconfig` maps every device and accel `CONFIG_*` symbol to whether it
> is enabled for that target.
KConfig is an internal implementation detail that should not be exposed
to management apps as we don't want KConfig to become an ABI we must
preserve. QAPI introspection provides feature based information to
the user. eg instead of querying for "CONFIG_SEV", qom-list-types can
be queried to look for the 'sev-guest' class.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 14:37 ` Daniel P. Berrangé
@ 2026-09-28 16:05 ` Yonggang Luo
0 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-28 16:05 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Richard Henderson, Philippe Mathieu-Daudé,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm
On Mon, Sep 28, 2026 at 10:38 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Mon, Sep 28, 2026 at 10:24:39PM +0800, Yonggang Luo wrote:
> > On Mon, Sep 28, 2026 at 6:14 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > >
> > > I don't think that we need to report machines though.
> > > We already have 'query-machines' which gives much broader
> > > information on the machines. "MachineInfo" needs to
> > > gain
> > >
> > > "targets": ["SysEmuTarget"]
> > >
> > > to list which target(s) a machine can be used with.
> > >
> >
> > This is my final design for the query-target / query-targets / query-machines,
> > for consistency and testability.
> >
> > Per review: reuse `QemuTargetInfo` for both target commands, drop the
> > per-target machine list, and let
> > `MachineInfo` say which target(s) each machine runs on.
> > `QemuTargetInfo` stays small; `query-target` and `query-targets` return a
> > derived struct that adds the target's device and accel Kconfig state.
> >
> > ## QemuTargetInfo
> >
> > ```
> > { 'struct': 'QemuTargetInfo',
> > 'data': { 'arch': 'SysEmuTarget' } } # since 1.2
> > ```
>
> > ## QemuTargetDetails: QemuTargetInfo plus kconfig
> >
> > ```
> > { 'struct': 'QemuTargetDetails',
> > 'base': 'QemuTargetInfo',
> > 'data': { 'kconfig': 'any' } }
> > ```
> >
> > `kconfig` maps every device and accel `CONFIG_*` symbol to whether it
> > is enabled for that target.
>
> KConfig is an internal implementation detail that should not be exposed
> to management apps as we don't want KConfig to become an ABI we must
> preserve. QAPI introspection provides feature based information to
> the user. eg instead of querying for "CONFIG_SEV", qom-list-types can
> be queried to look for the 'sev-guest' class.
For example, `TYPE_NITRO_ENCLAVE_MACHINE` is available only when
`CONFIG_NITRO_ENCLAVE` is enabled for the target. When I construct the
machine list literal,
I need this information to help me to check if the machine is listed
in qemu-system that matches
qemu-sysetem-$arch. That needs a QAPI for it. What's the method you
would suggest
for? Otherwise, the test for the listing machine names can not be
reliably running for it.
for example:
/*
* Machines omitted from the normal lists. Merged in when @kconfig is
* true in the target's query-targets "kconfig" object, which already
* folds in host libraries and accelerators. xenfv is an alias of
* xenfv-4.2.
*/
static const char * const xen_pc_machines[] = {
"xenpv",
"xenpvh",
"xenfv-4.2",
};
static const char * const xen_aarch64_machines[] = {
"xenpvh",
};
static const char * const vmapple_machines[] = {
"vmapple",
};
static const char * const microvm_machines[] = {
"microvm",
};
static const char * const nitro_machines[] = {
"nitro",
};
static const char * const nitro_enclave_machines[] = {
"nitro-enclave",
};
static const char * const x_remote_machines[] = {
"x-remote",
};
#define SPECIAL(t, k, m) { t, k, m, G_N_ELEMENTS(m) }
static const struct SpecialMachineMap {
const char *target;
const char *kconfig;
const char * const *machines;
size_t n_machines;
} special_machine_map[] = {
SPECIAL("i386", "CONFIG_XEN", xen_pc_machines),
SPECIAL("x86_64", "CONFIG_XEN", xen_pc_machines),
SPECIAL("aarch64", "CONFIG_XEN", xen_aarch64_machines),
SPECIAL("aarch64", "CONFIG_VMAPPLE", vmapple_machines),
SPECIAL("i386", "CONFIG_MICROVM", microvm_machines),
SPECIAL("x86_64", "CONFIG_MICROVM", microvm_machines),
SPECIAL("x86_64", "CONFIG_NITRO_MACHINE", nitro_machines),
SPECIAL("aarch64", "CONFIG_NITRO_MACHINE", nitro_machines),
SPECIAL("i386", "CONFIG_NITRO_ENCLAVE", nitro_enclave_machines),
SPECIAL("x86_64", "CONFIG_NITRO_ENCLAVE", nitro_enclave_machines),
SPECIAL("i386", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("x86_64", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("aarch64", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("ppc", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("ppc64", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("s390x", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("riscv64", "CONFIG_MULTIPROCESS", x_remote_machines),
SPECIAL("loongarch64", "CONFIG_MULTIPROCESS", x_remote_machines),
};
#undef SPECIAL
These machines all depend on the kconfig. When I try to write qtest
for it, I need the CONFIG_* information to be returned for them.
>
>
> With regards,
> Daniel
> --
> |: https://berrange.com ~~ https://hachyderm.io/@berrange :|
> |: https://libvirt.org ~~ https://entangle-photo.org :|
> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 11:34 ` Philippe Mathieu-Daudé
@ 2026-09-28 18:50 ` Yonggang Luo
0 siblings, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-28 18:50 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Daniel P. Berrangé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On Mon, Sep 28, 2026 at 7:34 PM Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> On 28/9/26 12:51, Yonggang Luo wrote:
> > On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> > philmd@oss.qualcomm.com> wrote:
> >>
> >> On 28/9/26 12:13, Daniel P. Berrangé wrote:
> >>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> >>>> query-targets lists each linked target, including none, with its
> >>>> arch, endianness, and the machines that target accepts.
> >>>>
> >>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >>>> ---
> >>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> >>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> >>>> 2 files changed, 65 insertions(+)
> >>>
> >>>
> >>>> diff --git a/qapi/machine.json b/qapi/machine.json
> >>>> index 6aaa2af709a..d8cdea6203e 100644
> >>>> --- a/qapi/machine.json
> >>>> +++ b/qapi/machine.json
> >>>> @@ -307,6 +307,41 @@
> >>>> ##
> >>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> >>>>
> >>>> +##
> >>>> +# @TargetMachines:
> >>>> +#
> >>>> +# One registered system target and the machines that can run on it.
> >>>> +#
> >>>> +# @arch: the target architecture
> >>>> +#
> >>>> +# @endianness: the target endianness
> >>>> +#
> >>>> +# @machines: machine type names, not aliases
> >>>> +#
> >>>> +# Since: 11.2
> >>>> +##
> >>>> +{ 'struct': 'TargetMachines',
> >>>> + 'data': { 'arch': 'SysEmuTarget',
> >>>> + 'endianness': 'EndianMode',
> >>>> + 'machines': ['str'] } }
> >>>
> >>> We already have 'QemuTargetInfo' struct which is used
> >>> with 'query-target', that should also be used with the
> >>> new 'query-targets' command.
> >>>
> >>> We need to add the 'endianness' field to QemuTargetInfo.
> >>
> >> Why do we want to expose endianness, and what endianness to
> >> expose? Endianness is a runtime bit state of CPUs. Sometime
> >> this bit is hardwired but that is an implementation detail.
> >
> > For some targets it's, but for some targets it's not. for example
> >
> > mips-softmmu.mak
> > mipsel-softmmu.mak
> > mips64el-softmmu.mak
> > mips64-softmmu.mak
> >
> >
> > mips64el-softmmu.mak
> > mips64-softmmu.mak
> > only differ the endianless
> If you look at git / mailing list history you'll see I spent more
> than a year unifying QEMU endianness. It was too much work for a
> single person so we decided to reduce the scope to ARM + MicroBlaze
> for single binary and we got MicroBlaze unified. We don't want
> an endianness-specific single binary. I'm not sure what you are
> trying to build, you didn't clearly explained what is your goal here.
>
> You can find series unifying endianness for MIPS, not merged because
> more things need to be addressed and not the priority.
Oh it's because target_arch is not setup properly for those arch
From bcffa0d129fd864037b4e0f7b2f46f4889e76509 Mon Sep 17 00:00:00 2001
From: Yonggang Luo <luoyonggang@gmail.com>
Date: Tue, 29 Sep 2026 02:47:48 +0800
Subject: [PATCH] target-info: preserve full softmmu target identity
Generate a full SysEmuTarget token separately from TARGET_ARCH, so variant
targets such as mipsel retain their QMP identity while user-mode targets
continue using the base architecture token.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
meson.build | 5 +++++
target-info-def.c | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/meson.build b/meson.build
index d63174ea8a4..e86daa47228 100644
--- a/meson.build
+++ b/meson.build
@@ -3319,6 +3319,9 @@ foreach target : target_dirs
endif
config_target += keyval.load('configs/targets' / target + '.mak')
+ if target.endswith('-softmmu')
+ config_target += { 'TARGET_SYS_EMU': config_target['TARGET_NAME'] }
+ endif
target_kconfig = []
foreach sym: accelerators
@@ -3374,6 +3377,8 @@ foreach target : target_dirs
# do nothing
elif k == 'TARGET_ARCH'
config_target_data.set(k, v.to_upper())
+ elif k == 'TARGET_SYS_EMU'
+ config_target_data.set(k, v.to_upper())
elif k == 'TARGET_BASE_ARCH'
# Note that TARGET_BASE_ARCH ends up in config-target.h but it is
# not used to select files from sourcesets.
diff --git a/target-info-def.c b/target-info-def.c
index c02d98e6875..54e499712bf 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -28,7 +28,11 @@ QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN);
static const TargetInfo target_info_stub = {
.target_name = TARGET_NAME,
+#ifdef CONFIG_SOFTMMU
+ .target_arch = glue(SYS_EMU_TARGET_, TARGET_SYS_EMU),
+#else
.target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
+#endif
.long_bits = TARGET_LONG_BITS,
.cpu_type = CPU_RESOLVING_TYPE,
.endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
--
2.52.0.windows.1
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply related [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
[not found] ` <CAE2XoE8Fp8w4m0WBjEXF3LceFXUqKDcXhdSmhCThgkAM3wRVaQ@mail.gmail.com>
@ 2026-09-28 19:11 ` Philippe Mathieu-Daudé
2026-09-28 19:18 ` Yonggang Luo
2026-09-29 1:36 ` Yonggang Luo
0 siblings, 2 replies; 82+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-28 19:11 UTC (permalink / raw)
To: luoyonggang
Cc: Daniel P. Berrangé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On 28/9/26 20:34, Yonggang Luo wrote:
> On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> philmd@oss.qualcomm.com> wrote:
>>
>> On 28/9/26 12:13, Daniel P. Berrangé wrote:
>>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
>>>> query-targets lists each linked target, including none, with its
>>>> arch, endianness, and the machines that target accepts.
>>>>
>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>>> ---
>>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
>>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
>>>> 2 files changed, 65 insertions(+)
>>>
>>>
>>>> diff --git a/qapi/machine.json b/qapi/machine.json
>>>> index 6aaa2af709a..d8cdea6203e 100644
>>>> --- a/qapi/machine.json
>>>> +++ b/qapi/machine.json
>>>> @@ -307,6 +307,41 @@
>>>> ##
>>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
>>>>
>>>> +##
>>>> +# @TargetMachines:
>>>> +#
>>>> +# One registered system target and the machines that can run on it.
>>>> +#
>>>> +# @arch: the target architecture
>>>> +#
>>>> +# @endianness: the target endianness
>>>> +#
>>>> +# @machines: machine type names, not aliases
>>>> +#
>>>> +# Since: 11.2
>>>> +##
>>>> +{ 'struct': 'TargetMachines',
>>>> + 'data': { 'arch': 'SysEmuTarget',
>>>> + 'endianness': 'EndianMode',
>>>> + 'machines': ['str'] } }
>>>
>>> We already have 'QemuTargetInfo' struct which is used
>>> with 'query-target', that should also be used with the
>>> new 'query-targets' command.
>>>
>>> We need to add the 'endianness' field to QemuTargetInfo.
>>
>> Why do we want to expose endianness, and what endianness to
>> expose? Endianness is a runtime bit state of CPUs. Sometime
>> this bit is hardwired but that is an implementation detail.
>>
>> See commit 0e2c5647d92 and surrounding for MicroBlaze for
>> example.
>
> Please take a look at
> https://gitlab.com/lygstate-qemu/qemu/-/pipelines/2890507627
>
> I do not have clue to fixes it properly
What are you asking here? I'm seeing failures on targets supporting
dual endianness. I can not try to help you until I understand what
your goal is (I asked it multiple times but you don't reply explaining).
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 19:11 ` Philippe Mathieu-Daudé
@ 2026-09-28 19:18 ` Yonggang Luo
2026-09-29 1:36 ` Yonggang Luo
1 sibling, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-28 19:18 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Daniel P. Berrangé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On Tue, Sep 29, 2026 at 3:11 AM Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> On 28/9/26 20:34, Yonggang Luo wrote:
> > On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> > philmd@oss.qualcomm.com> wrote:
> >>
> >> On 28/9/26 12:13, Daniel P. Berrangé wrote:
> >>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> >>>> query-targets lists each linked target, including none, with its
> >>>> arch, endianness, and the machines that target accepts.
> >>>>
> >>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >>>> ---
> >>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> >>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> >>>> 2 files changed, 65 insertions(+)
> >>>
> >>>
> >>>> diff --git a/qapi/machine.json b/qapi/machine.json
> >>>> index 6aaa2af709a..d8cdea6203e 100644
> >>>> --- a/qapi/machine.json
> >>>> +++ b/qapi/machine.json
> >>>> @@ -307,6 +307,41 @@
> >>>> ##
> >>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> >>>>
> >>>> +##
> >>>> +# @TargetMachines:
> >>>> +#
> >>>> +# One registered system target and the machines that can run on it.
> >>>> +#
> >>>> +# @arch: the target architecture
> >>>> +#
> >>>> +# @endianness: the target endianness
> >>>> +#
> >>>> +# @machines: machine type names, not aliases
> >>>> +#
> >>>> +# Since: 11.2
> >>>> +##
> >>>> +{ 'struct': 'TargetMachines',
> >>>> + 'data': { 'arch': 'SysEmuTarget',
> >>>> + 'endianness': 'EndianMode',
> >>>> + 'machines': ['str'] } }
> >>>
> >>> We already have 'QemuTargetInfo' struct which is used
> >>> with 'query-target', that should also be used with the
> >>> new 'query-targets' command.
> >>>
> >>> We need to add the 'endianness' field to QemuTargetInfo.
> >>
> >> Why do we want to expose endianness, and what endianness to
> >> expose? Endianness is a runtime bit state of CPUs. Sometime
> >> this bit is hardwired but that is an implementation detail.
> >>
> >> See commit 0e2c5647d92 and surrounding for MicroBlaze for
> >> example.
> >
> > Please take a look at
> > https://gitlab.com/lygstate-qemu/qemu/-/pipelines/2890507627
> >
> > I do not have clue to fixes it properly
>
> What are you asking here? I'm seeing failures on targets supporting
> dual endianness. I can not try to help you until I understand what
> your goal is (I asked it multiple times but you don't reply explaining).
>
MM, let me try to explain it.
The machine list of mips64 and mips64el is different as follows
mips64_machines/mips64el_machines,
and the two lists are generated from original qemu-system-mips64 and
qemu-system-mips64el respectively.
But TargetInfo::target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH), so
qemu-system-mips64 qemu-system-mips64el
are sharing the same SYS_EMU_TARGET_MIPS64 for the function
target_arch(), and it's returned for
query-target/query-targets. so we can not distinguish them.
And I want to deal with this issue, here is one of my try:
+#ifdef CONFIG_SOFTMMU
+ .target_arch = glue(SYS_EMU_TARGET_, TARGET_SYS_EMU),
+#else
.target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
+#endif
Is this proper?
static const char * const mips64_machines[] = {
"magnum",
"malta",
"none",
"pica61",
};
static const char * const mips64el_machines[] = {
"boston",
"fuloong2e",
"loongson3-virt",
"magnum",
"malta",
"none",
"pica61",
};
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v4 46/55] qapi: add query-targets
2026-09-28 19:11 ` Philippe Mathieu-Daudé
2026-09-28 19:18 ` Yonggang Luo
@ 2026-09-29 1:36 ` Yonggang Luo
1 sibling, 0 replies; 82+ messages in thread
From: Yonggang Luo @ 2026-09-29 1:36 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Daniel P. Berrangé, qemu-devel, Richard Henderson,
Edgar E. Iglesias, Pierrick Bouvier, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini, Alistair Francis, Peter Maydell,
Marc-André Lureau, qemu-arm, kvm, Thomas Huth
On Tue, Sep 29, 2026 at 3:11 AM Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> On 28/9/26 20:34, Yonggang Luo wrote:
> > On Mon, Sep 28, 2026 at 6:39 PM Philippe Mathieu-Daudé <
> > philmd@oss.qualcomm.com> wrote:
> >>
> >> On 28/9/26 12:13, Daniel P. Berrangé wrote:
> >>> On Sat, Sep 26, 2026 at 03:00:45PM +0800, Yonggang Luo wrote:
> >>>> query-targets lists each linked target, including none, with its
> >>>> arch, endianness, and the machines that target accepts.
> >>>>
> >>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >>>> ---
> >>>> hw/core/machine-qmp-cmds.c | 30 ++++++++++++++++++++++++++++++
> >>>> qapi/machine.json | 35 +++++++++++++++++++++++++++++++++++
> >>>> 2 files changed, 65 insertions(+)
> >>>
> >>>
> >>>> diff --git a/qapi/machine.json b/qapi/machine.json
> >>>> index 6aaa2af709a..d8cdea6203e 100644
> >>>> --- a/qapi/machine.json
> >>>> +++ b/qapi/machine.json
> >>>> @@ -307,6 +307,41 @@
> >>>> ##
> >>>> { 'command': 'query-target', 'returns': 'QemuTargetInfo' }
> >>>>
> >>>> +##
> >>>> +# @TargetMachines:
> >>>> +#
> >>>> +# One registered system target and the machines that can run on it.
> >>>> +#
> >>>> +# @arch: the target architecture
> >>>> +#
> >>>> +# @endianness: the target endianness
> >>>> +#
> >>>> +# @machines: machine type names, not aliases
> >>>> +#
> >>>> +# Since: 11.2
> >>>> +##
> >>>> +{ 'struct': 'TargetMachines',
> >>>> + 'data': { 'arch': 'SysEmuTarget',
> >>>> + 'endianness': 'EndianMode',
> >>>> + 'machines': ['str'] } }
> >>>
> >>> We already have 'QemuTargetInfo' struct which is used
> >>> with 'query-target', that should also be used with the
> >>> new 'query-targets' command.
> >>>
> >>> We need to add the 'endianness' field to QemuTargetInfo.
> >>
> >> Why do we want to expose endianness, and what endianness to
> >> expose? Endianness is a runtime bit state of CPUs. Sometime
> >> this bit is hardwired but that is an implementation detail.
> >>
> >> See commit 0e2c5647d92 and surrounding for MicroBlaze for
> >> example.
> >
> > Please take a look at
> > https://gitlab.com/lygstate-qemu/qemu/-/pipelines/2890507627
> >
> > I do not have clue to fixes it properly
>
> What are you asking here? I'm seeing failures on targets supporting
> dual endianness. I can not try to help you until I understand what
> your goal is (I asked it multiple times but you don't reply explaining).
Now I can answer the question more clear, it's because the pitfall of commit
https://gitlab.com/qemu-project/qemu/-/commit/e934c624f32f6f44f427d73a2e6a67e983a02ae6
cause the issue
target-info-stub.c | 2 +-
target-info.c | 8 +-------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/target-info-stub.c b/target-info-stub.c
index 8392d81e8f..65220cc782 100644
--- a/target-info-stub.c
+++ b/target-info-stub.c
@@ -18,7 +18,7 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
static const TargetInfo target_info_stub = {
.target_name = TARGET_NAME,
- .target_arch = SYS_EMU_TARGET__MAX,
+ .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
.long_bits = TARGET_LONG_BITS,
.cpu_type = CPU_RESOLVING_TYPE,
.machine_typename = TYPE_MACHINE,
diff --git a/target-info.c b/target-info.c
index 5a6d728252..a26532f660 100644
--- a/target-info.c
+++ b/target-info.c
@@ -24,13 +24,7 @@ unsigned target_long_bits(void)
SysEmuTarget target_arch(void)
{
- SysEmuTarget arch = target_info()->target_arch;
-
- if (arch == SYS_EMU_TARGET__MAX) {
- arch = qapi_enum_parse(&SysEmuTarget_lookup, target_name(), -1,
- &error_abort);
- }
- return arch;
+ return target_info()->target_arch;
}
const char *target_cpu_type(void)
Look at the diff, the original one is directly parsed from
target_name(). and the new one
defines "glue(SYS_EMU_TARGET_, TARGET_ARCH)", but that indeed does not
match target_name() at all.
And TARGET_ARCH is introduced in commit
https://gitlab.com/lygstate-qemu/qemu/-/commit/f87f7e145d63f93315e0f0e00fb9ba0b6ee8570f
for this.
Hi Richard, is this done for intention or a mistake?
maybe we should always generate target_arch from target_name()
in meson.build?
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply related [flat|nested] 82+ messages in thread
end of thread, other threads:[~2026-09-29 1:36 UTC | newest]
Thread overview: 82+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-26 6:59 [PATCH v4 00/55] single-binary: link multi-targets into qemu-system Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 01/55] target-info: Introduce target_riscv32 Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 02/55] configs/targets: remove target info definitions Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 03/55] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 04/55] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 05/55] vl: parse early options before target-info init Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 06/55] target-info: replace QOM registration with a constructor list Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 07/55] tests/unit: add test-target-info Yonggang Luo
2026-09-28 9:07 ` Markus Armbruster
[not found] ` <CAE2XoE9_R13NsUWu-s12QA9RBJykR87TEMh3VmndNEXQsCkNtg@mail.gmail.com>
2026-09-28 9:43 ` Daniel P. Berrangé
2026-09-28 9:48 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 08/55] tests/qtest: prepare machine-list-test for combined qemu-system Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 09/55] kconfig: rename REGISTER to HW_REGISTER Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 10/55] target-info: add TargetKconfig Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 11/55] target-info: add target_is_* helpers for each architecture Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 12/55] target-info: add target_is_any() Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 13/55] qom: pass TargetInfo to is_available for latter use Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 14/55] target/arm: move kvm_arm_set_cpreg_mig_tolerances to kvm.c Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 15/55] target/arm: allow -cpu host with Nitro Yonggang Luo
2026-09-28 10:06 ` Philippe Mathieu-Daudé
2026-09-26 7:00 ` [PATCH v4 16/55] target/arm: gate -cpu host with TypeIsAvailable Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 17/55] target/arm: replace target_long in A64 translate Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 18/55] target/arm: use vaddr for the A64 insn_start pc Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 19/55] tests/qtest: raise aspeed_smc-test timeout to 12 minutes Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 20/55] target-info: add tl_is_64() and target_is_tl32/64 helpers Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 21/55] tcg: declare TCGv in tcg.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 22/55] tcg: dispatch TL memory helpers from tcg-op-mem.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 23/55] tcg: dispatch tcg_gen_*_tl without TARGET_LONG_BITS Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 24/55] tcg: dispatch tcg_gen_gvec_dup_tl at runtime Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 25/55] tcg: give common-system helper tl an i64 slot Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 26/55] accel/tcg: move helper_exit_atomic next to cpu_loop_exit_atomic Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 27/55] tcg: move dup_const into tcg.c Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 28/55] tcg: move goto_tb helpers into tcg-op-ldst.c Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 29/55] accel/tcg: move gvec helpers into tcg-runtime-gvec.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 30/55] accel/tcg: move helper_lookup_tb_ptr into cpu-exec.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 31/55] accel/tcg: move memory helpers out of tcg-runtime.h Yonggang Luo
2026-09-28 10:40 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 32/55] tests/unit: cover common-system tl dispatch and calls Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 33/55] target/arm: fix A64 guest address width at 64 Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 34/55] target/arm: pass tl temps into SVE and SME helpers Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 35/55] exec: provide target_ulong for softmmu common code Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 36/55] exec: compile abi_ptr.h without per-target cpu-param.h Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 37/55] accel/tcg: keep cpu-ldst endian aliases per-target Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 38/55] target/arm: fold arm_ss into common source sets Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 39/55] target/microblaze: fold system sources " Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 40/55] meson: link shared objects into qemu-system Yonggang Luo
2026-09-28 11:41 ` Markus Armbruster
2026-09-28 11:47 ` Daniel P. Berrangé
2026-09-28 12:23 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 41/55] target-info: add SysEmuTarget none Yonggang Luo
2026-09-28 11:47 ` Markus Armbruster
[not found] ` <CAE2XoE_QozVhBix251nyUQkFMi6p_4idGXpVOT0LSP7VYK8ddw@mail.gmail.com>
2026-09-28 12:17 ` Markus Armbruster
[not found] ` <CAE2XoE88wDu5dYzqVd4gvwNV=bf8qcztLos0xx3iMFnWB+=Nvw@mail.gmail.com>
2026-09-28 12:24 ` Markus Armbruster
2026-09-26 7:00 ` [PATCH v4 42/55] module: load every arch-tagged module when target is none Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 43/55] accel/tcg: tolerate NULL target_cpu_type for -M none Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 44/55] target-info: select combined qemu-system target by name Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 45/55] vl: parse arch: machine types on combined qemu-system Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 46/55] qapi: add query-targets Yonggang Luo
2026-09-28 10:13 ` Daniel P. Berrangé
2026-09-28 10:39 ` Philippe Mathieu-Daudé
[not found] ` <CAE2XoE9qsZZ+AnfGQ797SQj5yXP8SDOZyxYoKP=oh57UPFqq0Q@mail.gmail.com>
2026-09-28 10:57 ` Daniel P. Berrangé
2026-09-28 11:29 ` Philippe Mathieu-Daudé
2026-09-28 11:36 ` Daniel P. Berrangé
2026-09-28 11:34 ` Philippe Mathieu-Daudé
2026-09-28 18:50 ` Yonggang Luo
[not found] ` <CAE2XoE8Fp8w4m0WBjEXF3LceFXUqKDcXhdSmhCThgkAM3wRVaQ@mail.gmail.com>
2026-09-28 19:11 ` Philippe Mathieu-Daudé
2026-09-28 19:18 ` Yonggang Luo
2026-09-29 1:36 ` Yonggang Luo
2026-09-28 12:03 ` Markus Armbruster
2026-09-28 12:08 ` Daniel P. Berrangé
2026-09-28 14:24 ` Yonggang Luo
2026-09-28 14:37 ` Daniel P. Berrangé
2026-09-28 16:05 ` Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 47/55] target-info: add target_is_microblaze Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 48/55] hw/microblaze: set petalogix-s3adsp1800 TypeInfo.is_available Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 49/55] hw/microblaze: expand petalogix-ml605 and xlnx-zynqmp-pmu to TypeInfo Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 50/55] hw/arm: expand leftover 32-bit DEFINE_MACHINE " Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 51/55] hw/arm: expand imx8mm-evk " Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 52/55] hw/arm: set virt TypeInfo.is_available Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 53/55] hw/arm: set remaining 32-bit machine TypeInfo.is_available Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 54/55] hw/arm: set aarch64-only " Yonggang Luo
2026-09-26 7:00 ` [PATCH v4 55/55] tests/qtest: cover combined qemu-system machines Yonggang Luo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox