mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-tcg-20230915-2' of https://gitlab.com/rth7680/qemu into staging
*: Delete checks for old host definitions tcg/loongarch64: Generate LSX instructions fpu: Add conversions between bfloat16 and [u]int8 fpu: Handle m68k extended precision denormals properly accel/tcg: Improve cputlb i/o organization accel/tcg: Simplify tlb_plugin_lookup accel/tcg: Remove false-negative halted assertion tcg: Add gvec compare with immediate and scalar operand tcg/aarch64: Emit BTI insns at jump landing pads [Resolved conflict between CPUINFO_PMULL and CPUINFO_BTI. --Stefan] * tag 'pull-tcg-20230915-2' of https://gitlab.com/rth7680/qemu: (39 commits) tcg: Map code_gen_buffer with PROT_BTI tcg/aarch64: Emit BTI insns at jump landing pads util/cpuinfo-aarch64: Add CPUINFO_BTI tcg: Add tcg_out_tb_start backend hook fpu: Handle m68k extended precision denormals properly fpu: Add conversions between bfloat16 and [u]int8 accel/tcg: Introduce do_st16_mmio_leN accel/tcg: Introduce do_ld16_mmio_beN accel/tcg: Merge io_writex into do_st_mmio_leN accel/tcg: Merge io_readx into do_ld_mmio_beN accel/tcg: Replace direct use of io_readx/io_writex in do_{ld,st}_1 accel/tcg: Merge cpu_transaction_failed into io_failed plugin: Simplify struct qemu_plugin_hwaddr accel/tcg: Use CPUTLBEntryFull.phys_addr in io_failed accel/tcg: Split out io_prepare and io_failed accel/tcg: Simplify tlb_plugin_lookup target/arm: Use tcg_gen_gvec_cmpi for compare vs 0 tcg: Add gvec compare with immediate and scalar operand tcg/loongarch64: Implement 128-bit load & store tcg/loongarch64: Lower rotli_vec to vrotri ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
+211
-226
File diff suppressed because it is too large
Load Diff
@@ -100,14 +100,9 @@ static void *mttcg_cpu_thread_fn(void *arg)
|
||||
break;
|
||||
case EXCP_HALTED:
|
||||
/*
|
||||
* during start-up the vCPU is reset and the thread is
|
||||
* kicked several times. If we don't ensure we go back
|
||||
* to sleep in the halted state we won't cleanly
|
||||
* start-up when the vCPU is enabled.
|
||||
*
|
||||
* cpu->halted should ensure we sleep in wait_io_event
|
||||
* Usually cpu->halted is set, but may have already been
|
||||
* reset by another thread by the time we arrive here.
|
||||
*/
|
||||
g_assert(cpu->halted);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
||||
@@ -1042,6 +1042,32 @@ DO_CMP2(64)
|
||||
#undef DO_CMP1
|
||||
#undef DO_CMP2
|
||||
|
||||
#define DO_CMP1(NAME, TYPE, OP) \
|
||||
void HELPER(NAME)(void *d, void *a, uint64_t b64, uint32_t desc) \
|
||||
{ \
|
||||
intptr_t oprsz = simd_oprsz(desc); \
|
||||
TYPE inv = simd_data(desc), b = b64; \
|
||||
for (intptr_t i = 0; i < oprsz; i += sizeof(TYPE)) { \
|
||||
*(TYPE *)(d + i) = -((*(TYPE *)(a + i) OP b) ^ inv); \
|
||||
} \
|
||||
clear_high(d, oprsz, desc); \
|
||||
}
|
||||
|
||||
#define DO_CMP2(SZ) \
|
||||
DO_CMP1(gvec_eqs##SZ, uint##SZ##_t, ==) \
|
||||
DO_CMP1(gvec_lts##SZ, int##SZ##_t, <) \
|
||||
DO_CMP1(gvec_les##SZ, int##SZ##_t, <=) \
|
||||
DO_CMP1(gvec_ltus##SZ, uint##SZ##_t, <) \
|
||||
DO_CMP1(gvec_leus##SZ, uint##SZ##_t, <=)
|
||||
|
||||
DO_CMP2(8)
|
||||
DO_CMP2(16)
|
||||
DO_CMP2(32)
|
||||
DO_CMP2(64)
|
||||
|
||||
#undef DO_CMP1
|
||||
#undef DO_CMP2
|
||||
|
||||
void HELPER(gvec_ssadd8)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
|
||||
@@ -297,4 +297,29 @@ DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_eqs8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_eqs16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_eqs32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_eqs64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_lts8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_lts16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_lts32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_lts64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_les8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_les16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_les32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_les64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_ltus8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_ltus16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_ltus32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_ltus64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_leus8, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leus16, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leus32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leus64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
@@ -118,7 +118,8 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
|
||||
} else {
|
||||
int shift = frac_normalize(p);
|
||||
p->cls = float_class_normal;
|
||||
p->exp = fmt->frac_shift - fmt->exp_bias - shift + 1;
|
||||
p->exp = fmt->frac_shift - fmt->exp_bias
|
||||
- shift + !fmt->m68k_denormal;
|
||||
}
|
||||
} else if (likely(p->exp < fmt->exp_max) || fmt->arm_althp) {
|
||||
p->cls = float_class_normal;
|
||||
@@ -256,7 +257,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
|
||||
is_tiny = !frac_addi(&discard, p, inc);
|
||||
}
|
||||
|
||||
frac_shrjam(p, 1 - exp);
|
||||
frac_shrjam(p, !fmt->m68k_denormal - exp);
|
||||
|
||||
if (p->frac_lo & round_mask) {
|
||||
/* Need to recompute round-to-even/round-to-odd. */
|
||||
@@ -287,7 +288,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
|
||||
p->frac_lo &= ~round_mask;
|
||||
}
|
||||
|
||||
exp = (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) != 0;
|
||||
exp = (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) && !fmt->m68k_denormal;
|
||||
frac_shr(p, frac_shift);
|
||||
|
||||
if (is_tiny && (flags & float_flag_inexact)) {
|
||||
|
||||
+66
-1
@@ -517,6 +517,7 @@ typedef struct {
|
||||
* round_mask: bits below lsb which must be rounded
|
||||
* The following optional modifiers are available:
|
||||
* arm_althp: handle ARM Alternative Half Precision
|
||||
* m68k_denormal: explicit integer bit for extended precision may be 1
|
||||
*/
|
||||
typedef struct {
|
||||
int exp_size;
|
||||
@@ -526,6 +527,7 @@ typedef struct {
|
||||
int frac_size;
|
||||
int frac_shift;
|
||||
bool arm_althp;
|
||||
bool m68k_denormal;
|
||||
uint64_t round_mask;
|
||||
} FloatFmt;
|
||||
|
||||
@@ -576,7 +578,12 @@ static const FloatFmt float128_params = {
|
||||
static const FloatFmt floatx80_params[3] = {
|
||||
[floatx80_precision_s] = { FLOATX80_PARAMS(23) },
|
||||
[floatx80_precision_d] = { FLOATX80_PARAMS(52) },
|
||||
[floatx80_precision_x] = { FLOATX80_PARAMS(64) },
|
||||
[floatx80_precision_x] = {
|
||||
FLOATX80_PARAMS(64),
|
||||
#ifdef TARGET_M68K
|
||||
.m68k_denormal = true,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
/* Unpack a float to parts, but do not canonicalize. */
|
||||
@@ -3126,6 +3133,15 @@ int64_t float64_to_int64_scalbn(float64 a, FloatRoundMode rmode, int scale,
|
||||
return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
|
||||
}
|
||||
|
||||
int8_t bfloat16_to_int8_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
|
||||
float_status *s)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
||||
bfloat16_unpack_canonical(&p, a, s);
|
||||
return parts_float_to_sint(&p, rmode, scale, INT8_MIN, INT8_MAX, s);
|
||||
}
|
||||
|
||||
int16_t bfloat16_to_int16_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
|
||||
float_status *s)
|
||||
{
|
||||
@@ -3392,6 +3408,11 @@ int64_t floatx80_to_int64_round_to_zero(floatx80 a, float_status *s)
|
||||
return floatx80_to_int64_scalbn(a, float_round_to_zero, 0, s);
|
||||
}
|
||||
|
||||
int8_t bfloat16_to_int8(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_int8_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
}
|
||||
|
||||
int16_t bfloat16_to_int16(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
@@ -3407,6 +3428,11 @@ int64_t bfloat16_to_int64(bfloat16 a, float_status *s)
|
||||
return bfloat16_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
}
|
||||
|
||||
int8_t bfloat16_to_int8_round_to_zero(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_int8_scalbn(a, float_round_to_zero, 0, s);
|
||||
}
|
||||
|
||||
int16_t bfloat16_to_int16_round_to_zero(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_int16_scalbn(a, float_round_to_zero, 0, s);
|
||||
@@ -3534,6 +3560,15 @@ uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int scale,
|
||||
return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
|
||||
}
|
||||
|
||||
uint8_t bfloat16_to_uint8_scalbn(bfloat16 a, FloatRoundMode rmode,
|
||||
int scale, float_status *s)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
||||
bfloat16_unpack_canonical(&p, a, s);
|
||||
return parts_float_to_uint(&p, rmode, scale, UINT8_MAX, s);
|
||||
}
|
||||
|
||||
uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode,
|
||||
int scale, float_status *s)
|
||||
{
|
||||
@@ -3759,6 +3794,11 @@ Int128 float128_to_uint128_round_to_zero(float128 a, float_status *s)
|
||||
return float128_to_uint128_scalbn(a, float_round_to_zero, 0, s);
|
||||
}
|
||||
|
||||
uint8_t bfloat16_to_uint8(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
}
|
||||
|
||||
uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
@@ -3774,6 +3814,11 @@ uint64_t bfloat16_to_uint64(bfloat16 a, float_status *s)
|
||||
return bfloat16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
|
||||
}
|
||||
|
||||
uint8_t bfloat16_to_uint8_round_to_zero(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_uint8_scalbn(a, float_round_to_zero, 0, s);
|
||||
}
|
||||
|
||||
uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *s)
|
||||
{
|
||||
return bfloat16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
|
||||
@@ -3929,6 +3974,11 @@ bfloat16 int16_to_bfloat16_scalbn(int16_t a, int scale, float_status *status)
|
||||
return int64_to_bfloat16_scalbn(a, scale, status);
|
||||
}
|
||||
|
||||
bfloat16 int8_to_bfloat16_scalbn(int8_t a, int scale, float_status *status)
|
||||
{
|
||||
return int64_to_bfloat16_scalbn(a, scale, status);
|
||||
}
|
||||
|
||||
bfloat16 int64_to_bfloat16(int64_t a, float_status *status)
|
||||
{
|
||||
return int64_to_bfloat16_scalbn(a, 0, status);
|
||||
@@ -3944,6 +3994,11 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status *status)
|
||||
return int64_to_bfloat16_scalbn(a, 0, status);
|
||||
}
|
||||
|
||||
bfloat16 int8_to_bfloat16(int8_t a, float_status *status)
|
||||
{
|
||||
return int64_to_bfloat16_scalbn(a, 0, status);
|
||||
}
|
||||
|
||||
float128 int128_to_float128(Int128 a, float_status *status)
|
||||
{
|
||||
FloatParts128 p = { };
|
||||
@@ -4139,6 +4194,11 @@ bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int scale, float_status *status)
|
||||
return uint64_to_bfloat16_scalbn(a, scale, status);
|
||||
}
|
||||
|
||||
bfloat16 uint8_to_bfloat16_scalbn(uint8_t a, int scale, float_status *status)
|
||||
{
|
||||
return uint64_to_bfloat16_scalbn(a, scale, status);
|
||||
}
|
||||
|
||||
bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status)
|
||||
{
|
||||
return uint64_to_bfloat16_scalbn(a, 0, status);
|
||||
@@ -4154,6 +4214,11 @@ bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status)
|
||||
return uint64_to_bfloat16_scalbn(a, 0, status);
|
||||
}
|
||||
|
||||
bfloat16 uint8_to_bfloat16(uint8_t a, float_status *status)
|
||||
{
|
||||
return uint64_to_bfloat16_scalbn(a, 0, status);
|
||||
}
|
||||
|
||||
float128 uint64_to_float128(uint64_t a, float_status *status)
|
||||
{
|
||||
FloatParts128 p;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define CPUINFO_LSE2 (1u << 2)
|
||||
#define CPUINFO_AES (1u << 3)
|
||||
#define CPUINFO_PMULL (1u << 4)
|
||||
#define CPUINFO_BTI (1u << 5)
|
||||
|
||||
/* Initialized with a constructor. */
|
||||
extern unsigned cpuinfo;
|
||||
|
||||
@@ -100,12 +100,12 @@
|
||||
typedef struct CPUTLBEntryFull {
|
||||
/*
|
||||
* @xlat_section contains:
|
||||
* - in the lower TARGET_PAGE_BITS, a physical section number
|
||||
* - with the lower TARGET_PAGE_BITS masked off, an offset which
|
||||
* must be added to the virtual address to obtain:
|
||||
* + the ram_addr_t of the target RAM (if the physical section
|
||||
* number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
|
||||
* + the offset within the target MemoryRegion (otherwise)
|
||||
* - For ram, an offset which must be added to the virtual address
|
||||
* to obtain the ram_addr_t of the target RAM
|
||||
* - For other memory regions,
|
||||
* + in the lower TARGET_PAGE_BITS, the physical section number
|
||||
* + with the TARGET_PAGE_BITS masked off, the offset within
|
||||
* the target MemoryRegion
|
||||
*/
|
||||
hwaddr xlat_section;
|
||||
|
||||
|
||||
@@ -111,8 +111,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||
if (is_host) {
|
||||
#if defined(HOST_X86_64)
|
||||
return 8;
|
||||
#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
|
||||
defined(HOST_PARISC) || defined(HOST_SPARC64)
|
||||
#elif defined(HOST_MIPS) || defined(HOST_SPARC64)
|
||||
return 4;
|
||||
#elif defined(HOST_PPC)
|
||||
return sizeof(void *);
|
||||
|
||||
@@ -366,6 +366,8 @@ float32 bfloat16_to_float32(bfloat16, float_status *status);
|
||||
bfloat16 float64_to_bfloat16(float64 a, float_status *status);
|
||||
float64 bfloat16_to_float64(bfloat16 a, float_status *status);
|
||||
|
||||
int8_t bfloat16_to_int8_scalbn(bfloat16, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
int16_t bfloat16_to_int16_scalbn(bfloat16, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
int32_t bfloat16_to_int32_scalbn(bfloat16, FloatRoundMode,
|
||||
@@ -373,14 +375,18 @@ int32_t bfloat16_to_int32_scalbn(bfloat16, FloatRoundMode,
|
||||
int64_t bfloat16_to_int64_scalbn(bfloat16, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
|
||||
int8_t bfloat16_to_int8(bfloat16, float_status *status);
|
||||
int16_t bfloat16_to_int16(bfloat16, float_status *status);
|
||||
int32_t bfloat16_to_int32(bfloat16, float_status *status);
|
||||
int64_t bfloat16_to_int64(bfloat16, float_status *status);
|
||||
|
||||
int8_t bfloat16_to_int8_round_to_zero(bfloat16, float_status *status);
|
||||
int16_t bfloat16_to_int16_round_to_zero(bfloat16, float_status *status);
|
||||
int32_t bfloat16_to_int32_round_to_zero(bfloat16, float_status *status);
|
||||
int64_t bfloat16_to_int64_round_to_zero(bfloat16, float_status *status);
|
||||
|
||||
uint8_t bfloat16_to_uint8_scalbn(bfloat16 a, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode,
|
||||
@@ -388,24 +394,30 @@ uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode,
|
||||
uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode,
|
||||
int, float_status *status);
|
||||
|
||||
uint8_t bfloat16_to_uint8(bfloat16 a, float_status *status);
|
||||
uint16_t bfloat16_to_uint16(bfloat16 a, float_status *status);
|
||||
uint32_t bfloat16_to_uint32(bfloat16 a, float_status *status);
|
||||
uint64_t bfloat16_to_uint64(bfloat16 a, float_status *status);
|
||||
|
||||
uint8_t bfloat16_to_uint8_round_to_zero(bfloat16 a, float_status *status);
|
||||
uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *status);
|
||||
uint32_t bfloat16_to_uint32_round_to_zero(bfloat16 a, float_status *status);
|
||||
uint64_t bfloat16_to_uint64_round_to_zero(bfloat16 a, float_status *status);
|
||||
|
||||
bfloat16 int8_to_bfloat16_scalbn(int8_t a, int, float_status *status);
|
||||
bfloat16 int16_to_bfloat16_scalbn(int16_t a, int, float_status *status);
|
||||
bfloat16 int32_to_bfloat16_scalbn(int32_t a, int, float_status *status);
|
||||
bfloat16 int64_to_bfloat16_scalbn(int64_t a, int, float_status *status);
|
||||
bfloat16 uint8_to_bfloat16_scalbn(uint8_t a, int, float_status *status);
|
||||
bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int, float_status *status);
|
||||
bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int, float_status *status);
|
||||
bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int, float_status *status);
|
||||
|
||||
bfloat16 int8_to_bfloat16(int8_t a, float_status *status);
|
||||
bfloat16 int16_to_bfloat16(int16_t a, float_status *status);
|
||||
bfloat16 int32_to_bfloat16(int32_t a, float_status *status);
|
||||
bfloat16 int64_to_bfloat16(int64_t a, float_status *status);
|
||||
bfloat16 uint8_to_bfloat16(uint8_t a, float_status *status);
|
||||
bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status);
|
||||
bfloat16 uint32_to_bfloat16(uint32_t a, float_status *status);
|
||||
bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status);
|
||||
|
||||
@@ -227,17 +227,6 @@ struct CPUWatchpoint {
|
||||
QTAILQ_ENTRY(CPUWatchpoint) entry;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PLUGIN
|
||||
/*
|
||||
* For plugins we sometime need to save the resolved iotlb data before
|
||||
* the memory regions get moved around by io_writex.
|
||||
*/
|
||||
typedef struct SavedIOTLB {
|
||||
MemoryRegionSection *section;
|
||||
hwaddr mr_offset;
|
||||
} SavedIOTLB;
|
||||
#endif
|
||||
|
||||
struct KVMState;
|
||||
struct kvm_run;
|
||||
|
||||
@@ -409,8 +398,6 @@ struct CPUState {
|
||||
|
||||
#ifdef CONFIG_PLUGIN
|
||||
GArray *plugin_mem_cbs;
|
||||
/* saved iotlb data from io_writex */
|
||||
SavedIOTLB saved_iotlb;
|
||||
#endif
|
||||
|
||||
/* TODO Move common fields from CPUArchState here. */
|
||||
|
||||
@@ -15,15 +15,8 @@
|
||||
struct qemu_plugin_hwaddr {
|
||||
bool is_io;
|
||||
bool is_store;
|
||||
union {
|
||||
struct {
|
||||
MemoryRegionSection *section;
|
||||
hwaddr offset;
|
||||
} io;
|
||||
struct {
|
||||
void *hostaddr;
|
||||
} ram;
|
||||
} v;
|
||||
hwaddr phys_addr;
|
||||
MemoryRegion *mr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -129,7 +129,6 @@ typedef struct QString QString;
|
||||
typedef struct RAMBlock RAMBlock;
|
||||
typedef struct Range Range;
|
||||
typedef struct ReservedRegion ReservedRegion;
|
||||
typedef struct SavedIOTLB SavedIOTLB;
|
||||
typedef struct SHPCDevice SHPCDevice;
|
||||
typedef struct SSIBus SSIBus;
|
||||
typedef struct TCGHelperInfo TCGHelperInfo;
|
||||
|
||||
@@ -374,6 +374,12 @@ void tcg_gen_gvec_rotrv(unsigned vece, uint32_t dofs, uint32_t aofs,
|
||||
void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, uint32_t dofs,
|
||||
uint32_t aofs, uint32_t bofs,
|
||||
uint32_t oprsz, uint32_t maxsz);
|
||||
void tcg_gen_gvec_cmpi(TCGCond cond, unsigned vece, uint32_t dofs,
|
||||
uint32_t aofs, int64_t c,
|
||||
uint32_t oprsz, uint32_t maxsz);
|
||||
void tcg_gen_gvec_cmps(TCGCond cond, unsigned vece, uint32_t dofs,
|
||||
uint32_t aofs, TCGv_i64 c,
|
||||
uint32_t oprsz, uint32_t maxsz);
|
||||
|
||||
/*
|
||||
* Perform vector bit select: d = (b & a) | (c & ~a).
|
||||
|
||||
+6
-21
@@ -316,22 +316,7 @@ uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr)
|
||||
{
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
if (haddr) {
|
||||
if (!haddr->is_io) {
|
||||
RAMBlock *block;
|
||||
ram_addr_t offset;
|
||||
void *hostaddr = haddr->v.ram.hostaddr;
|
||||
|
||||
block = qemu_ram_block_from_host(hostaddr, false, &offset);
|
||||
if (!block) {
|
||||
error_report("Bad host ram pointer %p", haddr->v.ram.hostaddr);
|
||||
abort();
|
||||
}
|
||||
|
||||
return block->offset + offset + block->mr->addr;
|
||||
} else {
|
||||
MemoryRegionSection *mrs = haddr->v.io.section;
|
||||
return mrs->offset_within_address_space + haddr->v.io.offset;
|
||||
}
|
||||
return haddr->phys_addr;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@@ -341,13 +326,13 @@ const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h)
|
||||
{
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
if (h && h->is_io) {
|
||||
MemoryRegionSection *mrs = h->v.io.section;
|
||||
if (!mrs->mr->name) {
|
||||
unsigned long maddr = 0xffffffff & (uintptr_t) mrs->mr;
|
||||
g_autofree char *temp = g_strdup_printf("anon%08lx", maddr);
|
||||
MemoryRegion *mr = h->mr;
|
||||
if (!mr->name) {
|
||||
unsigned maddr = (uintptr_t)mr;
|
||||
g_autofree char *temp = g_strdup_printf("anon%08x", maddr);
|
||||
return g_intern_string(temp);
|
||||
} else {
|
||||
return g_intern_string(mrs->mr->name);
|
||||
return g_intern_string(mr->name);
|
||||
}
|
||||
} else {
|
||||
return g_intern_static_string("RAM");
|
||||
|
||||
@@ -121,10 +121,7 @@ static void *new_stack_for_clone(void)
|
||||
|
||||
/* Allocate a new stack and get a pointer to its top. */
|
||||
stack_ptr = qemu_alloc_stack(&stack_size);
|
||||
#if !defined(HOST_HPPA)
|
||||
/* The top is at the end of the area, except on HPPA. */
|
||||
stack_ptr += stack_size;
|
||||
#endif
|
||||
|
||||
return stack_ptr;
|
||||
}
|
||||
|
||||
@@ -2943,54 +2943,16 @@ void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
|
||||
}
|
||||
|
||||
#define GEN_CMP0(NAME, COND) \
|
||||
static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
|
||||
{ \
|
||||
tcg_gen_negsetcond_i32(COND, d, a, tcg_constant_i32(0)); \
|
||||
} \
|
||||
static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
|
||||
{ \
|
||||
tcg_gen_negsetcond_i64(COND, d, a, tcg_constant_i64(0)); \
|
||||
} \
|
||||
static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
|
||||
{ \
|
||||
TCGv_vec zero = tcg_constant_vec_matching(d, vece, 0); \
|
||||
tcg_gen_cmp_vec(COND, vece, d, a, zero); \
|
||||
} \
|
||||
void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
|
||||
uint32_t opr_sz, uint32_t max_sz) \
|
||||
{ \
|
||||
const GVecGen2 op[4] = { \
|
||||
{ .fno = gen_helper_gvec_##NAME##0_b, \
|
||||
.fniv = gen_##NAME##0_vec, \
|
||||
.opt_opc = vecop_list_cmp, \
|
||||
.vece = MO_8 }, \
|
||||
{ .fno = gen_helper_gvec_##NAME##0_h, \
|
||||
.fniv = gen_##NAME##0_vec, \
|
||||
.opt_opc = vecop_list_cmp, \
|
||||
.vece = MO_16 }, \
|
||||
{ .fni4 = gen_##NAME##0_i32, \
|
||||
.fniv = gen_##NAME##0_vec, \
|
||||
.opt_opc = vecop_list_cmp, \
|
||||
.vece = MO_32 }, \
|
||||
{ .fni8 = gen_##NAME##0_i64, \
|
||||
.fniv = gen_##NAME##0_vec, \
|
||||
.opt_opc = vecop_list_cmp, \
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64, \
|
||||
.vece = MO_64 }, \
|
||||
}; \
|
||||
tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
|
||||
}
|
||||
#define GEN_CMP0(NAME, COND) \
|
||||
void NAME(unsigned vece, uint32_t d, uint32_t m, \
|
||||
uint32_t opr_sz, uint32_t max_sz) \
|
||||
{ tcg_gen_gvec_cmpi(COND, vece, d, m, 0, opr_sz, max_sz); }
|
||||
|
||||
static const TCGOpcode vecop_list_cmp[] = {
|
||||
INDEX_op_cmp_vec, 0
|
||||
};
|
||||
|
||||
GEN_CMP0(ceq, TCG_COND_EQ)
|
||||
GEN_CMP0(cle, TCG_COND_LE)
|
||||
GEN_CMP0(cge, TCG_COND_GE)
|
||||
GEN_CMP0(clt, TCG_COND_LT)
|
||||
GEN_CMP0(cgt, TCG_COND_GT)
|
||||
GEN_CMP0(gen_gvec_ceq0, TCG_COND_EQ)
|
||||
GEN_CMP0(gen_gvec_cle0, TCG_COND_LE)
|
||||
GEN_CMP0(gen_gvec_cge0, TCG_COND_GE)
|
||||
GEN_CMP0(gen_gvec_clt0, TCG_COND_LT)
|
||||
GEN_CMP0(gen_gvec_cgt0, TCG_COND_GT)
|
||||
|
||||
#undef GEN_CMP0
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
|
||||
}
|
||||
}
|
||||
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
|
||||
{
|
||||
if (ct & TCG_CT_CONST) {
|
||||
return 1;
|
||||
@@ -602,6 +602,10 @@ typedef enum {
|
||||
DMB_ISH = 0xd50338bf,
|
||||
DMB_LD = 0x00000100,
|
||||
DMB_ST = 0x00000200,
|
||||
|
||||
BTI_C = 0xd503245f,
|
||||
BTI_J = 0xd503249f,
|
||||
BTI_JC = 0xd50324df,
|
||||
} AArch64Insn;
|
||||
|
||||
static inline uint32_t tcg_in32(TCGContext *s)
|
||||
@@ -843,6 +847,17 @@ static void tcg_out_insn_3313(TCGContext *s, AArch64Insn insn,
|
||||
| rn << 5 | (rd & 0x1f));
|
||||
}
|
||||
|
||||
static void tcg_out_bti(TCGContext *s, AArch64Insn insn)
|
||||
{
|
||||
/*
|
||||
* While BTI insns are nops on hosts without FEAT_BTI,
|
||||
* there is no point in emitting them in that case either.
|
||||
*/
|
||||
if (cpuinfo & CPUINFO_BTI) {
|
||||
tcg_out32(s, insn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register to register move using ORR (shifted register with no shift). */
|
||||
static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rm)
|
||||
{
|
||||
@@ -1351,18 +1366,6 @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
|
||||
tcg_out_insn(s, 3206, B, offset);
|
||||
}
|
||||
|
||||
static void tcg_out_goto_long(TCGContext *s, const tcg_insn_unit *target)
|
||||
{
|
||||
ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2;
|
||||
if (offset == sextract64(offset, 0, 26)) {
|
||||
tcg_out_insn(s, 3206, B, offset);
|
||||
} else {
|
||||
/* Choose X9 as a call-clobbered non-LR temporary. */
|
||||
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X9, (intptr_t)target);
|
||||
tcg_out_insn(s, 3207, BR, TCG_REG_X9);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *target)
|
||||
{
|
||||
ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2;
|
||||
@@ -1947,12 +1950,28 @@ static const tcg_insn_unit *tb_ret_addr;
|
||||
|
||||
static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
|
||||
{
|
||||
const tcg_insn_unit *target;
|
||||
ptrdiff_t offset;
|
||||
|
||||
/* Reuse the zeroing that exists for goto_ptr. */
|
||||
if (a0 == 0) {
|
||||
tcg_out_goto_long(s, tcg_code_gen_epilogue);
|
||||
target = tcg_code_gen_epilogue;
|
||||
} else {
|
||||
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
|
||||
tcg_out_goto_long(s, tb_ret_addr);
|
||||
target = tb_ret_addr;
|
||||
}
|
||||
|
||||
offset = tcg_pcrel_diff(s, target) >> 2;
|
||||
if (offset == sextract64(offset, 0, 26)) {
|
||||
tcg_out_insn(s, 3206, B, offset);
|
||||
} else {
|
||||
/*
|
||||
* Only x16/x17 generate BTI type Jump (2),
|
||||
* other registers generate BTI type Jump|Call (3).
|
||||
*/
|
||||
QEMU_BUILD_BUG_ON(TCG_REG_TMP0 != TCG_REG_X16);
|
||||
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, (intptr_t)target);
|
||||
tcg_out_insn(s, 3207, BR, TCG_REG_TMP0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1970,6 +1989,7 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
|
||||
tcg_out32(s, I3206_B);
|
||||
tcg_out_insn(s, 3207, BR, TCG_REG_TMP0);
|
||||
set_jmp_reset_offset(s, which);
|
||||
tcg_out_bti(s, BTI_J);
|
||||
}
|
||||
|
||||
void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
|
||||
@@ -3074,6 +3094,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
{
|
||||
TCGReg r;
|
||||
|
||||
tcg_out_bti(s, BTI_C);
|
||||
|
||||
/* Push (FP, LR) and allocate space for all saved registers. */
|
||||
tcg_out_insn(s, 3314, STP, TCG_REG_FP, TCG_REG_LR,
|
||||
TCG_REG_SP, -PUSH_SIZE, 1, 1);
|
||||
@@ -3114,10 +3136,12 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
* and fall through to the rest of the epilogue.
|
||||
*/
|
||||
tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
|
||||
tcg_out_bti(s, BTI_J);
|
||||
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_X0, 0);
|
||||
|
||||
/* TB epilogue */
|
||||
tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
|
||||
tcg_out_bti(s, BTI_J);
|
||||
|
||||
/* Remove TCG locals stack space. */
|
||||
tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
|
||||
@@ -3135,6 +3159,11 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
tcg_out_insn(s, 3207, RET, TCG_REG_LR);
|
||||
}
|
||||
|
||||
static void tcg_out_tb_start(TCGContext *s)
|
||||
{
|
||||
tcg_out_bti(s, BTI_J);
|
||||
}
|
||||
|
||||
static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -509,7 +509,7 @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
|
||||
* mov operand2: values represented with x << (2 * y), x < 0x100
|
||||
* add, sub, eor...: ditto
|
||||
*/
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
|
||||
{
|
||||
if (ct & TCG_CT_CONST) {
|
||||
return 1;
|
||||
@@ -2962,6 +2962,11 @@ static void tcg_out_epilogue(TCGContext *s)
|
||||
(1 << TCG_REG_R10) | (1 << TCG_REG_R11) | (1 << TCG_REG_PC));
|
||||
}
|
||||
|
||||
static void tcg_out_tb_start(TCGContext *s)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
DebugFrameHeader h;
|
||||
uint8_t fde_def_cfa[4];
|
||||
|
||||
@@ -198,7 +198,7 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
||||
}
|
||||
|
||||
/* test if a constant matches the constraint */
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
|
||||
static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
|
||||
{
|
||||
if (ct & TCG_CT_CONST) {
|
||||
return 1;
|
||||
@@ -4191,6 +4191,11 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
tcg_out_opc(s, OPC_RET, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void tcg_out_tb_start(TCGContext *s)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
|
||||
{
|
||||
memset(p, 0x90, count);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user