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:
Richard Henderson 2023-07-01 08:55:37 +02:00
commit d145c0da22
14 changed files with 258 additions and 155 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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
*

View File

@ -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
*/

View File

@ -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 *);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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. */

View File

@ -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 */

View File

@ -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)

View File

@ -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

View 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;
}

View File

@ -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);