[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH
From: |
Daniel P . Berrangé |
Subject: |
Re: [RFC PATCH 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH with fallthrough |
Date: |
Fri, 13 Oct 2023 09:16:43 +0100 |
User-agent: |
Mutt/2.2.9 (2022-11-12) |
On Fri, Oct 13, 2023 at 10:47:05AM +0300, Emmanouil Pitsidianakis wrote:
> Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> audio/pwaudio.c | 8 ++++----
> hw/arm/smmuv3.c | 2 +-
> include/qemu/compiler.h | 30 +++++++++++++++++++++++-------
> include/qemu/osdep.h | 4 ++--
> target/loongarch/cpu.c | 4 ++--
> target/loongarch/translate.c | 2 +-
> tcg/optimize.c | 8 ++++----
> 7 files changed, 37 insertions(+), 21 deletions(-)
This patch (and all the others in the series) have a ridiculously
large context either side of the change. It makes this horrible
to review as it requires wading through pages of pre-existing code
trying to spot the change.
Please send patches with the default git context lines setting.
>
> diff --git a/audio/pwaudio.c b/audio/pwaudio.c
> index 3ce5f6507b..bf26fadb06 100644
> --- a/audio/pwaudio.c
> +++ b/audio/pwaudio.c
> @@ -1,29 +1,29 @@
> /*
> * QEMU PipeWire audio driver
> *
> * Copyright (c) 2023 Red Hat Inc.
> *
> * Author: Dorinda Bassey <dbassey@redhat.com>
> *
> * SPDX-License-Identifier: GPL-2.0-or-later
> */
>
> +#include <spa/param/audio/format-utils.h>
> +#include <spa/utils/ringbuffer.h>
> +#include <spa/utils/result.h>
> +#include <spa/param/props.h>
> #include "qemu/osdep.h"
> #include "qemu/module.h"
> #include "audio.h"
> #include <errno.h>
> #include "qemu/error-report.h"
> #include "qapi/error.h"
> -#include <spa/param/audio/format-utils.h>
> -#include <spa/utils/ringbuffer.h>
> -#include <spa/utils/result.h>
> -#include <spa/param/props.h>
>
> #include <pipewire/pipewire.h>
> #include "trace.h"
>
> #define AUDIO_CAP "pipewire"
> #define RINGBUFFER_SIZE (1u << 22)
> #define RINGBUFFER_MASK (RINGBUFFER_SIZE - 1)
>
> #include "audio_int.h"
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 6f2b2bd45f..545d82ff04 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1166,210 +1166,210 @@ smmuv3_invalidate_ste(gpointer key, gpointer value,
> gpointer user_data)
> static int smmuv3_cmdq_consume(SMMUv3State *s)
> {
> SMMUState *bs = ARM_SMMU(s);
> SMMUCmdError cmd_error = SMMU_CERROR_NONE;
> SMMUQueue *q = &s->cmdq;
> SMMUCommandType type = 0;
>
> if (!smmuv3_cmdq_enabled(s)) {
> return 0;
> }
> /*
> * some commands depend on register values, typically CR0. In case those
> * register values change while handling the command, spec says it
> * is UNPREDICTABLE whether the command is interpreted under the new
> * or old value.
> */
>
> while (!smmuv3_q_empty(q)) {
> uint32_t pending = s->gerror ^ s->gerrorn;
> Cmd cmd;
>
> trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q),
> Q_PROD_WRAP(q), Q_CONS_WRAP(q));
>
> if (FIELD_EX32(pending, GERROR, CMDQ_ERR)) {
> break;
> }
>
> if (queue_read(q, &cmd) != MEMTX_OK) {
> cmd_error = SMMU_CERROR_ABT;
> break;
> }
>
> type = CMD_TYPE(&cmd);
>
> trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
>
> qemu_mutex_lock(&s->mutex);
> switch (type) {
> case SMMU_CMD_SYNC:
> if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
> smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0);
> }
> break;
> case SMMU_CMD_PREFETCH_CONFIG:
> case SMMU_CMD_PREFETCH_ADDR:
> break;
> case SMMU_CMD_CFGI_STE:
> {
> uint32_t sid = CMD_SID(&cmd);
> IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
> SMMUDevice *sdev;
>
> if (CMD_SSEC(&cmd)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
>
> if (!mr) {
> break;
> }
>
> trace_smmuv3_cmdq_cfgi_ste(sid);
> sdev = container_of(mr, SMMUDevice, iommu);
> smmuv3_flush_config(sdev);
>
> break;
> }
> case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
> {
> uint32_t sid = CMD_SID(&cmd), mask;
> uint8_t range = CMD_STE_RANGE(&cmd);
> SMMUSIDRange sid_range;
>
> if (CMD_SSEC(&cmd)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
>
> mask = (1ULL << (range + 1)) - 1;
> sid_range.start = sid & ~mask;
> sid_range.end = sid_range.start + mask;
>
> trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
> g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
> &sid_range);
> break;
> }
> case SMMU_CMD_CFGI_CD:
> case SMMU_CMD_CFGI_CD_ALL:
> {
> uint32_t sid = CMD_SID(&cmd);
> IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
> SMMUDevice *sdev;
>
> if (CMD_SSEC(&cmd)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
>
> if (!mr) {
> break;
> }
>
> trace_smmuv3_cmdq_cfgi_cd(sid);
> sdev = container_of(mr, SMMUDevice, iommu);
> smmuv3_flush_config(sdev);
> break;
> }
> case SMMU_CMD_TLBI_NH_ASID:
> {
> uint16_t asid = CMD_ASID(&cmd);
>
> if (!STAGE1_SUPPORTED(s)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
>
> trace_smmuv3_cmdq_tlbi_nh_asid(asid);
> smmu_inv_notifiers_all(&s->smmu_state);
> smmu_iotlb_inv_asid(bs, asid);
> break;
> }
> case SMMU_CMD_TLBI_NH_ALL:
> if (!STAGE1_SUPPORTED(s)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case SMMU_CMD_TLBI_NSNH_ALL:
> trace_smmuv3_cmdq_tlbi_nh();
> smmu_inv_notifiers_all(&s->smmu_state);
> smmu_iotlb_inv_all(bs);
> break;
> case SMMU_CMD_TLBI_NH_VAA:
> case SMMU_CMD_TLBI_NH_VA:
> if (!STAGE1_SUPPORTED(s)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
> smmuv3_range_inval(bs, &cmd);
> break;
> case SMMU_CMD_TLBI_S12_VMALL:
> {
> uint16_t vmid = CMD_VMID(&cmd);
>
> if (!STAGE2_SUPPORTED(s)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
>
> trace_smmuv3_cmdq_tlbi_s12_vmid(vmid);
> smmu_inv_notifiers_all(&s->smmu_state);
> smmu_iotlb_inv_vmid(bs, vmid);
> break;
> }
> case SMMU_CMD_TLBI_S2_IPA:
> if (!STAGE2_SUPPORTED(s)) {
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
> /*
> * As currently only either s1 or s2 are supported
> * we can reuse same function for s2.
> */
> smmuv3_range_inval(bs, &cmd);
> break;
> case SMMU_CMD_TLBI_EL3_ALL:
> case SMMU_CMD_TLBI_EL3_VA:
> case SMMU_CMD_TLBI_EL2_ALL:
> case SMMU_CMD_TLBI_EL2_ASID:
> case SMMU_CMD_TLBI_EL2_VA:
> case SMMU_CMD_TLBI_EL2_VAA:
> case SMMU_CMD_ATC_INV:
> case SMMU_CMD_PRI_RESP:
> case SMMU_CMD_RESUME:
> case SMMU_CMD_STALL_TERM:
> trace_smmuv3_unhandled_cmd(type);
> break;
> default:
> cmd_error = SMMU_CERROR_ILL;
> break;
> }
> qemu_mutex_unlock(&s->mutex);
> if (cmd_error) {
> if (cmd_error == SMMU_CERROR_ILL) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "Illegal command type: %d\n", CMD_TYPE(&cmd));
> }
> break;
> }
> /*
> * We only increment the cons index after the completion of
> * the command. We do that because the SYNC returns immediately
> * and does not check the completion of previous commands
> */
> queue_cons_incr(q);
> }
>
> if (cmd_error) {
> trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error);
> smmu_write_cmdq_err(s, cmd_error);
> smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK);
> }
>
> trace_smmuv3_cmdq_consume_out(Q_PROD(q), Q_CONS(q),
> Q_PROD_WRAP(q), Q_CONS_WRAP(q));
>
> return 0;
> }
> diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
> index 1109482a00..959982805d 100644
> --- a/include/qemu/compiler.h
> +++ b/include/qemu/compiler.h
> @@ -1,215 +1,231 @@
> /* compiler.h: macros to abstract away compiler specifics
> *
> * This work is licensed under the terms of the GNU GPL, version 2 or later.
> * See the COPYING file in the top-level directory.
> */
>
> #ifndef COMPILER_H
> #define COMPILER_H
>
> #define HOST_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
>
> /* HOST_LONG_BITS is the size of a native pointer in bits. */
> #define HOST_LONG_BITS (__SIZEOF_POINTER__ * 8)
>
> #if defined __clang_analyzer__ || defined __COVERITY__
> #define QEMU_STATIC_ANALYSIS 1
> #endif
>
> #ifdef __cplusplus
> #define QEMU_EXTERN_C extern "C"
> #else
> #define QEMU_EXTERN_C extern
> #endif
>
> #if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
> # define QEMU_PACKED __attribute__((gcc_struct, packed))
> #else
> # define QEMU_PACKED __attribute__((packed))
> #endif
>
> #define QEMU_ALIGNED(X) __attribute__((aligned(X)))
>
> #ifndef glue
> #define xglue(x, y) x ## y
> #define glue(x, y) xglue(x, y)
> #define stringify(s) tostring(s)
> #define tostring(s) #s
> #endif
>
> /* Expands into an identifier stemN, where N is another number each time */
> #define MAKE_IDENTFIER(stem) glue(stem, __COUNTER__)
>
> #ifndef likely
> #define likely(x) __builtin_expect(!!(x), 1)
> #define unlikely(x) __builtin_expect(!!(x), 0)
> #endif
>
> #ifndef container_of
> #define container_of(ptr, type, member) ({ \
> const typeof(((type *) 0)->member) *__mptr = (ptr); \
> (type *) ((char *) __mptr - offsetof(type, member));})
> #endif
>
> #define sizeof_field(type, field) sizeof(((type *)0)->field)
>
> /*
> * Calculate the number of bytes up to and including the given 'field' of
> * 'container'.
> */
> #define endof(container, field) \
> (offsetof(container, field) + sizeof_field(container, field))
>
> /* Convert from a base type to a parent type, with compile time checking. */
> #define DO_UPCAST(type, field, dev) ( __extension__ ( { \
> char __attribute__((unused)) offset_must_be_zero[ \
> -offsetof(type, field)]; \
> container_of(dev, type, field);}))
>
> #define typeof_field(type, field) typeof(((type *)0)->field)
> #define type_check(t1,t2) ((t1*)0 - (t2*)0)
>
> #define QEMU_BUILD_BUG_ON_STRUCT(x) \
> struct { \
> int:(x) ? -1 : 1; \
> }
>
> #define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg)
>
> #define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x)
>
> #define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \
> sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)))
>
> #if !defined(__clang__) && defined(_WIN32)
> /*
> * Map __printf__ to __gnu_printf__ because we want standard format strings
> even
> * when MinGW or GLib include files use __printf__.
> */
> # define __printf__ __gnu_printf__
> #endif
>
> #ifndef __has_warning
> #define __has_warning(x) 0 /* compatibility with non-clang compilers */
> #endif
>
> #ifndef __has_feature
> #define __has_feature(x) 0 /* compatibility with non-clang compilers */
> #endif
>
> #ifndef __has_builtin
> #define __has_builtin(x) 0 /* compatibility with non-clang compilers */
> #endif
>
> #if __has_builtin(__builtin_assume_aligned) || !defined(__clang__)
> #define HAS_ASSUME_ALIGNED
> #endif
>
> #ifndef __has_attribute
> #define __has_attribute(x) 0 /* compatibility with older GCC */
> #endif
>
> #if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
> # define QEMU_SANITIZE_ADDRESS 1
> #endif
>
> #if defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer)
> # define QEMU_SANITIZE_THREAD 1
> #endif
>
> /*
> * GCC doesn't provide __has_attribute() until GCC 5, but we know all the GCC
> * versions we support have the "flatten" attribute. Clang may not have the
> * "flatten" attribute but always has __has_attribute() to check for it.
> */
> #if __has_attribute(flatten) || !defined(__clang__)
> # define QEMU_FLATTEN __attribute__((flatten))
> #else
> # define QEMU_FLATTEN
> #endif
>
> /*
> * If __attribute__((error)) is present, use it to produce an error at
> * compile time. Otherwise, one must wait for the linker to diagnose
> * the missing symbol.
> */
> #if __has_attribute(error)
> # define QEMU_ERROR(X) __attribute__((error(X)))
> #else
> # define QEMU_ERROR(X)
> #endif
>
> /*
> * The nonstring variable attribute specifies that an object or member
> * declaration with type array of char or pointer to char is intended
> * to store character arrays that do not necessarily contain a terminating
> * NUL character. This is useful in detecting uses of such arrays or pointers
> * with functions that expect NUL-terminated strings, and to avoid warnings
> * when such an array or pointer is used as an argument to a bounded string
> * manipulation function such as strncpy.
> */
> #if __has_attribute(nonstring)
> # define QEMU_NONSTRING __attribute__((nonstring))
> #else
> # define QEMU_NONSTRING
> #endif
>
> /*
> * Forced inlining may be desired to encourage constant propagation
> * of function parameters. However, it can also make debugging harder,
> * so disable it for a non-optimizing build.
> */
> #if defined(__OPTIMIZE__)
> #define QEMU_ALWAYS_INLINE __attribute__((always_inline))
> #else
> #define QEMU_ALWAYS_INLINE
> #endif
>
> -/**
> - * In most cases, normal "fallthrough" comments are good enough for
> - * switch-case statements, but sometimes the compiler has problems
> - * with those. In that case you can use QEMU_FALLTHROUGH instead.
> +/*
> + * Add the pseudo keyword 'fallthrough' so case statement blocks
> + * must end with any of these keywords:
> + * break;
> + * fallthrough;
> + * continue;
> + * goto <label>;
> + * return [expression];
> + *
> + * gcc:
> https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
> */
> -#if __has_attribute(fallthrough)
> -# define QEMU_FALLTHROUGH __attribute__((fallthrough))
> +
> +/*
> + * glib_macros.h contains its own definition of fallthrough, so if we define
> + * the pseudokeyword here it will expand when the glib header checks for the
> + * attribute. glib headers must be #included after this header.
> + */
> +#ifdef fallthrough
> +#undef fallthrough
> +#endif
> +
> +#if __has_attribute(__fallthrough__)
> +# define fallthrough __attribute__((__fallthrough__))
> #else
> -# define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */
> +# define fallthrough do {} while (0) /* fallthrough */
> #endif
>
> #ifdef CONFIG_CFI
> /*
> * If CFI is enabled, use an attribute to disable cfi-icall on the following
> * function
> */
> #define QEMU_DISABLE_CFI __attribute__((no_sanitize("cfi-icall")))
> #else
> /* If CFI is not enabled, use an empty define to not change the behavior */
> #define QEMU_DISABLE_CFI
> #endif
>
> /*
> * Apple clang version 14 has a bug in its __builtin_subcll(); define
> * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
> * When a version of Apple clang which has this bug fixed is released
> * we can add an upper bound to this check.
> * See https://gitlab.com/qemu-project/qemu/-/issues/1631
> * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
> * The bug never made it into any upstream LLVM releases, only Apple ones.
> */
> #if defined(__apple_build_version__) && __clang_major__ >= 14
> #define BUILTIN_SUBCLL_BROKEN
> #endif
>
> #if __has_attribute(annotate)
> #define QEMU_ANNOTATE(x) __attribute__((annotate(x)))
> #else
> #define QEMU_ANNOTATE(x)
> #endif
>
> #if __has_attribute(used)
> # define QEMU_USED __attribute__((used))
> #else
> # define QEMU_USED
> #endif
>
> #endif /* COMPILER_H */
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index 475a1c62ff..8f790f0deb 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -1,171 +1,171 @@
> /*
> * OS includes and handling of OS dependencies
> *
> * This header exists to pull in some common system headers that
> * most code in QEMU will want, and to fix up some possible issues with
> * it (missing defines, Windows weirdness, and so on).
> *
> * To avoid getting into possible circular include dependencies, this
> * file should not include any other QEMU headers, with the exceptions
> * of config-host.h, config-target.h, qemu/compiler.h,
> * sysemu/os-posix.h, sysemu/os-win32.h, glib-compat.h and
> * qemu/typedefs.h, all of which are doing a similar job to this file
> * and are under similar constraints.
> *
> * This header also contains prototypes for functions defined in
> * os-*.c and util/oslib-*.c; those would probably be better split
> * out into separate header files.
> *
> * In an ideal world this header would contain only:
> * (1) things which everybody needs
> * (2) things without which code would work on most platforms but
> * fail to compile or misbehave on a minority of host OSes
> *
> * This work is licensed under the terms of the GNU GPL, version 2 or later.
> * See the COPYING file in the top-level directory.
> */
> #ifndef QEMU_OSDEP_H
> #define QEMU_OSDEP_H
>
> #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ &&
> defined __linux__
> # define _FORTIFY_SOURCE 2
> #endif
>
> #include "config-host.h"
> #ifdef NEED_CPU_H
> #include CONFIG_TARGET
> #else
> #include "exec/poison.h"
> #endif
>
> /*
> * HOST_WORDS_BIGENDIAN was replaced with HOST_BIG_ENDIAN. Prevent it from
> * creeping back in.
> */
> #pragma GCC poison HOST_WORDS_BIGENDIAN
>
> /*
> * TARGET_WORDS_BIGENDIAN was replaced with TARGET_BIG_ENDIAN. Prevent it
> from
> * creeping back in.
> */
> #pragma GCC poison TARGET_WORDS_BIGENDIAN
>
> -#include "qemu/compiler.h"
> -
> /* Older versions of C++ don't get definitions of various macros from
> * stdlib.h unless we define these macros before first inclusion of
> * that system header.
> */
> #ifndef __STDC_CONSTANT_MACROS
> #define __STDC_CONSTANT_MACROS
> #endif
> #ifndef __STDC_LIMIT_MACROS
> #define __STDC_LIMIT_MACROS
> #endif
> #ifndef __STDC_FORMAT_MACROS
> #define __STDC_FORMAT_MACROS
> #endif
>
> /* The following block of code temporarily renames the daemon() function so
> the
> * compiler does not see the warning associated with it in stdlib.h on OSX
> */
> #ifdef __APPLE__
> #define daemon qemu_fake_daemon_function
> #include <stdlib.h>
> #undef daemon
> QEMU_EXTERN_C int daemon(int, int);
> #endif
>
> #ifdef _WIN32
> /* as defined in sdkddkver.h */
> #ifndef _WIN32_WINNT
> #define _WIN32_WINNT 0x0602 /* Windows 8 API (should be >= the one from
> glib) */
> #endif
> /* reduces the number of implicitly included headers */
> #ifndef WIN32_LEAN_AND_MEAN
> #define WIN32_LEAN_AND_MEAN
> #endif
> #endif
>
> /* enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) */
> #ifdef __MINGW32__
> #define __USE_MINGW_ANSI_STDIO 1
> #endif
>
> /*
> * We need the FreeBSD "legacy" definitions. Rust needs the FreeBSD 11 system
> * calls since it doesn't use libc at all, so we have to emulate that despite
> * FreeBSD 11 being EOL'd.
> */
> #ifdef __FreeBSD__
> #define _WANT_FREEBSD11_STAT
> #define _WANT_FREEBSD11_STATFS
> #define _WANT_FREEBSD11_DIRENT
> #define _WANT_KERNEL_ERRNO
> #define _WANT_SEMUN
> #endif
>
> #include <stdarg.h>
> #include <stddef.h>
> #include <stdbool.h>
> #include <stdint.h>
> #include <sys/types.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> #include <string.h>
> #include <strings.h>
> #include <inttypes.h>
> #include <limits.h>
> /* Put unistd.h before time.h as that triggers localtime_r/gmtime_r
> * function availability on recentish Mingw-w64 platforms. */
> #include <unistd.h>
> #include <time.h>
> #include <ctype.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <getopt.h>
> #include <sys/stat.h>
> #include <sys/time.h>
> #include <assert.h>
> /* setjmp must be declared before sysemu/os-win32.h
> * because it is redefined there. */
> #include <setjmp.h>
> #include <signal.h>
>
> #ifdef CONFIG_IOVEC
> #include <sys/uio.h>
> #endif
>
> #if defined(__linux__) && defined(__sparc__)
> /* The SPARC definition of QEMU_VMALLOC_ALIGN needs SHMLBA */
> #include <sys/shm.h>
> #endif
>
> #ifndef _WIN32
> #include <sys/wait.h>
> #else
> #define WIFEXITED(x) 1
> #define WEXITSTATUS(x) (x)
> #endif
>
> #ifdef __APPLE__
> #include <AvailabilityMacros.h>
> #endif
>
> /*
> * This is somewhat like a system header; it must be outside any extern "C"
> * block because it includes system headers itself, including glib.h,
> * which will not compile if inside an extern "C" block.
> */
> #include "glib-compat.h"
>
> +#include "qemu/compiler.h"
> +
> #ifdef _WIN32
> #include "sysemu/os-win32.h"
> #endif
>
> #ifdef CONFIG_POSIX
> #include "sysemu/os-posix.h"
> #endif
>
> #ifdef __cplusplus
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index 2bea7ca5d5..e01d626b15 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -142,145 +142,145 @@ static inline bool
> cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
> static void loongarch_cpu_do_interrupt(CPUState *cs)
> {
> LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> CPULoongArchState *env = &cpu->env;
> bool update_badinstr = 1;
> int cause = -1;
> const char *name;
> bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR);
> uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
>
> if (cs->exception_index != EXCCODE_INT) {
> if (cs->exception_index < 0 ||
> cs->exception_index >= ARRAY_SIZE(excp_names)) {
> name = "unknown";
> } else {
> name = excp_names[cs->exception_index];
> }
>
> qemu_log_mask(CPU_LOG_INT,
> "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx
> " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__,
> env->pc, env->CSR_ERA, env->CSR_TLBRERA, name);
> }
>
> switch (cs->exception_index) {
> case EXCCODE_DBP:
> env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1);
> env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC);
> goto set_DERA;
> set_DERA:
> env->CSR_DERA = env->pc;
> env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
> set_pc(env, env->CSR_EENTRY + 0x480);
> break;
> case EXCCODE_INT:
> if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
> env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1);
> goto set_DERA;
> }
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case EXCCODE_PIF:
> case EXCCODE_ADEF:
> cause = cs->exception_index;
> update_badinstr = 0;
> break;
> case EXCCODE_SYS:
> case EXCCODE_BRK:
> case EXCCODE_INE:
> case EXCCODE_IPE:
> case EXCCODE_FPD:
> case EXCCODE_FPE:
> case EXCCODE_SXD:
> case EXCCODE_ASXD:
> env->CSR_BADV = env->pc;
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case EXCCODE_BCE:
> case EXCCODE_ADEM:
> case EXCCODE_PIL:
> case EXCCODE_PIS:
> case EXCCODE_PME:
> case EXCCODE_PNR:
> case EXCCODE_PNX:
> case EXCCODE_PPI:
> cause = cs->exception_index;
> break;
> default:
> qemu_log("Error: exception(%d) has not been supported\n",
> cs->exception_index);
> abort();
> }
>
> if (update_badinstr) {
> env->CSR_BADI = cpu_ldl_code(env, env->pc);
> }
>
> /* Save PLV and IE */
> if (tlbfill) {
> env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV,
> FIELD_EX64(env->CSR_CRMD,
> CSR_CRMD, PLV));
> env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE,
> FIELD_EX64(env->CSR_CRMD, CSR_CRMD,
> IE));
> /* set the DA mode */
> env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1);
> env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0);
> env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
> PC, (env->pc >> 2));
> } else {
> env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE,
> EXCODE_MCODE(cause));
> env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE,
> EXCODE_SUBCODE(cause));
> env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
> FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
> env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
> FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE));
> env->CSR_ERA = env->pc;
> }
>
> env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0);
> env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0);
>
> if (vec_size) {
> vec_size = (1 << vec_size) * 4;
> }
>
> if (cs->exception_index == EXCCODE_INT) {
> /* Interrupt */
> uint32_t vector = 0;
> uint32_t pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS);
> pending &= FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE);
>
> /* Find the highest-priority interrupt. */
> vector = 31 - clz32(pending);
> set_pc(env, env->CSR_EENTRY + \
> (EXCCODE_EXTERNAL_INT + vector) * vec_size);
> qemu_log_mask(CPU_LOG_INT,
> "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
> " cause %d\n" " A " TARGET_FMT_lx " D "
> TARGET_FMT_lx " vector = %d ExC " TARGET_FMT_lx "ExS"
> TARGET_FMT_lx "\n",
> __func__, env->pc, env->CSR_ERA,
> cause, env->CSR_BADV, env->CSR_DERA, vector,
> env->CSR_ECFG, env->CSR_ESTAT);
> } else {
> if (tlbfill) {
> set_pc(env, env->CSR_TLBRENTRY);
> } else {
> set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size);
> }
> qemu_log_mask(CPU_LOG_INT,
> "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
> " cause %d%s\n, ESTAT " TARGET_FMT_lx
> " EXCFG " TARGET_FMT_lx " BADVA " TARGET_FMT_lx
> "BADI " TARGET_FMT_lx " SYS_NUM " TARGET_FMT_lu
> " cpu %d asid " TARGET_FMT_lx "\n", __func__, env->pc,
> tlbfill ? env->CSR_TLBRERA : env->CSR_ERA,
> cause, tlbfill ? "(refill)" : "", env->CSR_ESTAT,
> env->CSR_ECFG,
> tlbfill ? env->CSR_TLBRBADV : env->CSR_BADV,
> env->CSR_BADI, env->gpr[11], cs->cpu_index,
> env->CSR_ASID);
> }
> cs->exception_index = -1;
> }
> diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
> index 21f4db6fbd..36fceb1beb 100644
> --- a/target/loongarch/translate.c
> +++ b/target/loongarch/translate.c
> @@ -304,24 +304,24 @@ static void
> loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
> static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
> {
> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>
> switch (ctx->base.is_jmp) {
> case DISAS_STOP:
> tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
> tcg_gen_lookup_and_goto_ptr();
> break;
> case DISAS_TOO_MANY:
> gen_goto_tb(ctx, 0, ctx->base.pc_next);
> break;
> case DISAS_NORETURN:
> break;
> case DISAS_EXIT_UPDATE:
> tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case DISAS_EXIT:
> tcg_gen_exit_tb(NULL, 0);
> break;
> default:
> g_assert_not_reached();
> }
> }
> diff --git a/tcg/optimize.c b/tcg/optimize.c
> index 3013eb04e6..3da135a353 100644
> --- a/tcg/optimize.c
> +++ b/tcg/optimize.c
> @@ -1062,81 +1062,81 @@ static bool fold_brcond(OptContext *ctx, TCGOp *op)
> static bool fold_brcond2(OptContext *ctx, TCGOp *op)
> {
> TCGCond cond = op->args[4];
> TCGArg label = op->args[5];
> int i, inv = 0;
>
> if (swap_commutative2(&op->args[0], &op->args[2])) {
> op->args[4] = cond = tcg_swap_cond(cond);
> }
>
> i = do_constant_folding_cond2(&op->args[0], &op->args[2], cond);
> if (i >= 0) {
> goto do_brcond_const;
> }
>
> switch (cond) {
> case TCG_COND_LT:
> case TCG_COND_GE:
> /*
> * Simplify LT/GE comparisons vs zero to a single compare
> * vs the high word of the input.
> */
> if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == 0 &&
> arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0) {
> goto do_brcond_high;
> }
> break;
>
> case TCG_COND_NE:
> inv = 1;
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case TCG_COND_EQ:
> /*
> * Simplify EQ/NE comparisons where one of the pairs
> * can be simplified.
> */
> i = do_constant_folding_cond(TCG_TYPE_I32, op->args[0],
> op->args[2], cond);
> switch (i ^ inv) {
> case 0:
> goto do_brcond_const;
> case 1:
> goto do_brcond_high;
> }
>
> i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1],
> op->args[3], cond);
> switch (i ^ inv) {
> case 0:
> goto do_brcond_const;
> case 1:
> op->opc = INDEX_op_brcond_i32;
> op->args[1] = op->args[2];
> op->args[2] = cond;
> op->args[3] = label;
> break;
> }
> break;
>
> default:
> break;
>
> do_brcond_high:
> op->opc = INDEX_op_brcond_i32;
> op->args[0] = op->args[1];
> op->args[1] = op->args[3];
> op->args[2] = cond;
> op->args[3] = label;
> break;
>
> do_brcond_const:
> if (i == 0) {
> tcg_op_remove(ctx->tcg, op);
> return true;
> }
> op->opc = INDEX_op_br;
> op->args[0] = label;
> break;
> }
> return false;
> }
> @@ -1424,46 +1424,46 @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
> static bool fold_exts(OptContext *ctx, TCGOp *op)
> {
> uint64_t s_mask_old, s_mask, z_mask, sign;
> bool type_change = false;
>
> if (fold_const1(ctx, op)) {
> return true;
> }
>
> z_mask = arg_info(op->args[1])->z_mask;
> s_mask = arg_info(op->args[1])->s_mask;
> s_mask_old = s_mask;
>
> switch (op->opc) {
> CASE_OP_32_64(ext8s):
> sign = INT8_MIN;
> z_mask = (uint8_t)z_mask;
> break;
> CASE_OP_32_64(ext16s):
> sign = INT16_MIN;
> z_mask = (uint16_t)z_mask;
> break;
> case INDEX_op_ext_i32_i64:
> type_change = true;
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case INDEX_op_ext32s_i64:
> sign = INT32_MIN;
> z_mask = (uint32_t)z_mask;
> break;
> default:
> g_assert_not_reached();
> }
>
> if (z_mask & sign) {
> z_mask |= sign;
> }
> s_mask |= sign << 1;
>
> ctx->z_mask = z_mask;
> ctx->s_mask = s_mask;
> if (!type_change) {
> ctx->a_mask = s_mask & ~s_mask_old;
> }
>
> return fold_masks(ctx, op);
> }
> @@ -1471,40 +1471,40 @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
> static bool fold_extu(OptContext *ctx, TCGOp *op)
> {
> uint64_t z_mask_old, z_mask;
> bool type_change = false;
>
> if (fold_const1(ctx, op)) {
> return true;
> }
>
> z_mask_old = z_mask = arg_info(op->args[1])->z_mask;
>
> switch (op->opc) {
> CASE_OP_32_64(ext8u):
> z_mask = (uint8_t)z_mask;
> break;
> CASE_OP_32_64(ext16u):
> z_mask = (uint16_t)z_mask;
> break;
> case INDEX_op_extrl_i64_i32:
> case INDEX_op_extu_i32_i64:
> type_change = true;
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case INDEX_op_ext32u_i64:
> z_mask = (uint32_t)z_mask;
> break;
> case INDEX_op_extrh_i64_i32:
> type_change = true;
> z_mask >>= 32;
> break;
> default:
> g_assert_not_reached();
> }
>
> ctx->z_mask = z_mask;
> ctx->s_mask = smask_from_zmask(z_mask);
> if (!type_change) {
> ctx->a_mask = z_mask_old ^ z_mask;
> }
> return fold_masks(ctx, op);
> }
> @@ -1835,75 +1835,75 @@ static bool fold_negsetcond(OptContext *ctx, TCGOp
> *op)
> static bool fold_setcond2(OptContext *ctx, TCGOp *op)
> {
> TCGCond cond = op->args[5];
> int i, inv = 0;
>
> if (swap_commutative2(&op->args[1], &op->args[3])) {
> op->args[5] = cond = tcg_swap_cond(cond);
> }
>
> i = do_constant_folding_cond2(&op->args[1], &op->args[3], cond);
> if (i >= 0) {
> goto do_setcond_const;
> }
>
> switch (cond) {
> case TCG_COND_LT:
> case TCG_COND_GE:
> /*
> * Simplify LT/GE comparisons vs zero to a single compare
> * vs the high word of the input.
> */
> if (arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0 &&
> arg_is_const(op->args[4]) && arg_info(op->args[4])->val == 0) {
> goto do_setcond_high;
> }
> break;
>
> case TCG_COND_NE:
> inv = 1;
> - QEMU_FALLTHROUGH;
> + fallthrough;
> case TCG_COND_EQ:
> /*
> * Simplify EQ/NE comparisons where one of the pairs
> * can be simplified.
> */
> i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1],
> op->args[3], cond);
> switch (i ^ inv) {
> case 0:
> goto do_setcond_const;
> case 1:
> goto do_setcond_high;
> }
>
> i = do_constant_folding_cond(TCG_TYPE_I32, op->args[2],
> op->args[4], cond);
> switch (i ^ inv) {
> case 0:
> goto do_setcond_const;
> case 1:
> op->args[2] = op->args[3];
> op->args[3] = cond;
> op->opc = INDEX_op_setcond_i32;
> break;
> }
> break;
>
> default:
> break;
>
> do_setcond_high:
> op->args[1] = op->args[2];
> op->args[2] = op->args[4];
> op->args[3] = cond;
> op->opc = INDEX_op_setcond_i32;
> break;
> }
>
> ctx->z_mask = 1;
> ctx->s_mask = smask_from_zmask(1);
> return false;
>
> do_setcond_const:
> return tcg_opt_gen_movi(ctx, op, op->args[0], i);
> }
> --
> 2.39.2
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
- [RFC PATCH 00/78] Strict disable implicit fallthrough, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH with fallthrough, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 02/78] block: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 04/78] qapi/opts-visitor: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 05/78] qobject/json: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 03/78] fpu/softfloat: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 07/78] hw/virtio/virtio-balloon.c: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 08/78] hw/block: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13