[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: |
Markus Armbruster |
Subject: |
Re: [RFC PATCH 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH with fallthrough |
Date: |
Fri, 13 Oct 2023 14:28:31 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) |
The commit message needs to explain why.
Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org> writes:
> 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(-)
>
> 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"
This is wrong. docs/devel/style.rst:
Include directives
------------------
Order include directives as follows:
.. code-block:: c
#include "qemu/osdep.h" /* Always first... */
#include <...> /* then system headers... */
#include "..." /* and finally QEMU headers. */
Separate patch, please.
[...]
> 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 @@
[...]
> #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
Pseudo-keyword? It's a macro.
> + * must end with any of these keywords:
> + * break;
> + * fallthrough;
> + * continue;
> + * goto <label>;
> + * return [expression];
These are statements, not keywords.
> + *
> + * gcc:
> https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
Not sure we need to point to the docs here. We have hundreds of
__attribute__ uses in the tree.
> */
> -#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
Why do we need to roll our own macro then?
> +
> +#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
> /*
[...]
> 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);
> }
- [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 03/78] fpu/softfloat: 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 07/78] hw/virtio/virtio-balloon.c: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 06/78] tcg: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 08/78] hw/block: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13
- [RFC PATCH 11/78] hw/timer: add fallthrough pseudo-keyword, Emmanouil Pitsidianakis, 2023/10/13