summaryrefslogtreecommitdiffstats
path: root/include/qemu
diff options
context:
space:
mode:
authorPeter Maydell2020-06-26 17:55:20 +0200
committerPeter Maydell2020-06-26 17:55:20 +0200
commit3591ddd39987cbdaa0cfa344a262f315abd97582 (patch)
tree4adfc6f7c9ee3d650087d01f8732fe8d6bcca2c3 /include/qemu
parentMerge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into ... (diff)
parenti386: Mask SVM features if nested SVM is disabled (diff)
downloadqemu-3591ddd39987cbdaa0cfa344a262f315abd97582.tar.gz
qemu-3591ddd39987cbdaa0cfa344a262f315abd97582.tar.xz
qemu-3591ddd39987cbdaa0cfa344a262f315abd97582.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Various fixes * libdaxctl support to correctly align devdax character devices (Jingqi) * initial-all-set support for live migration (Jay) * forbid '-numa node, mem' for 5.1 and newer machine types (Igor) * x87 fixes (Joseph) * Tighten memory_region_access_valid (Michael) and fix fallout (myself) * Replay fixes (Pavel) # gpg: Signature made Fri 26 Jun 2020 14:42:17 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (31 commits) i386: Mask SVM features if nested SVM is disabled ibex_uart: fix XOR-as-pow vmport: move compat properties to hw_compat_5_0 hyperv: vmbus: Remove the 2nd IRQ kvm: i386: allow TSC to differ by NTP correction bounds without TSC scaling numa: forbid '-numa node, mem' for 5.1 and newer machine types osdep: Make MIN/MAX evaluate arguments only once target/i386: Add notes for versioned CPU models target/i386: reimplement fpatan using floatx80 operations target/i386: reimplement fyl2x using floatx80 operations target/i386: reimplement fyl2xp1 using floatx80 operations target/i386: reimplement fprem, fprem1 using floatx80 operations softfloat: return low bits of quotient from floatx80_modrem softfloat: do not set denominator high bit for floatx80 remainder softfloat: do not return pseudo-denormal from floatx80 remainder softfloat: fix floatx80 remainder pseudo-denormal check for zero softfloat: merge floatx80_mod and floatx80_rem target/i386: reimplement f2xm1 using floatx80 operations xen: Actually fix build without passthrough Makefile: Install qemu-[qmp/ga]-ref.* into the directory "interop" ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/qemu')
-rw-r--r--include/qemu/osdep.h57
1 files changed, 47 insertions, 10 deletions
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ff7c17b857..0d26a1b9bd 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -236,18 +236,55 @@ extern int daemon(int, int);
#define SIZE_MAX ((size_t)-1)
#endif
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
+/*
+ * Two variations of MIN/MAX macros. The first is for runtime use, and
+ * evaluates arguments only once (so it is safe even with side
+ * effects), but will not work in constant contexts (such as array
+ * size declarations) because of the '{}'. The second is for constant
+ * expression use, where evaluating arguments twice is safe because
+ * the result is going to be constant anyway, but will not work in a
+ * runtime context because of a void expression where a value is
+ * expected. Thus, both gcc and clang will fail to compile if you use
+ * the wrong macro (even if the error may seem a bit cryptic).
+ *
+ * Note that neither form is usable as an #if condition; if you truly
+ * need to write conditional code that depends on a minimum or maximum
+ * determined by the pre-processor instead of the compiler, you'll
+ * have to open-code it.
+ */
+#undef MIN
+#define MIN(a, b) \
+ ({ \
+ typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
+ _a < _b ? _a : _b; \
+ })
+#define MIN_CONST(a, b) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(a) && __builtin_constant_p(b), \
+ (a) < (b) ? (a) : (b), \
+ ((void)0))
+#undef MAX
+#define MAX(a, b) \
+ ({ \
+ typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
+ _a > _b ? _a : _b; \
+ })
+#define MAX_CONST(a, b) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(a) && __builtin_constant_p(b), \
+ (a) > (b) ? (a) : (b), \
+ ((void)0))
-/* Minimum function that returns zero only iff both values are zero.
- * Intended for use with unsigned values only. */
+/*
+ * Minimum function that returns zero only if both values are zero.
+ * Intended for use with unsigned values only.
+ */
#ifndef MIN_NON_ZERO
-#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
- ((b) == 0 ? (a) : (MIN(a, b))))
+#define MIN_NON_ZERO(a, b) \
+ ({ \
+ typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
+ _a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \
+ })
#endif
/* Round number down to multiple */