qemu-sparc queue

-----BEGIN PGP SIGNATURE-----
 
 iQFSBAABCgA8FiEEzGIauY6CIA2RXMnEW8LFb64PMh8FAmY4wZceHG1hcmsuY2F2
 ZS1heWxhbmRAaWxhbmRlLmNvLnVrAAoJEFvCxW+uDzIftQsH+wfIWymTdQMowfM6
 Ze/T8KODn+MqU5eg25VPSTojnmr7LFaCj2yK6zWX61RwIqtMc3NaxX0G7ksW12/g
 35ACqiEEd5WRDhAtVhj5Wp+WEDoR4AD3LWIaN7a/qjO3qb78l7Bujw3qXzGSq4lQ
 hST6dTgMwn5LhJOyz+5dORVUK1UZSBuDxHeKRHgdoFi6yqGQ5bao5TpaDYOnGSbx
 8KPrAFfXG1T6xRS8Ih5HXAPE5VJztLFPiVtCTTrETDP/o8EzvOZj5y/nJVZXXC3N
 57g+QyJX9EdrRZvobef4LnNnoZyiqG+uQNugglqZqjiiLjl6AzYxI+ed0hU+cZR9
 pz76Hr8=
 =i2cV
 -----END PGP SIGNATURE-----

Merge tag 'qemu-sparc-20240506' of https://github.com/mcayland/qemu into staging

qemu-sparc queue

# -----BEGIN PGP SIGNATURE-----
#
# iQFSBAABCgA8FiEEzGIauY6CIA2RXMnEW8LFb64PMh8FAmY4wZceHG1hcmsuY2F2
# ZS1heWxhbmRAaWxhbmRlLmNvLnVrAAoJEFvCxW+uDzIftQsH+wfIWymTdQMowfM6
# Ze/T8KODn+MqU5eg25VPSTojnmr7LFaCj2yK6zWX61RwIqtMc3NaxX0G7ksW12/g
# 35ACqiEEd5WRDhAtVhj5Wp+WEDoR4AD3LWIaN7a/qjO3qb78l7Bujw3qXzGSq4lQ
# hST6dTgMwn5LhJOyz+5dORVUK1UZSBuDxHeKRHgdoFi6yqGQ5bao5TpaDYOnGSbx
# 8KPrAFfXG1T6xRS8Ih5HXAPE5VJztLFPiVtCTTrETDP/o8EzvOZj5y/nJVZXXC3N
# 57g+QyJX9EdrRZvobef4LnNnoZyiqG+uQNugglqZqjiiLjl6AzYxI+ed0hU+cZR9
# pz76Hr8=
# =i2cV
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 06 May 2024 04:40:07 AM PDT
# gpg:                using RSA key CC621AB98E82200D915CC9C45BC2C56FAE0F321F
# gpg:                issuer "mark.cave-ayland@ilande.co.uk"
# gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" [full]

* tag 'qemu-sparc-20240506' of https://github.com/mcayland/qemu:
  target/sparc: Split out do_ms16b
  target/sparc: Fix FPMERGE
  target/sparc: Fix FMULD8*X16
  target/sparc: Fix FMUL8x16A{U,L}
  target/sparc: Fix FMUL8x16
  target/sparc: Fix FEXPAND
  linux-user/sparc: Add more hwcap bits for sparc64
  hw/sparc64: set iommu_platform=on for virtio devices attached to the sun4u machine
  docs/about: Deprecate the old "UltraSparc" CPU names that contain a "+"
  docs/system/target-sparc: Improve the Sparc documentation
  target/sparc/cpu: Avoid spaces by default in the CPU names
  target/sparc/cpu: Rename the CPU models with a "+" in their names

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-05-06 10:19:56 -07:00
commit e116b92d01
10 changed files with 268 additions and 219 deletions

View file

@ -194,6 +194,15 @@ in the QEMU object model anymore. ``power5+``, ``power5+_v2.1``,
an alias, but for consistency these will get removed in a future
release, too. Use ``power5p_v2.1`` and ``power7p_v2.1`` instead.
``Sun-UltraSparc-IIIi+`` and ``Sun-UltraSparc-IV+`` CPU names (since 9.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The character "+" in device (and thus also CPU) names is not allowed
in the QEMU object model anymore. ``Sun-UltraSparc-IIIi+`` and
``Sun-UltraSparc-IV+`` are currently still supported via a workaround,
but for consistency these will get removed in a future release, too.
Use ``Sun-UltraSparc-IIIi-plus`` and ``Sun-UltraSparc-IV-plus`` instead.
CRIS CPU architecture (since 9.0)
'''''''''''''''''''''''''''''''''

View file

@ -27,6 +27,11 @@ architecture machines:
The emulation is somewhat complete. SMP up to 16 CPUs is supported, but
Linux limits the number of usable CPUs to 4.
The list of available CPUs can be viewed by starting QEMU with ``-cpu help``.
Optional boolean features can be added with a "+" in front of the feature name,
or disabled with a "-" in front of the name, for example
``-cpu TI-SuperSparc-II,+float128``.
QEMU emulates the following sun4m peripherals:
- IOMMU
@ -55,8 +60,5 @@ OpenBIOS is a free (GPL v2) portable firmware implementation. The goal
is to implement a 100% IEEE 1275-1994 (referred to as Open Firmware)
compliant firmware.
A sample Linux 2.6 series kernel and ram disk image are available on the
QEMU web site. There are still issues with NetBSD and OpenBSD, but most
kernel versions work. Please note that currently older Solaris kernels
don't work probably due to interface issues between OpenBIOS and
Solaris.
Please note that currently older Solaris kernels don't work; this is probably
due to interface issues between OpenBIOS and Solaris.

View file

@ -793,6 +793,12 @@ static void sun4v_init(MachineState *machine)
sun4uv_init(get_system_memory(), machine, &hwdefs[1]);
}
static GlobalProperty hw_compat_sparc64[] = {
{ "virtio-pci", "disable-legacy", "on", .optional = true },
{ "virtio-device", "iommu_platform", "on" },
};
static const size_t hw_compat_sparc64_len = G_N_ELEMENTS(hw_compat_sparc64);
static void sun4u_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@ -810,6 +816,7 @@ static void sun4u_class_init(ObjectClass *oc, void *data)
mc->default_nic = "sunhme";
mc->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
fwc->get_dev_path = sun4u_fw_dev_path;
compat_props_add(mc->compat_props, hw_compat_sparc64, hw_compat_sparc64_len);
}
static const TypeInfo sun4u_type = {

View file

@ -969,24 +969,44 @@ const char *elf_hwcap2_str(uint32_t bit)
#endif /* TARGET_ARM */
#ifdef TARGET_SPARC
#ifdef TARGET_SPARC64
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9)
#ifndef TARGET_ABI32
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
#ifndef TARGET_SPARC64
# define ELF_CLASS ELFCLASS32
# define ELF_ARCH EM_SPARC
#elif defined(TARGET_ABI32)
# define ELF_CLASS ELFCLASS32
# define elf_check_arch(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
#else
#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
# define ELF_CLASS ELFCLASS64
# define ELF_ARCH EM_SPARCV9
#endif
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_SPARCV9
#else
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SPARC
#endif /* TARGET_SPARC64 */
#include "elf.h"
#define ELF_HWCAP get_elf_hwcap()
static uint32_t get_elf_hwcap(void)
{
/* There are not many sparc32 hwcap bits -- we have all of them. */
uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
#ifdef TARGET_SPARC64
CPUSPARCState *env = cpu_env(thread_cpu);
uint32_t features = env->def.features;
r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
/* 32x32 multiply and divide are efficient. */
r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
/* We don't have an internal feature bit for this. */
r |= HWCAP_SPARC_POPC;
r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
#endif
return r;
}
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)

View file

@ -157,14 +157,6 @@ static bool type_name_is_valid(const char *name)
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789-_.");
/* Allow some legacy names with '+' in it for compatibility reasons */
if (name[plen] == '+') {
if (plen >= 17 && g_str_has_prefix(name, "Sun-UltraSparc-I")) {
/* Allow "Sun-UltraSparc-IV+" and "Sun-UltraSparc-IIIi+" */
return true;
}
}
return plen == slen;
}

View file

@ -206,7 +206,7 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
static const sparc_def_t sparc_defs[] = {
#ifdef TARGET_SPARC64
{
.name = "Fujitsu Sparc64",
.name = "Fujitsu-Sparc64",
.iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -215,7 +215,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Fujitsu Sparc64 III",
.name = "Fujitsu-Sparc64-III",
.iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -224,7 +224,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Fujitsu Sparc64 IV",
.name = "Fujitsu-Sparc64-IV",
.iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -233,7 +233,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Fujitsu Sparc64 V",
.name = "Fujitsu-Sparc64-V",
.iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -242,7 +242,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI UltraSparc I",
.name = "TI-UltraSparc-I",
.iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -251,7 +251,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI UltraSparc II",
.name = "TI-UltraSparc-II",
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -260,7 +260,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI UltraSparc IIi",
.name = "TI-UltraSparc-IIi",
.iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -269,7 +269,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI UltraSparc IIe",
.name = "TI-UltraSparc-IIe",
.iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -278,7 +278,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc III",
.name = "Sun-UltraSparc-III",
.iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -287,7 +287,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc III Cu",
.name = "Sun-UltraSparc-III-Cu",
.iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_3,
@ -296,7 +296,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc IIIi",
.name = "Sun-UltraSparc-IIIi",
.iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -305,7 +305,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc IV",
.name = "Sun-UltraSparc-IV",
.iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_4,
@ -314,7 +314,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc IV+",
.name = "Sun-UltraSparc-IV-plus",
.iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -323,7 +323,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
},
{
.name = "Sun UltraSparc IIIi+",
.name = "Sun-UltraSparc-IIIi-plus",
.iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_3,
@ -332,7 +332,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Sun UltraSparc T1",
.name = "Sun-UltraSparc-T1",
/* defined in sparc_ifu_fdp.v and ctu.h */
.iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
.fpu_version = 0x00000000,
@ -343,7 +343,7 @@ static const sparc_def_t sparc_defs[] = {
| CPU_FEATURE_GL,
},
{
.name = "Sun UltraSparc T2",
.name = "Sun-UltraSparc-T2",
/* defined in tlu_asi_ctl.v and n2_revid_cust.v */
.iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
.fpu_version = 0x00000000,
@ -354,7 +354,7 @@ static const sparc_def_t sparc_defs[] = {
| CPU_FEATURE_GL,
},
{
.name = "NEC UltraSparc I",
.name = "NEC-UltraSparc-I",
.iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
.fpu_version = 0x00000000,
.mmu_version = mmu_us_12,
@ -364,7 +364,7 @@ static const sparc_def_t sparc_defs[] = {
},
#else
{
.name = "Fujitsu MB86904",
.name = "Fujitsu-MB86904",
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
@ -377,7 +377,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "Fujitsu MB86907",
.name = "Fujitsu-MB86907",
.iu_version = 0x05 << 24, /* Impl 0, ver 5 */
.fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
@ -390,7 +390,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI MicroSparc I",
.name = "TI-MicroSparc-I",
.iu_version = 0x41000000,
.fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x41000000,
@ -403,7 +403,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_FEATURE_MUL | CPU_FEATURE_DIV,
},
{
.name = "TI MicroSparc II",
.name = "TI-MicroSparc-II",
.iu_version = 0x42000000,
.fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x02000000,
@ -416,7 +416,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI MicroSparc IIep",
.name = "TI-MicroSparc-IIep",
.iu_version = 0x42000000,
.fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x04000000,
@ -429,7 +429,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc 40", /* STP1020NPGA */
.name = "TI-SuperSparc-40", /* STP1020NPGA */
.iu_version = 0x41000000, /* SuperSPARC 2.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
@ -442,7 +442,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc 50", /* STP1020PGA */
.name = "TI-SuperSparc-50", /* STP1020PGA */
.iu_version = 0x40000000, /* SuperSPARC 3.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
@ -455,7 +455,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc 51",
.name = "TI-SuperSparc-51",
.iu_version = 0x40000000, /* SuperSPARC 3.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
@ -469,7 +469,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc 60", /* STP1020APGA */
.name = "TI-SuperSparc-60", /* STP1020APGA */
.iu_version = 0x40000000, /* SuperSPARC 3.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
@ -482,7 +482,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc 61",
.name = "TI-SuperSparc-61",
.iu_version = 0x44000000, /* SuperSPARC 3.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
@ -496,7 +496,7 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
.name = "TI SuperSparc II",
.name = "TI-SuperSparc-II",
.iu_version = 0x40000000, /* SuperSPARC II 1.x */
.fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
@ -762,6 +762,16 @@ static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model)
char *typename;
typename = sparc_cpu_type_name(cpu_model);
/* Fix up legacy names with '+' in it */
if (g_str_equal(typename, SPARC_CPU_TYPE_NAME("Sun-UltraSparc-IV+"))) {
g_free(typename);
typename = g_strdup(SPARC_CPU_TYPE_NAME("Sun-UltraSparc-IV-plus"));
} else if (g_str_equal(typename, SPARC_CPU_TYPE_NAME("Sun-UltraSparc-IIIi+"))) {
g_free(typename);
typename = g_strdup(SPARC_CPU_TYPE_NAME("Sun-UltraSparc-IIIi-plus"));
}
oc = object_class_by_name(typename);
g_free(typename);
return oc;

View file

@ -94,15 +94,12 @@ DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_WG, s64, env, f32)
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64)
DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128)
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16al, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16au, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i32, i32)
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i32, i64)
DEF_HELPER_FLAGS_2(fmul8x16a, TCG_CALL_NO_RWG_SE, i64, i32, s32)
DEF_HELPER_FLAGS_2(fmul8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmuld8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmuld8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fexpand, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_1(fexpand, TCG_CALL_NO_RWG_SE, i64, i32)
DEF_HELPER_FLAGS_3(pdist, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_NO_RWG_SE, i32, i64, i64)
DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)

View file

@ -352,7 +352,7 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
BSHUFFLE 10 ..... 110110 ..... 0 0100 1100 ..... @r_r_r
FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r
FEXPAND 10 ..... 110110 00000 0 0100 1101 ..... @r_r2
FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s

View file

@ -45,6 +45,7 @@
# define gen_helper_clear_softint(E, S) qemu_build_not_reached()
# define gen_helper_done(E) qemu_build_not_reached()
# define gen_helper_flushw(E) qemu_build_not_reached()
# define gen_helper_fmul8x16a(D, S1, S2) qemu_build_not_reached()
# define gen_helper_rdccr(D, E) qemu_build_not_reached()
# define gen_helper_rdcwp(D, E) qemu_build_not_reached()
# define gen_helper_restored(E) qemu_build_not_reached()
@ -72,11 +73,7 @@
# define gen_helper_fexpand ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmul8sux16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmul8ulx16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmul8x16al ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmul8x16au ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmul8x16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmuld8sux16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmuld8ulx16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fpmerge ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
@ -719,6 +716,60 @@ static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
#endif
}
static void gen_op_fmul8x16al(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
{
tcg_gen_ext16s_i32(src2, src2);
gen_helper_fmul8x16a(dst, src1, src2);
}
static void gen_op_fmul8x16au(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
{
tcg_gen_sari_i32(src2, src2, 16);
gen_helper_fmul8x16a(dst, src1, src2);
}
static void gen_op_fmuld8ulx16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
TCGv_i32 t2 = tcg_temp_new_i32();
tcg_gen_ext8u_i32(t0, src1);
tcg_gen_ext16s_i32(t1, src2);
tcg_gen_mul_i32(t0, t0, t1);
tcg_gen_extract_i32(t1, src1, 16, 8);
tcg_gen_sextract_i32(t2, src2, 16, 16);
tcg_gen_mul_i32(t1, t1, t2);
tcg_gen_concat_i32_i64(dst, t0, t1);
}
static void gen_op_fmuld8sux16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
TCGv_i32 t2 = tcg_temp_new_i32();
/*
* The insn description talks about extracting the upper 8 bits
* of the signed 16-bit input rs1, performing the multiply, then
* shifting left by 8 bits. Instead, zap the lower 8 bits of
* the rs1 input, which avoids the need for two shifts.
*/
tcg_gen_ext16s_i32(t0, src1);
tcg_gen_andi_i32(t0, t0, ~0xff);
tcg_gen_ext16s_i32(t1, src2);
tcg_gen_mul_i32(t0, t0, t1);
tcg_gen_sextract_i32(t1, src1, 16, 16);
tcg_gen_andi_i32(t1, t1, ~0xff);
tcg_gen_sextract_i32(t2, src2, 16, 16);
tcg_gen_mul_i32(t1, t1, t2);
tcg_gen_concat_i32_i64(dst, t0, t1);
}
static void finishing_insn(DisasContext *dc)
{
/*
@ -4358,6 +4409,25 @@ TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
static bool do_df(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i64, TCGv_i32))
{
TCGv_i64 dst;
TCGv_i32 src;
if (gen_trap_ifnofpu(dc)) {
return true;
}
dst = tcg_temp_new_i64();
src = gen_load_fpr_F(dc, a->rs);
func(dst, src);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
TRANS(FEXPAND, VIS1, do_df, a, gen_helper_fexpand)
static bool do_env_df(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
{
@ -4564,6 +4634,50 @@ TRANS(FSUBs, ALL, do_env_fff, a, gen_helper_fsubs)
TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls)
TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs)
static bool do_dff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i32, TCGv_i32))
{
TCGv_i64 dst;
TCGv_i32 src1, src2;
if (gen_trap_ifnofpu(dc)) {
return true;
}
dst = gen_dest_fpr_D(dc, a->rd);
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
func(dst, src1, src2);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
TRANS(FMUL8x16AU, VIS1, do_dff, a, gen_op_fmul8x16au)
TRANS(FMUL8x16AL, VIS1, do_dff, a, gen_op_fmul8x16al)
TRANS(FMULD8SUx16, VIS1, do_dff, a, gen_op_fmuld8sux16)
TRANS(FMULD8ULx16, VIS1, do_dff, a, gen_op_fmuld8ulx16)
TRANS(FPMERGE, VIS1, do_dff, a, gen_helper_fpmerge)
static bool do_dfd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i32, TCGv_i64))
{
TCGv_i64 dst, src2;
TCGv_i32 src1;
if (gen_trap_ifnofpu(dc)) {
return true;
}
dst = gen_dest_fpr_D(dc, a->rd);
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
func(dst, src1, src2);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
TRANS(FMUL8x16, VIS1, do_dfd, a, gen_helper_fmul8x16)
static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
{
@ -4581,15 +4695,8 @@ static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
return advance_pc(dc);
}
TRANS(FMUL8x16, VIS1, do_ddd, a, gen_helper_fmul8x16)
TRANS(FMUL8x16AU, VIS1, do_ddd, a, gen_helper_fmul8x16au)
TRANS(FMUL8x16AL, VIS1, do_ddd, a, gen_helper_fmul8x16al)
TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16)
TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16)
TRANS(FMULD8SUx16, VIS1, do_ddd, a, gen_helper_fmuld8sux16)
TRANS(FMULD8ULx16, VIS1, do_ddd, a, gen_helper_fmuld8ulx16)
TRANS(FPMERGE, VIS1, do_ddd, a, gen_helper_fpmerge)
TRANS(FEXPAND, VIS1, do_ddd, a, gen_helper_fexpand)
TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64)
TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64)

View file

@ -44,6 +44,7 @@ target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
#if HOST_BIG_ENDIAN
#define VIS_B64(n) b[7 - (n)]
#define VIS_SB64(n) sb[7 - (n)]
#define VIS_W64(n) w[3 - (n)]
#define VIS_SW64(n) sw[3 - (n)]
#define VIS_L64(n) l[1 - (n)]
@ -51,6 +52,7 @@ target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
#define VIS_W32(n) w[1 - (n)]
#else
#define VIS_B64(n) b[n]
#define VIS_SB64(n) sb[n]
#define VIS_W64(n) w[n]
#define VIS_SW64(n) sw[n]
#define VIS_L64(n) l[n]
@ -60,6 +62,7 @@ target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
typedef union {
uint8_t b[8];
int8_t sb[8];
uint16_t w[4];
int16_t sw[4];
uint32_t l[2];
@ -74,94 +77,60 @@ typedef union {
float32 f;
} VIS32;
uint64_t helper_fpmerge(uint64_t src1, uint64_t src2)
uint64_t helper_fpmerge(uint32_t src1, uint32_t src2)
{
VIS64 s, d;
VIS32 s1, s2;
VIS64 d;
s.ll = src1;
d.ll = src2;
s1.l = src1;
s2.l = src2;
d.ll = 0;
/* Reverse calculation order to handle overlap */
d.VIS_B64(7) = s.VIS_B64(3);
d.VIS_B64(6) = d.VIS_B64(3);
d.VIS_B64(5) = s.VIS_B64(2);
d.VIS_B64(4) = d.VIS_B64(2);
d.VIS_B64(3) = s.VIS_B64(1);
d.VIS_B64(2) = d.VIS_B64(1);
d.VIS_B64(1) = s.VIS_B64(0);
/* d.VIS_B64(0) = d.VIS_B64(0); */
d.VIS_B64(7) = s1.VIS_B32(3);
d.VIS_B64(6) = s2.VIS_B32(3);
d.VIS_B64(5) = s1.VIS_B32(2);
d.VIS_B64(4) = s2.VIS_B32(2);
d.VIS_B64(3) = s1.VIS_B32(1);
d.VIS_B64(2) = s2.VIS_B32(1);
d.VIS_B64(1) = s1.VIS_B32(0);
d.VIS_B64(0) = s2.VIS_B32(0);
return d.ll;
}
uint64_t helper_fmul8x16(uint64_t src1, uint64_t src2)
static inline int do_ms16b(int x, int y)
{
VIS64 s, d;
uint32_t tmp;
return ((x * y) + 0x80) >> 8;
}
s.ll = src1;
uint64_t helper_fmul8x16(uint32_t src1, uint64_t src2)
{
VIS64 d;
VIS32 s;
s.l = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_W64(r) = tmp >> 8;
PMUL(0);
PMUL(1);
PMUL(2);
PMUL(3);
#undef PMUL
d.VIS_W64(0) = do_ms16b(s.VIS_B32(0), d.VIS_SW64(0));
d.VIS_W64(1) = do_ms16b(s.VIS_B32(1), d.VIS_SW64(1));
d.VIS_W64(2) = do_ms16b(s.VIS_B32(2), d.VIS_SW64(2));
d.VIS_W64(3) = do_ms16b(s.VIS_B32(3), d.VIS_SW64(3));
return d.ll;
}
uint64_t helper_fmul8x16al(uint64_t src1, uint64_t src2)
uint64_t helper_fmul8x16a(uint32_t src1, int32_t src2)
{
VIS64 s, d;
uint32_t tmp;
VIS32 s;
VIS64 d;
s.ll = src1;
d.ll = src2;
s.l = src1;
d.ll = 0;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_W64(r) = tmp >> 8;
PMUL(0);
PMUL(1);
PMUL(2);
PMUL(3);
#undef PMUL
return d.ll;
}
uint64_t helper_fmul8x16au(uint64_t src1, uint64_t src2)
{
VIS64 s, d;
uint32_t tmp;
s.ll = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_W64(r) = tmp >> 8;
PMUL(0);
PMUL(1);
PMUL(2);
PMUL(3);
#undef PMUL
d.VIS_W64(0) = do_ms16b(s.VIS_B32(0), src2);
d.VIS_W64(1) = do_ms16b(s.VIS_B32(1), src2);
d.VIS_W64(2) = do_ms16b(s.VIS_B32(2), src2);
d.VIS_W64(3) = do_ms16b(s.VIS_B32(3), src2);
return d.ll;
}
@ -169,23 +138,14 @@ uint64_t helper_fmul8x16au(uint64_t src1, uint64_t src2)
uint64_t helper_fmul8sux16(uint64_t src1, uint64_t src2)
{
VIS64 s, d;
uint32_t tmp;
s.ll = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_W64(r) = tmp >> 8;
PMUL(0);
PMUL(1);
PMUL(2);
PMUL(3);
#undef PMUL
d.VIS_W64(0) = do_ms16b(s.VIS_SB64(1), d.VIS_SW64(0));
d.VIS_W64(1) = do_ms16b(s.VIS_SB64(3), d.VIS_SW64(1));
d.VIS_W64(2) = do_ms16b(s.VIS_SB64(5), d.VIS_SW64(2));
d.VIS_W64(3) = do_ms16b(s.VIS_SB64(7), d.VIS_SW64(3));
return d.ll;
}
@ -193,80 +153,25 @@ uint64_t helper_fmul8sux16(uint64_t src1, uint64_t src2)
uint64_t helper_fmul8ulx16(uint64_t src1, uint64_t src2)
{
VIS64 s, d;
uint32_t tmp;
s.ll = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_W64(r) = tmp >> 8;
PMUL(0);
PMUL(1);
PMUL(2);
PMUL(3);
#undef PMUL
d.VIS_W64(0) = do_ms16b(s.VIS_B64(0), d.VIS_SW64(0));
d.VIS_W64(1) = do_ms16b(s.VIS_B64(2), d.VIS_SW64(1));
d.VIS_W64(2) = do_ms16b(s.VIS_B64(4), d.VIS_SW64(2));
d.VIS_W64(3) = do_ms16b(s.VIS_B64(6), d.VIS_SW64(3));
return d.ll;
}
uint64_t helper_fmuld8sux16(uint64_t src1, uint64_t src2)
{
VIS64 s, d;
uint32_t tmp;
s.ll = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_L64(r) = tmp;
/* Reverse calculation order to handle overlap */
PMUL(1);
PMUL(0);
#undef PMUL
return d.ll;
}
uint64_t helper_fmuld8ulx16(uint64_t src1, uint64_t src2)
{
VIS64 s, d;
uint32_t tmp;
s.ll = src1;
d.ll = src2;
#define PMUL(r) \
tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
if ((tmp & 0xff) > 0x7f) { \
tmp += 0x100; \
} \
d.VIS_L64(r) = tmp;
/* Reverse calculation order to handle overlap */
PMUL(1);
PMUL(0);
#undef PMUL
return d.ll;
}
uint64_t helper_fexpand(uint64_t src1, uint64_t src2)
uint64_t helper_fexpand(uint32_t src2)
{
VIS32 s;
VIS64 d;
s.l = (uint32_t)src1;
d.ll = src2;
s.l = src2;
d.ll = 0;
d.VIS_W64(0) = s.VIS_B32(0) << 4;
d.VIS_W64(1) = s.VIS_B32(1) << 4;
d.VIS_W64(2) = s.VIS_B32(2) << 4;