mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180301' into staging
target-arm queue: * update MAINTAINERS for Alistair's new email address * add Arm v8.2 FP16 arithmetic extension for linux-user * implement display connector emulation for vexpress board * xilinx_spips: Enable only two slaves when reading/writing with stripe * xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands * hw: register: Run post_write hook on reset # gpg: Signature made Thu 01 Mar 2018 11:22:46 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180301: (42 commits) MAINTAINERS: Update my email address linux-user: Report AArch64 FP16 support via hwcap bits target/arm: Enable ARM_V8_FP16 feature bit for the AArch64 "any" CPU arm/translate-a64: add all single op FP16 to handle_fp_1src_half arm/translate-a64: implement simd_scalar_three_reg_same_fp16 arm/translate-a64: add all FP16 ops in simd_scalar_pairwise arm/translate-a64: add FP16 FMOV to simd_mod_imm arm/translate-a64: add FP16 FRSQRTE to simd_two_reg_misc_fp16 arm/helper.c: re-factor rsqrte and add rsqrte_f16 arm/translate-a64: add FP16 FSQRT to simd_two_reg_misc_fp16 arm/translate-a64: add FP16 FRCPX to simd_two_reg_misc_fp16 arm/translate-a64: add FP16 FRECPE arm/helper.c: re-factor recpe and add recepe_f16 arm/translate-a64: add FP16 FNEG/FABS to simd_two_reg_misc_fp16 arm/translate-a64: add FP16 SCVTF/UCVFT to simd_two_reg_misc_fp16 arm/translate-a64: add FP16 FCMxx (zero) to simd_two_reg_misc_fp16 arm/translate-a64: add FCVTxx to simd_two_reg_misc_fp16 arm/translate-a64: add FP16 FPRINTx to simd_two_reg_misc_fp16 arm/translate-a64: initial decode for simd_two_reg_misc_fp16 arm/translate-a64: add FP16 x2 ops for simd_indexed ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+6
-6
@@ -556,7 +556,7 @@ F: hw/misc/arm_sysctl.c
|
||||
|
||||
Xilinx Zynq
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/xilinx_*
|
||||
@@ -566,7 +566,7 @@ F: include/hw/misc/zynq*
|
||||
X: hw/ssi/xilinx_*
|
||||
|
||||
Xilinx ZynqMP
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
@@ -1075,7 +1075,7 @@ T: git git://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
SSI
|
||||
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/ssi/*
|
||||
F: hw/block/m25p80.c
|
||||
@@ -1084,7 +1084,7 @@ X: hw/ssi/xilinx_*
|
||||
F: tests/m25p80-test.c
|
||||
|
||||
Xilinx SPI
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
S: Maintained
|
||||
F: hw/ssi/xilinx_*
|
||||
@@ -1254,7 +1254,7 @@ S: Maintained
|
||||
F: hw/net/eepro100.c
|
||||
|
||||
Generic Loader
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/core/generic-loader.c
|
||||
F: include/hw/core/generic-loader.h
|
||||
@@ -1600,7 +1600,7 @@ F: tests/qmp-test.c
|
||||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
||||
Register API
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/core/register.c
|
||||
F: include/hw/register.h
|
||||
|
||||
@@ -21,6 +21,8 @@ CONFIG_STELLARIS_INPUT=y
|
||||
CONFIG_STELLARIS_ENET=y
|
||||
CONFIG_SSD0303=y
|
||||
CONFIG_SSD0323=y
|
||||
CONFIG_DDC=y
|
||||
CONFIG_SII9022=y
|
||||
CONFIG_ADS7846=y
|
||||
CONFIG_MAX111X=y
|
||||
CONFIG_SSI=y
|
||||
|
||||
+5
-1
@@ -29,6 +29,7 @@
|
||||
#include "hw/arm/arm.h"
|
||||
#include "hw/arm/primecell.h"
|
||||
#include "hw/devices.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "net/net.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/boards.h"
|
||||
@@ -537,6 +538,7 @@ static void vexpress_common_init(MachineState *machine)
|
||||
uint32_t sys_id;
|
||||
DriveInfo *dinfo;
|
||||
pflash_t *pflash0;
|
||||
I2CBus *i2c;
|
||||
ram_addr_t vram_size, sram_size;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *vram = g_new(MemoryRegion, 1);
|
||||
@@ -628,7 +630,9 @@ static void vexpress_common_init(MachineState *machine)
|
||||
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
|
||||
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
|
||||
|
||||
/* VE_SERIALDVI: not modelled */
|
||||
dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
|
||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||
i2c_create_slave(i2c, "sii9022", 0x39);
|
||||
|
||||
sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */
|
||||
|
||||
|
||||
@@ -159,13 +159,21 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
|
||||
|
||||
void register_reset(RegisterInfo *reg)
|
||||
{
|
||||
const RegisterAccessInfo *ac;
|
||||
|
||||
g_assert(reg);
|
||||
|
||||
if (!reg->data || !reg->access) {
|
||||
return;
|
||||
}
|
||||
|
||||
ac = reg->access;
|
||||
|
||||
register_write_val(reg, reg->access->reset);
|
||||
|
||||
if (ac->post_write) {
|
||||
ac->post_write(reg, reg->access->reset);
|
||||
}
|
||||
}
|
||||
|
||||
void register_init(RegisterInfo *reg)
|
||||
|
||||
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
|
||||
common-obj-$(CONFIG_G364FB) += g364fb.o
|
||||
common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
|
||||
common-obj-$(CONFIG_PL110) += pl110.o
|
||||
common-obj-$(CONFIG_SII9022) += sii9022.o
|
||||
common-obj-$(CONFIG_SSD0303) += ssd0303.o
|
||||
common-obj-$(CONFIG_SSD0323) += ssd0323.o
|
||||
common-obj-$(CONFIG_XEN) += xenfb.o
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Silicon Image SiI9022
|
||||
*
|
||||
* This is a pretty hollow emulation: all we do is acknowledge that we
|
||||
* exist (chip ID) and confirm that we get switched over into DDC mode
|
||||
* so the emulated host can proceed to read out EDID data. All subsequent
|
||||
* set-up of connectors etc will be acknowledged and ignored.
|
||||
*
|
||||
* Copyright (C) 2018 Linus Walleij
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "hw/i2c/i2c-ddc.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define SII9022_SYS_CTRL_DATA 0x1a
|
||||
#define SII9022_SYS_CTRL_PWR_DWN 0x10
|
||||
#define SII9022_SYS_CTRL_AV_MUTE 0x08
|
||||
#define SII9022_SYS_CTRL_DDC_BUS_REQ 0x04
|
||||
#define SII9022_SYS_CTRL_DDC_BUS_GRTD 0x02
|
||||
#define SII9022_SYS_CTRL_OUTPUT_MODE 0x01
|
||||
#define SII9022_SYS_CTRL_OUTPUT_HDMI 1
|
||||
#define SII9022_SYS_CTRL_OUTPUT_DVI 0
|
||||
#define SII9022_REG_CHIPID 0x1b
|
||||
#define SII9022_INT_ENABLE 0x3c
|
||||
#define SII9022_INT_STATUS 0x3d
|
||||
#define SII9022_INT_STATUS_HOTPLUG 0x01;
|
||||
#define SII9022_INT_STATUS_PLUGGED 0x04;
|
||||
|
||||
#define TYPE_SII9022 "sii9022"
|
||||
#define SII9022(obj) OBJECT_CHECK(sii9022_state, (obj), TYPE_SII9022)
|
||||
|
||||
typedef struct sii9022_state {
|
||||
I2CSlave parent_obj;
|
||||
uint8_t ptr;
|
||||
bool addr_byte;
|
||||
bool ddc_req;
|
||||
bool ddc_skip_finish;
|
||||
bool ddc;
|
||||
} sii9022_state;
|
||||
|
||||
static const VMStateDescription vmstate_sii9022 = {
|
||||
.name = "sii9022",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_I2C_SLAVE(parent_obj, sii9022_state),
|
||||
VMSTATE_UINT8(ptr, sii9022_state),
|
||||
VMSTATE_BOOL(addr_byte, sii9022_state),
|
||||
VMSTATE_BOOL(ddc_req, sii9022_state),
|
||||
VMSTATE_BOOL(ddc_skip_finish, sii9022_state),
|
||||
VMSTATE_BOOL(ddc, sii9022_state),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static int sii9022_event(I2CSlave *i2c, enum i2c_event event)
|
||||
{
|
||||
sii9022_state *s = SII9022(i2c);
|
||||
|
||||
switch (event) {
|
||||
case I2C_START_SEND:
|
||||
s->addr_byte = true;
|
||||
break;
|
||||
case I2C_START_RECV:
|
||||
break;
|
||||
case I2C_FINISH:
|
||||
break;
|
||||
case I2C_NACK:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sii9022_rx(I2CSlave *i2c)
|
||||
{
|
||||
sii9022_state *s = SII9022(i2c);
|
||||
uint8_t res = 0x00;
|
||||
|
||||
switch (s->ptr) {
|
||||
case SII9022_SYS_CTRL_DATA:
|
||||
if (s->ddc_req) {
|
||||
/* Acknowledge DDC bus request */
|
||||
res = SII9022_SYS_CTRL_DDC_BUS_GRTD | SII9022_SYS_CTRL_DDC_BUS_REQ;
|
||||
}
|
||||
break;
|
||||
case SII9022_REG_CHIPID:
|
||||
res = 0xb0;
|
||||
break;
|
||||
case SII9022_INT_STATUS:
|
||||
/* Something is cold-plugged in, no interrupts */
|
||||
res = SII9022_INT_STATUS_PLUGGED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
trace_sii9022_read_reg(s->ptr, res);
|
||||
s->ptr++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int sii9022_tx(I2CSlave *i2c, uint8_t data)
|
||||
{
|
||||
sii9022_state *s = SII9022(i2c);
|
||||
|
||||
if (s->addr_byte) {
|
||||
s->ptr = data;
|
||||
s->addr_byte = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (s->ptr) {
|
||||
case SII9022_SYS_CTRL_DATA:
|
||||
if (data & SII9022_SYS_CTRL_DDC_BUS_REQ) {
|
||||
s->ddc_req = true;
|
||||
if (data & SII9022_SYS_CTRL_DDC_BUS_GRTD) {
|
||||
s->ddc = true;
|
||||
/* Skip this finish since we just switched to DDC */
|
||||
s->ddc_skip_finish = true;
|
||||
trace_sii9022_switch_mode("DDC");
|
||||
}
|
||||
} else {
|
||||
s->ddc_req = false;
|
||||
s->ddc = false;
|
||||
trace_sii9022_switch_mode("normal");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
trace_sii9022_write_reg(s->ptr, data);
|
||||
s->ptr++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sii9022_reset(DeviceState *dev)
|
||||
{
|
||||
sii9022_state *s = SII9022(dev);
|
||||
|
||||
s->ptr = 0;
|
||||
s->addr_byte = false;
|
||||
s->ddc_req = false;
|
||||
s->ddc_skip_finish = false;
|
||||
s->ddc = false;
|
||||
}
|
||||
|
||||
static void sii9022_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
I2CBus *bus;
|
||||
|
||||
bus = I2C_BUS(qdev_get_parent_bus(dev));
|
||||
i2c_create_slave(bus, TYPE_I2CDDC, 0x50);
|
||||
}
|
||||
|
||||
static void sii9022_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->event = sii9022_event;
|
||||
k->recv = sii9022_rx;
|
||||
k->send = sii9022_tx;
|
||||
dc->reset = sii9022_reset;
|
||||
dc->realize = sii9022_realize;
|
||||
dc->vmsd = &vmstate_sii9022;
|
||||
}
|
||||
|
||||
static const TypeInfo sii9022_info = {
|
||||
.name = TYPE_SII9022,
|
||||
.parent = TYPE_I2C_SLAVE,
|
||||
.instance_size = sizeof(sii9022_state),
|
||||
.class_init = sii9022_class_init,
|
||||
};
|
||||
|
||||
static void sii9022_register_types(void)
|
||||
{
|
||||
type_register_static(&sii9022_info);
|
||||
}
|
||||
|
||||
type_init(sii9022_register_types)
|
||||
@@ -132,3 +132,8 @@ vga_cirrus_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
|
||||
vga_cirrus_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
|
||||
vga_cirrus_read_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
|
||||
vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
|
||||
|
||||
# hw/display/sii9022.c
|
||||
sii9022_read_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
|
||||
sii9022_write_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
|
||||
sii9022_switch_mode(const char *mode) "mode: %s"
|
||||
|
||||
@@ -10,31 +10,13 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
|
||||
typedef struct I2CNode I2CNode;
|
||||
|
||||
struct I2CNode {
|
||||
I2CSlave *elt;
|
||||
QLIST_ENTRY(I2CNode) next;
|
||||
};
|
||||
|
||||
#define I2C_BROADCAST 0x00
|
||||
|
||||
struct I2CBus
|
||||
{
|
||||
BusState qbus;
|
||||
QLIST_HEAD(, I2CNode) current_devs;
|
||||
uint8_t saved_address;
|
||||
bool broadcast;
|
||||
};
|
||||
|
||||
static Property i2c_props[] = {
|
||||
DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
#define TYPE_I2C_BUS "i2c-bus"
|
||||
#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
|
||||
|
||||
static const TypeInfo i2c_bus_info = {
|
||||
.name = TYPE_I2C_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
|
||||
+2
-2
@@ -259,12 +259,12 @@ static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data)
|
||||
s->reg = data;
|
||||
s->firstbyte = false;
|
||||
DPRINTF("[EDID] Written new pointer: %u\n", data);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore all writes */
|
||||
s->reg++;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_ddc_init(Object *obj)
|
||||
|
||||
+38
-5
@@ -223,7 +223,7 @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->num_cs; i++) {
|
||||
for (i = 0; i < s->num_cs * s->num_busses; i++) {
|
||||
bool old_state = s->cs_lines_state[i];
|
||||
bool new_state = field & (1 << i);
|
||||
|
||||
@@ -234,7 +234,7 @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
|
||||
}
|
||||
qemu_set_irq(s->cs_lines[i], !new_state);
|
||||
}
|
||||
if (!(field & ((1 << s->num_cs) - 1))) {
|
||||
if (!(field & ((1 << (s->num_cs * s->num_busses)) - 1))) {
|
||||
s->snoop_state = SNOOP_CHECKING;
|
||||
s->cmd_dummies = 0;
|
||||
s->link_state = 1;
|
||||
@@ -248,7 +248,40 @@ static void xlnx_zynqmp_qspips_update_cs_lines(XlnxZynqMPQSPIPS *s)
|
||||
{
|
||||
if (s->regs[R_GQSPI_GF_SNAPSHOT]) {
|
||||
int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT);
|
||||
xilinx_spips_update_cs(XILINX_SPIPS(s), field);
|
||||
bool upper_cs_sel = field & (1 << 1);
|
||||
bool lower_cs_sel = field & 1;
|
||||
bool bus0_enabled;
|
||||
bool bus1_enabled;
|
||||
uint8_t buses;
|
||||
int cs = 0;
|
||||
|
||||
buses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT);
|
||||
bus0_enabled = buses & 1;
|
||||
bus1_enabled = buses & (1 << 1);
|
||||
|
||||
if (bus0_enabled && bus1_enabled) {
|
||||
if (lower_cs_sel) {
|
||||
cs |= 1;
|
||||
}
|
||||
if (upper_cs_sel) {
|
||||
cs |= 1 << 3;
|
||||
}
|
||||
} else if (bus0_enabled) {
|
||||
if (lower_cs_sel) {
|
||||
cs |= 1;
|
||||
}
|
||||
if (upper_cs_sel) {
|
||||
cs |= 1 << 1;
|
||||
}
|
||||
} else if (bus1_enabled) {
|
||||
if (lower_cs_sel) {
|
||||
cs |= 1 << 2;
|
||||
}
|
||||
if (upper_cs_sel) {
|
||||
cs |= 1 << 3;
|
||||
}
|
||||
}
|
||||
xilinx_spips_update_cs(XILINX_SPIPS(s), cs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +293,7 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
|
||||
if (num_effective_busses(s) == 2) {
|
||||
/* Single bit chip-select for qspi */
|
||||
field &= 0x1;
|
||||
field |= field << 1;
|
||||
field |= field << 3;
|
||||
/* Dual stack U-Page */
|
||||
} else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM &&
|
||||
s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) {
|
||||
@@ -544,7 +577,7 @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
|
||||
return 2;
|
||||
case QIOR:
|
||||
case QIOR_4:
|
||||
return 5;
|
||||
return 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define dh_alias_int i32
|
||||
#define dh_alias_i64 i64
|
||||
#define dh_alias_s64 i64
|
||||
#define dh_alias_f16 i32
|
||||
#define dh_alias_f32 i32
|
||||
#define dh_alias_f64 i64
|
||||
#define dh_alias_ptr ptr
|
||||
@@ -38,6 +39,7 @@
|
||||
#define dh_ctype_int int
|
||||
#define dh_ctype_i64 uint64_t
|
||||
#define dh_ctype_s64 int64_t
|
||||
#define dh_ctype_f16 float16
|
||||
#define dh_ctype_f32 float32
|
||||
#define dh_ctype_f64 float64
|
||||
#define dh_ctype_ptr void *
|
||||
@@ -94,6 +96,7 @@
|
||||
#define dh_is_signed_s32 1
|
||||
#define dh_is_signed_i64 0
|
||||
#define dh_is_signed_s64 1
|
||||
#define dh_is_signed_f16 0
|
||||
#define dh_is_signed_f32 0
|
||||
#define dh_is_signed_f64 0
|
||||
#define dh_is_signed_tl 0
|
||||
|
||||
+13
-5
@@ -306,8 +306,11 @@ static inline float16 float16_set_sign(float16 a, int sign)
|
||||
}
|
||||
|
||||
#define float16_zero make_float16(0)
|
||||
#define float16_one make_float16(0x3c00)
|
||||
#define float16_half make_float16(0x3800)
|
||||
#define float16_one make_float16(0x3c00)
|
||||
#define float16_one_point_five make_float16(0x3e00)
|
||||
#define float16_two make_float16(0x4000)
|
||||
#define float16_three make_float16(0x4200)
|
||||
#define float16_infinity make_float16(0x7c00)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
@@ -415,11 +418,13 @@ static inline float32 float32_set_sign(float32 a, int sign)
|
||||
}
|
||||
|
||||
#define float32_zero make_float32(0)
|
||||
#define float32_one make_float32(0x3f800000)
|
||||
#define float32_half make_float32(0x3f000000)
|
||||
#define float32_one make_float32(0x3f800000)
|
||||
#define float32_one_point_five make_float32(0x3fc00000)
|
||||
#define float32_two make_float32(0x40000000)
|
||||
#define float32_three make_float32(0x40400000)
|
||||
#define float32_infinity make_float32(0x7f800000)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated single-precision NaN.
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -526,9 +531,12 @@ static inline float64 float64_set_sign(float64 a, int sign)
|
||||
}
|
||||
|
||||
#define float64_zero make_float64(0)
|
||||
#define float64_one make_float64(0x3ff0000000000000LL)
|
||||
#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
|
||||
#define float64_half make_float64(0x3fe0000000000000LL)
|
||||
#define float64_one make_float64(0x3ff0000000000000LL)
|
||||
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
|
||||
#define float64_two make_float64(0x4000000000000000ULL)
|
||||
#define float64_three make_float64(0x4008000000000000ULL)
|
||||
#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
|
||||
#define float64_infinity make_float64(0x7ff0000000000000LL)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
||||
+19
-4
@@ -25,8 +25,7 @@ typedef struct I2CSlave I2CSlave;
|
||||
#define I2C_SLAVE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
|
||||
|
||||
typedef struct I2CSlaveClass
|
||||
{
|
||||
typedef struct I2CSlaveClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
/* Callbacks provided by the device. */
|
||||
@@ -50,14 +49,30 @@ typedef struct I2CSlaveClass
|
||||
int (*event)(I2CSlave *s, enum i2c_event event);
|
||||
} I2CSlaveClass;
|
||||
|
||||
struct I2CSlave
|
||||
{
|
||||
struct I2CSlave {
|
||||
DeviceState qdev;
|
||||
|
||||
/* Remaining fields for internal use by the I2C code. */
|
||||
uint8_t address;
|
||||
};
|
||||
|
||||
#define TYPE_I2C_BUS "i2c-bus"
|
||||
#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
|
||||
|
||||
typedef struct I2CNode I2CNode;
|
||||
|
||||
struct I2CNode {
|
||||
I2CSlave *elt;
|
||||
QLIST_ENTRY(I2CNode) next;
|
||||
};
|
||||
|
||||
struct I2CBus {
|
||||
BusState qbus;
|
||||
QLIST_HEAD(, I2CNode) current_devs;
|
||||
uint8_t saved_address;
|
||||
bool broadcast;
|
||||
};
|
||||
|
||||
I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
|
||||
void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
|
||||
int i2c_bus_busy(I2CBus *bus);
|
||||
|
||||
@@ -34,7 +34,7 @@ typedef struct RegisterInfoArray RegisterInfoArray;
|
||||
* immediately before the actual write. The returned value is what is written,
|
||||
* giving the handler a chance to modify the written value.
|
||||
* @post_write: Post write callback. Passed the written value. Most write side
|
||||
* effects should be implemented here.
|
||||
* effects should be implemented here. This is called during device reset.
|
||||
*
|
||||
* @post_read: Post read callback. Passes the value that is about to be returned
|
||||
* for a read. The return value from this function is what is ultimately read,
|
||||
@@ -135,8 +135,8 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
|
||||
bool debug);
|
||||
|
||||
/**
|
||||
* reset a register
|
||||
* @reg: register to reset
|
||||
* Resets a register. This will also call the post_write hook if it exists.
|
||||
* @reg: The register to reset.
|
||||
*/
|
||||
|
||||
void register_reset(RegisterInfo *reg);
|
||||
|
||||
@@ -551,6 +551,8 @@ static uint32_t get_elf_hwcap(void)
|
||||
GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
|
||||
GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
|
||||
GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
|
||||
GET_FEATURE(ARM_FEATURE_V8_FP16,
|
||||
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
|
||||
#undef GET_FEATURE
|
||||
|
||||
return hwcaps;
|
||||
|
||||
+27
-7
@@ -168,6 +168,7 @@ typedef struct {
|
||||
* Qn = regs[n].d[1]:regs[n].d[0]
|
||||
* Dn = regs[n].d[0]
|
||||
* Sn = regs[n].d[0] bits 31..0
|
||||
* Hn = regs[n].d[0] bits 15..0
|
||||
*
|
||||
* This corresponds to the architecturally defined mapping between
|
||||
* the two execution states, and means we do not need to explicitly
|
||||
@@ -537,19 +538,29 @@ typedef struct CPUARMState {
|
||||
/* scratch space when Tn are not sufficient. */
|
||||
uint32_t scratch[8];
|
||||
|
||||
/* fp_status is the "normal" fp status. standard_fp_status retains
|
||||
* values corresponding to the ARM "Standard FPSCR Value", ie
|
||||
* default-NaN, flush-to-zero, round-to-nearest and is used by
|
||||
* any operations (generally Neon) which the architecture defines
|
||||
* as controlled by the standard FPSCR value rather than the FPSCR.
|
||||
/* There are a number of distinct float control structures:
|
||||
*
|
||||
* fp_status: is the "normal" fp status.
|
||||
* fp_status_fp16: used for half-precision calculations
|
||||
* standard_fp_status : the ARM "Standard FPSCR Value"
|
||||
*
|
||||
* Half-precision operations are governed by a separate
|
||||
* flush-to-zero control bit in FPSCR:FZ16. We pass a separate
|
||||
* status structure to control this.
|
||||
*
|
||||
* The "Standard FPSCR", ie default-NaN, flush-to-zero,
|
||||
* round-to-nearest and is used by any operations (generally
|
||||
* Neon) which the architecture defines as controlled by the
|
||||
* standard FPSCR value rather than the FPSCR.
|
||||
*
|
||||
* To avoid having to transfer exception bits around, we simply
|
||||
* say that the FPSCR cumulative exception flags are the logical
|
||||
* OR of the flags in the two fp statuses. This relies on the
|
||||
* OR of the flags in the three fp statuses. This relies on the
|
||||
* only thing which needs to read the exception flags being
|
||||
* an explicit FPSCR read.
|
||||
*/
|
||||
float_status fp_status;
|
||||
float_status fp_status_f16;
|
||||
float_status standard_fp_status;
|
||||
|
||||
/* ZCR_EL[1-3] */
|
||||
@@ -1189,12 +1200,20 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
uint32_t vfp_get_fpscr(CPUARMState *env);
|
||||
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
|
||||
|
||||
/* For A64 the FPSCR is split into two logically distinct registers,
|
||||
/* FPCR, Floating Point Control Register
|
||||
* FPSR, Floating Poiht Status Register
|
||||
*
|
||||
* For A64 the FPSCR is split into two logically distinct registers,
|
||||
* FPCR and FPSR. However since they still use non-overlapping bits
|
||||
* we store the underlying state in fpscr and just mask on read/write.
|
||||
*/
|
||||
#define FPSR_MASK 0xf800009f
|
||||
#define FPCR_MASK 0x07f79f00
|
||||
|
||||
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
|
||||
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
|
||||
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
|
||||
|
||||
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
|
||||
{
|
||||
return vfp_get_fpscr(env) & FPSR_MASK;
|
||||
@@ -1408,6 +1427,7 @@ enum arm_features {
|
||||
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
|
||||
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
|
||||
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
|
||||
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
|
||||
};
|
||||
|
||||
static inline int arm_feature(CPUARMState *env, int feature)
|
||||
|
||||
@@ -230,6 +230,7 @@ static void aarch64_any_initfn(Object *obj)
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
|
||||
set_feature(&cpu->env, ARM_FEATURE_CRC);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
|
||||
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
|
||||
cpu->dcz_blocksize = 7; /* 512 bytes */
|
||||
}
|
||||
|
||||
@@ -192,6 +192,10 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
|
||||
* versions, these do a fully fused multiply-add or
|
||||
* multiply-add-and-halve.
|
||||
*/
|
||||
#define float16_two make_float16(0x4000)
|
||||
#define float16_three make_float16(0x4200)
|
||||
#define float16_one_point_five make_float16(0x3e00)
|
||||
|
||||
#define float32_two make_float32(0x40000000)
|
||||
#define float32_three make_float32(0x40400000)
|
||||
#define float32_one_point_five make_float32(0x3fc00000)
|
||||
@@ -200,6 +204,21 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
|
||||
#define float64_three make_float64(0x4008000000000000ULL)
|
||||
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
|
||||
|
||||
float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
a = float16_squash_input_denormal(a, fpst);
|
||||
b = float16_squash_input_denormal(b, fpst);
|
||||
|
||||
a = float16_chs(a);
|
||||
if ((float16_is_infinity(a) && float16_is_zero(b)) ||
|
||||
(float16_is_infinity(b) && float16_is_zero(a))) {
|
||||
return float16_two;
|
||||
}
|
||||
return float16_muladd(a, b, float16_two, 0, fpst);
|
||||
}
|
||||
|
||||
float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
@@ -230,6 +249,21 @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
|
||||
return float64_muladd(a, b, float64_two, 0, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
a = float16_squash_input_denormal(a, fpst);
|
||||
b = float16_squash_input_denormal(b, fpst);
|
||||
|
||||
a = float16_chs(a);
|
||||
if ((float16_is_infinity(a) && float16_is_zero(b)) ||
|
||||
(float16_is_infinity(b) && float16_is_zero(a))) {
|
||||
return float16_one_point_five;
|
||||
}
|
||||
return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
|
||||
}
|
||||
|
||||
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
@@ -322,6 +356,35 @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
|
||||
}
|
||||
|
||||
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
|
||||
float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
uint16_t val16, sbit;
|
||||
int16_t exp;
|
||||
|
||||
if (float16_is_any_nan(a)) {
|
||||
float16 nan = a;
|
||||
if (float16_is_signaling_nan(a, fpst)) {
|
||||
float_raise(float_flag_invalid, fpst);
|
||||
nan = float16_maybe_silence_nan(a, fpst);
|
||||
}
|
||||
if (fpst->default_nan_mode) {
|
||||
nan = float16_default_nan(fpst);
|
||||
}
|
||||
return nan;
|
||||
}
|
||||
|
||||
val16 = float16_val(a);
|
||||
sbit = 0x8000 & val16;
|
||||
exp = extract32(val16, 10, 5);
|
||||
|
||||
if (exp == 0) {
|
||||
return make_float16(deposit32(sbit, 10, 5, 0x1e));
|
||||
} else {
|
||||
return make_float16(deposit32(sbit, 10, 5, ~exp));
|
||||
}
|
||||
}
|
||||
|
||||
float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
@@ -572,3 +635,209 @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
|
||||
{
|
||||
return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
|
||||
}
|
||||
|
||||
/*
|
||||
* AdvSIMD half-precision
|
||||
*/
|
||||
|
||||
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
|
||||
|
||||
#define ADVSIMD_HALFOP(name) \
|
||||
float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
return float16_ ## name(a, b, fpst); \
|
||||
}
|
||||
|
||||
ADVSIMD_HALFOP(add)
|
||||
ADVSIMD_HALFOP(sub)
|
||||
ADVSIMD_HALFOP(mul)
|
||||
ADVSIMD_HALFOP(div)
|
||||
ADVSIMD_HALFOP(min)
|
||||
ADVSIMD_HALFOP(max)
|
||||
ADVSIMD_HALFOP(minnum)
|
||||
ADVSIMD_HALFOP(maxnum)
|
||||
|
||||
#define ADVSIMD_TWOHALFOP(name) \
|
||||
uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, void *fpstp) \
|
||||
{ \
|
||||
float16 a1, a2, b1, b2; \
|
||||
uint32_t r1, r2; \
|
||||
float_status *fpst = fpstp; \
|
||||
a1 = extract32(two_a, 0, 16); \
|
||||
a2 = extract32(two_a, 16, 16); \
|
||||
b1 = extract32(two_b, 0, 16); \
|
||||
b2 = extract32(two_b, 16, 16); \
|
||||
r1 = float16_ ## name(a1, b1, fpst); \
|
||||
r2 = float16_ ## name(a2, b2, fpst); \
|
||||
return deposit32(r1, 16, 16, r2); \
|
||||
}
|
||||
|
||||
ADVSIMD_TWOHALFOP(add)
|
||||
ADVSIMD_TWOHALFOP(sub)
|
||||
ADVSIMD_TWOHALFOP(mul)
|
||||
ADVSIMD_TWOHALFOP(div)
|
||||
ADVSIMD_TWOHALFOP(min)
|
||||
ADVSIMD_TWOHALFOP(max)
|
||||
ADVSIMD_TWOHALFOP(minnum)
|
||||
ADVSIMD_TWOHALFOP(maxnum)
|
||||
|
||||
/* Data processing - scalar floating-point and advanced SIMD */
|
||||
static float16 float16_mulx(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
a = float16_squash_input_denormal(a, fpst);
|
||||
b = float16_squash_input_denormal(b, fpst);
|
||||
|
||||
if ((float16_is_zero(a) && float16_is_infinity(b)) ||
|
||||
(float16_is_infinity(a) && float16_is_zero(b))) {
|
||||
/* 2.0 with the sign bit set to sign(A) XOR sign(B) */
|
||||
return make_float16((1U << 14) |
|
||||
((float16_val(a) ^ float16_val(b)) & (1U << 15)));
|
||||
}
|
||||
return float16_mul(a, b, fpst);
|
||||
}
|
||||
|
||||
ADVSIMD_HALFOP(mulx)
|
||||
ADVSIMD_TWOHALFOP(mulx)
|
||||
|
||||
/* fused multiply-accumulate */
|
||||
float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
return float16_muladd(a, b, c, 0, fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
|
||||
uint32_t two_c, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 a1, a2, b1, b2, c1, c2;
|
||||
uint32_t r1, r2;
|
||||
a1 = extract32(two_a, 0, 16);
|
||||
a2 = extract32(two_a, 16, 16);
|
||||
b1 = extract32(two_b, 0, 16);
|
||||
b2 = extract32(two_b, 16, 16);
|
||||
c1 = extract32(two_c, 0, 16);
|
||||
c2 = extract32(two_c, 16, 16);
|
||||
r1 = float16_muladd(a1, b1, c1, 0, fpst);
|
||||
r2 = float16_muladd(a2, b2, c2, 0, fpst);
|
||||
return deposit32(r1, 16, 16, r2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Floating point comparisons produce an integer result. Softfloat
|
||||
* routines return float_relation types which we convert to the 0/-1
|
||||
* Neon requires.
|
||||
*/
|
||||
|
||||
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
|
||||
|
||||
uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare_quiet(a, b, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare(a, b, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_greater ||
|
||||
compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare(a, b, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_greater);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 f0 = float16_abs(a);
|
||||
float16 f1 = float16_abs(b);
|
||||
int compare = float16_compare(f0, f1, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_greater ||
|
||||
compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 f0 = float16_abs(a);
|
||||
float16 f1 = float16_abs(b);
|
||||
int compare = float16_compare(f0, f1, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_greater);
|
||||
}
|
||||
|
||||
/* round to integral */
|
||||
float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
|
||||
{
|
||||
return float16_round_to_int(x, fp_status);
|
||||
}
|
||||
|
||||
float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
|
||||
{
|
||||
int old_flags = get_float_exception_flags(fp_status), new_flags;
|
||||
float16 ret;
|
||||
|
||||
ret = float16_round_to_int(x, fp_status);
|
||||
|
||||
/* Suppress any inexact exceptions the conversion produced */
|
||||
if (!(old_flags & float_flag_inexact)) {
|
||||
new_flags = get_float_exception_flags(fp_status);
|
||||
set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Half-precision floating point conversion functions
|
||||
*
|
||||
* There are a multitude of conversion functions with various
|
||||
* different rounding modes. This is dealt with by the calling code
|
||||
* setting the mode appropriately before calling the helper.
|
||||
*/
|
||||
|
||||
uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
/* Invalid if we are passed a NaN */
|
||||
if (float16_is_any_nan(a)) {
|
||||
float_raise(float_flag_invalid, fpst);
|
||||
return 0;
|
||||
}
|
||||
return float16_to_int16(a, fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
/* Invalid if we are passed a NaN */
|
||||
if (float16_is_any_nan(a)) {
|
||||
float_raise(float_flag_invalid, fpst);
|
||||
return 0;
|
||||
}
|
||||
return float16_to_uint16(a, fpst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Square Root and Reciprocal square root
|
||||
*/
|
||||
|
||||
float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
|
||||
{
|
||||
float_status *s = fpstp;
|
||||
|
||||
return float16_sqrt(a, s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,8 +29,10 @@ DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
|
||||
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
|
||||
DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
|
||||
DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
|
||||
DEF_HELPER_FLAGS_3(recpsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
|
||||
DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
|
||||
DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
|
||||
DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
|
||||
DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64)
|
||||
@@ -39,6 +41,7 @@ DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64)
|
||||
DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
|
||||
DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
|
||||
DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, env)
|
||||
DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
|
||||
@@ -48,3 +51,33 @@ DEF_HELPER_FLAGS_4(paired_cmpxchg64_le_parallel, TCG_CALL_NO_WG,
|
||||
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be_parallel, TCG_CALL_NO_WG,
|
||||
i64, env, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_addh, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_subh, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_mulh, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_divh, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_mulxh, f16, f16, f16, ptr)
|
||||
DEF_HELPER_4(advsimd_muladdh, f16, f16, f16, f16, ptr)
|
||||
DEF_HELPER_3(advsimd_add2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_sub2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_mul2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_div2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_max2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_min2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_maxnum2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_minnum2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
|
||||
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
|
||||
DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
|
||||
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
|
||||
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
|
||||
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
|
||||
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
|
||||
|
||||
+258
-223
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user