target-arm queue:

* xlnx_dpdma: fix descriptor endianness bug
  * hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System registers
  * hw/arm/npcm7xx: remove setting of mp-affinity
  * hw/char: Correct STM32L4x5 usart register CR2 field ADD_0 size
  * hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n>
  * hw/input/tsc2005: Fix -Wchar-subscripts warning in tsc2005_txrx()
  * hw: arm: Remove use of tabs in some source files
  * docs/system: Remove ADC from raspi documentation
  * target/arm: Start of the conversion of A64 SIMD to decodetree
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmZV5HsZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3j+CD/9V5kC3DJtovMiolr1z8YYI
 eRj0I/pKacgIzz9kVwzo+UVVgzXAi80VFO7xbe+aucCKs0c2s3wrUnUWkAaGHUYR
 DKhRIp017HKW8esgDVQsItn2030PLQLlhxpLvhSfN7NR2jHiJdE914Kb3h6XIEVE
 CqMRaYt9Vrh5o0e51VSzzccFK+kyYV1MDvNyx1/8F4KJpsMFeK0iy9WYrXx2UxlT
 dlrJZdrShIkOWiQB+bi6zQzjMveNmDicjBCgnC7TO2ayOl0AD24sNg/Z49w+4Hjb
 azUDYR45uuyQD5HJLyBsk5BcYhfyZttn2U5uTvNQ6SEfMuKUFEfdoSebTHngEb6t
 ObOdJW6+GmyaIaaJS99ea8u8jbe1r5zhQGJEBeEWOyGYTKUJ6Q0J+g6dZUdgniOp
 bvORX4qnIlMLMGGYT34410Wf0lsE88BHspcVX0WLGFLMZcEYsHhdgG6/f0p8D3nD
 m3R5+/BxUHK7A6OVe/1YU6jTqnfPBY6CGKSqEvXbJGlPp7LAjIxuUHBRxRnXU+Ad
 ohBwOIEEDNhGnEiiHFFK+wrc8BncXY4eSiJBCLlRaf1AcxCT6ibWXuUlpnWeAwNk
 E3Kmvq9BCdQZpIj7EsyvngTc5PsQrqK0FNIVuSVi38QQnqS/0oykvsPzgSlD6blP
 zcFIgG7aUiPOkdTxcPTYnA==
 =TjtM
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20240528' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * xlnx_dpdma: fix descriptor endianness bug
 * hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System registers
 * hw/arm/npcm7xx: remove setting of mp-affinity
 * hw/char: Correct STM32L4x5 usart register CR2 field ADD_0 size
 * hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n>
 * hw/input/tsc2005: Fix -Wchar-subscripts warning in tsc2005_txrx()
 * hw: arm: Remove use of tabs in some source files
 * docs/system: Remove ADC from raspi documentation
 * target/arm: Start of the conversion of A64 SIMD to decodetree

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmZV5HsZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3j+CD/9V5kC3DJtovMiolr1z8YYI
# eRj0I/pKacgIzz9kVwzo+UVVgzXAi80VFO7xbe+aucCKs0c2s3wrUnUWkAaGHUYR
# DKhRIp017HKW8esgDVQsItn2030PLQLlhxpLvhSfN7NR2jHiJdE914Kb3h6XIEVE
# CqMRaYt9Vrh5o0e51VSzzccFK+kyYV1MDvNyx1/8F4KJpsMFeK0iy9WYrXx2UxlT
# dlrJZdrShIkOWiQB+bi6zQzjMveNmDicjBCgnC7TO2ayOl0AD24sNg/Z49w+4Hjb
# azUDYR45uuyQD5HJLyBsk5BcYhfyZttn2U5uTvNQ6SEfMuKUFEfdoSebTHngEb6t
# ObOdJW6+GmyaIaaJS99ea8u8jbe1r5zhQGJEBeEWOyGYTKUJ6Q0J+g6dZUdgniOp
# bvORX4qnIlMLMGGYT34410Wf0lsE88BHspcVX0WLGFLMZcEYsHhdgG6/f0p8D3nD
# m3R5+/BxUHK7A6OVe/1YU6jTqnfPBY6CGKSqEvXbJGlPp7LAjIxuUHBRxRnXU+Ad
# ohBwOIEEDNhGnEiiHFFK+wrc8BncXY4eSiJBCLlRaf1AcxCT6ibWXuUlpnWeAwNk
# E3Kmvq9BCdQZpIj7EsyvngTc5PsQrqK0FNIVuSVi38QQnqS/0oykvsPzgSlD6blP
# zcFIgG7aUiPOkdTxcPTYnA==
# =TjtM
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 28 May 2024 07:04:43 AM PDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]

* tag 'pull-target-arm-20240528' of https://git.linaro.org/people/pmaydell/qemu-arm: (42 commits)
  target/arm: Convert disas_simd_3same_logic to decodetree
  target/arm: Convert FMLAL, FMLSL to decodetree
  target/arm: Use gvec for neon pmax, pmin
  target/arm: Convert SMAXP, SMINP, UMAXP, UMINP to decodetree
  target/arm: Use gvec for neon padd
  target/arm: Convert ADDP to decodetree
  target/arm: Use gvec for neon faddp, fmaxp, fminp
  target/arm: Convert FMAXP, FMINP, FMAXNMP, FMINNMP to decodetree
  target/arm: Convert FADDP to decodetree
  target/arm: Convert FRECPS, FRSQRTS to decodetree
  target/arm: Convert FABD to decodetree
  target/arm: Convert FCMEQ, FCMGE, FCMGT, FACGE, FACGT to decodetree
  target/arm: Convert FMLA, FMLS to decodetree
  target/arm: Convert FNMUL to decodetree
  target/arm: Expand vfp neg and abs inline
  target/arm: Introduce vfp_load_reg16
  target/arm: Convert FMAX, FMIN, FMAXNM, FMINNM to decodetree
  target/arm: Convert FADD, FSUB, FDIV, FMUL to decodetree
  target/arm: Convert FMULX to decodetree
  target/arm: Convert Advanced SIMD copy to decodetree
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-05-28 10:06:53 -07:00
commit f8e5c833f9
27 changed files with 3860 additions and 4297 deletions

View File

@ -40,7 +40,6 @@ Implemented devices
Missing devices
---------------
* Analog to Digital Converter (ADC)
* Pulse Width Modulation (PWM)
* PCIE Root Port (raspi4b)
* GENET Ethernet Controller (raspi4b)

View File

@ -347,13 +347,13 @@ static void set_kernel_args_old(const struct arm_boot_info *info,
WRITE_WORD(p, info->ram_size / 4096);
/* ramdisk_size */
WRITE_WORD(p, 0);
#define FLAG_READONLY 1
#define FLAG_RDLOAD 4
#define FLAG_RDPROMPT 8
#define FLAG_READONLY 1
#define FLAG_RDLOAD 4
#define FLAG_RDPROMPT 8
/* flags */
WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
/* rootdev */
WRITE_WORD(p, (31 << 8) | 0); /* /dev/mtdblock0 */
WRITE_WORD(p, (31 << 8) | 0); /* /dev/mtdblock0 */
/* video_num_cols */
WRITE_WORD(p, 0);
/* video_num_rows */

View File

@ -487,9 +487,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
/* CPUs */
for (i = 0; i < nc->num_cpus; i++) {
object_property_set_int(OBJECT(&s->cpu[i]), "mp-affinity",
arm_build_mp_affinity(i, NPCM7XX_MAX_NUM_CPUS),
&error_abort);
object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar",
NPCM7XX_GIC_CPU_IF_ADDR, &error_abort);
object_property_set_bool(OBJECT(&s->cpu[i]), "reset-hivecs", true,

View File

@ -61,7 +61,7 @@ struct omap_uart_s *omap_uart_init(hwaddr base,
s->fclk = fclk;
s->irq = irq;
s->serial = serial_mm_init(get_system_memory(), base, 2, irq,
omap_clk_getrate(fclk)/16,
omap_clk_getrate(fclk) / 16,
chr ?: qemu_chr_new(label, "null", NULL),
DEVICE_NATIVE_ENDIAN);
return s;
@ -76,27 +76,27 @@ static uint64_t omap_uart_read(void *opaque, hwaddr addr, unsigned size)
}
switch (addr) {
case 0x20: /* MDR1 */
case 0x20: /* MDR1 */
return s->mdr[0];
case 0x24: /* MDR2 */
case 0x24: /* MDR2 */
return s->mdr[1];
case 0x40: /* SCR */
case 0x40: /* SCR */
return s->scr;
case 0x44: /* SSR */
case 0x44: /* SSR */
return 0x0;
case 0x48: /* EBLR (OMAP2) */
case 0x48: /* EBLR (OMAP2) */
return s->eblr;
case 0x4C: /* OSC_12M_SEL (OMAP1) */
case 0x4C: /* OSC_12M_SEL (OMAP1) */
return s->clksel;
case 0x50: /* MVR */
case 0x50: /* MVR */
return 0x30;
case 0x54: /* SYSC (OMAP2) */
case 0x54: /* SYSC (OMAP2) */
return s->syscontrol;
case 0x58: /* SYSS (OMAP2) */
case 0x58: /* SYSS (OMAP2) */
return 1;
case 0x5c: /* WER (OMAP2) */
case 0x5c: /* WER (OMAP2) */
return s->wkup;
case 0x60: /* CFPS (OMAP2) */
case 0x60: /* CFPS (OMAP2) */
return s->cfps;
}
@ -115,35 +115,36 @@ static void omap_uart_write(void *opaque, hwaddr addr,
}
switch (addr) {
case 0x20: /* MDR1 */
case 0x20: /* MDR1 */
s->mdr[0] = value & 0x7f;
break;
case 0x24: /* MDR2 */
case 0x24: /* MDR2 */
s->mdr[1] = value & 0xff;
break;
case 0x40: /* SCR */
case 0x40: /* SCR */
s->scr = value & 0xff;
break;
case 0x48: /* EBLR (OMAP2) */
case 0x48: /* EBLR (OMAP2) */
s->eblr = value & 0xff;
break;
case 0x4C: /* OSC_12M_SEL (OMAP1) */
case 0x4C: /* OSC_12M_SEL (OMAP1) */
s->clksel = value & 1;
break;
case 0x44: /* SSR */
case 0x50: /* MVR */
case 0x58: /* SYSS (OMAP2) */
case 0x44: /* SSR */
case 0x50: /* MVR */
case 0x58: /* SYSS (OMAP2) */
OMAP_RO_REG(addr);
break;
case 0x54: /* SYSC (OMAP2) */
case 0x54: /* SYSC (OMAP2) */
s->syscontrol = value & 0x1d;
if (value & 2)
if (value & 2) {
omap_uart_reset(s);
}
break;
case 0x5c: /* WER (OMAP2) */
case 0x5c: /* WER (OMAP2) */
s->wkup = value & 0x7f;
break;
case 0x60: /* CFPS (OMAP2) */
case 0x60: /* CFPS (OMAP2) */
s->cfps = value & 0xff;
break;
default:

View File

@ -56,7 +56,7 @@ REG32(CR1, 0x00)
FIELD(CR1, UE, 0, 1) /* USART enable */
REG32(CR2, 0x04)
FIELD(CR2, ADD_1, 28, 4) /* ADD[7:4] */
FIELD(CR2, ADD_0, 24, 1) /* ADD[3:0] */
FIELD(CR2, ADD_0, 24, 4) /* ADD[3:0] */
FIELD(CR2, RTOEN, 23, 1) /* Receiver timeout enable */
FIELD(CR2, ABRMOD, 21, 2) /* Auto baud rate mode */
FIELD(CR2, ABREN, 20, 1) /* Auto baud rate enable */

View File

@ -614,6 +614,65 @@ static void xlnx_dpdma_register_types(void)
type_register_static(&xlnx_dpdma_info);
}
static MemTxResult xlnx_dpdma_read_descriptor(XlnxDPDMAState *s,
uint64_t desc_addr,
DPDMADescriptor *desc)
{
MemTxResult res = dma_memory_read(&address_space_memory, desc_addr,
&desc, sizeof(DPDMADescriptor),
MEMTXATTRS_UNSPECIFIED);
if (res) {
return res;
}
/* Convert from LE into host endianness. */
desc->control = le32_to_cpu(desc->control);
desc->descriptor_id = le32_to_cpu(desc->descriptor_id);
desc->xfer_size = le32_to_cpu(desc->xfer_size);
desc->line_size_stride = le32_to_cpu(desc->line_size_stride);
desc->timestamp_lsb = le32_to_cpu(desc->timestamp_lsb);
desc->timestamp_msb = le32_to_cpu(desc->timestamp_msb);
desc->address_extension = le32_to_cpu(desc->address_extension);
desc->next_descriptor = le32_to_cpu(desc->next_descriptor);
desc->source_address = le32_to_cpu(desc->source_address);
desc->address_extension_23 = le32_to_cpu(desc->address_extension_23);
desc->address_extension_45 = le32_to_cpu(desc->address_extension_45);
desc->source_address2 = le32_to_cpu(desc->source_address2);
desc->source_address3 = le32_to_cpu(desc->source_address3);
desc->source_address4 = le32_to_cpu(desc->source_address4);
desc->source_address5 = le32_to_cpu(desc->source_address5);
desc->crc = le32_to_cpu(desc->crc);
return res;
}
static MemTxResult xlnx_dpdma_write_descriptor(uint64_t desc_addr,
DPDMADescriptor *desc)
{
DPDMADescriptor tmp_desc = *desc;
/* Convert from host endianness into LE. */
tmp_desc.control = cpu_to_le32(tmp_desc.control);
tmp_desc.descriptor_id = cpu_to_le32(tmp_desc.descriptor_id);
tmp_desc.xfer_size = cpu_to_le32(tmp_desc.xfer_size);
tmp_desc.line_size_stride = cpu_to_le32(tmp_desc.line_size_stride);
tmp_desc.timestamp_lsb = cpu_to_le32(tmp_desc.timestamp_lsb);
tmp_desc.timestamp_msb = cpu_to_le32(tmp_desc.timestamp_msb);
tmp_desc.address_extension = cpu_to_le32(tmp_desc.address_extension);
tmp_desc.next_descriptor = cpu_to_le32(tmp_desc.next_descriptor);
tmp_desc.source_address = cpu_to_le32(tmp_desc.source_address);
tmp_desc.address_extension_23 = cpu_to_le32(tmp_desc.address_extension_23);
tmp_desc.address_extension_45 = cpu_to_le32(tmp_desc.address_extension_45);
tmp_desc.source_address2 = cpu_to_le32(tmp_desc.source_address2);
tmp_desc.source_address3 = cpu_to_le32(tmp_desc.source_address3);
tmp_desc.source_address4 = cpu_to_le32(tmp_desc.source_address4);
tmp_desc.source_address5 = cpu_to_le32(tmp_desc.source_address5);
tmp_desc.crc = cpu_to_le32(tmp_desc.crc);
return dma_memory_write(&address_space_memory, desc_addr, &tmp_desc,
sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED);
}
size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
bool one_desc)
{
@ -651,8 +710,7 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
desc_addr = xlnx_dpdma_descriptor_next_address(s, channel);
}
if (dma_memory_read(&address_space_memory, desc_addr, &desc,
sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED)) {
if (xlnx_dpdma_read_descriptor(s, desc_addr, &desc)) {
s->registers[DPDMA_EISR] |= ((1 << 1) << channel);
xlnx_dpdma_update_irq(s);
s->operation_finished[channel] = true;
@ -755,8 +813,10 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
/* The descriptor need to be updated when it's completed. */
DPRINTF("update the descriptor with the done flag set.\n");
xlnx_dpdma_desc_set_done(&desc);
dma_memory_write(&address_space_memory, desc_addr, &desc,
sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED);
if (xlnx_dpdma_write_descriptor(desc_addr, &desc)) {
DPRINTF("Can't write the descriptor.\n");
/* TODO: check hardware behaviour for memory write failure */
}
}
if (xlnx_dpdma_desc_completion_interrupt(&desc)) {

View File

@ -49,19 +49,20 @@ struct ScoopInfo {
uint16_t isr;
};
#define SCOOP_MCR 0x00
#define SCOOP_CDR 0x04
#define SCOOP_CSR 0x08
#define SCOOP_CPR 0x0c
#define SCOOP_CCR 0x10
#define SCOOP_IRR_IRM 0x14
#define SCOOP_IMR 0x18
#define SCOOP_ISR 0x1c
#define SCOOP_GPCR 0x20
#define SCOOP_GPWR 0x24
#define SCOOP_GPRR 0x28
#define SCOOP_MCR 0x00
#define SCOOP_CDR 0x04
#define SCOOP_CSR 0x08
#define SCOOP_CPR 0x0c
#define SCOOP_CCR 0x10
#define SCOOP_IRR_IRM 0x14
#define SCOOP_IMR 0x18
#define SCOOP_ISR 0x1c
#define SCOOP_GPCR 0x20
#define SCOOP_GPWR 0x24
#define SCOOP_GPRR 0x28
static inline void scoop_gpio_handler_update(ScoopInfo *s) {
static inline void scoop_gpio_handler_update(ScoopInfo *s)
{
uint32_t level, diff;
int bit;
level = s->gpio_level & s->gpio_dir;
@ -125,8 +126,9 @@ static void scoop_write(void *opaque, hwaddr addr,
break;
case SCOOP_CPR:
s->power = value;
if (value & 0x80)
if (value & 0x80) {
s->power |= 0x8040;
}
break;
case SCOOP_CCR:
s->ccr = value;
@ -145,7 +147,7 @@ static void scoop_write(void *opaque, hwaddr addr,
scoop_gpio_handler_update(s);
break;
case SCOOP_GPWR:
case SCOOP_GPRR: /* GPRR is probably R/O in real HW */
case SCOOP_GPRR: /* GPRR is probably R/O in real HW */
s->gpio_level = value & s->gpio_dir;
scoop_gpio_handler_update(s);
break;
@ -166,10 +168,11 @@ static void scoop_gpio_set(void *opaque, int line, int level)
{
ScoopInfo *s = (ScoopInfo *) opaque;
if (level)
if (level) {
s->gpio_level |= (1 << line);
else
} else {
s->gpio_level &= ~(1 << line);
}
}
static void scoop_init(Object *obj)
@ -203,7 +206,7 @@ static int scoop_post_load(void *opaque, int version_id)
return 0;
}
static bool is_version_0 (void *opaque, int version_id)
static bool is_version_0(void *opaque, int version_id)
{
return version_id == 0;
}
@ -265,7 +268,7 @@ type_init(scoop_register_types)
/* Write the bootloader parameters memory area. */
#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a)
#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a)
static struct QEMU_PACKED sl_param_info {
uint32_t comadj_keyword;
@ -286,16 +289,16 @@ static struct QEMU_PACKED sl_param_info {
uint32_t phad_keyword;
int32_t phadadj;
} zaurus_bootparam = {
.comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'),
.comadj = 125,
.uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'),
.uuid = { -1 },
.touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'),
.touch_xp = -1,
.adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'),
.adadj = -1,
.phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'),
.phadadj = 0x01,
.comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'),
.comadj = 125,
.uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'),
.uuid = { -1 },
.touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'),
.touch_xp = -1,
.adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'),
.adadj = -1,
.phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'),
.phadadj = 0x01,
};
void sl_bootparam_write(hwaddr ptr)

View File

@ -28,10 +28,10 @@
#include "migration/vmstate.h"
#include "trace.h"
#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10)))
#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10)))
typedef struct {
qemu_irq pint; /* Combination of the nPENIRQ and DAV signals */
qemu_irq pint; /* Combination of the nPENIRQ and DAV signals */
QEMUTimer *timer;
uint16_t model;
@ -63,7 +63,7 @@ typedef struct {
} TSC2005State;
enum {
TSC_MODE_XYZ_SCAN = 0x0,
TSC_MODE_XYZ_SCAN = 0x0,
TSC_MODE_XY_SCAN,
TSC_MODE_X,
TSC_MODE_Y,
@ -82,100 +82,100 @@ enum {
};
static const uint16_t mode_regs[16] = {
0xf000, /* X, Y, Z scan */
0xc000, /* X, Y scan */
0x8000, /* X */
0x4000, /* Y */
0x3000, /* Z */
0x0800, /* AUX */
0x0400, /* TEMP1 */
0x0200, /* TEMP2 */
0x0800, /* AUX scan */
0x0040, /* X test */
0x0020, /* Y test */
0x0080, /* Short-circuit test */
0x0000, /* Reserved */
0x0000, /* X+, X- drivers */
0x0000, /* Y+, Y- drivers */
0x0000, /* Y+, X- drivers */
0xf000, /* X, Y, Z scan */
0xc000, /* X, Y scan */
0x8000, /* X */
0x4000, /* Y */
0x3000, /* Z */
0x0800, /* AUX */
0x0400, /* TEMP1 */
0x0200, /* TEMP2 */
0x0800, /* AUX scan */
0x0040, /* X test */
0x0020, /* Y test */
0x0080, /* Short-circuit test */
0x0000, /* Reserved */
0x0000, /* X+, X- drivers */
0x0000, /* Y+, Y- drivers */
0x0000, /* Y+, X- drivers */
};
#define X_TRANSFORM(s) \
#define X_TRANSFORM(s) \
((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
#define Y_TRANSFORM(s) \
#define Y_TRANSFORM(s) \
((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
#define Z1_TRANSFORM(s) \
#define Z1_TRANSFORM(s) \
((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
#define Z2_TRANSFORM(s) \
#define Z2_TRANSFORM(s) \
((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
#define AUX_VAL (700 << 4) /* +/- 3 at 12-bit */
#define TEMP1_VAL (1264 << 4) /* +/- 5 at 12-bit */
#define TEMP2_VAL (1531 << 4) /* +/- 5 at 12-bit */
#define AUX_VAL (700 << 4) /* +/- 3 at 12-bit */
#define TEMP1_VAL (1264 << 4) /* +/- 5 at 12-bit */
#define TEMP2_VAL (1531 << 4) /* +/- 5 at 12-bit */
static uint16_t tsc2005_read(TSC2005State *s, int reg)
{
uint16_t ret;
switch (reg) {
case 0x0: /* X */
case 0x0: /* X */
s->dav &= ~mode_regs[TSC_MODE_X];
return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
(s->noise & 3);
case 0x1: /* Y */
case 0x1: /* Y */
s->dav &= ~mode_regs[TSC_MODE_Y];
s->noise ++;
s->noise++;
return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
(s->noise & 3);
case 0x2: /* Z1 */
case 0x2: /* Z1 */
s->dav &= 0xdfff;
return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
(s->noise & 3);
case 0x3: /* Z2 */
case 0x3: /* Z2 */
s->dav &= 0xefff;
return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
(s->noise & 3);
case 0x4: /* AUX */
case 0x4: /* AUX */
s->dav &= ~mode_regs[TSC_MODE_AUX];
return TSC_CUT_RESOLUTION(AUX_VAL, s->precision);
case 0x5: /* TEMP1 */
case 0x5: /* TEMP1 */
s->dav &= ~mode_regs[TSC_MODE_TEMP1];
return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
(s->noise & 5);
case 0x6: /* TEMP2 */
case 0x6: /* TEMP2 */
s->dav &= 0xdfff;
s->dav &= ~mode_regs[TSC_MODE_TEMP2];
return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
(s->noise & 3);
case 0x7: /* Status */
case 0x7: /* Status */
ret = s->dav | (s->reset << 7) | (s->pdst << 2) | 0x0;
s->dav &= ~(mode_regs[TSC_MODE_X_TEST] | mode_regs[TSC_MODE_Y_TEST] |
mode_regs[TSC_MODE_TS_TEST]);
s->reset = true;
return ret;
case 0x8: /* AUX high threshold */
case 0x8: /* AUX high threshold */
return s->aux_thr[1];
case 0x9: /* AUX low threshold */
case 0x9: /* AUX low threshold */
return s->aux_thr[0];
case 0xa: /* TEMP high threshold */
case 0xa: /* TEMP high threshold */
return s->temp_thr[1];
case 0xb: /* TEMP low threshold */
case 0xb: /* TEMP low threshold */
return s->temp_thr[0];
case 0xc: /* CFR0 */
case 0xc: /* CFR0 */
return (s->pressure << 15) | ((!s->busy) << 14) |
(s->nextprecision << 13) | s->timing[0];
case 0xd: /* CFR1 */
(s->nextprecision << 13) | s->timing[0];
case 0xd: /* CFR1 */
return s->timing[1];
case 0xe: /* CFR2 */
case 0xe: /* CFR2 */
return (s->pin_func << 14) | s->filter;
case 0xf: /* Function select status */
case 0xf: /* Function select status */
return s->function >= 0 ? 1 << s->function : 0;
}
@ -200,13 +200,14 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
s->temp_thr[0] = data;
break;
case 0xc: /* CFR0 */
case 0xc: /* CFR0 */
s->host_mode = (data >> 15) != 0;
if (s->enabled != !(data & 0x4000)) {
s->enabled = !(data & 0x4000);
trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
if (s->busy && !s->enabled)
if (s->busy && !s->enabled) {
timer_del(s->timer);
}
s->busy = s->busy && s->enabled;
}
s->nextprecision = (data >> 13) & 1;
@ -216,10 +217,10 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
"tsc2005_write: illegal conversion clock setting\n");
}
break;
case 0xd: /* CFR1 */
case 0xd: /* CFR1 */
s->timing[1] = data & 0xf07;
break;
case 0xe: /* CFR2 */
case 0xe: /* CFR2 */
s->pin_func = (data >> 14) & 3;
s->filter = data & 0x3fff;
break;
@ -258,10 +259,12 @@ static void tsc2005_pin_update(TSC2005State *s)
switch (s->nextfunction) {
case TSC_MODE_XYZ_SCAN:
case TSC_MODE_XY_SCAN:
if (!s->host_mode && s->dav)
if (!s->host_mode && s->dav) {
s->enabled = false;
if (!s->pressure)
}
if (!s->pressure) {
return;
}
/* Fall through */
case TSC_MODE_AUX_SCAN:
break;
@ -269,8 +272,9 @@ static void tsc2005_pin_update(TSC2005State *s)
case TSC_MODE_X:
case TSC_MODE_Y:
case TSC_MODE_Z:
if (!s->pressure)
if (!s->pressure) {
return;
}
/* Fall through */
case TSC_MODE_AUX:
case TSC_MODE_TEMP1:
@ -278,8 +282,9 @@ static void tsc2005_pin_update(TSC2005State *s)
case TSC_MODE_X_TEST:
case TSC_MODE_Y_TEST:
case TSC_MODE_TS_TEST:
if (s->dav)
if (s->dav) {
s->enabled = false;
}
break;
case TSC_MODE_RESERVED:
@ -290,13 +295,14 @@ static void tsc2005_pin_update(TSC2005State *s)
return;
}
if (!s->enabled || s->busy)
if (!s->enabled || s->busy) {
return;
}
s->busy = true;
s->precision = s->nextprecision;
s->function = s->nextfunction;
s->pdst = !s->pnd0; /* Synchronised on internal clock */
s->pdst = !s->pnd0; /* Synchronised on internal clock */
expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(NANOSECONDS_PER_SECOND >> 7);
timer_mod(s->timer, expires);
@ -331,7 +337,7 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
TSC2005State *s = opaque;
uint32_t ret = 0;
switch (s->state ++) {
switch (s->state++) {
case 0:
if (value & 0x80) {
/* Command */
@ -343,8 +349,9 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
if (s->enabled != !(value & 1)) {
s->enabled = !(value & 1);
trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
if (s->busy && !s->enabled)
if (s->busy && !s->enabled) {
timer_del(s->timer);
}
s->busy = s->busy && s->enabled;
}
tsc2005_pin_update(s);
@ -368,10 +375,11 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
break;
case 1:
if (s->command)
if (s->command) {
ret = (s->data >> 8) & 0xff;
else
} else {
s->data |= value << 8;
}
break;
case 2:
@ -406,14 +414,18 @@ uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len)
static void tsc2005_timer_tick(void *opaque)
{
TSC2005State *s = opaque;
unsigned int function = s->function;
assert(function < ARRAY_SIZE(mode_regs));
/* Timer ticked -- a set of conversions has been finished. */
if (!s->busy)
if (!s->busy) {
return;
}
s->busy = false;
s->dav |= mode_regs[s->function];
s->dav |= mode_regs[function];
s->function = -1;
tsc2005_pin_update(s);
}
@ -435,8 +447,9 @@ static void tsc2005_touchscreen_event(void *opaque,
* signaling TS events immediately, but for now we simulate
* the first conversion delay for sake of correctness.
*/
if (p != s->pressure)
if (p != s->pressure) {
tsc2005_pin_update(s);
}
}
static int tsc2005_post_load(void *opaque, int version_id)

View File

@ -1658,7 +1658,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
*data = s->h_apr[gic_get_vcpu_real_id(cpu)];
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
*data = gic_apr_ns_view(s, regno, cpu);
*data = gic_apr_ns_view(s, cpu, regno);
} else {
*data = s->apr[regno][cpu];
}
@ -1746,7 +1746,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
s->h_apr[gic_get_vcpu_real_id(cpu)] = value;
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
gic_apr_write_ns_view(s, regno, cpu, value);
gic_apr_write_ns_view(s, cpu, regno, value);
} else {
s->apr[regno][cpu] = value;
}

View File

@ -132,12 +132,6 @@ DEF_HELPER_3(vfp_maxnumd, f64, f64, f64, ptr)
DEF_HELPER_3(vfp_minnumh, f16, f16, f16, ptr)
DEF_HELPER_3(vfp_minnums, f32, f32, f32, ptr)
DEF_HELPER_3(vfp_minnumd, f64, f64, f64, ptr)
DEF_HELPER_1(vfp_negh, f16, f16)
DEF_HELPER_1(vfp_negs, f32, f32)
DEF_HELPER_1(vfp_negd, f64, f64)
DEF_HELPER_1(vfp_absh, f16, f16)
DEF_HELPER_1(vfp_abss, f32, f32)
DEF_HELPER_1(vfp_absd, f64, f64)
DEF_HELPER_2(vfp_sqrth, f16, f16, env)
DEF_HELPER_2(vfp_sqrts, f32, f32, env)
DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
@ -360,8 +354,6 @@ DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64)
DEF_HELPER_2(neon_add_u8, i32, i32, i32)
DEF_HELPER_2(neon_add_u16, i32, i32, i32)
DEF_HELPER_2(neon_padd_u8, i32, i32, i32)
DEF_HELPER_2(neon_padd_u16, i32, i32, i32)
DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
@ -656,13 +648,6 @@ DEF_HELPER_FLAGS_6(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_6(gvec_fcmlad, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_paddh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_pmaxh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_pminh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_padds, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_pmaxs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(neon_pmins, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sstoh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sitos, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_ustoh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
@ -730,33 +715,43 @@ DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fceq_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fceq_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fceq_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcge_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcge_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcge_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcgt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcgt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fcgt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facge_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facge_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facge_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facgt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facgt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_facgt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmax_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmax_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmax_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmin_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmin_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmin_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnum_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnum_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnum_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnum_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnum_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnum_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_recps_nf_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_recps_nf_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
@ -772,9 +767,11 @@ DEF_HELPER_FLAGS_5(gvec_fmls_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfma_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfma_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfma_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfms_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfms_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_vfms_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
@ -1042,6 +1039,47 @@ DEF_HELPER_FLAGS_5(gvec_uclamp_s, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_faddp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_faddp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_faddp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnump_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnump_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmaxnump_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnump_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnump_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fminnump_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_addp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_addp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_addp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_addp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smaxp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sminp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umaxp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uminp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
#ifdef TARGET_AARCH64
#include "tcg/helper-a64.h"
#include "tcg/helper-sve.h"

View File

@ -396,85 +396,85 @@ struct hvf_sreg_match {
};
static struct hvf_sreg_match hvf_sreg_match[] = {
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 7) },
#ifdef SYNC_NO_RAW_REGS
/*
@ -486,7 +486,7 @@ static struct hvf_sreg_match hvf_sreg_match[] = {
{ HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
{ HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
#endif
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) },
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 1) },
{ HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
{ HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
{ HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },

View File

@ -19,11 +19,53 @@
# This file is processed by scripts/decodetree.py
#
&r rn
&ri rd imm
&rri_sf rd rn imm sf
&i imm
%rd 0:5
%esz_sd 22:1 !function=plus_2
%esz_hsd 22:2 !function=xor_2
%hl 11:1 21:1
%hlm 11:1 20:2
&r rn
&ri rd imm
&rri_sf rd rn imm sf
&i imm
&rr_e rd rn esz
&rrr_e rd rn rm esz
&rrx_e rd rn rm idx esz
&qrr_e q rd rn esz
&qrrr_e q rd rn rm esz
&qrrx_e q rd rn rm idx esz
&qrrrr_e q rd rn rm ra esz
@rr_h ........ ... ..... ...... rn:5 rd:5 &rr_e esz=1
@rr_d ........ ... ..... ...... rn:5 rd:5 &rr_e esz=3
@rr_sd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_sd
@rrr_h ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=1
@rrr_sd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_sd
@rrr_hsd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_hsd
@rrx_h ........ .. .. rm:4 .... . . rn:5 rd:5 &rrx_e esz=1 idx=%hlm
@rrx_s ........ .. . rm:5 .... . . rn:5 rd:5 &rrx_e esz=2 idx=%hl
@rrx_d ........ .. . rm:5 .... idx:1 . rn:5 rd:5 &rrx_e esz=3
@rr_q1e0 ........ ........ ...... rn:5 rd:5 &qrr_e q=1 esz=0
@r2r_q1e0 ........ ........ ...... rm:5 rd:5 &qrrr_e rn=%rd q=1 esz=0
@rrr_q1e0 ........ ... rm:5 ...... rn:5 rd:5 &qrrr_e q=1 esz=0
@rrr_q1e3 ........ ... rm:5 ...... rn:5 rd:5 &qrrr_e q=1 esz=3
@rrrr_q1e3 ........ ... rm:5 . ra:5 rn:5 rd:5 &qrrrr_e q=1 esz=3
@qrrr_b . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=0
@qrrr_h . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=1
@qrrr_sd . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=%esz_sd
@qrrr_e . q:1 ...... esz:2 . rm:5 ...... rn:5 rd:5 &qrrr_e
@qrrx_h . q:1 .. .... .. .. rm:4 .... . . rn:5 rd:5 \
&qrrx_e esz=1 idx=%hlm
@qrrx_s . q:1 .. .... .. . rm:5 .... . . rn:5 rd:5 \
&qrrx_e esz=2 idx=%hl
@qrrx_d . q:1 .. .... .. . rm:5 .... idx:1 . rn:5 rd:5 \
&qrrx_e esz=3
### Data Processing - Immediate
@ -590,3 +632,268 @@ CPYFE 00 011 0 01100 ..... .... 01 ..... ..... @cpy
CPYP 00 011 1 01000 ..... .... 01 ..... ..... @cpy
CPYM 00 011 1 01010 ..... .... 01 ..... ..... @cpy
CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy
### Cryptographic AES
AESE 01001110 00 10100 00100 10 ..... ..... @r2r_q1e0
AESD 01001110 00 10100 00101 10 ..... ..... @r2r_q1e0
AESMC 01001110 00 10100 00110 10 ..... ..... @rr_q1e0
AESIMC 01001110 00 10100 00111 10 ..... ..... @rr_q1e0
### Cryptographic three-register SHA
SHA1C 0101 1110 000 ..... 000000 ..... ..... @rrr_q1e0
SHA1P 0101 1110 000 ..... 000100 ..... ..... @rrr_q1e0
SHA1M 0101 1110 000 ..... 001000 ..... ..... @rrr_q1e0
SHA1SU0 0101 1110 000 ..... 001100 ..... ..... @rrr_q1e0
SHA256H 0101 1110 000 ..... 010000 ..... ..... @rrr_q1e0
SHA256H2 0101 1110 000 ..... 010100 ..... ..... @rrr_q1e0
SHA256SU1 0101 1110 000 ..... 011000 ..... ..... @rrr_q1e0
### Cryptographic two-register SHA
SHA1H 0101 1110 0010 1000 0000 10 ..... ..... @rr_q1e0
SHA1SU1 0101 1110 0010 1000 0001 10 ..... ..... @rr_q1e0
SHA256SU0 0101 1110 0010 1000 0010 10 ..... ..... @rr_q1e0
### Cryptographic three-register SHA512
SHA512H 1100 1110 011 ..... 100000 ..... ..... @rrr_q1e0
SHA512H2 1100 1110 011 ..... 100001 ..... ..... @rrr_q1e0
SHA512SU1 1100 1110 011 ..... 100010 ..... ..... @rrr_q1e0
RAX1 1100 1110 011 ..... 100011 ..... ..... @rrr_q1e3
SM3PARTW1 1100 1110 011 ..... 110000 ..... ..... @rrr_q1e0
SM3PARTW2 1100 1110 011 ..... 110001 ..... ..... @rrr_q1e0
SM4EKEY 1100 1110 011 ..... 110010 ..... ..... @rrr_q1e0
### Cryptographic two-register SHA512
SHA512SU0 1100 1110 110 00000 100000 ..... ..... @rr_q1e0
SM4E 1100 1110 110 00000 100001 ..... ..... @r2r_q1e0
### Cryptographic four-register
EOR3 1100 1110 000 ..... 0 ..... ..... ..... @rrrr_q1e3
BCAX 1100 1110 001 ..... 0 ..... ..... ..... @rrrr_q1e3
SM3SS1 1100 1110 010 ..... 0 ..... ..... ..... @rrrr_q1e3
### Cryptographic three-register, imm2
&crypto3i rd rn rm imm
@crypto3i ........ ... rm:5 .. imm:2 .. rn:5 rd:5 &crypto3i
SM3TT1A 11001110 010 ..... 10 .. 00 ..... ..... @crypto3i
SM3TT1B 11001110 010 ..... 10 .. 01 ..... ..... @crypto3i
SM3TT2A 11001110 010 ..... 10 .. 10 ..... ..... @crypto3i
SM3TT2B 11001110 010 ..... 10 .. 11 ..... ..... @crypto3i
### Cryptographic XAR
XAR 1100 1110 100 rm:5 imm:6 rn:5 rd:5
### Advanced SIMD scalar copy
DUP_element_s 0101 1110 000 imm:5 0 0000 1 rn:5 rd:5
### Advanced SIMD copy
DUP_element_v 0 q:1 00 1110 000 imm:5 0 0000 1 rn:5 rd:5
DUP_general 0 q:1 00 1110 000 imm:5 0 0001 1 rn:5 rd:5
INS_general 0 1 00 1110 000 imm:5 0 0011 1 rn:5 rd:5
SMOV 0 q:1 00 1110 000 imm:5 0 0101 1 rn:5 rd:5
UMOV 0 q:1 00 1110 000 imm:5 0 0111 1 rn:5 rd:5
INS_element 0 1 10 1110 000 di:5 0 si:4 1 rn:5 rd:5
### Advanced SIMD scalar three same
FADD_s 0001 1110 ..1 ..... 0010 10 ..... ..... @rrr_hsd
FSUB_s 0001 1110 ..1 ..... 0011 10 ..... ..... @rrr_hsd
FDIV_s 0001 1110 ..1 ..... 0001 10 ..... ..... @rrr_hsd
FMUL_s 0001 1110 ..1 ..... 0000 10 ..... ..... @rrr_hsd
FNMUL_s 0001 1110 ..1 ..... 1000 10 ..... ..... @rrr_hsd
FMAX_s 0001 1110 ..1 ..... 0100 10 ..... ..... @rrr_hsd
FMIN_s 0001 1110 ..1 ..... 0101 10 ..... ..... @rrr_hsd
FMAXNM_s 0001 1110 ..1 ..... 0110 10 ..... ..... @rrr_hsd
FMINNM_s 0001 1110 ..1 ..... 0111 10 ..... ..... @rrr_hsd
FMULX_s 0101 1110 010 ..... 00011 1 ..... ..... @rrr_h
FMULX_s 0101 1110 0.1 ..... 11011 1 ..... ..... @rrr_sd
FCMEQ_s 0101 1110 010 ..... 00100 1 ..... ..... @rrr_h
FCMEQ_s 0101 1110 0.1 ..... 11100 1 ..... ..... @rrr_sd
FCMGE_s 0111 1110 010 ..... 00100 1 ..... ..... @rrr_h
FCMGE_s 0111 1110 0.1 ..... 11100 1 ..... ..... @rrr_sd
FCMGT_s 0111 1110 110 ..... 00100 1 ..... ..... @rrr_h
FCMGT_s 0111 1110 1.1 ..... 11100 1 ..... ..... @rrr_sd
FACGE_s 0111 1110 010 ..... 00101 1 ..... ..... @rrr_h
FACGE_s 0111 1110 0.1 ..... 11101 1 ..... ..... @rrr_sd
FACGT_s 0111 1110 110 ..... 00101 1 ..... ..... @rrr_h
FACGT_s 0111 1110 1.1 ..... 11101 1 ..... ..... @rrr_sd
FABD_s 0111 1110 110 ..... 00010 1 ..... ..... @rrr_h
FABD_s 0111 1110 1.1 ..... 11010 1 ..... ..... @rrr_sd
FRECPS_s 0101 1110 010 ..... 00111 1 ..... ..... @rrr_h
FRECPS_s 0101 1110 0.1 ..... 11111 1 ..... ..... @rrr_sd
FRSQRTS_s 0101 1110 110 ..... 00111 1 ..... ..... @rrr_h
FRSQRTS_s 0101 1110 1.1 ..... 11111 1 ..... ..... @rrr_sd
### Advanced SIMD scalar pairwise
FADDP_s 0101 1110 0011 0000 1101 10 ..... ..... @rr_h
FADDP_s 0111 1110 0.11 0000 1101 10 ..... ..... @rr_sd
FMAXP_s 0101 1110 0011 0000 1111 10 ..... ..... @rr_h
FMAXP_s 0111 1110 0.11 0000 1111 10 ..... ..... @rr_sd
FMINP_s 0101 1110 1011 0000 1111 10 ..... ..... @rr_h
FMINP_s 0111 1110 1.11 0000 1111 10 ..... ..... @rr_sd
FMAXNMP_s 0101 1110 0011 0000 1100 10 ..... ..... @rr_h
FMAXNMP_s 0111 1110 0.11 0000 1100 10 ..... ..... @rr_sd
FMINNMP_s 0101 1110 1011 0000 1100 10 ..... ..... @rr_h
FMINNMP_s 0111 1110 1.11 0000 1100 10 ..... ..... @rr_sd
ADDP_s 0101 1110 1111 0001 1011 10 ..... ..... @rr_d
### Advanced SIMD three same
FADD_v 0.00 1110 010 ..... 00010 1 ..... ..... @qrrr_h
FADD_v 0.00 1110 0.1 ..... 11010 1 ..... ..... @qrrr_sd
FSUB_v 0.00 1110 110 ..... 00010 1 ..... ..... @qrrr_h
FSUB_v 0.00 1110 1.1 ..... 11010 1 ..... ..... @qrrr_sd
FDIV_v 0.10 1110 010 ..... 00111 1 ..... ..... @qrrr_h
FDIV_v 0.10 1110 0.1 ..... 11111 1 ..... ..... @qrrr_sd
FMUL_v 0.10 1110 010 ..... 00011 1 ..... ..... @qrrr_h
FMUL_v 0.10 1110 0.1 ..... 11011 1 ..... ..... @qrrr_sd
FMAX_v 0.00 1110 010 ..... 00110 1 ..... ..... @qrrr_h
FMAX_v 0.00 1110 0.1 ..... 11110 1 ..... ..... @qrrr_sd
FMIN_v 0.00 1110 110 ..... 00110 1 ..... ..... @qrrr_h
FMIN_v 0.00 1110 1.1 ..... 11110 1 ..... ..... @qrrr_sd
FMAXNM_v 0.00 1110 010 ..... 00000 1 ..... ..... @qrrr_h
FMAXNM_v 0.00 1110 0.1 ..... 11000 1 ..... ..... @qrrr_sd
FMINNM_v 0.00 1110 110 ..... 00000 1 ..... ..... @qrrr_h
FMINNM_v 0.00 1110 1.1 ..... 11000 1 ..... ..... @qrrr_sd
FMULX_v 0.00 1110 010 ..... 00011 1 ..... ..... @qrrr_h
FMULX_v 0.00 1110 0.1 ..... 11011 1 ..... ..... @qrrr_sd
FMLA_v 0.00 1110 010 ..... 00001 1 ..... ..... @qrrr_h
FMLA_v 0.00 1110 0.1 ..... 11001 1 ..... ..... @qrrr_sd
FMLS_v 0.00 1110 110 ..... 00001 1 ..... ..... @qrrr_h
FMLS_v 0.00 1110 1.1 ..... 11001 1 ..... ..... @qrrr_sd
FMLAL_v 0.00 1110 001 ..... 11101 1 ..... ..... @qrrr_h
FMLSL_v 0.00 1110 101 ..... 11101 1 ..... ..... @qrrr_h
FMLAL2_v 0.10 1110 001 ..... 11001 1 ..... ..... @qrrr_h
FMLSL2_v 0.10 1110 101 ..... 11001 1 ..... ..... @qrrr_h
FCMEQ_v 0.00 1110 010 ..... 00100 1 ..... ..... @qrrr_h
FCMEQ_v 0.00 1110 0.1 ..... 11100 1 ..... ..... @qrrr_sd
FCMGE_v 0.10 1110 010 ..... 00100 1 ..... ..... @qrrr_h
FCMGE_v 0.10 1110 0.1 ..... 11100 1 ..... ..... @qrrr_sd
FCMGT_v 0.10 1110 110 ..... 00100 1 ..... ..... @qrrr_h
FCMGT_v 0.10 1110 1.1 ..... 11100 1 ..... ..... @qrrr_sd
FACGE_v 0.10 1110 010 ..... 00101 1 ..... ..... @qrrr_h
FACGE_v 0.10 1110 0.1 ..... 11101 1 ..... ..... @qrrr_sd
FACGT_v 0.10 1110 110 ..... 00101 1 ..... ..... @qrrr_h
FACGT_v 0.10 1110 1.1 ..... 11101 1 ..... ..... @qrrr_sd
FABD_v 0.10 1110 110 ..... 00010 1 ..... ..... @qrrr_h
FABD_v 0.10 1110 1.1 ..... 11010 1 ..... ..... @qrrr_sd
FRECPS_v 0.00 1110 010 ..... 00111 1 ..... ..... @qrrr_h
FRECPS_v 0.00 1110 0.1 ..... 11111 1 ..... ..... @qrrr_sd
FRSQRTS_v 0.00 1110 110 ..... 00111 1 ..... ..... @qrrr_h
FRSQRTS_v 0.00 1110 1.1 ..... 11111 1 ..... ..... @qrrr_sd
FADDP_v 0.10 1110 010 ..... 00010 1 ..... ..... @qrrr_h
FADDP_v 0.10 1110 0.1 ..... 11010 1 ..... ..... @qrrr_sd
FMAXP_v 0.10 1110 010 ..... 00110 1 ..... ..... @qrrr_h
FMAXP_v 0.10 1110 0.1 ..... 11110 1 ..... ..... @qrrr_sd
FMINP_v 0.10 1110 110 ..... 00110 1 ..... ..... @qrrr_h
FMINP_v 0.10 1110 1.1 ..... 11110 1 ..... ..... @qrrr_sd
FMAXNMP_v 0.10 1110 010 ..... 00000 1 ..... ..... @qrrr_h
FMAXNMP_v 0.10 1110 0.1 ..... 11000 1 ..... ..... @qrrr_sd
FMINNMP_v 0.10 1110 110 ..... 00000 1 ..... ..... @qrrr_h
FMINNMP_v 0.10 1110 1.1 ..... 11000 1 ..... ..... @qrrr_sd
ADDP_v 0.00 1110 ..1 ..... 10111 1 ..... ..... @qrrr_e
SMAXP_v 0.00 1110 ..1 ..... 10100 1 ..... ..... @qrrr_e
SMINP_v 0.00 1110 ..1 ..... 10101 1 ..... ..... @qrrr_e
UMAXP_v 0.10 1110 ..1 ..... 10100 1 ..... ..... @qrrr_e
UMINP_v 0.10 1110 ..1 ..... 10101 1 ..... ..... @qrrr_e
AND_v 0.00 1110 001 ..... 00011 1 ..... ..... @qrrr_b
BIC_v 0.00 1110 011 ..... 00011 1 ..... ..... @qrrr_b
ORR_v 0.00 1110 101 ..... 00011 1 ..... ..... @qrrr_b
ORN_v 0.00 1110 111 ..... 00011 1 ..... ..... @qrrr_b
EOR_v 0.10 1110 001 ..... 00011 1 ..... ..... @qrrr_b
BSL_v 0.10 1110 011 ..... 00011 1 ..... ..... @qrrr_b
BIT_v 0.10 1110 101 ..... 00011 1 ..... ..... @qrrr_b
BIF_v 0.10 1110 111 ..... 00011 1 ..... ..... @qrrr_b
### Advanced SIMD scalar x indexed element
FMUL_si 0101 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
FMUL_si 0101 1111 10 . ..... 1001 . 0 ..... ..... @rrx_s
FMUL_si 0101 1111 11 0 ..... 1001 . 0 ..... ..... @rrx_d
FMLA_si 0101 1111 00 .. .... 0001 . 0 ..... ..... @rrx_h
FMLA_si 0101 1111 10 .. .... 0001 . 0 ..... ..... @rrx_s
FMLA_si 0101 1111 11 0. .... 0001 . 0 ..... ..... @rrx_d
FMLS_si 0101 1111 00 .. .... 0101 . 0 ..... ..... @rrx_h
FMLS_si 0101 1111 10 .. .... 0101 . 0 ..... ..... @rrx_s
FMLS_si 0101 1111 11 0. .... 0101 . 0 ..... ..... @rrx_d
FMULX_si 0111 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
FMULX_si 0111 1111 10 . ..... 1001 . 0 ..... ..... @rrx_s
FMULX_si 0111 1111 11 0 ..... 1001 . 0 ..... ..... @rrx_d
### Advanced SIMD vector x indexed element
FMUL_vi 0.00 1111 00 .. .... 1001 . 0 ..... ..... @qrrx_h
FMUL_vi 0.00 1111 10 . ..... 1001 . 0 ..... ..... @qrrx_s
FMUL_vi 0.00 1111 11 0 ..... 1001 . 0 ..... ..... @qrrx_d
FMLA_vi 0.00 1111 00 .. .... 0001 . 0 ..... ..... @qrrx_h
FMLA_vi 0.00 1111 10 . ..... 0001 . 0 ..... ..... @qrrx_s
FMLA_vi 0.00 1111 11 0 ..... 0001 . 0 ..... ..... @qrrx_d
FMLS_vi 0.00 1111 00 .. .... 0101 . 0 ..... ..... @qrrx_h
FMLS_vi 0.00 1111 10 . ..... 0101 . 0 ..... ..... @qrrx_s
FMLS_vi 0.00 1111 11 0 ..... 0101 . 0 ..... ..... @qrrx_d
FMULX_vi 0.10 1111 00 .. .... 1001 . 0 ..... ..... @qrrx_h
FMULX_vi 0.10 1111 10 . ..... 1001 . 0 ..... ..... @qrrx_s
FMULX_vi 0.10 1111 11 0 ..... 1001 . 0 ..... ..... @qrrx_d
FMLAL_vi 0.00 1111 10 .. .... 0000 . 0 ..... ..... @qrrx_h
FMLSL_vi 0.00 1111 10 .. .... 0100 . 0 ..... ..... @qrrx_h
FMLAL2_vi 0.10 1111 10 .. .... 1000 . 0 ..... ..... @qrrx_h
FMLSL2_vi 0.10 1111 10 .. .... 1100 . 0 ..... ..... @qrrx_h

1672
target/arm/tcg/gengvec.c Normal file

File diff suppressed because it is too large Load Diff

190
target/arm/tcg/gengvec64.c Normal file
View File

@ -0,0 +1,190 @@
/*
* AArch64 generic vector expansion
*
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "translate.h"
#include "translate-a64.h"
static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
{
tcg_gen_rotli_i64(d, m, 1);
tcg_gen_xor_i64(d, d, n);
}
static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m)
{
tcg_gen_rotli_vec(vece, d, m, 1);
tcg_gen_xor_vec(vece, d, d, n);
}
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
static const TCGOpcode vecop_list[] = { INDEX_op_rotli_vec, 0 };
static const GVecGen3 op = {
.fni8 = gen_rax1_i64,
.fniv = gen_rax1_vec,
.opt_opc = vecop_list,
.fno = gen_helper_crypto_rax1,
.vece = MO_64,
};
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &op);
}
static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
TCGv_i64 t = tcg_temp_new_i64();
uint64_t mask = dup_const(MO_8, 0xff >> sh);
tcg_gen_xor_i64(t, n, m);
tcg_gen_shri_i64(d, t, sh);
tcg_gen_shli_i64(t, t, 8 - sh);
tcg_gen_andi_i64(d, d, mask);
tcg_gen_andi_i64(t, t, ~mask);
tcg_gen_or_i64(d, d, t);
}
static void gen_xar16_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
TCGv_i64 t = tcg_temp_new_i64();
uint64_t mask = dup_const(MO_16, 0xffff >> sh);
tcg_gen_xor_i64(t, n, m);
tcg_gen_shri_i64(d, t, sh);
tcg_gen_shli_i64(t, t, 16 - sh);
tcg_gen_andi_i64(d, d, mask);
tcg_gen_andi_i64(t, t, ~mask);
tcg_gen_or_i64(d, d, t);
}
static void gen_xar_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, int32_t sh)
{
tcg_gen_xor_i32(d, n, m);
tcg_gen_rotri_i32(d, d, sh);
}
static void gen_xar_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
tcg_gen_xor_i64(d, n, m);
tcg_gen_rotri_i64(d, d, sh);
}
static void gen_xar_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, int64_t sh)
{
tcg_gen_xor_vec(vece, d, n, m);
tcg_gen_rotri_vec(vece, d, d, sh);
}
void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, int64_t shift,
uint32_t opr_sz, uint32_t max_sz)
{
static const TCGOpcode vecop[] = { INDEX_op_rotli_vec, 0 };
static const GVecGen3i ops[4] = {
{ .fni8 = gen_xar8_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_b,
.opt_opc = vecop,
.vece = MO_8 },
{ .fni8 = gen_xar16_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_h,
.opt_opc = vecop,
.vece = MO_16 },
{ .fni4 = gen_xar_i32,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_s,
.opt_opc = vecop,
.vece = MO_32 },
{ .fni8 = gen_xar_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_gvec_xar_d,
.opt_opc = vecop,
.vece = MO_64 }
};
int esize = 8 << vece;
/* The SVE2 range is 1 .. esize; the AdvSIMD range is 0 .. esize-1. */
tcg_debug_assert(shift >= 0);
tcg_debug_assert(shift <= esize);
shift &= esize - 1;
if (shift == 0) {
/* xar with no rotate devolves to xor. */
tcg_gen_gvec_xor(vece, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz);
} else {
tcg_gen_gvec_3i(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz,
shift, &ops[vece]);
}
}
static void gen_eor3_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
{
tcg_gen_xor_i64(d, n, m);
tcg_gen_xor_i64(d, d, k);
}
static void gen_eor3_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
tcg_gen_xor_vec(vece, d, n, m);
tcg_gen_xor_vec(vece, d, d, k);
}
void gen_gvec_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz)
{
static const GVecGen4 op = {
.fni8 = gen_eor3_i64,
.fniv = gen_eor3_vec,
.fno = gen_helper_sve2_eor3,
.vece = MO_64,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
};
tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
}
static void gen_bcax_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
{
tcg_gen_andc_i64(d, m, k);
tcg_gen_xor_i64(d, d, n);
}
static void gen_bcax_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
tcg_gen_andc_vec(vece, d, m, k);
tcg_gen_xor_vec(vece, d, d, n);
}
void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz)
{
static const GVecGen4 op = {
.fni8 = gen_bcax_i64,
.fniv = gen_bcax_vec,
.fno = gen_helper_sve2_bcax,
.vece = MO_64,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
};
tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
}

View File

@ -132,3 +132,15 @@ DEF_HELPER_4(cpye, void, env, i32, i32, i32)
DEF_HELPER_4(cpyfp, void, env, i32, i32, i32)
DEF_HELPER_4(cpyfm, void, env, i32, i32, i32)
DEF_HELPER_4(cpyfe, void, env, i32, i32, i32)
DEF_HELPER_FLAGS_5(gvec_fdiv_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fdiv_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fdiv_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(gvec_fmulx_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)

View File

@ -24,6 +24,7 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: gen_a64)
arm_ss.add(files(
'cpu32.c',
'gengvec.c',
'translate.c',
'translate-m-nocp.c',
'translate-mve.c',
@ -42,6 +43,7 @@ arm_ss.add(files(
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
'cpu64.c',
'gengvec64.c',
'translate-a64.c',
'translate-sve.c',
'translate-sme.c',

View File

@ -745,11 +745,6 @@ uint32_t HELPER(neon_add_u16)(uint32_t a, uint32_t b)
return (a + b) ^ mask;
}
#define NEON_FN(dest, src1, src2) dest = src1 + src2
NEON_POP(padd_u8, neon_u8, 4)
NEON_POP(padd_u16, neon_u16, 2)
#undef NEON_FN
#define NEON_FN(dest, src1, src2) dest = src1 - src2
NEON_VOP(sub_u8, neon_u8, 4)
NEON_VOP(sub_u16, neon_u16, 2)

View File

@ -458,41 +458,41 @@ STR_ri 1111 1000 1100 .... .... ............ @ldst_ri_pos
# Note that Load, unsigned (literal) overlaps all other load encodings.
{
{
NOP 1111 1000 -001 1111 1111 ------------ # PLD
PLD 1111 1000 -001 1111 1111 ------------ # (literal)
LDRB_ri 1111 1000 .001 1111 .... ............ @ldst_ri_lit
}
{
NOP 1111 1000 1001 ---- 1111 ------------ # PLD
PLD 1111 1000 1001 ---- 1111 ------------ # (immediate T1)
LDRB_ri 1111 1000 1001 .... .... ............ @ldst_ri_pos
}
LDRB_ri 1111 1000 0001 .... .... 1..1 ........ @ldst_ri_idx
{
NOP 1111 1000 0001 ---- 1111 1100 -------- # PLD
PLD 1111 1000 0001 ---- 1111 1100 -------- # (immediate T2)
LDRB_ri 1111 1000 0001 .... .... 1100 ........ @ldst_ri_neg
}
LDRBT_ri 1111 1000 0001 .... .... 1110 ........ @ldst_ri_unp
{
NOP 1111 1000 0001 ---- 1111 000000 -- ---- # PLD
PLD 1111 1000 0001 ---- 1111 000000 -- ---- # (register)
LDRB_rr 1111 1000 0001 .... .... 000000 .. .... @ldst_rr
}
}
{
{
NOP 1111 1000 -011 1111 1111 ------------ # PLD
PLD 1111 1000 -011 1111 1111 ------------ # (literal)
LDRH_ri 1111 1000 .011 1111 .... ............ @ldst_ri_lit
}
{
NOP 1111 1000 1011 ---- 1111 ------------ # PLDW
PLDW 1111 1000 1011 ---- 1111 ------------ # (immediate T1)
LDRH_ri 1111 1000 1011 .... .... ............ @ldst_ri_pos
}
LDRH_ri 1111 1000 0011 .... .... 1..1 ........ @ldst_ri_idx
{
NOP 1111 1000 0011 ---- 1111 1100 -------- # PLDW
PLDW 1111 1000 0011 ---- 1111 1100 -------- # (immediate T2)
LDRH_ri 1111 1000 0011 .... .... 1100 ........ @ldst_ri_neg
}
LDRHT_ri 1111 1000 0011 .... .... 1110 ........ @ldst_ri_unp
{
NOP 1111 1000 0011 ---- 1111 000000 -- ---- # PLDW
PLDW 1111 1000 0011 ---- 1111 000000 -- ---- # (register)
LDRH_rr 1111 1000 0011 .... .... 000000 .. .... @ldst_rr
}
}
@ -504,24 +504,23 @@ STR_ri 1111 1000 1100 .... .... ............ @ldst_ri_pos
LDRT_ri 1111 1000 0101 .... .... 1110 ........ @ldst_ri_unp
LDR_rr 1111 1000 0101 .... .... 000000 .. .... @ldst_rr
}
# NOPs here are PLI.
{
{
NOP 1111 1001 -001 1111 1111 ------------
PLI 1111 1001 -001 1111 1111 ------------ # (literal T3)
LDRSB_ri 1111 1001 .001 1111 .... ............ @ldst_ri_lit
}
{
NOP 1111 1001 1001 ---- 1111 ------------
PLI 1111 1001 1001 ---- 1111 ------------ # (immediate T1)
LDRSB_ri 1111 1001 1001 .... .... ............ @ldst_ri_pos
}
LDRSB_ri 1111 1001 0001 .... .... 1..1 ........ @ldst_ri_idx
{
NOP 1111 1001 0001 ---- 1111 1100 --------
PLI 1111 1001 0001 ---- 1111 1100 -------- # (immediate T2)
LDRSB_ri 1111 1001 0001 .... .... 1100 ........ @ldst_ri_neg
}
LDRSBT_ri 1111 1001 0001 .... .... 1110 ........ @ldst_ri_unp
{
NOP 1111 1001 0001 ---- 1111 000000 -- ----
PLI 1111 1001 0001 ---- 1111 000000 -- ---- # (register)
LDRSB_rr 1111 1001 0001 .... .... 000000 .. .... @ldst_rr
}
}

File diff suppressed because it is too large Load Diff

View File

@ -193,6 +193,10 @@ void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, int64_t shift,
uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);
void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);

View File

@ -830,6 +830,11 @@ DO_3SAME_NO_SZ_3(VABD_S, gen_gvec_sabd)
DO_3SAME_NO_SZ_3(VABA_S, gen_gvec_saba)
DO_3SAME_NO_SZ_3(VABD_U, gen_gvec_uabd)
DO_3SAME_NO_SZ_3(VABA_U, gen_gvec_uaba)
DO_3SAME_NO_SZ_3(VPADD, gen_gvec_addp)
DO_3SAME_NO_SZ_3(VPMAX_S, gen_gvec_smaxp)
DO_3SAME_NO_SZ_3(VPMIN_S, gen_gvec_sminp)
DO_3SAME_NO_SZ_3(VPMAX_U, gen_gvec_umaxp)
DO_3SAME_NO_SZ_3(VPMIN_U, gen_gvec_uminp)
#define DO_3SAME_CMP(INSN, COND) \
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
@ -1002,82 +1007,6 @@ DO_3SAME_32_ENV(VQSHL_U, qshl_u)
DO_3SAME_32_ENV(VQRSHL_S, qrshl_s)
DO_3SAME_32_ENV(VQRSHL_U, qrshl_u)
static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
{
/* Operations handled pairwise 32 bits at a time */
TCGv_i32 tmp, tmp2, tmp3;
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
return false;
}
/* UNDEF accesses to D16-D31 if they don't exist. */
if (!dc_isar_feature(aa32_simd_r32, s) &&
((a->vd | a->vn | a->vm) & 0x10)) {
return false;
}
if (a->size == 3) {
return false;
}
if (!vfp_access_check(s)) {
return true;
}
assert(a->q == 0); /* enforced by decode patterns */
/*
* Note that we have to be careful not to clobber the source operands
* in the "vm == vd" case by storing the result of the first pass too
* early. Since Q is 0 there are always just two passes, so instead
* of a complicated loop over each pass we just unroll.
*/
tmp = tcg_temp_new_i32();
tmp2 = tcg_temp_new_i32();
tmp3 = tcg_temp_new_i32();
read_neon_element32(tmp, a->vn, 0, MO_32);
read_neon_element32(tmp2, a->vn, 1, MO_32);
fn(tmp, tmp, tmp2);
read_neon_element32(tmp3, a->vm, 0, MO_32);
read_neon_element32(tmp2, a->vm, 1, MO_32);
fn(tmp3, tmp3, tmp2);
write_neon_element32(tmp, a->vd, 0, MO_32);
write_neon_element32(tmp3, a->vd, 1, MO_32);
return true;
}
#define DO_3SAME_PAIR(INSN, func) \
static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
{ \
static NeonGenTwoOpFn * const fns[] = { \
gen_helper_neon_##func##8, \
gen_helper_neon_##func##16, \
gen_helper_neon_##func##32, \
}; \
if (a->size > 2) { \
return false; \
} \
return do_3same_pair(s, a, fns[a->size]); \
}
/* 32-bit pairwise ops end up the same as the elementwise versions. */
#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
#define gen_helper_neon_padd_u32 tcg_gen_add_i32
DO_3SAME_PAIR(VPMAX_S, pmax_s)
DO_3SAME_PAIR(VPMIN_S, pmin_s)
DO_3SAME_PAIR(VPMAX_U, pmax_u)
DO_3SAME_PAIR(VPMIN_U, pmin_u)
DO_3SAME_PAIR(VPADD, padd_u)
#define DO_3SAME_VQDMULH(INSN, FUNC) \
WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16); \
WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##_s32); \
@ -1144,6 +1073,9 @@ DO_3S_FP_GVEC(VFMA, gen_helper_gvec_vfma_s, gen_helper_gvec_vfma_h)
DO_3S_FP_GVEC(VFMS, gen_helper_gvec_vfms_s, gen_helper_gvec_vfms_h)
DO_3S_FP_GVEC(VRECPS, gen_helper_gvec_recps_nf_s, gen_helper_gvec_recps_nf_h)
DO_3S_FP_GVEC(VRSQRTS, gen_helper_gvec_rsqrts_nf_s, gen_helper_gvec_rsqrts_nf_h)
DO_3S_FP_GVEC(VPADD, gen_helper_gvec_faddp_s, gen_helper_gvec_faddp_h)
DO_3S_FP_GVEC(VPMAX, gen_helper_gvec_fmaxp_s, gen_helper_gvec_fmaxp_h)
DO_3S_FP_GVEC(VPMIN, gen_helper_gvec_fminp_s, gen_helper_gvec_fminp_h)
WRAP_FP_GVEC(gen_VMAXNM_fp32_3s, FPST_STD, gen_helper_gvec_fmaxnum_s)
WRAP_FP_GVEC(gen_VMAXNM_fp16_3s, FPST_STD_F16, gen_helper_gvec_fmaxnum_h)
@ -1180,58 +1112,6 @@ static bool trans_VMINNM_fp_3s(DisasContext *s, arg_3same *a)
return do_3same(s, a, gen_VMINNM_fp32_3s);
}
static bool do_3same_fp_pair(DisasContext *s, arg_3same *a,
gen_helper_gvec_3_ptr *fn)
{
/* FP pairwise operations */
TCGv_ptr fpstatus;
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
return false;
}
/* UNDEF accesses to D16-D31 if they don't exist. */
if (!dc_isar_feature(aa32_simd_r32, s) &&
((a->vd | a->vn | a->vm) & 0x10)) {
return false;
}
if (!vfp_access_check(s)) {
return true;
}
assert(a->q == 0); /* enforced by decode patterns */
fpstatus = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD);
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
vfp_reg_offset(1, a->vn),
vfp_reg_offset(1, a->vm),
fpstatus, 8, 8, 0, fn);
return true;
}
/*
* For all the functions using this macro, size == 1 means fp16,
* which is an architecture extension we don't implement yet.
*/
#define DO_3S_FP_PAIR(INSN,FUNC) \
static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
{ \
if (a->size == MO_16) { \
if (!dc_isar_feature(aa32_fp16_arith, s)) { \
return false; \
} \
return do_3same_fp_pair(s, a, FUNC##h); \
} \
return do_3same_fp_pair(s, a, FUNC##s); \
}
DO_3S_FP_PAIR(VPADD, gen_helper_neon_padd)
DO_3S_FP_PAIR(VPMAX, gen_helper_neon_pmax)
DO_3S_FP_PAIR(VPMIN, gen_helper_neon_pmin)
static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
{
/* Handle a 2-reg-shift insn which can be vectorized. */

View File

@ -527,94 +527,6 @@ TRANS_FEAT(ORR_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_or, a)
TRANS_FEAT(EOR_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_xor, a)
TRANS_FEAT(BIC_zzz, aa64_sve, gen_gvec_fn_arg_zzz, tcg_gen_gvec_andc, a)
static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
TCGv_i64 t = tcg_temp_new_i64();
uint64_t mask = dup_const(MO_8, 0xff >> sh);
tcg_gen_xor_i64(t, n, m);
tcg_gen_shri_i64(d, t, sh);
tcg_gen_shli_i64(t, t, 8 - sh);
tcg_gen_andi_i64(d, d, mask);
tcg_gen_andi_i64(t, t, ~mask);
tcg_gen_or_i64(d, d, t);
}
static void gen_xar16_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
TCGv_i64 t = tcg_temp_new_i64();
uint64_t mask = dup_const(MO_16, 0xffff >> sh);
tcg_gen_xor_i64(t, n, m);
tcg_gen_shri_i64(d, t, sh);
tcg_gen_shli_i64(t, t, 16 - sh);
tcg_gen_andi_i64(d, d, mask);
tcg_gen_andi_i64(t, t, ~mask);
tcg_gen_or_i64(d, d, t);
}
static void gen_xar_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, int32_t sh)
{
tcg_gen_xor_i32(d, n, m);
tcg_gen_rotri_i32(d, d, sh);
}
static void gen_xar_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
{
tcg_gen_xor_i64(d, n, m);
tcg_gen_rotri_i64(d, d, sh);
}
static void gen_xar_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, int64_t sh)
{
tcg_gen_xor_vec(vece, d, n, m);
tcg_gen_rotri_vec(vece, d, d, sh);
}
void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, int64_t shift,
uint32_t opr_sz, uint32_t max_sz)
{
static const TCGOpcode vecop[] = { INDEX_op_rotli_vec, 0 };
static const GVecGen3i ops[4] = {
{ .fni8 = gen_xar8_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_b,
.opt_opc = vecop,
.vece = MO_8 },
{ .fni8 = gen_xar16_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_h,
.opt_opc = vecop,
.vece = MO_16 },
{ .fni4 = gen_xar_i32,
.fniv = gen_xar_vec,
.fno = gen_helper_sve2_xar_s,
.opt_opc = vecop,
.vece = MO_32 },
{ .fni8 = gen_xar_i64,
.fniv = gen_xar_vec,
.fno = gen_helper_gvec_xar_d,
.opt_opc = vecop,
.vece = MO_64 }
};
int esize = 8 << vece;
/* The SVE2 range is 1 .. esize; the AdvSIMD range is 0 .. esize-1. */
tcg_debug_assert(shift >= 0);
tcg_debug_assert(shift <= esize);
shift &= esize - 1;
if (shift == 0) {
/* xar with no rotate devolves to xor. */
tcg_gen_gvec_xor(vece, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz);
} else {
tcg_gen_gvec_3i(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz,
shift, &ops[vece]);
}
}
static bool trans_XAR(DisasContext *s, arg_rrri_esz *a)
{
if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
@ -629,61 +541,8 @@ static bool trans_XAR(DisasContext *s, arg_rrri_esz *a)
return true;
}
static void gen_eor3_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
{
tcg_gen_xor_i64(d, n, m);
tcg_gen_xor_i64(d, d, k);
}
static void gen_eor3_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
tcg_gen_xor_vec(vece, d, n, m);
tcg_gen_xor_vec(vece, d, d, k);
}
static void gen_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz)
{
static const GVecGen4 op = {
.fni8 = gen_eor3_i64,
.fniv = gen_eor3_vec,
.fno = gen_helper_sve2_eor3,
.vece = MO_64,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
};
tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
}
TRANS_FEAT(EOR3, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_eor3, a)
static void gen_bcax_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
{
tcg_gen_andc_i64(d, m, k);
tcg_gen_xor_i64(d, d, n);
}
static void gen_bcax_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
tcg_gen_andc_vec(vece, d, m, k);
tcg_gen_xor_vec(vece, d, d, n);
}
static void gen_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz)
{
static const GVecGen4 op = {
.fni8 = gen_bcax_i64,
.fniv = gen_bcax_vec,
.fno = gen_helper_sve2_bcax,
.vece = MO_64,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
};
tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
}
TRANS_FEAT(BCAX, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_bcax, a)
TRANS_FEAT(EOR3, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_gvec_eor3, a)
TRANS_FEAT(BCAX, aa64_sve2, gen_gvec_fn_arg_zzzz, gen_gvec_bcax, a)
static void gen_bsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz)

View File

@ -48,6 +48,12 @@ static inline void vfp_store_reg32(TCGv_i32 var, int reg)
tcg_gen_st_i32(var, tcg_env, vfp_reg_offset(false, reg));
}
static inline void vfp_load_reg16(TCGv_i32 var, int reg)
{
tcg_gen_ld16u_i32(var, tcg_env,
vfp_reg_offset(false, reg) + HOST_BIG_ENDIAN * 2);
}
/*
* The imm8 encodes the sign bit, enough bits to represent an exponent in
* the range 01....1xx to 10....0xx, and the most significant 4 bits of
@ -902,8 +908,7 @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
if (a->l) {
/* VFP to general purpose register */
tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vn);
tcg_gen_andi_i32(tmp, tmp, 0xffff);
vfp_load_reg16(tmp, a->vn);
store_reg(s, a->rt, tmp);
} else {
/* general purpose register to VFP */
@ -1453,11 +1458,11 @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
fd = tcg_temp_new_i32();
fpst = fpstatus_ptr(FPST_FPCR_F16);
vfp_load_reg32(f0, vn);
vfp_load_reg32(f1, vm);
vfp_load_reg16(f0, vn);
vfp_load_reg16(f1, vm);
if (reads_vd) {
vfp_load_reg32(fd, vd);
vfp_load_reg16(fd, vd);
}
fn(fd, f0, f1, fpst);
vfp_store_reg32(fd, vd);
@ -1633,7 +1638,7 @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
}
f0 = tcg_temp_new_i32();
vfp_load_reg32(f0, vm);
vfp_load_reg16(f0, vm);
fn(f0, f0);
vfp_store_reg32(f0, vd);
@ -1763,7 +1768,7 @@ static void gen_VMLS_hp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_mulh(tmp, vn, vm, fpst);
gen_helper_vfp_negh(tmp, tmp);
gen_vfp_negh(tmp, tmp);
gen_helper_vfp_addh(vd, vd, tmp, fpst);
}
@ -1781,7 +1786,7 @@ static void gen_VMLS_sp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_muls(tmp, vn, vm, fpst);
gen_helper_vfp_negs(tmp, tmp);
gen_vfp_negs(tmp, tmp);
gen_helper_vfp_adds(vd, vd, tmp, fpst);
}
@ -1799,7 +1804,7 @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
TCGv_i64 tmp = tcg_temp_new_i64();
gen_helper_vfp_muld(tmp, vn, vm, fpst);
gen_helper_vfp_negd(tmp, tmp);
gen_vfp_negd(tmp, tmp);
gen_helper_vfp_addd(vd, vd, tmp, fpst);
}
@ -1819,7 +1824,7 @@ static void gen_VNMLS_hp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_mulh(tmp, vn, vm, fpst);
gen_helper_vfp_negh(vd, vd);
gen_vfp_negh(vd, vd);
gen_helper_vfp_addh(vd, vd, tmp, fpst);
}
@ -1839,7 +1844,7 @@ static void gen_VNMLS_sp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_muls(tmp, vn, vm, fpst);
gen_helper_vfp_negs(vd, vd);
gen_vfp_negs(vd, vd);
gen_helper_vfp_adds(vd, vd, tmp, fpst);
}
@ -1859,7 +1864,7 @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
TCGv_i64 tmp = tcg_temp_new_i64();
gen_helper_vfp_muld(tmp, vn, vm, fpst);
gen_helper_vfp_negd(vd, vd);
gen_vfp_negd(vd, vd);
gen_helper_vfp_addd(vd, vd, tmp, fpst);
}
@ -1874,8 +1879,8 @@ static void gen_VNMLA_hp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_mulh(tmp, vn, vm, fpst);
gen_helper_vfp_negh(tmp, tmp);
gen_helper_vfp_negh(vd, vd);
gen_vfp_negh(tmp, tmp);
gen_vfp_negh(vd, vd);
gen_helper_vfp_addh(vd, vd, tmp, fpst);
}
@ -1890,8 +1895,8 @@ static void gen_VNMLA_sp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_vfp_muls(tmp, vn, vm, fpst);
gen_helper_vfp_negs(tmp, tmp);
gen_helper_vfp_negs(vd, vd);
gen_vfp_negs(tmp, tmp);
gen_vfp_negs(vd, vd);
gen_helper_vfp_adds(vd, vd, tmp, fpst);
}
@ -1906,8 +1911,8 @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
TCGv_i64 tmp = tcg_temp_new_i64();
gen_helper_vfp_muld(tmp, vn, vm, fpst);
gen_helper_vfp_negd(tmp, tmp);
gen_helper_vfp_negd(vd, vd);
gen_vfp_negd(tmp, tmp);
gen_vfp_negd(vd, vd);
gen_helper_vfp_addd(vd, vd, tmp, fpst);
}
@ -1935,7 +1940,7 @@ static void gen_VNMUL_hp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
{
/* VNMUL: -(fn * fm) */
gen_helper_vfp_mulh(vd, vn, vm, fpst);
gen_helper_vfp_negh(vd, vd);
gen_vfp_negh(vd, vd);
}
static bool trans_VNMUL_hp(DisasContext *s, arg_VNMUL_sp *a)
@ -1947,7 +1952,7 @@ static void gen_VNMUL_sp(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm, TCGv_ptr fpst)
{
/* VNMUL: -(fn * fm) */
gen_helper_vfp_muls(vd, vn, vm, fpst);
gen_helper_vfp_negs(vd, vd);
gen_vfp_negs(vd, vd);
}
static bool trans_VNMUL_sp(DisasContext *s, arg_VNMUL_sp *a)
@ -1959,7 +1964,7 @@ static void gen_VNMUL_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
{
/* VNMUL: -(fn * fm) */
gen_helper_vfp_muld(vd, vn, vm, fpst);
gen_helper_vfp_negd(vd, vd);
gen_vfp_negd(vd, vd);
}
static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
@ -2106,16 +2111,16 @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
vm = tcg_temp_new_i32();
vd = tcg_temp_new_i32();
vfp_load_reg32(vn, a->vn);
vfp_load_reg32(vm, a->vm);
vfp_load_reg16(vn, a->vn);
vfp_load_reg16(vm, a->vm);
if (neg_n) {
/* VFNMS, VFMS */
gen_helper_vfp_negh(vn, vn);
gen_vfp_negh(vn, vn);
}
vfp_load_reg32(vd, a->vd);
vfp_load_reg16(vd, a->vd);
if (neg_d) {
/* VFNMA, VFNMS */
gen_helper_vfp_negh(vd, vd);
gen_vfp_negh(vd, vd);
}
fpst = fpstatus_ptr(FPST_FPCR_F16);
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
@ -2169,12 +2174,12 @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
vfp_load_reg32(vm, a->vm);
if (neg_n) {
/* VFNMS, VFMS */
gen_helper_vfp_negs(vn, vn);
gen_vfp_negs(vn, vn);
}
vfp_load_reg32(vd, a->vd);
if (neg_d) {
/* VFNMA, VFNMS */
gen_helper_vfp_negs(vd, vd);
gen_vfp_negs(vd, vd);
}
fpst = fpstatus_ptr(FPST_FPCR);
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
@ -2234,12 +2239,12 @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
vfp_load_reg64(vm, a->vm);
if (neg_n) {
/* VFNMS, VFMS */
gen_helper_vfp_negd(vn, vn);
gen_vfp_negd(vn, vn);
}
vfp_load_reg64(vd, a->vd);
if (neg_d) {
/* VFNMA, VFNMS */
gen_helper_vfp_negd(vd, vd);
gen_vfp_negd(vd, vd);
}
fpst = fpstatus_ptr(FPST_FPCR);
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
@ -2409,13 +2414,13 @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
DO_VFP_VMOV(VMOV_reg, sp, tcg_gen_mov_i32)
DO_VFP_VMOV(VMOV_reg, dp, tcg_gen_mov_i64)
DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd, aa32_fpdp_v2)
DO_VFP_2OP(VABS, hp, gen_vfp_absh, aa32_fp16_arith)
DO_VFP_2OP(VABS, sp, gen_vfp_abss, aa32_fpsp_v2)
DO_VFP_2OP(VABS, dp, gen_vfp_absd, aa32_fpdp_v2)
DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh, aa32_fp16_arith)
DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs, aa32_fpsp_v2)
DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd, aa32_fpdp_v2)
DO_VFP_2OP(VNEG, hp, gen_vfp_negh, aa32_fp16_arith)
DO_VFP_2OP(VNEG, sp, gen_vfp_negs, aa32_fpsp_v2)
DO_VFP_2OP(VNEG, dp, gen_vfp_negd, aa32_fpdp_v2)
static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm)
{
@ -2456,11 +2461,11 @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
vd = tcg_temp_new_i32();
vm = tcg_temp_new_i32();
vfp_load_reg32(vd, a->vd);
vfp_load_reg16(vd, a->vd);
if (a->z) {
tcg_gen_movi_i32(vm, 0);
} else {
vfp_load_reg32(vm, a->vm);
vfp_load_reg16(vm, a->vm);
}
if (a->e) {
@ -2700,7 +2705,7 @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
}
tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm);
vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16);
gen_helper_rinth(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd);
@ -2773,7 +2778,7 @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
}
tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm);
vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16);
tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst);
gen_helper_rinth(tmp, tmp, fpst);
@ -2853,7 +2858,7 @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
}
tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm);
vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16);
gen_helper_rinth_exact(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd);
@ -3270,7 +3275,7 @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
fpst = fpstatus_ptr(FPST_FPCR_F16);
vm = tcg_temp_new_i32();
vfp_load_reg32(vm, a->vm);
vfp_load_reg16(vm, a->vm);
if (a->s) {
if (a->rz) {
@ -3383,8 +3388,8 @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
/* Insert low half of Vm into high half of Vd */
rm = tcg_temp_new_i32();
rd = tcg_temp_new_i32();
vfp_load_reg32(rm, a->vm);
vfp_load_reg32(rd, a->vd);
vfp_load_reg16(rm, a->vm);
vfp_load_reg16(rd, a->vd);
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
vfp_store_reg32(rd, a->vd);
return true;

File diff suppressed because it is too large Load Diff

View File

@ -252,6 +252,11 @@ static inline int shl_12(DisasContext *s, int x)
return x << 12;
}
static inline int xor_2(DisasContext *s, int x)
{
return x ^ 2;
}
static inline int neon_3same_fp_size(DisasContext *s, int x)
{
/* Convert 0==fp32, 1==fp16 into a MO_* value */
@ -401,6 +406,36 @@ static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
*/
uint64_t vfp_expand_imm(int size, uint8_t imm8);
static inline void gen_vfp_absh(TCGv_i32 d, TCGv_i32 s)
{
tcg_gen_andi_i32(d, s, INT16_MAX);
}
static inline void gen_vfp_abss(TCGv_i32 d, TCGv_i32 s)
{
tcg_gen_andi_i32(d, s, INT32_MAX);
}
static inline void gen_vfp_absd(TCGv_i64 d, TCGv_i64 s)
{
tcg_gen_andi_i64(d, s, INT64_MAX);
}
static inline void gen_vfp_negh(TCGv_i32 d, TCGv_i32 s)
{
tcg_gen_xori_i32(d, s, 1u << 15);
}
static inline void gen_vfp_negs(TCGv_i32 d, TCGv_i32 s)
{
tcg_gen_xori_i32(d, s, 1u << 31);
}
static inline void gen_vfp_negd(TCGv_i64 d, TCGv_i64 s)
{
tcg_gen_xori_i64(d, s, 1ull << 63);
}
/* Vector operations shared between ARM and AArch64. */
void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
uint32_t opr_sz, uint32_t max_sz);
@ -445,6 +480,11 @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
@ -474,6 +514,17 @@ void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_smaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_sminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
/*
* Forward to the isar_feature_* tests given a DisasContext pointer.
*/

View File

@ -971,6 +971,11 @@ static uint32_t float32_ceq(float32 op1, float32 op2, float_status *stat)
return -float32_eq_quiet(op1, op2, stat);
}
static uint64_t float64_ceq(float64 op1, float64 op2, float_status *stat)
{
return -float64_eq_quiet(op1, op2, stat);
}
static uint16_t float16_cge(float16 op1, float16 op2, float_status *stat)
{
return -float16_le(op2, op1, stat);
@ -981,6 +986,11 @@ static uint32_t float32_cge(float32 op1, float32 op2, float_status *stat)
return -float32_le(op2, op1, stat);
}
static uint64_t float64_cge(float64 op1, float64 op2, float_status *stat)
{
return -float64_le(op2, op1, stat);
}
static uint16_t float16_cgt(float16 op1, float16 op2, float_status *stat)
{
return -float16_lt(op2, op1, stat);
@ -991,6 +1001,11 @@ static uint32_t float32_cgt(float32 op1, float32 op2, float_status *stat)
return -float32_lt(op2, op1, stat);
}
static uint64_t float64_cgt(float64 op1, float64 op2, float_status *stat)
{
return -float64_lt(op2, op1, stat);
}
static uint16_t float16_acge(float16 op1, float16 op2, float_status *stat)
{
return -float16_le(float16_abs(op2), float16_abs(op1), stat);
@ -1001,6 +1016,11 @@ static uint32_t float32_acge(float32 op1, float32 op2, float_status *stat)
return -float32_le(float32_abs(op2), float32_abs(op1), stat);
}
static uint64_t float64_acge(float64 op1, float64 op2, float_status *stat)
{
return -float64_le(float64_abs(op2), float64_abs(op1), stat);
}
static uint16_t float16_acgt(float16 op1, float16 op2, float_status *stat)
{
return -float16_lt(float16_abs(op2), float16_abs(op1), stat);
@ -1011,6 +1031,11 @@ static uint32_t float32_acgt(float32 op1, float32 op2, float_status *stat)
return -float32_lt(float32_abs(op2), float32_abs(op1), stat);
}
static uint64_t float64_acgt(float64 op1, float64 op2, float_status *stat)
{
return -float64_lt(float64_abs(op2), float64_abs(op1), stat);
}
static int16_t vfp_tosszh(float16 x, void *fpstp)
{
float_status *fpst = fpstp;
@ -1129,6 +1154,11 @@ static float32 float32_abd(float32 op1, float32 op2, float_status *stat)
return float32_abs(float32_sub(op1, op2, stat));
}
static float64 float64_abd(float64 op1, float64 op2, float_status *stat)
{
return float64_abs(float64_sub(op1, op2, stat));
}
/*
* Reciprocal step. These are the AArch32 version which uses a
* non-fused multiply-and-subtract.
@ -1213,33 +1243,43 @@ DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
DO_3OP(gvec_fabd_h, float16_abd, float16)
DO_3OP(gvec_fabd_s, float32_abd, float32)
DO_3OP(gvec_fabd_d, float64_abd, float64)
DO_3OP(gvec_fceq_h, float16_ceq, float16)
DO_3OP(gvec_fceq_s, float32_ceq, float32)
DO_3OP(gvec_fceq_d, float64_ceq, float64)
DO_3OP(gvec_fcge_h, float16_cge, float16)
DO_3OP(gvec_fcge_s, float32_cge, float32)
DO_3OP(gvec_fcge_d, float64_cge, float64)
DO_3OP(gvec_fcgt_h, float16_cgt, float16)
DO_3OP(gvec_fcgt_s, float32_cgt, float32)
DO_3OP(gvec_fcgt_d, float64_cgt, float64)
DO_3OP(gvec_facge_h, float16_acge, float16)
DO_3OP(gvec_facge_s, float32_acge, float32)
DO_3OP(gvec_facge_d, float64_acge, float64)
DO_3OP(gvec_facgt_h, float16_acgt, float16)
DO_3OP(gvec_facgt_s, float32_acgt, float32)
DO_3OP(gvec_facgt_d, float64_acgt, float64)
DO_3OP(gvec_fmax_h, float16_max, float16)
DO_3OP(gvec_fmax_s, float32_max, float32)
DO_3OP(gvec_fmax_d, float64_max, float64)
DO_3OP(gvec_fmin_h, float16_min, float16)
DO_3OP(gvec_fmin_s, float32_min, float32)
DO_3OP(gvec_fmin_d, float64_min, float64)
DO_3OP(gvec_fmaxnum_h, float16_maxnum, float16)
DO_3OP(gvec_fmaxnum_s, float32_maxnum, float32)
DO_3OP(gvec_fmaxnum_d, float64_maxnum, float64)
DO_3OP(gvec_fminnum_h, float16_minnum, float16)
DO_3OP(gvec_fminnum_s, float32_minnum, float32)
DO_3OP(gvec_fminnum_d, float64_minnum, float64)
DO_3OP(gvec_recps_nf_h, float16_recps_nf, float16)
DO_3OP(gvec_recps_nf_s, float32_recps_nf, float32)
@ -1248,6 +1288,13 @@ DO_3OP(gvec_rsqrts_nf_h, float16_rsqrts_nf, float16)
DO_3OP(gvec_rsqrts_nf_s, float32_rsqrts_nf, float32)
#ifdef TARGET_AARCH64
DO_3OP(gvec_fdiv_h, float16_div, float16)
DO_3OP(gvec_fdiv_s, float32_div, float32)
DO_3OP(gvec_fdiv_d, float64_div, float64)
DO_3OP(gvec_fmulx_h, helper_advsimd_mulxh, float16)
DO_3OP(gvec_fmulx_s, helper_vfp_mulxs, float32)
DO_3OP(gvec_fmulx_d, helper_vfp_mulxd, float64)
DO_3OP(gvec_recps_h, helper_recpsf_f16, float16)
DO_3OP(gvec_recps_s, helper_recpsf_f32, float32)
@ -1298,6 +1345,12 @@ static float32 float32_muladd_f(float32 dest, float32 op1, float32 op2,
return float32_muladd(op1, op2, dest, 0, stat);
}
static float64 float64_muladd_f(float64 dest, float64 op1, float64 op2,
float_status *stat)
{
return float64_muladd(op1, op2, dest, 0, stat);
}
static float16 float16_mulsub_f(float16 dest, float16 op1, float16 op2,
float_status *stat)
{
@ -1310,6 +1363,12 @@ static float32 float32_mulsub_f(float32 dest, float32 op1, float32 op2,
return float32_muladd(float32_chs(op1), op2, dest, 0, stat);
}
static float64 float64_mulsub_f(float64 dest, float64 op1, float64 op2,
float_status *stat)
{
return float64_muladd(float64_chs(op1), op2, dest, 0, stat);
}
#define DO_MULADD(NAME, FUNC, TYPE) \
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
{ \
@ -1329,9 +1388,11 @@ DO_MULADD(gvec_fmls_s, float32_mulsub_nf, float32)
DO_MULADD(gvec_vfma_h, float16_muladd_f, float16)
DO_MULADD(gvec_vfma_s, float32_muladd_f, float32)
DO_MULADD(gvec_vfma_d, float64_muladd_f, float64)
DO_MULADD(gvec_vfms_h, float16_mulsub_f, float16)
DO_MULADD(gvec_vfms_s, float32_mulsub_f, float32)
DO_MULADD(gvec_vfms_d, float64_mulsub_f, float64)
/* For the indexed ops, SVE applies the index per 128-bit vector segment.
* For AdvSIMD, there is of course only one such vector segment.
@ -1385,7 +1446,7 @@ DO_MLA_IDX(gvec_mls_idx_d, uint64_t, -, H8)
#undef DO_MLA_IDX
#define DO_FMUL_IDX(NAME, ADD, TYPE, H) \
#define DO_FMUL_IDX(NAME, ADD, MUL, TYPE, H) \
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
{ \
intptr_t i, j, oprsz = simd_oprsz(desc); \
@ -1395,33 +1456,37 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
TYPE mm = m[H(i + idx)]; \
for (j = 0; j < segment; j++) { \
d[i + j] = TYPE##_##ADD(d[i + j], \
TYPE##_mul(n[i + j], mm, stat), stat); \
d[i + j] = ADD(d[i + j], MUL(n[i + j], mm, stat), stat); \
} \
} \
clear_tail(d, oprsz, simd_maxsz(desc)); \
}
#define float16_nop(N, M, S) (M)
#define float32_nop(N, M, S) (M)
#define float64_nop(N, M, S) (M)
#define nop(N, M, S) (M)
DO_FMUL_IDX(gvec_fmul_idx_h, nop, float16, H2)
DO_FMUL_IDX(gvec_fmul_idx_s, nop, float32, H4)
DO_FMUL_IDX(gvec_fmul_idx_d, nop, float64, H8)
DO_FMUL_IDX(gvec_fmul_idx_h, nop, float16_mul, float16, H2)
DO_FMUL_IDX(gvec_fmul_idx_s, nop, float32_mul, float32, H4)
DO_FMUL_IDX(gvec_fmul_idx_d, nop, float64_mul, float64, H8)
#ifdef TARGET_AARCH64
DO_FMUL_IDX(gvec_fmulx_idx_h, nop, helper_advsimd_mulxh, float16, H2)
DO_FMUL_IDX(gvec_fmulx_idx_s, nop, helper_vfp_mulxs, float32, H4)
DO_FMUL_IDX(gvec_fmulx_idx_d, nop, helper_vfp_mulxd, float64, H8)
#endif
#undef nop
/*
* Non-fused multiply-accumulate operations, for Neon. NB that unlike
* the fused ops below they assume accumulate both from and into Vd.
*/
DO_FMUL_IDX(gvec_fmla_nf_idx_h, add, float16, H2)
DO_FMUL_IDX(gvec_fmla_nf_idx_s, add, float32, H4)
DO_FMUL_IDX(gvec_fmls_nf_idx_h, sub, float16, H2)
DO_FMUL_IDX(gvec_fmls_nf_idx_s, sub, float32, H4)
DO_FMUL_IDX(gvec_fmla_nf_idx_h, float16_add, float16_mul, float16, H2)
DO_FMUL_IDX(gvec_fmla_nf_idx_s, float32_add, float32_mul, float32, H4)
DO_FMUL_IDX(gvec_fmls_nf_idx_h, float16_sub, float16_mul, float16, H2)
DO_FMUL_IDX(gvec_fmls_nf_idx_s, float32_sub, float32_mul, float32, H4)
#undef float16_nop
#undef float32_nop
#undef float64_nop
#undef DO_FMUL_IDX
#define DO_FMLA_IDX(NAME, TYPE, H) \
@ -2127,50 +2192,90 @@ DO_ABA(gvec_uaba_d, uint64_t)
#undef DO_ABA
#define DO_NEON_PAIRWISE(NAME, OP) \
void HELPER(NAME##s)(void *vd, void *vn, void *vm, \
void *stat, uint32_t oprsz) \
{ \
float_status *fpst = stat; \
float32 *d = vd; \
float32 *n = vn; \
float32 *m = vm; \
float32 r0, r1; \
\
/* Read all inputs before writing outputs in case vm == vd */ \
r0 = float32_##OP(n[H4(0)], n[H4(1)], fpst); \
r1 = float32_##OP(m[H4(0)], m[H4(1)], fpst); \
\
d[H4(0)] = r0; \
d[H4(1)] = r1; \
} \
\
void HELPER(NAME##h)(void *vd, void *vn, void *vm, \
void *stat, uint32_t oprsz) \
{ \
float_status *fpst = stat; \
float16 *d = vd; \
float16 *n = vn; \
float16 *m = vm; \
float16 r0, r1, r2, r3; \
\
/* Read all inputs before writing outputs in case vm == vd */ \
r0 = float16_##OP(n[H2(0)], n[H2(1)], fpst); \
r1 = float16_##OP(n[H2(2)], n[H2(3)], fpst); \
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
\
d[H2(0)] = r0; \
d[H2(1)] = r1; \
d[H2(2)] = r2; \
d[H2(3)] = r3; \
}
#define DO_3OP_PAIR(NAME, FUNC, TYPE, H) \
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
{ \
ARMVectorReg scratch; \
intptr_t oprsz = simd_oprsz(desc); \
intptr_t half = oprsz / sizeof(TYPE) / 2; \
TYPE *d = vd, *n = vn, *m = vm; \
if (unlikely(d == m)) { \
m = memcpy(&scratch, m, oprsz); \
} \
for (intptr_t i = 0; i < half; ++i) { \
d[H(i)] = FUNC(n[H(i * 2)], n[H(i * 2 + 1)], stat); \
} \
for (intptr_t i = 0; i < half; ++i) { \
d[H(i + half)] = FUNC(m[H(i * 2)], m[H(i * 2 + 1)], stat); \
} \
clear_tail(d, oprsz, simd_maxsz(desc)); \
}
DO_NEON_PAIRWISE(neon_padd, add)
DO_NEON_PAIRWISE(neon_pmax, max)
DO_NEON_PAIRWISE(neon_pmin, min)
DO_3OP_PAIR(gvec_faddp_h, float16_add, float16, H2)
DO_3OP_PAIR(gvec_faddp_s, float32_add, float32, H4)
DO_3OP_PAIR(gvec_faddp_d, float64_add, float64, )
#undef DO_NEON_PAIRWISE
DO_3OP_PAIR(gvec_fmaxp_h, float16_max, float16, H2)
DO_3OP_PAIR(gvec_fmaxp_s, float32_max, float32, H4)
DO_3OP_PAIR(gvec_fmaxp_d, float64_max, float64, )
DO_3OP_PAIR(gvec_fminp_h, float16_min, float16, H2)
DO_3OP_PAIR(gvec_fminp_s, float32_min, float32, H4)
DO_3OP_PAIR(gvec_fminp_d, float64_min, float64, )
DO_3OP_PAIR(gvec_fmaxnump_h, float16_maxnum, float16, H2)
DO_3OP_PAIR(gvec_fmaxnump_s, float32_maxnum, float32, H4)
DO_3OP_PAIR(gvec_fmaxnump_d, float64_maxnum, float64, )
DO_3OP_PAIR(gvec_fminnump_h, float16_minnum, float16, H2)
DO_3OP_PAIR(gvec_fminnump_s, float32_minnum, float32, H4)
DO_3OP_PAIR(gvec_fminnump_d, float64_minnum, float64, )
#undef DO_3OP_PAIR
#define DO_3OP_PAIR(NAME, FUNC, TYPE, H) \
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
{ \
ARMVectorReg scratch; \
intptr_t oprsz = simd_oprsz(desc); \
intptr_t half = oprsz / sizeof(TYPE) / 2; \
TYPE *d = vd, *n = vn, *m = vm; \
if (unlikely(d == m)) { \
m = memcpy(&scratch, m, oprsz); \
} \
for (intptr_t i = 0; i < half; ++i) { \
d[H(i)] = FUNC(n[H(i * 2)], n[H(i * 2 + 1)]); \
} \
for (intptr_t i = 0; i < half; ++i) { \
d[H(i + half)] = FUNC(m[H(i * 2)], m[H(i * 2 + 1)]); \
} \
clear_tail(d, oprsz, simd_maxsz(desc)); \
}
#define ADD(A, B) (A + B)
DO_3OP_PAIR(gvec_addp_b, ADD, uint8_t, H1)
DO_3OP_PAIR(gvec_addp_h, ADD, uint16_t, H2)
DO_3OP_PAIR(gvec_addp_s, ADD, uint32_t, H4)
DO_3OP_PAIR(gvec_addp_d, ADD, uint64_t, )
#undef ADD
DO_3OP_PAIR(gvec_smaxp_b, MAX, int8_t, H1)
DO_3OP_PAIR(gvec_smaxp_h, MAX, int16_t, H2)
DO_3OP_PAIR(gvec_smaxp_s, MAX, int32_t, H4)
DO_3OP_PAIR(gvec_umaxp_b, MAX, uint8_t, H1)
DO_3OP_PAIR(gvec_umaxp_h, MAX, uint16_t, H2)
DO_3OP_PAIR(gvec_umaxp_s, MAX, uint32_t, H4)
DO_3OP_PAIR(gvec_sminp_b, MIN, int8_t, H1)
DO_3OP_PAIR(gvec_sminp_h, MIN, int16_t, H2)
DO_3OP_PAIR(gvec_sminp_s, MIN, int32_t, H4)
DO_3OP_PAIR(gvec_uminp_b, MIN, uint8_t, H1)
DO_3OP_PAIR(gvec_uminp_h, MIN, uint16_t, H2)
DO_3OP_PAIR(gvec_uminp_s, MIN, uint32_t, H4)
#undef DO_3OP_PAIR
#define DO_VCVT_FIXED(NAME, FUNC, TYPE) \
void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \

View File

@ -281,36 +281,6 @@ VFP_BINOP(minnum)
VFP_BINOP(maxnum)
#undef VFP_BINOP
dh_ctype_f16 VFP_HELPER(neg, h)(dh_ctype_f16 a)
{
return float16_chs(a);
}
float32 VFP_HELPER(neg, s)(float32 a)
{
return float32_chs(a);
}
float64 VFP_HELPER(neg, d)(float64 a)
{
return float64_chs(a);
}
dh_ctype_f16 VFP_HELPER(abs, h)(dh_ctype_f16 a)
{
return float16_abs(a);
}
float32 VFP_HELPER(abs, s)(float32 a)
{
return float32_abs(a);
}
float64 VFP_HELPER(abs, d)(float64 a)
{
return float64_abs(a);
}
dh_ctype_f16 VFP_HELPER(sqrt, h)(dh_ctype_f16 a, CPUARMState *env)
{
return float16_sqrt(a, &env->vfp.fp_status_f16);