mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
d5910e2673
- Fixed bug where stdio eof wasn't being sticky - Fixed bug where fseeko() wasn't clearing eof state - Removed assert() usage from libc favoring _unassert() / _npassert()
32 lines
979 B
C
32 lines
979 B
C
#ifndef COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_
|
|
#define COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_
|
|
#include "libc/assert.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
|
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__)
|
|
/**
|
|
* Computes `(a + b) / 2` assuming unsigned.
|
|
*
|
|
* This implementation is the fastest on AMD Zen architecture.
|
|
*/
|
|
#define _midpoint(a, b) \
|
|
({ \
|
|
typeof((a) + (b)) a_ = (a); \
|
|
typeof(a_) b_ = (b); \
|
|
_unassert(a_ >= 0); \
|
|
_unassert(b_ >= 0); \
|
|
asm("add\t%1,%0\n\t" \
|
|
"rcr\t%0" \
|
|
: "+r"(a_) \
|
|
: "r"(b_)); \
|
|
a_; \
|
|
})
|
|
#else
|
|
/**
|
|
* Computes `(a + b) / 2` assuming unsigned.
|
|
*/
|
|
#define _midpoint(a, b) (((a) & (b)) + ((a) ^ (b)) / 2)
|
|
#endif /* __GNUC__ && !__STRICT_ANSI__ && x86 */
|
|
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_ */
|