dbus: Two hot fixes, per request of Marc-André Lureau
accel/tcg: Fix tb_invalidate_phys_range iteration fpu: Add float64_to_int{32,64}_modulo tcg: Reduce scope of tcg_assert_listed_vecop target/nios2: Explicitly ask for target-endian loads linux-user: Avoid mmap of the last byte of the reserved_va -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmSfzXwdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+GMAgAicMA7dZEUNiKT1co pwQNF/aQehs3a+UYcHFZRQWjwNsXzDrPRTAyBkDFrzR2ILxKlpPw2JBRiqrr9pqj YWit0pHVv/OAYfSEzcqUaIeWyAh2xlAT4IbSz+sLcPBdPgUwm3z0Y7mTz3kUAkB2 gXO/iuoD8ORwgSnFvH+FSws16kr1x/8cAaObY7BupUhS7hK8M9zsCehhk6ssxv7+ EpR0kDIeoC2kjJLvQAoGW4DPzfmAvVmI/OiJKpqrAlTJIeAkngalSuaxj/t9Dte6 zy4h8JW5VbHw3qLxTvg42/Pk4AiweBh38hpUfLQ2cprO7dy+T9qS2v8CGnMzrmeB kzlIMg== =a7vA -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20230701' of https://gitlab.com/rth7680/qemu into staging dbus: Two hot fixes, per request of Marc-André Lureau accel/tcg: Fix tb_invalidate_phys_range iteration fpu: Add float64_to_int{32,64}_modulo tcg: Reduce scope of tcg_assert_listed_vecop target/nios2: Explicitly ask for target-endian loads linux-user: Avoid mmap of the last byte of the reserved_va # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmSfzXwdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+GMAgAicMA7dZEUNiKT1co # pwQNF/aQehs3a+UYcHFZRQWjwNsXzDrPRTAyBkDFrzR2ILxKlpPw2JBRiqrr9pqj # YWit0pHVv/OAYfSEzcqUaIeWyAh2xlAT4IbSz+sLcPBdPgUwm3z0Y7mTz3kUAkB2 # gXO/iuoD8ORwgSnFvH+FSws16kr1x/8cAaObY7BupUhS7hK8M9zsCehhk6ssxv7+ # EpR0kDIeoC2kjJLvQAoGW4DPzfmAvVmI/OiJKpqrAlTJIeAkngalSuaxj/t9Dte6 # zy4h8JW5VbHw3qLxTvg42/Pk4AiweBh38hpUfLQ2cprO7dy+T9qS2v8CGnMzrmeB # kzlIMg== # =a7vA # -----END PGP SIGNATURE----- # gpg: Signature made Sat 01 Jul 2023 08:53:48 AM CEST # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * tag 'pull-tcg-20230701' of https://gitlab.com/rth7680/qemu: linux-user: Avoid mmap of the last byte of the reserved_va target/nios2 : Explicitly ask for target-endian loads and stores tcg: Reduce tcg_assert_listed_vecop() scope target/arm: Use float64_to_int32_modulo for FJCVTZS target/alpha: Use float64_to_int64_modulo for CVTTQ tests/tcg/alpha: Add test for cvttq fpu: Add float64_to_int{32,64}_modulo accel/tcg: Assert one page in tb_invalidate_phys_page_range__locked accel/tcg: Fix start page passed to tb_invalidate_phys_page_range__locked audio: dbus requires pixman ui/dbus: fix build errors in dbus_update_gl_cb and dbus_call_update_gl Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
d145c0da22
@ -1092,6 +1092,9 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
|
||||
TranslationBlock *current_tb = retaddr ? tcg_tb_lookup(retaddr) : NULL;
|
||||
#endif /* TARGET_HAS_PRECISE_SMC */
|
||||
|
||||
/* Range may not cross a page. */
|
||||
tcg_debug_assert(((start ^ last) & TARGET_PAGE_MASK) == 0);
|
||||
|
||||
/*
|
||||
* We remove all the TBs in the range [start, last].
|
||||
* XXX: see if in some cases it could be faster to invalidate all the code
|
||||
@ -1182,15 +1185,17 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last)
|
||||
index_last = last >> TARGET_PAGE_BITS;
|
||||
for (index = start >> TARGET_PAGE_BITS; index <= index_last; index++) {
|
||||
PageDesc *pd = page_find(index);
|
||||
tb_page_addr_t bound;
|
||||
tb_page_addr_t page_start, page_last;
|
||||
|
||||
if (pd == NULL) {
|
||||
continue;
|
||||
}
|
||||
assert_page_locked(pd);
|
||||
bound = (index << TARGET_PAGE_BITS) | ~TARGET_PAGE_MASK;
|
||||
bound = MIN(bound, last);
|
||||
tb_invalidate_phys_page_range__locked(pages, pd, start, bound, 0);
|
||||
page_start = index << TARGET_PAGE_BITS;
|
||||
page_last = page_start | ~TARGET_PAGE_MASK;
|
||||
page_last = MIN(page_last, last);
|
||||
tb_invalidate_phys_page_range__locked(pages, pd,
|
||||
page_start, page_last, 0);
|
||||
}
|
||||
page_collection_unlock(pages);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ endforeach
|
||||
|
||||
if dbus_display
|
||||
module_ss = ss.source_set()
|
||||
module_ss.add(when: gio, if_true: files('dbusaudio.c'))
|
||||
module_ss.add(when: [gio, pixman], if_true: files('dbusaudio.c'))
|
||||
audio_modules += {'dbus': module_ss}
|
||||
endif
|
||||
|
||||
|
@ -1181,6 +1181,84 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like partsN(float_to_sint), except do not saturate the result.
|
||||
* Instead, return the rounded unbounded precision two's compliment result,
|
||||
* modulo 2**(bitsm1 + 1).
|
||||
*/
|
||||
static int64_t partsN(float_to_sint_modulo)(FloatPartsN *p,
|
||||
FloatRoundMode rmode,
|
||||
int bitsm1, float_status *s)
|
||||
{
|
||||
int flags = 0;
|
||||
uint64_t r;
|
||||
bool overflow = false;
|
||||
|
||||
switch (p->cls) {
|
||||
case float_class_snan:
|
||||
flags |= float_flag_invalid_snan;
|
||||
/* fall through */
|
||||
case float_class_qnan:
|
||||
flags |= float_flag_invalid;
|
||||
r = 0;
|
||||
break;
|
||||
|
||||
case float_class_inf:
|
||||
overflow = true;
|
||||
r = 0;
|
||||
break;
|
||||
|
||||
case float_class_zero:
|
||||
return 0;
|
||||
|
||||
case float_class_normal:
|
||||
/* TODO: N - 2 is frac_size for rounding; could use input fmt. */
|
||||
if (parts_round_to_int_normal(p, rmode, 0, N - 2)) {
|
||||
flags = float_flag_inexact;
|
||||
}
|
||||
|
||||
if (p->exp <= DECOMPOSED_BINARY_POINT) {
|
||||
/*
|
||||
* Because we rounded to integral, and exp < 64,
|
||||
* we know frac_low is zero.
|
||||
*/
|
||||
r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
|
||||
if (p->exp < bitsm1) {
|
||||
/* Result in range. */
|
||||
} else if (p->exp == bitsm1) {
|
||||
/* The only in-range value is INT_MIN. */
|
||||
overflow = !p->sign || p->frac_hi != DECOMPOSED_IMPLICIT_BIT;
|
||||
} else {
|
||||
overflow = true;
|
||||
}
|
||||
} else {
|
||||
/* Overflow, but there might still be bits to return. */
|
||||
int shl = p->exp - DECOMPOSED_BINARY_POINT;
|
||||
if (shl < N) {
|
||||
frac_shl(p, shl);
|
||||
r = p->frac_hi;
|
||||
} else {
|
||||
r = 0;
|
||||
}
|
||||
overflow = true;
|
||||
}
|
||||
|
||||
if (p->sign) {
|
||||
r = -r;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (overflow) {
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
}
|
||||
float_raise(flags, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Integer to float conversions
|
||||
*
|
||||
|
@ -852,11 +852,24 @@ static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rmode,
|
||||
#define parts_float_to_uint(P, R, Z, M, S) \
|
||||
PARTS_GENERIC_64_128(float_to_uint, P)(P, R, Z, M, S)
|
||||
|
||||
static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
|
||||
FloatRoundMode rmode,
|
||||
int bitsm1, float_status *s);
|
||||
static int64_t parts128_float_to_sint_modulo(FloatParts128 *p,
|
||||
FloatRoundMode rmode,
|
||||
int bitsm1, float_status *s);
|
||||
|
||||
#define parts_float_to_sint_modulo(P, R, M, S) \
|
||||
PARTS_GENERIC_64_128(float_to_sint_modulo, P)(P, R, M, S)
|
||||
|
||||
static void parts64_sint_to_float(FloatParts64 *p, int64_t a,
|
||||
int scale, float_status *s);
|
||||
static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
|
||||
int scale, float_status *s);
|
||||
|
||||
#define parts_float_to_sint(P, R, Z, MN, MX, S) \
|
||||
PARTS_GENERIC_64_128(float_to_sint, P)(P, R, Z, MN, MX, S)
|
||||
|
||||
#define parts_sint_to_float(P, I, Z, S) \
|
||||
PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S)
|
||||
|
||||
@ -3409,6 +3422,24 @@ int64_t bfloat16_to_int64_round_to_zero(bfloat16 a, float_status *s)
|
||||
return bfloat16_to_int64_scalbn(a, float_round_to_zero, 0, s);
|
||||
}
|
||||
|
||||
int32_t float64_to_int32_modulo(float64 a, FloatRoundMode rmode,
|
||||
float_status *s)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
||||
float64_unpack_canonical(&p, a, s);
|
||||
return parts_float_to_sint_modulo(&p, rmode, 31, s);
|
||||
}
|
||||
|
||||
int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
|
||||
float_status *s)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
||||
float64_unpack_canonical(&p, a, s);
|
||||
return parts_float_to_sint_modulo(&p, rmode, 63, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Floating-point to unsigned integer conversions
|
||||
*/
|
||||
|
@ -751,6 +751,9 @@ int16_t float64_to_int16_round_to_zero(float64, float_status *status);
|
||||
int32_t float64_to_int32_round_to_zero(float64, float_status *status);
|
||||
int64_t float64_to_int64_round_to_zero(float64, float_status *status);
|
||||
|
||||
int32_t float64_to_int32_modulo(float64, FloatRoundMode, float_status *status);
|
||||
int64_t float64_to_int64_modulo(float64, FloatRoundMode, float_status *status);
|
||||
|
||||
uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *);
|
||||
uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *);
|
||||
uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *);
|
||||
|
@ -1135,12 +1135,6 @@ uint64_t dup_const(unsigned vece, uint64_t c);
|
||||
: (qemu_build_not_reached_always(), 0)) \
|
||||
: dup_const(VECE, C))
|
||||
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
void tcg_assert_listed_vecop(TCGOpcode);
|
||||
#else
|
||||
static inline void tcg_assert_listed_vecop(TCGOpcode op) { }
|
||||
#endif
|
||||
|
||||
static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
|
@ -281,9 +281,15 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
|
||||
/* Note that start and size have already been aligned by mmap_find_vma. */
|
||||
|
||||
end_addr = start + size;
|
||||
/*
|
||||
* Start at the top of the address space, ignoring the last page.
|
||||
* If reserved_va == UINT32_MAX, then end_addr wraps to 0,
|
||||
* throwing the rest of the calculations off.
|
||||
* TODO: rewrite using last_addr instead.
|
||||
* TODO: use the interval tree instead of probing every page.
|
||||
*/
|
||||
if (start > reserved_va - size) {
|
||||
/* Start at the top of the address space. */
|
||||
end_addr = ((reserved_va + 1 - size) & -align) + size;
|
||||
end_addr = ((reserved_va - size) & -align) + size;
|
||||
looped = true;
|
||||
}
|
||||
|
||||
@ -296,8 +302,8 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
|
||||
/* Failure. The entire address space has been searched. */
|
||||
return (abi_ulong)-1;
|
||||
}
|
||||
/* Re-start at the top of the address space. */
|
||||
addr = end_addr = ((reserved_va + 1 - size) & -align) + size;
|
||||
/* Re-start at the top of the address space (see above). */
|
||||
addr = end_addr = ((reserved_va - size) & -align) + size;
|
||||
looped = true;
|
||||
} else {
|
||||
prot = page_get_flags(addr);
|
||||
|
@ -453,78 +453,29 @@ uint64_t helper_cvtqs(CPUAlphaState *env, uint64_t a)
|
||||
|
||||
static uint64_t do_cvttq(CPUAlphaState *env, uint64_t a, int roundmode)
|
||||
{
|
||||
uint64_t frac, ret = 0;
|
||||
uint32_t exp, sign, exc = 0;
|
||||
int shift;
|
||||
float64 fa;
|
||||
int64_t ret;
|
||||
uint32_t exc;
|
||||
|
||||
sign = (a >> 63);
|
||||
exp = (uint32_t)(a >> 52) & 0x7ff;
|
||||
frac = a & 0xfffffffffffffull;
|
||||
fa = t_to_float64(a);
|
||||
ret = float64_to_int64_modulo(fa, roundmode, &FP_STATUS);
|
||||
|
||||
if (exp == 0) {
|
||||
if (unlikely(frac != 0) && !env->fp_status.flush_inputs_to_zero) {
|
||||
goto do_underflow;
|
||||
}
|
||||
} else if (exp == 0x7ff) {
|
||||
exc = FPCR_INV;
|
||||
} else {
|
||||
/* Restore implicit bit. */
|
||||
frac |= 0x10000000000000ull;
|
||||
exc = get_float_exception_flags(&FP_STATUS);
|
||||
if (unlikely(exc)) {
|
||||
set_float_exception_flags(0, &FP_STATUS);
|
||||
|
||||
shift = exp - 1023 - 52;
|
||||
if (shift >= 0) {
|
||||
/* In this case the number is so large that we must shift
|
||||
the fraction left. There is no rounding to do. */
|
||||
if (shift < 64) {
|
||||
ret = frac << shift;
|
||||
}
|
||||
/* Check for overflow. Note the special case of -0x1p63. */
|
||||
if (shift >= 11 && a != 0xC3E0000000000000ull) {
|
||||
/* We need to massage the resulting exceptions. */
|
||||
if (exc & float_flag_invalid_cvti) {
|
||||
/* Overflow, either normal or infinity. */
|
||||
if (float64_is_infinity(fa)) {
|
||||
exc = FPCR_INV;
|
||||
} else {
|
||||
exc = FPCR_IOV | FPCR_INE;
|
||||
}
|
||||
} else {
|
||||
uint64_t round;
|
||||
|
||||
/* In this case the number is smaller than the fraction as
|
||||
represented by the 52 bit number. Here we must think
|
||||
about rounding the result. Handle this by shifting the
|
||||
fractional part of the number into the high bits of ROUND.
|
||||
This will let us efficiently handle round-to-nearest. */
|
||||
shift = -shift;
|
||||
if (shift < 63) {
|
||||
ret = frac >> shift;
|
||||
round = frac << (64 - shift);
|
||||
} else {
|
||||
/* The exponent is so small we shift out everything.
|
||||
Leave a sticky bit for proper rounding below. */
|
||||
do_underflow:
|
||||
round = 1;
|
||||
}
|
||||
|
||||
if (round) {
|
||||
exc = FPCR_INE;
|
||||
switch (roundmode) {
|
||||
case float_round_nearest_even:
|
||||
if (round == (1ull << 63)) {
|
||||
/* Fraction is exactly 0.5; round to even. */
|
||||
ret += (ret & 1);
|
||||
} else if (round > (1ull << 63)) {
|
||||
ret += 1;
|
||||
}
|
||||
break;
|
||||
case float_round_to_zero:
|
||||
break;
|
||||
case float_round_up:
|
||||
ret += 1 - sign;
|
||||
break;
|
||||
case float_round_down:
|
||||
ret += sign;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sign) {
|
||||
ret = -ret;
|
||||
} else if (exc & float_flag_invalid) {
|
||||
exc = FPCR_INV;
|
||||
} else if (exc & float_flag_inexact) {
|
||||
exc = FPCR_INE;
|
||||
}
|
||||
}
|
||||
env->error_code = exc;
|
||||
|
@ -1120,68 +1120,21 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
|
||||
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
|
||||
{
|
||||
float_status *status = vstatus;
|
||||
uint32_t exp, sign;
|
||||
uint64_t frac;
|
||||
uint32_t inexact = 1; /* !Z */
|
||||
uint32_t inexact, frac;
|
||||
uint32_t e_old, e_new;
|
||||
|
||||
sign = extract64(value, 63, 1);
|
||||
exp = extract64(value, 52, 11);
|
||||
frac = extract64(value, 0, 52);
|
||||
e_old = get_float_exception_flags(status);
|
||||
set_float_exception_flags(0, status);
|
||||
frac = float64_to_int32_modulo(value, float_round_to_zero, status);
|
||||
e_new = get_float_exception_flags(status);
|
||||
set_float_exception_flags(e_old | e_new, status);
|
||||
|
||||
if (exp == 0) {
|
||||
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
inexact = sign;
|
||||
if (frac != 0) {
|
||||
if (status->flush_inputs_to_zero) {
|
||||
float_raise(float_flag_input_denormal, status);
|
||||
} else {
|
||||
float_raise(float_flag_inexact, status);
|
||||
inexact = 1;
|
||||
}
|
||||
}
|
||||
frac = 0;
|
||||
} else if (exp == 0x7ff) {
|
||||
/* This operation raises Invalid for both NaN and overflow (Inf). */
|
||||
float_raise(float_flag_invalid, status);
|
||||
frac = 0;
|
||||
if (value == float64_chs(float64_zero)) {
|
||||
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
inexact = 1;
|
||||
} else {
|
||||
int true_exp = exp - 1023;
|
||||
int shift = true_exp - 52;
|
||||
|
||||
/* Restore implicit bit. */
|
||||
frac |= 1ull << 52;
|
||||
|
||||
/* Shift the fraction into place. */
|
||||
if (shift >= 0) {
|
||||
/* The number is so large we must shift the fraction left. */
|
||||
if (shift >= 64) {
|
||||
/* The fraction is shifted out entirely. */
|
||||
frac = 0;
|
||||
} else {
|
||||
frac <<= shift;
|
||||
}
|
||||
} else if (shift > -64) {
|
||||
/* Normal case -- shift right and notice if bits shift out. */
|
||||
inexact = (frac << (64 + shift)) != 0;
|
||||
frac >>= -shift;
|
||||
} else {
|
||||
/* The fraction is shifted out entirely. */
|
||||
frac = 0;
|
||||
}
|
||||
|
||||
/* Notice overflow or inexact exceptions. */
|
||||
if (true_exp > 31 || frac > (sign ? 0x80000000ull : 0x7fffffff)) {
|
||||
/* Overflow, for which this operation raises invalid. */
|
||||
float_raise(float_flag_invalid, status);
|
||||
inexact = 1;
|
||||
} else if (inexact) {
|
||||
float_raise(float_flag_inexact, status);
|
||||
}
|
||||
|
||||
/* Honor the sign. */
|
||||
if (sign) {
|
||||
frac = -frac;
|
||||
}
|
||||
/* Normal inexact or overflow or NaN */
|
||||
inexact = e_new & (float_flag_inexact | float_flag_invalid);
|
||||
}
|
||||
|
||||
/* Pack the result and the env->ZF representation of Z together. */
|
||||
|
@ -436,19 +436,19 @@ static const Nios2Instruction i_type_instructions[] = {
|
||||
INSTRUCTION_FLG(gen_cmpxxsi, TCG_COND_GE), /* cmpgei */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_FLG(gen_ldx, MO_UW), /* ldhu */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TEUW), /* ldhu */
|
||||
INSTRUCTION(andi), /* andi */
|
||||
INSTRUCTION_FLG(gen_stx, MO_UW), /* sth */
|
||||
INSTRUCTION_FLG(gen_stx, MO_TEUW), /* sth */
|
||||
INSTRUCTION_FLG(gen_bxx, TCG_COND_GE), /* bge */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_SW), /* ldh */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TESW), /* ldh */
|
||||
INSTRUCTION_FLG(gen_cmpxxsi, TCG_COND_LT), /* cmplti */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_NOP(), /* initda */
|
||||
INSTRUCTION(ori), /* ori */
|
||||
INSTRUCTION_FLG(gen_stx, MO_UL), /* stw */
|
||||
INSTRUCTION_FLG(gen_stx, MO_TEUL), /* stw */
|
||||
INSTRUCTION_FLG(gen_bxx, TCG_COND_LT), /* blt */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_UL), /* ldw */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TEUL), /* ldw */
|
||||
INSTRUCTION_FLG(gen_cmpxxsi, TCG_COND_NE), /* cmpnei */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
@ -468,19 +468,19 @@ static const Nios2Instruction i_type_instructions[] = {
|
||||
INSTRUCTION_FLG(gen_cmpxxui, TCG_COND_GEU), /* cmpgeui */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_FLG(gen_ldx, MO_UW), /* ldhuio */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TEUW), /* ldhuio */
|
||||
INSTRUCTION(andhi), /* andhi */
|
||||
INSTRUCTION_FLG(gen_stx, MO_UW), /* sthio */
|
||||
INSTRUCTION_FLG(gen_stx, MO_TEUW), /* sthio */
|
||||
INSTRUCTION_FLG(gen_bxx, TCG_COND_GEU), /* bgeu */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_SW), /* ldhio */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TESW), /* ldhio */
|
||||
INSTRUCTION_FLG(gen_cmpxxui, TCG_COND_LTU), /* cmpltui */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_UNIMPLEMENTED(), /* custom */
|
||||
INSTRUCTION_NOP(), /* initd */
|
||||
INSTRUCTION(orhi), /* orhi */
|
||||
INSTRUCTION_FLG(gen_stx, MO_SL), /* stwio */
|
||||
INSTRUCTION_FLG(gen_stx, MO_TESL), /* stwio */
|
||||
INSTRUCTION_FLG(gen_bxx, TCG_COND_LTU), /* bltu */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_UL), /* ldwio */
|
||||
INSTRUCTION_FLG(gen_ldx, MO_TEUL), /* ldwio */
|
||||
INSTRUCTION(rdprs), /* rdprs */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_FLG(handle_r_type_instr, 0), /* R-Type */
|
||||
|
@ -42,9 +42,9 @@
|
||||
* tcg_ctx->vec_opt_opc is non-NULL, the tcg_gen_*_vec expanders
|
||||
* will validate that their opcode is present in the list.
|
||||
*/
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
void tcg_assert_listed_vecop(TCGOpcode op)
|
||||
static void tcg_assert_listed_vecop(TCGOpcode op)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
const TCGOpcode *p = tcg_ctx->vecop_list;
|
||||
if (p) {
|
||||
for (; *p; ++p) {
|
||||
@ -54,8 +54,8 @@ void tcg_assert_listed_vecop(TCGOpcode op)
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool tcg_can_emit_vecop_list(const TCGOpcode *list,
|
||||
TCGType type, unsigned vece)
|
||||
|
@ -5,7 +5,7 @@
|
||||
ALPHA_SRC=$(SRC_PATH)/tests/tcg/alpha
|
||||
VPATH+=$(ALPHA_SRC)
|
||||
|
||||
ALPHA_TESTS=hello-alpha test-cond test-cmov test-ovf
|
||||
ALPHA_TESTS=hello-alpha test-cond test-cmov test-ovf test-cvttq
|
||||
TESTS+=$(ALPHA_TESTS)
|
||||
|
||||
test-cmov: EXTRA_CFLAGS=-DTEST_CMOV
|
||||
|
78
tests/tcg/alpha/test-cvttq.c
Normal file
78
tests/tcg/alpha/test-cvttq.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define FPCR_SUM (1UL << 63)
|
||||
#define FPCR_INED (1UL << 62)
|
||||
#define FPCR_UNFD (1UL << 61)
|
||||
#define FPCR_UNDZ (1UL << 60)
|
||||
#define FPCR_DYN_SHIFT 58
|
||||
#define FPCR_DYN_CHOPPED (0UL << FPCR_DYN_SHIFT)
|
||||
#define FPCR_DYN_MINUS (1UL << FPCR_DYN_SHIFT)
|
||||
#define FPCR_DYN_NORMAL (2UL << FPCR_DYN_SHIFT)
|
||||
#define FPCR_DYN_PLUS (3UL << FPCR_DYN_SHIFT)
|
||||
#define FPCR_DYN_MASK (3UL << FPCR_DYN_SHIFT)
|
||||
#define FPCR_IOV (1UL << 57)
|
||||
#define FPCR_INE (1UL << 56)
|
||||
#define FPCR_UNF (1UL << 55)
|
||||
#define FPCR_OVF (1UL << 54)
|
||||
#define FPCR_DZE (1UL << 53)
|
||||
#define FPCR_INV (1UL << 52)
|
||||
#define FPCR_OVFD (1UL << 51)
|
||||
#define FPCR_DZED (1UL << 50)
|
||||
#define FPCR_INVD (1UL << 49)
|
||||
#define FPCR_DNZ (1UL << 48)
|
||||
#define FPCR_DNOD (1UL << 47)
|
||||
#define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \
|
||||
| FPCR_OVF | FPCR_DZE | FPCR_INV)
|
||||
|
||||
static long test_cvttq(long *ret_e, double d)
|
||||
{
|
||||
unsigned long reset = (FPCR_INED | FPCR_UNFD | FPCR_OVFD | FPCR_DZED |
|
||||
FPCR_INVD | FPCR_DYN_NORMAL);
|
||||
long r, e;
|
||||
|
||||
asm("excb\n\t"
|
||||
"mt_fpcr %3\n\t"
|
||||
"excb\n\t"
|
||||
"cvttq/svic %2, %0\n\t"
|
||||
"excb\n\t"
|
||||
"mf_fpcr %1\n\t"
|
||||
"excb\n\t"
|
||||
: "=f"(r), "=f"(e)
|
||||
: "f"(d), "f"(reset));
|
||||
|
||||
*ret_e = e & FPCR_STATUS_MASK;
|
||||
return r;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
static const struct {
|
||||
double d;
|
||||
long r;
|
||||
long e;
|
||||
} T[] = {
|
||||
{ 1.0, 1, 0 },
|
||||
{ -1.0, -1, 0 },
|
||||
{ 1.5, 1, FPCR_INE },
|
||||
{ 0x1.0p32, 0x0000000100000000ul, 0 },
|
||||
{ -0x1.0p63, 0x8000000000000000ul, 0 },
|
||||
{ 0x1.0p63, 0x8000000000000000ul, FPCR_IOV | FPCR_INE },
|
||||
{ 0x1.0p64, 0x0000000000000000ul, FPCR_IOV | FPCR_INE },
|
||||
{ 0x1.cccp64, 0xccc0000000000000ul, FPCR_IOV | FPCR_INE },
|
||||
{ __builtin_inf(), 0, FPCR_INV },
|
||||
{ __builtin_nan(""), 0, FPCR_INV },
|
||||
};
|
||||
|
||||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < sizeof(T)/sizeof(T[0]); i++) {
|
||||
long e, r = test_cvttq(&e, T[i].d);
|
||||
|
||||
if (r != T[i].r || e != T[i].e) {
|
||||
printf("Fail %a: expect (%016lx : %04lx) got (%016lx : %04lx)\n",
|
||||
T[i].d, T[i].r, T[i].e >> 48, r, e >> 48);
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
@ -177,6 +177,7 @@ fail:
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
#if defined(CONFIG_GBM) || defined(WIN32)
|
||||
static void dbus_update_gl_cb(GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
@ -203,11 +204,14 @@ static void dbus_update_gl_cb(GObject *source_object,
|
||||
graphic_hw_gl_block(ddl->dcl.con, false);
|
||||
g_object_unref(ddl);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dbus_call_update_gl(DisplayChangeListener *dcl,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
#if defined(CONFIG_GBM) || defined(WIN32)
|
||||
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
|
||||
#endif
|
||||
|
||||
trace_dbus_update_gl(x, y, w, h);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user